Parcourir la source

Merge branch 'feature/mongodb' into dev

master
anastasijasavov il y a 3 ans
Parent
révision
3b62a1a209

+ 17
- 0
GrpcShared/DTO/Db/DbRequestMessage.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.Db
{
[ProtoContract]
public class DbRequestMessage
{
[ProtoMember(1)]
public string Id { get; set; }

}
}

+ 16
- 0
GrpcShared/DTO/Db/SaveTrackRequest.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.Db
{
[ProtoContract]
public class SaveTrackRequest : TrackResponse
{
[ProtoMember(1)]
public string UserId { get; set; }
}
}

+ 25
- 0
GrpcShared/DTO/Db/TrackResponse.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.Db
{
[ProtoContract]
[ProtoInclude(6, typeof(SaveTrackRequest))]
public class TrackResponse
{
[ProtoMember(1)]
public string Id { get; set; }
[ProtoMember(2)]
public string Title { get; set; }
[ProtoMember(3)]
public string Artist { get; set; }
[ProtoMember(4)]
public string Album { get; set; }
[ProtoMember(5)]
public string TrackId { get; set; }
}
}

+ 20
- 0
GrpcShared/DTO/Db/UserResponse.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO.Db
{
[ProtoContract]
public class UserResponse
{
[ProtoMember(1)]
public string Id { get; set; }
[ProtoMember(2)]
public string Token { get; set; }
[ProtoMember(3)]
public string RefreshToken{ get; set; }
}
}

+ 17
- 0
GrpcShared/DTO/VoidMessage.cs Voir le fichier

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.DTO
{
[ProtoContract]
public class VoidMessage
{
[ProtoMember(1)]
public string InsertedId { get; set; }
}
}

+ 24
- 0
GrpcShared/Interfaces/IIdentityService.cs Voir le fichier

using GrpcShared.DTO;
using GrpcShared.DTO.Db;
using ProtoBuf.Grpc.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrpcShared.Interfaces
{
[Service]
public interface IIdentityService
{
Task<UserResponse> GetTokenByIdAsync(DbRequestMessage id);
Task<List<UserResponse>> ListUsersAsync(VoidMessage msg);
Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage id);
Task<VoidMessage> SaveTrackAsync(SaveTrackRequest track);
Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id);
Task<VoidMessage> SaveUserAsync(UserResponse user);
Task<VoidMessage> DeleteUserAsync(DbRequestMessage user);
Task<VoidMessage> UpdateTokenAsync (UserResponse user);
}
}

+ 1
- 4
IdentityProvider/IdentityProvider.csproj Voir le fichier

<PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" />
<PackageReference Include="MongoDB.Driver" Version="2.17.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.152" /> <PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.152" />
<ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" />
</ItemGroup> </ItemGroup>


<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>

</Project> </Project>

+ 10
- 0
IdentityProvider/Models/SpotifyDbConfig.cs Voir le fichier

namespace IdentityProvider.Models
{
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!;
}
}

+ 17
- 0
IdentityProvider/Models/TrackModel.cs Voir le fichier

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace IdentityProvider.Models
{
public class TrackModel
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
public string Album { get; set; }
public string UserId { get; set; }
public string TrackId { get; set; }
}
}

+ 14
- 0
IdentityProvider/Models/UserModel.cs Voir le fichier

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace IdentityProvider.Models
{
public class UserModel
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Token { get; set; }
public string RefreshToken { get; set; }
}
}

+ 10
- 1
IdentityProvider/Program.cs Voir le fichier

using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using GrpcShared.DTO.Auth; using GrpcShared.DTO.Auth;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using IdentityProvider.Models;
using IdentityProvider.Services;


var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
#if DEBUG #if DEBUG
}); });
builder.Services.AddOptions(); builder.Services.AddOptions();
builder.Services.AddSingleton<SpotifyDbConfig>();
// Additional configuration is required to successfully run gRPC on macOS. // 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 // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
builder.Services.AddControllersWithViews(); builder.Services.AddControllersWithViews();
builder.Services.AddBlazoredLocalStorage(); builder.Services.AddBlazoredLocalStorage();
//call spotify api //call spotify api
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
builder.Services.Configure<CodeRequest>(builder.Configuration.GetSection("AuthParams"));

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

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


