Skip to end of banner
Go to start of banner

Link management between Capabilities/CapabilitySets and Users/Roles

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 6 Current »

Overview

This page describes algorithms that are used to assign capabilities to a user and role, capability sets to a user, and role.

Capability Relation Management

Role

Capability assignment process

safeCreate flag is used only internally, for outside requests a user must always assign a set of new capability ids, if not - an update operation allows the creation and delete capabilities in a single request

role-capability-assigment-20241014-152818.png

 Role-Capability assignment PlantUML
@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>

group RoleCapabilityServiceImpl {
  :get role by id;<<input>>
  :get ""roleCapabilities"" by ""roleId"";<<task>>
  :extract existing ""capabilityIds"" from ""roleCapabilities"";<<task>>
  if (not ""safeCreate"" AND ""capabilityIds"" not empty)) then (yes)
    :throw EntityExistsException;<<output>>
    end
  else (no)
    :get difference between new and existing ""capabilityIds"" sets as ""newCapabilityIds"";<<input>>
  end if

  group assignCapabilities {
    :get assigned capabilities through capability sets as ""assignedCapabilityIds"";<<input>>

    :store union of ""assignedCapabilityIds"" and ""newCapabilityIds"" as ""assignedCapabilityIds"";<<input>>

    group #LightSteelBlue CapabilityEndpointService.getByCapabilityIds {
      :get difference with ""newCapabilityIds"" and ""assignedCapabilityIds"" as ""changedIdentifiers"";<<input>>

      :get changed capability endpoints by querying capabilities by ""changedIdentifiers""
      and extracting distinct list of assigned endpoints and store it as ""changedCapabilityEndpoints"";<<task>>

      :get assigned capability endpoints by querying capabilities by ""assignedIds""
      and extracting distinct list of assigned endpoints and store it as ""assignedCapabilityEndpoints"";<<task>>

      :return subtraction ""assignedCapabilityEndpoints"" from ""changedCapabilityEndpoints"";<<output>>
    }

    :rolePermissionsService.createPermissions for ""roleId"" and ""endpoints"";<<task>>

    group #LightSteelBlue CapabilityEndpointService.getByCapabilityIds {
      if (""endpoints"" are empty) then (yes)
        :do nothing;<<output>>
      else (no)
        :get role by ""roleId"";<<input>>
        :generate policy name for ""role"";<<input>>
        :getOrCreate role policy by name
        //Policy name template:// ""Policy for role: {{roleId}}"";<<task>>

        :create permissions in Keycloak with role policy, list of endpoint and using permissionNameGenerator

        //Permission name template:// ""{{httpMethod}} access for role '{{roleId}}' to '{{path}}'"";
      end if
    }

    :generate RoleCapabilityEntity for ""newIds"" and store them as ""entities"";<<task>>
    :upsert entities to table ""role_capability"" in database;<<output>>
    :convert ""RoleCapabilityEntity"" to ""RoleCapability"" and return them as ""PageResult"";<<output>>
  }
}

@enduml

Capability remove process

role-capability-remove-20241014-153718.png
 Role-Capability removal process PlantUML
@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>

group UserCapabilityServiceImpl {
  :get existing ""userCapabilities"" by ""userId"";<<task>>
  :extract existing ""capabilityIds"" from ""userCapabilities"";<<task>>

  if (not ""safeCreate"" AND ""capabilityIds"" not empty)) then (yes)
    :do nothing;<<output>>
    end
  else (no)
    :get intersection between ""capabilityIds"" and existing ""capabilityIds"" sets as ""deprecatedIds"";<<input>>
    :get subtraction between ""assignedCapabilityIds"" and existing ""deprecatedIds"" sets as ""assignedIds"";<<input>>
  end if

  group removeCapabilities {
    :get assigned capabilities through capability sets as ""assignedCapabilityIds"";<<input>>
    :store union of ""assignedCapabilityIds"" and ""assignedIds"" as ""assignedCapabilityIds"";<<task>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      :get difference with ""deprecatedIds"" and ""assignedIds"" as ""changedIdentifiers"";<<input>>

      :get changed capability endpoints by querying capabilities by ""changedIdentifiers""
      and extracting distinct list of assigned endpoints and store it as ""changedCapabilityEndpoints"";<<task>>

      :get assigned capability endpoints by querying capabilities by ""assignedIds""
      and extracting distinct list of assigned endpoints and store it as ""assignedCapabilityEndpoints"";<<task>>

      :return subtraction ""assignedCapabilityEndpoints"" from ""changedCapabilityEndpoints"";<<output>>
    }

    :userPermissionsService.deletePermissions for ""userId"" and ""endpoints"";<<task>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      if (""endpoints"" are empty) then (yes)
        :do nothing;<<output>>
      else (no)
        :get keycloak user by ""userId"";<<input>>
        :generate policy name for ""user"";<<input>>
        :get policy by ""name"" and type == ""USER"";<<task>>

        :delete permissions in Keycloak with user policy, list of endpoint and using permissionNameGenerator

        //Permission name template:// ""{{httpMethod}} access for user '{{userId}}' to '{{path}}'"";
      end if
    }


    :delete entities from table ""user_capability"" in database by ""userId"" and ""deprecatedIds"";<<output>>
  }
}

