User profile service #2
12 changed files with 416 additions and 14 deletions
29
DrinkRateAPI/ApiModels/UserProfile/UserProfileGet.cs
Normal file
29
DrinkRateAPI/ApiModels/UserProfile/UserProfileGet.cs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
namespace DrinkRateAPI.ApiModels.UserProfile;
|
||||||
|
|
||||||
|
public class UserProfileGet
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// User profile ID
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User profile name
|
||||||
|
/// </summary>
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is user admin
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAdmin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is user deleted
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applicaton user ID of the user profile
|
||||||
|
/// </summary>
|
||||||
|
public string ApplicationUserId { get; set; }
|
||||||
|
}
|
9
DrinkRateAPI/ApiModels/UserProfile/UserProfilePut.cs
Normal file
9
DrinkRateAPI/ApiModels/UserProfile/UserProfilePut.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace DrinkRateAPI.ApiModels.UserProfile;
|
||||||
|
|
||||||
|
public class UserProfilePut : UserProfileSelfPut
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Is user admin
|
||||||
|
/// </summary>
|
||||||
|
public bool? IsAdmin { get; set; }
|
||||||
|
}
|
9
DrinkRateAPI/ApiModels/UserProfile/UserProfileSelfPut.cs
Normal file
9
DrinkRateAPI/ApiModels/UserProfile/UserProfileSelfPut.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace DrinkRateAPI.ApiModels.UserProfile;
|
||||||
|
|
||||||
|
public class UserProfileSelfPut
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// User profile name
|
||||||
|
/// </summary>
|
||||||
|
public string? UserName { get; set; }
|
||||||
|
}
|
36
DrinkRateAPI/AuthorizationPolicies/AdminOnlyRequirement.cs
Normal file
36
DrinkRateAPI/AuthorizationPolicies/AdminOnlyRequirement.cs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
using DrinkRateAPI.DbEntities;
|
||||||
|
using DrinkRateAPI.Services;
|
||||||
|
|
||||||
|
namespace DrinkRateAPI.AuthorizationPolicies;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
|
public class AdminOnlyRequirement : IAuthorizationRequirement
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AdminOnlyHandler : AuthorizationHandler<AdminOnlyRequirement>
|
||||||
|
{
|
||||||
|
private readonly ApplicationUserService _applicationUserService;
|
||||||
|
private readonly UserProfileService _userProfileService;
|
||||||
|
|
||||||
|
public AdminOnlyHandler(
|
||||||
|
ApplicationUserService applicationUserService,
|
||||||
|
UserProfileService userProfileService)
|
||||||
|
{
|
||||||
|
_applicationUserService = applicationUserService;
|
||||||
|
_userProfileService = userProfileService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task HandleRequirementAsync(
|
||||||
|
AuthorizationHandlerContext context,
|
||||||
|
AdminOnlyRequirement requirement)
|
||||||
|
{
|
||||||
|
var userProfile = await _applicationUserService.UserProfileByApplicationUserAsync(context.User);
|
||||||
|
|
||||||
|
if (_userProfileService.IsUserProfileAdmin(userProfile))
|
||||||
|
{
|
||||||
|
context.Succeed(requirement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
DrinkRateAPI/Controllers/UserProfileController.cs
Normal file
48
DrinkRateAPI/Controllers/UserProfileController.cs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
using DrinkRateAPI.ApiModels.UserProfile;
|
||||||
|
using DrinkRateAPI.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace DrinkRateAPI.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("userProfile")]
|
||||||
|
public class UserProfileController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly UserProfileService _userProfileService;
|
||||||
|
|
||||||
|
public UserProfileController(UserProfileService userProfileService)
|
||||||
|
{
|
||||||
|
_userProfileService = userProfileService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public async Task<UserProfileGet> PutUserProfileSelf([FromBody] UserProfileSelfPut userProfile)
|
||||||
|
{
|
||||||
|
return await _userProfileService.PutUserProfileSelfAsync(User, userProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public async Task<UserProfileGet> GetUserProfileSelf()
|
||||||
|
{
|
||||||
|
return await _userProfileService.GetUserProfileSelfAsync(User);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{userId}")]
|
||||||
|
[Authorize(Policy = "AdminOnly")]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public async Task<UserProfileGet> PutUserProfile(string userId, [FromBody] UserProfilePut userProfile)
|
||||||
|
{
|
||||||
|
return await _userProfileService.PutUserProfileAsync(User, userProfile, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{userId}")]
|
||||||
|
[Authorize(Policy = "AdminOnly")]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public async Task<UserProfileGet> GetUserProfile(string userId)
|
||||||
|
{
|
||||||
|
return await _userProfileService.GetUserProfileAsync(User, userId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,5 @@ public class DbUserProfile : DbEntityWithHistory
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
|
|
||||||
public Guid ApplicationUserId { get; set; }
|
public Guid ApplicationUserId { get; set; }
|
||||||
|
|
||||||
public virtual DbApplicationUser ApplicationUser { get; set; }
|
public virtual DbApplicationUser ApplicationUser { get; set; }
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="ApiModels\" />
|
||||||
<Folder Include="Migrations\" />
|
<Folder Include="Migrations\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
52
DrinkRateAPI/Exceptions/ExceptionHandlingMiddleware.cs
Normal file
52
DrinkRateAPI/Exceptions/ExceptionHandlingMiddleware.cs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
|
||||||
|
namespace DrinkRateAPI.Exceptions;
|
||||||
|
|
||||||
|
public record ExceptionResponse(int StatusCode, string Description);
|
||||||
|
|
||||||
|
public class ExceptionHandlingMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
|
||||||
|
|
||||||
|
public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await HandleExceptionAsync(context, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
_logger.LogError(exception, "An unexpected error occurred.");
|
||||||
|
|
||||||
|
|
||||||
|
var response = exception switch
|
||||||
|
{
|
||||||
|
BadRequestException _ => new ExceptionResponse(StatusCodes.Status400BadRequest, "Application exception occurred."),
|
||||||
|
NotFoundException _ => new ExceptionResponse(StatusCodes.Status404NotFound, "The request key not found."),
|
||||||
|
UnauthenticatedException _ => new ExceptionResponse(StatusCodes.Status401Unauthorized, "Unauthorized."),
|
||||||
|
PaymentRequiredException _ => new ExceptionResponse(StatusCodes.Status402PaymentRequired, "Payment required."),
|
||||||
|
ForbiddenException _ => new ExceptionResponse(StatusCodes.Status403Forbidden, "Forbidden."),
|
||||||
|
IamATeapotException _ => new ExceptionResponse(StatusCodes.Status418ImATeapot, "I am a teapot."),
|
||||||
|
UnavailableForLagalReasonsException _ => new ExceptionResponse(StatusCodes.Status451UnavailableForLegalReasons, "Unavailable for legal reasons."),
|
||||||
|
_ => new ExceptionResponse(StatusCodes.Status500InternalServerError, "Internal server error. Please retry later.")
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.StatusCode = response.StatusCode;
|
||||||
|
await context.Response.WriteAsJsonAsync(response);
|
||||||
|
}
|
||||||
|
}
|
70
DrinkRateAPI/Exceptions/Exceptions.cs
Normal file
70
DrinkRateAPI/Exceptions/Exceptions.cs
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
namespace DrinkRateAPI.Exceptions;
|
||||||
|
|
||||||
|
public class DrinkRateException : Exception
|
||||||
|
{
|
||||||
|
public DrinkRateException() : base() { }
|
||||||
|
public DrinkRateException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 400 - Bad request
|
||||||
|
/// </summary>
|
||||||
|
public class BadRequestException : DrinkRateException
|
||||||
|
{
|
||||||
|
public BadRequestException() : base() { }
|
||||||
|
public BadRequestException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 401 - Unauthenticated
|
||||||
|
/// </summary>
|
||||||
|
public class UnauthenticatedException : DrinkRateException
|
||||||
|
{
|
||||||
|
public UnauthenticatedException() : base() { }
|
||||||
|
public UnauthenticatedException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 402 - Payment required
|
||||||
|
/// </summary>
|
||||||
|
public class PaymentRequiredException : DrinkRateException
|
||||||
|
{
|
||||||
|
public PaymentRequiredException() : base() { }
|
||||||
|
public PaymentRequiredException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 403 - Forbidden
|
||||||
|
/// </summary>
|
||||||
|
public class ForbiddenException : DrinkRateException
|
||||||
|
{
|
||||||
|
public ForbiddenException() : base() { }
|
||||||
|
public ForbiddenException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 404 - Not found
|
||||||
|
/// </summary>
|
||||||
|
public class NotFoundException : DrinkRateException
|
||||||
|
{
|
||||||
|
public NotFoundException() : base() { }
|
||||||
|
public NotFoundException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 418 - I'm a teapot
|
||||||
|
/// </summary>
|
||||||
|
public class IamATeapotException : DrinkRateException
|
||||||
|
{
|
||||||
|
public IamATeapotException() : base() { }
|
||||||
|
public IamATeapotException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 451 - Unavailable for lagal reasons
|
||||||
|
/// </summary>
|
||||||
|
public class UnavailableForLagalReasonsException : DrinkRateException
|
||||||
|
{
|
||||||
|
public UnavailableForLagalReasonsException() : base() { }
|
||||||
|
public UnavailableForLagalReasonsException(string message) : base(message) { }
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
|
using DrinkRateAPI.AuthorizationPolicies;
|
||||||
using DrinkRateAPI.Contexts;
|
using DrinkRateAPI.Contexts;
|
||||||
using DrinkRateAPI.DbEntities;
|
using DrinkRateAPI.DbEntities;
|
||||||
|
using DrinkRateAPI.Exceptions;
|
||||||
|
using DrinkRateAPI.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
|
||||||
|
@ -10,10 +14,13 @@ var builder = WebApplication.CreateBuilder(args);
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddAuthorization();
|
builder.Services.AddAuthorizationBuilder()
|
||||||
|
.AddPolicy("AdminOnly", policy =>
|
||||||
|
policy.Requirements.Add(new AdminOnlyRequirement()));
|
||||||
builder.Services.AddIdentityApiEndpoints<DbApplicationUser>()
|
builder.Services.AddIdentityApiEndpoints<DbApplicationUser>()
|
||||||
.AddEntityFrameworkStores<ApplicationDbContext>();
|
.AddEntityFrameworkStores<ApplicationDbContext>();
|
||||||
builder.Services.AddScoped<UserManager<DbApplicationUser>, UserWithProfileManager>();
|
builder.Services.AddScoped<UserManager<DbApplicationUser>, UserWithProfileManager>();
|
||||||
|
builder.Services.AddScoped<IAuthorizationHandler, AdminOnlyHandler>();
|
||||||
|
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
|
@ -31,25 +38,26 @@ builder.Services.AddSwaggerGen(c =>
|
||||||
|
|
||||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
new OpenApiSecurityScheme
|
|
||||||
{
|
{
|
||||||
Reference = new OpenApiReference
|
new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Type = ReferenceType.SecurityScheme,
|
Reference = new OpenApiReference
|
||||||
Id = "Bearer"
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer"
|
||||||
|
},
|
||||||
|
Scheme = "oauth2",
|
||||||
|
Name = "Bearer",
|
||||||
|
In = ParameterLocation.Header,
|
||||||
},
|
},
|
||||||
Scheme = "oauth2",
|
new List<string>()
|
||||||
Name = "Bearer",
|
|
||||||
In = ParameterLocation.Header,
|
|
||||||
|
|
||||||
},
|
|
||||||
new List<string>()
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddDbContext<ApplicationDbContext>();
|
builder.Services.AddDbContext<ApplicationDbContext>();
|
||||||
|
builder.Services.AddScoped<ApplicationUserService>();
|
||||||
|
builder.Services.AddScoped<UserProfileService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
@ -63,6 +71,8 @@ if (app.Environment.IsDevelopment())
|
||||||
|
|
||||||
app.MapIdentityApi<DbApplicationUser>();
|
app.MapIdentityApi<DbApplicationUser>();
|
||||||
|
|
||||||
|
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
21
DrinkRateAPI/Services/ApplicationUserService.cs
Normal file
21
DrinkRateAPI/Services/ApplicationUserService.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
using DrinkRateAPI.Contexts;
|
||||||
|
using DrinkRateAPI.DbEntities;
|
||||||
|
using DrinkRateAPI.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace DrinkRateAPI.Services;
|
||||||
|
|
||||||
|
public class ApplicationUserService(ApplicationDbContext context)
|
||||||
|
{
|
||||||
|
private ApplicationDbContext _context = context;
|
||||||
|
public async Task<DbUserProfile> UserProfileByApplicationUserAsync(ClaimsPrincipal identity)
|
||||||
|
{
|
||||||
|
var appUserId = identity.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
var profile = await _context.UserProfiles
|
||||||
|
.FirstOrDefaultAsync(x => x.ApplicationUserId.ToString() == appUserId && !x.IsDeleted)
|
||||||
|
?? throw new NotFoundException();
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
}
|
118
DrinkRateAPI/Services/UserProfileService.cs
Normal file
118
DrinkRateAPI/Services/UserProfileService.cs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
using DrinkRateAPI.ApiModels.UserProfile;
|
||||||
|
using DrinkRateAPI.Contexts;
|
||||||
|
using DrinkRateAPI.DbEntities;
|
||||||
|
using DrinkRateAPI.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace DrinkRateAPI.Services;
|
||||||
|
|
||||||
|
public class UserProfileService(ApplicationDbContext context, ApplicationUserService applicationUserService)
|
||||||
|
{
|
||||||
|
private ApplicationDbContext _context = context;
|
||||||
|
private ApplicationUserService _applicationUserService = applicationUserService;
|
||||||
|
|
||||||
|
public bool IsUserProfileAdmin(DbUserProfile userProfile)
|
||||||
|
{
|
||||||
|
return userProfile.IsAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserProfileGet> PutUserProfileSelfAsync(ClaimsPrincipal identity, UserProfileSelfPut userProfileSelfPut)
|
||||||
|
{
|
||||||
|
var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity);
|
||||||
|
|
||||||
|
var userId = authenticatedUser.Id.ToString();
|
||||||
|
await PutUserProfile(userProfileSelfPut, userId, false);
|
||||||
|
|
||||||
|
return await GetUserProfile(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserProfileGet> GetUserProfileSelfAsync(ClaimsPrincipal identity)
|
||||||
|
{
|
||||||
|
var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity);
|
||||||
|
|
||||||
|
var userId = authenticatedUser.Id.ToString();
|
||||||
|
|
||||||
|
return await GetUserProfile(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserProfileGet> PutUserProfileAsync(ClaimsPrincipal identity, UserProfilePut userProfilePut, string userId)
|
||||||
|
{
|
||||||
|
var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity);
|
||||||
|
|
||||||
|
if (authenticatedUser.Id.ToString() == userId)
|
||||||
|
{
|
||||||
|
// Prevent admin de-admining him/herself
|
||||||
|
await PutUserProfile(userProfilePut, userId, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await PutUserProfile(userProfilePut, userId, IsUserProfileAdmin(authenticatedUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
return await GetUserProfile(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserProfileGet> GetUserProfileAsync(ClaimsPrincipal identity, string userId)
|
||||||
|
{
|
||||||
|
var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity);
|
||||||
|
|
||||||
|
return await GetUserProfile(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PutUserProfile<TUserProfilePut>(TUserProfilePut userProfilePut, string userId, bool byAdmin) where TUserProfilePut : UserProfileSelfPut
|
||||||
|
{
|
||||||
|
var userProfile = await GetUserProfileById(userId);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(userProfilePut.UserName) && userProfile.UserName != userProfilePut.UserName)
|
||||||
|
{
|
||||||
|
var userByName = await TryGetUserProfileByUserName(userProfilePut.UserName);
|
||||||
|
if (userByName == null)
|
||||||
|
{
|
||||||
|
userProfile.UserName = userProfilePut.UserName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new BadRequestException($"User with username {userProfilePut.UserName} already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byAdmin && userProfilePut is UserProfilePut adminPut && adminPut.IsAdmin != null)
|
||||||
|
{
|
||||||
|
userProfile.IsAdmin = (bool)adminPut.IsAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.UserProfiles.Update(userProfile);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<UserProfileGet> GetUserProfile(string userId)
|
||||||
|
{
|
||||||
|
var userProfile = await GetUserProfileById(userId);
|
||||||
|
|
||||||
|
var userProfileGet = new UserProfileGet
|
||||||
|
{
|
||||||
|
Id = userProfile.Id.ToString(),
|
||||||
|
UserName = userProfile.UserName,
|
||||||
|
IsAdmin = userProfile.IsAdmin,
|
||||||
|
IsDeleted = userProfile.IsDeleted,
|
||||||
|
ApplicationUserId = userProfile.ApplicationUserId.ToString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return userProfileGet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<DbUserProfile> GetUserProfileById(string userId)
|
||||||
|
{
|
||||||
|
var userProfile = await _context.UserProfiles.FirstOrDefaultAsync(x => x.Id.ToString() == userId);
|
||||||
|
|
||||||
|
return userProfile ?? throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<DbUserProfile?> TryGetUserProfileByUserName(string userName)
|
||||||
|
{
|
||||||
|
var userProfile = await _context.UserProfiles.FirstOrDefaultAsync(x => x.UserName == userName);
|
||||||
|
|
||||||
|
return userProfile;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue