protected void Page_Load(object sender, EventArgs e)
        {
            GoogleAuthorizationCodeFlow flow;
            var assembly = Assembly.GetExecutingAssembly();
            using (var stream = assembly.GetManifestResourceStream("Tasks.ASP.NET.SimpleOAuth2.client_secrets.json"))
            {
                flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    DataStore = new FileDataStore("Tasks.ASP.NET.Sample.Store"),
                    ClientSecretsStream = stream,
                    Scopes = new[] { TasksService.Scope.TasksReadonly }
                });
            }

            var uri = Request.Url.ToString();
            var code = Request["code"];
            if (code != null)
            {
                var token = flow.ExchangeCodeForTokenAsync(UserId, code,
                    uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;

                // Extract the right state.
                var oauthState = AuthWebUtility.ExtracRedirectFromState(
                    flow.DataStore, UserId, Request["state"]).Result;
                Response.Redirect(oauthState);
            }
            else
            {
                var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(UserId,
                    CancellationToken.None).Result;
                if (result.RedirectUri != null)
                {
                    // Redirect the user to the authorization server.
                    Response.Redirect(result.RedirectUri);
                }
                else
                {
                    // The data store contains the user credential, so the user has been already authenticated.
                    service = new TasksService(new BaseClientService.Initializer
                    {
                        ApplicationName = "Tasks API Sample",
                        HttpClientInitializer = result.Credential
                    });
                }
            }
        }
        public void ConstructorTest()
        {
            var flow = new GoogleAuthorizationCodeFlow(initializer);

            Assert.That(flow.RevokeTokenUrl, Is.EqualTo(initializer.RevokeTokenUrl));
            Assert.That(flow.IncludeGrantedScopes, Is.EqualTo(initializer.IncludeGrantedScopes));
            Assert.That(flow.UserDefinedQueryParams, Is.EqualTo(initializer.UserDefinedQueryParams));
        }
 /// <summary>
 /// Constructs a new initializer from the given <see cref="GoogleAuthorizationCodeFlow"/>.
 /// </summary>
 internal Initializer(GoogleAuthorizationCodeFlow flow)
     : base(flow)
 {
     ProjectId            = flow.ProjectId;
     RevokeTokenUrl       = flow.revokeTokenUrl;
     IncludeGrantedScopes = flow.IncludeGrantedScopes;
     LoginHint            = flow.LoginHint;
     Prompt = flow.Prompt;
     Nonce  = flow.Nonce;
     UserDefinedQueryParams = flow.UserDefinedQueryParams;
 }
