123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- using System.Text;
- using Logging.Net;
- using Moonlight.App.Database.Entities;
- using Moonlight.App.Exceptions;
- using Moonlight.App.Models.Google.Requests;
- using RestSharp;
- namespace Moonlight.App.Services.OAuth2;
- public class GoogleOAuth2Service
- {
- private readonly bool EnableGoogle;
- private readonly string GoogleClientId;
- private readonly string GoogleClientSecret;
-
- private readonly bool EnableOverrideUrl;
- private readonly string OverrideUrl;
- private readonly string AppUrl;
- public GoogleOAuth2Service(ConfigService configService)
- {
- var config = configService
- .GetSection("Moonlight")
- .GetSection("OAuth2");
- EnableGoogle = config
- .GetSection("Google")
- .GetValue<bool>("Enable");
- if (EnableGoogle)
- {
- GoogleClientId = config.GetSection("Google").GetValue<string>("ClientId");
- GoogleClientSecret = config.GetSection("Google").GetValue<string>("ClientSecret");
- }
- EnableOverrideUrl = config.GetValue<bool>("EnableOverrideUrl");
- if (EnableOverrideUrl)
- OverrideUrl = config.GetValue<string>("OverrideUrl");
- AppUrl = configService.GetSection("Moonlight").GetValue<string>("AppUrl");
- }
-
- public Task<string> GetUrl()
- {
- if (!EnableGoogle)
- throw new DisplayException("Google OAuth2 not enabled");
- var endpoint = GetBaseUrl() + "/api/moonlight/oauth2/google";
- var scope = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email";
- return Task.FromResult(
- $"https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={GoogleClientId}&redirect_uri={endpoint}&scope={scope}"
- );
- }
- public async Task<User?> HandleCode(string code)
- {
- // Generate access token
- var endpoint = GetBaseUrl() + "/api/moonlight/oauth2/google";
- var googleEndpoint = "https://oauth2.googleapis.com/token";
-
- // Setup payload
- var payload = new GoogleOAuth2CodePayload()
- {
- Code = code,
- RedirectUri = endpoint,
- ClientId = GoogleClientId,
- ClientSecret = GoogleClientSecret
- };
- using var client = new RestClient();
- var request = new RestRequest(googleEndpoint);
- request.AddBody(payload);
- var response = await client.ExecutePostAsync(request);
- if (!response.IsSuccessful)
- {
- //TODO: Maybe add better error handling
- Logger.Debug("oAuth2 validate error: " + response.Content!);
- return null;
- }
-
- // parse response
-
- var data = new ConfigurationBuilder().AddJsonStream(
- new MemoryStream(Encoding.ASCII.GetBytes(response.Content!))
- ).Build();
- var accessToken = data.GetValue<string>("access_token");
-
- // Now, we will call the google api with our access token to get the data we need
- var googlePeopleEndpoint = "https://people.googleapis.com/v1/people/me";
-
- var getRequest = new RestRequest(googlePeopleEndpoint);
- getRequest.AddHeader("Authorization", $"Bearer {accessToken}");
- getRequest.AddParameter("personFields", "names,emailAddresses");
- var getResponse = await client.ExecuteGetAsync(getRequest);
-
- if (!getResponse.IsSuccessful)
- {
- //TODO: Maybe add better error handling
- Logger.Debug("OAuth2 api access error: " + getResponse.Content!);
- return null;
- }
-
- // Parse response
-
- var getData = new ConfigurationBuilder().AddJsonStream(
- new MemoryStream(Encoding.ASCII.GetBytes(getResponse.Content!))
- ).Build();
- var firstName = getData
- .GetSection("names")
- .GetChildren()
- .First()
- .GetValue<string>("givenName");
-
- var lastName = getData
- .GetSection("names")
- .GetChildren()
- .First()
- .GetValue<string>("familyName");
-
- var email = getData
- .GetSection("emailAddresses")
- .GetChildren()
- .First()
- .GetValue<string>("value");
- return new()
- {
- Email = email,
- FirstName = firstName,
- LastName = lastName
- };
- }
- private string GetBaseUrl()
- {
- if (EnableOverrideUrl)
- return OverrideUrl;
- return AppUrl;
- }
- }
|