blob: f5613c7d69d287b05609f49cb0da040b5a4d5164 [file] [log] [blame]
/*
* Copyright (C) 2010-2011 The University of Manchester
*
* See the file "LICENSE" for license terms.
*/
package org.taverna.server.master.worker;
import static org.taverna.server.master.identity.WorkflowInternalAuthProvider.PREFIX;
import java.net.URI;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.taverna.server.master.common.Roles;
import org.taverna.server.master.common.Workflow;
import org.taverna.server.master.exceptions.NoCreateException;
import org.taverna.server.master.exceptions.NoDestroyException;
import org.taverna.server.master.exceptions.NoUpdateException;
import org.taverna.server.master.interfaces.Policy;
import org.taverna.server.master.interfaces.TavernaRun;
import org.taverna.server.master.interfaces.TavernaSecurityContext;
import org.taverna.server.master.utils.UsernamePrincipal;
/**
* Basic policy implementation that allows any workflow to be instantiated by
* any user, but which does not permit users to access each others workflow
* runs. It also imposes a global limit on the number of workflow runs at once.
*
* @author Donal Fellows
*/
class PolicyImpl implements Policy {
Log log = LogFactory.getLog("Taverna.Server.Worker.Policy");
private PolicyLimits limits;
private RunDBSupport runDB;
@Required
public void setLimits(PolicyLimits limits) {
this.limits = limits;
}
@Required
public void setRunDB(RunDBSupport runDB) {
this.runDB = runDB;
}
@Override
public int getMaxRuns() {
return limits.getMaxRuns();
}
@Override
public Integer getMaxRuns(UsernamePrincipal user) {
return null;
}
@Override
public int getOperatingLimit() {
return limits.getOperatingLimit();
}
@Override
public List<URI> listPermittedWorkflowURIs(UsernamePrincipal user) {
return limits.getPermittedWorkflowURIs();
}
private boolean isSelfAccess(String runId) {
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
boolean self = false;
String id = null;
for (GrantedAuthority a : auth.getAuthorities()) {
String aa = a.getAuthority();
if (aa.equals(Roles.SELF)) {
self = true;
continue;
}
if (!aa.startsWith(PREFIX))
continue;
id = aa.substring(PREFIX.length());
}
return self && runId.equals(id);
}
@Override
public boolean permitAccess(UsernamePrincipal user, TavernaRun run) {
String username = user.getName();
TavernaSecurityContext context = run.getSecurityContext();
if (context.getOwner().getName().equals(username)) {
if (log.isDebugEnabled())
log.debug("granted access by " + user.getName() + " to "
+ run.getId());
return true;
}
if (isSelfAccess(run.getId())) {
if (log.isDebugEnabled())
log.debug("access by workflow to itself: " + run.getId());
return true;
}
if (log.isDebugEnabled())
log.debug("considering access by " + user.getName() + " to "
+ run.getId());
return context.getPermittedReaders().contains(username);
}
@Override
public void permitCreate(UsernamePrincipal user, Workflow workflow)
throws NoCreateException {
if (user == null)
throw new NoCreateException(
"anonymous workflow creation not allowed");
if (runDB.countRuns() >= getMaxRuns())
throw new NoCreateException("server load exceeded; please wait");
}
@Override
public synchronized void permitDestroy(UsernamePrincipal user, TavernaRun run)
throws NoDestroyException {
if (user == null)
throw new NoDestroyException();
String username = user.getName();
TavernaSecurityContext context = run.getSecurityContext();
if (context.getOwner() == null
|| context.getOwner().getName().equals(username))
return;
if (!context.getPermittedDestroyers().contains(username))
throw new NoDestroyException();
}
@Override
public void permitUpdate(UsernamePrincipal user, TavernaRun run)
throws NoUpdateException {
if (user == null)
throw new NoUpdateException(
"workflow run not owned by you and you're not granted access");
TavernaSecurityContext context = run.getSecurityContext();
if (context.getOwner().getName().equals(user.getName()))
return;
if (isSelfAccess(run.getId())) {
if (log.isDebugEnabled())
log.debug("update access by workflow to itself: " + run.getId());
return;
}
if (!context.getPermittedUpdaters().contains(user.getName()))
throw new NoUpdateException(
"workflow run not owned by you and you're not granted access");
}
@Override
public void setPermittedWorkflowURIs(UsernamePrincipal user,
List<URI> permitted) {
limits.setPermittedWorkflowURIs(permitted);
}
}