-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ODS-6418] Enforce token limits on API clients (#1117)
- Loading branch information
Showing
6 changed files
with
150 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
Application/EdFi.Ods.Common/Exceptions/TooManyTokensException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Licensed to the Ed-Fi Alliance under one or more agreements. | ||
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
// See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
using System.Collections.Generic; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace EdFi.Ods.Common.Exceptions; | ||
|
||
public class TooManyTokensException : EdFiProblemDetailsExceptionBase | ||
{ | ||
// Fields containing override values for Problem Details | ||
private const string TypePart = "security:authentication:too-many-tokens"; | ||
private const string TitleText = "Too Many Tokens"; | ||
|
||
private const int StatusValue = StatusCodes.Status429TooManyRequests; | ||
|
||
private const string DetailText = "The caller has authenticated too many times in too short of a time period."; | ||
private const string ErrorText = "Too many access tokens have been requested (limit is {0}). Access tokens should be reused until they expire."; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="TooManyTokensException"/> class using the default text and error messages | ||
/// indicating that the maximum token limit has been reached by the API client. | ||
/// </summary> | ||
public TooManyTokensException(int tokenPerClientLimit) | ||
: base(DetailText, [string.Format(ErrorText, tokenPerClientLimit.ToString())]) { } | ||
|
||
// --------------------------- | ||
// Boilerplate for overrides | ||
// --------------------------- | ||
public override string Title { get => TitleText; } | ||
|
||
public override int Status { get => StatusValue; } | ||
|
||
protected override IEnumerable<string> GetTypeParts() | ||
{ | ||
foreach (var part in base.GetTypeParts()) | ||
{ | ||
yield return part; | ||
} | ||
|
||
yield return TypePart; | ||
} | ||
// --------------------------- | ||
} |
37 changes: 37 additions & 0 deletions
37
Artifacts/MsSql/Structure/Admin/0175-Add-CreateClientAccessToken.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
-- SPDX-License-Identifier: Apache-2.0 | ||
-- Licensed to the Ed-Fi Alliance under one or more agreements. | ||
-- The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
-- See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
CREATE OR ALTER PROCEDURE dbo.CreateClientAccessToken( | ||
@Id UNIQUEIDENTIFIER = NULL, | ||
@Expiration DATETIME = NULL, | ||
@Scope NVARCHAR(max) = NULL, | ||
@ApiClientId INT = NULL, | ||
@MaxTokenCount INT = NULL | ||
) | ||
AS | ||
BEGIN | ||
SET NOCOUNT ON | ||
|
||
DECLARE @ActiveTokenCount INT | ||
|
||
IF @MaxTokenCount < 1 | ||
SET @ActiveTokenCount = 0 | ||
ELSE | ||
BEGIN | ||
SET @ActiveTokenCount = (SELECT COUNT(1) | ||
FROM dbo.ClientAccessTokens actoken | ||
WHERE ApiClient_ApiClientId = @ApiClientId | ||
AND actoken.Expiration > GETUTCDATE()) | ||
END | ||
|
||
IF (@MaxTokenCount < 1) OR (@ActiveTokenCount < @MaxTokenCount) | ||
BEGIN | ||
INSERT INTO dbo.ClientAccessTokens(Id, Expiration, Scope, ApiClient_ApiClientId) | ||
VALUES (@Id, @Expiration, @Scope, @ApiClientId) | ||
END | ||
ELSE | ||
THROW 50000, 'Token limit reached', 1; | ||
END | ||
GO |
37 changes: 37 additions & 0 deletions
37
Artifacts/PgSql/Structure/Admin/0175-Add-CreateClientAccessToken.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
-- SPDX-License-Identifier: Apache-2.0 | ||
-- Licensed to the Ed-Fi Alliance under one or more agreements. | ||
-- The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. | ||
-- See the LICENSE and NOTICES files in the project root for more information. | ||
|
||
CREATE OR REPLACE PROCEDURE dbo.CreateClientAccessToken( | ||
id uuid, | ||
expiration timestamp without time zone, | ||
scope text, | ||
apiclientid integer, | ||
maxtokencount integer) | ||
AS | ||
$BODY$ | ||
DECLARE | ||
active_token_count integer; | ||
BEGIN | ||
|
||
IF maxtokencount < 1 THEN | ||
active_token_count := 0; | ||
ELSE | ||
active_token_count := (SELECT COUNT(1) | ||
FROM dbo.clientaccesstokens actoken | ||
WHERE apiclient_apiclientid = ApiClientId | ||
AND actoken.expiration > current_timestamp at time zone 'utc'); | ||
END IF; | ||
|
||
IF (maxtokencount < 1) OR (active_token_count < maxtokencount) THEN | ||
INSERT INTO dbo.ClientAccessTokens(id, expiration, scope, apiclient_apiclientid) | ||
VALUES (CreateClientAccessToken.id, CreateClientAccessToken.expiration, CreateClientAccessToken.scope, | ||
apiclientid); | ||
ELSE | ||
RAISE EXCEPTION USING MESSAGE = 'Token limit reached'; | ||
END IF; | ||
|
||
END | ||
$BODY$ | ||
LANGUAGE plpgsql; |