:drunk: No idea what did AI did
This commit is contained in:
181
DysonNetwork.Pass/Features/Auth/Services/AccountService.cs
Normal file
181
DysonNetwork.Pass/Features/Auth/Services/AccountService.cs
Normal file
@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DysonNetwork.Common.Models;
|
||||
using DysonNetwork.Pass.Data;
|
||||
using DysonNetwork.Pass.Features.Auth.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using Account = DysonNetwork.Common.Models.Account;
|
||||
using AuthTokens = DysonNetwork.Common.Models.AuthTokens;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.Services;
|
||||
|
||||
public class AccountService : IAccountService
|
||||
{
|
||||
private readonly PassDatabase _db;
|
||||
private readonly IClock _clock;
|
||||
|
||||
public AccountService(PassDatabase db, IClock clock)
|
||||
{
|
||||
_db = db;
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
public async Task<Account> CreateAccount(Common.Models.OidcUserInfo userInfo)
|
||||
{
|
||||
if (string.IsNullOrEmpty(userInfo.Email))
|
||||
throw new ArgumentException("Email is required for account creation", nameof(userInfo));
|
||||
|
||||
var now = _clock.GetCurrentInstant();
|
||||
var account = new Models.Account
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Email = userInfo.Email,
|
||||
Name = userInfo.Name ?? userInfo.Email.Split('@')[0],
|
||||
CreatedAt = now,
|
||||
UpdatedAt = now,
|
||||
Status = "Active"
|
||||
};
|
||||
|
||||
_db.Accounts.Add(account);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return new Account
|
||||
{
|
||||
Id = account.Id.ToString(),
|
||||
Email = account.Email,
|
||||
Name = account.Name,
|
||||
CreatedAt = account.CreatedAt,
|
||||
UpdatedAt = account.UpdatedAt,
|
||||
Status = account.Status
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Account?> FindByEmailAsync(string email)
|
||||
{
|
||||
if (string.IsNullOrEmpty(email))
|
||||
return null;
|
||||
|
||||
var account = await _db.Accounts
|
||||
.FirstOrDefaultAsync(a => a.Email == email);
|
||||
|
||||
if (account == null)
|
||||
return null;
|
||||
|
||||
return new Account
|
||||
{
|
||||
Id = account.Id.ToString(),
|
||||
Email = account.Email,
|
||||
Name = account.Name,
|
||||
CreatedAt = account.CreatedAt,
|
||||
UpdatedAt = account.UpdatedAt,
|
||||
Status = account.Status
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Account?> FindByIdAsync(string accountId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(accountId) || !Guid.TryParse(accountId, out var id))
|
||||
return null;
|
||||
|
||||
var account = await _db.Accounts
|
||||
.FirstOrDefaultAsync(a => a.Id == id);
|
||||
|
||||
if (account == null)
|
||||
return null;
|
||||
|
||||
return new Account
|
||||
{
|
||||
Id = account.Id.ToString(),
|
||||
Email = account.Email,
|
||||
Name = account.Name,
|
||||
CreatedAt = account.CreatedAt,
|
||||
UpdatedAt = account.UpdatedAt,
|
||||
Status = account.Status
|
||||
};
|
||||
}
|
||||
|
||||
public async Task UpdateAccount(Account account)
|
||||
{
|
||||
if (!Guid.TryParse(account.Id, out var id))
|
||||
throw new ArgumentException("Invalid account ID format", nameof(account));
|
||||
|
||||
var existingAccount = await _db.Accounts.FindAsync(id);
|
||||
if (existingAccount == null)
|
||||
throw new InvalidOperationException($"Account with ID {account.Id} not found");
|
||||
|
||||
existingAccount.Name = account.Name;
|
||||
existingAccount.Email = account.Email;
|
||||
existingAccount.UpdatedAt = _clock.GetCurrentInstant();
|
||||
existingAccount.Status = account.Status;
|
||||
|
||||
_db.Accounts.Update(existingAccount);
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<Account> FindOrCreateAccountAsync(Common.Models.OidcUserInfo userInfo, string provider)
|
||||
{
|
||||
if (string.IsNullOrEmpty(userInfo.Email))
|
||||
throw new ArgumentException("Email is required for account creation", nameof(userInfo));
|
||||
|
||||
// Check if account exists by email
|
||||
var account = await FindByEmailAsync(userInfo.Email);
|
||||
if (account != null)
|
||||
return account;
|
||||
|
||||
// Create new account if not found
|
||||
return await CreateAccount(userInfo);
|
||||
}
|
||||
|
||||
public async Task<Account?> GetAccountByIdAsync(Guid accountId)
|
||||
{
|
||||
var account = await _db.Accounts
|
||||
.FirstOrDefaultAsync(a => a.Id == accountId);
|
||||
|
||||
if (account == null)
|
||||
return null;
|
||||
|
||||
return new Account
|
||||
{
|
||||
Id = account.Id.ToString(),
|
||||
Email = account.Email,
|
||||
Name = account.Name,
|
||||
CreatedAt = account.CreatedAt,
|
||||
UpdatedAt = account.UpdatedAt,
|
||||
Status = account.Status
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<AuthTokens> GenerateAuthTokensAsync(Account account, string sessionId)
|
||||
{
|
||||
if (!Guid.TryParse(sessionId, out var sessionGuid))
|
||||
throw new ArgumentException("Invalid session ID format", nameof(sessionId));
|
||||
|
||||
var now = _clock.GetCurrentInstant();
|
||||
var accessTokenLifetime = Duration.FromHours(1);
|
||||
var accessTokenExpiry = now.Plus(accessTokenLifetime);
|
||||
|
||||
// In a real implementation, you would generate proper JWT tokens here
|
||||
// This is a simplified version for demonstration
|
||||
var accessToken = $"access_token_{Guid.NewGuid()}";
|
||||
var refreshToken = $"refresh_token_{Guid.NewGuid()}";
|
||||
|
||||
// Create or update the session
|
||||
var session = await _db.AuthSessions.FindAsync(sessionGuid);
|
||||
if (session != null)
|
||||
{
|
||||
session.UpdateTokens(accessToken, refreshToken, accessTokenLifetime);
|
||||
_db.AuthSessions.Update(session);
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return new AuthTokens
|
||||
{
|
||||
AccessToken = accessToken,
|
||||
RefreshToken = refreshToken,
|
||||
ExpiresIn = (int)accessTokenLifetime.TotalSeconds,
|
||||
TokenType = "Bearer"
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user