mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-21 20:17:22 +01:00
Merge pull request #1699 from tgstation/1693-Shrimple
Stop using HTTP 426 (In the HTTP API at least)
This commit is contained in:
@@ -72,7 +72,6 @@ TGS will only every return the response codes listed here
|
||||
- 410: Gone. Attempted to access/modify a resource that ideally should have been ready, but isn't or no longer is
|
||||
- 422: Unprocessable Entity: Used specifically when an operation that requires a server restart is unable to be performed due to the @ref Tgstation.Server.Host.Watchdog not being present in the deployment. Should not happen with a proper server configuration. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
|
||||
- 424: Failed Dependency: When a request that depends on an external API fails for a reason other than rate limiting. The response body will contain an @ref Tgstation.Server.Api.Models.ErrorMessage model detailing the error.
|
||||
- 426: Upgrade required: Used when the client's API version is not compatible with the server's. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
|
||||
- 429: Rate limited. Used with operations that rely on GitHub.com. If a rate limit is hit for an operation this will be returned. Response will contain a Retry-After header with the amount of seconds to wait.
|
||||
- 500: Server error. Please report the request and response body to the code repository
|
||||
- 501: Not implemented. Functionality not available in the current server version
|
||||
|
||||
@@ -131,8 +131,6 @@ namespace Tgstation.Server.Client
|
||||
#pragma warning restore IDE0066 // Convert switch statement to expression
|
||||
#pragma warning restore IDE0010 // Add missing cases
|
||||
{
|
||||
case HttpStatusCode.UpgradeRequired:
|
||||
throw new VersionMismatchException(errorMessage, response);
|
||||
case HttpStatusCode.Unauthorized:
|
||||
throw new UnauthorizedException(errorMessage, response);
|
||||
case HttpStatusCode.InternalServerError:
|
||||
@@ -154,6 +152,9 @@ namespace Tgstation.Server.Client
|
||||
case (HttpStatusCode)429:
|
||||
throw new RateLimitException(errorMessage, response);
|
||||
default:
|
||||
if (errorMessage?.ErrorCode == ErrorCode.ApiMismatch)
|
||||
throw new VersionMismatchException(errorMessage, response);
|
||||
|
||||
throw new ApiConflictException(errorMessage, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<Description>Client library for tgstation-server.</Description>
|
||||
<PackageTags>json web api tgstation-server tgstation ss13 byond client http</PackageTags>
|
||||
<PackageReleaseNotes>$(TGS_NUGET_RELEASE_NOTES_CLIENT)</PackageReleaseNotes>
|
||||
<NoWarn>NU5104</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,7 +7,6 @@ Some notable exceptions:
|
||||
- [ApiController](./ApiController.cs) is the base class of nearly all API related controllers. It does the following:
|
||||
- Contains code to deny the request if the instance is not present when it should be.
|
||||
- Contains the `IDatabaseContext` and `ILogger` properties for child controllers.
|
||||
- Returns 426 Upgrade Required if the API version in the headers are incompatible with the request.
|
||||
- Returns 400 Bad Request if the headers or the PUT/POST'd model is invalid.
|
||||
- Returns 401 If an `IAuthenticationContext` could not be created for a request.
|
||||
- [BridgeController](./BridgeController.cs) is a special controller accessible only from localhost and is used to receive bridge request from DreamDaemon
|
||||
|
||||
@@ -132,11 +132,8 @@ namespace Tgstation.Server.Host.Extensions
|
||||
var apiHeadersProvider = context.RequestServices.GetRequiredService<IApiHeadersProvider>();
|
||||
if (apiHeadersProvider.ApiHeaders?.Compatible() == false)
|
||||
{
|
||||
await new JsonResult(
|
||||
await new BadRequestObjectResult(
|
||||
new ErrorMessageResponse(ErrorCode.ApiMismatch))
|
||||
{
|
||||
StatusCode = (int)HttpStatusCode.UpgradeRequired,
|
||||
}
|
||||
.ExecuteResultAsync(new ActionContext
|
||||
{
|
||||
HttpContext = context,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
## For the login request (`POST /`)
|
||||
|
||||
1. An attempt to parse the `ApiHeaders` is made. If they were valid, the API version check is performed. If it fails, HTTP 426 with an `ErrorMessageResponse` will be returned.
|
||||
1. An attempt to parse the `ApiHeaders` is made. If they were valid, the API version check is performed. If it fails, HTTP 400 with an `ErrorMessageResponse` will be returned.
|
||||
1. If, for some reason, the user attempts to use a JWT to authenticate this request, steps 2-4 of the non-login pipeline list below are performed.
|
||||
1. The `ApiController` base class inspects the request.
|
||||
- At this point, if the `ApiHeaders` (MINUS the `Authorization` header) cannot be properly parsed, HTTP 400 with an `ErrorMessageResponse` is returned.
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
## For all other authenticated requests
|
||||
|
||||
1. An attempt to parse the `ApiHeaders` is made. If they were valid. The API version check is performed. If it fails, HTTP 426 with an `ErrorMessageResponse` will be returned.
|
||||
1. An attempt to parse the `ApiHeaders` is made. If they were valid. The API version check is performed. If it fails, HTTP 400 with an `ErrorMessageResponse` will be returned.
|
||||
1. The JWT, if present, is validated. If it is, the scope's [AuthenticationContextFactory](./AuthenticationContextFactory.cs) has `SetTokenNbf` called. If not, HTTP 401 will be returned.
|
||||
- Inside ASP.NET Core, this initializes the calling user's identity principal and sets the "sub" claim to the TGS user ID parsed out of the JWT.
|
||||
- We know it's the user ID because we set it up like that in the [TokenFactory](./TokenFactory.cs)
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Tgstation.Server.Tests.Live
|
||||
request.Headers.Add(ApiHeaders.ApiVersionHeader, "Tgstation.Server.Api/6.0.0");
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue(ApiHeaders.BearerAuthenticationScheme, token);
|
||||
using var response = await httpClient.SendAsync(request, cancellationToken);
|
||||
Assert.AreEqual(HttpStatusCode.UpgradeRequired, response.StatusCode);
|
||||
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
var content = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
var message = JsonConvert.DeserializeObject<ErrorMessageResponse>(content);
|
||||
Assert.AreEqual(ErrorCode.ApiMismatch, message.ErrorCode);
|
||||
@@ -101,7 +101,7 @@ namespace Tgstation.Server.Tests.Live
|
||||
request.Headers.Add(ApiHeaders.ApiVersionHeader, "Tgstation.Server.Api/6.0.0");
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue(ApiHeaders.BearerAuthenticationScheme, token);
|
||||
using var response = await httpClient.SendAsync(request, cancellationToken);
|
||||
Assert.AreEqual(HttpStatusCode.UpgradeRequired, response.StatusCode);
|
||||
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
var content = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
var message = JsonConvert.DeserializeObject<ErrorMessageResponse>(content);
|
||||
Assert.AreEqual(ErrorCode.ApiMismatch, message.ErrorCode);
|
||||
|
||||
Reference in New Issue
Block a user