Преглед изворни кода

Merge branch 'feature/identity-transfer' into dev

master
anastasijasavov пре 3 година
родитељ
комит
5cffa86509
29 измењених фајлова са 244 додато и 188 уклоњено
  1. 1
    1
      GrpcShared/DTO/Search/SearchRequest.cs
  2. 29
    0
      GrpcShared/DTO/SessionMessage.cs
  3. 1
    6
      GrpcShared/DTO/TokenMessage.cs
  4. 1
    1
      GrpcShared/DTO/TopItem/TopItemRequest.cs
  5. 1
    1
      GrpcShared/DTO/Track/MultipleTrack/MultipleTrackRequest.cs
  6. 1
    1
      GrpcShared/DTO/Track/SaveTracks/SaveTracksRequest.cs
  7. 1
    1
      GrpcShared/DTO/Track/SingleTrack/SingleTrackRequest.cs
  8. 1
    1
      GrpcShared/DTO/Track/TrackByID/TrackRequest.cs
  9. 3
    2
      GrpcShared/Interfaces/IAuthService.cs
  10. 1
    1
      GrpcShared/Interfaces/IStatsService.cs
  11. 0
    1
      IdentityProvider/IdentityProvider.csproj
  12. 4
    4
      IdentityProvider/Models/SpotifyDbConfig.cs
  13. 21
    21
      IdentityProvider/Program.cs
  14. 8
    7
      IdentityProvider/Properties/launchSettings.json
  15. 2
    1
      IdentityProvider/Services/IdentityService.cs
  16. 5
    7
      IdentityProvider/appsettings.json
  17. 12
    26
      NemAnCore/Pages/FetchData.razor
  18. 10
    41
      NemAnCore/Pages/Home.razor
  19. 10
    10
      NemAnCore/Services/AuthClientService.cs
  20. 3
    2
      NemAnCore/Services/Interfaces/IAuthClientService.cs
  21. 1
    1
      NemAnCore/Services/Interfaces/IStatsClientService.cs
  22. 2
    2
      NemAnCore/Services/StatsClientService.cs
  23. 80
    15
      gRPCServer/HttpUtils/HttpUtils.cs
  24. 7
    8
      gRPCServer/HttpUtils/SpotifyHelper.cs
  25. 12
    4
      gRPCServer/Program.cs
  26. 3
    2
      gRPCServer/Services/AuthService.cs
  27. 10
    8
      gRPCServer/Services/StatsService.cs
  28. 13
    13
      gRPCServer/Services/TrackService.cs
  29. 1
    0
      gRPCServer/SpotifyService.csproj