var app = builder.Build(); var app = builder.Build();


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


app.MapCodeFirstGrpcReflectionService(); app.MapCodeFirstGrpcReflectionService();



+ 8
- 9
IdentityProvider/Properties/launchSettings.json Voir le fichier

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

+ 131
- 0
IdentityProvider/Services/IdentityService.cs Voir le fichier

using GrpcShared.DTO;
using GrpcShared.DTO.Db;
using GrpcShared.Interfaces;
using IdentityProvider.Models;
using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace IdentityProvider.Services
{
public class IdentityService : IIdentityService
{
private readonly IMongoCollection<UserModel> _userCollection;
private readonly IMongoCollection<TrackModel> _trackCollection;
public IdentityService(IOptions<SpotifyDbConfig> spotifyDbConfig)
{
var mongoClient = new MongoClient(spotifyDbConfig.Value.ConnectionString);
var mongoDbContext = mongoClient.GetDatabase(spotifyDbConfig.Value.DatabaseName);
_userCollection = mongoDbContext.GetCollection<UserModel>(spotifyDbConfig.Value.UserCollection);
_trackCollection = mongoDbContext.GetCollection<TrackModel>(spotifyDbConfig.Value.TracksCollection);
}


public async Task<List<UserResponse>> ListUsersAsync(VoidMessage msg)
{
List<UserModel> users = await _userCollection.Find(_ => true).ToListAsync();
//map users to match the grpc response
var usersRes = users.Select(u => new UserResponse
{
Id = u.Id,
Token = u.Token
}).ToList();
return usersRes;
}
public async Task<UserResponse> GetTokenByIdAsync(DbRequestMessage request)
{
UserModel user = await _userCollection.Find(u => u.Id == request.Id).FirstOrDefaultAsync();
if (user != null)
return new UserResponse
{
Id = user.Id,
Token = user.Token
};
else return new UserResponse();
}
public async Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage request)
{
TrackModel track = await _trackCollection.Find(t => t.UserId == request.Id).FirstOrDefaultAsync();
return new TrackResponse
{
Id = track.Id,
Album = track.Album,
Artist = track.Artist,
Title = track.Title,
TrackId = track.TrackId
};
}
public async Task<VoidMessage> SaveTrackAsync(SaveTrackRequest track)
{

TrackModel trackModel = new()
{
Id = track.Id,
Title = track.Title,
Album = track.Album,
Artist = track.Artist,
UserId = track.UserId,
TrackId = track.TrackId
};
//first check if there's already a song in the db, if yes, update the row
bool song = await _trackCollection.Find(x => x.UserId == track.UserId).AnyAsync();

if (song) await _trackCollection.DeleteOneAsync(s => s.UserId == track.UserId);

await _trackCollection.InsertOneAsync(trackModel);

return new VoidMessage() { InsertedId = trackModel.Id };


}
public async Task<VoidMessage> SaveUserAsync(UserResponse userRequest)
{
bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync();

UserModel tempUser = new()
{
Token = userRequest.Token,
RefreshToken = userRequest.RefreshToken
};

if (!user) await _userCollection.InsertOneAsync(tempUser);

return new VoidMessage() { InsertedId = tempUser.Id };

}
public async Task<VoidMessage> DeleteTrackAsync(DbRequestMessage request)
{
await _trackCollection.DeleteOneAsync(x => x.Id == request.Id);
return new VoidMessage();
}
public async Task<VoidMessage> DeleteUserAsync(DbRequestMessage userRequest)
{
//check if user exists
bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync();
//delete track related to him
if (user)
{
await _trackCollection.DeleteManyAsync(x => x.UserId == userRequest.Id);
//delete user
await _userCollection.DeleteOneAsync(x => x.Id == userRequest.Id);
}
return new VoidMessage();
}

public async Task<VoidMessage> UpdateTokenAsync(UserResponse user)
{

UserModel dbUser = await _userCollection.Find(x => x.Id == user.Id).FirstOrDefaultAsync();
if (dbUser.Id != null)
{
dbUser.Token = user.Token;
dbUser.RefreshToken = user.RefreshToken;
await _userCollection.ReplaceOneAsync(x => x.Id == user.Id, dbUser);
}

return new VoidMessage
{
InsertedId = dbUser.Id
};
}
}
}

