♻️ Move most of models to the Shared package
This commit is contained in:
@ -12,6 +12,7 @@ using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using NodaTime;
|
||||
using System.Text;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Auth.OidcProvider.Controllers;
|
||||
using DysonNetwork.Sphere.Auth.OidcProvider.Services;
|
||||
using SystemClock = NodaTime.SystemClock;
|
||||
|
@ -6,6 +6,7 @@ using NodaTime;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Connection;
|
||||
|
||||
namespace DysonNetwork.Sphere.Auth;
|
||||
|
@ -5,6 +5,9 @@ using DysonNetwork.Sphere.Account;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using Challenge = DysonNetwork.Sphere.Auth.Proto.Challenge;
|
||||
using Session = DysonNetwork.Sphere.Auth.Proto.Session;
|
||||
|
||||
namespace DysonNetwork.Sphere.Auth;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Account;
|
||||
using DysonNetwork.Sphere.Storage;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -24,7 +25,7 @@ public class AuthService(
|
||||
/// <param name="request">The request context</param>
|
||||
/// <param name="account">The account to login</param>
|
||||
/// <returns>The required steps to login</returns>
|
||||
public async Task<int> DetectChallengeRisk(HttpRequest request, Account.Account account)
|
||||
public async Task<int> DetectChallengeRisk(HttpRequest request, Shared.Models.Account account)
|
||||
{
|
||||
// 1) Find out how many authentication factors the account has enabled.
|
||||
var maxSteps = await db.AccountAuthFactors
|
||||
@ -73,7 +74,7 @@ public class AuthService(
|
||||
return totalRequiredSteps;
|
||||
}
|
||||
|
||||
public async Task<Session> CreateSessionForOidcAsync(Account.Account account, Instant time, Guid? customAppId = null)
|
||||
public async Task<Session> CreateSessionForOidcAsync(Shared.Models.Account account, Instant time, Guid? customAppId = null)
|
||||
{
|
||||
var challenge = new Challenge
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Security.Cryptography;
|
||||
using DysonNetwork.Shared.Models;
|
||||
|
||||
namespace DysonNetwork.Sphere.Auth;
|
||||
|
||||
|
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Account;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
@ -114,7 +115,7 @@ public class OidcProviderController(
|
||||
[Authorize]
|
||||
public async Task<IActionResult> GetUserInfo()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser ||
|
||||
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser ||
|
||||
HttpContext.Items["CurrentSession"] is not Session currentSession) return Unauthorized();
|
||||
|
||||
// Get requested scopes from the token
|
||||
|
@ -2,6 +2,7 @@ using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Auth.OidcProvider.Models;
|
||||
using DysonNetwork.Sphere.Auth.OidcProvider.Options;
|
||||
using DysonNetwork.Sphere.Auth.OidcProvider.Responses;
|
||||
|
@ -1,3 +1,4 @@
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Account;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -25,7 +26,7 @@ public class ConnectionController(
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<List<AccountConnection>>> GetConnections()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var connections = await db.AccountConnections
|
||||
@ -48,7 +49,7 @@ public class ConnectionController(
|
||||
[HttpDelete("{id:guid}")]
|
||||
public async Task<ActionResult> RemoveConnection(Guid id)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var connection = await db.AccountConnections
|
||||
@ -66,7 +67,7 @@ public class ConnectionController(
|
||||
[HttpPost("/auth/connect/apple/mobile")]
|
||||
public async Task<ActionResult> ConnectAppleMobile([FromBody] AppleMobileConnectRequest request)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
if (GetOidcService("apple") is not AppleOidcService appleService)
|
||||
@ -132,7 +133,7 @@ public class ConnectionController(
|
||||
[HttpPost("connect")]
|
||||
public async Task<ActionResult<object>> InitiateConnection([FromBody] ConnectProviderRequest request)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is not Shared.Models.Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var oidcService = GetOidcService(request.Provider);
|
||||
|
@ -1,3 +1,4 @@
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Account;
|
||||
using DysonNetwork.Sphere.Storage;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -32,7 +33,7 @@ public class OidcController(
|
||||
var oidcService = GetOidcService(provider);
|
||||
|
||||
// If the user is already authenticated, treat as an account connection request
|
||||
if (HttpContext.Items["CurrentUser"] is Account.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is Shared.Models.Account currentUser)
|
||||
{
|
||||
var state = Guid.NewGuid().ToString();
|
||||
var nonce = Guid.NewGuid().ToString();
|
||||
@ -125,7 +126,7 @@ public class OidcController(
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<Account.Account> FindOrCreateAccount(OidcUserInfo userInfo, string provider)
|
||||
private async Task<Shared.Models.Account> FindOrCreateAccount(OidcUserInfo userInfo, string provider)
|
||||
{
|
||||
if (string.IsNullOrEmpty(userInfo.Email))
|
||||
throw new ArgumentException("Email is required for account creation");
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Account;
|
||||
using DysonNetwork.Sphere.Storage;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -190,7 +191,7 @@ public abstract class OidcService(
|
||||
/// </summary>
|
||||
public async Task<Challenge> CreateChallengeForUserAsync(
|
||||
OidcUserInfo userInfo,
|
||||
Account.Account account,
|
||||
Shared.Models.Account account,
|
||||
HttpContext request,
|
||||
string deviceId
|
||||
)
|
||||
|
@ -1,69 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Sphere.Developer;
|
||||
using NodaTime;
|
||||
using Point = NetTopologySuite.Geometries.Point;
|
||||
|
||||
namespace DysonNetwork.Sphere.Auth;
|
||||
|
||||
public class Session : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
[MaxLength(1024)] public string? Label { get; set; }
|
||||
public Instant? LastGrantedAt { get; set; }
|
||||
public Instant? ExpiredAt { get; set; }
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
[JsonIgnore] public Account.Account Account { get; set; } = null!;
|
||||
public Guid ChallengeId { get; set; }
|
||||
public Challenge Challenge { get; set; } = null!;
|
||||
public Guid? AppId { get; set; }
|
||||
public CustomApp? App { get; set; }
|
||||
}
|
||||
|
||||
public enum ChallengeType
|
||||
{
|
||||
Login,
|
||||
OAuth, // Trying to authorize other platforms
|
||||
Oidc // Trying to connect other platforms
|
||||
}
|
||||
|
||||
public enum ChallengePlatform
|
||||
{
|
||||
Unidentified,
|
||||
Web,
|
||||
Ios,
|
||||
Android,
|
||||
MacOs,
|
||||
Windows,
|
||||
Linux
|
||||
}
|
||||
|
||||
public class Challenge : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Instant? ExpiredAt { get; set; }
|
||||
public int StepRemain { get; set; }
|
||||
public int StepTotal { get; set; }
|
||||
public int FailedAttempts { get; set; }
|
||||
public ChallengePlatform Platform { get; set; } = ChallengePlatform.Unidentified;
|
||||
public ChallengeType Type { get; set; } = ChallengeType.Login;
|
||||
[Column(TypeName = "jsonb")] public List<Guid> BlacklistFactors { get; set; } = new();
|
||||
[Column(TypeName = "jsonb")] public List<string> Audiences { get; set; } = new();
|
||||
[Column(TypeName = "jsonb")] public List<string> Scopes { get; set; } = new();
|
||||
[MaxLength(128)] public string? IpAddress { get; set; }
|
||||
[MaxLength(512)] public string? UserAgent { get; set; }
|
||||
[MaxLength(256)] public string? DeviceId { get; set; }
|
||||
[MaxLength(1024)] public string? Nonce { get; set; }
|
||||
public Point? Location { get; set; }
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
[JsonIgnore] public Account.Account Account { get; set; } = null!;
|
||||
|
||||
public Challenge Normalize()
|
||||
{
|
||||
if (StepRemain == 0 && BlacklistFactors.Count == 0) StepRemain = StepTotal;
|
||||
return this;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user