summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
blob: 7fac125659812a4f76a74dcc7892af20e1814f65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//-----------------------------------------------------------------------
// <copyright file="InMemoryTokenManager.cs" company="Outercurve Foundation">
//     Copyright (c) Outercurve Foundation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.Test.Mocks {
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Linq;
	using DotNetOpenAuth.Messaging;
	using DotNetOpenAuth.OAuth.ChannelElements;
	using DotNetOpenAuth.OAuth.Messages;
	using DotNetOpenAuth.Test.OAuth;

	internal class InMemoryTokenManager : IServiceProviderTokenManager {
		private KeyedCollectionDelegate<string, ConsumerInfo> consumers = new KeyedCollectionDelegate<string, ConsumerInfo>(c => c.Key);
		private KeyedCollectionDelegate<string, TokenInfo> tokens = new KeyedCollectionDelegate<string, TokenInfo>(t => t.Token);

		/// <summary>
		/// Request tokens that have been issued, and whether they have been authorized yet.
		/// </summary>
		private Dictionary<string, bool> requestTokens = new Dictionary<string, bool>();

		/// <summary>
		/// Access tokens that have been issued and have not yet expired.
		/// </summary>
		private List<string> accessTokens = new List<string>();

		#region ITokenManager Members

		public string GetTokenSecret(string token) {
			return this.tokens[token].Secret;
		}

		public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) {
			this.tokens.Add(new TokenInfo { ConsumerKey = request.ConsumerKey, Token = response.Token, Secret = response.TokenSecret });
			this.requestTokens.Add(response.Token, false);
		}

		/// <summary>
		/// Checks whether a given request token has already been authorized
		/// by some user for use by the Consumer that requested it.
		/// </summary>
		/// <param name="requestToken">The Consumer's request token.</param>
		/// <returns>
		/// True if the request token has already been fully authorized by the user
		/// who owns the relevant protected resources.  False if the token has not yet
		/// been authorized, has expired or does not exist.
		/// </returns>
		public bool IsRequestTokenAuthorized(string requestToken) {
			return this.requestTokens[requestToken];
		}

		public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
			// The following line is commented out because consumers don't mark their own tokens
			// as authorized... only the SPs do.  And since we multi-purpose this test class for
			// both SPs and Consumers, we won't do this extra check.
			////Debug.Assert(this.requestTokens[requestToken], "Unauthorized token should not be exchanged for access token.");
			this.requestTokens.Remove(requestToken);
			this.accessTokens.Add(accessToken);
			this.tokens.Remove(requestToken);
			this.tokens.Add(new TokenInfo { Token = accessToken, Secret = accessTokenSecret });
		}

		/// <summary>
		/// Classifies a token as a request token or an access token.
		/// </summary>
		/// <param name="token">The token to classify.</param>
		/// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
		public TokenType GetTokenType(string token) {
			if (this.requestTokens.ContainsKey(token)) {
				return TokenType.RequestToken;
			} else if (this.accessTokens.Contains(token)) {
				return TokenType.AccessToken;
			} else {
				return TokenType.InvalidToken;
			}
		}

		#endregion

		#region IServiceProviderTokenManager Members

		public IConsumerDescription GetConsumer(string consumerKey) {
			return this.consumers[consumerKey];
		}

		public IServiceProviderRequestToken GetRequestToken(string token) {
			return this.tokens[token];
		}

		public IServiceProviderAccessToken GetAccessToken(string token) {
			return this.tokens[token];
		}

		public void UpdateToken(IServiceProviderRequestToken token) {
			// Nothing to do here, since we're using Linq To SQL.
		}

		#endregion

		/// <summary>
		/// Tells a Service Provider's token manager about a consumer and its secret
		/// so that the SP can verify the Consumer's signed messages.
		/// </summary>
		/// <param name="consumerDescription">The consumer description.</param>
		internal void AddConsumer(ConsumerDescription consumerDescription) {
			this.consumers.Add(new ConsumerInfo { Key = consumerDescription.ConsumerKey, Secret = consumerDescription.ConsumerSecret });
		}

		/// <summary>
		/// Marks an existing token as authorized.
		/// </summary>
		/// <param name="requestToken">The request token.</param>
		internal void AuthorizeRequestToken(string requestToken) {
			if (requestToken == null) {
				throw new ArgumentNullException("requestToken");
			}

			this.requestTokens[requestToken] = true;
		}

		private class TokenInfo : IServiceProviderRequestToken, IServiceProviderAccessToken {
			internal TokenInfo() {
				this.CreatedOn = DateTime.Now;
			}

			public string ConsumerKey { get; set; }

			public DateTime CreatedOn { get; set; }

			public string Token { get; set; }

			public string VerificationCode { get; set; }

			public Uri Callback { get; set; }

			public Version ConsumerVersion { get; set; }

			public string Username { get; set; }

			public string[] Roles { get; set; }

			public DateTime? ExpirationDate { get; set; }

			internal string Secret { get; set; }
		}

		private class ConsumerInfo : IConsumerDescription {
			#region IConsumerDescription Members

			public string Key { get; set; }

			public string Secret { get; set; }

			public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get; set; }

			public Uri Callback { get; set; }

			public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat { get; set; }

			public int VerificationCodeLength { get; set; }

			#endregion
		}
	}
}