:drunk: AI trying to fix bugs
This commit is contained in:
@ -212,7 +212,7 @@ public class AccountCurrentController(
|
||||
}
|
||||
|
||||
[HttpPost("statuses")]
|
||||
[DysonNetwork.Sphere.Permission.RequiredPermission("global", "accounts.statuses.create")]
|
||||
[DysonNetwork.Common.Services.Permission.RequiredPermission("global", "accounts.statuses.create")]
|
||||
public async Task<ActionResult<Status>> CreateStatus([FromBody] AccountController.StatusRequest request)
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Common.Models.Account currentUser) return Unauthorized();
|
||||
|
@ -140,7 +140,7 @@ public class NotificationController(PassDatabase db, NotificationService nty) :
|
||||
|
||||
[HttpPost("send")]
|
||||
[Authorize]
|
||||
[DysonNetwork.Sphere.Permission.RequiredPermission("global", "notifications.send")]
|
||||
[DysonNetwork.Common.Services.Permission.RequiredPermission("global", "notifications.send")]
|
||||
public async Task<ActionResult> SendNotification(
|
||||
[FromBody] NotificationWithAimRequest request,
|
||||
[FromQuery] bool save = false
|
||||
|
@ -3,7 +3,7 @@ using DysonNetwork.Pass.Features.Auth;
|
||||
using DysonNetwork.Pass.Features.Auth.OpenId;
|
||||
using DysonNetwork.Pass.Email;
|
||||
using DysonNetwork.Pass.Localization;
|
||||
using DysonNetwork.Sphere.Permission;
|
||||
// Permission types are now in DysonNetwork.Common.Models
|
||||
using DysonNetwork.Pass.Storage;
|
||||
using EFCore.BulkExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
@ -3,7 +3,7 @@ using DysonNetwork.Pass.Storage;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using DysonNetwork.Common.Models;
|
||||
using DysonNetwork.Sphere.Permission;
|
||||
// Permission types are now in DysonNetwork.Common.Models
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Account;
|
||||
|
||||
|
@ -6,7 +6,7 @@ namespace DysonNetwork.Pass.Features.Auth.Interfaces;
|
||||
public interface IOidcService
|
||||
{
|
||||
string GetAuthorizationUrl(string state, string nonce);
|
||||
Task<OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData);
|
||||
Task<DysonNetwork.Common.Models.OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData);
|
||||
Task<AuthResult> AuthenticateAsync(string provider, string code, string state);
|
||||
IEnumerable<string> GetSupportedProviders();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Common.Models;
|
||||
using NodaTime;
|
||||
using AccountConnection = DysonNetwork.Common.Models.AccountConnection;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.Models;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Common.Models;
|
||||
using DysonNetwork.Common.Models.Auth;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.Models;
|
||||
@ -34,6 +35,9 @@ public class AccountAuthFactor : ModelBase
|
||||
[Required]
|
||||
public bool IsBackup { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
public Instant? LastUsedAt { get; set; }
|
||||
|
||||
public Instant? EnabledAt { get; set; }
|
||||
|
@ -1,70 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Pass.Models;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.Models;
|
||||
|
||||
public class AccountConnection : ModelBase
|
||||
{
|
||||
[Required]
|
||||
public Guid AccountId { get; set; }
|
||||
|
||||
[ForeignKey(nameof(AccountId))]
|
||||
[JsonIgnore]
|
||||
public virtual Account Account { get; set; } = null!;
|
||||
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[MaxLength(256)]
|
||||
public string ProviderId { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(256)]
|
||||
public string? DisplayName { get; set; }
|
||||
|
||||
[MaxLength(1000)]
|
||||
public string? AccessToken { get; set; }
|
||||
|
||||
[MaxLength(1000)]
|
||||
public string? RefreshToken { get; set; }
|
||||
|
||||
public Instant? ExpiresAt { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public JsonDocument? ProfileData { get; set; }
|
||||
|
||||
public Instant ConnectedAt { get; set; } = SystemClock.Instance.GetCurrentInstant();
|
||||
public Instant? LastUsedAt { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public JsonDocument? Metadata { get; set; }
|
||||
|
||||
public bool IsConnected => ExpiresAt == null || ExpiresAt > SystemClock.Instance.GetCurrentInstant();
|
||||
|
||||
public void UpdateTokens(string? accessToken, string? refreshToken, Instant? expiresAt)
|
||||
{
|
||||
AccessToken = accessToken;
|
||||
RefreshToken = refreshToken;
|
||||
ExpiresAt = expiresAt;
|
||||
LastUsedAt = SystemClock.Instance.GetCurrentInstant();
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
AccessToken = null;
|
||||
RefreshToken = null;
|
||||
ExpiresAt = null;
|
||||
ConnectedAt = default; // Set to default value for Instant
|
||||
}
|
||||
|
||||
public void UpdateProfileData(JsonDocument? profileData)
|
||||
{
|
||||
ProfileData = profileData;
|
||||
}
|
||||
}
|
@ -6,6 +6,8 @@ using DysonNetwork.Pass.Storage;
|
||||
using NodaTime;
|
||||
using DysonNetwork.Pass.Data;
|
||||
using DysonNetwork.Common.Models;
|
||||
using Account = DysonNetwork.Common.Models.Account;
|
||||
using AccountConnection = DysonNetwork.Common.Models.AccountConnection;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.OpenId;
|
||||
|
||||
@ -27,21 +29,24 @@ public class ConnectionController(
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<List<AccountConnection>>> GetConnections()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Models.Account currentUser)
|
||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||
return Unauthorized();
|
||||
|
||||
var connections = await db.AccountConnections
|
||||
.Where(c => c.AccountId == currentUser.Id)
|
||||
.Select(c => new
|
||||
.Select(c => new AccountConnection
|
||||
{
|
||||
c.Id,
|
||||
c.AccountId,
|
||||
c.Provider,
|
||||
c.ProvidedIdentifier,
|
||||
c.Meta,
|
||||
c.LastUsedAt,
|
||||
c.CreatedAt,
|
||||
c.UpdatedAt,
|
||||
Id = c.Id,
|
||||
AccountId = c.AccountId,
|
||||
Provider = c.Provider,
|
||||
ProvidedIdentifier = c.ProvidedIdentifier,
|
||||
DisplayName = c.DisplayName,
|
||||
AccessToken = c.AccessToken,
|
||||
RefreshToken = c.RefreshToken,
|
||||
ExpiresAt = c.ExpiresAt,
|
||||
LastUsedAt = c.LastUsedAt,
|
||||
CreatedAt = c.CreatedAt,
|
||||
UpdatedAt = c.UpdatedAt
|
||||
})
|
||||
.ToListAsync();
|
||||
return Ok(connections);
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using DysonNetwork.Common.Models;
|
||||
using DysonNetwork.Common.Services;
|
||||
using DysonNetwork.Pass.Data;
|
||||
using DysonNetwork.Sphere;
|
||||
|
||||
namespace DysonNetwork.Pass.Features.Auth.OpenId;
|
||||
|
||||
@ -47,7 +47,7 @@ public class DiscordOidcService(
|
||||
})!;
|
||||
}
|
||||
|
||||
public override async Task<OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData)
|
||||
public override async Task<DysonNetwork.Common.Models.OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData)
|
||||
{
|
||||
var tokenResponse = await ExchangeCodeForTokensAsync(callbackData.Code);
|
||||
if (tokenResponse?.AccessToken == null)
|
||||
@ -84,7 +84,7 @@ public class DiscordOidcService(
|
||||
return await response.Content.ReadFromJsonAsync<OidcTokenResponse>();
|
||||
}
|
||||
|
||||
private async Task<OidcUserInfo> GetUserInfoAsync(string accessToken)
|
||||
private async Task<DysonNetwork.Common.Models.OidcUserInfo> GetUserInfoAsync(string accessToken)
|
||||
{
|
||||
var client = HttpClientFactory.CreateClient();
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "https://discord.com/users/@me");
|
||||
@ -99,7 +99,7 @@ public class DiscordOidcService(
|
||||
var userId = discordUser.GetProperty("id").GetString() ?? "";
|
||||
var avatar = discordUser.TryGetProperty("avatar", out var avatarElement) ? avatarElement.GetString() : null;
|
||||
|
||||
return new OidcUserInfo
|
||||
return new DysonNetwork.Common.Models.OidcUserInfo
|
||||
{
|
||||
UserId = userId,
|
||||
Email = (discordUser.TryGetProperty("email", out var emailElement) ? emailElement.GetString() : null) ?? "",
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Common.Models;
|
||||
using DysonNetwork.Common.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
@ -48,7 +50,7 @@ public abstract class OidcService(
|
||||
/// <summary>
|
||||
/// Process the callback from the OIDC provider
|
||||
/// </summary>
|
||||
public abstract Task<OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData);
|
||||
public abstract Task<DysonNetwork.Common.Models.OidcUserInfo> ProcessCallbackAsync(OidcCallbackData callbackData);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the provider configuration
|
||||
@ -145,7 +147,7 @@ public abstract class OidcService(
|
||||
/// <summary>
|
||||
/// Validates and extracts information from an ID token
|
||||
/// </summary>
|
||||
protected virtual OidcUserInfo ValidateAndExtractIdToken(string idToken,
|
||||
protected virtual DysonNetwork.Common.Models.OidcUserInfo ValidateAndExtractIdToken(string idToken,
|
||||
TokenValidationParameters validationParameters)
|
||||
{
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
@ -171,18 +173,24 @@ public abstract class OidcService(
|
||||
username = !string.IsNullOrEmpty(email) ? email.Split('@')[0] : null;
|
||||
}
|
||||
|
||||
return new OidcUserInfo
|
||||
// Convert the user info to our model
|
||||
var userInfo = new DysonNetwork.Common.Models.OidcUserInfo
|
||||
{
|
||||
UserId = userId,
|
||||
Email = email,
|
||||
EmailVerified = emailVerified,
|
||||
FirstName = givenName ?? "",
|
||||
LastName = familyName ?? "",
|
||||
DisplayName = name ?? $"{givenName} {familyName}".Trim(),
|
||||
PreferredUsername = username ?? "",
|
||||
ProfilePictureUrl = picture,
|
||||
Provider = ProviderName
|
||||
GivenName = givenName,
|
||||
FamilyName = familyName,
|
||||
Name = name,
|
||||
UserId = userId,
|
||||
Picture = picture,
|
||||
AccessToken = "",
|
||||
RefreshToken = "",
|
||||
Provider = ProviderName,
|
||||
ExpiresAt = null,
|
||||
Claims = null
|
||||
};
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -190,7 +198,7 @@ public abstract class OidcService(
|
||||
/// Also creates or updates the account connection
|
||||
/// </summary>
|
||||
public async Task<Challenge> CreateChallengeForUserAsync(
|
||||
OidcUserInfo userInfo,
|
||||
DysonNetwork.Common.Models.OidcUserInfo userInfo,
|
||||
Models.Account account,
|
||||
HttpContext request,
|
||||
string deviceId
|
||||
@ -199,20 +207,22 @@ public abstract class OidcService(
|
||||
// Create or update the account connection
|
||||
var connection = await Db.AccountConnections
|
||||
.FirstOrDefaultAsync(c => c.Provider == ProviderName &&
|
||||
c.ProvidedIdentifier == userInfo.UserId &&
|
||||
c.AccountId == account.Id
|
||||
c.ProvidedIdentifier == userInfo.UserId &&
|
||||
c.AccountId == account.Id
|
||||
);
|
||||
|
||||
if (connection is null)
|
||||
{
|
||||
connection = new AccountConnection
|
||||
connection = new DysonNetwork.Common.Models.AccountConnection
|
||||
{
|
||||
Provider = ProviderName,
|
||||
ProvidedIdentifier = userInfo.UserId ?? "",
|
||||
AccessToken = userInfo.AccessToken,
|
||||
RefreshToken = userInfo.RefreshToken,
|
||||
LastUsedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
AccountId = account.Id
|
||||
AccountId = account.Id,
|
||||
CreatedAt = SystemClock.Instance.GetCurrentInstant(),
|
||||
ProfileData = userInfo.Claims != null ? JsonSerializer.SerializeToDocument(userInfo.Claims) : null
|
||||
};
|
||||
await Db.AccountConnections.AddAsync(connection);
|
||||
}
|
||||
|
Reference in New Issue
Block a user