+ 6
- 0
IdentityProvider/appsettings.json Voir le fichier

"RedirectURI": "https://localhost:44342/callback", "RedirectURI": "https://localhost:44342/callback",
"Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private", "Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read user-read-private",
"ClientSecret": "ea752433d0774fad87fab5c1ee788c8d" "ClientSecret": "ea752433d0774fad87fab5c1ee788c8d"
},
"SpotifyDb": {
"ConnectionString": "mongodb://127.0.0.1:27017",
"DatabaseName": "spotifyDb",
"UserCollection": "Users",
"TracksCollection": "Tracks"
} }
} }

+ 18
- 3
NemAnCore/Pages/Callback.razor Voir le fichier

@page "/callback" @page "/callback"
@using GrpcShared.DTO
@using GrpcShared.DTO.Db
@using NemAnBlazor.Services.Interfaces @using NemAnBlazor.Services.Interfaces
@inject NavigationManager NavigationMgr @inject NavigationManager NavigationMgr
@inject IAuthClientService AuthService @inject IAuthClientService AuthService
@inject Blazored.LocalStorage.ILocalStorageService localStorage @inject Blazored.LocalStorage.ILocalStorageService localStorage
@inject IIdentityClientService identityService

<PageTitle>Redirecting...</PageTitle> <PageTitle>Redirecting...</PageTitle>




//if (response.access_token == null) NavigationMgr.NavigateTo("/"); //if (response.access_token == null) NavigationMgr.NavigateTo("/");


//store access token in local storage //store access token in local storage
await localStorage.SetItemAsync("token", response.AccessToken);
await localStorage.SetItemAsync("refresh_token", response.RefreshToken);
//await localStorage.SetItemAsync("token", response.AccessToken);
//await localStorage.SetItemAsync("refresh_token", response.RefreshToken);
//UserResponse user = new();
//await identityService.SaveUserAsync(new GrpcShared.DTO.Db.UserResponse());
string userId = await localStorage.GetItemAsync<string>("user_info");
if(userId == null)
{
VoidMessage userRes = await identityService.SaveUserAsync(new GrpcShared.DTO.Db.UserResponse { RefreshToken = response.RefreshToken , Token = response.AccessToken});
if (userRes.InsertedId != null)
await localStorage.SetItemAsync<string>("user_info", userRes.InsertedId);
}
//redirect to home //redirect to home
NavigationMgr.NavigateTo("/home"); NavigationMgr.NavigateTo("/home");
} }

+ 10
- 6
NemAnCore/Pages/FetchData.razor Voir le fichier

@inject Blazored.LocalStorage.ILocalStorageService localStorage @inject Blazored.LocalStorage.ILocalStorageService localStorage
@inject ITrackClientService SearchService @inject ITrackClientService SearchService
@inject IAuthClientService AuthService @inject IAuthClientService AuthService
@inject IIdentityClientService identityService




<PageTitle>Search</PageTitle> <PageTitle>Search</PageTitle>
private async Task Click() private async Task Click()
{ {


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


TokenMessage tokenM = new TokenMessage { Token = token, RefreshToken = refreshT };
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 = token };
SearchRequest request = new() { Query = "aitch", Type = "track", Token = user.Token };


try try
{ {


if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{ {
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, localStorage);
token = tempToken == null ? token : tempToken;
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService);
} }
} }
catch (RpcException e) catch (RpcException e)

+ 65
- 7
NemAnCore/Pages/Home.razor Voir le fichier

@page "/home" @page "/home"
@using Grpc.Core @using Grpc.Core
@using GrpcShared.DTO @using GrpcShared.DTO
@using GrpcShared.DTO.Db
@using GrpcShared.DTO.Track @using GrpcShared.DTO.Track
@using NemAnBlazor.Services.Interfaces @using NemAnBlazor.Services.Interfaces
@using System.Net @using System.Net
@inject IStatsClientService spotifyService @inject IStatsClientService spotifyService
@inject ITrackClientService trackService @inject ITrackClientService trackService
@inject IAuthClientService AuthService @inject IAuthClientService AuthService
@inject NavigationManager NavigationMgr
@inject IIdentityClientService identityService