Пример #4
0
        public void CreateAuthorizationCodeRequestTest()
        {
            var flow = new GoogleAuthorizationCodeFlow(initializer);

            var request = flow.CreateAuthorizationCodeRequest("TestRedirectUri") as GoogleAuthorizationCodeRequestUrl;

            Assert.AreEqual(request.AccessType, "offline");
            Assert.AreEqual(request.IncludeGrantedScopes, "true");
            Assert.AreEqual(request.UserDefinedQueryParams, userDefinedParams);
            Assert.AreEqual(request.RedirectUri, "TestRedirectUri");
        }
        public void CreateAuthorizationCodeRequestTest()
        {
            var flow = new GoogleAuthorizationCodeFlow(initializer);

            var request = flow.CreateAuthorizationCodeRequest("TestRedirectUri") as GoogleAuthorizationCodeRequestUrl;

            Assert.AreEqual(request.AccessType, "offline");
            Assert.AreEqual(request.IncludeGrantedScopes, "true");
            Assert.AreEqual(request.UserDefinedQueryParams, userDefinedParams);
            Assert.AreEqual(request.RedirectUri, "TestRedirectUri");
        }
        private static async Task<UserCredential> AuthorizeAsyncCore(
            GoogleAuthorizationCodeFlow.Initializer initializer, IEnumerable<string> scopes, string user,
            CancellationToken taskCancellationToken, IDataStore dataStore = null)
        {
            initializer.Scopes = scopes;
            initializer.DataStore = dataStore ?? new FileDataStore(Folder);
            var flow = new GCSMAuthorizationCodeFlow(initializer,user);

            // Create an authorization code installed app instance and authorize the user.
            return await new AuthorizationCodeInstalledApp(flow, new LocalServerCodeReceiver()).AuthorizeAsync
                (user, taskCancellationToken).ConfigureAwait(false);
        }
        /// <summary>
        /// 저장위치와 접근 권한 설정을 해주는 함수
        /// </summary>
        /// <param name="initializer"> 초기 설정이 담겨있는 클래스</param>
        /// <param name="scopes"> 접근 권한이 담겨있음</param>
        /// <param name="user">사용자를 구별하기 위한 유저 이름 (닉네임)</param>
        /// <param name="taskCancellationToken"> 작업이 취소되지 않아야 함을 나타내는 값 : None으로 표시</param>
        /// <param name="dataStore"> 토큰값이 저장되는 경로 (설정 하지 않으면 null로 값이 들어감  (경로로 표시 : 기본 위치 -> C:\Users\bit-user\AppData\Roaming)) </param>
        /// <returns>반환값은 유저의 정보가 담긴 UserCredential 클래스 반환 </returns>
        private static async Task<UserCredential> AuthorizeAsyncCore(
            GoogleAuthorizationCodeFlow.Initializer initializer, IEnumerable<string> scopes, string user,
            CancellationToken taskCancellationToken, IDataStore dataStore = null)
        {
            initializer.Scopes = scopes;
            initializer.DataStore = dataStore ?? new FileDataStore(Folder);
            GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(initializer);

            // 토큰을 이용하여 사용자의 정보를 얻어와서 반환해준다.
            return await new googleauth(flow, new LocalServerCodeReceiver()).AuthorizeAsync
                (user, taskCancellationToken).ConfigureAwait(false);
        }
Пример #8
0
 public AppFlowMetadata()
 {
     var confService = new Configuration();
     CodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
     {
         ClientSecrets = new ClientSecrets
         {
             ClientId = confService.ClientId,
             ClientSecret = confService.ClientSecret
         },
         Scopes = new[] { MirrorService.Scope.GlassTimeline, MirrorService.Scope.GlassLocation },
         DataStore = new FileDataStore("Drive.Api.Auth.Store")
     });
 }
 public AppFlowMetadata(ISettingService settingService)
 {
     _setting = settingService.GetCurrentSetting();
     _flow = new GoogleAuthorizationCodeFlow(
         new GoogleAuthorizationCodeFlow.Initializer
             {
                 ClientSecrets =
                     new ClientSecrets
                         {
                             ClientId = _setting.GoogleClientId,
                             ClientSecret = _setting.GoogleClientSecret
                         },
                 Scopes = new[] { DriveService.Scope.Drive },
                 DataStore = MemoryDataStore.Instance
             });
 }
        private async Task<UserCredential> GetCredentialForApiAsync()
        {
            var initializer = new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets
                {
                    ClientId = MyClientSecrets.ClientId,
                    ClientSecret = MyClientSecrets.ClientSecret,
                },
                Scopes = MyRequestedScopes.Scopes,
            };
            var flow = new GoogleAuthorizationCodeFlow(initializer);

            var identity = await HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(
                DefaultAuthenticationTypes.ApplicationCookie);
            var userId = identity.FindFirstValue(MyClaimTypes.GoogleUserId);

            var token = await dataStore.GetAsync<TokenResponse>(userId);
            return new UserCredential(flow, userId, token);
        }
