Codeunit 9061 Stor. Serv. Auth. SAS, source in 25
Source242526272829metadata in 25
src/System Application/App/Azure Storage Services Authorization/src/SAS/StorServAuthSAS.Codeunit.al252 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.Azure.Storage;
using System.Utilities;
codeunit 9061 "Stor. Serv. Auth. SAS" implements "Storage Service Authorization"
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
[NonDebuggable]
procedure Authorize(var HttpRequestMessage: HttpRequestMessage; StorageAccount: Text)
var
Uri: Codeunit Uri;
UriBuilder: Codeunit "Uri Builder";
UriText, QueryText : Text;
begin
StorageAccountName := StorageAccount;
UriText := HttpRequestMessage.GetRequestUri();
UriBuilder.Init(UriText);
QueryText := UriBuilder.GetQuery();
QueryText := DelChr(QueryText, '<', '?'); // remove ? from the query
if QueryText <> '' then
QueryText += '&';
QueryText += GetSharedAccessSignature();
UriBuilder.SetQuery(QueryText);
UriBuilder.GetUri(Uri);
HttpRequestMessage.SetRequestUri(Uri.GetAbsoluteUri());
end;
procedure SetStorageAccountName(NewStorageAccountName: Text)
begin
StorageAccountName := NewStorageAccountName;
end;
procedure SetSigningKey(NewSigningKey: SecretText)
begin
SigningKey := NewSigningKey;
end;
procedure SetSignedStart(SignedStart: DateTime)
begin
if SignedStart = 0DT then
SignedStart := CurrentDateTime();
StartDate := SignedStart;
end;
procedure SetSignedExpiry(SignedExpiry: DateTime)
begin
EndDate := SignedExpiry;
end;
procedure SetIPrange(NewIPRange: Text)
begin
IPRange := NewIPRange;
end;
procedure SetSignedEncryptionScope(NewSignedEncryptionScope: Text)
begin
SignedEncryptionScope := NewSignedEncryptionScope;
end;
procedure SetVersion(NewAPIVersion: Enum "Storage Service API Version")
begin
ApiVersion := NewAPIVersion;
end;
procedure SetSignedServices(SignedServices: List of [Enum "SAS Service Type"])
begin
Services := SignedServices;
end;
procedure SetResources(SignedResources: List of [Enum "SAS Resource Type"])
begin
Resources := SignedResources;
end;
procedure SetSignedPermissions(SignedPermissions: List of [Enum "SAS Permission"])
begin
Permissions := SignedPermissions;
end;
procedure SetProtocol(SignedProtocol: Option "https&http",https)
begin
Clear(Protocols);
Protocols.Add('https');
if SignedProtocol = SignedProtocol::"https&http" then
Protocols.Add('http');
end;
[NonDebuggable]
procedure GetSharedAccessSignature(): Text
var
StringToSign: Text;
Signature: Text;
SharedAccessSignature: Text;
begin
StringToSign := CreateSharedAccessSignatureStringToSign();
Signature := AuthFormatHelper.GetAccessKeyHashCode(StringToSign, SigningKey);
SharedAccessSignature := CreateSasUrlString(ApiVersion, StartDate, EndDate, Services, Resources, Permissions, Protocols, IPRange, Signature, SignedEncryptionScope);
exit(SharedAccessSignature);
end;
[NonDebuggable]
local procedure CreateSharedAccessSignatureStringToSign(): Text
var
StringToSign: TextBuilder;
begin
StringToSign.Append(StorageAccountName + NewLine());
StringToSign.Append(PermissionsToString(Permissions) + NewLine());
StringToSign.Append(ServicesToString(Services) + NewLine());
StringToSign.Append(ResourcesToString(Resources) + NewLine());
StringToSign.Append(DateToString(StartDate) + NewLine());
StringToSign.Append(DateToString(EndDate) + NewLine());
StringToSign.Append(IPRange + NewLine());
StringToSign.Append(ProtocolsToString(Protocols) + NewLine());
StringToSign.Append(VersionToString(ApiVersion) + NewLine());
if ApiVersion <> Enum::"Storage Service API Version"::"2020-10-02" then // Must be provided for all versions above 2020-10-02
StringToSign.Append(SignedEncryptionScope + NewLine());
exit(StringToSign.ToText());
end;
local procedure PermissionsToString(SasPermissions: List of [Enum "SAS Permission"]): Text
var
Permission: Enum "SAS Permission";
Builder: TextBuilder;
begin
foreach Permission in Enum::"SAS Permission".Ordinals() do
if SasPermissions.Contains(Permission) then
Builder.Append(Format(Permission));
exit(Builder.ToText());
end;
local procedure ProtocolsToString(ProtocolsList: List of [Text]): Text
var
Protocol: Text;
Builder: TextBuilder;
begin
foreach Protocol in ProtocolsList do begin
if Builder.ToText() <> '' then
Builder.Append(',');
Builder.Append(Protocol)
end;
exit(Builder.ToText());
end;
local procedure ServicesToString(ServiceTypes: List of [Enum "SAS Service Type"]): Text
var
Service: Enum "SAS Service Type";
Builder: TextBuilder;
begin
foreach Service in Enum::"SAS Service Type".Ordinals() do
if ServiceTypes.Contains(Service) then
Builder.Append(Format(Service));
exit(Builder.ToText());
end;
[NonDebuggable]
procedure CreateSasUrlString(StorageServiceApiVersion: Enum "Storage Service API Version"; StartDateTime: DateTime; EndDateTime: DateTime; SasServiceTypes: List of [Enum "SAS Service Type"]; SasResourceTypes: List of [Enum "SAS Resource Type"]; SasPermissions: List of [Enum "SAS Permission"]; ProtocolStrings: List of [Text]; IPRangeString: Text; Signature: Text; SignedEncryptionScopeString: Text): Text
var
Uri: Codeunit Uri;
Builder: TextBuilder;
KeyValueLbl: Label '%1=%2', Comment = '%1 = Key; %2 = Value', Locked = true;
begin
Builder.Append(StrSubstNo(KeyValueLbl, 'sv', VersionToString(StorageServiceApiVersion)));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'ss', ServicesToString(SasServiceTypes)));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'srt', ResourcesToString(SasResourceTypes)));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'sp', PermissionsToString(SasPermissions)));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'se', Uri.EscapeDataString(DateToString(EndDateTime))));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'st', Uri.EscapeDataString(DateToString(StartDateTime))));
Builder.Append('&');
Builder.Append(StrSubstNo(KeyValueLbl, 'spr', ProtocolsToString(ProtocolStrings)));
Builder.Append('&');
if IPRangeString <> '' then begin
Builder.Append(StrSubstNo(KeyValueLbl, 'sip', IPRangeString));
Builder.Append('&');
end;
if SignedEncryptionScopeString <> '' then begin
Builder.Append(StrSubstNo(KeyValueLbl, 'ses', SignedEncryptionScopeString));
Builder.Append('&');
end;
Builder.Append(StrSubstNo(KeyValueLbl, 'sig', Uri.EscapeDataString(Signature)));
exit(Builder.ToText());
end;
local procedure VersionToString(StorageServiceApiVersion: Enum "Storage Service API Version"): Text
begin
exit(Format(StorageServiceApiVersion));
end;
local procedure DateToString(MyDateTime: DateTime): Text
begin
exit(AuthFormatHelper.GetIso8601DateTime(MyDateTime) + 'Z'); // Must be in 'yyyy-MM-ddTHH:mm:ssZ' UTC format
end;
local procedure ResourcesToString(ResourceTypes: List of [Enum "SAS Resource Type"]): Text
var
Resource: Enum "SAS Resource Type";
Builder: TextBuilder;
begin
foreach Resource in Enum::"SAS Resource Type".Ordinals() do
if ResourceTypes.Contains(Resource) then
Builder.Append(Format(Resource));
exit(Builder.ToText());
end;
local procedure NewLine(): Text
begin
exit(AuthFormatHelper.NewLine());
end;
var
AuthFormatHelper: Codeunit "Auth. Format Helper";
[NonDebuggable]
StorageAccountName: Text;
SigningKey: SecretText;
SignedEncryptionScope: Text;
StartDate: DateTime;
EndDate: DateTime;
ApiVersion: Enum "Storage Service API Version";
Services: List of [Enum "SAS Service Type"];
Resources: List of [Enum "SAS Resource Type"];
Permissions: List of [Enum "SAS Permission"];
Protocols: List of [Text];
IPRange: Text;
}