+ 1
- 1
GrpcShared/DTO/Search/SearchRequest.cs Прегледај датотеку

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.Search
{
[ProtoContract]
public class SearchRequest : TokenMessage
public class SearchRequest : SessionMessage
{
[ProtoMember(1)]

+ 29
- 0
GrpcShared/DTO/SessionMessage.cs Прегледај датотеку

@@ -0,0 +1,29 @@
using GrpcShared.DTO.Search;
using GrpcShared.DTO.TopItem;
using GrpcShared.DTO.Track.MultipleTrack;
using GrpcShared.DTO.Track.SaveTracks;
using GrpcShared.DTO.Track.SingleTrack;
using GrpcShared.DTO.TrackByID;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO
{
[ProtoContract]
[ProtoInclude(5, typeof(TopItemRequest))]
[ProtoInclude(6, typeof(SingleTrackRequest))]
[ProtoInclude(7, typeof(SearchRequest))]
[ProtoInclude(8, typeof(MultipleTrackRequest))]
[ProtoInclude(9, typeof(SaveTracksRequest))]
[ProtoInclude(10, typeof(TrackRequest))]
public class SessionMessage
{
[ProtoMember(1)]
public string? UserId { get; set; }
}
}

+ 1
- 6
GrpcShared/DTO/TokenMessage.cs Прегледај датотеку

@@ -13,12 +13,7 @@ using System.Threading.Tasks;

namespace GrpcShared.DTO
{
[ProtoInclude(5, typeof(TopItemRequest))]
[ProtoInclude(6, typeof(SingleTrackRequest))]
[ProtoInclude(7, typeof(SearchRequest))]
[ProtoInclude(8,typeof(MultipleTrackRequest))]
[ProtoInclude(9,typeof(SaveTracksRequest))]
[ProtoInclude(10,typeof(TrackRequest))]

[ProtoContract(SkipConstructor = true)]
public class TokenMessage

+ 1
- 1
GrpcShared/DTO/TopItem/TopItemRequest.cs Прегледај датотеку

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.TopItem
{
[ProtoContract]
public class TopItemRequest : TokenMessage
public class TopItemRequest : SessionMessage
{

[ProtoMember(1)]

+ 1
- 1
GrpcShared/DTO/Track/MultipleTrack/MultipleTrackRequest.cs Прегледај датотеку

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.Track.MultipleTrack
{
[ProtoContract]
public class MultipleTrackRequest:TokenMessage
public class MultipleTrackRequest: SessionMessage
{
[ProtoMember(1)]
public List<string>? Ids { get; set; }

+ 1
- 1
GrpcShared/DTO/Track/SaveTracks/SaveTracksRequest.cs Прегледај датотеку

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.Track.SaveTracks
{
[ProtoContract]
public class SaveTracksRequest : TokenMessage
public class SaveTracksRequest : SessionMessage
{
[ProtoMember(1)]
public List<string>? Ids { get; set; }

+ 1
- 1
GrpcShared/DTO/Track/SingleTrack/SingleTrackRequest.cs Прегледај датотеку

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.Track.SingleTrack
{
[ProtoContract]
public class SingleTrackRequest : TokenMessage
public class SingleTrackRequest : SessionMessage
{
[ProtoMember(1)]
public string? Id { get; set; }

+ 1
- 1
GrpcShared/DTO/Track/TrackByID/TrackRequest.cs Прегледај датотеку

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace GrpcShared.DTO.TrackByID
{
[ProtoContract]
public class TrackRequest:TokenMessage
public class TrackRequest: SessionMessage
{
[ProtoMember(1)]
[JsonProperty("id")]

+ 3
- 2
GrpcShared/Interfaces/IAuthService.cs Прегледај датотеку

@@ -1,5 +1,6 @@
using GrpcShared.DTO;
using GrpcShared.DTO.Auth;
using GrpcShared.DTO.Db;
using GrpcShared.DTO.User;
using ProtoBuf.Grpc.Configuration;

@@ -10,8 +11,8 @@ namespace GrpcShared.Interfaces
{
Task<TokenResponse> GetAccessToken(TokenRequest code);
Task<CodeRequest> GetAuthParams();
Task<UserInfoResponse> GetUserInfo(TokenMessage token);
Task<RefreshTokenResponse> RefreshAccessToken(TokenMessage msg);
Task<UserInfoResponse> GetUserInfo(UserResponse token);
Task<RefreshTokenResponse> RefreshAccessToken(UserResponse msg);
//Task<ClientSecrets> GetClientSecrets();
}
}

+ 1
- 1
GrpcShared/Interfaces/IStatsService.cs Прегледај датотеку

@@ -13,7 +13,7 @@ namespace GrpcShared.Interfaces
[Service]
public interface IStatsService
{
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token);
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(SessionMessage message);
Task<TopItemResponse> GetTopItems(TopItemRequest request);
}
}

+ 0
- 1
IdentityProvider/IdentityProvider.csproj Прегледај датотеку

@@ -20,7 +20,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\gRPCServer\SpotifyService.csproj" />
<ProjectReference Include="..\GrpcShared\GrpcShared.csproj" />
<ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" />
</ItemGroup>

+ 4
- 4
IdentityProvider/Models/SpotifyDbConfig.cs Прегледај датотеку

@@ -2,9 +2,9 @@
{
public class SpotifyDbConfig
{
public string ConnectionString { get; set; } = null!;
public string DatabaseName { get; set; } = null!;
public string UserCollection { get; set; } = null!;
public string TracksCollection { get; set; } = null!;
public string ConnectionString { get; set; } = "mongodb://127.0.0.1:27017";
public string DatabaseName { get; set; } = "spotifyDb";
public string UserCollection { get; set; } = "Users";
public string TracksCollection { get; set; } = "Tracks";
}
}

+ 21
- 21
IdentityProvider/Program.cs Прегледај датотеку

@@ -1,5 +1,5 @@
using GrpcShared;
using SpotifyService.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using ProtoBuf.Grpc.Server;
using Microsoft.Extensions.Options;
@@ -11,23 +11,17 @@ using IdentityProvider.Services;
var builder = WebApplication.CreateBuilder(args);
#if DEBUG

builder.WebHost.ConfigureKestrel(options =>
{
options.ListenLocalhost(5050, o => o.Protocols =
HttpProtocols.Http2);
options.ListenLocalhost(5051, o => o.Protocols =
HttpProtocols.Http1AndHttp2);
});
//builder.WebHost.ConfigureKestrel(options =>
//{
// options.ListenLocalhost(5050, o => o.Protocols =
// HttpProtocols.Http2);
// options.ListenLocalhost(5051, o => o.Protocols =
// HttpProtocols.Http1AndHttp2);
//});

#endif
builder.Services.AddHttpClient("HttpClient", c =>
{
c.BaseAddress = new Uri(SpotifyService.GLOBALS.SPOTIFYURL);
c.DefaultRequestHeaders.Add("Accept", SpotifyService.GLOBALS.MEDIATYPE);
});

builder.Services.AddOptions();
builder.Services.AddSingleton<SpotifyDbConfig>();
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
builder.Services.AddControllersWithViews();
@@ -42,12 +36,18 @@ builder.Services.AddBlazoredLocalStorage();
//call spotify api
builder.Services.AddHttpClient();

builder.Services.Configure<CodeRequest>(
builder.Configuration.GetSection("AuthParams"));
builder.Services.AddSingleton<SpotifyDbConfig>();

builder.Services.Configure<SpotifyDbConfig>(
builder.Configuration.GetSection("SpotifyDb"));

//builder.Services.AddHttpClient("HttpClient", c =>
//{
// c.BaseAddress = new Uri(builder.Configuration.GetSection("SpotifyConfig:SpotifyURL").Value.ToString());
// c.DefaultRequestHeaders.Add("Accept", builder.Configuration.GetSection("SpotifyConfig:MediaType").Value.ToString());

//});

var app = builder.Build();

// Configure the HTTP request pipeline.
@@ -77,10 +77,10 @@ app.MapRazorPages();
app.MapControllers();

//app.MapGrpcService<WeatherService>();
app.MapGrpcService<AuthService>().EnableGrpcWeb();
app.MapGrpcService<TrackService>().EnableGrpcWeb();
app.MapGrpcService<StatsService>().EnableGrpcWeb();
app.MapGrpcService<IdentityService>().EnableGrpcWeb();
//app.MapGrpcService<AuthService>().EnableGrpcWeb();
//app.MapGrpcService<TrackService>().EnableGrpcWeb();
//app.MapGrpcService<StatsService>().EnableGrpcWeb();
//app.MapGrpcService<IdentityService>().EnableGrpcWeb();

app.MapCodeFirstGrpcReflectionService();


+ 8
- 7
IdentityProvider/Properties/launchSettings.json Прегледај датотеку

@@ -10,20 +10,21 @@
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
}
},
"IdentityProvider": {
"SpotifyService": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"dotnetRunMessages": "true"
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

+ 2
- 1
IdentityProvider/Services/IdentityService.cs Прегледај датотеку

@@ -38,7 +38,8 @@ namespace IdentityProvider.Services
return new UserResponse
{
Id = user.Id,
Token = user.Token
Token = user.Token,
RefreshToken = user.RefreshToken
};
else return new UserResponse();
}

+ 5
- 7
IdentityProvider/appsettings.json Прегледај датотеку

@@ -8,19 +8,17 @@
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
"Protocols": "Http1AndHttp2"
}
},
"AuthParams": {
"ClientId": "83e1d09876b049c4bb1953185a4b3bfb",
"RedirectURI": "https://localhost:44342/callback",
"Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private",
"ClientSecret": "ea752433d0774fad87fab5c1ee788c8d"
},
"SpotifyDb": {
"ConnectionString": "mongodb://127.0.0.1:27017",
"DatabaseName": "spotifyDb",
"UserCollection": "Users",
"TracksCollection": "Tracks"
}
//"SpotifyConfig": {
// "SpotifyURL": "https://api.spotify.com/v1/",
// "MediaType": "application/json"
//}
}

+ 12
- 26
NemAnCore/Pages/FetchData.razor Прегледај датотеку

@@ -1,6 +1,7 @@
@page "/search"
@using Grpc.Core
@using GrpcShared.DTO
@using GrpcShared.DTO.Db
@using GrpcShared.DTO.Search
@using GrpcShared.DTO.Track.MultipleTrack
@using GrpcShared.DTO.Track.SingleTrack
@@ -38,32 +39,17 @@

var userInfo = await localStorage.GetItemAsync<string>("user_info");

var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage
{
Id = userInfo
});

TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken };

SearchRequest request = new() { Query = "aitch", Type = "track", Token = user.Token };

try
{
SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);

if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService);
}
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
return;
}
throw;
}
UserResponse userResponse = await identityService.GetTokenByIdAsync(new DbRequestMessage { Id = userInfo });
//var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage
// {
// Id = userInfo
// });

//TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken };

SearchRequest request = new() { Query = "aitch", Type = "track", UserId = userInfo };

SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);

}


+ 10
- 41
NemAnCore/Pages/Home.razor Прегледај датотеку

@@ -33,61 +33,30 @@
tokenS = userResponse.Token;
refreshT = userResponse.RefreshToken;
}
else {
else
{
await localStorage.RemoveItemAsync("user_info");
NavigationMgr.NavigateTo("/");
}
}

//tokenS = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN";
TokenMessage token = new() { Token = tokenS, RefreshToken = refreshT };
UserResponse user = new() { Id = userId, RefreshToken = refreshT };
try
{
track = await spotifyService.GetCurrentlyPlayingTrack(token);

//if token expired, refresh it
if (track.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, user, localStorage, identityService);
tokenS = tempToken == null ? tokenS : tempToken;
//if refreshed token is null, that means that refresh token was invalid, so you should redirect to login
}
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
return;
}
throw;
}
track = await spotifyService.GetCurrentlyPlayingTrack(new SessionMessage { UserId = userId });


//napravi komponentu koja ce da prikazuje sta trenutno slusas i passuj joj parametre

//var trackById = await trackService.GetById(new GrpcShared.DTO.TrackByID.TrackRequest { TrackID = "4fy1A2WBTPX55mUI16TQXa", Token = tokenS });
try
{
var items = await spotifyService.GetTopItems(new GrpcShared.DTO.TopItem.TopItemRequest { Token = tokenS, IsTracks = false, Offset = 5 });

if (items.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, user, localStorage, identityService);
tokenS = tempToken == null ? tokenS : tempToken;
}
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
return;
}
throw;
}