Пример #11
0
        public void Open(OAuth20Token token)
        {
            if (IsOpened)
                return;

            if (token == null) throw new UnauthorizedAccessException("Cannot create GoogleDrive session with given token");
            if (token.IsExpired) token = OAuth20TokenHelper.RefreshToken(GoogleUrlToken, token);
            _token = token;

            var tokenResponse = new TokenResponse
                {
                    AccessToken = _token.AccessToken,
                    RefreshToken = _token.RefreshToken,
                    Issued = _token.Timestamp,
                    ExpiresInSeconds = _token.ExpiresIn,
                    TokenType = "Bearer"
                };

            var apiCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                        {
                            ClientId = _token.ClientID,
                            ClientSecret = _token.ClientSecret
                        },
                    Scopes = new[] { DriveService.Scope.Drive }
                });

            _driveService = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = new UserCredential(apiCodeFlow, string.Empty, tokenResponse)
                });

            IsOpened = true;
        }
		/// <summary>Creates a user credential from JSON data.</summary>
		private static UserCredential CreateUserCredentialFromJson(JsonCredentialParameters credentialParameters)
		{
			if (credentialParameters.Type != JsonCredentialParameters.AuthorizedUserCredentialType ||
				string.IsNullOrEmpty(credentialParameters.ClientId) ||
				string.IsNullOrEmpty(credentialParameters.ClientSecret))
			{
				throw new InvalidOperationException("JSON data does not represent a valid user credential.");
			}

			var token = new TokenResponse
			{
				RefreshToken = credentialParameters.RefreshToken
			};

			var initializer = new GoogleAuthorizationCodeFlow.Initializer
			{
				ClientSecrets = new ClientSecrets
				{
					ClientId = credentialParameters.ClientId,
					ClientSecret = credentialParameters.ClientSecret
				}
			};
			var flow = new GoogleAuthorizationCodeFlow(initializer);
			return new UserCredential(flow, "ApplicationDefaultCredentials", token);
		}
Пример #13
0
        private DriveService CreateServie()
        { 
                var tokenResponse = new TokenResponse
                {
                    AccessToken = WebStorageConstants.GoogleDriveAccessToken,
                    RefreshToken = WebStorageConstants.GoogleRefreshToken,
                };

                var apiCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = WebStorageConstants.GoogleDriveId,
                        ClientSecret = WebStorageConstants.GoogleDriveSecret
                    },
                    Scopes = new[] { DriveService.Scope.Drive },
                    DataStore = new FileDataStore(WebStorageConstants.GoogleDriveApplicationName)
                });

                var credential = new UserCredential(apiCodeFlow, WebStorageConstants.GoogleDriveEmail, tokenResponse);

                var newService = new DriveService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = WebStorageConstants.GoogleDriveApplicationName
                });

                return newService;
        }
        public static DriveService CreateServie(string applicationName, string clientId, string clientSecret, string accessToken, string refreshToken)
        {
            var tokenResponse = new TokenResponse
            {
                AccessToken = accessToken,
                RefreshToken = refreshToken,
            };

            var apiCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets
                {
                    ClientId = clientId,
                    ClientSecret = clientSecret
                },
                Scopes = new[]
                {
                    DriveService.Scope.Drive, // view and manage your files and documents
                    DriveService.Scope.DriveAppdata, // view and manage its own configuration data
                    DriveService.Scope.DriveAppsReadonly, // view your drive apps
                    DriveService.Scope.DriveFile, // view and manage files created by this app
                    DriveService.Scope.DriveMetadataReadonly, // view metadata for files
                    DriveService.Scope.DriveReadonly, // view files and documents on your drive
                    DriveService.Scope.DriveScripts
                },
                DataStore = new FileDataStore(applicationName)
            });

            var credential = new UserCredential(apiCodeFlow, "*****@*****.**", tokenResponse);

            var service = new DriveService(new BaseClientService.Initializer
            {
                HttpClientInitializer = credential,
                ApplicationName = applicationName
            });

            return service;
        }
