import javax.ws.rs.core.UriInfo;
import org.collectionspace.services.authorization.AccountRoleRel;
+import org.collectionspace.services.authorization.AccountPermission;
//import org.collectionspace.services.authorization.AccountRolesList;
import org.collectionspace.services.account.storage.AccountStorageClient;
import org.collectionspace.services.authorization.AccountRole;
import org.collectionspace.services.common.document.DocumentHandler;
import org.collectionspace.services.common.security.UnauthorizedException;
import org.collectionspace.services.common.storage.StorageClient;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
import org.jboss.resteasy.util.HttpResponseCodes;
import org.slf4j.Logger;
@Path("{csid}")
public AccountsCommon getAccount(
@PathParam("csid") String csid) {
+
if (logger.isDebugEnabled()) {
logger.debug("getAccount with csid=" + csid);
}
return result;
}
+ @GET
+ @Path("{csid}/accountperms")
+ public AccountPermission getAccountPerm(
+ @PathParam("csid") String accCsid) {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("getAccountPerm with accCsid=" + accCsid);
+ }
+ if (accCsid == null || "".equals(accCsid)) {
+ logger.error("getAccountPerm: missing accCsid!");
+ Response response = Response.status(Response.Status.BAD_REQUEST).entity(
+ ServiceMessages.GET_FAILED + "getAccountPerm account "
+ + ServiceMessages.MISSING_INVALID_CSID + accCsid).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+
+ AccountPermission result = null;
+ String userId = "undefined";
+ try {
+ result = JpaStorageUtils.getAccountPermissions(accCsid);
+ } catch (UnauthorizedException ue) {
+ Response response = Response.status(Response.Status.UNAUTHORIZED).entity(ServiceMessages.GET_FAILED +
+ ue.getErrorReason()).type("text/plain").build();
+ throw new WebApplicationException(response);
+ } catch (DocumentNotFoundException dnfe) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("getAccountPerm", dnfe);
+ }
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(ServiceMessages.GET_FAILED +
+ "account userId=" + userId).type("text/plain").build();
+ throw new WebApplicationException(response);
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("getAccountPerm", e);
+ }
+ logger.error(ServiceMessages.UNKNOWN_ERROR_MSG, e);
+ Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+ ServiceMessages.GET_FAILED + ServiceMessages.UNKNOWN_ERROR_MSG).type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ if (result == null) {
+ Response response = Response.status(Response.Status.NOT_FOUND).entity(
+ ServiceMessages.GET_FAILED + "account userId=" + userId).type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ return result;
+ }
+
/**
* Delete account role.
*
List<AccountValue> avs = new ArrayList<AccountValue>();
ar.setAccounts(avs);
- AccountValue av = buildAccountValue(ar0);
+ AccountValue av = AuthorizationRoleRel.buildAccountValue(ar0);
avs.add(av);
//add roles
List<AccountValue> avs = new ArrayList<AccountValue>();
ar.setAccounts(avs);
for (AccountRoleRel arr : arrl) {
- AccountValue av = buildAccountValue(arr);
+ AccountValue av = AuthorizationRoleRel.buildAccountValue(arr);
avs.add(av);
}
}
return new DocumentFilter(this.getServiceContext());
}
- /**
- * Builds the account value.
- *
- * @param arr the arr
- * @return the account value
- */
- private AccountValue buildAccountValue(AccountRoleRel arr) {
- AccountValue av = new AccountValue();
- av.setAccountId(arr.getAccountId());
- av.setUserId(arr.getUserId());
- av.setScreenName(arr.getScreenName());
- return av;
- }
-
/**
* Builds the account role rel.
*
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+\r
+<!--\r
+ CollectionSpace default (security) authorization provider schema (XSD)\r
+\r
+ $LastChangedRevision: 916 $\r
+ $LastChangedDate: 2009-11-05 16:59:20 -0800 (Thu, 05 Nov 2009) $\r
+-->\r
+\r
+<xs:schema\r
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
+ xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"\r
+ jaxb:version="1.0" elementFormDefault="unqualified"\r
+ xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"\r
+ xmlns:hj="http://hyperjaxb3.jvnet.org/ejb/schemas/customizations"\r
+ xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"\r
+ xmlns:ns="http://collectionspace.org/services/authorization"\r
+ xmlns="http://collectionspace.org/services/authorization"\r
+ targetNamespace="http://collectionspace.org/services/authorization"\r
+ version="0.1"\r
+ jaxb:extensionBindingPrefixes="hj orm xjc"\r
+ >\r
+\r
+ <!--\r
+ Avoid XmlRootElement nightmare:\r
+ See http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html\r
+ -->\r
+\r
+ <!--xs:annotation>\r
+ Note that roles.xsd already defines global bindings for the authorization namespace\r
+ so, it is not necessary to give the bindingings here because all the xsds are compiled\r
+ at once for this namespace\r
+ <xs:appinfo>\r
+ <jaxb:globalBindings>\r
+ <xjc:simple />\r
+ </jaxb:globalBindings>\r
+ </xs:appinfo>\r
+ </xs:annotation-->\r
+\r
+ <xs:include schemaLocation="authorization_common.xsd"/>\r
+\r
+ <xs:element name="account_permission" type="account_permission"/>\r
+ <xs:complexType name="account_permission">\r
+ <xs:annotation>\r
+ <xs:documentation>\r
+ AccountPermission defines 1-n association between\r
+ an account and its corresponding permissions.\r
+ </xs:documentation>\r
+ <xs:appinfo>\r
+ <hj:ignored/>\r
+ </xs:appinfo>\r
+ </xs:annotation>\r
+ <xs:sequence>\r
+ <!-- subject is not required to be given by the service consumer -->\r
+ <!-- subject is for service use only -->\r
+ <xs:element name="account" type="ns:account_value" minOccurs="1" maxOccurs="unbounded"/>\r
+ <xs:element name="permission" type="ns:permission_value" minOccurs="1" maxOccurs="unbounded"/>\r
+ </xs:sequence>\r
+ </xs:complexType>\r
+</xs:schema>\r
+\r
package org.collectionspace.services.common.authorization_mgt;\r
\r
+import org.collectionspace.services.authorization.AccountValue;\r
import org.collectionspace.services.authorization.PermissionRoleRel;\r
import org.collectionspace.services.authorization.AccountRoleRel;\r
import org.collectionspace.services.authorization.PermissionValue;\r
\r
public class AuthorizationRoleRel {\r
\r
+ /**\r
+ * Builds the account value.\r
+ *\r
+ * @param arr the arr\r
+ * @return the account value\r
+ */\r
+ static public AccountValue buildAccountValue(AccountRoleRel arr) {\r
+ AccountValue av = new AccountValue();\r
+ av.setAccountId(arr.getAccountId());\r
+ av.setUserId(arr.getUserId());\r
+ av.setScreenName(arr.getScreenName());\r
+ return av;\r
+ }\r
+ \r
/**\r
* Builds the role value.\r
*\r
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class);
+ private static final String ACCOUNT_PERMISSIONS = "accounts/*/accountperms";
/* (non-Javadoc)
* @see org.jboss.resteasy.spi.interception.PreProcessInterceptor#preProcess(org.jboss.resteasy.spi.HttpRequest, org.jboss.resteasy.core.ResourceMethod)
// If the resource entity is acting as a proxy then all sub-resource will map to the resource itself.
// This essentially means that the sub-resource inherit all the authz permissions of the entity.
//
- if (SecurityUtils.isEntityProxy() == true) {
+ if (SecurityUtils.isEntityProxy() == true && !resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS)) {
resName = resEntity;
}
checkActive();
- AuthZ authZ = AuthZ.get();
- CSpaceResource res = new URIResourceImpl(resName, httpMethod);
- if (!authZ.isAccessAllowed(res)) {
- logger.error("Access to " + res.getId() + " is NOT allowed to "
- + " user=" + AuthN.get().getUserId());
- Response response = Response.status(
- Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
- throw new WebApplicationException(response);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Access to " + res.getId() + " is allowed to "
- + " user=" + AuthN.get().getUserId() +
- " for tenant id=" + AuthN.get().getCurrentTenantName());
+
+ //
+ // All active users are allowed to the their current list of permissions. If this is not
+ // the request, then we'll do a full AuthZ check.
+ //
+ if (resName.equalsIgnoreCase(ACCOUNT_PERMISSIONS) != true) {
+ AuthZ authZ = AuthZ.get();
+ CSpaceResource res = new URIResourceImpl(resName, httpMethod);
+ if (!authZ.isAccessAllowed(res)) {
+ logger.error("Access to " + res.getId() + " is NOT allowed to "
+ + " user=" + AuthN.get().getUserId());
+ Response response = Response.status(
+ Response.Status.FORBIDDEN).entity(uriPath + " " + httpMethod).type("text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Access to " + res.getId() + " is allowed to "
+ + " user=" + AuthN.get().getUserId() +
+ " for tenant id=" + AuthN.get().getCurrentTenantName());
+ }
}
+
return null;
}
*/
package org.collectionspace.services.common.storage.jpa;
+import java.util.List;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import javax.persistence.PersistenceException;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import org.collectionspace.authentication.AuthN;
+import org.collectionspace.services.authorization.AccountPermission;
+import org.collectionspace.services.authorization.AccountValue;
+import org.collectionspace.services.authorization.AccountRole;
+import org.collectionspace.services.authorization.AccountRoleRel;
+import org.collectionspace.services.authorization.AuthZ;
+import org.collectionspace.services.authorization.CSpaceResource;
+import org.collectionspace.services.authorization.PermissionRole;
+import org.collectionspace.services.authorization.PermissionRoleRel;
+import org.collectionspace.services.authorization.PermissionValue;
+import org.collectionspace.services.authorization.URIResourceImpl;
+import org.collectionspace.services.common.authorization_mgt.AuthorizationRoleRel;
import org.collectionspace.services.common.document.DocumentNotFoundException;
+import org.collectionspace.services.common.security.UnauthorizedException;
+import org.collectionspace.services.common.document.JaxbUtils;
import org.collectionspace.services.common.security.SecurityUtils;
import org.slf4j.Logger;
//FIXME: it would be nice to verify tenantid as well
return em.find(entityClazz, id);
}
+
+ private static String getUserId(String csid)
+ throws DocumentNotFoundException {
+ String result = null;
+
+ //FIXME: Why can't the common jar depend on the account service? Can we move the account
+ //jaxb classes to the common "jaxb" module?
+ try {
+ //can't use JAXB here as this runs from the common jar which cannot
+ //depend upon the account service
+ String whereClause = "where csid = :csid";
+ HashMap<String, Object> params = new HashMap<String, Object>();
+ params.put("csid", csid);
+
+ Object account = JpaStorageUtils.getEntity(
+ "org.collectionspace.services.account.AccountsCommon", whereClause, params);
+ if (account == null) {
+ String msg = "User's account not found, csid=" + csid;
+ throw new DocumentNotFoundException(msg);
+ }
+ //
+ // Retrieve the userId that corresponds to the csid passed in to us
+ //
+ result = (String)JaxbUtils.getValue(account, "getUserId");
+ } catch (Exception e) {
+ String msg = "User's account is in invalid state, csid=" + csid;
+ throw new DocumentNotFoundException(msg);
+ }
+
+ return result;
+ }
+
+ //FIXME: This method should be moved to the AccountPermissionDocumemntHandler
+ /*
+ * This is a prototype for the /accounts/{csid}/permissions GET service call.
+ */
+ public static AccountPermission getAccountPermissions(String csid)
+ throws UnauthorizedException, DocumentNotFoundException {
+ //
+ // Make sure the user asking for this list has the correct
+ // permission -that is, the csid's userId match the currently logged in userId or
+ // that they have read access to the "accounts" resource.
+ //
+ String userId = getUserId(csid);
+ String currentUserId = AuthN.get().getUserId();
+ if (currentUserId.equalsIgnoreCase(userId) == false) {
+ CSpaceResource res = new URIResourceImpl("accounts", "GET");
+ if (AuthZ.get().isAccessAllowed(res) == false) {
+ String msg = "Access to the permissions for the account with csid = " + csid + " is NOT allowed for " +
+ " user=" + currentUserId;
+ if (logger.isDebugEnabled() == true) {
+ logger.debug(msg);
+ }
+ throw new UnauthorizedException(msg);
+ }
+ }
+
+ AccountPermission result = new AccountPermission();
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ Iterator<Object[]> tuples = null;
+ try {
+ StringBuilder queryStrBldr = new StringBuilder("SELECT ar, pr FROM " + AccountRoleRel.class.getName() +
+ " ar, " + PermissionRoleRel.class.getName() + " pr" +
+ " WHERE ar.roleId = pr.roleId and ar.userId=" + "'" + userId + "'" +
+ "group by pr.permissionId");
+
+ emf = getEntityManagerFactory();
+ em = emf.createEntityManager();
+ String queryStr = queryStrBldr.toString(); //for debugging
+ Query q = em.createQuery(queryStr);
+ tuples = q.getResultList().iterator();
+ if (tuples.hasNext()) {
+ //
+ // get the first tuple, extract the AccountRoleRel and set the Account value for the result list
+ //
+ Object[] tuple = tuples.next();
+ List<AccountValue> accountValues = new ArrayList<AccountValue>();
+ accountValues.add(AuthorizationRoleRel.buildAccountValue((AccountRoleRel)tuple[0]));
+ //
+ // Since we extracted the first tuple, we need to store the first perm value as well
+ // before iterating over the rest of the tuples.
+ //
+ List<PermissionValue> permissionValues = new ArrayList<PermissionValue>();
+ permissionValues.add(AuthorizationRoleRel.buildPermissionValue((PermissionRoleRel)tuple[1]));
+ //
+ // Now finish add the permission values.
+ //
+ while (tuples.hasNext()) {
+ tuple = tuples.next();
+ permissionValues.add(AuthorizationRoleRel.buildPermissionValue((PermissionRoleRel)tuple[1]));
+ }
+ result.setAccounts(accountValues);
+ result.setPermissions(permissionValues);
+ }
+ } catch (NoResultException nre) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("could not find entity with id=" + userId, nre);
+ }
+ //returns null
+ } catch (Exception e) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("could not find entity(2) with id=" + userId, e);
+ }
+ } finally {
+ if (em != null) {
+ releaseEntityManagerFactory(emf);
+ }
+ }
+
+ return result;
+ }
/**
* getEntity