Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
strawman delegate implementation
  • Loading branch information
acoburn committed Aug 27, 2015
1 parent 6e8d3f2 commit 07fab3a
Showing 1 changed file with 87 additions and 1 deletion.
Expand Up @@ -15,6 +15,17 @@
*/
package org.fcrepo.auth.webac;

// The WEBAC_HAS_ACL variable does not exist (we don't even have a namespace for it yet).
import static org.fcrepo.auth.webac.URIConstants.WEBAC_HAS_ACL;
import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_APPEND;
import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_READ;
import static org.fcrepo.auth.webac.URIConstants.WEBAC_MODE_WRITE;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import javax.jcr.Session;
Expand All @@ -28,6 +39,7 @@
* control lists.
*
* @author Peter Eichman
* @author acoburn
* @since Aug 24, 2015
*/
public class WebACAuthorizationDelegate extends AbstractRolesAuthorizationDelegate {
Expand All @@ -37,10 +49,46 @@ public class WebACAuthorizationDelegate extends AbstractRolesAuthorizationDelega
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebACAuthorizationDelegate.class);

private static final Map<String, URI> actionMap;

static {
Map<String, URI> map = new HashMap<>();
map.put("GET", WEBAC_MODE_READ);
map.put("POST", WEBAC_MODE_APPEND);
map.put("PUT", WEBAC_MODE_WRITE);
map.put("DELETE", WEBAC_MODE_WRITE);
map.put("PATCH", WEBAC_MODE_WRITE);
map.put("OPTIONS", WEBAC_MODE_READ);
actionMap = Collections.unmodifiableMap(map);
}

@Override
public boolean rolesHavePermission(final Session userSession, final String absPath,
final String[] actions, final Set<String> roles) {
final boolean permit = false;

// This is not correct -- we should get it from the container or header, etc
final String agent = userSession.getUserID();

final List<URI> actionURIs = actionsAsURIs(actions);

final Optional<URI> effectiveACL = getEffectiveAcl(new FedoraResourceImpl(userSession.getNode(absPath)));

final AuthorizationHandler authHandler = new AuthorizationHandlerImpl();

This comment has been minimized.

Copy link
@awoods

awoods Aug 27, 2015

Member

The AuthorizationHandler should be injected.


// The getAuthorizations(URI, String, String) signature doesn't exist
final Optional<boolean> userPermission = effectiveACL
.map(x -> authHandler.getAuthorizations(x, absPath, agent))
.map(x -> isPermitted(actionURIs, x));

// The getAuthorizations(URI, String, Set<String>) signature doesn't exist
final Optional<boolean> groupPermission = effectiveACL

This comment has been minimized.

Copy link
@awoods

awoods Aug 27, 2015

Member

Is searching for group-permissions necessary if user-permissions were found?

This comment has been minimized.

Copy link
@acoburn

acoburn Aug 27, 2015

Author Contributor

That's not evaluated unless there are no user-permissions found (lazy evaluation)

This comment has been minimized.

Copy link
@awoods

awoods Aug 27, 2015

Member

Right. nice.

.map(x -> authHandler.getAuthorizations(x, absPath, roles))
.map(x -> isPermitted(actionURIs, x));

final boolean permit = userPermission
.orElse(groupPermission)
.orElse(false);

LOGGER.debug("Request for actions: {}, on path: {}, with roles: {}. Permission={}",
actions,
absPath,
Expand All @@ -50,4 +98,42 @@ public boolean rolesHavePermission(final Session userSession, final String absPa
return permit;
}

/**
* Given a set of WebACAuthorization objects, determine if the given modes are allowed.
*
* NOTE: Its use above should be replaced with a curried version of this function.
*/
private boolean isPermitted(final Set<URI> modes, final Set<WebACAuthorization> acl) {
return acl.stream()
.map(WebACAuthorization::getModes)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList())
.containsAll(modes);
}

/**
* A convenience method for converting an array of actions to a List<URI> structure.
*/
private List<URI> actionsAsUris(final String[] actions) {
final List<URI> uris = new ArrayList<>();
for (final String a : actions) {
uris.add(actionsMap.get(a));
}
return uris;
}

/**
* Find the effective ACL as a URI. It may or may not exist, and it may or may
* not be a fedora resource.
*/
private Optional<URI> getEffectiveAcl(final FedoraResource resource) {
if (resource.hasProperty(WEBAC_HAS_ACL)) {
return Optional<URI>.of(new URI(resource.getProperty(WEBAC_HAS_ACL).getString()));
} else if (resource.getNode().getDepth() == 0) {
return Optional<URI>.empty();
} else {
return getEffectiveAcl(resource.getContainer());
}
}
}

0 comments on commit 07fab3a

Please sign in to comment.