Пример #15
0
        public object RefreshOauth()
        {
            var CLIENT_ID = "570313910467-h8raudku9n9n65118tqndopih9breo53.apps.googleusercontent.com";
            var CLIENT_SECRET = "T8vlM82EEb82IAtDSaey-Oet";
            ClientSecrets secrets = new ClientSecrets
            {
                ClientId = CLIENT_ID,
                ClientSecret = CLIENT_SECRET
            };

            TokenResponse token = new TokenResponse
            {
                AccessToken = "sfd",                
                RefreshToken = "1/RcTEm-ZKEtBZzS2jOVLONQcmhtEpRZ7r2zny2HjWtMY"
            };

            IAuthorizationCodeFlow flow =
                new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = secrets,
                    Scopes = new string[] { DriveService.Scope.Drive }
                });

            UserCredential credential = new UserCredential(flow, "me", token);
            bool success = credential.RefreshTokenAsync(CancellationToken.None).Result;

            token = credential.Token;
            string access = token.AccessToken;

            var dbCtx = new CompassDBEntities();
            var oauthVal = new DriveOauth();
            oauthVal.Id = 1;
            var DriveAuth = dbCtx.DriveOauths.Find(oauthVal.Id);
            
            DriveAuth.AccessToken = token.AccessToken;
            DriveAuth.ExpireTime = token.ExpiresInSeconds.ToString();
            DriveAuth.IssueTime = token.Issued.ToString();
            dbCtx.SaveChanges();
            return token;
        }
 /// <summary>
 /// Metoda wypełniająca wszystkie niezbędne dane do autoryzacji w usłudze Google Calendar.
 /// </summary>
 private bool SetUserCalendarAuthData()
 {
     Logs.WriteErrorLog("SetUserCalendarAuthData");
     Logs.WriteErrorLog("ClientCredentials.ClientId: " + ClientCredentials.ClientId.ToString() + "ClientCredentials.ClientSecret: " + ClientCredentials.ClientSecret);
     Flow = new GoogleAuthorizationCodeFlow(
         new GoogleAuthorizationCodeFlow.Initializer
         {
             ClientSecrets = new ClientSecrets()
             {
                 ClientId = ClientCredentials.ClientId,
                 ClientSecret = ClientCredentials.ClientSecret
             }
         });
     Logs.WriteErrorLog("UserIdInDatabase: ");
     Logs.WriteErrorLog(UserIdInDatabase.ToString());
     var tokenFromWs = GetTokenFromWebService.GetTokenFromDatabase(UserIdInDatabase).Result;
     if (tokenFromWs == null)
     {
         IsCalendarAuthorized = false;
         return false;
     }
     Token = new TokenResponse
     {
         RefreshToken = tokenFromWs
     };
     IsCalendarAuthorized = true;
     return true;
 }
        /// <summary>
        /// Processes the request based on the path.
        /// </summary>
        /// <param name="context">Contains the request and response.</param>
        public void ProcessRequest(HttpContext context)
        {
            // Redirect base path to signin.
            if (context.Request.Path.EndsWith("/"))
            {
                context.Response.RedirectPermanent("signin.ashx");
            }

            // This is reached when the root document is passed. Return HTML
            // using index.html as a template.
            if (context.Request.Path.EndsWith("/signin.ashx"))
            {
                String state = (String)context.Session["state"];

                // Store a random string in the session for verifying
                // the responses in our OAuth2 flow.
                if (state == null)
                {
                    Random random = new Random((int)DateTime.Now.Ticks);
                    StringBuilder builder = new StringBuilder();
                    for (int i = 0; i < 13; i++)
                    {
                        builder.Append(Convert.ToChar(
                                Convert.ToInt32(Math.Floor(
                                        26 * random.NextDouble() + 65))));
                    }
                    state = builder.ToString();
                    context.Session["state"] = state;
                }

                // Render the templated HTML.
                String templatedHTML = File.ReadAllText(
                     context.Server.MapPath("index.html"));
                templatedHTML = Regex.Replace(templatedHTML,
                    "[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}", APP_NAME);
                templatedHTML = Regex.Replace(templatedHTML,
                    "[{]{2}\\s*CLIENT_ID\\s*[}]{2}", secrets.ClientId);
                templatedHTML = Regex.Replace(templatedHTML,
                    "[{]{2}\\s*STATE\\s*[}]{2}", state);

                context.Response.ContentType = "text/html";
                context.Response.Write(templatedHTML);
                return;
            }

            if (context.Session["authState"] == null)
            {
                // The connect action exchanges a code from the sign-in button,
                // verifies it, and creates OAuth2 credentials.
                if (context.Request.Path.Contains("/connect"))
                {
                    // Get the code from the request POST body.
                    StreamReader sr = new StreamReader(
                        context.Request.InputStream);
                    string code = sr.ReadToEnd();

                    string state = context.Request["state"];

                    // Test that the request state matches the session state.
                    if (!state.Equals(context.Session["state"]))
                    {
                        context.Response.StatusCode = 401;
                        return;
                    }

                    // Use the code exchange flow to get an access and refresh token.
                    IAuthorizationCodeFlow flow =
                        new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                        {
                            ClientSecrets = secrets,
                            Scopes = SCOPES
                        });

                    token = flow.ExchangeCodeForTokenAsync("", code, "postmessage",
                            CancellationToken.None).Result;

                    // Create an authorization state from the returned token.
                    context.Session["authState"] = token;

                    // Get tokeninfo for the access token if you want to verify.
                    Oauth2Service service = new Oauth2Service(
                        new Google.Apis.Services.BaseClientService.Initializer());
                    Oauth2Service.TokeninfoRequest request = service.Tokeninfo();
                    request.AccessToken = token.AccessToken;

                    Tokeninfo info = request.Execute();

                    string gplus_id = info.UserId;
                }
                else
                {
                    // No cached state and we are not connecting.
                    context.Response.StatusCode = 400;
                    return;
                }
            }
            else if (context.Request.Path.Contains("/connect"))
            {
                // The user is already connected and credentials are cached.
                context.Response.ContentType = "application/json";
                context.Response.StatusCode = 200;
                context.Response.Write(JsonConvert.SerializeObject("Current user is already connected."));
                return;
            }
            else
            {
                // Register the authenticator and construct the Plus service
                // for performing API calls on behalf of the user.
                token = (TokenResponse)context.Session["authState"];
                IAuthorizationCodeFlow flow =
                    new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                    {
                        ClientSecrets = secrets,
                        Scopes = SCOPES
                    });

                UserCredential credential = new UserCredential(flow, "me", token);
                bool success = credential.RefreshTokenAsync(CancellationToken.None).Result;

                token = credential.Token;
                ps = new PlusService(
                    new Google.Apis.Services.BaseClientService.Initializer()
                    {
                        ApplicationName = ".NET Quickstart",
                        HttpClientInitializer = credential
                    });
            }

            // Perform an authenticated API request to retrieve the list of
            // people that the user has made visible to the app.
            if (context.Request.Path.Contains("/people"))
            {
                // Get the PeopleFeed for the currently authenticated user.
                PeopleFeed pf = ps.People.List("me",
                        PeopleResource.ListRequest.CollectionEnum.Visible).Execute();

                // This JSON, representing the people feed, will later be
                // parsed by the JavaScript client.
                string jsonContent =
                    Newtonsoft.Json.JsonConvert.SerializeObject(pf);
                context.Response.ContentType = "application/json";
                context.Response.Write(jsonContent);
                return;
            }

            // Disconnect the user from the application by revoking the tokens
            // and removing all locally stored data associated with the user.
            if (context.Request.Path.Contains("/disconnect"))
            {
                // Perform a get request to the token endpoint to revoke the
                // refresh token.
                token = (TokenResponse)context.Session["authState"];
                string tokenToRevoke = (token.RefreshToken != null) ?
                    token.RefreshToken : token.AccessToken;

                WebRequest request = WebRequest.Create(
                    "https://accounts.google.com/o/oauth2/revoke?token=" +
                    tokenToRevoke);

                WebResponse response = request.GetResponse();

                // Remove the cached credentials.
                context.Session["authState"] = null;

                // You could reset the state in the session but you must also
                // reset the state on the client.
                // context.Session["state"] = null;
                context.Response.Write(
                    response.GetResponseStream().ToString().ToCharArray());
                return;
            }
        }
