We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: A C# implementation of the OpenID Authentication protocol
Homepage: http://dotnetopenid.googlecode.com
Clone URL: git://github.com/AArnott/dotnetopenid.git
More refactoring...

 * Renamed ServerAssocs to Associations
 * Removed ISessionState members: this[int] and Count.
 * Gave the Provider two different secret key lifetimes: one for dumb and 
 one for smart consumers
 * Changed up the IAssociationStore to store by smart/dumb as well as by 
 serverUri.
 * Dumb/Smart clients are now distinguished by a descriptive enum instead 
 of just a 'bool dumb'
 * Added Excel document documenting some common OpenId workflows.


git-svn-id: https://dotnetopenid.googlecode.com/svn/trunk@156 
01efa1a6-402a-0410-b0ae-47b76eba00f0
AArnott (author)
Sun Feb 17 08:17:46 -0800 2008
commit  2ca40f76d79a4613ddcd090aa59a6bf634a9fc89
tree    624ec32412aa588e77884ca43a19a8073940a2be
parent  9219d2c0c4a37caba44432c181bd20f1d7fd727a
...
9
10
11
12
 
13
14
15
 
16
17
18
...
9
10
11
 
12
13
14
 
15
16
17
18
0
@@ -9,10 +9,10 @@ namespace DotNetOpenId.Test {
0
   [TestFixture]
0
   public class ServerAssocsTest {
0
 
0
- ServerAssocs assocs;
0
+ Associations assocs;
0
     [SetUp]
0
     public void SetUp() {
0
- assocs = new ServerAssocs();
0
+ assocs = new Associations();
0
     }
0
 
0
     [Test]
...
8
9
10
 
 
11
12
13
...
85
86
87
88
 
89
90
91
...
124
125
126
127
 
128
129
130
131
132
 
133
134
135
136
137
 
 
138
139
140
...
8
9
10
11
12
13
14
15
...
87
88
89
 
90
91
92
93
...
126
127
128
 
129
130
131
132
133
 
134
135
136
137
 
 
138
139
140
141
142
0
@@ -8,6 +8,8 @@ namespace DotNetOpenId.Consumer
0
   using DotNetOpenId.Session;
0
   using System.Web;
0
   using System.Collections.Generic;
0
+ using IConsumerAssociationStore = DotNetOpenId.Store.IAssociationStore<System.Uri>;
0
+ using ConsumerMemoryStore = DotNetOpenId.Store.AssociationMemoryStore<System.Uri>;
0
 
0
   public class FailureException : ApplicationException
0
   {
0
@@ -85,7 +87,7 @@ namespace DotNetOpenId.Consumer
0
     /// <summary>
0
     /// Constructs an OpenId consumer that uses a given IAssociationStore.
0
     /// </summary>
0
- public Consumer(ISessionState session, IAssociationStore store)
0
+ public Consumer(ISessionState session, IConsumerAssociationStore store)
0
     {
0
       this.session = session;
0
       this.manager = new ServiceEndpointManager(session);
0
@@ -124,17 +126,17 @@ namespace DotNetOpenId.Consumer
0
     }
0
 
0
     const string associationStoreKey = "DotNetOpenId.Consumer.Consumer.AssociationStore";
0
- static IAssociationStore HttpApplicationAssociationStore {
0
+ static IConsumerAssociationStore HttpApplicationAssociationStore {
0
       get {
0
         HttpContext context = HttpContext.Current;
0
         if (context == null)
0
           throw new InvalidOperationException(Strings.IAssociationStoreRequiredWhenNoHttpContextAvailable);
0
- IAssociationStore store = (IAssociationStore)context.Application[associationStoreKey];
0
+ var store = (IConsumerAssociationStore)context.Application[associationStoreKey];
0
         if (store == null) {
0
           context.Application.Lock();
0
           try {
0
- if ((store = (IAssociationStore)context.Application[associationStoreKey]) == null) {
0
- context.Application[associationStoreKey] = store = new MemoryStore();
0
+ if ((store = (IConsumerAssociationStore)context.Application[associationStoreKey]) == null) {
0
+ context.Application[associationStoreKey] = store = new ConsumerMemoryStore();
0
             }
0
           } finally {
0
             context.Application.UnLock();
...
12
13
14
 
15
16
17
18
19
20
21
 
 
22
23
 
24
25
26
...
284
285
286
287
288
289
290
291
292
...
12
13
14
15
16
17
18
19
20
 
 
21
22
23
 
24
25
26
27
...
285
286
287
 
 
 
288
289
290
0
@@ -12,15 +12,16 @@ namespace DotNetOpenId.Consumer
0
   using DotNetOpenId.Store;
0
   using System.Web;
0
   using System.IO;
0
+ using IConsumerAssociationStore = DotNetOpenId.Store.IAssociationStore<System.Uri>;
0
 
0
   internal class GenericConsumer
0
   {
0
     static readonly TimeSpan minimumUsefulAssociationLifetime = TimeSpan.FromSeconds(120);
0
 
0
- private IAssociationStore store;
0
- private Fetcher fetcher;
0
+ IConsumerAssociationStore store;
0
+ Fetcher fetcher;
0
 
0
- public GenericConsumer(IAssociationStore store, Fetcher fetcher)
0
+ public GenericConsumer(IConsumerAssociationStore store, Fetcher fetcher)
0
     {
0
       this.store = store;
0
       this.fetcher = fetcher;
0
@@ -284,9 +285,6 @@ namespace DotNetOpenId.Consumer
0
 
0
     private Association GetAssociation(Uri server_url)
0
     {
0
- if (store.IsDumb)
0
- return null;
0
-
0
       Association assoc = store.GetAssociation(server_url);
0
 
0
       if (assoc == null || assoc.SecondsTillExpiration < minimumUsefulAssociationLifetime.TotalSeconds)
...
141
142
143
144
 
145
...
141
142
143
 
144
145
0
@@ -141,4 +141,4 @@
0
   <Target Name="AfterBuild">
0
   </Target>
0
   -->
0
-</Project>
0
+</Project>
0
\ No newline at end of file
...
1
2
3
 
4
5
6
7
8
9
10
 
11
12
13
...
41
42
43
44
 
45
46
47
...
82
83
84
85
 
86
87
88
...
1
2
3
4
5
6
7
8
9
10
 
11
12
13
14
...
42
43
44
 
45
46
47
48
...
83
84
85
 
86
87
88
89
0
@@ -1,13 +1,14 @@
0
 using System;
0
 using System.Collections.Specialized;
0
 using System.Text;
0
+using DotNetOpenId.Store;
0
 
0
 namespace DotNetOpenId.Provider {
0
   /// <summary>
0
   /// A request to establish an association.
0
   /// </summary>
0
   internal class AssociateRequest : Request {
0
- string associationType = QueryStringArgs.HMAC_SHA1;
0
+ string associationKeyType = QueryStringArgs.HMAC_SHA1;
0
     ServerSession session;
0
 
0
     public AssociateRequest(Server server, NameValueCollection query)
0
@@ -41,7 +42,7 @@ namespace DotNetOpenId.Provider {
0
     /// Respond to this request with an association.
0
     /// </summary>
0
     public Response Answer() {
0
- Association assoc = Server.Signatory.CreateAssociation(false);
0
+ Association assoc = Server.Signatory.CreateAssociation(AssociationConsumerType.Smart);
0
       #region Trace
0
       if (TraceUtil.Switch.TraceInfo) {
0
         TraceUtil.ServerTrace("Start processing response for AssociateRequest");
0
@@ -82,7 +83,7 @@ namespace DotNetOpenId.Provider {
0
 
0
     public override string ToString() {
0
       string returnString = "AssociateRequest._assoc_type = {0}";
0
- return base.ToString() + Environment.NewLine + String.Format(returnString, associationType);
0
+ return base.ToString() + Environment.NewLine + String.Format(returnString, associationKeyType);
0
     }
0
 
0
   }
...
3
4
5
 
6
7
8
...
52
53
54
55
 
56
57
58
59
60
61
62
 
63
64
65
...
3
4
5
6
7
8
9
...
53
54
55
 
56
57
58
59
60
61
62
 
63
64
65
66
0
@@ -3,6 +3,7 @@ using System.Collections;
0
 using System.Collections.Specialized;
0
 using System.Text;
0
 using System.Collections.Generic;
0
+using DotNetOpenId.Store;
0
 
0
 namespace DotNetOpenId.Provider {
0
   /// <summary>
0
@@ -52,14 +53,14 @@ namespace DotNetOpenId.Provider {
0
 
0
       bool is_valid = Server.Signatory.Verify(AssociationHandle, signature, signedFields);
0
 
0
- Server.Signatory.Invalidate(AssociationHandle, true);
0
+ Server.Signatory.Invalidate(AssociationHandle, AssociationConsumerType.Dumb);
0
 
0
       Response response = new Response(this);
0
 
0
       response.Fields[QueryStringArgs.openidnp.is_valid] = (is_valid ? "true" : "false");
0
 
0
       if (!string.IsNullOrEmpty(invalidate_handle)) {
0
- Association assoc = Server.Signatory.GetAssociation(invalidate_handle, false);
0
+ Association assoc = Server.Signatory.GetAssociation(invalidate_handle, AssociationConsumerType.Smart);
0
 
0
         if (assoc == null) {
0
           #region Trace
...
3
4
5
6
 
 
7
8
9
10
11
12
13
 
14
15
16
...
23
24
25
26
 
27
28
29
...
143
144
145
146
 
147
148
149
150
151
 
152
153
154
155
156
 
 
157
158
159
...
3
4
5
 
6
7
8
9
10
11
12
13
 
14
15
16
17
...
24
25
26
 
27
28
29
30
...
144
145
146
 
147
148
149
150
151
 
152
153
154
155
 
 
156
157
158
159
160
0
@@ -3,14 +3,15 @@ using System.Collections.Specialized;
0
 using System.Text;
0
 using DotNetOpenId.Store;
0
 using System.Web;
0
-
0
+using IProviderAssociationStore = DotNetOpenId.Store.IAssociationStore<DotNetOpenId.Store.AssociationConsumerType>;
0
+using ProviderMemoryStore = DotNetOpenId.Store.AssociationMemoryStore<DotNetOpenId.Store.AssociationConsumerType>;
0
 
0
 namespace DotNetOpenId.Provider {
0
   /// <summary>
0
   /// Offers services for a web page that is acting as an OpenID identity server.
0
   /// </summary>
0
   public class Server {
0
- IAssociationStore store;
0
+ IProviderAssociationStore store;
0
     internal Signatory Signatory { get; private set; }
0
     Encoder encoder;
0
 
0
@@ -23,7 +24,7 @@ namespace DotNetOpenId.Provider {
0
     /// <summary>
0
     /// Constructs an OpenId server that uses a given IAssociationStore.
0
     /// </summary>
0
- public Server(IAssociationStore store) {
0
+ public Server(IProviderAssociationStore store) {
0
       if (store == null) throw new ArgumentNullException("store");
0
       this.store = store;
0
       Signatory = new Signatory(store);
0
@@ -143,17 +144,17 @@ namespace DotNetOpenId.Provider {
0
     }
0
 
0
     const string associationStoreKey = "DotNetOpenId.Provider.Server.AssociationStore";
0
- static IAssociationStore httpApplicationAssociationStore {
0
+ static IProviderAssociationStore httpApplicationAssociationStore {
0
       get {
0
         HttpContext context = HttpContext.Current;
0
         if (context == null)
0
           throw new InvalidOperationException(Strings.IAssociationStoreRequiredWhenNoHttpContextAvailable);
0
- IAssociationStore store = (IAssociationStore)context.Application[associationStoreKey];
0
+ var store = (IProviderAssociationStore)context.Application[associationStoreKey];
0
         if (store == null) {
0
           context.Application.Lock();
0
           try {
0
- if ((store = (IAssociationStore)context.Application[associationStoreKey]) == null) {
0
- context.Application[associationStoreKey] = store = new MemoryStore();
0
+ if ((store = (IProviderAssociationStore)context.Application[associationStoreKey]) == null) {
0
+ context.Application[associationStoreKey] = store = new ProviderMemoryStore();
0
             }
0
           } finally {
0
             context.Application.UnLock();
...
5
6
7
 
8
9
10
11
12
13
14
15
16
17
18
19
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
22
23
...
35
36
37
38
 
39
40
41
...
45
46
47
48
 
49
50
51
...
54
55
56
57
 
58
59
60
...
79
80
81
82
 
83
84
85
...
126
127
128
129
 
130
131
 
 
132
133
134
...
147
148
149
150
 
 
151
152
153
 
154
155
156
 
157
158
159
160
161
162
 
163
164
165
...
168
169
170
171
172
 
173
174
175
 
176
177
178
...
183
184
185
186
 
187
188
189
190
191
192
 
193
194
195
...
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
...
44
45
46
 
47
48
49
50
...
54
55
56
 
57
58
59
60
...
63
64
65
 
66
67
68
69
...
88
89
90
 
91
92
93
94
...
135
136
137
 
138
139
 
140
141
142
143
144
...
157
158
159
 
160
161
162
 
 
163
164
165
 
166
167
168
169
170
171
 
172
173
174
175
...
178
179
180
 
 
181
182
183
 
184
185
186
187
...
192
193
194
 
195
196
197
198
199
 
 
200
201
202
203
0
@@ -5,19 +5,28 @@ using System.Text;
0
 using System.Security.Cryptography;
0
 using DotNetOpenId.Store;
0
 using System.Collections.Generic;
0
+using IProviderAssociationStore = DotNetOpenId.Store.IAssociationStore<DotNetOpenId.Store.AssociationConsumerType>;
0
 
0
 namespace DotNetOpenId.Provider {
0
   /// <summary>
0
   /// Signs things.
0
   /// </summary>
0
   internal class Signatory {
0
- static readonly TimeSpan associationLifetime = TimeSpan.FromDays(14);
0
-
0
- static readonly Uri _normal_key = new Uri("http://localhost/|normal");
0
- static readonly Uri _dumb_key = new Uri("http://localhost/|dumb");
0
- IAssociationStore store;
0
-
0
- public Signatory(IAssociationStore store) {
0
+ /// <summary>
0
+ /// The duration any association and secret key the Provider generates will be good for.
0
+ /// </summary>
0
+ static readonly TimeSpan smartAssociationLifetime = TimeSpan.FromDays(14);
0
+ /// <summary>
0
+ /// The duration a secret key used for signing dumb client requests will be good for.
0
+ /// </summary>
0
+ static readonly TimeSpan dumbSecretLifetime = TimeSpan.FromMinutes(5);
0
+
0
+ /// <summary>
0
+ /// The store for shared secrets.
0
+ /// </summary>
0
+ IProviderAssociationStore store;
0
+
0
+ public Signatory(IProviderAssociationStore store) {
0
       if (store == null)
0
         throw new ArgumentNullException("store");
0
 
0
@@ -35,7 +44,7 @@ namespace DotNetOpenId.Provider {
0
       string assoc_handle = ((AssociatedRequest)response.Request).AssociationHandle;
0
 
0
       if (!string.IsNullOrEmpty(assoc_handle)) {
0
- assoc = this.GetAssociation(assoc_handle, false);
0
+ assoc = this.GetAssociation(assoc_handle, AssociationConsumerType.Smart);
0
 
0
         if (assoc == null) {
0
           #region Trace
0
@@ -45,7 +54,7 @@ namespace DotNetOpenId.Provider {
0
           #endregion
0
 
0
           response.Fields[QueryStringArgs.openidnp.invalidate_handle] = assoc_handle;
0
- assoc = this.CreateAssociation(true);
0
+ assoc = this.CreateAssociation(AssociationConsumerType.Dumb);
0
         } else {
0
           #region Trace
0
           if (TraceUtil.Switch.TraceInfo) {
0
@@ -54,7 +63,7 @@ namespace DotNetOpenId.Provider {
0
           #endregion
0
         }
0
       } else {
0
- assoc = this.CreateAssociation(true);
0
+ assoc = this.CreateAssociation(AssociationConsumerType.Dumb);
0
         TraceUtil.ServerTrace(String.Format("No assoc_handle supplied. Creating new association."));
0
       }
0
 
0
@@ -79,7 +88,7 @@ namespace DotNetOpenId.Provider {
0
       }
0
       #endregion
0
 
0
- Association assoc = this.GetAssociation(assoc_handle, true);
0
+ Association assoc = this.GetAssociation(assoc_handle, AssociationConsumerType.Dumb);
0
 
0
       string expected_sig;
0
 
0
@@ -126,9 +135,10 @@ namespace DotNetOpenId.Provider {
0
       return expected_sig.Equals(signature, StringComparison.OrdinalIgnoreCase);
0
     }
0
 
0
- public virtual Association CreateAssociation(bool dumb) {
0
+ public virtual Association CreateAssociation(AssociationConsumerType associationType) {
0
       if (TraceUtil.Switch.TraceInfo) {
0
- TraceUtil.ServerTrace(String.Format("Start Create Association. InDumbMode = {0}", dumb));
0
+ TraceUtil.ServerTrace(String.Format("Start Create Association. Association type = {0}",
0
+ associationType));
0
       }
0
 
0
       RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider();
0
@@ -147,19 +157,19 @@ namespace DotNetOpenId.Provider {
0
 
0
       handle = "{{HMAC-SHA1}{" + seconds + "}{" + uniq + "}";
0
 
0
- assoc = new HmacSha1Association(handle, secret, associationLifetime);
0
+ assoc = new HmacSha1Association(handle, secret,
0
+ associationType == AssociationConsumerType.Dumb ? dumbSecretLifetime : smartAssociationLifetime);
0
 
0
- Uri key = dumb ? _dumb_key : _normal_key;
0
- store.StoreAssociation(key, assoc);
0
+ store.StoreAssociation(associationType, assoc);
0
 
0
       if (TraceUtil.Switch.TraceInfo) {
0
- TraceUtil.ServerTrace(String.Format("End Create Association. Association successfully created. key = '{0}', handle = '{1}' ", key, handle));
0
+ TraceUtil.ServerTrace(String.Format("End Create Association. Association successfully created. key = '{0}', handle = '{1}' ", associationType, handle));
0
       }
0
 
0
       return assoc;
0
     }
0
 
0
- public virtual Association GetAssociation(string assoc_handle, bool dumb) {
0
+ public virtual Association GetAssociation(string assoc_handle, AssociationConsumerType associationType) {
0
       if (TraceUtil.Switch.TraceInfo) {
0
         TraceUtil.ServerTrace(String.Format("Start get association from store '{0}'.", assoc_handle));
0
       }
0
@@ -168,11 +178,10 @@ namespace DotNetOpenId.Provider {
0
       if (assoc_handle == null)
0
         throw new ArgumentNullException(QueryStringArgs.openidnp.assoc_handle);
0
 
0
- Uri key = dumb ? _dumb_key : _normal_key;
0
- Association assoc = store.GetAssociation(key, assoc_handle);
0
+ Association assoc = store.GetAssociation(associationType, assoc_handle);
0
       if (assoc == null || assoc.IsExpired) {
0
         TraceUtil.ServerTrace("Association expired or not in store. Trying to remove association if it still exists.");
0
- store.RemoveAssociation(key, assoc_handle);
0
+ store.RemoveAssociation(associationType, assoc_handle);
0
         assoc = null;
0
       }
0
 
0
@@ -183,13 +192,12 @@ namespace DotNetOpenId.Provider {
0
       return assoc;
0
     }
0
 
0
- public virtual void Invalidate(string assoc_handle, bool dumb) {
0
+ public virtual void Invalidate(string assoc_handle, AssociationConsumerType associationType) {
0
       if (TraceUtil.Switch.TraceInfo) {
0
         TraceUtil.ServerTrace(String.Format("Start invalidate association '{0}'.", assoc_handle));
0
       }
0
 
0
- Uri key = dumb ? _dumb_key : _normal_key;
0
- store.RemoveAssociation(key, assoc_handle);
0
+ store.RemoveAssociation(associationType, assoc_handle);
0
 
0
       if (TraceUtil.Switch.TraceInfo) {
0
         TraceUtil.ServerTrace(String.Format("End invalidate association '{0}'.", assoc_handle));
...
7
8
9
10
11
12
13
14
15
16
17
18
...
33
34
35
36
37
38
39
40
41
42
...
7
8
9
 
 
 
 
 
 
10
11
12
...
27
28
29
 
 
 
 
 
30
31
0
@@ -7,12 +7,6 @@ namespace DotNetOpenId.Session
0
     public interface ISessionState
0
     {
0
         /// <summary>
0
- /// Gets or sets a session value by numerical index.
0
- /// </summary>
0
- /// <param name="index">The numerical index of the session value.</param>
0
- /// <returns>The session-state value stored at the specified index.</returns>
0
- object this[int index] { get; set; }
0
- /// <summary>
0
         /// Gets or sets a session value by name.
0
         /// </summary>
0
         /// <param name="name">The key name of the session value.</param>
0
@@ -33,10 +27,5 @@ namespace DotNetOpenId.Session
0
         /// </summary>
0
         /// <param name="name">The name of the item to delete from the session-state collection.</param>
0
         void Remove(string name);
0
- /// <summary>
0
- /// Gets the number of items in the session-state collection.
0
- /// </summary>
0
- /// <value>The number of items in the collection.</value>
0
- int Count { get; }
0
     }
0
 }
...
21
22
23
24
25
26
27
28
...
21
22
23
 
 
24
25
26
0
@@ -21,8 +21,6 @@ namespace DotNetOpenId.Session
0
             return local_instance;
0
         }
0
 
0
- public int Count { get { return hashtable.Count; } }
0
- public object this[int index] { get { return hashtable[index]; } set { hashtable[index] = value; } }
0
         public object this[string index] { get { return hashtable[index]; } set { hashtable[index] = value; } }
0
         public void Add(string name, object value) { hashtable.Add(name, value); }
0
         public void Clear() { hashtable.Clear(); }
...
15
16
17
18
19
20
21
22
...
15
16
17
 
 
18
19
20
0
@@ -15,8 +15,6 @@ namespace DotNetOpenId.Session
0
             sessionstate = value;
0
         }
0
 
0
- public int Count { get { return sessionstate.Count; } }
0
- public object this[int index] { get { return sessionstate[index]; } set { sessionstate[index] = value; } }
0
         public object this[string index] { get { return sessionstate[index]; } set { sessionstate[index] = value; } }
0
         public void Add(string name, object value) { sessionstate.Add(name, value); }
0
         public void Clear() { sessionstate.Clear(); }
...
3
4
5
6
7
8
9
 
 
 
 
 
10
11
12
 
 
 
 
 
 
 
 
 
 
 
 
13
14
15
16
17
18
19
 
 
 
 
 
20
...
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
0
@@ -3,18 +3,28 @@ using System.Collections.Generic;
0
 using System.Text;
0
 using DotNetOpenId;
0
 
0
-namespace DotNetOpenId.Store
0
-{
0
- public interface IAssociationStore
0
- {
0
+namespace DotNetOpenId.Store {
0
+ public enum AssociationConsumerType {
0
+ Smart,
0
+ Dumb
0
+ }
0
 
0
- byte[] AuthKey { get; }
0
- bool IsDumb { get; }
0
+ /// <summary>
0
+ /// Stores <see cref="Association"/>s for lookup by their handle, keeping
0
+ /// associations separated by a given distinguishing factor (like which server the
0
+ /// association is with).
0
+ /// </summary>
0
+ /// <typeparam name="TKey">
0
+ /// <see cref="System.Uri"/> for consumers (to distinguish associations across servers) or
0
+ /// <see cref="AssociationType"/> for providers (to distingish dumb and smart client associaitons).
0
+ /// </typeparam>
0
+ public interface IAssociationStore<TKey> {
0
+ // TODO: is this only used by Consumers? Does it relate to association storage?
0
+ byte[] AuthKey { get; }
0
 
0
- void StoreAssociation(Uri serverUri, Association assoc);
0
- Association GetAssociation(Uri serverUri);
0
- Association GetAssociation(Uri serverUri, string handle);
0
- bool RemoveAssociation(Uri serverUri, string handle);
0
-
0
- }
0
+ void StoreAssociation(TKey distinguishingFactor, Association assoc);
0
+ Association GetAssociation(TKey distinguishingFactor);
0
+ Association GetAssociation(TKey distinguishingFactor, string handle);
0
+ bool RemoveAssociation(TKey distinguishingFactor, string handle);
0
+ }
0
 }
...
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
...
80
81
82
83
84
85
86
87
88
89
90
...
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
...
72
73
74
 
 
 
 
75
 
76
77
0
@@ -10,61 +10,53 @@ using DotNetOpenId;
0
 
0
 namespace DotNetOpenId.Store {
0
 
0
- internal class MemoryStore : IAssociationStore {
0
-
0
- #region Member Variables
0
-
0
- Dictionary<Uri, ServerAssocs> serverAssocsTable = new Dictionary<Uri, ServerAssocs>();
0
+ internal class AssociationMemoryStore<TKey> : IAssociationStore<TKey> {
0
+ Dictionary<TKey, Associations> serverAssocsTable = new Dictionary<TKey, Associations>();
0
     byte[] authKey;
0
 
0
- #endregion
0
-
0
- #region Methods
0
-
0
- internal ServerAssocs GetServerAssocs(Uri server_url) {
0
+ internal Associations GetServerAssocs(TKey distinguishingFactor) {
0
       lock (this) {
0
- if (!serverAssocsTable.ContainsKey(server_url)) {
0
- serverAssocsTable.Add(server_url, new ServerAssocs());
0
+
0
+ if (!serverAssocsTable.ContainsKey(distinguishingFactor)) {
0
+ serverAssocsTable.Add(distinguishingFactor, new Associations());
0
         }
0
 
0
- return serverAssocsTable[server_url];
0
+ return serverAssocsTable[distinguishingFactor];
0
       }
0
     }
0
 
0
- public void StoreAssociation(Uri server_url, Association assoc) {
0
+ public void StoreAssociation(TKey distinguishingFactor, Association assoc) {
0
       lock (this) {
0
- if (!serverAssocsTable.ContainsKey(server_url))
0
- serverAssocsTable.Add(server_url, new ServerAssocs());
0
+ if (!serverAssocsTable.ContainsKey(distinguishingFactor))
0
+ serverAssocsTable.Add(distinguishingFactor, new Associations());
0
 
0
- ServerAssocs server_assocs = serverAssocsTable[server_url];
0
+ Associations server_assocs = serverAssocsTable[distinguishingFactor];
0
 
0
         server_assocs.Set(assoc);
0
       }
0
     }
0
 
0
- public Association GetAssociation(Uri serverUri) {
0
+ public Association GetAssociation(TKey distinguishingFactor) {
0
       lock (this) {
0
- return GetServerAssocs(serverUri).Best;
0
+ return GetServerAssocs(distinguishingFactor).Best;
0
       }
0
     }
0
 
0
- public Association GetAssociation(Uri serverUri, string handle) {
0
+ public Association GetAssociation(TKey distinguishingFactor, string handle) {
0
       lock (this) {
0
- return GetServerAssocs(serverUri).Get(handle);
0
+ return GetServerAssocs(distinguishingFactor).Get(handle);
0
       }
0
     }
0
 
0
- public bool RemoveAssociation(Uri serverUri, string handle) {
0
+ public bool RemoveAssociation(TKey distinguishingFactor, string handle) {
0
       lock (this) {
0
- return GetServerAssocs(serverUri).Remove(handle);
0
+ return GetServerAssocs(distinguishingFactor).Remove(handle);
0
       }
0
     }
0
 
0
- #endregion
0
-
0
     #region IAssociationStore Members
0
 
0
- byte[] IAssociationStore.AuthKey {
0
+ byte[] IAssociationStore<TKey>.AuthKey {
0
       get {
0
         if (authKey == null) {
0
           lock (this) {
0
@@ -80,11 +72,6 @@ namespace DotNetOpenId.Store {
0
       }
0
     }
0
 
0
- bool IAssociationStore.IsDumb {
0
- get { return false; }
0
- }
0
-
0
     #endregion
0
-
0
   }
0
 }