mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-21 12:06:59 +01:00
Implement OAuthConnections loading for GraphQL
This commit is contained in:
@@ -34,6 +34,14 @@ namespace Tgstation.Server.Host.Authority
|
||||
[TgsAuthorize(AdministrationRights.ReadUsers)]
|
||||
public ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, bool allowSystemUser, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="OAuthConnection"/>s for the <see cref="User"/> with a given <paramref name="userId"/>.
|
||||
/// </summary>
|
||||
/// <param name="userId">The <see cref="EntityId.Id"/> of the <see cref="User"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in an <see cref="global::System.Array"/> of <see cref="GraphQL.Types.OAuthConnection"/> <see cref="AuthorityResponse{TResult}"/>.</returns>
|
||||
public ValueTask<AuthorityResponse<GraphQL.Types.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered <see cref="User"/>s.
|
||||
/// </summary>
|
||||
|
||||
@@ -27,7 +27,12 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// <summary>
|
||||
/// The <see cref="IUsersDataLoader"/> for the <see cref="UserAuthority"/>.
|
||||
/// </summary>
|
||||
readonly IUsersDataLoader dataLoader;
|
||||
readonly IUsersDataLoader usersDataLoader;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IOAuthConnectionsDataLoader"/> for the <see cref="UserAuthority"/>.
|
||||
/// </summary>
|
||||
readonly IOAuthConnectionsDataLoader oAuthConnectionsDataLoader;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IAuthenticationContext"/> for the <see cref="UserAuthority"/>.
|
||||
@@ -35,7 +40,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
readonly IAuthenticationContext authenticationContext;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="dataLoader"/>.
|
||||
/// Implements the <see cref="usersDataLoader"/>.
|
||||
/// </summary>
|
||||
/// <param name="ids">The <see cref="IReadOnlyCollection{T}"/> of <see cref="User"/> <see cref="Api.Models.EntityId.Id"/>s to load.</param>
|
||||
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> to load from.</param>
|
||||
@@ -57,22 +62,52 @@ namespace Tgstation.Server.Host.Authority
|
||||
.ToDictionaryAsync(user => user.Id!.Value, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="usersDataLoader"/>.
|
||||
/// </summary>
|
||||
/// <param name="userIds">The <see cref="IReadOnlyCollection{T}"/> of <see cref="User"/> <see cref="Api.Models.EntityId.Id"/>s to load the OAuthConnections for.</param>
|
||||
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> to load from.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="Dictionary{TKey, TValue}"/> of the requested <see cref="User"/>s.</returns>
|
||||
[DataLoader]
|
||||
public static async ValueTask<ILookup<long, GraphQL.Types.OAuthConnection>> GetOAuthConnections(
|
||||
IReadOnlyList<long> userIds,
|
||||
IDatabaseContext databaseContext,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userIds);
|
||||
ArgumentNullException.ThrowIfNull(databaseContext);
|
||||
|
||||
var list = await databaseContext
|
||||
.OAuthConnections
|
||||
.AsQueryable()
|
||||
.Where(x => userIds.Contains(x.User!.Id!.Value))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return list.ToLookup(
|
||||
oauthConnection => oauthConnection.UserId,
|
||||
x => new GraphQL.Types.OAuthConnection(x.ExternalUserId!, x.Provider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserAuthority"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The <see cref="ILogger"/> to use.</param>
|
||||
/// <param name="databaseContext">The value of <see cref="databaseContext"/>.</param>
|
||||
/// <param name="dataLoader">The value of <see cref="dataLoader"/>.</param>
|
||||
/// <param name="usersDataLoader">The value of <see cref="usersDataLoader"/>.</param>
|
||||
/// <param name="oAuthConnectionsDataLoader">The value of <see cref="oAuthConnectionsDataLoader"/>.</param>
|
||||
/// <param name="authenticationContext">The value of <see cref="authenticationContext"/>.</param>
|
||||
public UserAuthority(
|
||||
ILogger<UserAuthority> logger,
|
||||
IDatabaseContext databaseContext,
|
||||
IUsersDataLoader dataLoader,
|
||||
IUsersDataLoader usersDataLoader,
|
||||
IOAuthConnectionsDataLoader oAuthConnectionsDataLoader,
|
||||
IAuthenticationContext authenticationContext)
|
||||
: base(logger)
|
||||
{
|
||||
this.databaseContext = databaseContext ?? throw new ArgumentNullException(nameof(databaseContext));
|
||||
this.dataLoader = dataLoader ?? throw new ArgumentNullException(nameof(dataLoader));
|
||||
this.usersDataLoader = usersDataLoader ?? throw new ArgumentNullException(nameof(usersDataLoader));
|
||||
this.oAuthConnectionsDataLoader = oAuthConnectionsDataLoader ?? throw new ArgumentNullException(nameof(oAuthConnectionsDataLoader));
|
||||
this.authenticationContext = authenticationContext ?? throw new ArgumentNullException(nameof(authenticationContext));
|
||||
}
|
||||
|
||||
@@ -93,7 +128,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
cancellationToken);
|
||||
}
|
||||
else
|
||||
user = await dataLoader.LoadAsync(id, cancellationToken);
|
||||
user = await usersDataLoader.LoadAsync(id, cancellationToken);
|
||||
|
||||
if (user == default)
|
||||
return NotFound<User>();
|
||||
@@ -108,6 +143,11 @@ namespace Tgstation.Server.Host.Authority
|
||||
public IQueryable<User> Queryable(bool includeJoins)
|
||||
=> Queryable(includeJoins, false);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<AuthorityResponse<GraphQL.Types.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken)
|
||||
=> new AuthorityResponse<GraphQL.Types.OAuthConnection[]>(
|
||||
await oAuthConnectionsDataLoader.LoadRequiredAsync(userId, cancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered <see cref="User"/>s.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -94,9 +93,17 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
/// <summary>
|
||||
/// List of <see cref="OAuthConnection"/>s associated with the user if OAuth is configured.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a new <see cref="List{T}"/> of <see cref="OAuthConnection"/>s for the <see cref="User"/> if OAuth is configured.</returns>
|
||||
public ValueTask<List<OAuthConnection>>? OAuthConnections()
|
||||
=> throw new NotImplementedException();
|
||||
/// <param name="userAuthority">The <see cref="IGraphQLAuthorityInvoker{TAuthority}"/> <see cref="IUserAuthority"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a new <see cref="Array"/> of <see cref="OAuthConnection"/>s for the <see cref="User"/> if OAuth is configured.</returns>
|
||||
public async ValueTask<OAuthConnection[]> OAuthConnections(
|
||||
[Service] IGraphQLAuthorityInvoker<IUserAuthority> userAuthority,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userAuthority);
|
||||
return (await userAuthority.Invoke<OAuthConnection[], OAuthConnection[]>(
|
||||
authority => authority.OAuthConnections(Id, cancellationToken)))!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Types.PermissionSet"/> directly associated with the <see cref="User"/>, if any.
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Api.Models.EntityId.Id"/> of <see cref="User"/>.
|
||||
/// </summary>
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The owning <see cref="Models.User"/>.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user