diff options
| author | ivar <i@oiee.no> | 2025-12-03 21:49:20 +0100 |
|---|---|---|
| committer | ivar <i@oiee.no> | 2025-12-03 21:49:20 +0100 |
| commit | cd70f54266d708867a1eb35870bc755bc5b2df32 (patch) | |
| tree | f0a8ec571ef3f345ac74293b4cb11918878b3ed5 /api/WhatApi/Endpoints | |
| parent | 5bd9ad8bd1740dcff179d66718532086304ca4c4 (diff) | |
| download | what-cd70f54266d708867a1eb35870bc755bc5b2df32.tar.xz what-cd70f54266d708867a1eb35870bc755bc5b2df32.zip | |
Refactor db
Diffstat (limited to 'api/WhatApi/Endpoints')
| -rw-r--r-- | api/WhatApi/Endpoints/BaseEndpoint.cs | 1 | ||||
| -rw-r--r-- | api/WhatApi/Endpoints/CreateUserEndpoint.cs | 30 | ||||
| -rw-r--r-- | api/WhatApi/Endpoints/GetPlacesEndpoint.cs | 3 | ||||
| -rw-r--r-- | api/WhatApi/Endpoints/LoginEndpoint.cs | 52 | ||||
| -rw-r--r-- | api/WhatApi/Endpoints/UploadContentEndpoint.cs | 6 |
5 files changed, 87 insertions, 5 deletions
diff --git a/api/WhatApi/Endpoints/BaseEndpoint.cs b/api/WhatApi/Endpoints/BaseEndpoint.cs index 1fdf14f..0820ac1 100644 --- a/api/WhatApi/Endpoints/BaseEndpoint.cs +++ b/api/WhatApi/Endpoints/BaseEndpoint.cs @@ -2,6 +2,7 @@ using System.Net; namespace WhatApi.Endpoints; +[Authorize] [ApiController] public class BaseEndpoint : ControllerBase { diff --git a/api/WhatApi/Endpoints/CreateUserEndpoint.cs b/api/WhatApi/Endpoints/CreateUserEndpoint.cs new file mode 100644 index 0000000..dc89c16 --- /dev/null +++ b/api/WhatApi/Endpoints/CreateUserEndpoint.cs @@ -0,0 +1,30 @@ +namespace WhatApi.Endpoints; + +public class CreateUserEndpoint(AppDatabase db, IConfiguration configuration) : BaseEndpoint +{ + public class CreateUserRequest + { + public required string Email { get; set; } + public required string Password { get; set; } + public required string Name { get; set; } + } + + [AllowAnonymous] + [HttpPost("~/create-user")] + public async Task<ActionResult> HandleAsync(CreateUserRequest req, CancellationToken ct = default) { + var userList = await db.Users.Select(c => new { + c.Name + }).ToListAsync(ct); + if (userList.Count == 0 && !configuration.IsDevelopment) return Unauthorized(); + if (userList.Any(c => c.Name.Equals(req.Name, StringComparison.InvariantCultureIgnoreCase))) return BadRequest("Username taken"); + var user = new User { + Name = req.Name, + Email = req.Email, + PasswordHash = PasswordHasher.HashPassword(req.Password) + }; + user.SetCreated(Constants.SystemUid); + db.Users.Add(user); + await db.SaveChangesAsync(ct); + return Ok(); + } +}
\ No newline at end of file diff --git a/api/WhatApi/Endpoints/GetPlacesEndpoint.cs b/api/WhatApi/Endpoints/GetPlacesEndpoint.cs index 08068c8..28b1613 100644 --- a/api/WhatApi/Endpoints/GetPlacesEndpoint.cs +++ b/api/WhatApi/Endpoints/GetPlacesEndpoint.cs @@ -1,9 +1,8 @@ using NetTopologySuite.Features; -using WhatApi.Tables; namespace WhatApi.Endpoints; -public class GetPlacesEndpoint(Database db) : BaseEndpoint +public class GetPlacesEndpoint(AppDatabase db) : BaseEndpoint { [HttpGet("~/places")] public async Task<ActionResult> HandleAsync(double w, double s, double e, double n, CancellationToken ct = default) { diff --git a/api/WhatApi/Endpoints/LoginEndpoint.cs b/api/WhatApi/Endpoints/LoginEndpoint.cs new file mode 100644 index 0000000..ee697ef --- /dev/null +++ b/api/WhatApi/Endpoints/LoginEndpoint.cs @@ -0,0 +1,52 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Microsoft.AspNetCore.Identity; +using Microsoft.IdentityModel.Tokens; + +namespace WhatApi.Endpoints; + +public class LoginEndpoint(AppDatabase db, IConfiguration configuration) : BaseEndpoint +{ + public class LoginRequest + { + public required string Username { get; set; } + public required string Password { get; set; } + } + + [HttpPost("~/login")] + public async Task<ActionResult> HandleAsync(LoginRequest login, CancellationToken ct = default) { + var user = await db.Users.FirstOrDefaultAsync(c => c.Name == login.Username, ct); + if (user?.PasswordHash is null) return Unauthorized(); + + var verificationResult = PasswordHasher.VerifyHashedPassword(user.PasswordHash, login.Password); + if (verificationResult == PasswordVerificationResult.Failed) return Unauthorized(); + + var tokenEntropy = configuration.GetValue<string>(Constants.Env.TokenEntropy); + + ArgumentException.ThrowIfNullOrWhiteSpace(tokenEntropy); + + var key = Encoding.ASCII.GetBytes(tokenEntropy); + var tokenIssuer = configuration.GetValue<string>(Constants.Env.TokenIssuer); + var tokenAudience = configuration.GetValue<string>(Constants.Env.TokenAudience); + var tokenHandler = new JwtSecurityTokenHandler(); + + var tokenDescriptor = new SecurityTokenDescriptor { + Subject = new ClaimsIdentity([ + new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), + new Claim(ClaimTypes.Name, user.Name) + ]), + Expires = DateTime.UtcNow.AddMinutes(60), + Issuer = tokenIssuer, + Audience = tokenAudience, + SigningCredentials = new SigningCredentials( + new SymmetricSecurityKey(key), + SecurityAlgorithms.HmacSha256Signature) + }; + + var token = tokenHandler.CreateToken(tokenDescriptor); + var tokenString = tokenHandler.WriteToken(token); + user.SetLastSeen(); + await db.SaveChangesAsync(ct); + return Ok(tokenString); + } +}
\ No newline at end of file diff --git a/api/WhatApi/Endpoints/UploadContentEndpoint.cs b/api/WhatApi/Endpoints/UploadContentEndpoint.cs index 2c84252..26dbdba 100644 --- a/api/WhatApi/Endpoints/UploadContentEndpoint.cs +++ b/api/WhatApi/Endpoints/UploadContentEndpoint.cs @@ -1,6 +1,6 @@ namespace WhatApi.Endpoints; -public class UploadContentEndpoint(Database db) : BaseEndpoint +public class UploadContentEndpoint(AppDatabase db) : BaseEndpoint { public record UploadContent(IFormFile File, string LatLong); @@ -19,12 +19,12 @@ public class UploadContentEndpoint(Database db) : BaseEndpoint var gf = NtsGeometryServices.Instance.CreateGeometryFactory(srid: Constants.Wgs84SpatialReferenceId); var point = gf.CreatePoint(new Coordinate(double.Parse(longitude), double.Parse(latitude))); - var place = new Tables.Place() { + var place = new Place() { ContentId = contentId, Location = point }; - var content = new Tables.Content() { + var content = new Content() { Id = contentId, Mime = request.File.ContentType, BlobId = blobId, |
