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 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 GetUserProfileSelfAsync(ClaimsPrincipal identity) { var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity); var userId = authenticatedUser.Id.ToString(); return await GetUserProfile(userId); } public async Task 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 GetUserProfileAsync(ClaimsPrincipal identity, string userId) { var authenticatedUser = await _applicationUserService.UserProfileByApplicationUserAsync(identity); return await GetUserProfile(userId); } private async Task PutUserProfile(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 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 GetUserProfileById(string userId) { var userProfile = await _context.UserProfiles.FirstOrDefaultAsync(x => x.Id.ToString() == userId); return userProfile ?? throw new NotFoundException(); } private async Task TryGetUserProfileByUserName(string userName) { var userProfile = await _context.UserProfiles.FirstOrDefaultAsync(x => x.UserName == userName); return userProfile; } }