Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command Console - New command effectiveAuthorisations for permissions plugin #163

Merged
merged 1 commit into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.javadoc.version}</version>
<configuration>
<!-- if built on a JDK 11, this suppresses issues due to referencing unnamed Java modules -->
<source>8</source>
</configuration>
<executions>
<execution>
<id>attach-javadoc</id>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Displays the l
ootbee-support-tools.command-console.permissions.effectivePermission.description=Checks if a user has a specific permission on a specific node
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Checks all settable permissions on a specific node for a specific user
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Determines the effective set of authorities a user has as would be evaluated during regular permission checks in the core permission service (excluding any higher-level overrides, e.g. as found in Records Management)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible and each parameter is optional. When the user is omitted, the current user will be used by default. When the node is omitted, only the core / global authorities will be collected.

ootbee-support-tools.command-console.subsystems.description=The subsystems plugin provides commands for inspecting / modifying subsystems.
ootbee-support-tools.command-console.subsystems.help.description=Displays the list of commands and their supported arguments within the current plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Zeigt die List
ootbee-support-tools.command-console.permissions.effectivePermission.description=Pr\u00fcft ob ein Nutzer eine bestimmte Berechtigung auf einem bestimmten Knoten besitzt bzw. diese ihm zugewiesen wurde
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Pr\u00fcft f\u00fcr alle vergebbaren Berechtigungen ob ein Nutzer diese auf einem bestimmten Knoten besitzt bzw. diese ihm zugewiesen wurde
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=Die Reihenfolge der Parameterpaare (Schl\u00fcssel <Wert>) ist flexibel
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Ermittelt die effektive Menge der Authorit\u00e4ten (Authority), die f\u00fcr einen Nutzer im Rahmen der allgemeinen Berechtigungspr\u00fcfung \u00fcber den Permission Service ber\u00fccksichtigt werden (dies schlie\u00dft keine Anpassungen auf h\u00f6herer Ebene ein, wie sie z.B. bei Records Management zu finden sind)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=Die Reihenfolge der Parameterpaare (Schl\u00fcssel <Wert>) ist flexibel und alle Parameter sind optional. Wird kein Nutzer angegeben, so wird der aktuell angemeldete Nutzer als Standardwert verwendet. Wird kein Knoten angegeben, so werden nur die allgemeinen / globalen Authorities betrachtet.

ootbee-support-tools.command-console.subsystems.description=Das Plugin 'subsystems' enth\u00e4lt Befehle zur Interaktion mit / Modifikation von Subsystemen.
ootbee-support-tools.command-console.subsystems.help.description=Zeigt die Liste der Befehle des aktuellen Plugins und deren unterst\u00fctzte Parameter an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Displays the l
ootbee-support-tools.command-console.permissions.effectivePermission.description=Checks if a user has a specific permission on a specific node
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Checks all settable permissions on a specific node for a specific user
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Determines the effective set of authorities a user has as would be evaluated during regular permission checks in the core permission service (excluding any higher-level overrides, e.g. as found in Records Management)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible and each parameter is optional. When the user is omitted, the current user will be used by default. When the node is omitted, only the core / global authorities will be collected.

ootbee-support-tools.command-console.subsystems.description=The subsystems plugin provides commands for inspecting / modifying subsystems.
ootbee-support-tools.command-console.subsystems.help.description=Displays the list of commands and their supported arguments within the current plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Muestra la lis
ootbee-support-tools.command-console.permissions.effectivePermission.description=Comprueba si un usuario tiene un permiso concreto sobre un nodo concreto
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Comprueba todos los permisos que pueden ser establecidos sobre un nodo por un usuario concreto
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=El orden de los par\u00E1metros (clave <valor>) es flexible
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Determines the effective set of authorities a user has with as would be evaluated during regular permission checks in the core permission service (excluding any higher-level overrides, e.g. as found in Records Management)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible and each parameter is optional. When the user is omitted, the current user will be used by default. When the node is omitted, only the core / global authorities will be collected.

ootbee-support-tools.command-console.subsystems.description=El plugin de subsistemas provee comandos para inspeccionar o modificar configuraciones de subsistemas.
ootbee-support-tools.command-console.subsystems.help.description=Muestra la lista de comandos y sus argumentos para el plugin actual
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Displays the l
ootbee-support-tools.command-console.permissions.effectivePermission.description=Checks if a user has a specific permission on a specific node
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Checks all settable permissions on a specific node for a specific user
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Determines the effective set of authorities a user has with as would be evaluated during regular permission checks in the core permission service (excluding any higher-level overrides, e.g. as found in Records Management)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible and each parameter is optional. When the user is omitted, the current user will be used by default. When the node is omitted, only the core / global authorities will be collected.

