| /* |
| * Copyright 1999-2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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. |
| * |
| */ |
| |
| package org.apache.lenya.cms.ac.usecase; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.apache.avalon.framework.activity.Disposable; |
| import org.apache.avalon.framework.logger.AbstractLogEnabled; |
| import org.apache.avalon.framework.parameters.ParameterException; |
| import org.apache.avalon.framework.parameters.Parameterizable; |
| import org.apache.avalon.framework.parameters.Parameters; |
| import org.apache.avalon.framework.service.ServiceException; |
| import org.apache.avalon.framework.service.ServiceManager; |
| import org.apache.avalon.framework.service.Serviceable; |
| import org.apache.cocoon.environment.Request; |
| import org.apache.excalibur.source.SourceResolver; |
| import org.apache.lenya.ac.AccessControlException; |
| import org.apache.lenya.ac.Authorizer; |
| import org.apache.lenya.ac.Role; |
| import org.apache.lenya.ac.cache.CachingException; |
| import org.apache.lenya.ac.cache.SourceCache; |
| import org.apache.lenya.ac.impl.PolicyAuthorizer; |
| import org.apache.lenya.cms.publication.URLInformation; |
| import org.apache.lenya.cms.repo.Publication; |
| import org.apache.lenya.cms.repo.RepositoryException; |
| import org.apache.lenya.cms.repo.Session; |
| import org.apache.lenya.cms.repo.impl.RepositoryUtil; |
| import org.apache.lenya.util.ServletHelper; |
| |
| /** |
| * Authorizer for usecases. |
| * @version $Id$ |
| */ |
| public class UsecaseAuthorizer extends AbstractLogEnabled implements Authorizer, Serviceable, |
| Disposable, Parameterizable { |
| |
| protected static final String TYPE = "usecase"; |
| protected static final String USECASE_PARAMETER = "lenya.usecase"; |
| |
| private SourceCache cache; |
| private String configurationUri; |
| |
| /** |
| * Returns the configuration source cache. |
| * @return A source cache. |
| */ |
| public SourceCache getCache() { |
| return this.cache; |
| } |
| |
| /** |
| * Returns the source URI of the usecase role configuration file for a certain publication. |
| * |
| * @param publication The publication. |
| * @return A string representing a URI. |
| */ |
| protected String getConfigurationURI(Publication publication) { |
| try { |
| return "context://lenya/pubs/" + publication.getPublicationId() + CONFIGURATION_FILE; |
| } catch (RepositoryException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| /** |
| * @see org.apache.lenya.ac.Authorizer#authorize(org.apache.cocoon.environment.Request) |
| */ |
| public boolean authorize(Request request) throws AccessControlException { |
| |
| String usecase = request.getParameter(USECASE_PARAMETER); |
| boolean authorized = true; |
| |
| SourceResolver resolver = null; |
| |
| try { |
| resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); |
| if (usecase != null) { |
| |
| String _configurationUri; |
| if (getConfigurationURI() != null) { |
| _configurationUri = getConfigurationURI(); |
| } else { |
| Session session = RepositoryUtil.getSession(this.manager, request, getLogger()); |
| String url = ServletHelper.getWebappURI(request); |
| String pubId = new URLInformation(url).getPublicationId(); |
| Publication publication = session.getPublication(pubId); |
| _configurationUri = getConfigurationURI(publication); |
| } |
| |
| Role[] roles = PolicyAuthorizer.getRoles(request); |
| authorized = authorizeUsecase(usecase, roles, _configurationUri); |
| } else { |
| getLogger().debug("No usecase to authorize. Granting access."); |
| } |
| } catch (final ServiceException e) { |
| throw new AccessControlException(e); |
| } catch (final Exception e) { |
| throw new AccessControlException(e); |
| } finally { |
| if (resolver != null) { |
| this.manager.release(resolver); |
| } |
| } |
| |
| return authorized; |
| } |
| |
| /** |
| * Authorizes a usecase. |
| * |
| * @param usecase The usecase ID. |
| * @param roles The roles of the current identity. |
| * @param _configurationUri The URI to retrieve the policy configuration from. |
| * @return A boolean value. |
| * @throws AccessControlException when something went wrong. |
| */ |
| public boolean authorizeUsecase(String usecase, Role[] roles, String _configurationUri) |
| throws AccessControlException { |
| getLogger().debug("Authorizing usecase [" + usecase + "]"); |
| boolean authorized = true; |
| |
| UsecaseRolesBuilder builder = new UsecaseRolesBuilder(); |
| UsecaseRoles usecaseRoles; |
| try { |
| usecaseRoles = (UsecaseRoles) getCache().get(_configurationUri, builder); |
| } catch (CachingException e) { |
| throw new AccessControlException(e); |
| } |
| |
| if (usecaseRoles == null) { |
| throw new AccessControlException("Usecase policies configuration not found at [" |
| + _configurationUri + "]"); |
| } |
| |
| if (usecaseRoles.hasRoles(usecase)) { |
| |
| getLogger().debug("Roles for usecase found."); |
| |
| List usecaseRoleIds = Arrays.asList(usecaseRoles.getRoles(usecase)); |
| |
| int i = 0; |
| authorized = false; |
| while (!authorized && i < roles.length) { |
| authorized = usecaseRoleIds.contains(roles[i].getId()); |
| getLogger().debug("Authorization for role [" + roles[i].getId() + "] is [" |
| + authorized + "]"); |
| i++; |
| } |
| } else { |
| getLogger().debug("No roles for usecase found. Granting access."); |
| } |
| return authorized; |
| } |
| |
| private ServiceManager manager; |
| |
| /** |
| * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager) |
| */ |
| public void service(ServiceManager _manager) throws ServiceException { |
| getLogger().debug("Servicing [" + getClass().getName() + "]"); |
| this.manager = _manager; |
| this.cache = (SourceCache) _manager.lookup(SourceCache.ROLE); |
| } |
| |
| /** |
| * @see org.apache.avalon.framework.activity.Disposable#dispose() |
| */ |
| public void dispose() { |
| if (getCache() != null) { |
| this.manager.release(getCache()); |
| } |
| } |
| |
| protected static final String CONFIGURATION_FILE = "/config/ac/usecase-policies.xml"; |
| protected static final String PARAMETER_CONFIGURATION = "configuration"; |
| |
| /** |
| * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters) |
| */ |
| public void parameterize(Parameters parameters) throws ParameterException { |
| if (parameters.isParameter(PARAMETER_CONFIGURATION)) { |
| this.configurationUri = parameters.getParameter(PARAMETER_CONFIGURATION); |
| } |
| } |
| |
| /** |
| * Returns the configuration URL. |
| * @return The configuration URL. |
| */ |
| public String getConfigurationURI() { |
| return this.configurationUri; |
| } |
| |
| /** |
| * Authorizes a usecase. |
| * |
| * @param usecase The usecase to authorize. |
| * @param roles The roles of the identity. |
| * @param publication The publication. |
| * @return A boolean value. |
| * @throws AccessControlException when something went wrong. |
| */ |
| public boolean authorizeUsecase(String usecase, Role[] roles, Publication publication) |
| throws AccessControlException { |
| return authorizeUsecase(usecase, roles, getConfigurationURI(publication)); |
| } |
| |
| /** |
| * FIXME: Should this be exposed publically now that this method signature has been removed from |
| * Authorizer? |
| */ |
| public boolean authorize(Request request, String webappUrl) throws AccessControlException { |
| return authorize(request); |
| } |
| |
| } |