diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/ArrayIdentifierBundle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/ArrayIdentifierBundle.java index 8686c54be..d0ca09e12 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/ArrayIdentifierBundle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/ArrayIdentifierBundle.java @@ -3,12 +3,19 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; /** - * Most common implementation of a List of Identifiers (IdentifierBundle). - * @author bdc34 - * + * Most common implementation of a List of Identifiers (IdentifierBundle). */ -public class ArrayIdentifierBundle extends ArrayList implements IdentifierBundle{ - +public class ArrayIdentifierBundle extends ArrayList implements + IdentifierBundle { + public ArrayIdentifierBundle(Collection ids) { + super(ids); + } + + public ArrayIdentifierBundle(Identifier... ids) { + this(Arrays.asList(ids)); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/CommonIdentifierBundleFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/CommonIdentifierBundleFactory.java deleted file mode 100644 index 44da8b360..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/CommonIdentifierBundleFactory.java +++ /dev/null @@ -1,211 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.identifier.common; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vedit.beans.LoginStatusBean; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; -import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; -import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; - -/** - * Create Identifiers that are recognized by the common policy family. - */ -public class CommonIdentifierBundleFactory implements IdentifierBundleFactory { - private static final Log log = LogFactory - .getLog(CommonIdentifierBundleFactory.class); - - private final ServletContext context; - - public CommonIdentifierBundleFactory(ServletContext context) { - this.context = context; - } - - @Override - public IdentifierBundle getIdentifierBundle(ServletRequest request, - HttpSession session, ServletContext unusedContext) { - - // If this is not an HttpServletRequest, we might as well fail now. - HttpServletRequest req = (HttpServletRequest) request; - - ArrayIdentifierBundle bundle = new ArrayIdentifierBundle(); - - bundle.addAll(createUserIdentifiers(req)); - bundle.addAll(createRootUserIdentifiers(req)); - bundle.addAll(createRoleLevelIdentifiers(req)); - bundle.addAll(createBlacklistOrAssociatedIndividualIdentifiers(req)); - bundle.addAll(createExplicitProxyEditingIdentifiers(req)); - bundle.addAll(createPermissionIdentifiers(req)); - - return bundle; - } - - /** - * If the user is logged in, create an identifier that shows his URI. - */ - private Collection createUserIdentifiers( - HttpServletRequest req) { - LoginStatusBean bean = LoginStatusBean.getBean(req); - if (bean.isLoggedIn()) { - return Collections.singleton(new IsUser(bean.getUserURI())); - } else { - return Collections.emptySet(); - } - } - - private Collection createRootUserIdentifiers( - HttpServletRequest req) { - UserAccount user = LoginStatusBean.getCurrentUser(req); - if ((user != null) && user.isRootUser()) { - return Collections.singleton(new IsRootUser()); - } else { - return Collections.emptySet(); - } - } - - /** - * Create an identifier that shows the role level of the current user, or - * PUBLIC if the user is not logged in. - */ - private Collection createRoleLevelIdentifiers( - HttpServletRequest req) { - RoleLevel roleLevel = RoleLevel.getRoleFromLoginStatus(req); - return Collections.singleton(new HasRoleLevel(roleLevel)); - } - - /** - * Find all of the individuals that are associated with the current user, - * and create either an IsBlacklisted or HasAssociatedIndividual for each - * one. - */ - private Collection createBlacklistOrAssociatedIndividualIdentifiers( - HttpServletRequest req) { - Collection ids = new ArrayList(); - - for (Individual ind : getAssociatedIndividuals(req)) { - // If they are blacklisted, this factory will return an identifier - Identifier id = IsBlacklisted.getInstance(ind, context); - if (id != null) { - ids.add(id); - } else { - ids.add(new HasProfile(ind.getURI())); - } - } - - return ids; - } - - /** - * Get all Individuals associated with the current user as SELF. - */ - private Collection getAssociatedIndividuals( - HttpServletRequest req) { - Collection individuals = new ArrayList(); - - UserAccount user = LoginStatusBean.getCurrentUser(req); - if (user == null) { - log.debug("No Associated Individuals: not logged in."); - return individuals; - } - - WebappDaoFactory wdf = (WebappDaoFactory) context - .getAttribute("webappDaoFactory"); - if (wdf == null) { - log.error("Could not get a WebappDaoFactory from the ServletContext"); - return individuals; - } - - IndividualDao indDao = wdf.getIndividualDao(); - - SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req); - individuals.addAll(sec.getAssociatedIndividuals(indDao, user)); - - return individuals; - } - - /** - * Get all Individuals associated with the current user by explicit proxy - * relationship. - */ - private Collection createExplicitProxyEditingIdentifiers( - HttpServletRequest req) { - Collection ids = new ArrayList(); - - UserAccount user = LoginStatusBean.getCurrentUser(req); - if (user != null) { - for (String proxiedUri : user.getProxiedIndividualUris()) { - ids.add(new HasProxyEditingRights(proxiedUri)); - } - } - - return ids; - } - - /** - * Create an identifier for each Permission that the User has. - */ - private Collection createPermissionIdentifiers( - HttpServletRequest req) { - Collection ids = new ArrayList(); - - UserAccount user = LoginStatusBean.getCurrentUser(req); - if (user == null) { - log.debug("No Permissions: not logged in."); - return ids; - } - - WebappDaoFactory wdf = (WebappDaoFactory) context - .getAttribute("webappDaoFactory"); - if (wdf == null) { - log.error("Could not get a WebappDaoFactory from the ServletContext"); - return ids; - } - - Set permissionUris = new HashSet(); - UserAccountsDao uaDao = wdf.getUserAccountsDao(); - for (String psUri: user.getPermissionSetUris()) { - PermissionSet ps = uaDao.getPermissionSetByUri(psUri); - if (ps != null) { - permissionUris.addAll(ps.getPermissionUris()); - } - } - - PermissionRegistry registry = PermissionRegistry.getRegistry(context); - for (String permissionUri: permissionUris) { - Permission permission = registry.getPermission(permissionUri); - ids.add(new HasPermission(permission)); - } - - return ids; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " - " + hashCode(); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java index 9621842b0..11de68c9b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java @@ -14,7 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; * The current user has this Permission, through one or more PermissionSets. */ public class HasPermission extends AbstractCommonIdentifier implements - Identifier { + Identifier, Comparable { public static Collection getIdentifiers(IdentifierBundle ids) { return getIdentifiersForClass(ids, HasPermission.class); } @@ -27,9 +27,12 @@ public class HasPermission extends AbstractCommonIdentifier implements return set; } - private final Permission permission; + private final Permission permission; // never null public HasPermission(Permission permission) { + if (permission == null) { + throw new NullPointerException("permission may not be null."); + } this.permission = permission; } @@ -41,4 +44,29 @@ public class HasPermission extends AbstractCommonIdentifier implements public String toString() { return "HasPermission[" + permission + "]"; } + + @Override + public int hashCode() { + return permission.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof HasPermission)) { + return false; + } + HasPermission that = (HasPermission) obj; + return this.permission.equals(that.permission); + } + + @Override + public int compareTo(HasPermission that) { + return this.permission.compareTo(that.permission); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsRootUser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsRootUser.java index a41c2ab04..01c47322e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsRootUser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsRootUser.java @@ -9,10 +9,17 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; * The current user is a root user. */ public class IsRootUser extends AbstractCommonIdentifier implements Identifier { + public static final IsRootUser INSTANCE = new IsRootUser(); + public static boolean isRootUser(IdentifierBundle ids) { return !getIdentifiersForClass(ids, IsRootUser.class).isEmpty(); } - + + /** Enforce the singleton pattern. */ + private IsRootUser() { + // Nothing to initialize. + } + @Override public String toString() { return "IsRootUser"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsUser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsUser.java index 635069a80..220e814af 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsUser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsUser.java @@ -25,9 +25,13 @@ public class IsUser extends AbstractCommonIdentifier implements Identifier { return set; } - private final String uri; + private final String uri; // never null public IsUser(String uri) { + if (uri == null) { + throw new NullPointerException("uri may not be null."); + } + this.uri = uri; } @@ -35,6 +39,26 @@ public class IsUser extends AbstractCommonIdentifier implements Identifier { return uri; } + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof IsUser)) { + return false; + } + IsUser that = (IsUser) obj; + return this.uri.equals(that.uri); + } + @Override public String toString() { return "IsUser[" + uri + "]"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java new file mode 100644 index 000000000..592242f3f --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java @@ -0,0 +1,66 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; + +/** + * Some fields and methods that are helpful to IdentifierBundleFactory classes. + */ +public abstract class BaseIdentifierBundleFactory implements + IdentifierBundleFactory { + protected final ServletContext ctx; + protected final WebappDaoFactory wdf; + protected final UserAccountsDao uaDao; + protected final IndividualDao indDao; + + public BaseIdentifierBundleFactory(ServletContext ctx) { + if (ctx == null) { + throw new NullPointerException("ctx may not be null."); + } + this.ctx = ctx; + + Object wdfObject = ctx.getAttribute("webappDaoFactory"); + if (wdfObject instanceof WebappDaoFactory) { + this.wdf = (WebappDaoFactory) wdfObject; + } else { + throw new IllegalStateException( + "Didn't find a WebappDaoFactory in the context. Found '" + + wdfObject + "' instead."); + } + + this.uaDao = wdf.getUserAccountsDao(); + this.indDao = wdf.getIndividualDao(); + } + + /** + * This method should go away. Why are we passing anything other than the + * request? + */ + @Override + public final IdentifierBundle getIdentifierBundle(ServletRequest request, + HttpSession session, ServletContext context) { + return getIdentifierBundle((HttpServletRequest) request); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + " - " + hashCode(); + } + + /** + * Return the IdentifierBundle from this factory. May return an empty + * bundle, but never returns null. + */ + public abstract IdentifierBundle getIdentifierBundle(HttpServletRequest req); + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java new file mode 100644 index 000000000..913132d44 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java @@ -0,0 +1,93 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Figure out what Permissions the user is entitled to have. + */ +public class HasPermissionFactory extends BaseIdentifierBundleFactory { + private static final Log log = LogFactory + .getLog(HasPermissionFactory.class); + + public HasPermissionFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + UserAccount user = LoginStatusBean.getCurrentUser(req); + if (user == null) { + return createPublicPermissions(); + } else { + return createUserPermissions(user); + } + } + + private IdentifierBundle createPublicPermissions() { + Set permissionUris = new HashSet(); + for (PermissionSet ps : uaDao.getAllPermissionSets()) { + if (ps.isForPublic()) { + permissionUris.addAll(ps.getPermissionUris()); + } + } + log.debug("Permission URIs: " + permissionUris); + + return new ArrayIdentifierBundle( + getIdentifiersFromPermissions(getPermissionsForUris(permissionUris))); + } + + private IdentifierBundle createUserPermissions(UserAccount user) { + Set permissionUris = new HashSet(); + for (String psUri : user.getPermissionSetUris()) { + PermissionSet ps = uaDao.getPermissionSetByUri(psUri); + if (ps != null) { + permissionUris.addAll(ps.getPermissionUris()); + } + } + log.debug("user permission sets: " + user.getPermissionSetUris()); + log.debug("Permission URIs: " + permissionUris); + + return new ArrayIdentifierBundle( + getIdentifiersFromPermissions(getPermissionsForUris(permissionUris))); + } + + private Collection getPermissionsForUris( + Collection permissionUris) { + List permissions = new ArrayList(); + PermissionRegistry registry = PermissionRegistry.getRegistry(ctx); + for (String uri : permissionUris) { + permissions.add(registry.getPermission(uri)); + } + return permissions; + } + + private List getIdentifiersFromPermissions( + Collection permissions) { + List ids = new ArrayList(); + for (Permission permission : permissions) { + ids.add(new HasPermission(permission)); + } + return ids; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java new file mode 100644 index 000000000..b4280960b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java @@ -0,0 +1,72 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProfile; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsBlacklisted; +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Find all of the individuals that are associated with the current user, and + * create either an IsBlacklisted or HasAssociatedIndividual for each one. + */ +public class HasProfileOrIsBlacklistedFactory extends + BaseIdentifierBundleFactory { + private static final Log log = LogFactory + .getLog(HasProfileOrIsBlacklistedFactory.class); + + public HasProfileOrIsBlacklistedFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + ArrayIdentifierBundle ids = new ArrayIdentifierBundle(); + + for (Individual ind : getAssociatedIndividuals(req)) { + // If they are blacklisted, this factory will return an identifier + Identifier id = IsBlacklisted.getInstance(ind, ctx); + if (id != null) { + ids.add(id); + } else { + ids.add(new HasProfile(ind.getURI())); + } + } + + return ids; + } + + /** + * Get all Individuals associated with the current user as SELF. + */ + private Collection getAssociatedIndividuals( + HttpServletRequest req) { + Collection individuals = new ArrayList(); + + UserAccount user = LoginStatusBean.getCurrentUser(req); + if (user == null) { + log.debug("No Associated Individuals: not logged in."); + return individuals; + } + + SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(req); + individuals.addAll(sec.getAssociatedIndividuals(indDao, user)); + + return individuals; + } +} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java new file mode 100644 index 000000000..905dfccac --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java @@ -0,0 +1,37 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProxyEditingRights; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Find out what Profiles the User can edit through proxy. + */ +public class HasProxyEditingRightsFactory extends BaseIdentifierBundleFactory { + + public HasProxyEditingRightsFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + ArrayIdentifierBundle ids = new ArrayIdentifierBundle(); + + UserAccount user = LoginStatusBean.getCurrentUser(req); + if (user != null) { + for (String proxiedUri : user.getProxiedIndividualUris()) { + ids.add(new HasProxyEditingRights(proxiedUri)); + } + } + + return ids; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java new file mode 100644 index 000000000..bf118184d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasRoleLevelFactory.java @@ -0,0 +1,29 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; +import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; + +/** + * Create an identifier that shows the role level of the current user, or + * PUBLIC if the user is not logged in. + */ +public class HasRoleLevelFactory extends BaseIdentifierBundleFactory { + + public HasRoleLevelFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + RoleLevel roleLevel = RoleLevel.getRoleFromLoginStatus(req); + return new ArrayIdentifierBundle(new HasRoleLevel(roleLevel)); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java new file mode 100644 index 000000000..2b0dfa455 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java @@ -0,0 +1,34 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * If the user is logged in as a Root User, create an identifier. + */ +public class IsRootUserFactory extends BaseIdentifierBundleFactory { + + public IsRootUserFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + UserAccount user = LoginStatusBean.getCurrentUser(req); + if ((user != null) && user.isRootUser()) { + return new ArrayIdentifierBundle(IsRootUser.INSTANCE); + } else { + return new ArrayIdentifierBundle(); + } + } + +} + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java new file mode 100644 index 000000000..825021eab --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java @@ -0,0 +1,32 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; + +/** + * If the user is logged in, create an Identifier. + */ +public class IsUserFactory extends BaseIdentifierBundleFactory { + + public IsUserFactory(ServletContext ctx) { + super(ctx); + } + + @Override + public IdentifierBundle getIdentifierBundle(HttpServletRequest req) { + LoginStatusBean bean = LoginStatusBean.getBean(req); + if (bean.isLoggedIn()) { + return new ArrayIdentifierBundle(new IsUser(bean.getUserURI())); + } else { + return new ArrayIdentifierBundle(); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java index f03d6c344..1fc841537 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java @@ -8,38 +8,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct * This is what the PermissionRegistry hands out if you ask for a Permission * that it doesn't know about. Nothing is authorized by this Permission. */ -public class BrokenPermission implements Permission { - private final String uri; - private final String localName; - private final String namespace; - +public class BrokenPermission extends Permission { public BrokenPermission(String uri) { - this.uri = uri; - - int namespaceBreak = uri.lastIndexOf("#"); - if (namespaceBreak == -1) { - namespaceBreak = uri.lastIndexOf("/"); - } - - int localNameStart = namespaceBreak + 1; - - this.namespace = uri.substring(0, localNameStart); - this.localName = uri.substring(localNameStart); - } - - @Override - public String getUri() { - return uri; - } - - @Override - public String getLocalName() { - return localName; - } - - @Override - public String getNamespace() { - return namespace; + super(uri); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java index 8089db2ec..c81bdd98c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java @@ -8,47 +8,64 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct * Interface that describes a unit of authorization, or permission to perform * requested actions. */ -public interface Permission { +public abstract class Permission implements Comparable { + protected final String uri; + + protected Permission(String uri) { + if (uri == null) { + throw new NullPointerException("uri may not be null."); + } + this.uri = uri; + } + /** * Get the URI that identifies this Permission object. */ - String getUri(); - - /** - * Convenience method to get the localName portion of the URI. - */ - String getLocalName(); - - /** - * Convenience method to get the namespace portion of the URI. - */ - String getNamespace(); + public String getUri() { + return uri; + } /** * Is a user with this Permission authorized to perform this * RequestedAction? */ - boolean isAuthorized(RequestedAction whatToAuth); + public abstract boolean isAuthorized(RequestedAction whatToAuth); + + @Override + public int compareTo(Permission that) { + return this.uri.compareTo(that.uri); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null) { + return false; + } + if (!obj.getClass().equals(this.getClass())) { + return false; + } + Permission that = (Permission) obj; + return this.uri.equals(that.uri); + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "['" + uri + "']"; + } /** - * An implementation of Permission that authorizes nothing. + * A concrete Permission instance that authorizes nothing. */ - static Permission NOT_AUTHORIZED = new Permission() { - - @Override - public String getUri() { - return "java:" + Permission.class.getName() + "#NOT_AUTHORIZED"; - } - - @Override - public String getLocalName() { - return "NOT_AUTHORIZED"; - } - - @Override - public String getNamespace() { - return "java:" + Permission.class.getName(); - } + static Permission NOT_AUTHORIZED = new Permission("java:" + + Permission.class.getName() + "#NOT_AUTHORIZED") { @Override public boolean isAuthorized(RequestedAction whatToAuth) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java index 2693c3196..8b1f457d5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java @@ -287,7 +287,7 @@ public class PermissionSetsLoader implements ServletContextListener { checkForPermissionSetsWithoutLabels(); checkForReferencesToNonexistentPermissionSets(); checkForReferencesToNonexistentPermissions(); - warnIfNoDefaultPermissionSetsForNewUsers(); + warnIfNoPermissionSetsForNewUsers(); } private void checkForPermissionSetsWithoutLabels() { @@ -327,14 +327,14 @@ public class PermissionSetsLoader implements ServletContextListener { } } - private void warnIfNoDefaultPermissionSetsForNewUsers() { + private void warnIfNoPermissionSetsForNewUsers() { for (PermissionSet ps : uaDao.getAllPermissionSets()) { - if (ps.isDefaultForNewUsers()) { + if (ps.isForNewUsers()) { return; } } ss.warning(listener, "No PermissionSet has been declared to be a " - + "Default PermissionSet for new users."); + + "PermissionSet for new users."); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java index 10e9e5e8b..4c059b4b9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -18,7 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct * A class of simple permissions. Each instance holds a RequestedAction, and * will only authorize that RequestedAction (or one with the same URI). */ -public class SimplePermission implements Permission { +public class SimplePermission extends Permission { private static final Log log = LogFactory.getLog(SimplePermission.class); private static final String NAMESPACE = "java:" @@ -52,6 +52,8 @@ public class SimplePermission implements Permission { "ManageTabs"); public static final SimplePermission MANAGE_USER_ACCOUNTS = new SimplePermission( "ManageUserAccounts"); + public static final SimplePermission QUERY_FULL_MODEL = new SimplePermission( + "QueryFullModel"); public static final SimplePermission QUERY_USER_ACCOUNTS_MODEL = new SimplePermission( "QueryUserAccountsModel"); public static final SimplePermission REBUILD_VCLASS_GROUP_CACHE = new SimplePermission( @@ -86,18 +88,17 @@ public class SimplePermission implements Permission { } private final String localName; - private final String uri; public final RequestedAction ACTION; public final Actions ACTIONS; public SimplePermission(String localName) { + super(NAMESPACE + localName); + if (localName == null) { throw new NullPointerException("name may not be null."); } this.localName = localName; - this.uri = NAMESPACE + localName; - this.ACTION = new SimpleRequestedAction(localName); this.ACTIONS = new Actions(this.ACTION); @@ -108,21 +109,14 @@ public class SimplePermission implements Permission { allInstances.put(uri, this); } - @Override public String getLocalName() { return this.localName; } - @Override public String getNamespace() { return NAMESPACE; } - @Override - public String getUri() { - return NAMESPACE + this.localName; - } - @Override public boolean isAuthorized(RequestedAction whatToAuth) { if (whatToAuth != null) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java index b6be06774..7d212e6fa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java @@ -19,14 +19,25 @@ public class PermissionsPolicy implements PolicyIface { @Override public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth) { + if (whoToAuth == null) { + return defaultDecision("whomToAuth was null"); + } + if (whatToAuth == null) { + return defaultDecision("whatToAuth was null"); + } + for (Permission p : HasPermission.getPermissions(whoToAuth)) { if (p.isAuthorized(whatToAuth)) { return new BasicPolicyDecision(Authorization.AUTHORIZED, "PermissionsPolicy: approved by " + p); } } - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, - "no permission will approve " + whatToAuth); + return defaultDecision("no permission will approve " + whatToAuth); + } + + /** If the user isn't explicitly authorized, return this. */ + private PolicyDecision defaultDecision(String message) { + return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java deleted file mode 100644 index 3ee7efb12..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/UseRestrictedPagesByRoleLevelPolicy.java +++ /dev/null @@ -1,83 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasRoleLevel; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.querymodel.QueryFullModel; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - -/** - * Check the users role level to determine whether they are allowed to use - * restricted pages. - */ -public class UseRestrictedPagesByRoleLevelPolicy implements PolicyIface { - private static final Log log = LogFactory - .getLog(UseRestrictedPagesByRoleLevelPolicy.class); - - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return defaultDecision("whomToAuth was null"); - } - if (whatToAuth == null) { - return defaultDecision("whatToAuth was null"); - } - - RoleLevel userRole = HasRoleLevel.getUsersRoleLevel(whoToAuth); - - PolicyDecision result; - if (whatToAuth instanceof QueryFullModel) { - result = isAuthorized(whatToAuth, RoleLevel.PUBLIC, userRole); - - } else { - result = defaultDecision("Unrecognized action"); - } - - log.debug("decision for '" + whatToAuth + "' is " + result); - return result; - } - - /** Authorize if user's role is at least as high as the required role. */ - private PolicyDecision isAuthorized(RequestedAction whatToAuth, - RoleLevel requiredRole, RoleLevel currentRole) { - if (isRoleAtLeast(requiredRole, currentRole)) { - return authorized("User may view page: " + whatToAuth - + ", requiredRole=" + requiredRole + ", currentRole=" - + currentRole); - } else { - return defaultDecision("User may not view page: " + whatToAuth - + ", requiredRole=" + requiredRole + ", currentRole=" - + currentRole); - } - } - - private boolean isRoleAtLeast(RoleLevel required, RoleLevel current) { - return (current.compareTo(required) >= 0); - } - - /** If the user is explicitly authorized, return this. */ - private PolicyDecision authorized(String message) { - String className = this.getClass().getSimpleName(); - return new BasicPolicyDecision(Authorization.AUTHORIZED, className - + ": " + message); - } - - /** If the user isn't explicitly authorized, return this. */ - private PolicyDecision defaultDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " - " + hashCode(); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index 2a9d02a27..850f6e586 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -7,18 +7,24 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.CommonIdentifierBundleFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProfileOrIsBlacklistedFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingRightsFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.EditRestrictedDataByRoleLevelPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy; import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; -import edu.cornell.mannlib.vitro.webapp.auth.policy.UseRestrictedPagesByRoleLevelPolicy; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** - * Set up the common policy family, with Identifier factory. + * Set up the common policy family, with Identifier factories. */ public class CommonPolicyFamilySetup implements ServletContextListener { @@ -28,29 +34,31 @@ public class CommonPolicyFamilySetup implements ServletContextListener { StartupStatus ss = StartupStatus.getBean(ctx); try { - ServletPolicyList.addPolicy(ctx, new PermissionsPolicy()); + policy(ctx, new PermissionsPolicy()); + policy(ctx, new DisplayRestrictedDataByRoleLevelPolicy(ctx)); + policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx)); + policy(ctx, new EditRestrictedDataByRoleLevelPolicy(ctx)); + policy(ctx, new SelfEditingPolicy(ctx)); - ServletPolicyList.addPolicy(ctx, - new DisplayRestrictedDataByRoleLevelPolicy(ctx)); - ServletPolicyList.addPolicy(ctx, - new DisplayRestrictedDataToSelfPolicy(ctx)); - ServletPolicyList.addPolicy(ctx, - new EditRestrictedDataByRoleLevelPolicy(ctx)); - ServletPolicyList.addPolicy(ctx, - new UseRestrictedPagesByRoleLevelPolicy()); - - ServletPolicyList.addPolicy(ctx, new SelfEditingPolicy(ctx)); - - // This factory creates Identifiers for all of the above policies. - CommonIdentifierBundleFactory factory = new CommonIdentifierBundleFactory( - ctx); - - ActiveIdentifierBundleFactories.addFactory(sce, factory); + factory(ctx, new IsUserFactory(ctx)); + factory(ctx, new IsRootUserFactory(ctx)); + factory(ctx, new HasRoleLevelFactory(ctx)); + factory(ctx, new HasProfileOrIsBlacklistedFactory(ctx)); + factory(ctx, new HasPermissionFactory(ctx)); + factory(ctx, new HasProxyEditingRightsFactory(ctx)); } catch (Exception e) { ss.fatal(this, "could not run CommonPolicyFamilySetup", e); } } + private void policy(ServletContext ctx, PolicyIface policy) { + ServletPolicyList.addPolicy(ctx, policy); + } + + private void factory(ServletContext ctx, IdentifierBundleFactory factory) { + ActiveIdentifierBundleFactories.addFactory(ctx, factory); + } + @Override public void contextDestroyed(ServletContextEvent sce) { /* nothing */ } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/querymodel/QueryFullModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/querymodel/QueryFullModel.java deleted file mode 100644 index db3473b98..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/querymodel/QueryFullModel.java +++ /dev/null @@ -1,10 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.querymodel; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; - -/** Should we allow the user to query the full data model? */ -public class QueryFullModel extends RequestedAction { - // no fields -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java index 0af4001a8..9767f5303 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/PermissionSet.java @@ -18,7 +18,8 @@ public class PermissionSet { /** This may be empty, but it should never be null. */ private String label = ""; - private boolean defaultForNewUsers; + private boolean forNewUsers; + private boolean forPublic; /** This may be empty, but it should never be null. */ private Set permissionUris = Collections.emptySet(); @@ -39,13 +40,22 @@ public class PermissionSet { this.label = (label == null) ? "" : label; } - public boolean isDefaultForNewUsers() { - return defaultForNewUsers; + public boolean isForNewUsers() { + return forNewUsers; } - public void setDefaultForNewUsers(Boolean defaultForNewUsers) { - this.defaultForNewUsers = (defaultForNewUsers == null) ? false - : defaultForNewUsers.booleanValue(); + public void setForNewUsers(Boolean forNewUsers) { + this.forNewUsers = (forNewUsers == null) ? false + : forNewUsers.booleanValue(); + } + + public boolean isForPublic() { + return forPublic; + } + + public void setForPublic(Boolean forPublic) { + this.forPublic = (forPublic == null) ? false + : forPublic.booleanValue(); } public Set getPermissionUris() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java index b6f837279..092e9c7e9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; @@ -54,11 +53,16 @@ public abstract class UserAccountsPage extends AbstractPageHandler { } /** - * Create a list of all known PermissionSets. + * Create a list of all known non-public PermissionSets. */ - protected List buildRolesList() { + protected List buildListOfSelectableRoles() { List list = new ArrayList(); - list.addAll(userAccountsDao.getAllPermissionSets()); + for (PermissionSet ps: userAccountsDao.getAllPermissionSets()) { + if (!ps.isForPublic()) { + list.add(ps); + } + } + Collections.sort(list, new Comparator() { @Override public int compare(PermissionSet ps1, PermissionSet ps2) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java index 6e5c53e20..2f0dcb3ae 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsAddPage.java @@ -2,13 +2,17 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; @@ -55,7 +59,7 @@ public class UserAccountsAddPage extends UserAccountsPage { private boolean externalAuthOnly; private String firstName = ""; private String lastName = ""; - private String selectedRoleUri = ""; + private Collection selectedRoleUris = Collections.emptyList(); private String associatedProfileUri = ""; private String newProfileClassUri = ""; @@ -88,7 +92,7 @@ public class UserAccountsAddPage extends UserAccountsPage { externalAuthOnly = isFlagOnRequest(PARAMETER_EXTERNAL_AUTH_ONLY); firstName = getStringParameter(PARAMETER_FIRST_NAME, ""); lastName = getStringParameter(PARAMETER_LAST_NAME, ""); - selectedRoleUri = getStringParameter(PARAMETER_ROLE, ""); + selectedRoleUris = getStringParameters(PARAMETER_ROLE); associatedProfileUri = getStringParameter( PARAMETER_ASSOCIATED_PROFILE_URI, ""); newProfileClassUri = getStringParameter( @@ -114,7 +118,7 @@ public class UserAccountsAddPage extends UserAccountsPage { errorCode = ERROR_NO_FIRST_NAME; } else if (lastName.isEmpty()) { errorCode = ERROR_NO_LAST_NAME; - } else if (selectedRoleUri.isEmpty()) { + } else if (selectedRoleUris.isEmpty()) { errorCode = ERROR_NO_ROLE; } else { errorCode = strategy.additionalValidations(); @@ -155,7 +159,7 @@ public class UserAccountsAddPage extends UserAccountsPage { u.setLoginCount(0); u.setLastLoginTime(0L); u.setStatus(Status.INACTIVE); - u.setPermissionSetUris(Collections.singleton(selectedRoleUri)); + u.setPermissionSetUris(selectedRoleUris); strategy.setAdditionalProperties(u); @@ -189,20 +193,29 @@ public class UserAccountsAddPage extends UserAccountsPage { public final ResponseValues showPage() { Map body = new HashMap(); - body.put(PARAMETER_EMAIL_ADDRESS, emailAddress); - body.put(PARAMETER_EXTERNAL_AUTH_ID, externalAuthId); - body.put(PARAMETER_FIRST_NAME, firstName); - body.put(PARAMETER_LAST_NAME, lastName); - body.put("selectedRole", selectedRoleUri); - body.put("roles", buildRolesList()); + if (isSubmit()) { + body.put(PARAMETER_EMAIL_ADDRESS, emailAddress); + body.put(PARAMETER_EXTERNAL_AUTH_ID, externalAuthId); + body.put(PARAMETER_FIRST_NAME, firstName); + body.put(PARAMETER_LAST_NAME, lastName); + body.put("selectedRoles", selectedRoleUris); + } else { + body.put(PARAMETER_EMAIL_ADDRESS, ""); + body.put(PARAMETER_EXTERNAL_AUTH_ID, ""); + body.put(PARAMETER_FIRST_NAME, ""); + body.put(PARAMETER_LAST_NAME, ""); + body.put("selectedRoles", getDefaultRolesForNewUsers()); + } + + body.put("roles", buildListOfSelectableRoles()); body.put("profileTypes", buildProfileTypesList()); body.put(PARAMETER_NEW_PROFILE_CLASS_URI, newProfileClassUri); body.put("formUrls", buildUrlsMap()); - + if (externalAuthOnly) { body.put(PARAMETER_EXTERNAL_AUTH_ONLY, Boolean.TRUE); } - + if (!associatedProfileUri.isEmpty()) { body.put("associatedProfileInfo", buildProfileInfo(associatedProfileUri)); @@ -221,6 +234,16 @@ public class UserAccountsAddPage extends UserAccountsPage { return new TemplateResponseValues(TEMPLATE_NAME, body); } + private Collection getDefaultRolesForNewUsers() { + List list = new ArrayList(); + for (PermissionSet ps : userAccountsDao.getAllPermissionSets()) { + if (ps.isForNewUsers()) { + list.add(ps.getUri()); + } + } + return list; + } + public UserAccount getAddedAccount() { return addedAccount; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java index 9640182dc..672d2883f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java @@ -2,11 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.admin; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -64,7 +65,7 @@ public class UserAccountsEditPage extends UserAccountsPage { private boolean externalAuthOnly; private String firstName = ""; private String lastName = ""; - private String selectedRoleUri = ""; + private Collection selectedRoleUris = new ArrayList(); private String associatedProfileUri = ""; private String newProfileClassUri = ""; @@ -101,7 +102,7 @@ public class UserAccountsEditPage extends UserAccountsPage { externalAuthOnly = isFlagOnRequest(PARAMETER_EXTERNAL_AUTH_ONLY); firstName = getStringParameter(PARAMETER_FIRST_NAME, ""); lastName = getStringParameter(PARAMETER_LAST_NAME, ""); - selectedRoleUri = getStringParameter(PARAMETER_ROLE, ""); + selectedRoleUris = getStringParameters(PARAMETER_ROLE); associatedProfileUri = getStringParameter( PARAMETER_ASSOCIATED_PROFILE_URI, ""); newProfileClassUri = getStringParameter( @@ -155,7 +156,7 @@ public class UserAccountsEditPage extends UserAccountsPage { errorCode = ERROR_NO_FIRST_NAME; } else if (lastName.isEmpty()) { errorCode = ERROR_NO_LAST_NAME; - } else if (!isRootUser() && selectedRoleUri.isEmpty()) { + } else if (!isRootUser() && selectedRoleUris.isEmpty()) { errorCode = ERROR_NO_ROLE; } else { errorCode = strategy.additionalValidations(); @@ -203,7 +204,7 @@ public class UserAccountsEditPage extends UserAccountsPage { body.put("externalAuthId", externalAuthId); body.put("firstName", firstName); body.put("lastName", lastName); - body.put("selectedRole", selectedRoleUri); + body.put("selectedRoles", selectedRoleUris); body.put(PARAMETER_NEW_PROFILE_CLASS_URI, newProfileClassUri); if (externalAuthOnly) { @@ -219,7 +220,7 @@ public class UserAccountsEditPage extends UserAccountsPage { body.put("externalAuthId", userAccount.getExternalAuthId()); body.put("firstName", userAccount.getFirstName()); body.put("lastName", userAccount.getLastName()); - body.put("selectedRole", getExistingRoleUri()); + body.put("selectedRoles", userAccount.getPermissionSetUris()); body.put(PARAMETER_NEW_PROFILE_CLASS_URI, ""); if (userAccount.isExternalAuthOnly()) { @@ -235,7 +236,7 @@ public class UserAccountsEditPage extends UserAccountsPage { } if (!isRootUser()) { - body.put("roles", buildRolesList()); + body.put("roles", buildListOfSelectableRoles()); } body.put("profileTypes", buildProfileTypesList()); @@ -254,15 +255,6 @@ public class UserAccountsEditPage extends UserAccountsPage { return new TemplateResponseValues(TEMPLATE_NAME, body); } - private String getExistingRoleUri() { - Set uris = userAccount.getPermissionSetUris(); - if (uris.isEmpty()) { - return ""; - } else { - return uris.iterator().next(); - } - } - private Map buildUrlsMapWithEditUrl() { Map map = buildUrlsMap(); map.put("edit", editAccountUrl(userAccount.getUri())); @@ -287,8 +279,7 @@ public class UserAccountsEditPage extends UserAccountsPage { userAccount.setPermissionSetUris(Collections. emptySet()); userAccount.setExternalAuthOnly(false); } else { - userAccount.setPermissionSetUris(Collections - .singleton(selectedRoleUri)); + userAccount.setPermissionSetUris(selectedRoleUris); userAccount.setExternalAuthOnly(externalAuthOnly); } strategy.setAdditionalProperties(userAccount); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java index 7615c9369..97f2365ab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java @@ -115,7 +115,7 @@ public class UserAccountsListPage extends UserAccountsPage { body.put("page", buildPageMap(selection)); body.put("formUrls", buildUrlsMap()); - body.put("roles", buildRolesList()); + body.put("roles", buildListOfSelectableRoles()); body.put("messages", buildMessagesMap()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java index de461c8cb..7a326c18e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java @@ -28,7 +28,6 @@ import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.querymodel.QueryFullModel; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; @@ -55,7 +54,7 @@ public class SparqlQueryAjaxController extends VitroAjaxController { if (OPTION_MODEL_USER_ACCOUNTS.equals(modelParam)) { return SimplePermission.QUERY_USER_ACCOUNTS_MODEL.ACTIONS; } else { - return new Actions(new QueryFullModel()); + return SimplePermission.QUERY_FULL_MODEL.ACTIONS; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java index dde828b54..67511a575 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VitroVocabulary.java @@ -169,7 +169,8 @@ public class VitroVocabulary { public static final String PERMISSIONSET = VITRO_AUTH + "PermissionSet"; public static final String PERMISSIONSET_HAS_PERMISSION = VITRO_AUTH + "hasPermission"; - public static final String DEFAULT_PERMISSION_SET_FOR_NEW_USERS = VITRO_AUTH + "DefaultPermissionSetForNewUsers"; + public static final String PERMISSION_SET_FOR_NEW_USERS = VITRO_AUTH + "PermissionSetForNewUsers"; + public static final String PERMISSION_SET_FOR_PUBLIC = VITRO_AUTH + "PermissionSetForPublic"; public static final String PERMISSION = VITRO_AUTH + "Permission"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java index 676bdfd33..4a4b4185e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDaoCon.java @@ -142,7 +142,8 @@ public class JenaBaseDaoCon { protected ObjectProperty USERACCOUNT_PROXY_EDITOR_FOR = _constModel.createObjectProperty(VitroVocabulary.USERACCOUNT_PROXY_EDITOR_FOR); protected OntClass PERMISSIONSET = _constModel.createClass(VitroVocabulary.PERMISSIONSET); - protected OntClass DEFAULT_PERMISSION_SET_FOR_NEW_USERS = _constModel.createClass(VitroVocabulary.DEFAULT_PERMISSION_SET_FOR_NEW_USERS); + protected OntClass PERMISSION_SET_FOR_NEW_USERS = _constModel.createClass(VitroVocabulary.PERMISSION_SET_FOR_NEW_USERS); + protected OntClass PERMISSION_SET_FOR_PUBLIC = _constModel.createClass(VitroVocabulary.PERMISSION_SET_FOR_PUBLIC); protected ObjectProperty PERMISSIONSET_HAS_PERMISSION = _constModel.createObjectProperty(VitroVocabulary.PERMISSIONSET_HAS_PERMISSION); protected OntClass PERMISSION = _constModel.createClass(VitroVocabulary.PERMISSION); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java index 7611e2ffb..5bdb5f0fe 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJena.java @@ -12,7 +12,6 @@ import java.util.Random; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntResource; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; @@ -410,8 +409,8 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao PermissionSet ps = new PermissionSet(); ps.setUri(uri); ps.setLabel(getPropertyStringValue(r, RDFS.label)); - ps.setDefaultForNewUsers(isResourceOfType(r, - DEFAULT_PERMISSION_SET_FOR_NEW_USERS)); + ps.setForNewUsers(isResourceOfType(r, PERMISSION_SET_FOR_NEW_USERS)); + ps.setForPublic(isResourceOfType(r, PERMISSION_SET_FOR_PUBLIC)); ps.setPermissionUris(getPropertyResourceURIValues(r, PERMISSIONSET_HAS_PERMISSION)); return ps; @@ -436,8 +435,10 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao PermissionSet ps = new PermissionSet(); ps.setUri(r.getURI()); ps.setLabel(getPropertyStringValue(r, RDFS.label)); - ps.setDefaultForNewUsers(isResourceOfType(r, - DEFAULT_PERMISSION_SET_FOR_NEW_USERS)); + ps.setForNewUsers(isResourceOfType(r, + PERMISSION_SET_FOR_NEW_USERS)); + ps.setForPublic(isResourceOfType(r, + PERMISSION_SET_FOR_PUBLIC)); ps.setPermissionUris(getPropertyResourceURIValues(r, PERMISSIONSET_HAS_PERMISSION)); list.add(ps); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java new file mode 100644 index 000000000..fb32a9728 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java @@ -0,0 +1,277 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.javax.servlet.ServletContextStub; +import stubs.javax.servlet.http.HttpServletRequestStub; +import stubs.javax.servlet.http.HttpSessionStub; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Can we tell whether a user is logged in as root? + */ +public class HasPermissionFactoryTest extends AbstractTestClass { + private static final String USER_URI = "http://userUri"; + private UserAccount user; + + private LoginStatusBean lsb; + + private PermissionSet emptyPublicPermissionSet; + private PermissionSet publicPermissionSet1; + private PermissionSet publicPermissionSet2; + private PermissionSet emptyLoggedInPermissionSet; + private PermissionSet loggedInPermissionSet1; + private PermissionSet loggedInPermissionSet2; + + private Permission permissionP1a; + private Permission permissionP1b; + private Permission permissionP2; + private Permission permissionLI1; + private Permission permissionLI2a; + private Permission permissionLI2b; + + private WebappDaoFactoryStub wdf; + private UserAccountsDaoStub uaDao; + + private ServletContextStub ctx; + private HttpSessionStub session; + private HttpServletRequestStub req; + + private HasPermissionFactory factory; + + private IdentifierBundle actualIds; + private IdentifierBundle expectedIds; + + @Before + public void setup() { + user = new UserAccount(); + user.setUri(USER_URI); + + lsb = new LoginStatusBean(USER_URI, AuthenticationSource.INTERNAL); + + uaDao = new UserAccountsDaoStub(); + uaDao.addUser(user); + + wdf = new WebappDaoFactoryStub(); + wdf.setUserAccountsDao(uaDao); + + ctx = new ServletContextStub(); + ctx.setAttribute("webappDaoFactory", wdf); + + session = new HttpSessionStub(); + session.setServletContext(ctx); + + req = new HttpServletRequestStub(); + req.setSession(session); + + factory = new HasPermissionFactory(ctx); + + preparePermissions(); + preparePermissionSets(); + } + + private void preparePermissions() { + permissionP1a = new MyPermission("permissionP1a"); + permissionP1b = new MyPermission("permissionP1b"); + permissionP2 = new MyPermission("permissionP2"); + permissionLI1 = new MyPermission("permissionLI1"); + permissionLI2a = new MyPermission("permissionLI2a"); + permissionLI2b = new MyPermission("permissionLI2b"); + PermissionRegistry.createRegistry( + ctx, + list(permissionP1a, permissionP1b, permissionP2, permissionLI1, + permissionLI2a, permissionLI2b)); + } + + private void preparePermissionSets() { + emptyPublicPermissionSet = new PermissionSet(); + emptyPublicPermissionSet.setUri("java:emptyPS"); + emptyPublicPermissionSet.setLabel("emptyPublicPermissionSet"); + emptyPublicPermissionSet.setForPublic(true); + + publicPermissionSet1 = new PermissionSet(); + publicPermissionSet1.setUri("java:publicPS1"); + publicPermissionSet1.setLabel("publicPermissionSet1"); + publicPermissionSet1.setForPublic(true); + setPermissions(publicPermissionSet1, permissionP1a, permissionP1b); + + publicPermissionSet2 = new PermissionSet(); + publicPermissionSet2.setUri("java:publicPS2"); + publicPermissionSet2.setLabel("publicPermissionSet2"); + publicPermissionSet2.setForPublic(true); + setPermissions(publicPermissionSet2, permissionP2); + + emptyLoggedInPermissionSet = new PermissionSet(); + emptyLoggedInPermissionSet.setUri("java:emptyPS"); + emptyLoggedInPermissionSet.setLabel("emptyLoggedInPermissionSet"); + + loggedInPermissionSet1 = new PermissionSet(); + loggedInPermissionSet1.setUri("java:loggedInPS1"); + loggedInPermissionSet1.setLabel("loggedInPermissionSet1"); + setPermissions(loggedInPermissionSet1, permissionLI1); + + loggedInPermissionSet2 = new PermissionSet(); + loggedInPermissionSet2.setUri("java:loggedInPS2"); + loggedInPermissionSet2.setLabel("loggedInPermissionSet2"); + setPermissions(loggedInPermissionSet2, permissionLI2a, permissionLI2b); + + uaDao.addPermissionSet(emptyLoggedInPermissionSet); + uaDao.addPermissionSet(loggedInPermissionSet1); + uaDao.addPermissionSet(loggedInPermissionSet2); + // "public" permission sets are added for specific tests. + } + + // ---------------------------------------------------------------------- + // the tests + // ---------------------------------------------------------------------- + + @Test + public void notLoggedInNoPublicSets() { + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("no public sets", expectedIds, actualIds); + } + + @Test + public void notLoggedInEmptyPublicSet() { + uaDao.addPermissionSet(emptyPublicPermissionSet); + + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("empty public set", expectedIds, actualIds); + } + + @Test + public void notLoggedInOnePublicSet() { + uaDao.addPermissionSet(publicPermissionSet1); + + expectedIds = new ArrayIdentifierBundle(id(permissionP1a), + id(permissionP1b)); + actualIds = factory.getIdentifierBundle(req); + assertEqualIds("one public set", expectedIds, actualIds); + } + + @Test + public void notLoggedInTwoPublicSets() { + uaDao.addPermissionSet(publicPermissionSet1); + uaDao.addPermissionSet(publicPermissionSet2); + + expectedIds = new ArrayIdentifierBundle(id(permissionP1a), + id(permissionP1b), id(permissionP2)); + actualIds = factory.getIdentifierBundle(req); + assertEqualIds("two public sets", expectedIds, actualIds); + } + + @Test + public void loggedInNoSets() { + LoginStatusBean.setBean(session, lsb); + + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("no logged in sets", expectedIds, actualIds); + } + + @Test + public void loggedInEmptySet() { + LoginStatusBean.setBean(session, lsb); + user.setPermissionSetUris(list(emptyLoggedInPermissionSet.getUri())); + + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("empty logged in set", expectedIds, actualIds); + } + + @Test + public void loggedInOneSet() { + LoginStatusBean.setBean(session, lsb); + user.setPermissionSetUris(list(loggedInPermissionSet1.getUri())); + + expectedIds = new ArrayIdentifierBundle(id(permissionLI1)); + actualIds = factory.getIdentifierBundle(req); + assertEqualIds("one logged in set", expectedIds, actualIds); + } + + @Test + public void loggedInTwoSets() { + LoginStatusBean.setBean(session, lsb); + user.setPermissionSetUris(list(loggedInPermissionSet1.getUri(), + loggedInPermissionSet2.getUri())); + + expectedIds = new ArrayIdentifierBundle(id(permissionLI1), + id(permissionLI2a), id(permissionLI2b)); + actualIds = factory.getIdentifierBundle(req); + assertEqualIds("two logged in sets", expectedIds, actualIds); + } + + // ---------------------------------------------------------------------- + // helper methods + // ---------------------------------------------------------------------- + + private void setPermissions(PermissionSet ps, Permission... permissions) { + List uris = new ArrayList(); + for (Permission p : permissions) { + uris.add(p.getUri()); + } + ps.setPermissionUris(uris); + } + + private HasPermission id(Permission p) { + return new HasPermission(p); + } + + private List list(T... elements) { + List l = new ArrayList(); + for (T element : elements) { + l.add(element); + } + return l; + } + + private void assertEqualIds(String message, IdentifierBundle expected, + IdentifierBundle actual) { + Set expectedSet = new HashSet(); + for (Identifier id : expected) { + expectedSet.add((HasPermission) id); + } + Set actualSet = new HashSet(); + for (Identifier id : actual) { + actualSet.add((HasPermission) id); + } + assertEqualSets(message, expectedSet, actualSet); + } + + private static class MyPermission extends Permission { + public MyPermission(String uri) { + super(uri); + } + + @Override + public boolean isAuthorized(RequestedAction whatToAuth) { + return false; + } + + } +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java new file mode 100644 index 000000000..2c08c0e16 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java @@ -0,0 +1,99 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.javax.servlet.ServletContextStub; +import stubs.javax.servlet.http.HttpServletRequestStub; +import stubs.javax.servlet.http.HttpSessionStub; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; + +/** + * Can we tell whether a user is logged in as root? + */ +public class IsRootUserFactoryTest extends AbstractTestClass { + private static final String PLAIN_USER_URI = "http://userUri"; + private static final String ROOT_USER_URI = "http://rootUri"; + + private WebappDaoFactoryStub wdf; + private UserAccountsDaoStub uaDao; + + private ServletContextStub ctx; + private HttpSessionStub session; + private HttpServletRequestStub req; + + private IsRootUserFactory factory; + + private IdentifierBundle actualIds; + private IdentifierBundle expectedIds; + + @Before + public void setup() { + UserAccount plainUser = new UserAccount(); + plainUser.setUri(PLAIN_USER_URI); + + UserAccount rootUser = new UserAccount(); + rootUser.setUri(ROOT_USER_URI); + rootUser.setRootUser(true); + + uaDao = new UserAccountsDaoStub(); + uaDao.addUser(plainUser); + uaDao.addUser(rootUser); + + wdf = new WebappDaoFactoryStub(); + wdf.setUserAccountsDao(uaDao); + + ctx = new ServletContextStub(); + ctx.setAttribute("webappDaoFactory", wdf); + + session = new HttpSessionStub(); + session.setServletContext(ctx); + + req = new HttpServletRequestStub(); + req.setSession(session); + + factory = new IsRootUserFactory(ctx); + } + + @Test + public void notLoggedIn() { + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("empty bundle", expectedIds, actualIds); + } + + @Test + public void loggedInNotRoot() { + LoginStatusBean lsb = new LoginStatusBean(PLAIN_USER_URI, + AuthenticationSource.EXTERNAL); + LoginStatusBean.setBean(session, lsb); + + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("not root", expectedIds, actualIds); + } + + @Test + public void loggedInAsRoot() { + LoginStatusBean lsb = new LoginStatusBean(ROOT_USER_URI, + AuthenticationSource.EXTERNAL); + LoginStatusBean.setBean(session, lsb); + + expectedIds = new ArrayIdentifierBundle(IsRootUser.INSTANCE); + actualIds = factory.getIdentifierBundle(req); + assertEquals("root", expectedIds, actualIds); + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java new file mode 100644 index 000000000..9d20003dd --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java @@ -0,0 +1,72 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.javax.servlet.ServletContextStub; +import stubs.javax.servlet.http.HttpServletRequestStub; +import stubs.javax.servlet.http.HttpSessionStub; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; + +/** + * The simplest of the IdentifierBundleFactory classes. + */ +public class IsUserFactoryTest extends AbstractTestClass { + private static final String USER_URI = "http://userUri"; + + private WebappDaoFactoryStub wdf; + + private ServletContextStub ctx; + private HttpSessionStub session; + private HttpServletRequestStub req; + + private IsUserFactory factory; + + private IdentifierBundle actualIds; + private IdentifierBundle expectedIds; + + @Before + public void setup() { + wdf = new WebappDaoFactoryStub(); + + ctx = new ServletContextStub(); + ctx.setAttribute("webappDaoFactory", wdf); + + session = new HttpSessionStub(); + session.setServletContext(ctx); + + req = new HttpServletRequestStub(); + req.setSession(session); + + factory = new IsUserFactory(ctx); + } + + @Test + public void notLoggedIn() { + expectedIds = new ArrayIdentifierBundle(); + actualIds = factory.getIdentifierBundle(req); + assertEquals("empty bundle", expectedIds, actualIds); + } + + @Test + public void loggedIn() { + LoginStatusBean lsb = new LoginStatusBean(USER_URI, + AuthenticationSource.EXTERNAL); + LoginStatusBean.setBean(session, lsb); + + expectedIds = new ArrayIdentifierBundle(new IsUser(USER_URI)); + actualIds = factory.getIdentifierBundle(req); + assertEquals("user id", expectedIds, actualIds); + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java index f1858e094..61da9cbe0 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java @@ -74,8 +74,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass { IndividualImpl ind = new IndividualImpl(); ind.setURI(SELFEDITOR_URI); - ids = new ArrayIdentifierBundle(); - ids.add(new HasProfile(SELFEDITOR_URI)); + ids = new ArrayIdentifierBundle(new HasProfile(SELFEDITOR_URI)); } @Test diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java index e0238bc1f..40d748341 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java @@ -94,8 +94,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass { seIndividual = new IndividualImpl(); seIndividual.setURI(SELFEDITOR_URI); - ids = new ArrayIdentifierBundle(); - ids.add(new HasProfile(SELFEDITOR_URI)); + ids = new ArrayIdentifierBundle(new HasProfile(SELFEDITOR_URI)); // setLoggerLevel(SelfEditingPolicySetupTest.class, Level.DEBUG); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java index b9518c3e2..d62993f30 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java @@ -36,7 +36,7 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.CommonIdentifierBundleFactory; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasRoleLevelFactory; import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; @@ -163,7 +163,7 @@ public class AuthenticateTest extends AbstractTestClass { new ConfigurationPropertiesStub().setBean(servletContext); ActiveIdentifierBundleFactories.addFactory(servletContext, - new CommonIdentifierBundleFactory(servletContext)); + new HasRoleLevelFactory(servletContext)); } private UserAccount createUserFromUserInfo(UserInfo userInfo) { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java index 1a6205e67..60483298a 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/UserAccountsDaoJenaTest.java @@ -358,9 +358,15 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass { PermissionSet ps2 = new PermissionSet(); ps2.setUri(URI_ROLE2); ps2.setLabel("Role 2"); - ps2.setDefaultForNewUsers(true); + ps2.setForNewUsers(true); expected.add(ps2); + PermissionSet ps3 = new PermissionSet(); + ps3.setUri(URI_ROLE3); + ps3.setLabel("Role 3"); + ps3.setForPublic(true); + expected.add(ps3); + assertCorrectPermissionSets(expected, dao.getAllPermissionSets()); } @@ -467,7 +473,8 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass { map.put("uri", ps.getUri()); map.put("label", ps.getLabel()); map.put("permissions", ps.getPermissionUris()); - map.put("defaultForNewUsers", ps.isDefaultForNewUsers()); + map.put("forNewUsers", ps.isForNewUsers()); + map.put("forPublic", ps.isForPublic()); return map; } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 index 007f41861..605ed33ae 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/jena/resources/UserAccountsDaoJenaTest.n3 @@ -31,10 +31,16 @@ mydomain:role1 mydomain:role2 a auth:PermissionSet ; - a auth:DefaultPermissionSetForNewUsers ; + a auth:PermissionSetForNewUsers ; rdfs:label "Role 2" ; . +mydomain:role3 + a auth:PermissionSet ; + a auth:PermissionSetForPublic ; + rdfs:label "Role 3" ; + . + mydomain:permissionA a auth:Permission ; rdfs:label "Permission A" ; diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDaoStub.java index e404b348e..856525409 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/UserAccountsDaoStub.java @@ -2,6 +2,7 @@ package stubs.edu.cornell.mannlib.vitro.webapp.dao; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -43,6 +44,11 @@ public class UserAccountsDaoStub implements UserAccountsDao { return userAccountsByUri.get(uri); } + @Override + public Collection getAllPermissionSets() { + return new ArrayList(permissionSetsByUri.values()); + } + @Override public PermissionSet getPermissionSetByUri(String uri) { return permissionSetsByUri.get(uri); @@ -76,12 +82,6 @@ public class UserAccountsDaoStub implements UserAccountsDao { "UserAccountsDaoStub.deleteUserAccount() not implemented."); } - @Override - public Collection getAllPermissionSets() { - throw new RuntimeException( - "UserAccountsDaoStub.getAllPermissionSets() not implemented."); - } - @Override public UserAccount getUserAccountByExternalAuthId(String externalAuthId) { throw new RuntimeException( diff --git a/webapp/web/WEB-INF/resources/permission_config.n3 b/webapp/web/WEB-INF/resources/permission_config.n3 index eca3dde66..67ecf59c7 100644 --- a/webapp/web/WEB-INF/resources/permission_config.n3 +++ b/webapp/web/WEB-INF/resources/permission_config.n3 @@ -42,6 +42,9 @@ auth:ADMIN auth:hasPermission simplePermission:QueryUserAccountsModel ; auth:hasPermission simplePermission:UseBasicAjaxControllers ; auth:hasPermission simplePermission:UseMiscellaneousPages ; + + # permissions for ANY user, even if they are not logged in. + auth:hasPermission simplePermission:QueryFullModel ; . auth:CURATOR @@ -70,6 +73,9 @@ auth:CURATOR auth:hasPermission simplePermission:QueryUserAccountsModel ; auth:hasPermission simplePermission:UseBasicAjaxControllers ; auth:hasPermission simplePermission:UseMiscellaneousPages ; + + # permissions for ANY user, even if they are not logged in. + auth:hasPermission simplePermission:QueryFullModel ; . auth:EDITOR @@ -90,11 +96,14 @@ auth:EDITOR auth:hasPermission simplePermission:QueryUserAccountsModel ; auth:hasPermission simplePermission:UseBasicAjaxControllers ; auth:hasPermission simplePermission:UseMiscellaneousPages ; + + # permissions for ANY user, even if they are not logged in. + auth:hasPermission simplePermission:QueryFullModel ; . auth:SELF_EDITOR a auth:PermissionSet ; - a auth:DefaultPermissionSetForNewUsers ; + a auth:PermissionSetForNewUsers ; rdfs:label "Self Editor" ; # permissions for ANY logged-in user. @@ -104,4 +113,16 @@ auth:SELF_EDITOR auth:hasPermission simplePermission:QueryUserAccountsModel ; auth:hasPermission simplePermission:UseBasicAjaxControllers ; auth:hasPermission simplePermission:UseMiscellaneousPages ; + + # permissions for ANY user, even if they are not logged in. + auth:hasPermission simplePermission:QueryFullModel ; + . + +auth:PUBLIC + a auth:PermissionSet ; + a auth:PermissionSetForPublic ; + rdfs:label "Public" ; + + # permissions for ANY user, even if they are not logged in. + auth:hasPermission simplePermission:QueryFullModel ; . diff --git a/webapp/web/css/showAuth.css b/webapp/web/css/showAuth.css index f5270119d..6f4d3721b 100644 --- a/webapp/web/css/showAuth.css +++ b/webapp/web/css/showAuth.css @@ -2,20 +2,20 @@ /* Styles for Freemarker template showAuth */ -#show-auth * h3 { +#show-auth h3 { padding: 20px 0 12px 0; } -#show-auth * caption { - padding: 20px 0 12px 0; +#show-auth h4 { + padding: 30px 0 12px 0; margin: 0; text-align: left; } -#show-auth * th { +#show-auth th { padding: 4px 10px 4px 10px; border: 1px solid black; text-align: right; } -#show-auth * td { +#show-auth td { padding: 4px 10px 4px 10px; text-align: left; border: 1px solid black; diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl index bb0a3c5f1..bd425ab88 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl @@ -67,7 +67,7 @@

checked />Externally Authenticated Only

Roles *

<#list roles as role> - checked /> +
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl index d1a826042..afc68e1ed 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl @@ -68,7 +68,7 @@ <#if roles?has_content>

Roles *

<#list roles as role> - checked /> +
diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl index 2194c0650..2a5a638c2 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl @@ -50,7 +50,7 @@