| using System; | |||||
| namespace Shared | |||||
| { | |||||
| public static class GLOBALS | |||||
| { | |||||
| public const String SPOTIFYURL = "https://api.spotify.com/v1/"; | |||||
| public const String MEDIATYPE = "application/json"; | |||||
| } | |||||
| } |
| <Router AppAssembly="@typeof(App).Assembly"> | |||||
| <CascadingAuthenticationState> | |||||
| <Router AppAssembly="@typeof(App).Assembly"> | |||||
| <Found Context="routeData"> | <Found Context="routeData"> | ||||
| <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> | |||||
| <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" > | |||||
| <Authorizing> | |||||
| <text>Please wait, we are authorizint the user.</text> | |||||
| </Authorizing> | |||||
| </AuthorizeRouteView> | |||||
| <FocusOnNavigate RouteData="@routeData" Selector="h1" /> | <FocusOnNavigate RouteData="@routeData" Selector="h1" /> | ||||
| </Found> | </Found> | ||||
| <NotFound> | <NotFound> | ||||
| </LayoutView> | </LayoutView> | ||||
| </NotFound> | </NotFound> | ||||
| </Router> | </Router> | ||||
| </CascadingAuthenticationState> |
| @page "/search" | @page "/search" | ||||
| @attribute [Authorize] | |||||
| @using Grpc.Core | @using Grpc.Core | ||||
| @using GrpcShared.DTO | @using GrpcShared.DTO | ||||
| @using GrpcShared.DTO.Search | @using GrpcShared.DTO.Search | ||||
| @using GrpcShared.DTO.Track.MultipleTrack | @using GrpcShared.DTO.Track.MultipleTrack | ||||
| @using GrpcShared.DTO.Track.SingleTrack | @using GrpcShared.DTO.Track.SingleTrack | ||||
| @using Microsoft.AspNetCore.Authorization | |||||
| @using NemAnBlazor.Services | |||||
| @using NemAnBlazor.Services.Interfaces | @using NemAnBlazor.Services.Interfaces | ||||
| @using System.Diagnostics | @using System.Diagnostics | ||||
| @*@inject HttpClient Http*@ | @*@inject HttpClient Http*@ | ||||
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| <AuthorizeView> | |||||
| <Authorized> | |||||
| The user is authorized | |||||
| </Authorized> | |||||
| <NotAuthorized> | |||||
| The User is not authorized | |||||
| </NotAuthorized> | |||||
| </AuthorizeView> | |||||
| <PageTitle>Search</PageTitle> | <PageTitle>Search</PageTitle> | ||||
| <h1>Search</h1> | <h1>Search</h1> | ||||
| <button class="btn btn-primary" @onclick="Click">Click me</button> | |||||
| <AuthorizeView> | |||||
| <Authorized> | |||||
| <button class="btn btn-primary" @onclick="Click">Click me</button> | |||||
| </Authorized> | |||||
| </AuthorizeView> | |||||
| @code { | @code { | ||||
| protected override async Task OnInitializedAsync() | protected override async Task OnInitializedAsync() | ||||
| { | { | ||||
| //MultipleTrackRequest mreq = new() { Ids = new List<string>(){"3JAeYOjyJodI4PRs44lx2l", "6clZa1yrZe7pJrYFUcD9KW"}, Token = token }; | //MultipleTrackRequest mreq = new() { Ids = new List<string>(){"3JAeYOjyJodI4PRs44lx2l", "6clZa1yrZe7pJrYFUcD9KW"}, Token = token }; | ||||
| //MultipleTrackResponse multipleTrackResponse = await SearchService.GetListMultipleTrackAsync(mreq); | //MultipleTrackResponse multipleTrackResponse = await SearchService.GetListMultipleTrackAsync(mreq); | ||||
| var token = await sessionStorage.GetItemAsync<string>("token"); | var token = await sessionStorage.GetItemAsync<string>("token"); | ||||
| TokenMessage tm = new() { Token = token }; | TokenMessage tm = new() { Token = token }; | ||||
| if ((await AuthService.GetUserInfo(tm)) != null) | |||||
| { | |||||
| SearchRequest request = new() { Query = "aitch", Type = "track", Token = token }; | SearchRequest request = new() { Query = "aitch", Type = "track", Token = token }; | ||||
| SearchResponse searchResponse = await SearchService.GetListSearchAsync(request); | SearchResponse searchResponse = await SearchService.GetListSearchAsync(request); | ||||
| } | |||||
| } | } | ||||
| @inject NavigationManager NavigationManager | @inject NavigationManager NavigationManager | ||||
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| @inject ITrackClientService SearchService | @inject ITrackClientService SearchService | ||||
| @using System.Security.Claims | |||||
| <AuthorizeView> | |||||
| <Authorized> | |||||
| Dobrodosli @context.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value.ToUpper() | |||||
| </Authorized> | |||||
| <NotAuthorized> | |||||
| Nisi autorizovan. | |||||
| <button class="btn btn-primary" @onclick="Login">Autorizuj</button> | |||||
| </NotAuthorized> | |||||
| </AuthorizeView> | |||||
| <PageTitle>Index</PageTitle> | <PageTitle>Index</PageTitle> | ||||
| <h1>Pozdrav Diligent!</h1> | <h1>Pozdrav Diligent!</h1> | ||||
| Dobrodošli u našu NemAn aplikaciju. | Dobrodošli u našu NemAn aplikaciju. | ||||
| @code { | @code { | ||||
| private string message; | |||||
| protected override async Task OnInitializedAsync() | protected override async Task OnInitializedAsync() | ||||
| { | |||||
| message = "Cao"; | |||||
| } | |||||
| private async Task Login() | |||||
| { | { | ||||
| //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"}); | ||||
| CodeRequest authParams = await AuthService.GetAuthParams(); | |||||
| CodeRequest authParams = await AuthService.GetAuthParams(); | |||||
| // await AuthService.GetAccessToken(new CodeResponse{ Code = "hello"}); | // await AuthService.GetAccessToken(new CodeResponse{ Code = "hello"}); | ||||
| string url = $"https://accounts.spotify.com/en/authorize?client_id={authParams.ClientId}&redirect_uri={authParams.RedirectURI}&response_type={authParams.ResponseType}&scope={authParams.Scope}&show_dialog={authParams.ShowDialog}"; | string url = $"https://accounts.spotify.com/en/authorize?client_id={authParams.ClientId}&redirect_uri={authParams.RedirectURI}&response_type={authParams.ResponseType}&scope={authParams.Scope}&show_dialog={authParams.ShowDialog}"; | ||||
| NavigationManager.NavigateTo(url); | NavigationManager.NavigateTo(url); | ||||
| } | } | ||||
| } | } |
| using Grpc.Net.Client; | using Grpc.Net.Client; | ||||
| using Grpc.Net.Client.Web; | using Grpc.Net.Client.Web; | ||||
| using Microsoft.AspNetCore.Components; | using Microsoft.AspNetCore.Components; | ||||
| using Microsoft.AspNetCore.Components.Authorization; | |||||
| using Microsoft.AspNetCore.Components.Web; | using Microsoft.AspNetCore.Components.Web; | ||||
| using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | ||||
| using NemAnBlazor; | using NemAnBlazor; | ||||
| return channel; | return channel; | ||||
| }); | }); | ||||
| builder.Services.AddAuthorizationCore(); | |||||
| builder.Services.AddScoped<AuthenticationStateProvider, AuthClientService>(); | |||||
| builder.Services.AddScoped<ITrackClientService, TrackClientService>(); | builder.Services.AddScoped<ITrackClientService, TrackClientService>(); | ||||
| builder.Services.AddScoped<IAuthClientService, AuthClientService>(); | builder.Services.AddScoped<IAuthClientService, AuthClientService>(); |
| namespace NemAnBlazor.Services | namespace NemAnBlazor.Services | ||||
| { | { | ||||
| public class AuthClientService : IAuthClientService | |||||
| public class AuthClientService : AuthenticationStateProvider, IAuthClientService | |||||
| { | { | ||||
| private IAuthService _serviceClient; | private IAuthService _serviceClient; | ||||
| public AuthClientService(GrpcChannel grpcChannel) | |||||
| private ISessionStorageService _sessionStorage; | |||||
| public AuthClientService(GrpcChannel grpcChannel, ISessionStorageService sessionStorage) | |||||
| { | { | ||||
| _serviceClient = grpcChannel.CreateGrpcService<IAuthService>(); | _serviceClient = grpcChannel.CreateGrpcService<IAuthService>(); | ||||
| _sessionStorage = sessionStorage; | |||||
| } | } | ||||
| public async Task<TokenResponse> GetAccessToken(TokenRequest request) | public async Task<TokenResponse> GetAccessToken(TokenRequest request) | ||||
| { | { | ||||
| return await _serviceClient.GetUserInfo(token); | return await _serviceClient.GetUserInfo(token); | ||||
| } | } | ||||
| //public override async Task<AuthenticationState> GetAuthenticationStateAsync() | |||||
| //{ | |||||
| // string token = await _sessionStorage.GetItemAsync<string>("token"); | |||||
| public override async Task<AuthenticationState> GetAuthenticationStateAsync() | |||||
| { | |||||
| await Task.Delay(1500); | |||||
| string token = await _sessionStorage.GetItemAsync<string>("token"); | |||||
| // //token = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"; | |||||
| // if (token == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); | |||||
| //token = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"; | |||||
| if (token == null) return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); | |||||
| // var userInfo = await _serviceClient.GetUserInfo(new TokenMessage { Token = token }); | |||||
| var userInfo = await _serviceClient.GetUserInfo(new TokenMessage { Token = token }); | |||||
| // List<Claim> claims = new(); | |||||
| List<Claim> claims = new(); | |||||
| // claims.Add(new Claim("email", userInfo.email!)); | |||||
| // claims.Add(new Claim("id", userInfo.id!)); | |||||
| // claims.Add(new Claim("name", userInfo.display_name!)); | |||||
| claims.Add(new Claim("email", userInfo.email!)); | |||||
| claims.Add(new Claim("id", userInfo.id!)); | |||||
| claims.Add(new Claim("name", userInfo.display_name!)); | |||||
| // ClaimsIdentity identity = new(claims, "jwt"); | |||||
| // //ClaimsIdentity identity = new(); | |||||
| // ClaimsPrincipal user = new(identity); | |||||
| // AuthenticationState state = new(user); | |||||
| ClaimsIdentity identity = new(claims, "jwt"); | |||||
| //ClaimsIdentity identity = new(); | |||||
| ClaimsPrincipal user = new(identity); | |||||
| AuthenticationState state = new(user); | |||||
| // NotifyAuthenticationStateChanged(Task.FromResult(state)); | |||||
| NotifyAuthenticationStateChanged(Task.FromResult(state)); | |||||
| // return state; | |||||
| //} | |||||
| return state; | |||||
| } | |||||
| } | } | ||||
| } | } |
| <div class="top-row ps-3 navbar navbar-dark"> | <div class="top-row ps-3 navbar navbar-dark"> | ||||
| <div class="container-fluid"> | <div class="container-fluid"> | ||||
| <a class="navbar-brand" href="">NemAnCore</a> | |||||
| <a class="navbar-brand" href="">Spotify</a> | |||||
| <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> | <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> | ||||
| <span class="navbar-toggler-icon"></span> | <span class="navbar-toggler-icon"></span> | ||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> | |||||
| <nav class="flex-column"> | |||||
| <div class="@NavMenuCssClass" @onclick="ToggleNavMenu" > | |||||
| <nav class="flex-column" > | |||||
| <div class="nav-item px-3"> | <div class="nav-item px-3"> | ||||
| <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> | <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> | ||||
| <span class="oi oi-home" aria-hidden="true"></span> Home | <span class="oi oi-home" aria-hidden="true"></span> Home | ||||
| </NavLink> | </NavLink> | ||||
| </div> | </div> | ||||
| <div class="nav-item px-3"> | |||||
| @* <div class="nav-item px-3"> | |||||
| <NavLink class="nav-link" href="callback"> | <NavLink class="nav-link" href="callback"> | ||||
| <span class="oi oi-plus" aria-hidden="true"></span> Counter | <span class="oi oi-plus" aria-hidden="true"></span> Counter | ||||
| </NavLink> | </NavLink> | ||||
| </div> | |||||
| </div>*@ | |||||
| <div class="nav-item px-3"> | <div class="nav-item px-3"> | ||||
| <NavLink class="nav-link" href="fetchdata"> | |||||
| <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data | |||||
| <NavLink class="nav-link" href="search"> | |||||
| <span class="oi oi-list-rich" aria-hidden="true"></span> Search | |||||
| </NavLink> | </NavLink> | ||||
| </div> | </div> | ||||
| </nav> | </nav> |
| @using Microsoft.JSInterop | @using Microsoft.JSInterop | ||||
| @using NemAnBlazor | @using NemAnBlazor | ||||
| @using NemAnBlazor.Shared | @using NemAnBlazor.Shared | ||||
| @using System.Web | |||||
| @using System.Web | |||||
| @using Microsoft.AspNetCore.Components.Authorization |
| <base href="/" /> | <base href="/" /> | ||||
| <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> | <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> | ||||
| <link href="css/app.css" rel="stylesheet" /> | <link href="css/app.css" rel="stylesheet" /> | ||||
| <link href="NemAnCore.styles.css" rel="stylesheet" /> | |||||
| <link href="NemAnBlazor.styles.css" rel="stylesheet" /> | |||||
| </head> | </head> | ||||
| <body> | <body> |
| public async Task<SearchResponse> ListSearchAsync(SearchRequest request) | public async Task<SearchResponse> ListSearchAsync(SearchRequest request) | ||||
| { | { | ||||
| var client = _httpClientFactory.CreateClient("HttpClient"); | var client = _httpClientFactory.CreateClient("HttpClient"); | ||||
| client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token ); | client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token ); | ||||
| client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token); | client.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + request.Token); | ||||
| //bool startingQuestionMarkAdded = false; | |||||
| //var sb = new StringBuilder(); | |||||
| var param = new Dictionary<string, List<string>>(); | var param = new Dictionary<string, List<string>>(); | ||||
| param["ids"] = request.Ids; | param["ids"] = request.Ids; | ||||