var items = await spotifyService.GetTopItems(new GrpcShared.DTO.TopItem.TopItemRequest { UserId = userId, IsTracks = false, Offset = 5 });

await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest
{
TrackId = track.Item.Id,

+ 10
- 10
NemAnCore/Services/AuthClientService.cs Прегледај датотеку

@@ -9,6 +9,7 @@ using GrpcShared.DTO;
using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using Blazored.LocalStorage;
using GrpcShared.DTO.Db;

namespace NemAnBlazor.Services
{
@@ -57,7 +58,7 @@ namespace NemAnBlazor.Services
return await _serviceClient.GetAuthParams();
}

public async Task<UserInfoResponse> GetUserInfo(TokenMessage token)
public async Task<UserInfoResponse> GetUserInfo(UserResponse token)
{
return await _serviceClient.GetUserInfo(token);
}
@@ -67,19 +68,18 @@ namespace NemAnBlazor.Services
//return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
await Task.Delay(500);

string token = await _localStorage.GetItemAsync<string>("token");
string refreshT = await _localStorage.GetItemAsync<string>("refresh_token");

string userId = await _localStorage.GetItemAsync<string>("user_info");
//token = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN";
if (token == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
if (userId == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));

var userInfo = await _serviceClient.GetUserInfo(new TokenMessage { Token = token, RefreshToken = refreshT });
// var userInfo = await _serviceClient.GetUserInfo(new UserResponse { Token = token, RefreshToken = refreshT });

List<Claim> claims = new();

claims.Add(new Claim("email", userInfo.Email!));
claims.Add(new Claim("id", userInfo.Id!));
claims.Add(new Claim("name", userInfo.DisplayName!));
//claims.Add(new Claim("email", userInfo.Email!));
claims.Add(new Claim("id", userId!));
//claims.Add(new Claim("name", userInfo.DisplayName!));

ClaimsIdentity identity = new(claims, "jwt");
//ClaimsIdentity identity = new();
@@ -91,7 +91,7 @@ namespace NemAnBlazor.Services
return state;
}

