mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-21 12:06:59 +01:00
Implement baby's first pagination on Users
This commit is contained in:
@@ -27,7 +27,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// Gets the <see cref="User"/> with a given <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">The <see cref="EntityId.Id"/> of the <see cref="User"/>.</param>
|
||||
/// <param name="includeJoins">If relevant entities should be loaded.</param>
|
||||
/// <param name="includeJoins">If related entities should be loaded.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="User"/> <see cref="AuthorityResponse{TResult}"/>.</returns>
|
||||
[TgsAuthorize(AdministrationRights.ReadUsers)]
|
||||
@@ -36,10 +36,9 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// <summary>
|
||||
/// Gets all registered <see cref="User"/>s.
|
||||
/// </summary>
|
||||
/// <param name="includeJoins">If relevant entities should be loaded.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <param name="includeJoins">If related entities should be loaded.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in a <see cref="IQueryable{T}"/> <see cref="User"/> <see cref="AuthorityResponse{TResult}"/>.</returns>
|
||||
[TgsAuthorize(AdministrationRights.ReadUsers)]
|
||||
public ValueTask<AuthorityResponse<IQueryable<User>>> List(bool includeJoins, CancellationToken cancellationToken);
|
||||
public ValueTask<AuthorityResponse<IQueryable<User>>> List(bool includeJoins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,18 +49,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, CancellationToken cancellationToken)
|
||||
{
|
||||
var queryable = databaseContext
|
||||
.Users
|
||||
.AsQueryable();
|
||||
|
||||
if (includeJoins)
|
||||
queryable = queryable
|
||||
.Where(x => x.Id == id)
|
||||
.Include(x => x.CreatedBy)
|
||||
.Include(x => x.OAuthConnections)
|
||||
.Include(x => x.Group!)
|
||||
.ThenInclude(x => x.PermissionSet)
|
||||
.Include(x => x.PermissionSet);
|
||||
var queryable = ListCore(includeJoins);
|
||||
|
||||
var user = await queryable.FirstOrDefaultAsync(
|
||||
dbModel => dbModel.Id == id,
|
||||
@@ -75,9 +64,35 @@ namespace Tgstation.Server.Host.Authority
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask<AuthorityResponse<IQueryable<User>>> List(bool includeJoins, CancellationToken cancellationToken)
|
||||
public ValueTask<AuthorityResponse<IQueryable<User>>> List(bool includeJoins)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var systemUserCanonicalName = User.CanonicalizeName(User.TgsSystemUserName);
|
||||
return ValueTask.FromResult(
|
||||
new AuthorityResponse<IQueryable<User>>(
|
||||
ListCore(includeJoins)
|
||||
.Where(x => x.CanonicalName != systemUserCanonicalName)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an <see cref="IQueryable{T}"/> for listing <see cref="User"/>s.
|
||||
/// </summary>
|
||||
/// <param name="includeJoins">If related entities should be loaded.</param>
|
||||
/// <returns>A new <see cref="IQueryable{T}"/> of <see cref="User"/>s.</returns>
|
||||
private IQueryable<User> ListCore(bool includeJoins)
|
||||
{
|
||||
var queryable = databaseContext
|
||||
.Users
|
||||
.AsQueryable();
|
||||
|
||||
if (includeJoins)
|
||||
queryable = queryable
|
||||
.Include(x => x.CreatedBy)
|
||||
.Include(x => x.OAuthConnections)
|
||||
.Include(x => x.Group!)
|
||||
.ThenInclude(x => x.PermissionSet)
|
||||
.Include(x => x.PermissionSet);
|
||||
|
||||
return queryable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -8,6 +9,7 @@ using HotChocolate.Types.Relay;
|
||||
|
||||
using Tgstation.Server.Host.Authority;
|
||||
using Tgstation.Server.Host.Authority.Core;
|
||||
using Tgstation.Server.Host.Models;
|
||||
using Tgstation.Server.Host.Security;
|
||||
|
||||
#pragma warning disable CA1724 // conflict with GitLabApiClient.Models.Users. They can fuck off
|
||||
@@ -40,7 +42,7 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
/// <param name="id">The <see cref="Entity.Id"/> of the <see cref="User"/>.</param>
|
||||
/// <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 <see cref="User"/>.</returns>
|
||||
/// <returns>The <see cref="User"/> represented by <paramref name="id"/>, if any.</returns>
|
||||
[Error(typeof(ErrorMessageException))]
|
||||
[TgsGraphQLAuthorize<IUserAuthority>(nameof(IUserAuthority.GetId))]
|
||||
public async ValueTask<User?> ById(
|
||||
@@ -51,5 +53,22 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
ArgumentNullException.ThrowIfNull(userAuthority);
|
||||
return await userAuthority.InvokeTransformable<Models.User, User>(authority => authority.GetId(id, false, cancellationToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists all registered <see cref="User"/>s.
|
||||
/// </summary>
|
||||
/// <param name="userAuthority">The <see cref="IGraphQLAuthorityInvoker{TAuthority}"/> <see cref="IUserAuthority"/>.</param>
|
||||
/// <returns>A list of all registered <see cref="User"/>s.</returns>
|
||||
[UsePaging(IncludeTotalCount = true)]
|
||||
[TgsGraphQLAuthorize<IUserAuthority>(nameof(IUserAuthority.List))]
|
||||
public async ValueTask<IQueryable<User?>> List(
|
||||
[Service] IGraphQLAuthorityInvoker<IUserAuthority> userAuthority)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userAuthority);
|
||||
var dtoQueryable = await userAuthority.Invoke<IQueryable<Models.User>, IQueryable<Models.User>>(authority => authority.List(false));
|
||||
return dtoQueryable
|
||||
.Cast<IApiTransformable<User>>()
|
||||
.Select(dto => dto.ToApi());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user