From: Sanjay Dalal Date: Fri, 30 Apr 2010 19:03:56 +0000 (+0000) Subject: NOJIRA introduced high level security context for service runtime. provides access... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=7f491341d803e2cf9e582f030340f7606f86a695;p=tmp%2Fjakarta-migration.git NOJIRA introduced high level security context for service runtime. provides access to userid, tenantid and tenantname. uses authn context underneath. test: all service tests M context/ServiceContext.java M context/AbstractServiceContextImpl.java A security/SecurityContext.java A security/SecurityContextImpl.java --- diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index 00ea2611e..4a11f52e9 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -23,20 +23,13 @@ */ package org.collectionspace.services.common.context; -import java.security.acl.Group; import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import javax.security.auth.Subject; -import javax.security.jacc.PolicyContext; -import javax.security.jacc.PolicyContextException; import javax.ws.rs.core.MultivaluedMap; import org.collectionspace.authentication.AuthN; -import org.collectionspace.authentication.CSpaceTenant; import org.collectionspace.services.common.ClientType; import org.collectionspace.services.common.ServiceMain; @@ -45,10 +38,11 @@ import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.ValidatorHandler; +import org.collectionspace.services.common.security.SecurityContext; +import org.collectionspace.services.common.security.SecurityContextImpl; import org.collectionspace.services.common.security.UnauthorizedException; import org.collectionspace.services.common.service.ObjectPartType; import org.collectionspace.services.common.service.ServiceBindingType; -import org.collectionspace.services.common.service.ServiceObjectType; import org.collectionspace.services.common.tenant.TenantBindingType; import org.collectionspace.services.common.types.PropertyItemType; import org.collectionspace.services.common.types.PropertyType; @@ -78,33 +72,28 @@ public abstract class AbstractServiceContextImpl /** The logger. */ final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class); - /** The properties. */ Map properties = new HashMap(); - /** The object part map. */ Map objectPartMap = new HashMap(); - /** The service binding. */ private ServiceBindingType serviceBinding; - /** The tenant binding. */ private TenantBindingType tenantBinding; - /** The override document type. */ private String overrideDocumentType = null; - /** The val handlers. */ private List valHandlers = null; - /** The doc handler. */ private DocumentHandler docHandler = null; + /** security context */ + private SecurityContext securityContext; - private AbstractServiceContextImpl() {} // private constructor for singleton pattern - + private AbstractServiceContextImpl() { + } // private constructor for singleton pattern // request query params private MultivaluedMap queryParams; - + /** * Instantiates a new abstract service context impl. * @@ -113,15 +102,16 @@ public abstract class AbstractServiceContextImpl * @throws UnauthorizedException the unauthorized exception */ protected AbstractServiceContextImpl(String serviceName) throws UnauthorizedException { + + //establish security context + securityContext = new SecurityContextImpl(); + //make sure tenant context exists + checkTenantContext(); + + //retrieve service bindings TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader(); - //FIXME retrieveTenantId is not working consistently in non-auth mode - //TODO: get tenant binding from security context - String tenantId = retrieveTenantId(); - if (tenantId == null) { - //for testing purposes - tenantId = "1"; //hardcoded for movingimages.us - } + String tenantId = securityContext.getCurrentTenantId(); tenantBinding = tReader.getTenantBinding(tenantId); if (tenantBinding == null) { String msg = "No tenant binding found for tenantId=" + tenantId @@ -180,13 +170,13 @@ public abstract class AbstractServiceContextImpl * @return the properties for part */ public List getPropertiesForPart(String partLabel) { - Map partMap = getPartsMetadata(); - ObjectPartType part = partMap.get(partLabel); - if(part==null) { - throw new RuntimeException("No such part found: "+partLabel); - } - List propNodeList = part.getProperties(); - return propNodeList.isEmpty()?null:propNodeList.get(0).getItem(); + Map partMap = getPartsMetadata(); + ObjectPartType part = partMap.get(partLabel); + if (part == null) { + throw new RuntimeException("No such part found: " + partLabel); + } + List propNodeList = part.getProperties(); + return propNodeList.isEmpty() ? null : propNodeList.get(0).getItem(); } /** @@ -197,9 +187,9 @@ public abstract class AbstractServiceContextImpl * @return List of property values for the matched property on the named schema part. */ public List getPropertyValuesForPart(String partLabel, String propName, boolean qualified) { - List allProps = getPropertiesForPart(partLabel); - return PropertyItemUtils.getPropertyValuesByName(allProps, propName, - (qualified?(partLabel+":"):null)); + List allProps = getPropertiesForPart(partLabel); + return PropertyItemUtils.getPropertyValuesByName(allProps, propName, + (qualified ? (partLabel + ":") : null)); } /** @@ -211,14 +201,14 @@ public abstract class AbstractServiceContextImpl public List getAllPartsPropertyValues(String propName, boolean qualified) { return ServiceBindingUtils.getAllPartsPropertyValues(getServiceBinding(), propName, qualified); } - + /* (non-Javadoc) * @see org.collectionspace.services.common.context.ServiceContext#getServiceBindingPropertyValue(java.lang.String) */ public String getServiceBindingPropertyValue(String propName) { return ServiceBindingUtils.getPropertyValue(getServiceBinding(), propName); } - + /** * Gets the common part properties. * @@ -326,12 +316,22 @@ public abstract class AbstractServiceContextImpl overrideDocumentType = docType; } + @Override + public SecurityContext getSecurityContext() { + return securityContext; + } + + @Override + public String getUserId() { + return securityContext.getUserId(); + } + /* (non-Javadoc) * @see org.collectionspace.services.common.context.ServiceContext#getTenantId() */ @Override public String getTenantId() { - return tenantBinding.getId(); + return securityContext.getCurrentTenantId(); } /* (non-Javadoc) @@ -339,7 +339,7 @@ public abstract class AbstractServiceContextImpl */ @Override public String getTenantName() { - return tenantBinding.getName(); + return securityContext.getCurrentTenantName(); } /* (non-Javadoc) @@ -396,27 +396,23 @@ public abstract class AbstractServiceContextImpl properties.put(name, o); } - /** - * Retrieve tenant id. - * + * checkTenantContext makss sure tenant context exists + * * @return the string - * + * * @throws UnauthorizedException the unauthorized exception */ - private String retrieveTenantId() throws UnauthorizedException { + private void checkTenantContext() throws UnauthorizedException { - String[] tenantIds = AuthN.get().getTenantIds(); - if (tenantIds.length == 0) { + String tenantId = securityContext.getCurrentTenantId(); + if (tenantId == null) { String msg = "Could not find tenant context"; logger.error(msg); throw new UnauthorizedException(msg); } - //TODO: if a user is associated with more than one tenants, the tenant - //id should be matched with the one sent over the wire - return tenantIds[0]; } - + /** * Creates the document handler instance. * @@ -441,8 +437,8 @@ public abstract class AbstractServiceContextImpl DocumentFilter docFilter = docHandler.createDocumentFilter(); docFilter.setPagination(this.getQueryParams()); docHandler.setDocumentFilter(docFilter); - - return docHandler; + + return docHandler; } /* (non-Javadoc) @@ -450,23 +446,23 @@ public abstract class AbstractServiceContextImpl */ @Override public DocumentHandler getDocumentHandler() throws Exception { - DocumentHandler result = docHandler; - // create a new instance if one does not yet exist - if (result == null) { - result = createDocumentHandlerInstance(); - } - return result; - } - + DocumentHandler result = docHandler; + // create a new instance if one does not yet exist + if (result == null) { + result = createDocumentHandlerInstance(); + } + return result; + } + /* (non-Javadoc) * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHanlder(javax.ws.rs.core.MultivaluedMap) */ @Override public DocumentHandler getDocumentHandler(MultivaluedMap queryParams) throws Exception { - DocumentHandler result = getDocumentHandler(); - DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view - documentFilter.setPagination(queryParams); - return result; + DocumentHandler result = getDocumentHandler(); + DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view + documentFilter.setPagination(queryParams); + return result; } /** @@ -527,14 +523,14 @@ public abstract class AbstractServiceContextImpl msg.append("]"); return msg.toString(); } - + @Override public MultivaluedMap getQueryParams() { - return this.queryParams; + return this.queryParams; } - + @Override public void setQueryParams(MultivaluedMap queryParams) { - this.queryParams = queryParams; - } + this.queryParams = queryParams; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java index f497f4ebe..fd53db1f1 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java @@ -31,6 +31,8 @@ import javax.ws.rs.core.MultivaluedMap; import org.collectionspace.services.common.ClientType; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.document.ValidatorHandler; +import org.collectionspace.services.common.security.SecurityContext; +import org.collectionspace.services.common.security.UnauthorizedException; import org.collectionspace.services.common.service.ObjectPartType; import org.collectionspace.services.common.service.ServiceBindingType; @@ -46,19 +48,28 @@ public interface ServiceContext { * The character used to separate the words in a part label */ public static final String PART_LABEL_SEPERATOR = "_"; - /** The Constant PART_COMMON_LABEL. */ public static final String PART_COMMON_LABEL = "common"; - + + /** + * getSecurityContext is contains security info. for the service layer + */ + public SecurityContext getSecurityContext(); + /** - * getTenantId get id of tenant for which service is accessed - * @return tenant id + * getUserId get authenticated user's userId + */ + public String getUserId(); + + /** + * getTenantId get id of tenant to which authenticated user is associated with + * @return tenant id, null if tenant context not found */ public String getTenantId(); /** - * getTenantName get tenant name from the binding - * @return tenant name such as movingimage.us + * getTenantName get tenant name o which authenticated user is associated with + * @return tenant name such as movingimage.us, null if tenant context not found */ public String getTenantName(); @@ -132,7 +143,6 @@ public interface ServiceContext { */ public String getRepositoryWorkspaceId(); - /** * Get input parts as received over the wire from service consumer * @return the input @@ -176,21 +186,19 @@ public interface ServiceContext { * @return label */ public String getCommonPartLabel(String schemaName); - + /** * getProperties retruns user-defined properties associated with this context * @return */ public Map getProperties(); - /** * setProperties sets user-defined properties to this context * @param props */ public void setProperties(Map props); - /** * getProperty returns specified user-defined property */ @@ -200,7 +208,7 @@ public interface ServiceContext { * setProperty sets user-defined property with given name */ public void setProperty(String name, Object o); - + /** * getServiceBindingPropertyValue returns configured property */ @@ -212,7 +220,7 @@ public interface ServiceContext { * @return document handler */ public DocumentHandler getDocumentHandler() throws Exception; - + /** * Gets the document hanlder. * @@ -222,7 +230,7 @@ public interface ServiceContext { * * @throws Exception the exception */ - public DocumentHandler getDocumentHandler(MultivaluedMap queryParams) throws Exception; + public DocumentHandler getDocumentHandler(MultivaluedMap queryParams) throws Exception; /** * getValidatorHandlers returns registered (from binding) validtor handlers @@ -230,20 +238,20 @@ public interface ServiceContext { * @return validation handlers */ public List getValidatorHandlers() throws Exception; - + /** * Gets the query params. * * @return the query params */ public MultivaluedMap getQueryParams(); - + /** * Sets the query params. * * @param queryParams the query params */ - public void setQueryParams(MultivaluedMap queryParams); + public void setQueryParams(MultivaluedMap queryParams); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContext.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContext.java new file mode 100644 index 000000000..19ecefc5f --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContext.java @@ -0,0 +1,59 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.collectionspace.services.common.security; + +import org.collectionspace.authentication.CSpaceTenant; + +/** + * Security context holds security related data that is useful to the service layer + * this context is relevant only during the request processing in the service layer + * @author + */ +public interface SecurityContext { + + /** + * getUserId get userid (principal id) of the logged in user + * @return + */ + public String getUserId(); + + /** + * getCurrentTenantId get id of the tenant for which the user has logged in + * @return tenant id, null if does not exist + * @return + */ + public String getCurrentTenantId(); + + /** + * getCurrentTenantName get name of the tenant for which the user has logged in + * @return tenant name, null if does not exist + * @return + */ + public String getCurrentTenantName(); + +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContextImpl.java new file mode 100644 index 000000000..fb6d38298 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityContextImpl.java @@ -0,0 +1,66 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2010 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.collectionspace.services.common.security; + +import org.collectionspace.authentication.AuthN; +import org.collectionspace.authentication.CSpaceTenant; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author + */ +public class SecurityContextImpl implements SecurityContext { + + final Logger logger = LoggerFactory.getLogger(SecurityContextImpl.class); + private String userId; + private CSpaceTenant[] tenants = new CSpaceTenant[0]; + private String[] tenantIds = new String[0]; + + public SecurityContextImpl() { + userId = AuthN.get().getUserId(); + tenantIds = AuthN.get().getTenantIds(); + tenants = AuthN.get().getTenants(); + } + + @Override + public String getUserId() { + return userId; + } + + @Override + public String getCurrentTenantId() { + return tenantIds[0]; + } + + @Override + public String getCurrentTenantName() { + return tenants[0].getName(); + } +}