Table 1140 OAuth 2.0 Setup
- App
- Base Application
- Namespace
- System.Security.Authentication
- Versions
- 17-28
Fields, 25Keys, 1Procedures, 14Events, 5Obsolete, 10
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/System/OAuth/OAuth20Setup.Table.al382 lines, Copyright (c) Microsoft Corporation. MIT
namespace System.Security.Authentication;
using Microsoft.Foundation.Enums;
using System.Integration;
using System.Security.AccessControl;
table 1140 "OAuth 2.0 Setup"
{
Caption = 'OAuth 2.0 Setup';
ReplicateData = false;
DataClassification = CustomerContent;
fields
{
field(1; "Code"; Code[20])
{
Caption = 'Code';
NotBlank = true;
}
field(2; Description; Text[250])
{
Caption = 'Description';
}
field(3; "Service URL"; Text[250])
{
Caption = 'Service URL';
trigger OnValidate()
var
WebRequestHelper: Codeunit "Web Request Helper";
begin
if "Service URL" <> '' then
WebRequestHelper.IsSecureHttpUrl("Service URL");
end;
}
field(4; "Redirect URL"; Text[250])
{
Caption = 'Redirect URL';
}
field(5; "Client ID"; Guid)
{
Caption = 'Client ID';
DataClassification = EndUserIdentifiableInformation;
}
field(6; "Client Secret"; Guid)
{
Caption = 'Client Secret';
DataClassification = EndUserIdentifiableInformation;
}
field(7; "Access Token"; Guid)
{
Caption = 'Access Token';
DataClassification = EndUserIdentifiableInformation;
}
field(8; "Refresh Token"; Guid)
{
Caption = 'Refresh Token';
DataClassification = EndUserIdentifiableInformation;
}
field(9; "Authorization URL Path"; Text[250])
{
Caption = 'Authorization URL Path';
trigger OnValidate()
begin
CheckAndAppendURLPath("Authorization URL Path");
end;
}
field(10; "Access Token URL Path"; Text[250])
{
Caption = 'Access Token URL Path';
trigger OnValidate()
begin
CheckAndAppendURLPath("Access Token URL Path");
end;
}
field(11; "Refresh Token URL Path"; Text[250])
{
Caption = 'Refresh Token URL Path';
trigger OnValidate()
begin
CheckAndAppendURLPath("Refresh Token URL Path");
end;
}
field(12; Scope; Text[250])
{
Caption = 'Scope';
}
field(13; "Authorization Response Type"; Text[250])
{
Caption = 'Authorization Response Type';
}
field(14; Status; Option)
{
Caption = 'Status';
OptionCaption = ' ,Enabled,Disabled,Connected,Error';
OptionMembers = " ",Enabled,Disabled,Connected,Error;
}
field(15; "Token DataScope"; Option)
{
Caption = 'Token DataScope';
OptionCaption = 'Module,User,Company,UserAndCompany';
OptionMembers = Module,User,Company,UserAndCompany;
}
field(16; "Activity Log ID"; Integer)
{
Caption = 'Activity Log ID';
}
field(17; "Daily Limit"; Integer)
{
Caption = 'Daily Limit';
Editable = false;
}
field(18; "Daily Count"; Integer)
{
Caption = 'Daily Count';
Editable = false;
}
field(19; "Latest Datetime"; DateTime)
{
Caption = 'Latest Datetime';
Editable = false;
}
field(20; "Access Token Due DateTime"; DateTime)
{
Caption = 'Access Token Due DateTime';
Editable = false;
}
field(21; "Feature GUID"; Guid)
{
Caption = 'Feature GUID';
Editable = false;
}
field(22; "User ID"; Code[50])
{
Caption = 'User ID';
DataClassification = EndUserIdentifiableInformation;
TableRelation = User."User Name";
}
field(50; "Code Challenge Method"; Enum "OAuth 2.0 Code Challenge")
{
}
field(51; "Code Verifier"; Guid)
{
}
field(52; "Use Nonce"; Boolean)
{
}
}
keys
{
key(Key1; "Code")
{
Clustered = true;
}
}
fieldgroups
{
}
trigger OnDelete()
begin
DeleteToken("Client ID");
DeleteToken("Client Secret");
DeleteToken("Access Token");
DeleteToken("Refresh Token");
end;
var
OAuth20Mgt: Codeunit "OAuth 2.0 Mgt.";
local procedure CheckAndAppendURLPath(var value: Text)
begin
if value <> '' then
if value[1] <> '/' then
value := '/' + value;
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Call IsolatedStorage.SetEncrypted or IsolatedStorage.Set from your app.', '27.0')]
#pragma warning restore AS0072
internal procedure SetToken(var TokenKey: Guid; TokenValue: SecretText)
#else
internal procedure SetToken(var TokenKey: Guid; TokenValue: SecretText)
#endif
begin
if IsNullGuid(TokenKey) then
TokenKey := CreateGuid();
if EncryptionEnabled() then
IsolatedStorage.SetEncrypted(TokenKey, TokenValue, GetTokenDataScope())
else
IsolatedStorage.Set(TokenKey, TokenValue, GetTokenDataScope());
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Call IsolatedStorage.Get from your app.', '27.0')]
internal procedure GetTokenAsSecretText(TokenKey: Guid) TokenValue: SecretText
#pragma warning restore AS0072
#else
internal procedure GetTokenAsSecretText(TokenKey: Guid) TokenValue: SecretText
#endif
begin
if not HasToken(TokenKey) then
exit(TokenValue);
IsolatedStorage.Get(TokenKey, GetTokenDataScope(), TokenValue);
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Call IsolatedStorage.Delete from your app.', '27.0')]
internal procedure DeleteToken(TokenKey: Guid)
#pragma warning restore AS0072
#else
internal procedure DeleteToken(TokenKey: Guid)
#endif
begin
if not HasToken(TokenKey) then
exit;
IsolatedStorage.Delete(TokenKey, GetTokenDataScope());
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Call IsolatedStorage.Contains from your app.', '27.0')]
internal procedure HasToken(TokenKey: Guid): Boolean
#pragma warning restore AS0072
#else
internal procedure HasToken(TokenKey: Guid): Boolean
#endif
begin
exit(not IsNullGuid(TokenKey) and IsolatedStorage.Contains(TokenKey, GetTokenDataScope()));
end;
procedure GetTokenDataScope(): DataScope
begin
case "Token DataScope" of
"Token DataScope"::Company:
exit(DataScope::Company);
"Token DataScope"::UserAndCompany:
exit(DataScope::CompanyAndUser);
"Token DataScope"::User:
exit(DataScope::User);
"Token DataScope"::Module:
exit(DataScope::Module);
end;
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Get the Rec."Client ID" from IsolatedStorage, call OAuth20Mgt.GetAuthorizationURLAsSecretText with it, unwrap the result and make a hyperlink.', '27.0')]
internal procedure RequestAuthorizationCode()
#pragma warning restore AS0072
#else
internal procedure RequestAuthorizationCode()
#endif
var
Processed: Boolean;
begin
OAuth20Mgt.CheckEncryption();
OnBeforeRequestAuthoizationCode(Rec, Processed);
if Processed then
exit;
OAuth20Mgt.RequestAuthorizationCode(Rec);
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Get the client credentials from IsolatedStorage using Rec."Client ID" and Rec."Client Secret", call OAuth20Mgt.RequestAccessToken or implement this yourself, then save the access token with IsolatedStorage.SetEncrypted or IsolatedStorage.Set.', '27.0')]
internal procedure RequestAccessToken(var MessageText: Text; AuthorizationCode: Text) Result: Boolean
#pragma warning restore AS0072
#else
internal procedure RequestAccessToken(var MessageText: Text; AuthorizationCode: Text) Result: Boolean
#endif
var
Processed: Boolean;
begin
OnBeforeRequestAccessToken(Rec, AuthorizationCode, Result, MessageText, Processed);
if not Processed then
Result := OAuth20Mgt.RequestAndSaveAccessToken(Rec, MessageText, AuthorizationCode);
OnAfterRequestAccessToken(Rec, Result, MessageText);
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Get the refresh token with IsolatedStorage.Get(Rec."Refresh Token"), then call OAuth20Mgt.RefreshAccessToken with it and save the access token with IsolatedStorage.SetEncrypted or IsolatedStorage.Set.', '27.0')]
internal procedure RefreshAccessToken(var MessageText: Text) Result: Boolean
#pragma warning restore AS0072
#else
internal procedure RefreshAccessToken(var MessageText: Text) Result: Boolean
#endif
var
Processed: Boolean;
begin
OnBeforeRefreshAccessToken(Rec, Result, MessageText, Processed);
if not Processed then
Result := OAuth20Mgt.RefreshAndSaveAccessToken(Rec, MessageText);
end;
[NonDebuggable]
#if not CLEAN27
#pragma warning disable AS0072
[Obsolete('This method is being marked as internal. Implement your version of InvokeRequest by getting the Rec."Access Token" from IsolatedStorage, then calling public method OAuth20Mgt.InvokeRequest with it. If you set parameter RetryOnCredentialsFailure to true, you must also subscribe to event OnBeforeRefreshAccessToken raised by OAuth20Setup table and process it with your implementation of RefreshAccessToken and subscribe to OnBeforeInvokeRequest event raised by OAuth20Setup table and process it with your implementation of InvokeRequest (this implementation)', '27.0')]
internal procedure InvokeRequest(RequestJSON: Text; var ResponseJSON: Text; var HttpError: Text; RetryOnCredentialsFailure: Boolean) Result: Boolean
#pragma warning restore AS0072
#else
internal procedure InvokeRequest(RequestJSON: Text; var ResponseJSON: Text; var HttpError: Text; RetryOnCredentialsFailure: Boolean) Result: Boolean
#endif
var
Processed: Boolean;
begin
OnBeforeInvokeRequest(Rec, RequestJSON, ResponseJSON, HttpError, Result, Processed, RetryOnCredentialsFailure);
if not Processed then
Result := OAuth20Mgt.InvokeRequestBasic(Rec, RequestJSON, ResponseJSON, HttpError, RetryOnCredentialsFailure);
end;
procedure FindSetOAuth20SetupByFeature(FeatureGUID: Guid): Boolean
begin
SetRange("Feature GUID", FeatureGUID);
exit(FindSet());
end;
procedure FindFirstOAuth20SetupByFeatureAndCurrUser(FeatureGUID: Guid): Boolean
begin
SetRange("Feature GUID", FeatureGUID);
SetRange("User ID", CopyStr(UserId(), 1, MaxStrLen("User Id")));
exit(FindFirst());
end;
procedure FindFirstOAuth20SetupByFeatureAndUser(FeatureGUID: Guid; OAuthUserID: Code[50]): Boolean
begin
SetRange("Feature GUID", FeatureGUID);
SetRange("User ID", OAuthUserID);
exit(FindFirst());
end;
[IntegrationEvent(false, false)]
local procedure OnAfterRequestAccessToken(OAuth20Setup: Record "OAuth 2.0 Setup"; Result: Boolean; var MessageText: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRequestAuthoizationCode(OAuth20Setup: Record "OAuth 2.0 Setup"; var Processed: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRefreshAccessToken(var OAuth20Setup: Record "OAuth 2.0 Setup"; var Result: Boolean; var MessageText: Text; var Processed: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRequestAccessToken(var OAuth20Setup: Record "OAuth 2.0 Setup"; AuthorizationCode: Text; var Result: Boolean; var MessageText: Text; var Processed: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInvokeRequest(var OAuth20Setup: Record "OAuth 2.0 Setup"; RequestJSON: Text; var ResponseJSON: Text; var HttpError: Text; var Result: Boolean; var Processed: Boolean; RetryOnCredentialsFailure: Boolean)
begin
end;
}