<h3>Home</h3> <h3>Home</h3>


@code { @code {
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
CurrentTrackResponse track;
string tokenS = "", refreshT = "";
string userId = await localStorage.GetItemAsync<string>("user_info");


string tokenS = await localStorage.GetItemAsync<string>("token");
string refreshT = await localStorage.GetItemAsync<string>("refresh_token");
if (userId != null)
{
//get token from identity
var userResponse = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage { Id = userId });


//tokenS = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN";
TokenMessage token = new TokenMessage { Token = tokenS, RefreshToken = refreshT };
if (userResponse != null)
{
tokenS = userResponse.Token;
refreshT = userResponse.RefreshToken;
}
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 try
{ {
CurrentTrackResponse track = await spotifyService.GetCurrentlyPlayingTrack(token);
track = await spotifyService.GetCurrentlyPlayingTrack(token);


//if token expired, refresh it //if token expired, refresh it
if (track.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) if (track.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{ {
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, localStorage);
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, user, localStorage, identityService);
tokenS = tempToken == null ? tokenS : tempToken; tokenS = tempToken == null ? tokenS : tempToken;
//if refreshed token is null, that means that refresh token was invalid, so you should redirect to login //if refreshed token is null, that means that refresh token was invalid, so you should redirect to login
} }


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




await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest
{
TrackId = track.Item.Id,
Title = track.Item.Name,
Album = track.Item.Album.Name,
Artist = track.Item.Artists[0].Name,
UserId = userId
});

//var resp = await identityService.ListUsersAsync(new VoidMessage());

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

var trackByUser = await identityService.GetTrackByUserAsync(new GrpcShared.DTO.Db.DbRequestMessage
{
Id = userId
});
//await identityService.DeleteTrackAsync(new GrpcShared.DTO.Db.DbRequestMessage
// {
// Id =
// });
await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest
{

TrackId = track.Item.Id,
Title = track.Item.Name,
Album = track.Item.Album.Name,
Artist = track.Item.Artists[0].Name,
UserId = userId
});
//find id from local storage
//await identityService.DeleteUserAsync(new GrpcShared.DTO.Db.DbRequestMessage
// {
// Id = userId
// });
} }
} }

+ 6
- 0
NemAnCore/Pages/Login.razor Voir le fichier

@inject IAuthClientService AuthService @inject IAuthClientService AuthService
@inject ITrackClientService SearchService @inject ITrackClientService SearchService
@using System.Security.Claims @using System.Security.Claims
@inject Blazored.LocalStorage.ILocalStorageService localStorage




