Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

spi-security: Use SudoService.Spi to propagate user/role permissions to an effective user #45

Open
danhaywood opened this issue Oct 13, 2017 · 0 comments

Comments

@danhaywood
Copy link
Contributor

danhaywood commented Oct 13, 2017

from isisaddons-legacy/isis-module-security#48

As introduced in 1.13.2

I tried to implement this at the generic Shiro security mechanism (within Isis core), but realized that actually it needs to be at a deeper level, ie in this module.

The code I sketched out before abandoning was:

@DomainService(nature = NatureOfService.DOMAIN)
public class SudoServiceSpi implements SudoService.Spi {

    @Override
    public void runAs(final String username, final List<String> roles) {
        try {
            final Subject subject = SecurityUtils.getSubject();
            if (subject == null) {
                return;
            }
            // can't set runAs if has no current principals
            if(!hasPrincipals(subject)) {
                return;
            }
            final SimplePrincipalCollection principals = new SimplePrincipalCollection();
            principals.add(new RunAsPrincipal(username, roles), "sudoRealm");
            subject.runAs(principals);
        } catch(UnavailableSecurityManagerException ex) {
            return;
        }
    }

    private boolean hasPrincipals(final Subject subject) {
        return !CollectionUtils.isEmpty(subject.getPrincipals());
    }

    @Override
    public void releaseRunAs() {
        try {
            final Subject subject = SecurityUtils.getSubject();
            if(subject == null) {
                return;
            }
            // can't set runAs if has no current principals
            if(!hasPrincipals(subject) || !subject.isRunAs()) {
                return;
            }
            subject.releaseRunAs();
        } catch (UnavailableSecurityManagerException ex) {
            return;
        }
    }
}

and also:

public class RunAsPrincipal implements AuthorizationInfo {

    private final String username;
    private final List<String> roles;

    public RunAsPrincipal(final String username, final List<String> roles) {
        this.username = username;
        this.roles = roles;
    }

    @Override
    public Collection<String> getRoles() {
        return roles;
    }

    @Override
    public Collection<String> getStringPermissions() {
        return Collections.emptyList();
    }

    @Override
    public Collection<Permission> getObjectPermissions() {
        return Collections.emptyList();
    }
}

Certainly RunAsPrincipal won't be needed; instead use the PrincipalForApplicationUser that already exists.

Also, will need to decide what to do if the specified user doesn't exist in the user; perhaps fall back on the above generic code (meaning no permissions, of course).

@danhaywood danhaywood added this to Backlog - Bugs in incode-platform (project) Oct 13, 2017
@danhaywood danhaywood moved this from Backlog - Bugs to Backlog - Improvement in incode-platform (project) Oct 13, 2017
@danhaywood danhaywood moved this from Backlog - Improvement to Backlog - Feature Requests in incode-platform (project) Oct 13, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
incode-platform (project)
  
Backlog - Feature Requests
Development

No branches or pull requests

1 participant