Пример #18
0
 public googleauth(GoogleAuthorizationCodeFlow flow, ICodeReceiver codeReceiver)
 { 
     this.flow = flow;
     this.codeReceiver = codeReceiver;
 }
        /// <summary>The core logic for asynchronously authorizing the specified user.</summary>
        /// <param name="initializer">The authorization code initializer.</param>
        /// <param name="scopes">
        /// The scopes which indicate the Google API access your application is requesting.
        /// </param>
        /// <param name="user">The user to authenticate.</param>
        /// <param name="taskCancellationToken">Cancellation token to cancel an operation.</param>
        /// <returns>User credential.</returns>
        private static async Task<UserCredential> AuthorizeAsyncCore(
            GoogleAuthorizationCodeFlow.Initializer initializer, IEnumerable<string> scopes, string user,
            CancellationToken taskCancellationToken)
        {
            initializer.Scopes = scopes;
            initializer.DataStore = new StorageDataStore();

            var installedApp = new AuthorizationCodeWPInstalledApp(new GoogleAuthorizationCodeFlow(initializer));
            return await installedApp.AuthorizeAsync(user, taskCancellationToken).ConfigureAwait(false);
        }
        private void VerifyAndRefreshCredentials(TransientCredentials tc)
        {
            var userCredential = tc.Token as UserCredential;
            var token = userCredential?.Token;

            if (IsValidToken(token))
            {
                // We already have a valid OAuth token.
                return;
            }

            if (userCredential == null)
            {
                // Attempt to load a cached OAuth token.
                var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecretsStream = ClientSecretsStream,
                    DataStore = GetCredentialsDataStoreForBlog(tc.Username),
                    Scopes = new List<string>() { BloggerServiceScope, PicasaServiceScope },
                });

                var loadTokenTask = flow.LoadTokenAsync(tc.Username, CancellationToken.None);
                loadTokenTask.Wait();
                if (loadTokenTask.IsCompleted)
                {
                    // We were able re-create the user credentials from the cache.
                    userCredential = new UserCredential(flow, tc.Username, loadTokenTask.Result);
                    token = loadTokenTask.Result;
                }
            }

            if (!IsValidToken(token))
            {
                // The token is invalid, so we need to login again. This likely includes popping out a new browser window.
                if (BlogClientUIContext.SilentModeForCurrentThread)
                {
                    // If we're in silent mode where prompting isn't allowed, throw the verification exception
                    throw new BlogClientAuthenticationException(String.Empty, String.Empty);
                }

                // Start an OAuth flow to renew the credentials.
                var authorizationTask = GetOAuth2AuthorizationAsync(tc.Username, CancellationToken.None);
                authorizationTask.Wait();
                if (authorizationTask.IsCompleted)
                {
                    userCredential = authorizationTask.Result;
                    token = userCredential?.Token;
                }
            }

            if (!IsValidToken(token))
            {
                // The token is still invalid after all of our attempts to refresh it. The user did not complete the 
                // authorization flow, so we interpret that as a cancellation.
                throw new BlogClientOperationCancelledException();
            }

            // Stash the valid user credentials.
            tc.Token = userCredential;
        }