ootbee-support-tools.command-console.subsystems.description=The subsystems plugin provides commands for inspecting / modifying subsystems.
ootbee-support-tools.command-console.subsystems.help.description=Displays the list of commands and their supported arguments within the current plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ ootbee-support-tools.command-console.permissions.help.description=Exibe a lista
ootbee-support-tools.command-console.permissions.effectivePermission.description=Verifica se um usu\u00e1rio tem uma permiss\u00e3o espec\u00edfica em um n\u00f3
ootbee-support-tools.command-console.permissions.effectivePermissions.description=Verifica todas as permiss\u00f5es atribu\u00edveis no no espec\u00edfico para um usu\u00e1rio espec\u00edfico
ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs=A ordem dos pares de par\u00e2metros (chave <valor>) \u00e9 flex\u00edvel
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description=Determines the effective set of authorities a user has with as would be evaluated during regular permission checks in the core permission service (excluding any higher-level overrides, e.g. as found in Records Management)
ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs=The order of parameter pairs (key <value>) is flexible and each parameter is optional. When the user is omitted, the current user will be used by default. When the node is omitted, only the core / global authorities will be collected.

ootbee-support-tools.command-console.subsystems.description=O plugin de subsistemas disponibiliza comandos para inspecionar / modificar subsistemas.
ootbee-support-tools.command-console.subsystems.help.description=Exibe a lista de comandos e os argumentos suportados para o plugin atual
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<url>/ootbee/admin/command-console/permissions/help</url>
<url>/ootbee/admin/command-console/permissions/effectivePermission</url>
<url>/ootbee/admin/command-console/permissions/effectivePermissions</url>
<url>/ootbee/admin/command-console/permissions/effectiveAuthorisations</url>
<family>OOTBee Support Tools</family>
<format default="json">any</format>
<negotiate accept="application/json">json</negotiate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,23 @@ Copyright (C) 2005 - 2020 Alfresco Software Limited.
"",
"effectivePermissions user <userName> node <nodeRef>",
"\t${msg("ootbee-support-tools.command-console.permissions.effectivePermissions.description")}",
"\t${msg("ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs")}"
"\t${msg("ootbee-support-tools.command-console.permissions.effectivePermissions.flexibleParameterPairs")}",
"",
"effectiveAuthorisations user <userName> node <nodeRef>",
"\t${msg("ootbee-support-tools.command-console.permissions.effectiveAuthorisations.description")}",
"\t${msg("ootbee-support-tools.command-console.permissions.effectiveAuthorisations.flexibleParameterPairs")}"
<#break>
<#case "effectivePermission">
<#case "effectivePermissions">
<#list checkedPermissions as checkedPermission>
"${msg("permissionCheck.result", checkedPermission.user, checkedPermission.permission, checkedPermission.node.nodeRef, checkedPermission.node.name, checkedPermission.allowed?string(msg("permissionCheck.allowed"), msg("permissionCheck.denied")))}"<#if checkedPermission_has_next>,</#if>
</#list>
<#break>
<#case "effectiveAuthorisations">
<#list authorisations as authorisation>
"${authorisation}"<#if authorisation_has_next>,</#if>
</#list>
<#break>
</#switch>
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@

/* global json: false */

function getAuthenticationComponent()
{
var ctxt, authenticationComponent;
ctxt = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
authenticationComponent = ctxt.getBean('AuthenticationComponent',
Packages.org.alfresco.repo.security.authentication.AuthenticationComponent);
return authenticationComponent;
}

function getPermissionService()
{
var ctxt, permissionService;
Expand All @@ -32,6 +41,49 @@ function getPermissionService()
return permissionService;
}

function getTenantService()
{
var ctxt, tenantService;
ctxt = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
tenantService = ctxt.getBean('tenantService', Packages.org.alfresco.repo.tenant.TenantService);
return tenantService;
}

function getPermissionServiceImpl()
{
var ctxt, permissionService;
ctxt = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
permissionService = ctxt.getBean('permissionServiceImpl', Packages.org.alfresco.repo.security.permissions.impl.PermissionServiceImpl);
return permissionService;
}

function getEffectiveDynamicAuthorities(node, user)
{
var permissionService, tenantService, permissionServiceClass, dynamicAuthorityField, dynamicAuthorities, effectiveDynamicAuthorities, nodeRef, idx, dynamicAuthority;

permissionService = getPermissionServiceImpl();
tenantService = getTenantService();

permissionServiceClass = Packages.java.lang.Class.forName('org.alfresco.repo.security.permissions.impl.PermissionServiceImpl');
dynamicAuthorityField = permissionServiceClass.getDeclaredField('dynamicAuthorities');
dynamicAuthorityField.setAccessible(true);

dynamicAuthorities = dynamicAuthorityField.get(permissionService);
effectiveDynamicAuthorities = [];

nodeRef = tenantService.getName(node.nodeRef);
for (idx = 0; idx < dynamicAuthorities.size(); idx++)
{
dynamicAuthority = dynamicAuthorities.get(idx);
if (dynamicAuthority.hasAuthority(nodeRef, user))
{
effectiveDynamicAuthorities.push(dynamicAuthority.getAuthority());
}
}

return effectiveDynamicAuthorities;
}

