mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-21 12:06:59 +01:00
Reorganize GraphQL types and make OAuthProviders stronger
This commit is contained in:
@@ -6,6 +6,7 @@ using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Request;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Host.Authority.Core;
|
||||
using Tgstation.Server.Host.GraphQL.Types.OAuth;
|
||||
using Tgstation.Server.Host.Models;
|
||||
using Tgstation.Server.Host.Security;
|
||||
|
||||
@@ -40,8 +41,8 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// </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>
|
||||
ValueTask<AuthorityResponse<GraphQL.Types.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in an <see cref="global::System.Array"/> of <see cref="Tgstation.Server.Host.GraphQL.Types.OAuth.OAuthConnection"/> <see cref="AuthorityResponse{TResult}"/>.</returns>
|
||||
ValueTask<AuthorityResponse<GraphQL.Types.OAuth.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered <see cref="User"/>s.
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
/// <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(
|
||||
public static async ValueTask<ILookup<long, GraphQL.Types.OAuth.OAuthConnection>> GetOAuthConnections(
|
||||
IReadOnlyList<long> userIds,
|
||||
IDatabaseContext databaseContext,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -118,7 +118,7 @@ namespace Tgstation.Server.Host.Authority
|
||||
|
||||
return list.ToLookup(
|
||||
oauthConnection => oauthConnection.UserId,
|
||||
x => new GraphQL.Types.OAuthConnection(x.ExternalUserId!, x.Provider));
|
||||
x => new GraphQL.Types.OAuth.OAuthConnection(x.ExternalUserId!, x.Provider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -285,8 +285,8 @@ namespace Tgstation.Server.Host.Authority
|
||||
=> Queryable(includeJoins, false);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask<AuthorityResponse<GraphQL.Types.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken)
|
||||
=> new AuthorityResponse<GraphQL.Types.OAuthConnection[]>(
|
||||
public async ValueTask<AuthorityResponse<GraphQL.Types.OAuth.OAuthConnection[]>> OAuthConnections(long userId, CancellationToken cancellationToken)
|
||||
=> new AuthorityResponse<GraphQL.Types.OAuth.OAuthConnection[]>(
|
||||
await oAuthConnectionsDataLoader.LoadRequiredAsync(userId, cancellationToken));
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -57,10 +57,10 @@ using Tgstation.Server.Host.Controllers.Results;
|
||||
using Tgstation.Server.Host.Database;
|
||||
using Tgstation.Server.Host.Extensions;
|
||||
using Tgstation.Server.Host.GraphQL;
|
||||
using Tgstation.Server.Host.GraphQL.Interceptors;
|
||||
using Tgstation.Server.Host.GraphQL.Scalars;
|
||||
using Tgstation.Server.Host.GraphQL.Subscriptions;
|
||||
using Tgstation.Server.Host.GraphQL.Types;
|
||||
using Tgstation.Server.Host.GraphQL.Types.Interceptors;
|
||||
using Tgstation.Server.Host.GraphQL.Types.Scalars;
|
||||
using Tgstation.Server.Host.IO;
|
||||
using Tgstation.Server.Host.Jobs;
|
||||
using Tgstation.Server.Host.Properties;
|
||||
|
||||
+2
-2
@@ -6,10 +6,10 @@ using System.Reflection;
|
||||
using HotChocolate.Configuration;
|
||||
using HotChocolate.Types;
|
||||
using HotChocolate.Types.Descriptors.Definitions;
|
||||
|
||||
using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Host.GraphQL.Types;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.Interceptors
|
||||
namespace Tgstation.Server.Host.GraphQL.Interceptors
|
||||
{
|
||||
/// <summary>
|
||||
/// Fixes the names used for the default flags types in API rights.
|
||||
@@ -1,6 +1,6 @@
|
||||
using HotChocolate;
|
||||
using Tgstation.Server.Api.Models.Response;
|
||||
using Tgstation.Server.Host.GraphQL.Types.Scalars;
|
||||
using Tgstation.Server.Host.GraphQL.Scalars;
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Mutations.Payloads
|
||||
|
||||
@@ -13,6 +13,7 @@ using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Host.Authority;
|
||||
using Tgstation.Server.Host.GraphQL.Mutations.Payloads;
|
||||
using Tgstation.Server.Host.GraphQL.Types;
|
||||
using Tgstation.Server.Host.GraphQL.Types.OAuth;
|
||||
using Tgstation.Server.Host.Models.Transformers;
|
||||
using Tgstation.Server.Host.Security;
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
using HotChocolate.Language;
|
||||
using HotChocolate.Types;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.Scalars
|
||||
namespace Tgstation.Server.Host.GraphQL.Scalars
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="ScalarType{TRuntimeType, TLiteral}"/> for encoded JSON Web Tokens.
|
||||
+1
-2
@@ -2,10 +2,9 @@
|
||||
|
||||
using HotChocolate.Language;
|
||||
using HotChocolate.Types;
|
||||
|
||||
using Tgstation.Server.Common.Extensions;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.Scalars
|
||||
namespace Tgstation.Server.Host.GraphQL.Scalars
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="ScalarType{TRuntimeType, TLiteral}"/> for semantic <see cref="Version"/>s.
|
||||
@@ -10,6 +10,7 @@ using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Host.Components.Interop;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.GraphQL.Types.OAuth;
|
||||
using Tgstation.Server.Host.Properties;
|
||||
using Tgstation.Server.Host.Security;
|
||||
using Tgstation.Server.Host.Security.OAuth;
|
||||
@@ -148,12 +149,12 @@ namespace Tgstation.Server.Host.GraphQL.Types
|
||||
/// Gets the information needed to perform open authentication with the <see cref="SwarmNode"/>.
|
||||
/// </summary>
|
||||
/// <param name="oAuthProviders">The <see cref="IOAuthProviders"/> to use.</param>
|
||||
/// <returns>A map of enabled <see cref="OAuthProvider"/>s to their <see cref="OAuthProviderInfo"/>.</returns>
|
||||
public IReadOnlyDictionary<OAuthProvider, OAuthProviderInfo> OAuthProviderInfos(
|
||||
/// <returns>A map of enabled <see cref="OAuthProvider"/>s to their <see cref="FullOAuthProviderInfo"/>.</returns>
|
||||
public OAuthProviderInfos OAuthProviderInfos(
|
||||
[Service] IOAuthProviders oAuthProviders)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(oAuthProviders);
|
||||
return oAuthProviders.ProviderInfos();
|
||||
return new OAuthProviderInfos(oAuthProviders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic OAuth provider info.
|
||||
/// </summary>
|
||||
public class BasicOAuthProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The client ID.
|
||||
/// </summary>
|
||||
public string ClientID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BasicOAuthProviderInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="providerInfo">The <see cref="OAuthProviderInfo"/> to build from.</param>
|
||||
public BasicOAuthProviderInfo(OAuthProviderInfo providerInfo)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(providerInfo);
|
||||
|
||||
ClientID = providerInfo.ClientId ?? throw new InvalidOperationException("ClientID not set!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth provider info with a <see cref="RedirectOAuthProviderInfo.RedirectUri"/> and <see cref="ServerUrl"/>.
|
||||
/// </summary>
|
||||
public sealed class FullOAuthProviderInfo : RedirectOAuthProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The remote service URL.
|
||||
/// </summary>
|
||||
public Uri ServerUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FullOAuthProviderInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="providerInfo">The <see cref="OAuthProviderInfo"/> to build from.</param>
|
||||
public FullOAuthProviderInfo(OAuthProviderInfo providerInfo)
|
||||
: base(providerInfo)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(providerInfo);
|
||||
|
||||
ServerUrl = providerInfo.ServerUrl ?? throw new InvalidOperationException("Missing OAuthProviderInfo ServerUrl!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a valid OAuth connection.
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Host.Security.OAuth;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of configured OAuth services.
|
||||
/// </summary>
|
||||
public sealed class OAuthProviderInfos
|
||||
{
|
||||
/// <summary>
|
||||
/// https://discord.com.
|
||||
/// </summary>
|
||||
public BasicOAuthProviderInfo? Discord { get; }
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com.
|
||||
/// </summary>
|
||||
public RedirectOAuthProviderInfo? GitHub { get; }
|
||||
|
||||
/// <summary>
|
||||
/// https://tgstation13.org.
|
||||
/// </summary>
|
||||
public RedirectOAuthProviderInfo? TGForums { get; }
|
||||
|
||||
/// <summary>
|
||||
/// https://www.keycloak.org.
|
||||
/// </summary>
|
||||
public FullOAuthProviderInfo? Keycloak { get; }
|
||||
|
||||
/// <summary>
|
||||
/// https://invisioncommunity.com.
|
||||
/// </summary>
|
||||
public FullOAuthProviderInfo? InvisionCommunity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OAuthProviderInfos"/> class.
|
||||
/// </summary>
|
||||
/// <param name="oAuthProviders">The <see cref="IOAuthProviders"/> to get data from.</param>
|
||||
public OAuthProviderInfos(IOAuthProviders oAuthProviders)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(oAuthProviders);
|
||||
|
||||
var dic = oAuthProviders.ProviderInfos();
|
||||
|
||||
TProviderInfo? TryBuild<TProviderInfo>(OAuthProvider oAuthProvider, Func<OAuthProviderInfo, TProviderInfo> contructor)
|
||||
where TProviderInfo : BasicOAuthProviderInfo
|
||||
{
|
||||
if (dic.TryGetValue(oAuthProvider, out var providerInfo))
|
||||
{
|
||||
return contructor(providerInfo);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Discord = TryBuild(OAuthProvider.Discord, info => new BasicOAuthProviderInfo(info));
|
||||
GitHub = TryBuild(OAuthProvider.GitHub, info => new RedirectOAuthProviderInfo(info));
|
||||
TGForums = TryBuild(OAuthProvider.TGForums, info => new RedirectOAuthProviderInfo(info));
|
||||
Keycloak = TryBuild(OAuthProvider.Keycloak, info => new FullOAuthProviderInfo(info));
|
||||
InvisionCommunity = TryBuild(OAuthProvider.InvisionCommunity, info => new FullOAuthProviderInfo(info));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth provider info with a <see cref="RedirectUri"/>.
|
||||
/// </summary>
|
||||
public class RedirectOAuthProviderInfo : BasicOAuthProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The authentication server URL.
|
||||
/// </summary>
|
||||
public Uri RedirectUri { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RedirectOAuthProviderInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="providerInfo">The <see cref="OAuthProviderInfo"/> to build from.</param>
|
||||
public RedirectOAuthProviderInfo(OAuthProviderInfo providerInfo)
|
||||
: base(providerInfo)
|
||||
{
|
||||
RedirectUri = providerInfo!.RedirectUri ?? throw new InvalidOperationException("RedirectUri not set!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
using Tgstation.Server.Api.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.GraphQL.Types.OAuth
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth provider info with a <see cref="ServerUrl"/>.
|
||||
/// </summary>
|
||||
public sealed class ServerUrlOAuthProviderInfo : BasicOAuthProviderInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The remote service URL.
|
||||
/// </summary>
|
||||
public Uri ServerUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerUrlOAuthProviderInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="providerInfo">The <see cref="OAuthProviderInfo"/> to build from.</param>
|
||||
public ServerUrlOAuthProviderInfo(OAuthProviderInfo providerInfo)
|
||||
: base(providerInfo)
|
||||
{
|
||||
ServerUrl = providerInfo!.ServerUrl ?? throw new InvalidOperationException("ServerUrl not set!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using HotChocolate.Types.Relay;
|
||||
|
||||
using Tgstation.Server.Host.Authority;
|
||||
using Tgstation.Server.Host.GraphQL.Interfaces;
|
||||
using Tgstation.Server.Host.GraphQL.Types.OAuth;
|
||||
using Tgstation.Server.Host.Models.Transformers;
|
||||
using Tgstation.Server.Host.Security;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user