@code { @code {
private string? message; private string? message;


protected override async Task OnInitializedAsync()
{
var userId = await localStorage.GetItemAsync<string>("user_info");
if (userId != null) NavigationManager.NavigateTo("/home");


}
private async Task LoginUser() private async Task LoginUser()
{ {
//var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"}); //var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"});

+ 1
- 0
NemAnCore/Program.cs Voir le fichier

builder.Services.AddScoped<ITrackClientService, TrackClientService>(); builder.Services.AddScoped<ITrackClientService, TrackClientService>();
builder.Services.AddScoped<IAuthClientService, AuthClientService>(); builder.Services.AddScoped<IAuthClientService, AuthClientService>();
builder.Services.AddScoped<IStatsClientService, StatsClientService>(); builder.Services.AddScoped<IStatsClientService, StatsClientService>();
builder.Services.AddScoped<IIdentityClientService, IdentityClientService>();
builder.Services.AddBlazoredLocalStorage(); builder.Services.AddBlazoredLocalStorage();
builder.Services.AddScoped<AuthenticationStateProvider, AuthClientService>(); builder.Services.AddScoped<AuthenticationStateProvider, AuthClientService>();
builder.Services.AddAuthorizationCore(); builder.Services.AddAuthorizationCore();

+ 57
- 0
NemAnCore/Services/IdentityClientService.cs Voir le fichier

using Grpc.Net.Client;
using GrpcShared.DTO;
using GrpcShared.DTO.Db;
using GrpcShared.Interfaces;
using NemAnBlazor.Services.Interfaces;
using ProtoBuf.Grpc.Client;

namespace NemAnBlazor.Services
{
public class IdentityClientService : IIdentityClientService
{
private IIdentityService _serviceClient;
public IdentityClientService(GrpcChannel channel)
{
_serviceClient = channel.CreateGrpcService<IIdentityService>();
}
public async Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id)
{
return await _serviceClient.DeleteTrackAsync(id);
}

public async Task<VoidMessage> DeleteUserAsync(DbRequestMessage user)
{
return await _serviceClient.DeleteUserAsync(user);
}

public async Task<UserResponse> GetTokenByIdAsync(DbRequestMessage id)
{
return await _serviceClient.GetTokenByIdAsync(id);
}

public async Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage id)
{
return await _serviceClient.GetTrackByUserAsync(id);
}

public async Task<List<UserResponse>> ListUsersAsync(VoidMessage msg)
{
return await _serviceClient.ListUsersAsync(msg);
}

public async Task<VoidMessage> SaveTrackAsync(SaveTrackRequest track)
{
return await _serviceClient.SaveTrackAsync(track);
}

public async Task<VoidMessage> SaveUserAsync(UserResponse user)
{
return await _serviceClient.SaveUserAsync(user);
}

public async Task<VoidMessage> UpdateTokenAsync(UserResponse user)
{
return await _serviceClient.UpdateTokenAsync(user);
}
}
}

+ 17
- 0
NemAnCore/Services/Interfaces/IIdentityClientService.cs Voir le fichier

using GrpcShared.DTO;
using GrpcShared.DTO.Db;

namespace NemAnBlazor.Services.Interfaces
{
public interface IIdentityClientService
{
Task<UserResponse> GetTokenByIdAsync(DbRequestMessage id);
Task<List<UserResponse>> ListUsersAsync(VoidMessage msg);
Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage id);
Task<VoidMessage> SaveTrackAsync(SaveTrackRequest track);
Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id);
Task<VoidMessage> SaveUserAsync(UserResponse user);
Task<VoidMessage> DeleteUserAsync(DbRequestMessage user);
Task<VoidMessage> UpdateTokenAsync(UserResponse user);
}
}

+ 12
- 2
NemAnCore/SpotifyHelper.cs Voir le fichier

using Blazored.LocalStorage; using Blazored.LocalStorage;
using GrpcShared.DTO; using GrpcShared.DTO;
using GrpcShared.DTO.Db;
using NemAnBlazor.Services.Interfaces; using NemAnBlazor.Services.Interfaces;


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


if (refreshResponse.AccessToken != null) if (refreshResponse.AccessToken != null)
{ {
await localStorage.SetItemAsync<string>("token", refreshResponse.AccessToken);
await identityService.UpdateTokenAsync(new UserResponse
{
Id = user.Id,
Token = refreshResponse.AccessToken,
RefreshToken = user.RefreshToken
});
return refreshResponse.AccessToken; return refreshResponse.AccessToken;
} }
else return null; else return null;

+ 5
- 0
SpotifyWorker/SpotifyWorker.csproj Voir le fichier

<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" />
</ItemGroup> </ItemGroup>

<ItemGroup>
<ProjectReference Include="..\gRPCServer\SpotifyService.csproj" />
<ProjectReference Include="..\IdentityProvider\IdentityProvider.csproj" />
</ItemGroup>
</Project> </Project>

+ 8
- 3
SpotifyWorker/Worker.cs Voir le fichier

public class Worker : BackgroundService public class Worker : BackgroundService
{ {
private readonly ILogger<Worker> _logger; private readonly ILogger<Worker> _logger;
private HttpClient _httpClient;
public Worker(ILogger<Worker> logger) public Worker(ILogger<Worker> logger)
{ {
_logger = logger; _logger = logger;
} }

public override Task StartAsync(CancellationToken cancellationToken)
{
_httpClient = new HttpClient();
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{ {
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
await Task.Delay(5000, stoppingToken);
} }
} }
} }

Chargement…
Annuler
Enregistrer