Permission-Capability/CapabilitySet mapping algorithm
- Pavel Filippov
Owned by Pavel Filippov
Capabilities are mapped from permissions using the following algorithm
@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 folio-permission-utils {
:read permission mapping overrides from URL
and store it as ""permissionMappingOverrides"";<<input>>
if (""permission"" in ""permissionMappingOverrides"") then (yes)
:read capability by permission name from mappingOverrides;<<input>>
:return PermissionData with (resource, action, type);<<output>>
end;
else (no)
:define DATA_SETTINGS_ACTIONS
""VIEW -> [ "get", "view", "read", "get-all", "read-all", "search" ]""
""CREATE -> [ "post", "create", "write" ]""
""EDIT -> [ "put", "edit", "update", "patch" ]""
""DELETE -> [ "delete", "delete-all" ]""
""MANAGE -> [ "all", "manage", "allops" ]"";<<input>>
:define SETTINGS_KEYWORD
""[ "module", "settings" ]"";<<input>>
:define DATA_KEYWORD_IDENTIFIERS
""[ "item", "collection", "items" ]"";<<input>>
:define DATA_SUFFIXES
""[ ".item.post" ]"""; <<input>>
:define PROCEDURAL_KEYWORDS
""[ "post", "download", "export", "assign", "restore", "approve", "reopen", "start", "unopen", "validate", "resend", "run-jobs", "stop-jobs", "generate", "reset", "test", "import", "cancel", "exportCSV", "showHidden", "updateEncumbrances", "execute", "move" ]"";<<input>>
:split permission name by ""."";<<task>>
:store it as ""permissionParts"";<<output>>
group calculatePermissionType {
if (""permissionParts"" contains any of ""SETTING_KEYWORDS"" \nOR ""permissionName"" start with ""SETTINGS_KEYWORDS"") then (yes)
:define capability/capability set type as ""SETTINGS"";<<output>>
else if (""name"" end with any of ""PROCEDURAL_KEYWORDS""\nAND ""permissionParts"" NOT contains\nany of ""DATA_KEYWORD_IDENTIFIERS"") then (yes)
:define capability/capability set type as ""PROCEDURAL"";<<output>>
else if (""name"" end with any of ""DATA_SUFFIXES"") then (yes)
:define capability/capability set type as ""DATA"";<<output>>
else if (""permissionParts"" contains\n any of ""PROCEDURAL_KEYWORDS"") then (yes)
:define capability/capability set type as ""PROCEDURAL"";<<output>>
else (no)
:define capability/capability set type as ""DATA"";<<output>>
end if
}
group calculatePermissionResourceAndAction {
if (""permissionParts"" size == 1) then (yes)
:define resource as ""null"" and action as ""null"";<<output>>
else (no)
:try resolve action from last part
of ""permissionParts"" using resolved ""type"";<<task>>
:store resolved action as ""action"";<<output>>
if (type is ""PROCEDURAL"") then (yes)
:define resource as substring before action and action as ""EXECUTE""
//""search_index_inventory_reindex.execute"" -> ""Search Index Inventory Reindex | EXECUTE""//
//""ui-inventory.item.move"" -> ""UI-Inventory Item | EXECUTE""//;<<output>>
else if (""action"" is ""null"" AND ""type"" is ""SETTINGS"") then (yes)
:define resource as substring before action and action as ""VIEW""
//""module.circulation-log.enabled"" -> ""Module Circulation-Log Enabled | VIEW""//;<<output>>
else (no)
:define resource as substring before action with resolved action
//""browse_subjects_instances_coll.view"" -> ""Browse Subjects Instances Coll | VIEW""//
//""inventory-storage.items.collection.get"" -> ""Inventory-Storage Items Collection | VIEW""//;<<output>>
end if
end if
}
end if
:return PermissionData with (resource, action, type);<<output>>
end
}
@enduml
The permission mapping overrides are stored in the following format (Mapping-overrides by Eureka )
[
"{sourcePermissionName}": {
"resource": "{expectedCapabilityName}",
"type": "{expectedCapabilityType}",
"action": "{expectedCapabilityAction}"
}
]