public async Task<RefreshTokenResponse> RefreshAccessToken(TokenMessage token)
public async Task<RefreshTokenResponse> RefreshAccessToken(UserResponse token)
{
return await _serviceClient.RefreshAccessToken(token);
}

+ 3
- 2
NemAnCore/Services/Interfaces/IAuthClientService.cs Прегледај датотеку

@@ -1,6 +1,7 @@
using GrpcShared;
using GrpcShared.DTO;
using GrpcShared.DTO.Auth;
using GrpcShared.DTO.Db;
using GrpcShared.DTO.User;

namespace NemAnBlazor.Services.Interfaces
@@ -9,7 +10,7 @@ namespace NemAnBlazor.Services.Interfaces
{
Task<TokenResponse> GetAccessToken(TokenRequest tokenRequest);
Task<CodeRequest> GetAuthParams();
Task<UserInfoResponse> GetUserInfo(TokenMessage token);
Task<RefreshTokenResponse> RefreshAccessToken(TokenMessage token);
Task<UserInfoResponse> GetUserInfo(UserResponse token);
Task<RefreshTokenResponse> RefreshAccessToken(UserResponse token);
}
}

+ 1
- 1
NemAnCore/Services/Interfaces/IStatsClientService.cs Прегледај датотеку

@@ -6,7 +6,7 @@ namespace NemAnBlazor.Services.Interfaces
{
public interface IStatsClientService
{
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token);
Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(SessionMessage message);
Task<TopItemResponse> GetTopItems(TopItemRequest request);
}
}

+ 2
- 2
NemAnCore/Services/StatsClientService.cs Прегледај датотеку

@@ -15,9 +15,9 @@ namespace NemAnBlazor.Services
{
_serviceClient = channel.CreateGrpcService<IStatsService>();
}
public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token)
public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(SessionMessage message)
{
return await _serviceClient.GetCurrentlyPlayingTrack(token);
return await _serviceClient.GetCurrentlyPlayingTrack(message);
}

