//using IdentityProvider.Protos.AuthService; using Blazored.LocalStorage; using Grpc.Core; using Grpc.Net.Client; using GrpcShared; using GrpcShared.DTO; using GrpcShared.DTO.Auth; using GrpcShared.DTO.Db; using GrpcShared.DTO.User; using GrpcShared.Interfaces; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; using Newtonsoft.Json; using System.Diagnostics; using System.IO; using System.Net; using System.Net.Http.Headers; using System.Text; using System.Text.Json; namespace SpotifyService.Services { public class AuthService : IAuthService { private readonly ILogger _logger; private readonly CodeRequest _params; private readonly IHttpClientFactory _httpClientFactory; //private ISessionStorageService _sessionStorageService; public AuthService(ILogger logger, IOptions options, IHttpClientFactory httpClientFactory) { _logger = logger; _params = options.Value; _httpClientFactory = httpClientFactory; } public async Task GetAccessToken(TokenRequest tokenRequest) { var http = _httpClientFactory.CreateClient("HttpClient"); string url = "https://accounts.spotify.com/api/token"; http.BaseAddress = new Uri(url); //get client id and secret, and redirect uri from appsettings, convert to base64 and set as header //var secrets = await GetAuthParams(); var secrets = new CodeRequest { ClientId = GLOBALS.CLIENT_ID , ClientSecret = GLOBALS.SECRET, RedirectURI = GLOBALS.REDIRECT_URI }; byte[] contentType = Encoding.UTF8.GetBytes($"{secrets.ClientId}:{secrets.ClientSecret}"); tokenRequest.RedirectUri = secrets.RedirectURI; //AUTHORIZATION HEADER http.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Basic " + Convert.ToBase64String(contentType)); //BODY PARAMS var requestBody = new Dictionary(); requestBody["grant_type"] = tokenRequest.GrantType; requestBody["code"] = tokenRequest.Code!; requestBody["redirect_uri"] = tokenRequest.RedirectUri!; try { //REQUEST var response = await http.PostAsync(url, new FormUrlEncodedContent(requestBody)); var contents = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync())!; return contents; } catch (RpcException e) { if (e.StatusCode == StatusCode.Cancelled) { return new TokenResponse(); } throw; } } public async Task GetAuthParams() { var authParams = new CodeRequest { ClientId = _params.ClientId, RedirectURI = _params.RedirectURI, Scope = _params.Scope, ClientSecret = _params.ClientSecret }; return await Task.FromResult(authParams); } public async Task GetUserInfo(UserResponse tokenM) { // expired token example "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN" var http = _httpClientFactory.CreateClient("HttpClient"); http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenM.Token!); var response = await http.GetAsync("me"); //make this a method in http utils if (response.StatusCode == HttpStatusCode.Unauthorized) { //refresh the token var refreshResponse = await RefreshAccessToken(tokenM); //if response is invalid redirect to login http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", refreshResponse.AccessToken); response = await http.GetAsync("me"); } //var headerError = response.Headers.WwwAuthenticate.; var userInfo = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync())!; userInfo.ResponseMsg = response.StatusCode; return userInfo; } public async Task RefreshAccessToken(UserResponse tokenM) { var client = _httpClientFactory.CreateClient("HttpClient"); client.BaseAddress = new Uri("https://accounts.spotify.com/api/token"); //BODY PARAMS var requestBody = new Dictionary(); requestBody["refresh_token"] = tokenM.RefreshToken!; requestBody["grant_type"] = "refresh_token"; //var secrets = await GetAuthParams(); var secrets = new CodeRequest { ClientId = GLOBALS.CLIENT_ID, ClientSecret = GLOBALS.SECRET, RedirectURI = GLOBALS.REDIRECT_URI }; byte[] contentType = Encoding.UTF8.GetBytes($"{secrets.ClientId}:{secrets.ClientSecret}"); //AUTHORIZATION HEADER client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Basic " + Convert.ToBase64String(contentType)); //REQUEST var response = await client.PostAsync("https://accounts.spotify.com/api/token", new FormUrlEncodedContent(requestBody)); var contents = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync())!; return contents; } } }