♻️ Moving to MagicOnion
This commit is contained in:
		| @@ -1,96 +0,0 @@ | ||||
| using DysonNetwork.Shared.Protos.Auth; | ||||
| using Grpc.Core; | ||||
| using Google.Protobuf.WellKnownTypes; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using NodaTime; | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using DysonNetwork.Pass.Account; | ||||
| using Challenge = DysonNetwork.Shared.Models.Challenge; | ||||
| using Session = DysonNetwork.Shared.Models.Session; | ||||
|  | ||||
| namespace DysonNetwork.Pass.Auth; | ||||
|  | ||||
| public class AuthGrpcService(AppDatabase db, AccountService accounts, AuthService auth) | ||||
|     : DysonNetwork.Shared.Protos.Auth.AuthService.AuthServiceBase | ||||
| { | ||||
|     public override async Task<LoginResponse> Login(LoginRequest request, ServerCallContext context) | ||||
|     { | ||||
|         var account = await accounts.LookupAccount(request.Username); | ||||
|         if (account == null) | ||||
|         { | ||||
|             throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, "Account not found.")); | ||||
|         } | ||||
|  | ||||
|         var factor = await db.AccountAuthFactors.FirstOrDefaultAsync(f => f.AccountId == account.Id && f.Type == AccountAuthFactorType.Password); | ||||
|         if (factor == null || !factor.VerifyPassword(request.Password)) | ||||
|         { | ||||
|             throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Invalid credentials.")); | ||||
|         } | ||||
|  | ||||
|         var session = new Session | ||||
|         { | ||||
|             LastGrantedAt = Instant.FromDateTimeUtc(DateTime.UtcNow), | ||||
|             ExpiredAt = Instant.FromDateTimeUtc(DateTime.UtcNow.AddDays(30)), | ||||
|             Account = account, | ||||
|             Challenge = new Challenge() | ||||
|         }; | ||||
|  | ||||
|         db.AuthSessions.Add(session); | ||||
|         await db.SaveChangesAsync(); | ||||
|  | ||||
|         var token = auth.CreateToken(session); | ||||
|  | ||||
|         return new LoginResponse | ||||
|         { | ||||
|             AccessToken = token, | ||||
|             ExpiresIn = (long)(session.ExpiredAt.Value - session.LastGrantedAt.Value).TotalSeconds | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public override async Task<IntrospectionResponse> IntrospectToken(IntrospectTokenRequest request, ServerCallContext context) | ||||
|     { | ||||
|         if (auth.ValidateToken(request.Token, out var sessionId)) | ||||
|         { | ||||
|             var session = await db.AuthSessions | ||||
|                 .Include(s => s.Account) | ||||
|                 .Include(s => s.Challenge) | ||||
|                 .FirstOrDefaultAsync(s => s.Id == sessionId); | ||||
|  | ||||
|             if (session != null) | ||||
|             { | ||||
|                 return new IntrospectionResponse | ||||
|                 { | ||||
|                     Active = true, | ||||
|                     Claims = JsonSerializer.Serialize(new { sub = session.AccountId }), | ||||
|                     ClientId = session.AppId?.ToString() ?? "", | ||||
|                     Username = session.Account.Name, | ||||
|                     Scope = string.Join(" ", session.Challenge.Scopes), | ||||
|                     Iat = Timestamp.FromDateTime(session.CreatedAt.ToDateTimeUtc()), | ||||
|                     Exp = Timestamp.FromDateTime(session.ExpiredAt?.ToDateTimeUtc() ?? DateTime.MaxValue) | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return new IntrospectionResponse { Active = false }; | ||||
|     } | ||||
|  | ||||
|     public override async Task<Empty> Logout(Empty request, ServerCallContext context) | ||||
|     { | ||||
|         var authorizationHeader = context.RequestHeaders.FirstOrDefault(h => h.Key == "authorization"); | ||||
|         if (authorizationHeader != null) | ||||
|         { | ||||
|             var token = authorizationHeader.Value.Replace("Bearer ", ""); | ||||
|             if (auth.ValidateToken(token, out var sessionId)) | ||||
|             { | ||||
|                 var session = await db.AuthSessions.FindAsync(sessionId); | ||||
|                 if (session != null) | ||||
|                 { | ||||
|                     db.AuthSessions.Remove(session); | ||||
|                     await db.SaveChangesAsync(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return new Empty(); | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
|  | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace DysonNetwork.Sphere.Auth.OpenId; | ||||
| namespace DysonNetwork.Pass.Auth.OpenId; | ||||
|  | ||||
| public class AppleMobileConnectRequest | ||||
| { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.IdentityModel.Tokens; | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using DysonNetwork.Pass.Account; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Net.Http.Json; | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
|  | ||||
| namespace DysonNetwork.Pass.Auth.OpenId; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Net.Http.Json; | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
|  | ||||
| namespace DysonNetwork.Pass.Auth.OpenId; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.IdentityModel.Tokens.Jwt; | ||||
| using System.Net.Http.Json; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.IdentityModel.Tokens; | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Net.Http.Json; | ||||
| using System.Text.Json; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using Microsoft.Extensions.Configuration; | ||||
|  | ||||
| namespace DysonNetwork.Pass.Auth.OpenId; | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using DysonNetwork.Pass.Account; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
|   | ||||
| @@ -3,7 +3,6 @@ using System.Net.Http.Json; | ||||
| using System.Text.Json.Serialization; | ||||
| using DysonNetwork.Shared.Cache; | ||||
| using DysonNetwork.Shared.Models; | ||||
| using DysonNetwork.Sphere.Auth.OpenId; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.Extensions.Configuration; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace DysonNetwork.Sphere.Auth.OpenId; | ||||
| namespace DysonNetwork.Pass.Auth.OpenId; | ||||
|  | ||||
| /// <summary> | ||||
| /// Represents the state parameter used in OpenID Connect flows. | ||||
|   | ||||
| @@ -1,49 +0,0 @@ | ||||
| namespace DysonNetwork.Sphere.Auth.OpenId; | ||||
|  | ||||
| /// <summary> | ||||
| /// Represents the user information from an OIDC provider | ||||
| /// </summary> | ||||
| public class OidcUserInfo | ||||
| { | ||||
|     public string? UserId { get; set; } | ||||
|     public string? Email { get; set; } | ||||
|     public bool EmailVerified { get; set; } | ||||
|     public string FirstName { get; set; } = ""; | ||||
|     public string LastName { get; set; } = ""; | ||||
|     public string DisplayName { get; set; } = ""; | ||||
|     public string PreferredUsername { get; set; } = ""; | ||||
|     public string? ProfilePictureUrl { get; set; } | ||||
|     public string Provider { get; set; } = ""; | ||||
|     public string? RefreshToken { get; set; } | ||||
|     public string? AccessToken { get; set; } | ||||
|  | ||||
|     public Dictionary<string, object> ToMetadata() | ||||
|     { | ||||
|         var metadata = new Dictionary<string, object>(); | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(UserId)) | ||||
|             metadata["user_id"] = UserId; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(Email)) | ||||
|             metadata["email"] = Email; | ||||
|  | ||||
|         metadata["email_verified"] = EmailVerified; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(FirstName)) | ||||
|             metadata["first_name"] = FirstName; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(LastName)) | ||||
|             metadata["last_name"] = LastName; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(DisplayName)) | ||||
|             metadata["display_name"] = DisplayName; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(PreferredUsername)) | ||||
|             metadata["preferred_username"] = PreferredUsername; | ||||
|  | ||||
|         if (!string.IsNullOrWhiteSpace(ProfilePictureUrl)) | ||||
|             metadata["profile_picture_url"] = ProfilePictureUrl; | ||||
|  | ||||
|         return metadata; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user