mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-21 12:06:59 +01:00
Properly setup GraphQL IUserName for TGS user
This commit is contained in:
@@ -28,10 +28,11 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// </summary>
|
||||
/// <param name="id">The <see cref="EntityId.Id"/> of the <see cref="User"/>.</param>
|
||||
/// <param name="includeJoins">If related entities should be loaded.</param>
|
||||
/// <param name="allowSystemUser">If the <see cref="User.TgsSystemUserName"/> may be returned.</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)]
|
||||
public ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, CancellationToken cancellationToken);
|
||||
public ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, bool allowSystemUser, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered <see cref="User"/>s.
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
=> ValueTask.FromResult(new AuthorityResponse<User>(authenticationContext.User));
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, CancellationToken cancellationToken)
|
||||
public async ValueTask<AuthorityResponse<User>> GetId(long id, bool includeJoins, bool allowSystemUser, CancellationToken cancellationToken)
|
||||
{
|
||||
var queryable = ListCore(includeJoins);
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
if (user == default)
|
||||
return NotFound<User>();
|
||||
|
||||
if (user.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName))
|
||||
if (!allowSystemUser && user.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName))
|
||||
return Forbid<User>();
|
||||
|
||||
return new AuthorityResponse<User>(user);
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|
||||
return await userAuthority.InvokeTransformable<User, UserResponse>(
|
||||
this,
|
||||
authority => authority.GetId(id, true, cancellationToken));
|
||||
authority => authority.GetId(id, true, false, cancellationToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -300,6 +300,7 @@ namespace Tgstation.Server.Host.Core
|
||||
.AddErrorFilter<ErrorMessageFilter>()
|
||||
.AddType<LocalGateway>()
|
||||
.AddType<RemoteGateway>()
|
||||
.AddType<GraphQL.Types.UserName>()
|
||||
.AddType<UnsignedIntType>()
|
||||
.BindRuntimeType<Version, SemverType>()
|
||||
.AddQueryType<Query>()
|
||||
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
using HotChocolate.Authorization;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.GraphQL.Types;
|
||||
using Tgstation.Server.Host.Security.OAuth;
|
||||
using Tgstation.Server.Host.System;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
namespace Tgstation.Server.Host.GraphQL.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Management interface for the parent <see cref="Node"/>.
|
||||
@@ -0,0 +1,21 @@
|
||||
using HotChocolate.Types.Relay;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// A lightly scoped <see cref="Types.User"/>.
|
||||
/// </summary>
|
||||
public interface IUserName
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the user.
|
||||
/// </summary>
|
||||
[ID]
|
||||
public long Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the user.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Options;
|
||||
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
using Tgstation.Server.Host.Security.OAuth;
|
||||
using Tgstation.Server.Host.System;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,6 +14,16 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NamedEntity"/> class.
|
||||
/// </summary>
|
||||
/// <param name="copy">The <see cref="IUserName"/> to copy.</param>
|
||||
protected NamedEntity(NamedEntity copy)
|
||||
: base(copy?.Id ?? throw new ArgumentNullException(nameof(copy)))
|
||||
{
|
||||
Name = copy.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NamedEntity"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ using HotChocolate;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using Microsoft.Extensions.Options;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
using Tgstation.Server.Host.Security.OAuth;
|
||||
using Tgstation.Server.Host.System;
|
||||
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using HotChocolate;
|
||||
|
||||
using Tgstation.Server.Host.Authority;
|
||||
using Tgstation.Server.Host.Authority.Core;
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// A user registered in the server.
|
||||
/// </summary>
|
||||
public sealed class User : NamedEntity
|
||||
public sealed class User : NamedEntity, IUserName
|
||||
{
|
||||
/// <summary>
|
||||
/// If the <see cref="User"/> is enabled since users cannot be deleted. System users cannot be disabled.
|
||||
@@ -72,9 +79,23 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
/// <summary>
|
||||
/// The <see cref="User"/> who created this <see cref="User"/>.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="User"/> who created this <see cref="User"/>, if any.</returns>
|
||||
public ValueTask<User?> CreatedBy()
|
||||
=> 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>The <see cref="IUserName"/> that created this <see cref="User"/>, if any.</returns>
|
||||
public async ValueTask<IUserName?> CreatedBy(
|
||||
[Service] IGraphQLAuthorityInvoker<IUserAuthority> userAuthority,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userAuthority);
|
||||
if (!createdById.HasValue)
|
||||
return null;
|
||||
|
||||
var user = await userAuthority.InvokeTransformable<Models.User, User>(authority => authority.GetId(createdById.Value, false, true, cancellationToken));
|
||||
if (user.CanonicalName == Models.User.CanonicalizeName(Models.User.TgsSystemUserName))
|
||||
return new UserName(user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of <see cref="OAuthConnection"/>s associated with the user if OAuth is configured.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="User"/> with limited fields.
|
||||
/// </summary>
|
||||
public sealed class UserName : NamedEntity, IUserName
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserName"/> class.
|
||||
/// </summary>
|
||||
/// <param name="copy">The <see cref="NamedEntity"/> to copy.</param>
|
||||
public UserName(NamedEntity copy)
|
||||
: base(copy)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userAuthority);
|
||||
return await userAuthority.InvokeTransformable<Models.User, User>(authority => authority.GetId(id, false, cancellationToken));
|
||||
return await userAuthority.InvokeTransformable<Models.User, User>(authority => authority.GetId(id, false, false, cancellationToken));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user