TEMP
[dotnetoauth.git] / src / DotNetOpenAuth / OpenId / Provider / Request.cs
blob0962e8490b8fdbd5827f9c2327bba8666bba0eeb
1 //-----------------------------------------------------------------------
2 // <copyright file="Request.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
4 // </copyright>
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth.OpenId.Provider {
8 using System;
9 using System.Collections.Generic;
10 using System.Linq;
11 using System.Text;
12 using DotNetOpenAuth.Messaging;
13 using DotNetOpenAuth.OpenId.Messages;
15 internal abstract class Request : IRequest {
16 private readonly OpenIdProvider provider;
17 private readonly IDirectedProtocolMessage request;
18 private readonly IProtocolMessageWithExtensions extensibleMessage;
19 private List<IOpenIdMessageExtension> extensions = new List<IOpenIdMessageExtension>();
20 private UserAgentResponse cachedUserAgentResponse;
22 protected Request(OpenIdProvider provider, IDirectedProtocolMessage request) {
23 ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
24 ErrorUtilities.VerifyArgumentNotNull(request, "request");
26 this.provider = provider;
27 this.request = request;
28 this.extensibleMessage = request as IProtocolMessageWithExtensions;
31 #region IRequest Members
33 public abstract bool IsResponseReady { get; }
35 #endregion
37 protected OpenIdProvider Provider {
38 get { return this.provider; }
41 protected IDirectedProtocolMessage RequestMessage {
42 get { return this.request; }
45 protected abstract IProtocolMessage ResponseMessage { get; }
47 protected Protocol Protocol {
48 get { return Protocol.Lookup(this.RequestMessage.Version); }
51 #region IRequest Methods
53 public void AddResponseExtension(IOpenIdMessageExtension extension) {
54 ErrorUtilities.VerifyArgumentNotNull(extension, "extension");
56 // Because the derived AuthenticationRequest class can swap out
57 // one response message for another (auth vs. no-auth), and because
58 // some response messages support extensions while others don't,
59 // we just add the extensions to a collection here and add them
60 // to the response on the way out.
61 this.extensions.Add(extension);
62 this.ResetUserAgentResponse();
65 public T GetExtension<T>() where T : IOpenIdMessageExtension, new() {
66 if (this.extensibleMessage != null) {
67 return this.extensibleMessage.Extensions.OfType<T>().SingleOrDefault();
68 } else {
69 return default(T);
73 public IOpenIdMessageExtension GetExtension(Type extensionType) {
74 ErrorUtilities.VerifyArgumentNotNull(extensionType, "extensionType");
75 if (this.extensibleMessage != null) {
76 return this.extensibleMessage.Extensions.OfType<IOpenIdMessageExtension>().Where(ext => extensionType.IsInstanceOfType(ext)).SingleOrDefault();
77 } else {
78 return null;
82 public UserAgentResponse GetResponse() {
83 if (this.cachedUserAgentResponse == null && this.IsResponseReady) {
84 if (this.extensions.Count > 0) {
85 var extensibleResponse = this.ResponseMessage as IProtocolMessageWithExtensions;
86 ErrorUtilities.VerifyOperation(extensibleResponse != null, MessagingStrings.MessageNotExtensible, this.ResponseMessage.GetType().Name);
87 foreach (var extension in this.extensions) {
88 // It's possible that a prior call to this property
89 // has already added some/all of the extensions to the message.
90 // We don't have to worry about deleting old ones because
91 // this class provides no facility for removing extensions
92 // that are previously added.
93 if (!extensibleResponse.Extensions.Contains(extension)) {
94 extensibleResponse.Extensions.Add(extension);
99 this.cachedUserAgentResponse = this.provider.Channel.Send(this.ResponseMessage);
102 return this.cachedUserAgentResponse;
105 #endregion
107 /// <summary>
108 /// Resets any user agent response that may have been created already and cached.
109 /// </summary>
110 protected void ResetUserAgentResponse() {
111 this.cachedUserAgentResponse = null;