function getAllSettablePermissions(node)
{
var permissions, permissionsArr, permissionsIter;
Expand All @@ -50,19 +102,31 @@ function runAsUser(fn, user)
{
var result;
Packages.org.alfresco.repo.security.authentication.AuthenticationUtil.pushAuthentication();
Packages.org.alfresco.repo.security.authentication.AuthenticationUtil.setRunAsUser(user);
try
{
// use full authentication instead of just runAs - depending on authentication subsystem, this may affect implicitly granted
// authorities
getAuthenticationComponent().setCurrentUser(user,
Packages.org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode.CHECK);

result = fn();

// restore
Packages.org.alfresco.repo.security.authentication.AuthenticationUtil.popAuthentication();
}
catch (e)
{

// restore
Packages.org.alfresco.repo.security.authentication.AuthenticationUtil.popAuthentication();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If popAuth() throws in 115 above deep in the implementation, you could end up trying to popAuth() again. Seems very unlikely, maybe it would be better to move the popAuth into a finally()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, there is no finally supported in the Rhino version used in Alfresco, AFAIK. At least I once tried to use it and failed, so I adopted that pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #169 to track that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, there is no finally supported in the Rhino version used in Alfresco, AFAIK. At least I once tried to use it and failed, so I adopted that pattern.

Weird, I though I used that inside JS Console a couple of times before !

Copy link
Contributor Author

@AFaust AFaust May 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yregaieg Yeah, we were talking during the hackathon Zoom session and I am fully prepared to consider that my state of knowledge on that might be seriously outdated because I never tried again. Don't want to change that on a whim here though and thus created that #169 to do a proper verification.

throw e;

if (e instanceof Packages.org.alfresco.repo.security.authentication.AuthenticationException)
{
status.setCode(status.STATUS_BAD_REQUEST, 'User ' + user + ' does not exist');
}
else
{
throw e;
}
}
return result;
}
Expand Down Expand Up @@ -134,6 +198,90 @@ function executeEffectivePermission(args, settable)
}
}

function executeEffectiveAuthorisations(args)
{
var userArg, nodeArg, argIdx, permissionService, effectiveAuthorisations, authorisations, authIter, dynamicAuthorities, node, authIdx;

for (argIdx = 0; argIdx < args.length; argIdx++)
{
switch (args[argIdx])
{
case 'user':
userArg = (args.length > argIdx + 1) ? args[++argIdx] : null;
break;
case 'node':
nodeArg = (args.length > argIdx + 1) ? args[++argIdx] : null;
break;
}
}

// for some reason, getAuthorisations on the public PermissionService is denied to all (even admin), so we have to use the impl bean
permissionService = getPermissionServiceImpl();
effectiveAuthorisations = {};

if (nodeArg)
{
node = search.findNode(nodeArg);
if (node !== null)
{
if (userArg)
{
runAsUser(function()
{
model.user = userArg;
authorisations = permissionService.getAuthorisations();
dynamicAuthorities = getEffectiveDynamicAuthorities(node, userArg);
}, userArg);
}
else
{
model.user = person.properties.userName;
authorisations = permissionService.getAuthorisations();
dynamicAuthorities = getEffectiveDynamicAuthorities(node, person.properties.userName);
}
}
else
{
status.setCode(status.STATUS_BAD_REQUEST, 'Node ' + nodeArg + ' does not exist');
}
}
else
{
if (userArg)
{
runAsUser(function()
{
model.user = userArg;
authorisations = permissionService.getAuthorisations();
}, userArg);
}
else
{
model.user = person.properties.userName;
authorisations = permissionService.getAuthorisations();
}
}

if (authorisations)
{
authIter = authorisations.iterator();
while (authIter.hasNext())
{
effectiveAuthorisations[authIter.next()] = true;
}
}

if (dynamicAuthorities)
{
for (authIdx = 0; authIdx < dynamicAuthorities.length; authIdx++)
{
effectiveAuthorisations[dynamicAuthorities[authIdx]] = true;
}
}

model.authorisations = Object.keys(effectiveAuthorisations);
}

function main()
{
var service, reqBody, reqArgs, argIdx;
Expand All @@ -160,6 +308,9 @@ function main()
case 'effectivePermissions':
executeEffectivePermission(reqArgs, true);
break;
case 'effectiveAuthorisations':
executeEffectiveAuthorisations(reqArgs);
break;
case 'help': // no-op
break;
default:
Expand Down