Пример #21
-1
		private static async Task<UserCredential> SAuthorizeAsync(string user, CancellationToken token)
		{
			Stream stream;
			try
			{
				using (stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("MailChecker.Resources.clientsecrets.json"))
				{
					var initializer = new GoogleAuthorizationCodeFlow.Initializer
					{
						ClientSecretsStream = stream,
					};

					initializer.Scopes = new[] { "https://mail.google.com" };

					var flow = new GoogleAuthorizationCodeFlow(initializer);

					return await new AuthorizationCodeInstalledApp(flow, new LocalServerCodeReceiver()).AuthorizeAsync
						(user, token).ConfigureAwait(false);
				}
			}
			catch (Exception e)
			{
				logging.TraceEvent(TraceEventType.Error, 1, "Error in SAuthorizeAsync: " + e);
				return null;
			}
		}
        private DriveService CreateDriveService(GoogleCredentials googleCredentials)
        {
            var authorizationCodeFlowInitializer = new GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new ClientSecrets
                {
                    ClientId = googleCredentials.ClientId,
                    ClientSecret = googleCredentials.ClientSecret
                }
            };
            var googleAuthorizationCodeFlow = new GoogleAuthorizationCodeFlow(authorizationCodeFlowInitializer);
            var token = new TokenResponse { RefreshToken = googleCredentials.RefreshToken };
            var credentials = new UserCredential(googleAuthorizationCodeFlow, "user", token);

            var initializer = new BaseClientService.Initializer
            {
                ApplicationName = "Emby",
                HttpClientInitializer = credentials
            };

            return new DriveService(initializer)
            {
                HttpClient = { Timeout = TimeSpan.FromHours(1) }
            };
        }