Skip to end of banner
Go to start of banner

User permissions migration

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Current »

image-20241016-142207.png
 PlantUML script
@startuml

!theme mono
!pragma useVerticalIf on
skinparam conditionStyle inside
skinparam defaultTextAlignment center
skinparam defaultFontSize 12

<style>
activityDiagram {
  activity {
    MaximumWidth 600
    backgroundColor #f0f0f0
    LineColor DimGrey
  }

  diamond {
    HorizontalAlignment center
  }

  group {
    LineColor LightGrey
    FontSize 10
  }
}
</style>


start
group PermissionMigrationService.migratePermissions {
  :log that migration started;<<task>>

  group UserPermissionsLoader.loadUserPermissions {
    :load all users from Keycloak

    //users loaded in batches, size is controlled by configuration properties//;<<task>>

    :extract user ids from loaded keycloak users and store it as ""userIds""

    //Folio user id is stored as ""user_id"" attribute in KeycloakUser entity//;<<input>>

    :create an empty list with user permissions
    as ""List<UserPermission> userPermissionsData"";

    while (""userIds"" has next element) is (yes)
      :get next user id from ""users"";

      :load user permissions from ""mod-permissions"" by ""userId"" as ""userPermissions""

      //""/users/{userId}/permissions"" endpoint is used//;<<input>>

      :extract permission names from ""userPermissions"" as ""permissionNames"";<<task>>
      if (""permissionNames"" is empty) then (yes)
        :log that user has no permissions;<<output>>
      else (no)
        :remove duplicates from ""permissionNames"" and store it as ""uniquePermissionNames"";<<task>>
        :sort alphabetically ""uniquePermissionNames"" as ""sortedUniquePermissionNames"";<<task>>
        :concatenate ""sortedUniquePermissionNames"" using delimiter ""'|'"" as ""concatenatedPermissionString"";<<task>>
        :generate ""roleName"" as sha1 hash from ""concatenatedPermissionString"";<<task>>
        :create ""userPermissionsValue"" from ""userId"", ""roleName"", ""uniquePermissionNames"";<<task>>
        :add ""userPermissionsValue"" to ""userPermissionsData"" list;<<output>>
      end if

    end while (no)

    :return ""userPermissionsData"";<<output>>
  }

  group MigrationRoleCreator.createRoles {
    :extract unique role names from ""userPermissionsData"" as ""uniqueRoleNames"";<<input>>
    :create roles using ""RoleService"" batch API as ""createdRoles"";<<task>>
    if (""createdRoles"" size is equal to ""uniqueRoleNames"" size) then (yes)
      :return ""createdRoles"";<<output>>
    else (no)
      :retrieve roles by ""uniqueRoleNames""
      from ""RoleService"" as ""foundRoles"";<<output>>
      :return ""foundRoles"" as ""createdRoles"";<<output>>
    end if
  }

  group validateAndGetUserPermissionsWithRoles {
    :group ""createdRoles"" by ""roleName"" as ""createdRolesByName"";<<task>>
    :for each value in ""userPermissionsData"" retrieve role object by ""roleName"" from ""createdRolesByName"";<<task>>
    if (all roles are not found by all ""roleNames"") then (yes)
      :thrown MigrationException;<<output>>
      end
    else (no)
      :return updated ""userPermissionsData"";<<output>>
    end if
  }

  group MigrationRoleCreator.assignUsers {
    :group users by ""roleName""
    as map where key = role identifier and value is a collection of user ids

    //""userId"" and generated ""roleName"" are extracted from ""userPermissionsData"";
    :create a user-role relation for each ""Pair(userId, roleId)"" in ""UserRoleService"";

    if (errors occurred during user-role relation assignment) then (yes)
      :thrown MigrationException;<<output>>
      end
    else (no)
      :log the number of created user-role relations;<<output>>
    end if
  }

  group RolePermissionAssignor.assignPermissions {
    :define a set with visited role identifiers as ""visitedRoleIds"";<<task>>
    while (""userPermissionsData"" has next value) is (yes)
      :get next ""userPermissions"" from ""userPermissionsData"";<<input>>
      :get role id as ""roleId"" from ""userPermissions"";<<input>>
      if (""visitedRoleIds"" contains ""roleId"") then (no)
        :get list of permission names as ""permissions"" from ""userPermissions"";<<input>>
        :find capabilities as ""foundCapabilities"" by ""permissions"" using ""CapabilityService"";<<task>>
        :extract ""capabilityPermissionNames"" from ""foundCapabilities"";<<task>>
        :define ""notFoundPermissions"" as difference between ""permissions"" and ""capabilityPermissionNames"";<<input>>
        if (""foundCapabilities"" collection is not empty) then (yes)
          :assign ""foundCapabilities"" to a role with ""roleId"";<<task>>
        end if

        :find capability sets as ""foundCapabilitySets"" by ""permissions"" using ""CapabilitySetService"";<<task>>
        :extract ""capabilitySetPermissionNames"" from ""foundCapabilitySets"";<<task>>
        :define ""notFoundPermissionsInSets"" as difference between ""notFoundPermissions"" and ""capabilitySetPermissionNames"";<<input>>

        if (""foundCapabilitySets"" collection is not empty) then (yes)
          :assign ""foundCapabilitySets"" to a role with ""roleId"";<<task>>
        end if

        :log assigned permissions for role with ""roleId"";<<output>>
        if (""notFoundPermissionsInSets"" collection is not empty) then (yes)
          :[warn] log ""notFoundPermissionsInSets"" were not assigned for role with ""roleId"";<<output>>
        end if
      else (yes)
      end if
    end while
  }

  :log that migration finished;<<task>>
}

end

@enduml
  • No labels