44using System . Linq ;
55using System . Text ;
66using System . Threading . Tasks ;
7+ using System . Collections . Generic ;
78
89using System . Net ;
910using System . Net . NetworkInformation ;
1011
1112using UnityEngine ;
13+ using UnityEditor ;
1214
1315using Newtonsoft . Json . Linq ;
1416
@@ -45,15 +47,51 @@ public Future<GoogleSignInUser> SignIn()
4547 return new Future < GoogleSignInUser > ( this ) ;
4648 }
4749
48- public Future < GoogleSignInUser > SignInSilently ( )
50+ const string GoogleSignInCacheKey = "googleSignInCache" ;
51+ public void SignOut ( )
4952 {
50- SigningIn ( ) ;
51- return new Future < GoogleSignInUser > ( this ) ;
53+ SessionState . EraseString ( GoogleSignInCacheKey + "Code" ) ;
54+ SessionState . EraseString ( GoogleSignInCacheKey ) ;
55+ Debug . Log ( "No need on editor?" ) ;
5256 }
5357
54- public void SignOut ( )
58+ public Future < GoogleSignInUser > SignInSilently ( )
5559 {
56- Debug . Log ( "No need on editor?" ) ;
60+ Status = GoogleSignInStatusCode . SIGN_IN_REQUIRED ;
61+
62+ string authCode = SessionState . GetString ( GoogleSignInCacheKey + "Code" , null ) ;
63+ string json = SessionState . GetString ( GoogleSignInCacheKey , null ) ;
64+ if ( ! string . IsNullOrEmpty ( authCode ) && ! string . IsNullOrEmpty ( json ) )
65+ {
66+ Pending = true ;
67+ var taskScheduler = TaskScheduler . FromCurrentSynchronizationContext ( ) ;
68+ GetUserInfo ( configuration , authCode , json , taskScheduler ) . ContinueWith ( ( task ) => {
69+ try
70+ {
71+ Result = task . Result ;
72+ Status = GoogleSignInStatusCode . SUCCESS_CACHE ;
73+ }
74+ catch ( Exception e )
75+ {
76+ Status = GoogleSignInStatusCode . ERROR ;
77+
78+ Debug . LogException ( e ) ;
79+ if ( e is AggregateException ae )
80+ {
81+ foreach ( var inner in ae . InnerExceptions )
82+ Debug . LogException ( inner ) ;
83+ }
84+
85+ throw ;
86+ }
87+ finally
88+ {
89+ Pending = false ;
90+ }
91+ } ) ;
92+ }
93+ else Pending = false ;
94+ return new Future < GoogleSignInUser > ( this ) ;
5795 }
5896
5997 static HttpListener BindLocalHostFirstAvailablePort ( )
@@ -120,42 +158,12 @@ void SigningIn()
120158 context . Response . OutputStream . Write ( Encoding . UTF8 . GetBytes ( "Can close this page" ) ) ;
121159 context . Response . Close ( ) ;
122160
123- var jobj = await HttpWebRequest . CreateHttp ( "https://www.googleapis.com/oauth2/v4/token" ) . Post ( "application/x-www-form-urlencoded" , "code=" + code + "&client_id=" + configuration . WebClientId + "&client_secret=" + configuration . ClientSecret + "&redirect_uri=" + httpListener . Prefixes . FirstOrDefault ( ) + "&grant_type=authorization_code" ) . ContinueWith ( ( task ) => {
124- return JObject . Parse ( task . Result ) ;
125- } , taskScheduler ) ;
126-
127- var accessToken = ( string ) jobj . GetValue ( "access_token" ) ;
128- var expiresIn = ( int ) jobj . GetValue ( "expires_in" ) ;
129- var scope = ( string ) jobj . GetValue ( "scope" ) ;
130- var tokenType = ( string ) jobj . GetValue ( "token_type" ) ;
131-
132- var user = new GoogleSignInUser ( ) ;
133- if ( configuration . RequestAuthCode )
134- user . AuthCode = code ;
135-
136- if ( configuration . RequestIdToken )
137- user . IdToken = ( string ) jobj . GetValue ( "id_token" ) ;
138-
139- var request = HttpWebRequest . CreateHttp ( "https://openidconnect.googleapis.com/v1/userinfo" ) ;
140- request . Method = "GET" ;
141- request . Headers . Add ( "Authorization" , "Bearer " + accessToken ) ;
161+ string json = await HttpWebRequest . CreateHttp ( "https://www.googleapis.com/oauth2/v4/token" ) . Post ( "application/x-www-form-urlencoded" , "code=" + code + "&client_id=" + configuration . WebClientId + "&client_secret=" + configuration . ClientSecret + "&redirect_uri=" + httpListener . Prefixes . FirstOrDefault ( ) + "&grant_type=authorization_code" ) . ContinueWith ( ( task ) => task . Result , taskScheduler ) ;
142162
143- var data = await request . GetResponseAsStringAsync ( ) . ContinueWith ( ( task ) => task . Result , taskScheduler ) ;
144- var userInfo = JObject . Parse ( data ) ;
145- user . UserId = ( string ) userInfo . GetValue ( "sub" ) ;
146- user . DisplayName = ( string ) userInfo . GetValue ( "name" ) ;
163+ Result = await GetUserInfo ( configuration , code , json , taskScheduler ) ;
147164
148- if ( configuration . RequestEmail )
149- user . Email = ( string ) userInfo . GetValue ( "email" ) ;
150-
151- if ( configuration . RequestProfile )
152- {
153- user . GivenName = ( string ) userInfo . GetValue ( "given_name" ) ;
154- user . FamilyName = ( string ) userInfo . GetValue ( "family_name" ) ;
155- user . ImageUrl = Uri . TryCreate ( ( string ) userInfo . GetValue ( "picture" ) , UriKind . Absolute , out var url ) ? url : null ;
156- }
157-
158- Result = user ;
165+ SessionState . SetString ( GoogleSignInCacheKey , json ) ;
166+ SessionState . SetString ( GoogleSignInCacheKey + "Code" , json ) ;
159167
160168 Status = GoogleSignInStatusCode . SUCCESS ;
161169 }
@@ -178,7 +186,45 @@ void SigningIn()
178186 }
179187 } , taskScheduler ) ;
180188 }
181- }
189+
190+ static async Task < GoogleSignInUser > GetUserInfo ( GoogleSignInConfiguration configuration , string authCode , string json , TaskScheduler taskScheduler )
191+ {
192+ var jobj = JObject . Parse ( json ) ;
193+
194+ var accessToken = ( string ) jobj . GetValue ( "access_token" ) ! ;
195+ var expiresIn = ( int ) jobj . GetValue ( "expires_in" ) ! ;
196+ var scope = ( string ) jobj . GetValue ( "scope" ) ! ;
197+ var tokenType = ( string ) jobj . GetValue ( "token_type" ) ! ;
198+
199+ var user = new GoogleSignInUser ( ) ;
200+ if ( configuration . RequestAuthCode )
201+ user . AuthCode = authCode ;
202+
203+ if ( configuration . RequestIdToken )
204+ user . IdToken = ( string ) jobj . GetValue ( "id_token" ) ! ;
205+
206+ var request = HttpWebRequest . CreateHttp ( "https://openidconnect.googleapis.com/v1/userinfo" ) ;
207+ request . Method = "GET" ;
208+ request . Headers . Add ( "Authorization" , "Bearer " + accessToken ) ;
209+
210+ var data = await request . GetResponseAsStringAsync ( ) . ContinueWith ( ( task ) => task . Result , taskScheduler ) ;
211+ var userInfo = JObject . Parse ( data ) ;
212+ user . UserId = ( string ) userInfo . GetValue ( "sub" ) ! ;
213+ user . DisplayName = ( string ) userInfo . GetValue ( "name" ) ! ;
214+
215+ if ( configuration . RequestEmail )
216+ user . Email = ( string ) userInfo . GetValue ( "email" ) ! ;
217+
218+ if ( configuration . RequestProfile )
219+ {
220+ user . GivenName = ( string ) userInfo . GetValue ( "given_name" ) ! ;
221+ user . FamilyName = ( string ) userInfo . GetValue ( "family_name" ) ! ;
222+ user . ImageUrl = Uri . TryCreate ( ( string ) userInfo . GetValue ( "picture" ) ! , UriKind . Absolute , out var url ) ? url : null ! ;
223+ }
224+
225+ return user ;
226+ }
227+ }
182228
183229 public static class EditorExt
184230 {
0 commit comments