Codeunit 9263 Cust. Exp. Survey Req. Impl. in 26
- App
- System Application
- Namespace
- System.Feedback
Versions171819202122232425262728latest
Source in 26
src/System Application/App/Customer Experience Survey/src/CustExpSurveyReqImpl.Codeunit.al297 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace System.Feedback;
using System.Security.Authentication;
using System.Azure.KeyVault;
codeunit 9263 "Cust. Exp. Survey Req. Impl."
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
var
GraphScopesLbl: Label 'https://graph.microsoft.com/.default', Locked = true;
GraphPPEScopesLbl: Label 'https://graph.microsoft-ppe.com/.default', Locked = true;
AuthorityLbl: Label 'https://login.microsoftonline.com/microsoft.onmicrosoft.com', Locked = true;
CouldNotGetAccessTokenErr: Label 'Could not get access token.', Locked = true;
CouldNotGetGraphAccessTokenErr: Label 'Could not get graph access token. ', Locked = true;
BearerLbl: Label 'Bearer %1', Locked = true, Comment = '%1 - Bearer token';
CategoryTok: Label 'Customer Experience Survey', Locked = true;
FailedGetRequestErr: Label 'GET %1 request failed with status code %2. Error message: %3', Locked = true, Comment = '%1 - Request, %2 - HTTP status code, %3 - Error message';
FailedPostRequestErr: Label 'POST %1 request failed with status code %2. Error message: %3', Locked = true, Comment = '%1 - Request, %2 - HTTP status code, %3 - Error message';
GetRequestSuccessfulLbl: Label 'GET %1 request was successful.', Locked = true, Comment = '%1 - Request';
PostRequestSuccessfulLbl: Label 'POST %1 request was successful.', Locked = true, Comment = '%1 - Request';
MissingClientIdOrCertificateTelemetryTxt: Label 'The client id or certificate have not been initialized.', Locked = true;
MissingScopeTelemetryTxt: Label 'The scope have not been initialized.', Locked = true;
ClientIdAKVSecretNameLbl: Label 'bctocesappid', Locked = true;
ClientCertificateAKVSecretNameLbl: Label 'bctocesappcertificatename', Locked = true;
ScopeAKVSecretNameLbl: Label 'bctocesappscope', Locked = true;
AcquiredCESTokenLbl: Label 'AcquireTokensWithCertificate call was successful.', Locked = true;
AcquiredGraphTokenLbl: Label 'AcquireOnBehalfOfToken call was successful.', Locked = true;
[TryFunction]
internal procedure TryGet(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text; IsGraph: Boolean)
var
IsHandled: Boolean;
begin
OnGetRequest(RequestUri, ResponseJsonObject, ErrorMessage, IsGraph, IsHandled);
if IsHandled then
exit;
if not Get(RequestUri, ResponseJsonObject, ErrorMessage, IsGraph) then
Error('');
end;
[TryFunction]
internal procedure TryPost(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text)
var
IsHandled: Boolean;
begin
OnPostRequest(RequestUri, ResponseJsonObject, ErrorMessage, IsHandled);
if IsHandled then
exit;
if not Post(RequestUri, ResponseJsonObject, ErrorMessage) then
Error('');
end;
[NonDebuggable]
local procedure Get(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text; IsGraph: Boolean): Boolean
var
CustomerExpSurveyImpl: Codeunit "Customer Exp. Survey Impl.";
HttpClient: HttpClient;
HttpHeaders: HttpHeaders;
HttpResponseMessage: HttpResponseMessage;
JsonContent: Text;
StatusCode: Integer;
begin
HttpHeaders := HttpClient.DefaultRequestHeaders();
HttpHeaders.Add('Accept', 'application/json');
if not Authorize(HttpHeaders, ErrorMessage, IsGraph) then
exit(false);
if not HttpClient.Get(RequestUri, HttpResponseMessage) then begin
ErrorMessage := StrSubstNo(FailedGetRequestErr, RequestUri, '-', '-');
exit(false);
end;
StatusCode := HttpResponseMessage.HttpStatusCode();
if StatusCode <> 200 then begin
ErrorMessage := StrSubstNo(FailedGetRequestErr, RequestUri, StatusCode, GetHttpErrorMessageAsText(HttpResponseMessage, IsGraph));
exit(false);
end;
if HttpResponseMessage.Content.ReadAs(JsonContent) then
if ResponseJsonObject.ReadFrom(JsonContent) then begin
Session.LogMessage('0000J98', CustomerExpSurveyImpl.RemoveUserIdFromMessage(StrSubstNo(GetRequestSuccessfulLbl, RequestUri)), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(true);
end;
ErrorMessage := StrSubstNo(FailedGetRequestErr, RequestUri, StatusCode, '-');
end;
[NonDebuggable]
local procedure Post(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text): Boolean
var
CustomerExpSurveyImpl: Codeunit "Customer Exp. Survey Impl.";
HttpContent: HttpContent;
HttpRequestMessage: HttpRequestMessage;
HttpResponseMessage: HttpResponseMessage;
RequestHttpHeaders: HttpHeaders;
ContentHttpHeaders: HttpHeaders;
HttpClient: HttpClient;
JsonContent: Text;
StatusCode: Integer;
begin
HttpRequestMessage.Method('POST');
HttpRequestMessage.SetRequestUri(RequestUri);
HttpRequestMessage.GetHeaders(RequestHttpHeaders);
if not Authorize(RequestHttpHeaders, ErrorMessage, false) then
exit(false);
HttpContent.WriteFrom(JsonContent);
HttpContent.GetHeaders(ContentHttpHeaders);
ContentHttpHeaders.Clear();
ContentHttpHeaders.Add('Content-Type', 'application/json');
HttpRequestMessage.Content := HttpContent;
if not HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then begin
ErrorMessage := StrSubstNo(FailedPostRequestErr, RequestUri, '-', '-');
exit(false);
end;
StatusCode := HttpResponseMessage.HttpStatusCode();
if (StatusCode <> 200) and (StatusCode <> 201) then begin
ErrorMessage := StrSubstNo(FailedPostRequestErr, RequestUri, StatusCode, GetHttpErrorMessageAsText(HttpResponseMessage, false));
exit(false);
end;
if HttpResponseMessage.Content.ReadAs(JsonContent) then
if ResponseJsonObject.ReadFrom(JsonContent) then begin
Session.LogMessage('0000J99', CustomerExpSurveyImpl.RemoveUserIdFromMessage(StrSubstNo(PostRequestSuccessfulLbl, RequestUri)), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(true);
end;
ErrorMessage := StrSubstNo(FailedPostRequestErr, RequestUri, StatusCode, '-');
end;
[NonDebuggable]
local procedure GetHttpErrorMessageAsText(var HttpResponseMessage: HttpResponseMessage; IsGraph: Boolean): Text
var
ErrorMessage: Text;
begin
if TryGetErrorMessage(HttpResponseMessage, ErrorMessage, IsGraph) then
exit(ErrorMessage);
end;
[TryFunction]
[NonDebuggable]
local procedure TryGetErrorMessage(var HttpResponseMessage: HttpResponseMessage; var ErrorMessage: Text; IsGraph: Boolean)
var
ResponseJsonText: Text;
JToken: JsonToken;
ResponseJsonObject: JsonObject;
begin
HttpResponseMessage.Content.ReadAs(ResponseJsonText);
ResponseJsonObject.ReadFrom(ResponseJsonText);
if IsGraph then begin
ResponseJsonObject.Get('error', JToken);
JToken.AsObject().Get('message', JToken);
end else
ResponseJsonObject.Get('Message', JToken);
ErrorMessage := JToken.AsValue().AsText();
end;
local procedure Authorize(var HttpHeaders: HttpHeaders; var ErrorMessage: Text; IsGraph: Boolean): Boolean
var
AccessToken: SecretText;
begin
if IsGraph then
AccessToken := AcquireGraphToken(ErrorMessage)
else
AccessToken := AcquireToken(ErrorMessage);
if not AccessToken.IsEmpty() then begin
HttpHeaders.Add('Authorization', SecretStrSubstNo(BearerLbl, AccessToken));
exit(true);
end;
if IsGraph then
Session.LogMessage('0000JC5', CouldNotGetGraphAccessTokenErr, Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok)
else
Session.LogMessage('0000J9A', CouldNotGetAccessTokenErr, Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(false);
end;
local procedure AcquireToken(var ErrorMessage: Text): SecretText
var
OAuth2: Codeunit OAuth2;
Scopes: List of [Text];
ClientId: Text;
ClientCertificate: SecretText;
AccessToken: SecretText;
IdToken: Text;
begin
ClientId := GetClientId();
ClientCertificate := GetClientCertificate();
Scopes.Add(GetScope());
if (ClientId <> '') and (not ClientCertificate.IsEmpty()) then
if OAuth2.AcquireTokensWithCertificate(ClientId, ClientCertificate, GetRedirectURL(), AuthorityLbl, Scopes, AccessToken, IdToken) then begin
Session.LogMessage('0000J9B', AcquiredCESTokenLbl, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(AccessToken);
end;
ErrorMessage := GetLastErrorText();
end;
[NonDebuggable]
local procedure AcquireGraphToken(var ErrorMessage: Text): SecretText
var
OAuth2: Codeunit OAuth2;
CustomerExpSurveyImpl: Codeunit "Customer Exp. Survey Impl.";
Scopes: List of [Text];
AccessToken: SecretText;
begin
if not CustomerExpSurveyImpl.IsPPE() then
Scopes.Add(GraphScopesLbl)
else
Scopes.Add(GraphPPEScopesLbl);
if OAuth2.AcquireOnBehalfOfToken(GetRedirectURL(), Scopes, AccessToken) then begin
Session.LogMessage('0000J9C', AcquiredGraphTokenLbl, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(AccessToken);
end else
ErrorMessage := GetLastErrorText();
end;
[NonDebuggable]
local procedure GetRedirectURL(): Text
var
OAuth2: Codeunit OAuth2;
RedirectURL: Text;
begin
OAuth2.GetDefaultRedirectURL(RedirectURL);
exit(RedirectURL)
end;
[NonDebuggable]
local procedure GetClientId(): Text
var
AzureKeyVault: Codeunit "Azure Key Vault";
ClientId: Text;
begin
if not AzureKeyVault.GetAzureKeyVaultSecret(ClientIdAKVSecretNameLbl, ClientId) then
Session.LogMessage('0000J9D', MissingClientIdOrCertificateTelemetryTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok)
else
exit(ClientId);
end;
[NonDebuggable]
local procedure GetClientCertificate(): SecretText
var
AzureKeyVault: Codeunit "Azure Key Vault";
Certificate: SecretText;
CertificateName: Text;
begin
if not AzureKeyVault.GetAzureKeyVaultSecret(ClientCertificateAKVSecretNameLbl, CertificateName) then begin
Session.LogMessage('0000J9E', MissingClientIdOrCertificateTelemetryTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(Certificate);
end;
if not AzureKeyVault.GetAzureKeyVaultCertificate(CertificateName, Certificate) then
Session.LogMessage('0000J9F', MissingClientIdOrCertificateTelemetryTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
exit(Certificate);
end;
[NonDebuggable]
local procedure GetScope(): Text
var
AzureKeyVault: Codeunit "Azure Key Vault";
Scope: Text;
begin
if not AzureKeyVault.GetAzureKeyVaultSecret(ScopeAKVSecretNameLbl, Scope) then
Session.LogMessage('0000JRJ', MissingScopeTelemetryTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok)
else
exit(Scope);
end;
[InternalEvent(false)]
local procedure OnGetRequest(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text; IsGraph: Boolean; var IsHandled: Boolean)
begin
end;
[InternalEvent(false)]
local procedure OnPostRequest(RequestUri: Text; var ResponseJsonObject: JsonObject; var ErrorMessage: Text; var IsHandled: Boolean)
begin
end;
}
Procedures, 2
| Name | Parameters | Returns | Access | Obsolete |
|---|---|---|---|---|
| TryGet | (Text, var JsonObject, var Text, Boolean) | Boolean | internal | - |
| TryPost | (Text, var JsonObject, var Text) | Boolean | internal | - |
Events, 2
| Kind | Name | Parameters | Obsolete |
|---|---|---|---|
| Internal event | OnGetRequest | (Text, var JsonObject, var Text, Boolean, var Boolean) | - |
| Internal event | OnPostRequest | (Text, var JsonObject, var Text, var Boolean) | - |