Api protected

This commit is contained in:
Paul Schneider
2025-02-16 22:40:51 +00:00
parent 968859babe
commit 84e58bb9eb
6 changed files with 82 additions and 182 deletions

View File

@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />

View File

@ -17,165 +17,56 @@ namespace Yavsc.WebApi.Controllers
[Authorize("ApiScope")]
public class ApiAccountController : Controller
{
private UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
readonly ApplicationDbContext _dbContext;
private readonly ILogger _logger;
public ApiAccountController(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
RoleManager<IdentityRole> roleManager,
public ApiAccountController(
ILoggerFactory loggerFactory, ApplicationDbContext dbContext)
{
UserManager = userManager;
this.roleManager = roleManager;
_signInManager = signInManager;
_logger = loggerFactory.CreateLogger(nameof(ApiAccountController));
_dbContext = dbContext;
}
public UserManager<ApplicationUser> UserManager
{
get
{
return _userManager;
}
private set
{
_userManager = value;
}
}
private readonly RoleManager<IdentityRole> roleManager;
// POST api/Account/ChangePassword
public async Task<IActionResult> ChangePassword(ChangePasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState);
}
var user = await _userManager.FindByIdAsync(User.GetUserId());
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) {
IdentityResult result = await UserManager.ChangePasswordAsync(user, model.OldPassword,
model.NewPassword);
if (!result.Succeeded)
{
AddErrors("NewPassword",result);
return new BadRequestObjectResult(ModelState);
}
}
return Ok();
}
// POST api/Account/SetPassword
public async Task<IActionResult> SetPassword(SetPasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState);
}
var user = await _userManager.FindByIdAsync(User.GetUserId());
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) {
IdentityResult result = await UserManager.AddPasswordAsync(user, model.NewPassword);
if (!result.Succeeded)
{
AddErrors ("NewPassword",result);
return new BadRequestObjectResult(ModelState);
}
}
return Ok();
}
// POST api/Account/Register
[AllowAnonymous]
public async Task<IActionResult> Register(RegisterModel model)
{
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState);
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
AddErrors ("Register",result);
return new BadRequestObjectResult(ModelState);
}
await _signInManager.SignInAsync(user, isPersistent: false);
return Ok();
}
private void AddErrors(string key, IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(key, error.Description);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
UserManager.Dispose();
}
base.Dispose(disposing);
}
[HttpGet("me")]
public async Task<IActionResult> Me()
{
if (User==null)
return new BadRequestObjectResult(
new { error = "user not found" });
if (User == null)
return new BadRequestObjectResult(
new { error = "user not found" });
var uid = User.GetUserId();
var userData = await _dbContext.Users
.Include(u=>u.PostalAddress)
.Include(u=>u.AccountBalance)
.FirstAsync(u=>u.Id == uid);
var user = new Yavsc.Models.Auth.Me(userData.Id, userData.UserName, userData.Email,
userData.Avatar ,
userData.PostalAddress, userData.DedicatedGoogleCalendar );
var userData = await GetUserData(uid);
var userRoles = _dbContext.UserRoles.Where(u=>u.UserId == uid).Select(r => r.RoleId).ToArray();
var user = new Yavsc.Models.Auth.Me(userData.Id, userData.UserName, userData.Email,
userData.Avatar,
userData.PostalAddress, userData.DedicatedGoogleCalendar);
IdentityRole [] roles = _dbContext.Roles.Where(r=>userRoles.Contains(r.Id)).ToArray();
user.Roles = roles.Select(r=>r.Name).ToArray();
var userRoles = _dbContext.UserRoles.Where(u => u.UserId == uid).Select(r => r.RoleId).ToArray();
IdentityRole[] roles = _dbContext.Roles.Where(r => userRoles.Contains(r.Id)).ToArray();
user.Roles = roles.Select(r => r.Name).ToArray();
return Ok(user);
}
private async Task<ApplicationUser> GetUserData(string uid)
{
return await _dbContext.Users
.Include(u => u.PostalAddress)
.Include(u => u.AccountBalance)
.FirstAsync(u => u.Id == uid);
}
[HttpGet("myhost")]
public IActionResult MyHost ()
{
return Ok(new { host = Request.ForHost() });
}
/// <summary>
/// Actually only updates the user's name.
/// </summary>
/// <param name="me">MyUpdate containing the new user name </param>
/// <returns>Ok when all is ok.</returns>
[HttpPut("me")]
public async Task<IActionResult> UpdateMe(UserInfo me)
{
if (!ModelState.IsValid) return new BadRequestObjectResult(
new { error = "Specify some valid user update request." });
var user = await _userManager.FindByIdAsync(User.GetUserId());
var result = await _userManager.SetUserNameAsync(user, me.UserName);
if (result.Succeeded)
return Ok();
else return new BadRequestObjectResult(result);
}
/// <summary>
/// Updates the avatar
/// </summary>
@ -184,11 +75,11 @@ namespace Yavsc.WebApi.Controllers
public async Task<IActionResult> SetAvatar()
{
var root = User.InitPostToFileSystem(null);
var user = await _userManager.FindByIdAsync(User.GetUserId());
var user = await GetUserData(User.GetUserId());
if (Request.Form.Files.Count!=1)
return new BadRequestResult();
var info = user.ReceiveAvatar(Request.Form.Files[0]);
await _userManager.UpdateAsync(user);
await _dbContext.SaveChangesAsync();
return Ok(info);
}

View File

@ -28,7 +28,7 @@ internal class Program
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
builder.Services.AddDistributedMemoryCache();
// builder.Services.AddDistributedMemoryCache();
// accepts any access token issued by identity server
// adds an authorization policy for scope 'scope1'
@ -63,22 +63,21 @@ internal class Program
options.Authority = "https://localhost:5001";
options.TokenValidationParameters =
new() { ValidateAudience = false };
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
services.AddScoped<UserManager<ApplicationUser>>();
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
services.AddTransient<ITrueEmailSender, MailSender>()
.AddTransient<IBillingService, BillingService>()
.AddTransient<ICalendarManager, CalendarManager>();
/*
services.AddSingleton<IConnexionManager, HubConnectionManager>();
services.AddSingleton<ILiveProcessor, LiveProcessor>();
services.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>();
services.AddIdentityApiEndpoints<ApplicationUser>();
services.AddSession();
services.AddTransient<ITrueEmailSender, MailSender>()
.AddTransient<IBillingService, BillingService>()
.AddTransient<ICalendarManager, CalendarManager>()
.AddTransient<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>()
.AddTransient<DbContext>();
*/
using (var app = builder.Build())
{
if (app.Environment.IsDevelopment())
@ -89,18 +88,20 @@ internal class Program
.UseAuthentication()
.UseAuthorization()
.UseCors("default")
.UseEndpoints(endpoints =>
/* .UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute()
.RequireAuthorization();
});
app.MapIdentityApi<ApplicationUser>().RequireAuthorization("ApiScope");
})*/
;
// app.MapIdentityApi<ApplicationUser>().RequireAuthorization("ApiScope");
app.MapDefaultControllerRoute();
app.MapGet("/identity", (HttpContext context) =>
new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))
);
app.UseSession();
// app.UseSession();
await app.RunAsync();
};