5using System.Threading.Tasks;
7using Microsoft.AspNetCore.Authorization;
8using Microsoft.AspNetCore.Http;
9using Microsoft.AspNetCore.Mvc;
10using Microsoft.EntityFrameworkCore;
11using Microsoft.Extensions.Logging;
12using Microsoft.Extensions.Options;
13using Microsoft.Extensions.Primitives;
14using Microsoft.Net.Http.Headers;
123 IOptions<GeneralConfiguration> generalConfigurationOptions,
124 IOptions<ControlPanelConfiguration> controlPanelConfigurationOptions,
125 ILogger<HomeController> logger)
128 authenticationContextFactory,
141 generalConfiguration = generalConfigurationOptions?.Value ??
throw new ArgumentNullException(nameof(generalConfigurationOptions));
142 controlPanelConfiguration = controlPanelConfigurationOptions?.Value ??
throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
156#pragma warning disable CA1506
157 public async Task<IActionResult>
Home(CancellationToken cancellationToken)
160 Response.Headers.Add(
168 Logger.LogDebug(
"No API headers on request, redirecting to control panel...");
171 if (String.IsNullOrWhiteSpace(controlPanelRoute))
174 return Redirect(controlPanelRoute);
180 var headers =
new ApiHeaders(Request.GetTypedHeaders(),
true);
181 if (!headers.Compatible())
183 HttpStatusCode.UpgradeRequired,
208#pragma warning restore CA1506
222#pragma warning disable CA1506
223 public async Task<IActionResult>
CreateToken(CancellationToken cancellationToken)
227 Response.Headers.Add(HeaderNames.WWWAuthenticate,
new StringValues(
"basic realm=\"Create TGS bearer token\""));
243 catch (NotImplementedException ex)
248 using (systemIdentity)
255 string externalUserId;
261 if (validator ==
null)
264 externalUserId = await validator
267 Logger.LogTrace(
"External {oAuthProvider} UID: {externalUserId}", oAuthProvider, externalUserId);
269 catch (RateLimitExceededException ex)
274 if (externalUserId ==
null)
275 return Unauthorized();
278 x => x.OAuthConnections.Any(
279 y => y.Provider == oAuthProvider
280 && y.ExternalUserId == externalUserId));
285 if (canonicalUserName == Models.User.CanonicalizeName(Models.User.TgsSystemUserName))
286 return Unauthorized();
288 if (systemIdentity ==
null)
289 query = query.Where(x => x.CanonicalName == canonicalUserName);
291 query = query.Where(x => x.CanonicalName == canonicalUserName || x.SystemIdentifier == systemIdentity.
Uid);
294 var users = await query
295 .Select(x =>
new Models.User
298 PasswordHash = x.PasswordHash,
301 SystemIdentifier = x.SystemIdentifier,
303 .ToListAsync(cancellationToken);
307 .OrderByDescending(dbUser => dbUser.SystemIdentifier ==
null)
312 return Unauthorized();
319 var originalHash = user.PasswordHash;
320 var isLikelyDbUser = originalHash !=
null;
321 bool usingSystemIdentity = systemIdentity !=
null && !isLikelyDbUser;
323 if (!usingSystemIdentity)
327 return Unauthorized();
328 if (user.PasswordHash != originalHash)
330 Logger.LogDebug(
"User ID {userId}'s password hash needs a refresh, updating database.", user.Id);
336 updatedUser.PasswordHash = user.PasswordHash;
342 var usernameMismatch = systemIdentity.Username != user.Name;
343 if (isLikelyDbUser || usernameMismatch)
349 Logger.LogDebug(
"System user ID {userId}'s PasswordHash is polluted, updating database.", user.Id);
350 user.PasswordHash =
null;
351 user.LastPasswordUpdate = DateTimeOffset.UtcNow;
354 if (usernameMismatch)
357 Logger.LogDebug(
"User ID {userId}'s system identity needs a refresh, updating database.", user.Id);
358 user.Name = systemIdentity.
Username;
359 user.CanonicalName = Models.User.CanonicalizeName(user.Name);
367 if (!user.Enabled.Value)
369 Logger.LogTrace(
"Not logging in disabled user {userId}.", user.Id);
374 if (usingSystemIdentity)
377 var identExpiry = token.ExpiresAt;
379 identExpiry += TimeSpan.FromSeconds(15);
383 Logger.LogDebug(
"Successfully logged in user {userId}!", user.Id);
388#pragma warning restore CA1506
virtual ? long Id
The ID of the entity.
Represents an error message returned by the server.
Represents a JWT returned by the API.
Routes to a server actions.
const string Root
The root controller.
Constants used for communication with the DMAPI.
static readonly Version InteropVersion
The DMAPI InteropVersion being used.
Configuration options for the web control panel.
bool Enable
If the control panel is enabled.
string PublicPath
The public path to the TGS control panel from a wider network.
General configuration options.
Base Controller for API functions.
ApiHeaders ApiHeaders
The Api.ApiHeaders for the operation.
IActionResult HeadersIssue(bool ignoreMissingAuth)
Response for missing/Invalid headers.
ObjectResult RequiresPosixSystemIdentity(NotImplementedException ex)
Generic 501 response.
StatusCodeResult StatusCode(HttpStatusCode statusCode)
Strongly type calls to ControllerBase.StatusCode(int).
ObjectResult RateLimit(RateLimitExceededException rateLimitException)
429 response for a given rateLimitException .
ILogger< ApiController > Logger
The ILogger for the ApiController.
Controller for the web control panel.
const string ControlPanelRoute
Route to the ControlPanelController.
Root ApiController for the Application.
readonly IPlatformIdentifier platformIdentifier
The IPlatformIdentifier for the HomeController.
readonly IServerControl serverControl
The IServerControl for the HomeController.
async Task< IActionResult > Home(CancellationToken cancellationToken)
Main page of the Application.
readonly IAssemblyInformationProvider assemblyInformationProvider
The IAssemblyInformationProvider for the HomeController.
readonly IOAuthProviders oAuthProviders
The IOAuthProviders for the HomeController.
async Task< IActionResult > CreateToken(CancellationToken cancellationToken)
Attempt to authenticate a User using ApiController.ApiHeaders.
readonly IIdentityCache identityCache
The IIdentityCache for the HomeController.
readonly ICryptographySuite cryptographySuite
The ICryptographySuite for the HomeController.
readonly GeneralConfiguration generalConfiguration
The GeneralConfiguration for the HomeController.
HomeController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, ITokenFactory tokenFactory, ISystemIdentityFactory systemIdentityFactory, ICryptographySuite cryptographySuite, IAssemblyInformationProvider assemblyInformationProvider, IIdentityCache identityCache, IOAuthProviders oAuthProviders, IPlatformIdentifier platformIdentifier, ISwarmService swarmService, IServerControl serverControl, IOptions< GeneralConfiguration > generalConfigurationOptions, IOptions< ControlPanelConfiguration > controlPanelConfigurationOptions, ILogger< HomeController > logger)
Initializes a new instance of the HomeController class.
readonly ControlPanelConfiguration controlPanelConfiguration
The ControlPanelConfiguration for the HomeController.
readonly ISystemIdentityFactory systemIdentityFactory
The ISystemIdentityFactory for the HomeController.
readonly ISwarmService swarmService
The ISwarmService for the HomeController.
readonly ITokenFactory tokenFactory
The ITokenFactory for the HomeController.
Backend abstract implementation of IDatabaseContext.
Task Save(CancellationToken cancellationToken)
Saves changes made to the IDatabaseContext. A Task representing the running operation.
DbSet< User > Users
The Users in the DatabaseContext.
Represents a service that may take an updated Host assembly and run it, stopping the current assembly...
bool UpdateInProgress
Whether or not the server is currently updating.
For creating and accessing authentication contexts.
Contains various cryptographic functions.
bool CheckUserPassword(User user, string password)
Checks a given password matches a given user 's User.PasswordHash. This may result in User....
For caching ISystemIdentitys.
void CacheSystemIdentity(User user, ISystemIdentity systemIdentity, DateTimeOffset expiry)
Keep a user 's systemIdentity alive until an expiry time.
Factory for ISystemIdentitys.
Task< ISystemIdentity > CreateSystemIdentity(User user, CancellationToken cancellationToken)
Create a ISystemIdentity for a given user .
Represents a user on the current global::System.Runtime.InteropServices.OSPlatform.
string Uid
A unique identifier for the user.
string Username
The user's name.
For creating TokenResponses.
Task< TokenResponse > CreateToken(Models.User user, bool oAuth, CancellationToken cancellationToken)
Create a TokenResponse for a given user .
TokenValidationParameters ValidationParameters
The TokenValidationParameters for the ITokenFactory.
Contains IOAuthValidators.
IOAuthValidator GetValidator(OAuthProvider oAuthProvider)
Gets the IOAuthValidator for a given oAuthProvider .
Task< Dictionary< OAuthProvider, OAuthProviderInfo > > ProviderInfos(CancellationToken cancellationToken)
Gets a Dictionary<TKey, TValue> of the provider client IDs.
Used for swarm operations. Functions may be no-op based on configuration.
ICollection< SwarmServerResponse > GetSwarmServers()
Gets the list of SwarmServerResponses in the swarm, including the current one.
ErrorCode
Types of Response.ErrorMessageResponses that the API may return.