public async Task<TopItemResponse> GetTopItems(TopItemRequest request)

+ 80
- 15
gRPCServer/HttpUtils/HttpUtils.cs Прегледај датотеку

@@ -1,32 +1,97 @@
using Grpc.Net.Client;
using Grpc.Core;
using Grpc.Net.Client;
using GrpcShared.DTO.Db;
using GrpcShared.Interfaces;
using Microsoft.Net.Http.Headers;
using NemAnBlazor.Services.Interfaces;
using Newtonsoft.Json;

namespace SpotifyService.HttpUtils
{
public static class HttpUtils<T>
public static class HttpUtils<T> where T : new()
{
public static async Task<T> GetData(HttpClient client, string url, string token)
public static async Task<T> GetData
(IHttpClientFactory _httpClientFactory,
string url,
string userId,
IIdentityService identityService,
IAuthService authService)

{
//add header
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + token);
try
{
var client = _httpClientFactory.CreateClient("HttpClient");

var userResponse = await identityService.GetTokenByIdAsync(new DbRequestMessage { Id = userId });


//add header
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + userResponse.Token);

//get request
var req = await client.GetAsync(url);

//get request
var req = await client.GetAsync(url);
//read response
var response = JsonConvert.DeserializeObject<T>(await req.Content.ReadAsStringAsync())!;

//read response
var response = JsonConvert.DeserializeObject<T>(await req.Content.ReadAsStringAsync())!;

return response;
if (req.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
string newToken = await SpotifyHelper.TryRefreshToken(authService, userResponse, identityService);
if (newToken != null)
{
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + newToken);
req = await client.GetAsync(url);
response = JsonConvert.DeserializeObject<T>(await req.Content.ReadAsStringAsync())!;
}

//ako to ne radi to znaci da je refresh token isteko, treba da se refreshuje
}
return response;
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
//vrati message sa status kodom?
return new T();
}
throw;
}


}
public static async Task PutData(HttpClient client, string url, string token)
public static async Task PutData(HttpClient client, string url, string userId, IIdentityService identityService, IAuthService authService)
{
//add header
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + token);
try
{
var tokenMessage = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage { Id = userId });
//add header
client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + tokenMessage.Token);

//get request
var responseMessage = await client.PutAsync(url, null);

if(responseMessage.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
string newToken = await SpotifyHelper.TryRefreshToken(authService, tokenMessage, identityService);
if (newToken != null)
{
responseMessage = await client.PutAsync(url, null);
}
}
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
//vrati message sa status kodom?
return;
}
throw;
}

//get request
await client.PutAsync(url, null);

}


NemAnCore/SpotifyHelper.cs → gRPCServer/HttpUtils/SpotifyHelper.cs Прегледај датотеку

@@ -1,19 +1,18 @@
using Blazored.LocalStorage;
using GrpcShared.DTO;
using GrpcShared.DTO;
using GrpcShared.DTO.Db;
using GrpcShared.Interfaces;
using NemAnBlazor.Services.Interfaces;

