tgstation-server 6.12.3
The /tg/station 13 server suite
Loading...
Searching...
No Matches
GraphQLServerClientFactory.cs
Go to the documentation of this file.
1using System;
2using System.Net.Http.Headers;
3using System.Text;
4using System.Threading;
5using System.Threading.Tasks;
6
7using Microsoft.Extensions.DependencyInjection;
8using Microsoft.Extensions.Logging;
9
10using StrawberryShake;
11
16
18{
21 {
26
35 static ServiceProvider SetupServiceProvider(Uri host, bool addAuthorizationHandler, AuthenticationHeaderValue? headerOverride = null, OAuthProvider? oAuthProvider = null)
36 {
37 var serviceCollection = new ServiceCollection();
38
39 var clientBuilder = serviceCollection
40 .AddGraphQLClient();
41 var graphQLEndpoint = new Uri(host, Routes.GraphQL);
42
43 clientBuilder.ConfigureHttpClient(
44 client =>
45 {
46 client.BaseAddress = graphQLEndpoint;
47 client.DefaultRequestHeaders.Add(ApiHeaders.ApiVersionHeader, $"Tgstation.Server.Api/{ApiHeaders.Version.Semver()}");
48 if (oAuthProvider.HasValue)
49 {
50 client.DefaultRequestHeaders.Add(ApiHeaders.OAuthProviderHeader, oAuthProvider.ToString());
51 }
52 },
53 clientBuilder =>
54 {
55 if (addAuthorizationHandler)
56 clientBuilder.AddHttpMessageHandler(() => new AuthorizationMessageHandler(headerOverride));
57 });
58
59 serviceCollection.AddSerializer<UnsignedIntSerializer>();
60 serviceCollection.AddSerializer<SemverSerializer>();
61 serviceCollection.AddSerializer<JwtSerializer>();
62
63 return serviceCollection.BuildServiceProvider();
64 }
65
71 {
72 this.restClientFactory = restClientFactory ?? throw new ArgumentNullException(nameof(restClientFactory));
73 }
74
76 public ValueTask<IAuthenticatedGraphQLServerClient> CreateFromLogin(Uri host, string username, string password, bool attemptLoginRefresh = true, CancellationToken cancellationToken = default)
77 {
78 var basicCredentials = new AuthenticationHeaderValue(
80 Convert.ToBase64String(
81 Encoding.UTF8.GetBytes($"{username}:{password}")));
82
83 return CreateWithAuthCall(
84 host,
85 basicCredentials,
86 null,
87 attemptLoginRefresh,
88 cancellationToken);
89 }
90
92 public ValueTask<IAuthenticatedGraphQLServerClient> CreateFromOAuth(Uri host, string oAuthCode, OAuthProvider oAuthProvider, CancellationToken cancellationToken = default)
93 {
94 var oAuthCredentials = new AuthenticationHeaderValue(
96 oAuthCode);
97
98 return CreateWithAuthCall(
99 host,
100 oAuthCredentials,
101 oAuthProvider,
102 false,
103 cancellationToken);
104 }
105
108 {
109 var authenticationHeader = new AuthenticationHeaderValue(
111 token);
112
113 var serviceProvider = SetupServiceProvider(
114 host,
115 true,
116 authenticationHeader);
117
119 serviceProvider.GetRequiredService<IGraphQLClient>(),
120 serviceProvider,
121 serviceProvider.GetRequiredService<ILogger<GraphQLServerClient>>(),
123 }
124
127 {
128 var serviceProvider = SetupServiceProvider(host, false);
129
130 return new GraphQLServerClient(
131 serviceProvider.GetRequiredService<IGraphQLClient>(),
132 serviceProvider,
133 serviceProvider.GetRequiredService<ILogger<GraphQLServerClient>>());
134 }
135
146 async ValueTask<IAuthenticatedGraphQLServerClient> CreateWithAuthCall(
147 Uri host,
148 AuthenticationHeaderValue initialCredentials,
149 OAuthProvider? oAuthProvider,
150 bool attemptLoginRefresh,
151 CancellationToken cancellationToken)
152 {
153 var serviceProvider = SetupServiceProvider(
154 host,
155 true,
156 oAuthProvider: oAuthProvider);
157 try
158 {
159 var client = serviceProvider.GetRequiredService<IGraphQLClient>();
160
161 IOperationResult<ILoginResult> result;
162
163 var previousAuthHeader = AuthorizationMessageHandler.Header.Value;
164 AuthorizationMessageHandler.Header.Value = initialCredentials;
165 try
166 {
167 result = await client.Login.ExecuteAsync(cancellationToken).ConfigureAwait(false);
168 }
169 finally
170 {
171 AuthorizationMessageHandler.Header.Value = previousAuthHeader;
172 }
173
174 var serverClient = new AuthenticatedGraphQLServerClient(
175 client,
176 serviceProvider,
177 serviceProvider.GetRequiredService<ILogger<GraphQLServerClient>>(),
178 newHeader => AuthorizationMessageHandler.Header.Value = newHeader,
179 attemptLoginRefresh ? initialCredentials : null,
180 result,
181 bearer => CreateAuthenticatedTransferClient(host, bearer));
182
183 await Task.Yield();
184
185 return serverClient;
186 }
187 catch
188 {
189 await serviceProvider.DisposeAsync().ConfigureAwait(false);
190 throw;
191 }
192 }
193
201 {
202 var restClient = restClientFactory.CreateFromToken(
203 host,
204 new TokenResponse
205 {
206 Bearer = bearer,
207 });
208
209 return restClient;
210 }
211 }
212}
Represents the header that must be present for every server request.
Definition ApiHeaders.cs:25
const string OAuthAuthenticationScheme
The JWT authentication header scheme.
Definition ApiHeaders.cs:54
const string BasicAuthenticationScheme
The JWT authentication header scheme.
Definition ApiHeaders.cs:49
const string ApiVersionHeader
The ApiVersion header key.
Definition ApiHeaders.cs:29
const string BearerAuthenticationScheme
The JWT authentication header scheme.
Definition ApiHeaders.cs:44
const string OAuthProviderHeader
The OAuthProvider header key.
Definition ApiHeaders.cs:39
Represents a JWT returned by the API.
Routes to a server actions.
Definition Routes.cs:9
const string GraphQL
The GraphQL route.
Definition Routes.cs:18
DelegatingHandler that applies the AuthenticationHeaderValue.
static AsyncLocal< AuthenticationHeaderValue?> Header
The AsyncLocal<T> AuthenticationHeaderValue to be applied.
readonly IRestServerClientFactory restClientFactory
The IRestServerClientFactory for the GraphQLServerClientFactory.
static ServiceProvider SetupServiceProvider(Uri host, bool addAuthorizationHandler, AuthenticationHeaderValue? headerOverride=null, OAuthProvider? oAuthProvider=null)
Sets up a ServiceProvider for providing the IGraphQLClient.
IAuthenticatedGraphQLServerClient CreateFromToken(Uri host, string token)
Create a IRestServerClient.A new IGraphQLServerClient.
GraphQLServerClientFactory(IRestServerClientFactory restClientFactory)
Initializes a new instance of the GraphQLServerClientFactory class.
IGraphQLServerClient CreateUnauthenticated(Uri host)
Create an unauthenticated IGraphQLServerClient.A new IGraphQLServerClient.
IRestServerClient CreateAuthenticatedTransferClient(Uri host, string bearer)
Create a ITransferClient for a given host and bearer token.
ValueTask< IAuthenticatedGraphQLServerClient > CreateFromOAuth(Uri host, string oAuthCode, OAuthProvider oAuthProvider, CancellationToken cancellationToken=default)
Create a IGraphQLServerClient using an OAuth login.A ValueTask<TResult> resulting in a new IAuthentic...
ValueTask< IAuthenticatedGraphQLServerClient > CreateFromLogin(Uri host, string username, string password, bool attemptLoginRefresh=true, CancellationToken cancellationToken=default)
Create a IGraphQLServerClient using a password login.A ValueTask<TResult> resulting in a new IAuthent...
async ValueTask< IAuthenticatedGraphQLServerClient > CreateWithAuthCall(Uri host, AuthenticationHeaderValue initialCredentials, OAuthProvider? oAuthProvider, bool attemptLoginRefresh, CancellationToken cancellationToken)
Create an IAuthenticatedGraphQLServerClient from a remote login call.
ScalarSerializer<TSerialized, TRuntime> for JsonWebTokens.
ScalarSerializer<TSerialized, TRuntime> for Versions.
ScalarSerializer<TSerialized, TRuntime> for UInt32s.
IRestServerClient CreateFromToken(Uri host, TokenResponse token)
Create a IRestServerClient.
Main client for communicating with a server.
OAuthProvider
List of OAuth providers supported by TGS.