Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public partial class EmailService : IEmailService
- {
- private const string ApplicationName = "Hidden-On-Purpose";
- public const string TokenUrl = "https://oauth2.googleapis.com/token";
- public const string FileNameCredentials = "Your_File_With_Credentials.json";
- public const string RefreshToken = "HiddenOnPurpose";
- // Update Scope to hit Google Calendar
- private readonly string[] _scopes = [GmailService.Scope.GmailReadonly];
- private readonly string _redirectUri;
- private static GoogleCredential Credential { get; set; } = default!;
- public static GoogleClientSecrets ClientSecrets { get; set; } = default!;
- private readonly IDataStore _dataStore;
- public EmailService(
- IHttpClientFactory httpClientFactory,
- IHttpContextAccessor httpContextAccessor,
- IDataStore dataStore)
- {
- if (httpContextAccessor?.HttpContext is null)
- {
- throw new ArgumentNullException(nameof(httpClientFactory));
- }
- // Must be the same as the one you set in the Google Console in the Oauth2 section ( https://console.cloud.google.com/apis/credentials/oauthclient/)
- _redirectUri = $"https://{httpContextAccessor.HttpContext!.Request.Host}/Home/AuthorizeGoogle";
- // I have my own custom DataStore, but you can use the default one it should not affect your code
- // I am storing my Token in Azure Storage, you can ask chatgpt for this it will help you
- _dataStore = dataStore ?? throw new ArgumentNullException(nameof(dataStore));
- }
- #region Google Authentication Process
- /// <summary>
- /// Starting point for the Gmail Authentication
- /// Very Important! Must be called in Incognito Mode to be able to get Refresh Token, otherwise you might not get.
- /// </summary>
- /// <returns></returns>
- public async Task<string> StartGmailChallengeAuthenticationAsync(CancellationToken cancellationToken)
- {
- if (ClientSecrets is null)
- {
- await InitializeClientSecretsAsync(cancellationToken);
- }
- using var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
- {
- ClientSecrets = ClientSecrets!.Secrets,
- Scopes = _scopes,
- DataStore = _dataStore
- });
- var absoluteUri = flow.CreateAuthorizationCodeRequest(_redirectUri).Build().AbsoluteUri;
- return absoluteUri;
- }
- public static async Task<TokenResponse> RefreshAccessTokenAsync([NotNull] HttpClient httpClient, string clientId, string clientSecret, string refreshToken)
- {
- using var requestBody = new FormUrlEncodedContent(new[]
- {
- new KeyValuePair<string, string>("client_id", clientId),
- new KeyValuePair<string, string>("client_secret", clientSecret),
- new KeyValuePair<string, string>("refresh_token", refreshToken),
- new KeyValuePair<string, string>("grant_type", "refresh_token")
- });
- var response = await httpClient.PostAsync(TokenUrl, requestBody);
- response.EnsureSuccessStatusCode();
- var responseContent = await response.Content.ReadFromJsonAsync<TokenResponse>() ?? throw new ApplicationException("Response content is null in the background job");
- return responseContent;
- }
- public async Task ExchangeCodeForTokenResponseGmailAsync(string code, CancellationToken cancellationToken)
- {
- if (string.IsNullOrEmpty(code))
- {
- throw new ApplicationException("No code found");
- }
- if (ClientSecrets is null)
- {
- await InitializeClientSecretsAsync(cancellationToken);
- throw new ApplicationException("Client Secrets is null");
- }
- // Exchange the authorization code for user credentials (tokens)
- using var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
- {
- ClientSecrets = ClientSecrets.Secrets,
- Scopes = _scopes,
- DataStore = _dataStore
- });
- var token = await flow.ExchangeCodeForTokenAsync(
- userId: "user",
- code: code,
- redirectUri: _redirectUri,
- cancellationToken);
- await _dataStore.StoreAsync("user", token);
- }
- public static async Task InitializeClientSecretsAsync(CancellationToken cancellationToken)
- {
- using var stream = new FileStream(FileNameCredentials, FileMode.Open, FileAccess.Read);
- ClientSecrets = await GoogleClientSecrets.FromStreamAsync(stream, cancellationToken: cancellationToken);
- }
- private async Task InitializeGoogleCredentialsAsync()
- {
- var tokenResponse = await _dataStore.GetAsync<TokenResponse>("user");
- Credential = GoogleCredential.FromAccessToken(tokenResponse.AccessToken);
- }
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement