Implemented api authentication. Removed old secret system

This commit is contained in:
2025-03-14 12:32:13 +01:00
parent 340cf738dc
commit f1c0d3b896
12 changed files with 302 additions and 131 deletions

View File

@@ -0,0 +1,56 @@
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using System.Text.Json;
using Microsoft.IdentityModel.Tokens;
using MoonCore.Attributes;
using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Database.Entities;
namespace Moonlight.ApiServer.Services;
[Singleton]
public class ApiKeyService
{
private readonly AppConfiguration Configuration;
public ApiKeyService(AppConfiguration configuration)
{
Configuration = configuration;
}
public string GenerateJwt(ApiKey apiKey)
{
var permissions = JsonSerializer.Deserialize<string[]>(apiKey.PermissionsJson) ?? [];
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
var descriptor = new SecurityTokenDescriptor()
{
Expires = apiKey.ExpiresAt,
IssuedAt = DateTime.Now,
NotBefore = DateTime.Now.AddMinutes(-1),
Claims = new Dictionary<string, object>()
{
{
"apiKeyId",
apiKey.Id
},
{
"permissions",
string.Join(";", permissions)
}
},
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration.Authentication.Secret)
),
SecurityAlgorithms.HmacSha256
),
Issuer = Configuration.PublicUrl,
Audience = Configuration.PublicUrl
};
var securityToken = jwtSecurityTokenHandler.CreateJwtSecurityToken(descriptor);
return jwtSecurityTokenHandler.WriteToken(securityToken);
}
}

View File

@@ -1,66 +0,0 @@
using MoonCore.Attributes;
using MoonCore.Exceptions;
using MoonCore.Extended.Abstractions;
using MoonCore.Extended.Helpers;
using MoonCore.Services;
using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Database.Entities;
namespace Moonlight.ApiServer.Services;
[Scoped]
public class AuthService
{
private readonly DatabaseRepository<User> UserRepository;
public AuthService(DatabaseRepository<User> userRepository)
{
UserRepository = userRepository;
}
public Task<User> Register(string username, string email, string password)
{
// Reformat values
username = username.ToLower().Trim();
email = email.ToLower().Trim();
// Check for users with the same values
if (UserRepository.Get().Any(x => x.Username == username))
throw new HttpApiException("A user with that username already exists", 400);
if (UserRepository.Get().Any(x => x.Email == email))
throw new HttpApiException("A user with that email address already exists", 400);
// Build model and add it to the database
var user = new User()
{
Username = username,
Email = email,
Password = HashHelper.Hash(password),
PermissionsJson = "[]",
TokenValidTimestamp = DateTime.UtcNow
};
UserRepository.Add(user);
return Task.FromResult(user);
}
public Task<User> Login(string email, string password)
{
// Reformat values
email = email.ToLower().Trim();
var user = UserRepository
.Get()
.FirstOrDefault(x => x.Email == email);
if (user == null)
throw new HttpApiException("Invalid email or password", 400);
if(!HashHelper.Verify(password, user.Password))
throw new HttpApiException("Invalid email or password", 400);
return Task.FromResult(user);
}
}