diff --git a/WebApp/APIClient.cs b/WebApp/APIClient.cs new file mode 100644 index 0000000..3257bd9 --- /dev/null +++ b/WebApp/APIClient.cs @@ -0,0 +1,70 @@ +using Newtonsoft.Json; +using System.Net.Http.Headers; +using System.Text; + +namespace WebApp; + +public class APIClient +{ + private static readonly HttpClient _client = new(); + + public static void Connect(IConfiguration configuration) + { + _client.BaseAddress = new Uri(configuration["API"]); + _client.DefaultRequestHeaders.Accept.Clear(); + _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + } + + public static T? GetRequest(string requestUrl) + { + var response = _client.GetAsync(requestUrl); + var result = response.Result.Content.ReadAsStringAsync().Result; + if (!response.Result.IsSuccessStatusCode) + { + throw new Exception(response.Result.ReasonPhrase); + } + return JsonConvert.DeserializeObject(result); + } + + public static object? PostRequest(string requestUrl, T model) + { + var json = JsonConvert.SerializeObject(model); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = _client.PostAsync(requestUrl, data); + + var result = response.Result.Content.ReadAsStringAsync().Result; + if (!response.Result.IsSuccessStatusCode) + { + throw new Exception(response.Result.ReasonPhrase); + } + return result; + } + + public static object? DeleteRequest(string requestUrl) + { + var response = _client.DeleteAsync(requestUrl); + + var result = response.Result.Content.ReadAsStringAsync().Result; + if (!response.Result.IsSuccessStatusCode) + { + throw new Exception(response.Result.ReasonPhrase); + } + return result; + } + + public static object? PatchRequest(string requestUrl, T model) + { + var json = JsonConvert.SerializeObject(model); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = _client.PatchAsync(requestUrl, data); + + var result = response.Result.Content.ReadAsStringAsync().Result; + if (!response.Result.IsSuccessStatusCode) + { + throw new Exception(response.Result.ReasonPhrase); + } + return result; + } +} \ No newline at end of file diff --git a/WebApp/Helpers/Roles.cs b/WebApp/Helpers/Roles.cs new file mode 100644 index 0000000..084cfe6 --- /dev/null +++ b/WebApp/Helpers/Roles.cs @@ -0,0 +1,10 @@ +namespace WebApp.Helpers; + +public static class Roles +{ + public const string User = "Обычный пользователь"; + public const string Admin = "Админ"; + + // TODO: Добавить нужные роли + public const string Worker = "Сотрудник"; +} \ No newline at end of file diff --git a/WebApp/Pages/Login.cshtml b/WebApp/Pages/Login.cshtml new file mode 100644 index 0000000..597f8be --- /dev/null +++ b/WebApp/Pages/Login.cshtml @@ -0,0 +1,9 @@ +@page +@model WebApp.Pages.LoginModel +
+ + + + + +
diff --git a/WebApp/Pages/Login.cshtml.cs b/WebApp/Pages/Login.cshtml.cs new file mode 100644 index 0000000..ce8c5b7 --- /dev/null +++ b/WebApp/Pages/Login.cshtml.cs @@ -0,0 +1,28 @@ +using Contracts.BindingModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Newtonsoft.Json; + +namespace WebApp.Pages +{ + public class LoginModel : PageModel + { + public void OnGet() + { + } + + public void OnPostAsync(string email, string password) + { + var response = APIClient.PostRequest("user/login", new { email, password }); + + if (response is null || response is not string) + { + return; + } + string token = (string)JsonConvert.DeserializeObject((string)response); + // + Response.Cookies.Append("21gunsthebest", token); + Redirect("/"); + } + } +} \ No newline at end of file diff --git a/WebApp/Pages/User/Settings.cshtml b/WebApp/Pages/User/Settings.cshtml new file mode 100644 index 0000000..256edcd --- /dev/null +++ b/WebApp/Pages/User/Settings.cshtml @@ -0,0 +1,2 @@ +@page +@model WebApp.Pages.User.SettingsModel diff --git a/WebApp/Pages/User/Settings.cshtml.cs b/WebApp/Pages/User/Settings.cshtml.cs new file mode 100644 index 0000000..519daf6 --- /dev/null +++ b/WebApp/Pages/User/Settings.cshtml.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using WebApp.Helpers; + +namespace WebApp.Pages.User +{ + [Authorize(Roles = Roles.Admin + Roles.Worker)] + public class SettingsModel : PageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/WebApp/Program.cs b/WebApp/Program.cs index bc275e4..5b659a3 100644 --- a/WebApp/Program.cs +++ b/WebApp/Program.cs @@ -1,8 +1,40 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using WebApp; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["SecretKey"])); + options.TokenValidationParameters = new() + { + ValidateLifetime = true, + IssuerSigningKey = secretKey, + ValidateIssuer = false, + ValidateAudience = false, + }; + options.Events = new JwtBearerEvents() + { + OnMessageReceived = context => + { + // JWT + context.Token = context.Request.Cookies["21gunsthebest"]; + return Task.CompletedTask; + } + }; + }); +builder.Services.AddAuthorization(); +// API +APIClient.Connect(builder.Configuration); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -18,8 +50,9 @@ app.UseStaticFiles(); app.UseRouting(); +app.UseAuthentication(); app.UseAuthorization(); app.MapRazorPages(); -app.Run(); +app.Run(); \ No newline at end of file diff --git a/WebApp/WebApp.csproj b/WebApp/WebApp.csproj index 1b28a01..33e3dc7 100644 --- a/WebApp/WebApp.csproj +++ b/WebApp/WebApp.csproj @@ -6,4 +6,13 @@ enable + + + + + + + + + diff --git a/WebApp/WebApp.sln b/WebApp/WebApp.sln index cb02cc3..622b5e3 100644 --- a/WebApp/WebApp.sln +++ b/WebApp/WebApp.sln @@ -3,19 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34728.123 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApp", "WebApp.csproj", "{494318C5-209C-42B9-B15F-BF0D5A8ECF18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApp", "WebApp.csproj", "{494318C5-209C-42B9-B15F-BF0D5A8ECF18}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsApp", "..\WinFormsApp\WinFormsApp.csproj", "{11F917BB-0ABC-41A0-91B9-B3FD9CEC5277}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsApp", "..\WinFormsApp\WinFormsApp.csproj", "{11F917BB-0ABC-41A0-91B9-B3FD9CEC5277}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestAPI", "..\RestAPI\RestAPI.csproj", "{D3211E26-438E-48B6-9396-2FFC28271DE1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestAPI", "..\RestAPI\RestAPI.csproj", "{D3211E26-438E-48B6-9396-2FFC28271DE1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogic", "..\BusinessLogic\BusinessLogic.csproj", "{919726B5-89B3-43B3-AA9A-25C1348D86B1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusinessLogic", "..\BusinessLogic\BusinessLogic.csproj", "{919726B5-89B3-43B3-AA9A-25C1348D86B1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataModels", "..\DataModels\DataModels.csproj", "{645ED499-8C00-4F04-91FB-A9EF6F1A438E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataModels", "..\DataModels\DataModels.csproj", "{645ED499-8C00-4F04-91FB-A9EF6F1A438E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "..\Contracts\Contracts.csproj", "{D7BD8791-F687-460F-8BF7-8F9CD2301EB5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "..\Contracts\Contracts.csproj", "{D7BD8791-F687-460F-8BF7-8F9CD2301EB5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseImplement", "..\DatabaseImplement\DatabaseImplement.csproj", "{527EAA88-4EAF-42D7-93E9-494221351F9C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseImplement", "..\DatabaseImplement\DatabaseImplement.csproj", "{527EAA88-4EAF-42D7-93E9-494221351F9C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/WebApp/appsettings.json b/WebApp/appsettings.json index 10f68b8..e4d66e6 100644 --- a/WebApp/appsettings.json +++ b/WebApp/appsettings.json @@ -5,5 +5,7 @@ "Microsoft.AspNetCore": "Warning" } }, + "API": "https://localhost:7051/", + "SecretKey": "secretkey_secretkey_secretkey_secretkey", "AllowedHosts": "*" -} +} \ No newline at end of file