| @@ -0,0 +1,131 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Text.Json.Serialization; | |||
| using System.Threading.Tasks; | |||
| namespace Grpc.Shared.DTOs.Search | |||
| { | |||
| [ProtoContract] | |||
| internal class SearchDTO | |||
| { | |||
| public partial class SearchContracts | |||
| { | |||
| [ProtoMember(1)] | |||
| public Tracks? Tracks { get; set; } | |||
| } | |||
| public partial class Tracks | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public Items[]? Items { get; set; } | |||
| } | |||
| public partial class Items | |||
| { | |||
| [ProtoMember(1)] | |||
| public Album Album { get; set; } | |||
| [ProtoMember(2)] | |||
| public Artist[] Artists { get; set; } | |||
| [ProtoMember(3)] | |||
| public long DurationMs { get; set; } | |||
| [ProtoMember(4)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(5)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(8)] | |||
| public long Popularity { get; set; } | |||
| [ProtoMember(9)] | |||
| public long TrackNumber { get; set; } | |||
| [ProtoMember(10)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(11)] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class Album | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(3)] | |||
| public Image[] Images { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public DateTimeOffset ReleaseDate { get; set; } | |||
| [ProtoMember(6)] | |||
| public long TotalTracks { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(8)] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class Image | |||
| { | |||
| [ProtoMember(1)] | |||
| public long Height { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Url { get; set; } | |||
| [ProtoMember(3)] | |||
| public long Width { get; set; } | |||
| } | |||
| public partial class Artist | |||
| { | |||
| [ProtoMember(1)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(3)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Uri { get; set; } | |||
| } | |||
| public partial class ExternalUrls | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Spotify { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace Grpc.Shared.DTOs.Search | |||
| { | |||
| internal class SearchRequestDTO | |||
| { | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <ImplicitUsings>enable</ImplicitUsings> | |||
| <Nullable>enable</Nullable> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="protobuf-net.Core" Version="3.1.17" /> | |||
| <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -0,0 +1,34 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Runtime.Serialization; | |||
| using System.ServiceModel; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.Interfaces | |||
| { | |||
| [ServiceContract] | |||
| public interface ISearchService | |||
| { | |||
| Task<SearchResult> SearchTracks(SearchRequest req); | |||
| } | |||
| [DataContract] | |||
| public class SearchResult | |||
| { | |||
| [DataMember(Order = 1)] | |||
| public string NewQuery { get; set; } | |||
| [DataMember(Order = 2)] | |||
| public string NewType { get; set; } | |||
| } | |||
| [DataContract] | |||
| public class SearchRequest | |||
| { | |||
| [DataMember(Order = 1)] | |||
| public string Query { get; set; } | |||
| [DataMember(Order = 2)] | |||
| public string Type { get; set; } = "track"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| using ProtoBuf; | |||
| namespace GrpcShared | |||
| { | |||
| [ProtoContract] | |||
| public class AuthParams | |||
| { | |||
| [ProtoMember(1)] | |||
| public string ClientId { get; set; } | |||
| [ProtoMember(2)] | |||
| public string RedirectURI { get; set; } | |||
| [ProtoMember(3)] | |||
| public string Scope { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Auth | |||
| { | |||
| [ProtoContract] | |||
| public class AuthRequest | |||
| { | |||
| [ProtoMember(1)] | |||
| public string ClientId { get; set; } | |||
| [ProtoMember(2)] | |||
| public string ClientSecret { get; set; } | |||
| [ProtoMember(3)] | |||
| public string RedirectURI { get; set; } | |||
| [ProtoMember(4)] | |||
| public string ResponseType { get; set; } = "track"; | |||
| [ProtoMember(5)] | |||
| public string Scope { get; set; } | |||
| [ProtoMember(6)] | |||
| public string ShowDialog{ get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Auth | |||
| { | |||
| [ProtoContract] | |||
| public class AuthResponse | |||
| { | |||
| [ProtoMember(1)] | |||
| public string AccessToken { get; set; } | |||
| [ProtoMember(2)] | |||
| public string RefreshToken{ get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Auth | |||
| { | |||
| [ProtoContract] | |||
| public class CodeResponse | |||
| { | |||
| [ProtoMember(1)] | |||
| public string Code { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,161 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Search | |||
| { | |||
| [ProtoContract] | |||
| public class SearchDetails | |||
| { | |||
| [ProtoContract] | |||
| public partial class SearchContracts | |||
| { | |||
| [ProtoMember(1)] | |||
| public Tracks? Tracks { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Tracks | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public Item[]? Items { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Item | |||
| { | |||
| [ProtoMember(1)] | |||
| public Album Album { get; set; } | |||
| [ProtoMember(2)] | |||
| public Artist[] Artists { get; set; } | |||
| [ProtoMember(3)] | |||
| public long DurationMs { get; set; } | |||
| [ProtoMember(4)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(5)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(8)] | |||
| public long Popularity { get; set; } | |||
| [ProtoMember(9)] | |||
| public long TrackNumber { get; set; } | |||
| [ProtoMember(10)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(11)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Album | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(3)] | |||
| public Image[] Images { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public DateTimeOffset ReleaseDate { get; set; } | |||
| [ProtoMember(6)] | |||
| public long TotalTracks { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(8)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Image | |||
| { | |||
| [ProtoMember(1)] | |||
| public long Height { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Url { get; set; } | |||
| [ProtoMember(3)] | |||
| public long Width { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Artist | |||
| { | |||
| [ProtoMember(1)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(3)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class ExternalUrls | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Spotify { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Search | |||
| { | |||
| [ProtoContract] | |||
| public class SearchRequest | |||
| { | |||
| [ProtoMember(1)] | |||
| public string Query { get; set; } | |||
| [ProtoMember(2)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(3)] | |||
| public string Include_External { get; set; } | |||
| [ProtoMember(4)] | |||
| public int Limit { get; set; } | |||
| [ProtoMember(5)] | |||
| public int Offset { get; set; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,161 @@ | |||
| using ProtoBuf; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace GrpcShared.DTO.Search | |||
| { | |||
| [ProtoContract] | |||
| public class SearchResponse | |||
| { | |||
| [ProtoContract] | |||
| public partial class SearchContracts | |||
| { | |||
| [ProtoMember(1)] | |||
| public Tracks? Tracks { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Tracks | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public List<Item>? Items { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Item | |||
| { | |||
| [ProtoMember(1)] | |||
| public Album? Album { get; set; } | |||
| [ProtoMember(2)] | |||
| public Artist[] Artists { get; set; } | |||
| [ProtoMember(3)] | |||
| public long DurationMs { get; set; } | |||
| [ProtoMember(4)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(5)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(8)] | |||
| public long Popularity { get; set; } | |||
| [ProtoMember(9)] | |||
| public long TrackNumber { get; set; } | |||
| [ProtoMember(10)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(11)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Album | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(2)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(3)] | |||
| public Image[] Images { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public DateTimeOffset ReleaseDate { get; set; } | |||
| [ProtoMember(6)] | |||
| public long TotalTracks { get; set; } | |||
| [ProtoMember(7)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(8)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Image | |||
| { | |||
| [ProtoMember(1)] | |||
| public long Height { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Url { get; set; } | |||
| [ProtoMember(3)] | |||
| public long Width { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class Artist | |||
| { | |||
| [ProtoMember(1)] | |||
| public ExternalUrls ExternalUrls { get; set; } | |||
| [ProtoMember(2)] | |||
| public Uri Href { get; set; } | |||
| [ProtoMember(3)] | |||
| public string Id { get; set; } | |||
| [ProtoMember(4)] | |||
| public string Name { get; set; } | |||
| [ProtoMember(5)] | |||
| public string Type { get; set; } | |||
| [ProtoMember(6)] | |||
| public string Uri { get; set; } | |||
| } | |||
| [ProtoContract] | |||
| public partial class ExternalUrls | |||
| { | |||
| [ProtoMember(1)] | |||
| public Uri Spotify { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <OutputType>Library</OutputType> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <ImplicitUsings>enable</ImplicitUsings> | |||
| <Nullable>enable</Nullable> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" /> | |||
| <PackageReference Include="protobuf-net.BuildTools" Version="3.1.17"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -0,0 +1,13 @@ | |||
| using GrpcShared.DTO.Auth; | |||
| using ProtoBuf.Grpc.Configuration; | |||
| namespace GrpcShared.Interfaces | |||
| { | |||
| [Service] | |||
| public interface IAuthService | |||
| { | |||
| Task<CodeResponse> GetCode(AuthRequest request); | |||
| Task<AuthResponse> GetAccessToken(CodeResponse code); | |||
| Task<AuthParams> GetAuthParams(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| using GrpcShared.DTO.Search; | |||
| 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 ISearchService | |||
| { | |||
| Task<SearchResponse> ListSearchAsync(SearchRequest request); | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| @@ -7,12 +7,18 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> | |||
| <Protobuf Include="Protos\auth.proto" GrpcServices="Server" /> | |||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||
| <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" /> | |||
| <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.Reflection" Version="1.0.152" /> | |||
| <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||
| <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,17 +1,66 @@ | |||
| using GrpcShared; | |||
| using IdentityProvider.Services; | |||
| using Microsoft.AspNetCore.Server.Kestrel.Core; | |||
| using ProtoBuf.Grpc.Server; | |||
| using Microsoft.Extensions.Options; | |||
| 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); | |||
| }); | |||
| #endif | |||
| builder.Services.AddOptions(); | |||
| // 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.Configure<AuthParams>(builder.Configuration.GetSection("AuthParams")); | |||
| builder.Services.AddControllersWithViews(); | |||
| builder.Services.AddRazorPages(); | |||
| builder.Services.AddEndpointsApiExplorer(); | |||
| // Add services to the container. | |||
| builder.Services.AddGrpc(); | |||
| builder.Services.AddCodeFirstGrpc(); | |||
| builder.Services.AddCodeFirstGrpcReflection(); | |||
| var app = builder.Build(); | |||
| // Configure the HTTP request pipeline. | |||
| app.MapGrpcService<GreeterService>(); | |||
| app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); | |||
| if (app.Environment.IsDevelopment()) | |||
| { | |||
| app.UseWebAssemblyDebugging(); | |||
| } | |||
| else | |||
| { | |||
| app.UseExceptionHandler("/Error"); | |||
| // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |||
| app.UseHsts(); | |||
| } | |||
| app.UseHttpsRedirection(); | |||
| app.UseBlazorFrameworkFiles(); | |||
| app.UseStaticFiles(); | |||
| app.UseRouting(); | |||
| app.UseGrpcWeb(); | |||
| app.MapRazorPages(); | |||
| app.MapControllers(); | |||
| //app.MapGrpcService<WeatherService>(); | |||
| app.MapGrpcService<AuthService>().EnableGrpcWeb(); | |||
| app.MapCodeFirstGrpcReflectionService(); | |||
| app.MapFallbackToFile("index.html"); | |||
| app.Run(); | |||
| app.Run(); | |||
| @@ -1,10 +1,27 @@ | |||
| { | |||
| "iisSettings": { | |||
| "windowsAuthentication": false, | |||
| "anonymousAuthentication": true, | |||
| "iisExpress": { | |||
| "applicationUrl": "http://localhost:28725", | |||
| "sslPort": 44342 | |||
| } | |||
| }, | |||
| "profiles": { | |||
| "IIS Express": { | |||
| "commandName": "IISExpress", | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| }, | |||
| "IdentityProvider": { | |||
| "commandName": "Project", | |||
| "dotnetRunMessages": true, | |||
| "launchBrowser": false, | |||
| "applicationUrl": "http://localhost:5164;https://localhost:7164", | |||
| "dotnetRunMessages": "true", | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| @@ -1,26 +0,0 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "IdentityProvider.Protos"; | |||
| package auth; | |||
| service AuthorizationService { | |||
| rpc RedirectUser(AuthParams) returns (AuthResponse); | |||
| rpc GetAccessToken(AuthResponse) returns (AccessResponse); | |||
| } | |||
| message AuthParams{ | |||
| string client_id = 1; | |||
| string redirect_uri = 2; | |||
| string response_type = 3; | |||
| string scope = 4; | |||
| bool show_dialog = 5; | |||
| } | |||
| message AuthResponse { | |||
| string code = 1; | |||
| } | |||
| message AccessResponse { | |||
| string access_token = 1; | |||
| } | |||
| @@ -1,21 +0,0 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "IdentityProvider"; | |||
| package greet; | |||
| // The greeting service definition. | |||
| service Greeter { | |||
| // Sends a greeting | |||
| rpc SayHello (HelloRequest) returns (HelloReply); | |||
| } | |||
| // The request message containing the user's name. | |||
| message HelloRequest { | |||
| string name = 1; | |||
| } | |||
| // The response message containing the greetings. | |||
| message HelloReply { | |||
| string message = 1; | |||
| } | |||
| @@ -1,14 +1,39 @@ | |||
| using IdentityProvider.Protos.AuthService; | |||
| //using IdentityProvider.Protos.AuthService; | |||
| using GrpcShared; | |||
| using GrpcShared.DTO.Auth; | |||
| using GrpcShared.Interfaces; | |||
| using Microsoft.Extensions.Options; | |||
| namespace IdentityProvider.Services | |||
| { | |||
| public class AuthService : AuthorizationService.AuthorizationServiceBase | |||
| public class AuthService : IAuthService | |||
| { | |||
| private readonly ILogger<AuthService> _logger; | |||
| public AuthService(ILogger<AuthService> logger) | |||
| private readonly AuthParams _params; | |||
| public AuthService(ILogger<AuthService> logger, IOptions<AuthParams> options ) | |||
| { | |||
| _logger = logger; | |||
| _params = options.Value; | |||
| } | |||
| public Task<AuthResponse> GetAccessToken(CodeResponse code) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Task<CodeResponse> GetCode(AuthRequest request) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public async Task<AuthParams> GetAuthParams() | |||
| { | |||
| var authParams = new AuthParams { | |||
| ClientId = _params.ClientId, | |||
| RedirectURI = _params.RedirectURI, | |||
| Scope =_params.Scope }; | |||
| return await Task.FromResult(authParams); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,22 +0,0 @@ | |||
| using Grpc.Core; | |||
| using IdentityProvider; | |||
| namespace IdentityProvider.Services | |||
| { | |||
| public class GreeterService : Greeter.GreeterBase | |||
| { | |||
| private readonly ILogger<GreeterService> _logger; | |||
| public GreeterService(ILogger<GreeterService> logger) | |||
| { | |||
| _logger = logger; | |||
| } | |||
| public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) | |||
| { | |||
| return Task.FromResult(new HelloReply | |||
| { | |||
| Message = "Hello " + request.Name | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -10,5 +10,10 @@ | |||
| "EndpointDefaults": { | |||
| "Protocols": "Http2" | |||
| } | |||
| }, | |||
| "AuthParams": { | |||
| "ClientId": "83e1d09876b049c4bb1953185a4b3bfb", | |||
| "RedirectURI": "https://localhost:44342/callback", | |||
| "Scope": "user-read-currently-playing user-read-email user-library-modify user-top-read" | |||
| } | |||
| } | |||
| @@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpotifyWorker", "SpotifyWor | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityProvider", "IdentityProvider\IdentityProvider.csproj", "{D160945A-5068-4D6A-A09D-5DD7A9EFBC01}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcShared", "GrpcShared\GrpcShared.csproj", "{C142D6DF-066A-4ADA-86A3-1C736136C1FA}" | |||
| EndProject | |||
| Global | |||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
| Debug|Any CPU = Debug|Any CPU | |||
| @@ -33,6 +35,10 @@ Global | |||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {D160945A-5068-4D6A-A09D-5DD7A9EFBC01}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {C142D6DF-066A-4ADA-86A3-1C736136C1FA}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| @@ -1,4 +1,4 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> | |||
| <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| @@ -7,8 +7,15 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Grpc.Net.Client" Version="2.47.0" /> | |||
| <PackageReference Include="Grpc.Net.Client.Web" Version="2.47.0" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.7" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.7" PrivateAssets="all" /> | |||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,18 +1,30 @@ | |||
| @page "/" | |||
| @using Grpc.Net.Client | |||
| @using Grpc.Net.Client.Web | |||
| @using GrpcShared | |||
| @using GrpcShared.DTO.Auth | |||
| @using NemAnBlazor.Services.Interfaces | |||
| @inject NavigationManager NavigationManager | |||
| @inject IAuthClientService AuthService | |||
| @*@inject ISearchClientService SearchService*@ | |||
| <PageTitle>Index</PageTitle> | |||
| <h1>Pozdrav Diligent!</h1> | |||
| Dobrodošli u našu NemAn aplikaciju. | |||
| <button class="btn-outline-success" @onclick="SpotifyRedirect">Spotify</button> | |||
| @code{ | |||
| private void SpotifyRedirect() | |||
| @code { | |||
| protected override async Task OnInitializedAsync() | |||
| { | |||
| NavigationManager.NavigateTo( | |||
| "https://accounts.spotify.com/en/authorize?client_id=83e1d09876b049c4bb1953185a4b3bfb&redirect_uri=https%3A%2F%2Flocalhost%3A7229%2F&response_type=code&scope=user-read-currently-playing%20user-read-email%20user-library-modify%20user-top-read%0A%0A%0A&show_dialog=true"); | |||
| //var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"}); | |||
| AuthParams authParams = await AuthService.GetAuthParams(); | |||
| // await AuthService.GetAccessToken(new CodeResponse{ Code = "hello"}); | |||
| AuthRequest request = new() { ResponseType = "code", Scope = authParams.Scope, ClientId = authParams.ClientId, RedirectURI = authParams.RedirectURI}; | |||
| string url = $"https://accounts.spotify.com/en/authorize?client_id={request.ClientId}&redirect_uri={request.RedirectURI}&response_type={request.ResponseType}&scope={request.Scope}&show_dialog=true"; | |||
| NavigationManager.NavigateTo(url); | |||
| } | |||
| } | |||
| @@ -1,6 +1,11 @@ | |||
| using Grpc.Net.Client; | |||
| using Grpc.Net.Client.Web; | |||
| using Microsoft.AspNetCore.Components; | |||
| using Microsoft.AspNetCore.Components.Web; | |||
| using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | |||
| using NemAnBlazor; | |||
| using NemAnBlazor.Services; | |||
| using NemAnBlazor.Services.Interfaces; | |||
| var builder = WebAssemblyHostBuilder.CreateDefault(args); | |||
| builder.RootComponents.Add<App>("#app"); | |||
| @@ -8,5 +13,16 @@ builder.RootComponents.Add<HeadOutlet>("head::after"); | |||
| builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | |||
| builder.Services.AddScoped(_ => | |||
| { | |||
| var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); | |||
| var channel = GrpcChannel.ForAddress(builder.HostEnvironment.BaseAddress, new GrpcChannelOptions { HttpHandler = grpcWebHandler }); | |||
| return channel; | |||
| }); | |||
| builder.Services.AddScoped<ISearchClientService, SearchClientService>(); | |||
| builder.Services.AddScoped<IAuthClientService, AuthClientService>(); | |||
| await builder.Build().RunAsync(); | |||
| @@ -1,30 +1,16 @@ | |||
| { | |||
| "iisSettings": { | |||
| "windowsAuthentication": false, | |||
| "anonymousAuthentication": true, | |||
| "iisExpress": { | |||
| "applicationUrl": "http://localhost:50338", | |||
| "sslPort": 44375 | |||
| } | |||
| "anonymousAuthentication": true | |||
| }, | |||
| "profiles": { | |||
| "NemAnCore": { | |||
| "commandName": "Project", | |||
| "dotnetRunMessages": true, | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "applicationUrl": "https://localhost:7229;http://localhost:5229", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| }, | |||
| "IIS Express": { | |||
| "commandName": "IISExpress", | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| using Grpc.Net.Client; | |||
| using GrpcShared.DTO.Auth; | |||
| using GrpcShared.Interfaces; | |||
| using NemAnBlazor.Services.Interfaces; | |||
| using ProtoBuf.Grpc.Client; | |||
| using GrpcShared; | |||
| namespace NemAnBlazor.Services | |||
| { | |||
| public class AuthClientService : IAuthClientService | |||
| { | |||
| private IAuthService _serviceClient; | |||
| public AuthClientService(GrpcChannel grpcChannel) | |||
| { | |||
| _serviceClient = grpcChannel.CreateGrpcService<IAuthService>(); | |||
| } | |||
| public async Task<AuthResponse> GetAccessToken(CodeResponse code) | |||
| { | |||
| return await _serviceClient.GetAccessToken(code); | |||
| } | |||
| public async Task <AuthParams> GetAuthParams() | |||
| { | |||
| return await _serviceClient.GetAuthParams(); | |||
| } | |||
| public Task<CodeResponse> GetCode(AuthRequest request) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| using GrpcShared; | |||
| using GrpcShared.DTO.Auth; | |||
| namespace NemAnBlazor.Services.Interfaces | |||
| { | |||
| public interface IAuthClientService | |||
| { | |||
| Task<CodeResponse> GetCode(AuthRequest request); | |||
| Task<AuthResponse> GetAccessToken(CodeResponse code); | |||
| Task<AuthParams> GetAuthParams(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| using GrpcShared.DTO.Search; | |||
| namespace NemAnBlazor.Services.Interfaces | |||
| { | |||
| public interface ISearchClientService | |||
| { | |||
| Task<SearchResponse> GetListSearchAsync(SearchRequest request); | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| using GrpcShared.DTO.Search; | |||
| using GrpcShared.Interfaces; | |||
| using NemAnBlazor.Services.Interfaces; | |||
| namespace NemAnBlazor.Services | |||
| { | |||
| public class SearchClientService : ISearchClientService | |||
| { | |||
| private ISearchService _serviceClient; | |||
| public SearchClientService(ISearchService serviceClient) | |||
| { | |||
| _serviceClient = serviceClient; | |||
| } | |||
| public async Task<SearchResponse> GetListSearchAsync(SearchRequest request) | |||
| { | |||
| return await _serviceClient.ListSearchAsync(request); | |||
| } | |||
| } | |||
| } | |||
| @@ -9,5 +9,6 @@ | |||
| <ItemGroup> | |||
| <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | |||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,17 +1,68 @@ | |||
| using gRPCServer.Services; | |||
| using Microsoft.AspNetCore.Server.Kestrel.Core; | |||
| using ProtoBuf.Grpc.Server; | |||
| using SpotifyService.Services; | |||
| var builder = WebApplication.CreateBuilder(args); | |||
| // 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 | |||
| #if DEBUG | |||
| /* | |||
| builder.WebHost.ConfigureKestrel(options => | |||
| { | |||
| options.ListenLocalhost(5050, o => o.Protocols = | |||
| HttpProtocols.Http2); | |||
| options.ListenLocalhost(5051, o => o.Protocols = | |||
| HttpProtocols.Http1AndHttp2); | |||
| }); | |||
| */ | |||
| #endif | |||
| // Add services to the container. | |||
| builder.Services.AddControllersWithViews(); | |||
| builder.Services.AddRazorPages(); | |||
| builder.Services.AddEndpointsApiExplorer(); | |||
| builder.Services.AddSwaggerGen(); | |||
| builder.Services.AddGrpc(); | |||
| builder.Services.AddCodeFirstGrpc(); | |||
| builder.Services.AddCodeFirstGrpcReflection(); | |||
| var app = builder.Build(); | |||
| app.UseSwagger(); | |||
| app.UseSwaggerUI(); | |||
| // Configure the HTTP request pipeline. | |||
| app.MapGrpcService<GreeterService>(); | |||
| app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); | |||
| if (app.Environment.IsDevelopment()) | |||
| { | |||
| app.UseWebAssemblyDebugging(); | |||
| } | |||
| else | |||
| { | |||
| app.UseExceptionHandler("/Error"); | |||
| // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |||
| app.UseHsts(); | |||
| } | |||
| app.UseHttpsRedirection(); | |||
| app.UseBlazorFrameworkFiles(); | |||
| app.UseStaticFiles(); | |||
| app.UseRouting(); | |||
| app.UseGrpcWeb(); | |||
| app.MapRazorPages(); | |||
| app.MapControllers(); | |||
| //app.MapGrpcService<WeatherService>(); | |||
| app.MapGrpcService<SearchService>().EnableGrpcWeb(); | |||
| app.MapCodeFirstGrpcReflectionService(); | |||
| app.MapFallbackToFile("index.html"); | |||
| app.Run(); | |||
| @@ -1,10 +1,27 @@ | |||
| { | |||
| "iisSettings": { | |||
| "windowsAuthentication": false, | |||
| "anonymousAuthentication": true, | |||
| "iisExpress": { | |||
| "applicationUrl": "http://localhost:28725", | |||
| "sslPort": 44342 | |||
| } | |||
| }, | |||
| "profiles": { | |||
| "gRPCServer": { | |||
| "IIS Express": { | |||
| "commandName": "IISExpress", | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| }, | |||
| "SpotifyService": { | |||
| "commandName": "Project", | |||
| "dotnetRunMessages": true, | |||
| "launchBrowser": false, | |||
| "applicationUrl": "http://localhost:5251;https://localhost:7251", | |||
| "dotnetRunMessages": "true", | |||
| "launchBrowser": true, | |||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||
| "environmentVariables": { | |||
| "ASPNETCORE_ENVIRONMENT": "Development" | |||
| } | |||
| @@ -1,21 +0,0 @@ | |||
| syntax = "proto3"; | |||
| option csharp_namespace = "gRPCServer"; | |||
| package greet; | |||
| // The greeting service definition. | |||
| service Greeter { | |||
| // Sends a greeting | |||
| rpc SayHello (HelloRequest) returns (HelloReply); | |||
| } | |||
| // The request message containing the user's name. | |||
| message HelloRequest { | |||
| string name = 1; | |||
| } | |||
| // The response message containing the greetings. | |||
| message HelloReply { | |||
| string message = 1; | |||
| } | |||
| @@ -1,22 +0,0 @@ | |||
| using Grpc.Core; | |||
| using gRPCServer; | |||
| namespace gRPCServer.Services | |||
| { | |||
| public class GreeterService : Greeter.GreeterBase | |||
| { | |||
| private readonly ILogger<GreeterService> _logger; | |||
| public GreeterService(ILogger<GreeterService> logger) | |||
| { | |||
| _logger = logger; | |||
| } | |||
| public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) | |||
| { | |||
| return Task.FromResult(new HelloReply | |||
| { | |||
| Message = "Hello " + request.Name | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| using Grpc.Core; | |||
| using System.Text.Json; | |||
| namespace SpotifyService.Services | |||
| { | |||
| public class SearchService | |||
| { | |||
| private readonly IHttpClientFactory _httpClientFactory; | |||
| public SearchService(IHttpClientFactory httpClientFactory) | |||
| { | |||
| _httpClientFactory = httpClientFactory; | |||
| } | |||
| } | |||
| } | |||
| @@ -7,11 +7,18 @@ | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> | |||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||
| <PackageReference Include="Grpc.AspNetCore.Web" Version="2.47.0" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.8" /> | |||
| <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.Reflection" Version="1.0.152" /> | |||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" /> | |||
| <ProjectReference Include="..\GrpcShared\GrpcShared.csproj" /> | |||
| <ProjectReference Include="..\NemAnCore\NemAnBlazor.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -8,7 +8,7 @@ | |||
| "AllowedHosts": "*", | |||
| "Kestrel": { | |||
| "EndpointDefaults": { | |||
| "Protocols": "Http2" | |||
| "Protocols": "Http1AndHttp2" | |||
| } | |||
| } | |||
| } | |||