Codeunit 104060 Upgrade App ID Permissions, source in 29
Source29
src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeAppIDPermissions.Codeunit.al131 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 Microsoft.Upgrade;
using System.Environment;
using System.Environment.Configuration;
using System.Security.AccessControl;
using System.Upgrade;
codeunit 104060 "Upgrade App ID Permissions"
{
Subtype = Upgrade;
var
RenamingFailedTxt: Label 'Failed to rename record of type %1. Error: %2', Locked = true;
DeleteUserGroupPermissionSetTxt: Label 'Deleted User Group Permission Set record because it has empty App ID. Code: %1; Role ID: %2; Scope: %3', Locked = true;
DeleteAccessControlTxt: Label 'Deleted Access Control record because it has empty App ID. User Security ID: %1; Role ID: %2; Company Name: %3; Scope: %4', Locked = true;
TelemetryCategoryTxt: Label 'AL SaaS Upgrade', Locked = true;
trigger OnUpgradePerDatabase()
begin
RunUpgrade();
end;
internal procedure RunUpgrade()
var
UpgradeTag: Codeunit "Upgrade Tag";
UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions";
ServerSettings: Codeunit "Server Setting";
HybridDeployment: Codeunit "Hybrid Deployment";
begin
if not HybridDeployment.VerifyCanStartUpgrade('') then
exit;
if not ServerSettings.GetUsePermissionSetsFromExtensions() then
exit;
if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetUserGroupsSetAppIdUpgradeTag()) then
exit;
SetAppIdOnAccessControl();
SetAppIdOnUserGroupPermissionSet();
UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetUserGroupsSetAppIdUpgradeTag());
end;
local procedure SetAppIdOnAccessControl()
var
AccessControl: Record "Access Control";
AccessControlWithoutAppId: Record "Access Control";
AccessControlWithAppId: Record "Access Control";
AggregatePermissionSet: Record "Aggregate Permission Set";
NullGuid: Guid;
begin
AccessControl.SetRange(Scope, AccessControl.Scope::System);
AccessControl.SetFilter("Role ID", '<>%1&<>%2', 'SECURITY', 'SUPER');
AccessControl.SetRange("App ID", NullGuid);
if AccessControl.FindSet() then
repeat
AggregatePermissionSet.SetRange("Role Id", AccessControl."Role ID");
if AggregatePermissionSet.FindFirst() then begin
// Get the current record to avoid side effects from FindSet()
AccessControlWithoutAppId.Get(AccessControl."User Security ID", AccessControl."Role ID", AccessControl."Company Name", AccessControl.Scope, AccessControl."App ID");
if AccessControlWithAppId.Get(AccessControlWithoutAppId."User Security ID", AccessControlWithoutAppId."Role ID", AccessControlWithoutAppId."Company Name", AccessControlWithoutAppId.Scope, AggregatePermissionSet."App ID") then begin
// In case a record with App ID already exists, delete the one without App ID
if AccessControlWithoutAppId.Delete() then
Session.LogMessage('0000F0C', StrSubstNo(DeleteAccessControlTxt, AccessControlWithoutAppId."User Security ID", AccessControlWithoutAppId."Role ID", AccessControlWithoutAppId."Company Name", AccessControlWithoutAppId.Scope), Verbosity::Normal, DataClassification::EndUserPseudonymousIdentifiers, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryTxt);
end else // Safely add the App ID
if not AccessControlWithoutAppId.Rename(AccessControlWithoutAppId."User Security ID", AccessControlWithoutAppId."Role ID", AccessControlWithoutAppId."Company Name", AccessControlWithoutAppId.Scope, AggregatePermissionSet."App ID") then
Session.LogMessage('0000F0B', StrSubstNo(RenamingFailedTxt, AccessControl.TableName(), GetLastErrorText()), Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryTxt);
end;
until AccessControl.Next() = 0;
end;
local procedure SetAppIdOnUserGroupPermissionSet()
var
UserGroupPermissionSet: Record "User Group Permission Set";
UserGroupPermissionSetWithoutAppId: Record "User Group Permission Set";
UserGroupPermissionSetWithAppId: Record "User Group Permission Set";
UserGroupAccessControl: Record "User Group Access Control";
UserGroupAccessControlWithoutAppId: Record "User Group Access Control";
UserGroupAccessControlWithAppId: Record "User Group Access Control";
AggregatePermissionSet: Record "Aggregate Permission Set";
NullGuid: Guid;
begin
UserGroupPermissionSet.SetRange(Scope, UserGroupPermissionSet.Scope::System);
UserGroupPermissionSet.SetFilter("Role ID", '<>%1&<>%2', 'SECURITY', 'SUPER');
UserGroupPermissionSet.SetRange("App ID", NullGuid);
if UserGroupPermissionSet.FindSet() then
repeat
AggregatePermissionSet.SetRange("Role Id", UserGroupPermissionSet."Role ID");
if AggregatePermissionSet.FindFirst() then begin
// Get the current record to avoid side effects from FindSet()
UserGroupPermissionSetWithoutAppId.Get(UserGroupPermissionSet."User Group Code", UserGroupPermissionSet."Role ID", UserGroupPermissionSet.Scope, UserGroupPermissionSet."App ID");
if UserGroupPermissionSetWithAppId.Get(UserGroupPermissionSetWithoutAppId."User Group Code", UserGroupPermissionSetWithoutAppId."Role ID", UserGroupPermissionSetWithoutAppId.Scope, AggregatePermissionSet."App ID") then begin
// In case a record with App ID already exists, delete the one without App ID
if UserGroupPermissionSetWithoutAppId.Delete() then
Session.LogMessage('0000F0E', StrSubstNo(DeleteUserGroupPermissionSetTxt, UserGroupPermissionSetWithoutAppId."User Group Code", UserGroupPermissionSetWithoutAppId."Role ID", UserGroupPermissionSetWithoutAppId.Scope), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryTxt);
end else // Safely add the App ID
if not UserGroupPermissionSetWithoutAppId.Rename(UserGroupPermissionSetWithoutAppId."User Group Code", UserGroupPermissionSetWithoutAppId."Role ID", UserGroupPermissionSetWithoutAppId.Scope, AggregatePermissionSet."App ID") then
Session.LogMessage('0000F0D', StrSubstNo(RenamingFailedTxt, UserGroupPermissionSet.TableName(), GetLastErrorText()), Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryTxt);
end;
until UserGroupPermissionSet.Next() = 0;
// User Group Access Control needs to be updated explicitly in v25+
UserGroupAccessControl.SetRange(Scope, UserGroupAccessControl.Scope::System);
UserGroupAccessControl.SetFilter("Role ID", '<>%1&<>%2', 'SECURITY', 'SUPER');
UserGroupAccessControl.SetRange("App ID", NullGuid);
if UserGroupAccessControl.FindSet() then
repeat
AggregatePermissionSet.SetRange("Role Id", UserGroupAccessControl."Role ID");
if AggregatePermissionSet.FindFirst() then begin
UserGroupAccessControlWithoutAppId.GetBySystemId(UserGroupAccessControl.SystemId);
if UserGroupAccessControlWithAppId.Get(UserGroupAccessControlWithoutAppId."User Group Code", UserGroupAccessControlWithoutAppId."User Security ID", UserGroupAccessControlWithoutAppId."Role ID", UserGroupAccessControlWithoutAppId."Company Name", UserGroupAccessControlWithoutAppId.Scope, AggregatePermissionSet."App ID") then
UserGroupAccessControlWithoutAppId.Delete()
else
UserGroupAccessControlWithoutAppId.Rename(UserGroupAccessControlWithoutAppId."User Group Code", UserGroupAccessControlWithoutAppId."User Security ID", UserGroupAccessControlWithoutAppId."Role ID", UserGroupAccessControlWithoutAppId."Company Name", UserGroupAccessControlWithoutAppId.Scope, AggregatePermissionSet."App ID");
end;
until UserGroupAccessControl.Next() = 0;
end;
}