namespace AAIntegration.SimmonsBank.API.Services; using AutoMapper; using BCrypt.Net; using AAIntegration.SimmonsBank.API.Entities; using AAIntegration.SimmonsBank.API.Config; using AAIntegration.SimmonsBank.API.Models.Users; using System; using System.Collections; using System.Collections.Generic; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.IdentityModel.Tokens; using System.Text; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using Microsoft.Extensions.Options; using System.Security.Cryptography; public interface IUserService { // New Based way string Create(UserCreateRequest model); void Update(string apiKey, UserUpdateRequest model); void Delete(string apiKey); Dictionary GetAllApiKeys(); User GetUser(string ApiKey); /* Other cringe way AuthenticateResponse Authenticate(AuthenticateRequest model); void Register(RegisterRequest model); IEnumerable GetAll(); User GetById(int id); void Update(int id, UserUpdateRequest model); void Delete(int id); Dictionary GetAllApiKeys(); string GetUserApiKey(int id); void InvalidateApiKey(string apiKey); string CreateUserApiKey(int id); */ } public class UserService : IUserService { private DataContext _context; private readonly IMapper _mapper; private readonly IOptions _appSettings; public UserService( DataContext context, IMapper mapper, IOptions appSettings) { _context = context; _mapper = mapper; _appSettings = appSettings; } public string Create(UserCreateRequest model) { User user = new User(); user.SimmonsBankUsername = model.Username; user.SimmonsBankPassword = model.Password; user.MFAKey = model.MFAKey; // Generate API Key user.ApiKey = generateApiKey(); // save user _context.Users.Add(user); _context.SaveChanges(); // Return API Key return user.ApiKey; } public void Update(string apiKey, UserUpdateRequest model) { var user = this.GetUser(apiKey); // User.Username if (model.Username != null) user.SimmonsBankUsername = model.Username; // User.Password if (model.Password != null) user.SimmonsBankPassword = model.Password; // User.MFAKey if (model.MFAKey != null) user.MFAKey = model.MFAKey; _context.Users.Update(user); _context.SaveChanges(); } public void Delete(string apiKey) { var user = this.GetUser(apiKey); _context.Users.Remove(user); _context.SaveChanges(); } public Dictionary GetAllApiKeys() { return _context.Users .Where(u => u.ApiKey != null) .ToDictionary(u => u.ApiKey, u => u.Id); } public User GetUser(string ApiKey) { var user = _context.Users .Where(u => u.ApiKey == ApiKey) .FirstOrDefault() ?? throw new KeyNotFoundException("User not found"); return user; } // helper methods private User getUser(int id) { var user = _context.Users.Find(id) ?? throw new KeyNotFoundException("User not found"); return user; } private const string _prefix = "CT-"; private const int _numberOfSecureBytesToGenerate = 32; private const int _lengthOfKey = 32; private string generateApiKey() { var bytes = RandomNumberGenerator.GetBytes(_numberOfSecureBytesToGenerate); string base64String = Convert.ToBase64String(bytes) .Replace("+", "-") .Replace("/", "_"); var keyLength = _lengthOfKey - _prefix.Length; return _prefix + base64String[..keyLength]; } }