Files
Swarm/DysonNetwork.Sphere/Account/AccountGrpcService.cs

89 lines
3.0 KiB
C#

using DysonNetwork.Shared.Models;
using DysonNetwork.Sphere.Account.Proto;
using Grpc.Core;
using Google.Protobuf.WellKnownTypes;
using Microsoft.EntityFrameworkCore;
using DysonNetwork.Sphere.Auth;
namespace DysonNetwork.Sphere.Account;
public class AccountGrpcService : DysonNetwork.Sphere.Account.Proto.AccountService.AccountServiceBase
{
private readonly AppDatabase _db;
private readonly AuthService _auth;
public AccountGrpcService(AppDatabase db, AuthService auth)
{
_db = db;
_auth = auth;
}
public override async Task<AccountResponse> GetAccount(Empty request, ServerCallContext context)
{
var account = await GetAccountFromContext(context);
return ToAccountResponse(account);
}
public override async Task<AccountResponse> UpdateAccount(UpdateAccountRequest request, ServerCallContext context)
{
var account = await GetAccountFromContext(context);
if (request.Email != null)
{
var emailContact = await _db.AccountContacts.FirstOrDefaultAsync(c => c.AccountId == account.Id && c.Type == AccountContactType.Email);
if (emailContact != null)
{
emailContact.Content = request.Email;
}
else
{
account.Contacts.Add(new AccountContact { Type = AccountContactType.Email, Content = request.Email });
}
}
if (request.DisplayName != null)
{
account.Nick = request.DisplayName;
}
await _db.SaveChangesAsync();
return ToAccountResponse(account);
}
private async Task<Shared.Models.Account> GetAccountFromContext(ServerCallContext context)
{
var authorizationHeader = context.RequestHeaders.FirstOrDefault(h => h.Key == "authorization");
if (authorizationHeader == null)
{
throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Missing authorization header."));
}
var token = authorizationHeader.Value.Replace("Bearer ", "");
if (!_auth.ValidateToken(token, out var sessionId))
{
throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Invalid token."));
}
var session = await _db.AuthSessions.Include(s => s.Account).ThenInclude(a => a.Contacts).FirstOrDefaultAsync(s => s.Id == sessionId);
if (session == null)
{
throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Session not found."));
}
return session.Account;
}
private AccountResponse ToAccountResponse(Shared.Models.Account account)
{
var emailContact = account.Contacts.FirstOrDefault(c => c.Type == AccountContactType.Email);
return new AccountResponse
{
Id = account.Id.ToString(),
Username = account.Name,
Email = emailContact?.Content ?? "",
DisplayName = account.Nick
};
}
}