Added StandardProviderApplicationStore and several OpenIdProvider unit tests.
[dotnetoauth.git] / src / DotNetOpenAuth / OpenId / AssociationMemoryStore.cs
blobf02245934dc46f15d66a1276b3adc89900abe108
1 //-----------------------------------------------------------------------
2 // <copyright file="AssociationMemoryStore.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
4 // </copyright>
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth.OpenId {
8 using System.Collections.Generic;
10 /// <summary>
11 /// Manages a set of associations in memory only (no database).
12 /// </summary>
13 /// <typeparam name="TKey">The type of the key.</typeparam>
14 /// <remarks>
15 /// This class should be used for low-to-medium traffic relying party sites that can afford to lose associations
16 /// if the app pool was ever restarted. High traffic relying parties and providers should write their own
17 /// implementation of <see cref="IAssociationStore&lt;TKey&gt;"/> that works against their own database schema
18 /// to allow for persistance and recall of associations across servers in a web farm and server restarts.
19 /// </remarks>
20 internal class AssociationMemoryStore<TKey> : IAssociationStore<TKey> {
21 /// <summary>
22 /// For Relying Parties, this maps OP Endpoints to a set of associations with that endpoint.
23 /// For Providers, this keeps smart and dumb associations in two distinct pools.
24 /// </summary>
25 private Dictionary<TKey, Associations> serverAssocsTable = new Dictionary<TKey, Associations>();
27 /// <summary>
28 /// Stores a given association for later recall.
29 /// </summary>
30 /// <param name="distinguishingFactor">The distinguishing factor, either an OP Endpoint or smart/dumb mode.</param>
31 /// <param name="association">The association to store.</param>
32 public void StoreAssociation(TKey distinguishingFactor, Association association) {
33 lock (this) {
34 if (!this.serverAssocsTable.ContainsKey(distinguishingFactor)) {
35 this.serverAssocsTable.Add(distinguishingFactor, new Associations());
37 Associations server_assocs = this.serverAssocsTable[distinguishingFactor];
39 server_assocs.Set(association);
43 /// <summary>
44 /// Gets the best association (the one with the longest remaining life) for a given key.
45 /// </summary>
46 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
47 /// <returns>
48 /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key.
49 /// </returns>
50 public Association GetAssociation(TKey distinguishingFactor) {
51 lock (this) {
52 return this.GetServerAssociations(distinguishingFactor).Best;
56 /// <summary>
57 /// Gets the association for a given key and handle.
58 /// </summary>
59 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
60 /// <param name="handle">The handle of the specific association that must be recalled.</param>
61 /// <returns>
62 /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle.
63 /// </returns>
64 public Association GetAssociation(TKey distinguishingFactor, string handle) {
65 lock (this) {
66 return this.GetServerAssociations(distinguishingFactor).Get(handle);
70 /// <summary>
71 /// Removes a specified handle that may exist in the store.
72 /// </summary>
73 /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
74 /// <param name="handle">The handle of the specific association that must be deleted.</param>
75 /// <returns>
76 /// True if the association existed in this store previous to this call.
77 /// </returns>
78 /// <remarks>
79 /// No exception should be thrown if the association does not exist in the store
80 /// before this call.
81 /// </remarks>
82 public bool RemoveAssociation(TKey distinguishingFactor, string handle) {
83 lock (this) {
84 return this.GetServerAssociations(distinguishingFactor).Remove(handle);
88 /// <summary>
89 /// Clears all expired associations from the store.
90 /// </summary>
91 public void ClearExpiredAssociations() {
92 lock (this) {
93 foreach (Associations assocs in this.serverAssocsTable.Values) {
94 assocs.ClearExpired();
99 /// <summary>
100 /// Gets the server associations for a given OP Endpoint or dumb/smart mode.
101 /// </summary>
102 /// <param name="distinguishingFactor">The distinguishing factor, either an OP Endpoint (for relying parties) or smart/dumb (for providers).</param>
103 /// <returns>The collection of associations that fit the <paramref name="distinguishingFactor"/>.</returns>
104 internal Associations GetServerAssociations(TKey distinguishingFactor) {
105 lock (this) {
106 if (!this.serverAssocsTable.ContainsKey(distinguishingFactor)) {
107 this.serverAssocsTable.Add(distinguishingFactor, new Associations());
110 return this.serverAssocsTable[distinguishingFactor];