55using System . Text . RegularExpressions ;
66using ServiceStack . Common ;
77using ServiceStack . Text ;
8- using ServiceStack . ServiceInterface . Auth ;
98
109using MongoDB . Bson ;
1110using MongoDB . Driver ;
1211using MongoDB . Driver . Builders ;
1312
14- namespace ServiceStack . Authentication . MongoDB
13+ namespace ServiceStack . ServiceInterface . Auth
1514{
1615 public class MongoDBAuthRepository : IUserAuthRepository , IClearable
1716 {
17+ // http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field
18+ class Counters
19+ {
20+ public int Id { get ; set ; }
21+ public int UserAuthCounter { get ; set ; }
22+ public int UserOAuthProviderCounter { get ; set ; }
23+ }
1824
1925 //http://stackoverflow.com/questions/3588623/c-sharp-regex-for-a-username-with-a-few-restrictions
2026 public Regex ValidUserNameRegEx = new Regex ( @"^(?=.{3,15}$)([A-Za-z0-9][._-]?)*$" , RegexOptions . Compiled ) ;
2127
2228 private readonly MongoDatabase mongoDatabase ;
2329
30+ // UserAuth collection name
31+ private static string UserAuth_Col
32+ {
33+ get
34+ {
35+ return typeof ( UserAuth ) . Name ;
36+ }
37+ }
38+ // UserOAuthProvider collection name
39+ private static string UserOAuthProvider_Col
40+ {
41+ get
42+ {
43+ return typeof ( UserOAuthProvider ) . Name ;
44+ }
45+ }
46+ // Counters collection name
47+ private static string Counters_Col
48+ {
49+ get
50+ {
51+ return typeof ( Counters ) . Name ;
52+ }
53+ }
54+
2455 public MongoDBAuthRepository ( MongoDatabase mongoDatabase )
2556 {
2657 this . mongoDatabase = mongoDatabase ;
2758 }
2859
2960 public void CreateMissingTables ( )
3061 {
31- if ( ! mongoDatabase . CollectionExists ( "UserAuth" ) )
32- mongoDatabase . CreateCollection ( "UserAuth" ) ;
62+ if ( ! mongoDatabase . CollectionExists ( UserAuth_Col ) )
63+ mongoDatabase . CreateCollection ( UserAuth_Col ) ;
3364
34- if ( ! mongoDatabase . CollectionExists ( "UserOAuthProvider" ) )
35- mongoDatabase . CreateCollection ( "UserOAuthProvider" ) ;
65+ if ( ! mongoDatabase . CollectionExists ( UserOAuthProvider_Col ) )
66+ mongoDatabase . CreateCollection ( UserOAuthProvider_Col ) ;
67+
68+ if ( ! mongoDatabase . CollectionExists ( Counters_Col ) )
69+ {
70+ mongoDatabase . CreateCollection ( Counters_Col ) ;
71+
72+ var CountersCollection = mongoDatabase . GetCollection < Counters > ( Counters_Col ) ;
73+ Counters counters = new Counters ( ) ;
74+ CountersCollection . Save ( counters ) ;
75+ }
3676 }
3777
3878 public void DropAndReCreateTables ( )
3979 {
40- if ( mongoDatabase . CollectionExists ( "UserAuth" ) )
41- mongoDatabase . DropCollection ( "UserAuth" ) ;
42- mongoDatabase . CreateCollection ( "UserAuth" ) ;
80+ if ( mongoDatabase . CollectionExists ( UserAuth_Col ) )
81+ mongoDatabase . DropCollection ( UserAuth_Col ) ;
82+
83+ if ( mongoDatabase . CollectionExists ( UserOAuthProvider_Col ) )
84+ mongoDatabase . DropCollection ( UserOAuthProvider_Col ) ;
4385
44- if ( mongoDatabase . CollectionExists ( "UserOAuthProvider" ) )
45- mongoDatabase . DropCollection ( "UserOAuthProvider" ) ;
46- mongoDatabase . CreateCollection ( "UserOAuthProvider" ) ;
86+ if ( mongoDatabase . CollectionExists ( Counters_Col ) )
87+ mongoDatabase . DropCollection ( Counters_Col ) ;
88+
89+ CreateMissingTables ( ) ;
4790 }
4891
4992 private void ValidateNewUser ( UserAuth newUser , string password )
@@ -61,6 +104,8 @@ private void ValidateNewUser(UserAuth newUser, string password)
61104 }
62105 }
63106
107+
108+
64109 public UserAuth CreateUserAuth ( UserAuth newUser , string password )
65110 {
66111 ValidateNewUser ( newUser , password ) ;
@@ -71,19 +116,45 @@ public UserAuth CreateUserAuth(UserAuth newUser, string password)
71116 string salt ;
72117 string hash ;
73118 saltedHash . GetHashAndSaltString ( password , out hash , out salt ) ;
74- var digestHelper = new DigestAuthFunctions ( ) ;
75- newUser . DigestHA1Hash = digestHelper . CreateHa1 ( newUser . UserName , DigestAuthProvider . Realm , password ) ;
119+ var digestHelper = new DigestAuthFunctions ( ) ;
120+ newUser . DigestHA1Hash = digestHelper . CreateHa1 ( newUser . UserName , DigestAuthProvider . Realm , password ) ;
76121 newUser . PasswordHash = hash ;
77122 newUser . Salt = salt ;
78123 newUser . CreatedDate = DateTime . UtcNow ;
79124 newUser . ModifiedDate = newUser . CreatedDate ;
80125
81- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
82- collection . Insert ( newUser ) ;
83- // todo - update id here
126+ SaveUser ( newUser ) ;
84127 return newUser ;
85128 }
86129
130+ private void SaveUser ( UserAuth userAuth )
131+ {
132+ if ( userAuth . Id == default ( int ) )
133+ userAuth . Id = IncUserAuthCounter ( ) ;
134+ var usersCollection = mongoDatabase . GetCollection < UserAuth > ( UserAuth_Col ) ;
135+ usersCollection . Save ( userAuth ) ;
136+ }
137+
138+ private int IncUserAuthCounter ( )
139+ {
140+ return IncCounter ( "UserAuthCounter" ) . UserAuthCounter ;
141+ }
142+
143+ private int IncUserOAuthProviderCounter ( )
144+ {
145+ return IncCounter ( "UserOAuthProviderCounter" ) . UserOAuthProviderCounter ;
146+ }
147+
148+
149+ private Counters IncCounter ( string counterName )
150+ {
151+ var CountersCollection = mongoDatabase . GetCollection < Counters > ( Counters_Col ) ;
152+ var incId = Update . Inc ( counterName , 1 ) ;
153+ var query = Query . Null ;
154+ FindAndModifyResult counterIncResult = CountersCollection . FindAndModify ( query , SortBy . Null , incId , true ) ;
155+ Counters updatedCounters = counterIncResult . GetModifiedDocumentAs < Counters > ( ) ;
156+ return updatedCounters ;
157+ }
87158 private static void AssertNoExistingUser ( MongoDatabase mongoDatabase , UserAuth newUser , UserAuth exceptForExistingUser = null )
88159 {
89160 if ( newUser . UserName != null )
@@ -110,27 +181,25 @@ public UserAuth UpdateUserAuth(UserAuth existingUser, UserAuth newUser, string p
110181
111182 var hash = existingUser . PasswordHash ;
112183 var salt = existingUser . Salt ;
113- if ( password != null )
184+ if ( password != null )
114185 {
115186 var saltedHash = new SaltedHash ( ) ;
116187 saltedHash . GetHashAndSaltString ( password , out hash , out salt ) ;
117188 }
118- // If either one changes the digest hash has to be recalculated
119- var digestHash = existingUser . DigestHA1Hash ;
120- if ( password != null || existingUser . UserName != newUser . UserName )
121- {
122- var digestHelper = new DigestAuthFunctions ( ) ;
123- digestHash = digestHelper . CreateHa1 ( newUser . UserName , DigestAuthProvider . Realm , password ) ;
124- }
189+ // If either one changes the digest hash has to be recalculated
190+ var digestHash = existingUser . DigestHA1Hash ;
191+ if ( password != null || existingUser . UserName != newUser . UserName )
192+ {
193+ var digestHelper = new DigestAuthFunctions ( ) ;
194+ digestHash = digestHelper . CreateHa1 ( newUser . UserName , DigestAuthProvider . Realm , password ) ;
195+ }
125196 newUser . Id = existingUser . Id ;
126197 newUser . PasswordHash = hash ;
127198 newUser . Salt = salt ;
128- newUser . DigestHA1Hash = digestHash ;
199+ newUser . DigestHA1Hash = digestHash ;
129200 newUser . CreatedDate = existingUser . CreatedDate ;
130201 newUser . ModifiedDate = DateTime . UtcNow ;
131-
132- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
133- collection . Insert ( newUser ) ;
202+ SaveUser ( newUser ) ;
134203
135204 return newUser ;
136205 }
@@ -143,11 +212,11 @@ public UserAuth GetUserAuthByUserName(string userNameOrEmail)
143212 private static UserAuth GetUserAuthByUserName ( MongoDatabase mongoDatabase , string userNameOrEmail )
144213 {
145214 var isEmail = userNameOrEmail . Contains ( "@" ) ;
146- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
215+ var collection = mongoDatabase . GetCollection < UserAuth > ( UserAuth_Col ) ;
147216
148217 QueryComplete query = isEmail
149218 ? Query . EQ ( "Email" , userNameOrEmail )
150- : Query . EQ ( "UserName" , userNameOrEmail ) ;
219+ : Query . EQ ( "UserName" , userNameOrEmail ) ;
151220
152221 UserAuth userAuth = collection . FindOne ( query ) ;
153222 return userAuth ;
@@ -169,21 +238,21 @@ public bool TryAuthenticate(string userName, string password, out UserAuth userA
169238 userAuth = null ;
170239 return false ;
171240 }
172- public bool TryAuthenticate ( Dictionary < string , string > digestHeaders , string PrivateKey , int NonceTimeOut , string sequence , out UserAuth userAuth )
173- {
174- //userId = null;
175- userAuth = GetUserAuthByUserName ( digestHeaders [ "username" ] ) ;
176- if ( userAuth == null ) return false ;
177-
178- var digestHelper = new DigestAuthFunctions ( ) ;
179- if ( digestHelper . ValidateResponse ( digestHeaders , PrivateKey , NonceTimeOut , userAuth . DigestHA1Hash , sequence ) )
180- {
181- //userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
182- return true ;
183- }
184- userAuth = null ;
185- return false ;
186- }
241+ public bool TryAuthenticate ( Dictionary < string , string > digestHeaders , string PrivateKey , int NonceTimeOut , string sequence , out UserAuth userAuth )
242+ {
243+ //userId = null;
244+ userAuth = GetUserAuthByUserName ( digestHeaders [ "username" ] ) ;
245+ if ( userAuth == null ) return false ;
246+
247+ var digestHelper = new DigestAuthFunctions ( ) ;
248+ if ( digestHelper . ValidateResponse ( digestHeaders , PrivateKey , NonceTimeOut , userAuth . DigestHA1Hash , sequence ) )
249+ {
250+ //userId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
251+ return true ;
252+ }
253+ userAuth = null ;
254+ return false ;
255+ }
187256
188257 public void LoadUserAuth ( IAuthSession session , IOAuthTokens tokens )
189258 {
@@ -198,15 +267,15 @@ private void LoadUserAuth(IAuthSession session, UserAuth userAuth)
198267 if ( userAuth == null ) return ;
199268
200269 session . PopulateWith ( userAuth ) ;
201- session . UserAuthId = userAuth . Id . ToString ( CultureInfo . InvariantCulture ) ;
202- session . ProviderOAuthAccess = GetUserOAuthProviders ( session . UserAuthId )
270+ session . UserAuthId = userAuth . Id . ToString ( CultureInfo . InvariantCulture ) ;
271+ session . ProviderOAuthAccess = GetUserOAuthProviders ( session . UserAuthId )
203272 . ConvertAll ( x => ( IOAuthTokens ) x ) ;
204-
273+
205274 }
206275
207276 public UserAuth GetUserAuth ( string userAuthId )
208277 {
209- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
278+ var collection = mongoDatabase . GetCollection < UserAuth > ( UserAuth_Col ) ;
210279 UserAuth userAuth = collection . FindOneById ( userAuthId ) ;
211280 return userAuth ;
212281 }
@@ -225,8 +294,8 @@ public void SaveUserAuth(IAuthSession authSession)
225294 if ( userAuth . CreatedDate == default ( DateTime ) )
226295 userAuth . CreatedDate = userAuth . ModifiedDate ;
227296
228- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
229- collection . Insert ( userAuth ) ;
297+ var collection = mongoDatabase . GetCollection < UserAuth > ( UserAuth_Col ) ;
298+ SaveUser ( userAuth ) ;
230299 }
231300
232301 public void SaveUserAuth ( UserAuth userAuth )
@@ -235,8 +304,7 @@ public void SaveUserAuth(UserAuth userAuth)
235304 if ( userAuth . CreatedDate == default ( DateTime ) )
236305 userAuth . CreatedDate = userAuth . ModifiedDate ;
237306
238- var collection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
239- collection . Insert ( userAuth ) ;
307+ SaveUser ( userAuth ) ;
240308 }
241309
242310 public List < UserOAuthProvider > GetUserOAuthProviders ( string userAuthId )
@@ -245,7 +313,7 @@ public List<UserOAuthProvider> GetUserOAuthProviders(string userAuthId)
245313
246314 QueryComplete query = Query . EQ ( "UserAuthId" , userAuthId ) ;
247315
248- var collection = mongoDatabase . GetCollection < UserOAuthProvider > ( "UserOAuthProvider" ) ;
316+ var collection = mongoDatabase . GetCollection < UserOAuthProvider > ( UserOAuthProvider_Col ) ;
249317 MongoCursor < UserOAuthProvider > queryResult = collection . Find ( query ) ;
250318 return queryResult . ToList ( ) ;
251319
@@ -272,13 +340,13 @@ public UserAuth GetUserAuth(IAuthSession authSession, IOAuthTokens tokens)
272340 Query . EQ ( "UserId" , tokens . UserId )
273341 ) ;
274342
275- var providerCollection = mongoDatabase . GetCollection < UserOAuthProvider > ( "UserOAuthProvider" ) ;
343+ var providerCollection = mongoDatabase . GetCollection < UserOAuthProvider > ( UserOAuthProvider_Col ) ;
276344 var oAuthProvider = providerCollection . FindOne ( query ) ;
277345
278346
279347 if ( oAuthProvider != null )
280348 {
281- var userAuthCollection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
349+ var userAuthCollection = mongoDatabase . GetCollection < UserAuth > ( UserAuth_Col ) ;
282350 var userAuth = userAuthCollection . FindOneById ( oAuthProvider . UserAuthId ) ;
283351 return userAuth ;
284352 }
@@ -292,13 +360,14 @@ public string CreateOrMergeAuthSession(IAuthSession authSession, IOAuthTokens to
292360 var query = Query . And (
293361 Query . EQ ( "Provider" , tokens . Provider ) ,
294362 Query . EQ ( "UserId" , tokens . UserId )
295- ) ;
296- var providerCollection = mongoDatabase . GetCollection < UserOAuthProvider > ( "UserOAuthProvider" ) ;
363+ ) ;
364+ var providerCollection = mongoDatabase . GetCollection < UserOAuthProvider > ( UserOAuthProvider_Col ) ;
297365 var oAuthProvider = providerCollection . FindOne ( query ) ;
298366
299367 if ( oAuthProvider == null )
300368 {
301- oAuthProvider = new UserOAuthProvider {
369+ oAuthProvider = new UserOAuthProvider
370+ {
302371 Provider = tokens . Provider ,
303372 UserId = tokens . UserId ,
304373 } ;
@@ -311,9 +380,10 @@ public string CreateOrMergeAuthSession(IAuthSession authSession, IOAuthTokens to
311380 if ( userAuth . CreatedDate == default ( DateTime ) )
312381 userAuth . CreatedDate = userAuth . ModifiedDate ;
313382
314- var userAuthCollection = mongoDatabase . GetCollection < UserAuth > ( "UserAuth" ) ;
383+ SaveUser ( userAuth ) ;
315384
316- userAuthCollection . Save ( userAuth ) ;
385+ if ( oAuthProvider . Id == default ( int ) )
386+ oAuthProvider . Id = IncUserOAuthProviderCounter ( ) ;
317387
318388 oAuthProvider . UserAuthId = userAuth . Id ;
319389
0 commit comments