@@ -18,6 +18,7 @@ use std::slice::Iter;
18
18
19
19
pub mod user {
20
20
use super :: * ;
21
+ use crate :: dto:: { OAuthResponse , SignInWithIdpRequest } ;
21
22
use credentials:: Credentials ;
22
23
23
24
#[ inline]
@@ -33,6 +34,36 @@ pub mod user {
33
34
format ! ( "https://securetoken.googleapis.com/v1/token?key={}" , v)
34
35
}
35
36
37
+ /// Default OAuth2 Providers supported by Firebase.
38
+ /// see: * https://firebase.google.com/docs/projects/provisioning/configure-oauth?hl=en#add-idp
39
+ pub enum OAuth2Provider {
40
+ Apple ,
41
+ AppleGameCenter ,
42
+ Facebook ,
43
+ GitHub ,
44
+ Google ,
45
+ GooglePlayGames ,
46
+ LinkedIn ,
47
+ Microsoft ,
48
+ Twitter ,
49
+ Yahoo ,
50
+ }
51
+
52
+ fn get_provider ( provider : OAuth2Provider ) -> String {
53
+ match provider {
54
+ OAuth2Provider :: Apple => "apple.com" . to_string ( ) ,
55
+ OAuth2Provider :: AppleGameCenter => "gc.apple.com" . to_string ( ) ,
56
+ OAuth2Provider :: Facebook => "facebook.com" . to_string ( ) ,
57
+ OAuth2Provider :: GitHub => "github.com" . to_string ( ) ,
58
+ OAuth2Provider :: Google => "google.com" . to_string ( ) ,
59
+ OAuth2Provider :: GooglePlayGames => "playgames.google.com" . to_string ( ) ,
60
+ OAuth2Provider :: LinkedIn => "linkedin.com" . to_string ( ) ,
61
+ OAuth2Provider :: Microsoft => "microsoft.com" . to_string ( ) ,
62
+ OAuth2Provider :: Twitter => "twitter.com" . to_string ( ) ,
63
+ OAuth2Provider :: Yahoo => "yahoo.com" . to_string ( ) ,
64
+ }
65
+ }
66
+
36
67
/// An impersonated session.
37
68
/// Firestore rules will restrict your access.
38
69
pub struct Session {
@@ -281,6 +312,46 @@ pub mod user {
281
312
client_async : reqwest:: Client :: new ( ) ,
282
313
} )
283
314
}
315
+
316
+ /// Creates a new user session with OAuth2 provider token.
317
+ /// If user don't exist it's create new user in firestore
318
+ ///
319
+ /// Arguments:
320
+ /// - `credentials` The credentials.
321
+ /// - `access_token` access_token provided by OAuth2 provider.
322
+ /// - `request_uri` The URI to which the provider redirects the user back same as from .
323
+ /// - `provider` OAuth2Provider enum: Apple, AppleGameCenter, Facebook, GitHub, Google, GooglePlayGames, LinkedIn, Microsoft, Twitter, Yahoo.
324
+ /// - `with_refresh_token` A refresh token is returned as well. This should be persisted somewhere for later reuse.
325
+ /// Google generates only a few dozens of refresh tokens before it starts to invalidate already generated ones.
326
+ /// For short lived, immutable, non-persisting services you do not want a refresh token.
327
+ ///
328
+ pub fn by_oauth2 (
329
+ credentials : & Credentials ,
330
+ access_token : String ,
331
+ provider : OAuth2Provider ,
332
+ request_uri : String ,
333
+ with_refresh_token : bool ,
334
+ ) -> Result < Session , FirebaseError > {
335
+ let uri = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=" . to_owned ( )
336
+ + & credentials. api_key ;
337
+
338
+ let post_body = format ! ( "access_token={}&providerId={}" , access_token, get_provider( provider) ) ;
339
+ let return_idp_credential = true ;
340
+ let return_secure_token = true ;
341
+
342
+ let json = & SignInWithIdpRequest {
343
+ post_body,
344
+ request_uri,
345
+ return_idp_credential,
346
+ return_secure_token,
347
+ } ;
348
+
349
+ let response = reqwest:: blocking:: Client :: new ( ) . post ( & uri) . json ( & json) . send ( ) ?;
350
+
351
+ let oauth_response: OAuthResponse = response. json ( ) ?;
352
+
353
+ self :: Session :: by_user_id ( & credentials, & oauth_response. local_id , with_refresh_token)
354
+ }
284
355
}
285
356
}
286
357
0 commit comments