unit OpenAPI.Classes.Security;

interface

uses
  Classes, Generics.Collections,
  Bcl.Collections,
  OpenAPI.Json.Attributes, OpenAPI.Types;

type
  TScopeNames = class(TList<string>)
  public
    constructor Create; overload;
    constructor Create(Names: array of string); overload;
  end;

  // Lists the required security schemes to execute an operation.
  // Each name must correspond to a security scheme which is declared in the Security Definitions.
  // If the security scheme is of type "oauth2", then the value is a list of scope names required for the execution.
  TSecurityRequirement = class(TOrderedObjectDictionary<string, TScopeNames>);

  TSecurityRequirements = class(TObjectList<TSecurityRequirement>)
  public
    function AddRequirement: TSecurityRequirement;
  end;

  // Lists the available scopes for an OAuth2 security scheme.
  // Maps between a name of a scope to a short description of it.
  TScopes = class(TOrderedDictionary<string, string>);

  // Allows the definition of a security scheme that can be used by the operations.
  [OAJsonInclusion, OAJsonNaming]
  TSecurityDefinition = class
  strict private
    FType: TSecuritySchemeType;
    FName: string;
    FDescription: string;
    FIn: TLocation;
    FAuthorizationUrl: TUrl;
    FTokenUrl: TUrl;
    FFlow: TSecurityFlow;
    FScopes: TScopes;
    function GetScopes: TScopes;
  public
    destructor Destroy; override;
    // Required. The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
    property &Type: TSecuritySchemeType read FType write FType;
    // A short description for security scheme.
    property Description: string read FDescription write FDescription;
    // Required. The name of the header or query parameter to be used.
    property Name: string read FName write FName;
    // Required. The location of the API key. Valid values are "query" or "header".
    property &In: TLocation read FIn write FIn;
    // Required. The flow used by the OAuth2 security scheme.
    // Valid values are "implicit", "password", "application" or "accessCode".
    property Flow: TSecurityFlow read FFlow write FFlow;
    // Required. The authorization URL to be used for this flow.
    property AuthorizationUrl: TUrl read FAuthorizationUrl write FAuthorizationUrl;
    // Required. The token URL to be used for this flow.
    property TokenUrl: TUrl read FTokenUrl write FTokenUrl;
    // Required. The available scopes for the OAuth2 security scheme.
    property Scopes: TScopes read GetScopes;
  end;

  // A declaration of the security schemes available to be used in the specification.
  TSecurityDefinitions = class(TOrderedObjectDictionary<string, TSecurityDefinition>);

implementation

{ TSecurityRequirements }

function TSecurityRequirements.AddRequirement: TSecurityRequirement;
begin
  result := TSecurityRequirement.Create;
  Add(result);
end;

{ TScopeNames }

constructor TScopeNames.Create(Names: array of string);
var
  name: string;
begin
  inherited Create;
  for name in Names do
    Add(name);
end;

constructor TScopeNames.Create;
begin
  inherited;
end;

{ TSecurityDefinition }

destructor TSecurityDefinition.Destroy;
begin
  FScopes.Free;
  inherited;
end;

function TSecurityDefinition.GetScopes: TScopes;
begin
  if FScopes = nil then
    FScopes := TScopes.Create;
  result := FScopes;
end;

end.

