From 5cb35f54d5975bc7d6a6a3aeb62e6a142152f3af Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Fri, 18 Jun 2021 23:57:02 +0100 Subject: [PATCH] ci & admin & auth & cli --- .gitlab-ci.yml | 3 +- .../UploadFilesToServerUsingWebRequest.cs | 39 ++++++++++--------- .../Authorisation/ValidApiKeyRequirement.cs | 10 +++++ .../ValidApiKeyRequirementHandler.cs | 13 +++++++ src/nuget-host/Constants.cs | 9 +++++ .../Controllers/AccountController.cs | 26 ++++++++++++- .../Controllers/NewUpdateController.cs | 17 ++++++++ src/nuget-host/Data/NewReleaseInfo.cs | 11 ++++++ src/nuget-host/Data/Roles/Administrator.cs | 7 ++++ src/nuget-host/Startup.cs | 32 +++++++++------ src/nuget-host/appsettings.Development.json | 5 +++ src/nuget-host/appsettings.json | 5 +++ 12 files changed, 143 insertions(+), 34 deletions(-) create mode 100644 src/nuget-host/Authorisation/ValidApiKeyRequirement.cs create mode 100644 src/nuget-host/Authorisation/ValidApiKeyRequirementHandler.cs create mode 100644 src/nuget-host/Constants.cs create mode 100644 src/nuget-host/Controllers/NewUpdateController.cs create mode 100644 src/nuget-host/Data/NewReleaseInfo.cs create mode 100644 src/nuget-host/Data/Roles/Administrator.cs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d17e473..9e7bc81 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,8 +7,7 @@ image: busybox:latest before_script: - dotnet restore -after_script: - - dotnet nuget remove source gitlab +#after_script: nonreg: stage: test diff --git a/src/nuget-cli/UploadFilesToServerUsingWebRequest.cs b/src/nuget-cli/UploadFilesToServerUsingWebRequest.cs index ecf8a20..48e372e 100644 --- a/src/nuget-cli/UploadFilesToServerUsingWebRequest.cs +++ b/src/nuget-cli/UploadFilesToServerUsingWebRequest.cs @@ -7,11 +7,12 @@ using Newtonsoft.Json; namespace nuget_cli { - public class nugetdresp { - public int ecode {get; set; } - public string message {get; set; } - public string id { get; set; } - } + public class nugetdresp + { + public int ecode { get; set; } + public string message { get; set; } + public string id { get; set; } + } public class UploadFilesToServerUsingWebRequest { @@ -41,7 +42,7 @@ namespace nuget_cli httpWebRequest.AllowAutoRedirect = false; httpWebRequest.Headers.Add("X-NuGet-Client-Version", Constants.ClientVersion); httpWebRequest.Headers.Add("X-NuGet-ApiKey", apikey); - httpWebRequest.ContentLength = boundarybytes.Length + + httpWebRequest.ContentLength = boundarybytes.Length + fileheaderbytes.Length + fi.Length + endBoundaryBytes.Length; @@ -68,7 +69,7 @@ namespace nuget_cli requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); requestStream.Close(); } - + } catch (Exception rex) { @@ -82,24 +83,24 @@ namespace nuget_cli }, httpWebRequest); WebResponse resp = httpWebRequest.GetResponse(); - + Stream stream = resp.GetResponseStream(); StreamReader re = new StreamReader(stream); if (resp is HttpWebResponse) { - String json = re.ReadToEnd(); - report.Message = json; + String json = re.ReadToEnd(); + report.Message = json; - var res = JsonConvert.DeserializeObject(json); - report.AlreadyPresent = res.ecode == 1; + var res = JsonConvert.DeserializeObject(json); + report.AlreadyPresent = res.ecode == 1; - var hrep = resp as HttpWebResponse; - report.StatusCode = hrep.StatusCode.ToString(); - // ecode == 1 => package already present server side. - report.OK = hrep.StatusCode == - HttpStatusCode.Accepted - || hrep.StatusCode == HttpStatusCode.OK - || res.ecode == 1; + var hrep = resp as HttpWebResponse; + report.StatusCode = hrep.StatusCode.ToString(); + // ecode == 1 => package already present server side. + report.AlreadyPresent = res.ecode == 1; + report.OK = hrep.StatusCode == HttpStatusCode.Accepted + || hrep.StatusCode == HttpStatusCode.OK + || report.AlreadyPresent; } else throw new Exception("Invalid server response type"); } diff --git a/src/nuget-host/Authorisation/ValidApiKeyRequirement.cs b/src/nuget-host/Authorisation/ValidApiKeyRequirement.cs new file mode 100644 index 0000000..cf1d918 --- /dev/null +++ b/src/nuget-host/Authorisation/ValidApiKeyRequirement.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Authorization; + +namespace nuget_host.Authorization +{ + internal class ValidApiKeyRequirement : IAuthorizationRequirement + { + } + + +} \ No newline at end of file diff --git a/src/nuget-host/Authorisation/ValidApiKeyRequirementHandler.cs b/src/nuget-host/Authorisation/ValidApiKeyRequirementHandler.cs new file mode 100644 index 0000000..95dfbea --- /dev/null +++ b/src/nuget-host/Authorisation/ValidApiKeyRequirementHandler.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace nuget_host.Authorization +{ + internal class ValidApiKeyRequirementHandler : AuthorizationHandler + { + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidApiKeyRequirement requirement) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/nuget-host/Constants.cs b/src/nuget-host/Constants.cs new file mode 100644 index 0000000..9df6e45 --- /dev/null +++ b/src/nuget-host/Constants.cs @@ -0,0 +1,9 @@ +namespace nuget_host +{ + public static class Constants + { + public const string AdministratorRoleName = "Admin"; + public const string RequireAdminPolicyName = "RequireAdministratorRole"; + public const string RequireValidApiKey = "RequireValideApiKey"; + } +} \ No newline at end of file diff --git a/src/nuget-host/Controllers/AccountController.cs b/src/nuget-host/Controllers/AccountController.cs index 4cebb17..99297a2 100644 --- a/src/nuget-host/Controllers/AccountController.cs +++ b/src/nuget-host/Controllers/AccountController.cs @@ -6,9 +6,12 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; using nuget_host.Data; +using nuget_host.Data.Roles; using System; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; namespace nuget_host.Controllers @@ -20,15 +23,18 @@ namespace nuget_host.Controllers private readonly SignInManager _signInManager; private readonly UserManager _userManager; + private readonly AdminStartupList _startupAdminList; public AccountController( IAuthenticationSchemeProvider schemeProvider, SignInManager signInManager, - UserManager userManager) + UserManager userManager, + IOptions startupAdminListConfig ) { _schemeProvider = schemeProvider; _signInManager = signInManager; _userManager = userManager; + _startupAdminList = startupAdminListConfig.Value; } /// @@ -232,5 +238,23 @@ namespace nuget_host.Controllers return vm; } + + [Authorize] + public async Task GetAdminrole() + { + string username = User.FindFirstValue(ClaimTypes.NameIdentifier); + if (_startupAdminList.Users.Contains(username)) + { + var user = await _userManager.FindByNameAsync(username); + var roles = await _userManager.GetRolesAsync(user); + if (!roles.Contains(Constants.AdministratorRoleName)) + { + await _userManager.AddToRoleAsync(user, Constants.AdministratorRoleName); + + } + return Ok(); + } + return BadRequest(); + } } } diff --git a/src/nuget-host/Controllers/NewUpdateController.cs b/src/nuget-host/Controllers/NewUpdateController.cs new file mode 100644 index 0000000..58300d6 --- /dev/null +++ b/src/nuget-host/Controllers/NewUpdateController.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using nuget_host.Data; + +namespace nuget_host.Controllers +{ + + public class NewUpdateController : Controller + { + [Authorize(Policy = Constants.RequireAdminPolicyName)] + public IActionResult NewRelease(NewReleaseInfo version) + { + return View(version); + } + } +} \ No newline at end of file diff --git a/src/nuget-host/Data/NewReleaseInfo.cs b/src/nuget-host/Data/NewReleaseInfo.cs new file mode 100644 index 0000000..54ae751 --- /dev/null +++ b/src/nuget-host/Data/NewReleaseInfo.cs @@ -0,0 +1,11 @@ +using System; + +namespace nuget_host.Data +{ + public class NewReleaseInfo + { + public string Version { get; set; } + public string ChangeLog { get; set; } + public DateTime BuildDate { get; set; } + } +} \ No newline at end of file diff --git a/src/nuget-host/Data/Roles/Administrator.cs b/src/nuget-host/Data/Roles/Administrator.cs new file mode 100644 index 0000000..e971f53 --- /dev/null +++ b/src/nuget-host/Data/Roles/Administrator.cs @@ -0,0 +1,7 @@ +namespace nuget_host.Data.Roles +{ + public class AdminStartupList + { + public string [] Users { get; set;} + } +} \ No newline at end of file diff --git a/src/nuget-host/Startup.cs b/src/nuget-host/Startup.cs index 91c2a16..ca458ce 100644 --- a/src/nuget-host/Startup.cs +++ b/src/nuget-host/Startup.cs @@ -1,24 +1,18 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI; -using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.Extensions.Hosting; using nuget_host.Data; using nuget_host.Interfaces; using nuget_host.Services; using nuget_host.Entities; -using nuget_host.Data; -using System.Reflection; +using nuget_host.Authorization; +using nuget_host.Data.Roles; +using Microsoft.AspNetCore.Authorization; namespace nuget_host { @@ -40,7 +34,8 @@ namespace nuget_host services.AddIdentity() - .AddEntityFrameworkStores() + .AddRoles() + .AddEntityFrameworkStores() .AddSignInManager() .AddDefaultUI() .AddDefaultTokenProviders(); @@ -48,14 +43,27 @@ namespace nuget_host services.AddMvc(); services.AddDataProtection(); + services.AddTransient(); services.AddTransient(); + services.AddAuthorization(options => + { + options.AddPolicy(Constants.RequireAdminPolicyName, + policy => policy.RequireRole(Constants.AdministratorRoleName)); + options.AddPolicy(Constants.RequireValidApiKey, policy => + policy.Requirements.Add(new ValidApiKeyRequirement())); + + }); + + services.AddSingleton(); + var smtpSettingsconf = Configuration.GetSection("Smtp"); services.Configure(smtpSettingsconf); var nugetSettingsconf = Configuration.GetSection("Nuget"); services.Configure(nugetSettingsconf); - + var adminStartupListConf = Configuration.GetSection("AdminList"); + services.Configure(adminStartupListConf); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/src/nuget-host/appsettings.Development.json b/src/nuget-host/appsettings.Development.json index 8a1a06d..1d20ae9 100644 --- a/src/nuget-host/appsettings.Development.json +++ b/src/nuget-host/appsettings.Development.json @@ -1,4 +1,9 @@ { + "AdminStartupList": { + "Users": [ + "paul@pschneider.fr" + ] + }, "Nuget": { "PackagesRootDir" : "packages", "ProtectionTitle": "protected-data-v1", diff --git a/src/nuget-host/appsettings.json b/src/nuget-host/appsettings.json index b13dd72..6ce100d 100644 --- a/src/nuget-host/appsettings.json +++ b/src/nuget-host/appsettings.json @@ -1,4 +1,9 @@ { + "AdminStartupList": { + "Users": [ + "happy-new-root" + ] + }, "Nuget": { "PackagesRootDir" : "", "ProtectionTitle": "protected-data-v1",