146 lines
3.8 KiB
C#

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<string, int> GetAllApiKeys();
/* Other cringe way
AuthenticateResponse Authenticate(AuthenticateRequest model);
void Register(RegisterRequest model);
IEnumerable<User> GetAll();
User GetById(int id);
void Update(int id, UserUpdateRequest model);
void Delete(int id);
Dictionary<string, int> 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> _appSettings;
public UserService(
DataContext context,
IMapper mapper,
IOptions<AppSettings> 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 = 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 = getUser(apiKey);
_context.Users.Remove(user);
_context.SaveChanges();
}
public Dictionary<string, int> GetAllApiKeys()
{
return _context.Users
.Where(u => u.ApiKey != null)
.ToDictionary(u => u.ApiKey, u => u.Id);
}
// helper methods
private User getUser(int id)
{
var user = _context.Users.Find(id);
if (user == null) throw new KeyNotFoundException("User not found");
return user;
}
private User getUser(string ApiKey)
{
var user = _context.Users
.Where(u => u.ApiKey == ApiKey)
.FirstOrDefault();
if (user == null) 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];
}
}