[backend/masto-client] Support client_credentials grant type (ISH-416)

This commit is contained in:
Laura Hausmann 2024-07-12 18:13:40 +02:00
parent 9c8debb5ed
commit b504bf2548
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
2 changed files with 33 additions and 2 deletions

View file

@ -87,9 +87,34 @@ public class AuthController(DatabaseContext db, MetaService meta) : ControllerBa
[ProducesErrors(HttpStatusCode.BadRequest)] [ProducesErrors(HttpStatusCode.BadRequest)]
public async Task<OauthTokenResponse> GetOauthToken([FromHybrid] OauthTokenRequest request) public async Task<OauthTokenResponse> GetOauthToken([FromHybrid] OauthTokenRequest request)
{ {
//TODO: app-level access (grant_type = "client_credentials") if (request.GrantType == "client_credentials")
{
// @formatter:off
var app = await db.OauthApps.FirstOrDefaultAsync(p => p.ClientId == request.ClientId &&
p.ClientSecret == request.ClientSecret) ??
throw GracefulException.Unauthorized("Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.");
// @formatter:on
var invalidAppScope = MastodonOauthHelpers.ExpandScopes(request.Scopes ?? [])
.Except(MastodonOauthHelpers.ExpandScopes(app.Scopes))
.Any();
if (invalidAppScope)
throw GracefulException.BadRequest("The requested scope is invalid, unknown, or malformed.");
app.Token ??= CryptographyHelpers.GenerateRandomString(32);
await db.SaveChangesAsync();
return new OauthTokenResponse
{
CreatedAt = app.CreatedAt,
Scopes = request.Scopes ?? app.Scopes,
AccessToken = app.Token
};
}
if (request.GrantType != "authorization_code") if (request.GrantType != "authorization_code")
throw GracefulException.BadRequest($"Invalid grant_type, only authorization_code is supported."); throw GracefulException.BadRequest("Invalid grant_type");
var token = await db.OauthTokens.FirstOrDefaultAsync(p => p.Code == request.Code && var token = await db.OauthTokens.FirstOrDefaultAsync(p => p.Code == request.Code &&
p.App.ClientId == request.ClientId && p.App.ClientId == request.ClientId &&
p.App.ClientSecret == request.ClientSecret); p.App.ClientSecret == request.ClientSecret);

View file

@ -61,4 +61,10 @@ public class OauthApp
[InverseProperty(nameof(OauthToken.App))] [InverseProperty(nameof(OauthToken.App))]
public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>(); public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>();
/// <summary>
/// The app token, returned by /oauth/token when grant_type client_credentials is requested
/// </summary>
[Column("appToken")] [StringLength(64)]
public string? Token;
} }