using Google.Apis.Auth.OAuth2; using Google.Apis.Oauth2.v2; using System; using System.Collections.Generic; using System.Threading.Tasks; using Windows.Security.Authentication.Web; using YouTube.Authorization; using System.Text.RegularExpressions; using Windows.Security.Credentials; using FoxTube.Models; using YouTube; using System.Threading; using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using Windows.UI.Xaml.Controls; using Windows.UI.Popups; using FoxTube.Utils; namespace FoxTube { public static class UserManagement { static ExtendedYouTubeService _defaultService = new ExtendedYouTubeService(new Google.Apis.Services.BaseClientService.Initializer { ApplicationName = "FoxTube", ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0" //ApiKey = "AIzaSyD7tpbuvmYDv9h4udo9L_g3r0sLPFAnN00" }); static string[] Scopes { get; } = new string[] { Oauth2Service.Scope.UserinfoProfile, Oauth2Service.Scope.UserinfoEmail, YouTubeService.Scope.YoutubeForceSsl }; static ClientSecrets ClientSecrets { get; } = new ClientSecrets { ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com", ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_" //ClientId = "1096685398208-u95rcpkqb4e1ijfmb8jdq3jsg37l8igv.apps.googleusercontent.com", //ClientSecret = "IU5bbdjwvmx8ttJoXQ7e6JWd" }; public static User CurrentUser { get; set; } public static bool Authorized => CurrentUser != null; public static ExtendedYouTubeService Service => CurrentUser?.Service ?? _defaultService; public static event EventHandler UserStateUpdated; public static event EventHandler SubscriptionsChanged; public static async Task AddUser() { Uri requestString = AuthorizationHelpers.FormQueryString(ClientSecrets, Scopes); WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.UseTitle, requestString, AuthorizationHelpers.Endpoint); switch (result.ResponseStatus) { case WebAuthenticationStatus.Success: string successCode = new Regex(@"(?<=code=)(.*?)(?=&)").Match(result.ResponseData).Value; UserCredential credential = await AuthorizationHelpers.ExchangeToken(ClientSecrets, successCode); CurrentUser = new User(credential); PasswordVault passwordVault = new PasswordVault(); passwordVault.Add(new PasswordCredential("foxtube", CurrentUser.UserInfo.Id, credential.Token.RefreshToken)); UserStateUpdated?.Invoke(null, true); return true; case WebAuthenticationStatus.UserCancel: break; case WebAuthenticationStatus.ErrorHttp: await new ContentDialog { Title = "Something went wrong...", Content = "It may be a bug or temporary server issues. Please, try again later" }.ShowAsync(); Metrics.SendReport(new Exception("Authorization failed (HTTP Error)"), null, ("Response status", result.ResponseStatus.ToString()), ("Response data", result.ResponseData), ("Error details", result.ResponseErrorDetail.ToString())); break; } return false; } public static async Task Initialize() { PasswordVault passwordVault = new PasswordVault(); IReadOnlyList credentials; credentials = passwordVault.RetrieveAll(); if (credentials.Count == 0) return; try { credentials[0].RetrievePassword(); UserCredential credential = await AuthorizationHelpers.RestoreUser(ClientSecrets, credentials[0].Password); credentials[0].Password = credential.Token.RefreshToken; CurrentUser = new User(credential); } catch (Exception e) { await new MessageDialog("It may be a bug or temporary server issues. Please, try again later", "Something went wrong...").ShowAsync(); Metrics.SendReport(new Exception("Refresh token exchange failed", e)); foreach (PasswordCredential i in credentials) passwordVault.Remove(i); } } public static async Task Logout() { PasswordVault passwordVault = new PasswordVault(); PasswordCredential credential = passwordVault.Retrieve("foxtube", CurrentUser.UserInfo.Id); passwordVault.Remove(credential); await CurrentUser.Credential.RevokeTokenAsync(CancellationToken.None); UserStateUpdated?.Invoke(null, false); } } }