Implemented api authentication. Removed old secret system
This commit is contained in:
56
Moonlight.ApiServer/Services/ApiKeyService.cs
Normal file
56
Moonlight.ApiServer/Services/ApiKeyService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user