Skip to content

Commit

Permalink
Updated to new E-Doc Core
Browse files Browse the repository at this point in the history
  • Loading branch information
Roglar01 committed Nov 26, 2024
1 parent 53a81f6 commit e214a39
Show file tree
Hide file tree
Showing 29 changed files with 1,220 additions and 1,382 deletions.
8 changes: 4 additions & 4 deletions Apps/W1/EDocumentConnectors/Tietoevry/app/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
"id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b",
"name": "E-Document Core",
"publisher": "Microsoft",
"version": "26.0.0.0"
"version": "26.0.27172.0"
},
{
"id": "d852a468-263e-49e5-bfda-f09e33342b89",
"name": "E-Documents Connector with External Endpoints",
"publisher": "Microsoft",
"version": "26.0.0.0"
"version": "26.0.27172.0"
}
],
"internalsVisibleTo": [
Expand All @@ -38,8 +38,8 @@
"platform": "26.0.0.0",
"idRanges": [
{
"from": 6380,
"to": 6389
"from": 6390,
"to": 6399
}
],
"resourceExposurePolicy": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.EServices.EDocumentConnector.Tietoevry;

using System.Security.Authentication;
codeunit 6394 "Authenticator"
{
Access = Internal;
Permissions = tabledata "OAuth 2.0 Setup" = im,
tabledata "Connection Setup" = rim;

procedure CreateConnectionSetupRecord()
var
ConnectionSetup: Record "Connection Setup";
begin
if not ConnectionSetup.Get() then begin
ConnectionSetup."Authentication URL" := this.AuthURLTxt;
ConnectionSetup."API URL" := this.APIURLTxt;
ConnectionSetup."Sandbox Authentication URL" := this.SandboxAuthURLTxt;
ConnectionSetup."Sandbox API URL" := this.SandboxAPIURLTxt;
ConnectionSetup."Send Mode" := ConnectionSetup."Send Mode"::Test; //Sandbox
ConnectionSetup.Insert();
end;
end;

procedure SetClientId(var ClientIdKey: Guid; ClientID: SecretText)
begin
this.SetIsolatedStorageValue(ClientIdKey, ClientID, DataScope::Company);
end;

procedure SetClientSecret(var ClienSecretKey: Guid; ClientSecret: SecretText)
begin
this.SetIsolatedStorageValue(ClienSecretKey, ClientSecret, DataScope::Company);
end;

procedure GetAccessToken() Token: SecretText
var
ConnectionSetup: Record "Connection Setup";
Requests: Codeunit Requests;
ExpiresIn: Integer;
ClientId, ClientSecret, TokenTxt, Response : SecretText;
TokenKey: Guid;
begin
ConnectionSetup.Get();

// Reuse token if it lives longer than 1 min in future
if (ConnectionSetup."Token Expiry" > CurrentDateTime() + 60 * 1000) and (not IsNullGuid(ConnectionSetup."Token - Key")) then
if this.GetTokenValue(ConnectionSetup."Token - Key", Token, DataScope::Company) then
exit;

if not this.GetTokenValue(ConnectionSetup."Client ID - Key", ClientId, DataScope::Company) then
Error(this.TietoevryClientIdErr, ConnectionSetup.TableCaption);

if not this.GetTokenValue(ConnectionSetup."Client Secret - Key", ClientSecret, DataScope::Company) then
Error(this.TietoevryClientSecretErr, ConnectionSetup.TableCaption);

Requests.Init();
Requests.CreateAuthenticateRequest(ClientId, ClientSecret);
this.ExecuteResponse(Requests, Response);
if not this.ParseResponse(Response, TokenTxt, ExpiresIn) then
Error(this.TietoevryParseTokenErr);

// Save token for reuse
this.SetIsolatedStorageValue(TokenKey, TokenTxt, DataScope::Company);
// Read again as we want fresh record to modify
ConnectionSetup.Get();
ConnectionSetup."Token - Key" := TokenKey;
ConnectionSetup."Token Expiry" := CurrentDateTime() + ExpiresIn * 1000;
ConnectionSetup.Modify();
Commit();
exit(TokenTxt);
end;

[NonDebuggable]
local procedure ExecuteResponse(var Request: Codeunit Requests; var Response: SecretText)
var
HttpExecutor: Codeunit "Http Executor";
begin
Response := HttpExecutor.ExecuteHttpRequest(Request);
end;

[NonDebuggable]
[TryFunction]
local procedure ParseResponse(Response: SecretText; var Token: SecretText; var ExpiresIn: Integer)
var
ResponseJson: JsonObject;
TokenJson, ExpiryJson : JsonToken;
begin
ResponseJson.ReadFrom(Response.Unwrap());
ResponseJson.Get('access_token', TokenJson);
Token := TokenJson.AsValue().AsText();
ResponseJson.Get('expires_in', ExpiryJson);
ExpiresIn := ExpiryJson.AsValue().AsInteger();
end;

procedure IsClientCredsSet(var ClientId: Text; var ClientSecret: Text): Boolean
var
ConnectionSetup: Record "Connection Setup";
begin
ConnectionSetup.Get();

if this.HasToken(ConnectionSetup."Client ID - Key", DataScope::Company) then
ClientId := '*';
if this.HasToken(ConnectionSetup."Client Secret - Key", DataScope::Company) then
ClientSecret := '*';
end;

procedure SetIsolatedStorageValue(var ValueKey: Guid; Value: SecretText; TokenDataScope: DataScope)
begin
if IsNullGuid(ValueKey) then
ValueKey := CreateGuid();

IsolatedStorage.Set(ValueKey, Value, TokenDataScope);
end;

local procedure GetTokenValue(TokenKey: Text; var TokenValueAsSecret: SecretText; TokenDataScope: DataScope): Boolean
begin
if not this.HasToken(TokenKey, TokenDataScope) then
exit(false);

exit(IsolatedStorage.Get(TokenKey, TokenDataScope, TokenValueAsSecret));
end;

local procedure HasToken(TokenKey: Text; TokenDataScope: DataScope): Boolean
begin
exit(IsolatedStorage.Contains(TokenKey, TokenDataScope));
end;

var
AuthURLTxt: Label 'https://auth.infotorg.no/auth/realms/fms-realm/protocol/openid-connect', Locked = true;
APIURLTxt: Label 'https://accesspoint-api.dataplatfor.ms', Locked = true;
SandboxAuthURLTxt: Label 'https://auth-qa.infotorg.no/auth/realms/fms-realm/protocol/openid-connect', Locked = true;
SandboxAPIURLTxt: Label 'https://accesspoint-api.qa.dataplatfor.ms', Locked = true;
TietoevryClientIdErr: Label 'Tietoevry Client Id is not set in %1', Comment = '%1 - Client id';
TietoevryClientSecretErr: Label 'Tietoevry Client Secret is not set in %1', Comment = '%1 - Client secret';
TietoevryParseTokenErr: Label 'Failed to parse response for Tietoevry Access token request';
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,86 @@
// ------------------------------------------------------------------------------------------------
namespace Microsoft.EServices.EDocumentConnector.Tietoevry;

table 6380 "Connection Setup"
using Microsoft.EServices.EDocumentConnector;

table 6392 "Connection Setup"
{
fields
{
field(1; PK; Code[10])
field(1; Id; Code[10])
{
DataClassification = CustomerContent;
}
field(3; "OAuth Feature GUID"; GUID)
field(2; "Client Id - Key"; Guid)
{
Caption = 'OAuth 2.0 Code';
DataClassification = CustomerContent;
Caption = 'Client Id';
DataClassification = EndUserIdentifiableInformation;
}
field(3; "Client Secret - Key"; Guid)
{
Caption = 'Client Secret';
DataClassification = EndUserIdentifiableInformation;
}
field(4; "Authentication URL"; Text[250])
{
Caption = 'Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(7; "Outbound API URL"; Text[250])
field(5; "API URL"; Text[250])
{
Caption = 'Outbound API URL';
Caption = 'API URL';
DataClassification = CustomerContent;
Editable = false;
}
field(8; "Inbound API URL"; Text[250])
field(6; "Sandbox Authentication URL"; Text[250])
{
Caption = 'Inbound API URL';
Caption = 'Sandbox Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(9; "Company Id"; Text[100])
field(7; "Sandbox API URL"; Text[250])
{
Caption = 'Company ID';
Caption = 'Sandbox Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(10; "Client ID"; Guid)
field(8; "Token - Key"; Guid)
{
Caption = 'Client ID';
DataClassification = EndUserIdentifiableInformation;
Caption = 'Token';
DataClassification = CustomerContent;
}
field(11; "Client Secret"; Guid)
field(9; "Token Expiry"; DateTime)
{
Caption = 'Client Secret';
DataClassification = EndUserIdentifiableInformation;
Caption = 'Token Expiry';
DataClassification = CustomerContent;
}
field(12; "Send Mode"; Enum "E-Document Send Mode")
field(10; "Company Id"; Text[250])
{
Caption = 'Send Mode';
DataClassification = EndUserIdentifiableInformation;
Caption = 'Company ID';
DataClassification = CustomerContent;

trigger OnValidate()
var
TietoevryAuth: Codeunit Authenticator;
TietoevryProcessing: Codeunit Processing;
begin
TietoevryAuth.SetDefaultEndpoints(Rec, "Send Mode");
if not TietoevryProcessing.IsValidSchemeId(Rec."Company Id") then
Rec.FieldError(Rec."Company Id");
end;
}
field(13; "Send Mode"; Enum "E-Doc. Ext. Send Mode")
{
Caption = 'Send Mode';
DataClassification = EndUserIdentifiableInformation;
}
}

keys
{
key(Key1; PK)
key(Key1; Id)
{
Clustered = true;
}
}

}
Loading

0 comments on commit e214a39

Please sign in to comment.