namespace NemAnBlazor
namespace SpotifyService
{
public static class SpotifyHelper
{
public static async Task<string?> TryRefreshToken
(IAuthClientService authService,
TokenMessage msg,UserResponse user,
ILocalStorageService localStorage,
IIdentityClientService identityService)
(IAuthService authService,
UserResponse user,
IIdentityService identityService)
{
var refreshResponse = await authService.RefreshAccessToken(msg);
var refreshResponse = await authService.RefreshAccessToken(user);

if (refreshResponse.AccessToken != null)
{

+ 12
- 4
gRPCServer/Program.cs Прегледај датотеку

@@ -7,11 +7,12 @@ using GrpcShared.Interfaces;
using Polly;
using Polly.Extensions.Http;
using GrpcShared.DTO.Auth;
using IdentityProvider.Services;

var builder = WebApplication.CreateBuilder(args);

#if DEBUG
/*
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenLocalhost(5050, o => o.Protocols =
@@ -19,7 +20,7 @@ builder.WebHost.ConfigureKestrel(options =>
options.ListenLocalhost(5051, o => o.Protocols =
HttpProtocols.Http1AndHttp2);
});
*/
#endif

// Add services to the container.
@@ -86,9 +87,13 @@ builder.Services.AddSwaggerGen();
builder.Services.AddGrpc();
builder.Services.AddCodeFirstGrpc();
builder.Services.AddCodeFirstGrpcReflection();
builder.Services.Configure<CodeRequest>(builder.Configuration.GetSection("AuthParams"));

builder.Services.AddScoped<IIdentityService, IdentityService>();
builder.Services.AddScoped<IAuthService, AuthService>();

var app = builder.Build();
builder.Services.Configure<CodeRequest>(builder.Configuration.GetSection("AuthParams"));

app.UseSwagger();
app.UseSwaggerUI();
@@ -118,7 +123,10 @@ app.MapRazorPages();
app.MapControllers();

//app.MapGrpcService<AuthService>();
//app.MapGrpcService<AuthService>().EnableGrpcWeb();
app.MapGrpcService<AuthService>().EnableGrpcWeb();
app.MapGrpcService<TrackService>().EnableGrpcWeb();
app.MapGrpcService<StatsService>().EnableGrpcWeb();
app.MapGrpcService<IdentityService>().EnableGrpcWeb();


app.MapCodeFirstGrpcReflectionService();

+ 3
- 2
gRPCServer/Services/AuthService.cs Прегледај датотеку

@@ -4,6 +4,7 @@ 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;
@@ -76,7 +77,7 @@ namespace SpotifyService.Services
return await Task.FromResult(authParams);
}

public async Task<UserInfoResponse> GetUserInfo(TokenMessage tokenM)
public async Task<UserInfoResponse> GetUserInfo(UserResponse tokenM)
{
// expired token example "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"
@@ -106,7 +107,7 @@ namespace SpotifyService.Services

}

public async Task<RefreshTokenResponse> RefreshAccessToken(TokenMessage tokenM)
public async Task<RefreshTokenResponse> RefreshAccessToken(UserResponse tokenM)
{
var client = _httpClientFactory.CreateClient("HttpClient");
client.BaseAddress = new Uri("https://accounts.spotify.com/api/token");

+ 10
- 8
gRPCServer/Services/StatsService.cs Прегледај датотеку

@@ -12,18 +12,21 @@ namespace SpotifyService.Services
public class StatsService : IStatsService
{
private readonly IHttpClientFactory _httpClientFactory;

public StatsService(IHttpClientFactory httpClientFactory)
private IIdentityService _identityService;
private IAuthService _authService;
public StatsService(IHttpClientFactory httpClientFactory, IIdentityService identityService, IAuthService authService)
{
_httpClientFactory = httpClientFactory;
_identityService = identityService;
_authService = authService;
}

public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(TokenMessage token)

public async Task<CurrentTrackResponse> GetCurrentlyPlayingTrack(SessionMessage message)
{
var client = _httpClientFactory.CreateClient("HttpClient");
string url = "me/player/currently-playing";
var response = await HttpUtils<CurrentTrackResponse>.GetData(client, url, token.Token!);
var response = await HttpUtils<CurrentTrackResponse>.GetData(_httpClientFactory, url, message.UserId, _identityService, _authService);
return response;

@@ -32,7 +35,6 @@ namespace SpotifyService.Services
public async Task<TopItemResponse> GetTopItems(TopItemRequest request)
{
//https://api.spotify.com/v1/me/top/albums?limit=10&offset=5
var client = _httpClientFactory.CreateClient("HttpClient");

//URL PARAMS
string url = "me/top/";
@@ -42,7 +44,7 @@ namespace SpotifyService.Services
if (request.Limit == null && request.Offset != null) url += $"?offset={request.Offset}";
else url += request.Offset == null ? "" : $"&offset={request.Offset}";

return await HttpUtils<TopItemResponse>.GetData(client, url, request.Token!);
return await HttpUtils<TopItemResponse>.GetData(_httpClientFactory, url, request.UserId!, _identityService, _authService);

}
}

+ 13
- 13
gRPCServer/Services/TrackService.cs Прегледај датотеку

@@ -22,39 +22,40 @@ namespace SpotifyService.Services
public class TrackService : ITrackService
{
private readonly IHttpClientFactory _httpClientFactory;
public TrackService(IHttpClientFactory httpClientFactory)
private IIdentityService _identityService;
private IAuthService _authService;

public TrackService(IHttpClientFactory httpClientFactory, IIdentityService identityService, IAuthService authService)
{
_httpClientFactory = httpClientFactory;
_identityService = identityService;
_authService = authService;
}
public async Task<SearchResponse> ListSearchAsync(SearchRequest request)
{

var client = _httpClientFactory.CreateClient("HttpClient");

string url = $"search?q={request.Query}&type={request.Type}";

return await HttpUtils.HttpUtils<SearchResponse>.GetData(client, url, request.Token!);
return await HttpUtils.HttpUtils<SearchResponse>.GetData(_httpClientFactory, url, request.UserId!, _identityService, _authService);


}
public async Task<SingleTrackResponse> ListSingleTrackAsync(SingleTrackRequest request)
{
var client = _httpClientFactory.CreateClient("HttpClient");
string url = $"audio-features/{request.Id}";
return await HttpUtils.HttpUtils<SingleTrackResponse>.GetData(client, url, request.Token!);
return await HttpUtils.HttpUtils<SingleTrackResponse>.GetData(_httpClientFactory, url, request.UserId!, _identityService,_authService);
}
public async Task<MultipleTrackResponse> ListMultipleTrackAsync(MultipleTrackRequest request)
{
var client = _httpClientFactory.CreateClient("HttpClient");

var param = new Dictionary<string, List<string>>();
param["ids"] = request.Ids!;

var query = UriUtil(param);
string url = $"audio-features{query}";

return await HttpUtils.HttpUtils<MultipleTrackResponse>.GetData(client,url,request.Token!);
return await HttpUtils.HttpUtils<MultipleTrackResponse>.GetData(_httpClientFactory, url, request.UserId, _identityService, _authService);
}
public async Task SaveTracks(SaveTracksRequest request)
{
@@ -67,7 +68,7 @@ namespace SpotifyService.Services
string url = $"me/tracks/{query}";

//the response type has nothing to do with the method, it's there so that the method can be called
await HttpUtils.HttpUtils<StatusCodeMessage>.PutData(client, url, request.Token!);
await HttpUtils.HttpUtils<StatusCodeMessage>.PutData(client, url, request.UserId!, _identityService, _authService);
}
public static string UriUtil(Dictionary<string, List<string>> param)
@@ -93,11 +94,10 @@ namespace SpotifyService.Services
}
public async Task<TrackResponse> GetById(TrackRequest request)
{
var client = _httpClientFactory.CreateClient("HttpClient");

string url = $"tracks/{request.TrackID}";

return await HttpUtils.HttpUtils<TrackResponse>.GetData(client, url, request.Token!);
return await HttpUtils.HttpUtils<TrackResponse>.GetData(_httpClientFactory, url, request.UserId!, _identityService, _authService);
}
}
}

+ 1
- 0
gRPCServer/SpotifyService.csproj Прегледај датотеку

@@ -22,6 +22,7 @@

<ItemGroup>
<ProjectReference Include="..\GrpcShared\GrpcShared.csproj" />
<ProjectReference Include="..\IdentityProvider\IdentityProvider.csproj" />
<ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" />
</ItemGroup>


Loading…
Откажи
Сачувај