@enduml

Capability update process

A capability update process is a combination of capability assignment and capability remove processes, where unmodified capabilities and corresponding keycloak permissions remain intact.

User

Capability assignment process

safeCreate flag is used only internally, for outside requests a user must always assign a set of new capability ids, if not - an update operation allows the creation and delete capabilities in a single request

user-capability-assigment-20241014-152842.png
 User-Capability assignment PlantUML
@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>

group UserCapabilityServiceImpl {
  :create keycloakUser If not exists by calling ""mod-users-keycloak"" API;<<task>>
  :extract existing ""capabilityIds"" from ""userCapabilities"";<<task>>
  if (not ""safeCreate"" AND ""capabilityIds"" not empty)) then (yes)
    :throw EntityExistsException;<<output>>
    end
  else (no)
    :get difference between new and existing ""capabilityIds"" sets as ""newCapabilityIds"";<<input>>
  end if

  group assignCapabilities {
    :get assigned capabilities through capability sets as ""assignedCapabilityIds"";<<input>>

    :store union of ""assignedCapabilityIds"" and ""newCapabilityIds"" as ""assignedCapabilityIds"";<<input>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      :get difference with ""newCapabilityIds"" and ""assignedCapabilityIds"" as ""changedIdentifiers"";<<input>>

      :get changed capability endpoints by querying capabilities by ""changedIdentifiers""
      and extracting distinct list of assigned endpoints and store it as ""changedCapabilityEndpoints"";<<task>>

      :get assigned capability endpoints by querying capabilities by ""assignedIds""
      and extracting distinct list of assigned endpoints and store it as ""assignedCapabilityEndpoints"";<<task>>

      :return subtraction ""assignedCapabilityEndpoints"" from ""changedCapabilityEndpoints"";<<output>>
    }

    :userPermissionsService.createPermissions for ""userId"" and ""endpoints"";<<task>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      if (""endpoints"" are empty) then (yes)
        :do nothing;<<output>>
      else (no)
        :get keycloak user by Folio ""userId"";<<input>>
        :generate policy name for ""user"";<<input>>
        :getOrCreate user policy by name
        //Policy name template:// ""Policy for user: {{userId}}"";<<task>>

        :create permissions in Keycloak with user policy, list of endpoint and using permissionNameGenerator

        //Permission name template:// ""{{httpMethod}} access for user '{{userId}}' to '{{path}}'"";
      end if
    }

    :generate UserCapabilityEntity for ""newIds"" and store them as ""entities"";<<task>>
    :upsert entities to table ""user_capability"" in database;<<output>>
    :convert ""UserCapabilityEntity"" to ""UserCapability"" and return them as ""PageResult"";<<output>>
  }
}

@enduml

Capability removal process

user-capability-remove-20241014-160359.png
 Capability removal process from a user process PlantUML
@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>

group UserCapabilityServiceImpl {
  :get existing ""userCapabilities"" by ""userId"";<<task>>
  :extract existing ""capabilityIds"" from ""userCapabilities"";<<task>>

  if (not ""safeCreate"" AND ""capabilityIds"" not empty)) then (yes)
    :do nothing;<<output>>
    end
  else (no)
    :get intersection between ""capabilityIds"" and existing ""capabilityIds"" sets as ""deprecatedIds"";<<input>>
    :get subtraction between ""assignedCapabilityIds"" and existing ""deprecatedIds"" sets as ""assignedIds"";<<input>>
  end if

  group removeCapabilities {
    :get assigned capabilities through capability sets as ""assignedCapabilityIds"";<<input>>
    :store union of ""assignedCapabilityIds"" and ""assignedIds"" as ""assignedCapabilityIds"";<<task>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      :get difference with ""deprecatedIds"" and ""assignedIds"" as ""changedIdentifiers"";<<input>>

      :get changed capability endpoints by querying capabilities by ""changedIdentifiers""
      and extracting distinct list of assigned endpoints and store it as ""changedCapabilityEndpoints"";<<task>>

      :get assigned capability endpoints by querying capabilities by ""assignedIds""
      and extracting distinct list of assigned endpoints and store it as ""assignedCapabilityEndpoints"";<<task>>

      :return subtraction ""assignedCapabilityEndpoints"" from ""changedCapabilityEndpoints"";<<output>>
    }

    :userPermissionsService.deletePermissions for ""userId"" and ""endpoints"";<<task>>

    group #PaleGreen CapabilityEndpointService.getByCapabilityIds {
      if (""endpoints"" are empty) then (yes)
        :do nothing;<<output>>
      else (no)
        :get keycloak user by ""userId"";<<input>>
        :generate policy name for ""user"";<<input>>
        :get policy by ""name"" and type == ""USER"";<<task>>

        :delete permissions in Keycloak with user policy, list of endpoint and using permissionNameGenerator

        //Permission name template:// ""{{httpMethod}} access for user '{{userId}}' to '{{path}}'"";
      end if
    }


    :delete entities from table ""user_capability"" in database by ""userId"" and ""deprecatedIds"";<<output>>
  }
}

@enduml

Capability update process

A capability update process is a combination of capability assignment and capability remove processes, where unmodified capabilities and corresponding keycloak permissions remain intact.

  • No labels