/**********************************************************************************
* $URL:https://source.sakaiproject.org/svn/osp/trunk/common/api-impl/src/java/org/theospi/portfolio/security/impl/sakai/WorksiteAwareAuthorizationFacade.java $
* $Id:WorksiteAwareAuthorizationFacade.java 9134 2006-05-08 20:28:42Z chmaurer@iupui.edu $
***********************************************************************************
*
* Copyright (c) 2005, 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.theospi.portfolio.security.impl.sakai;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.metaobj.security.impl.sakai.SecurityBase;
import org.sakaiproject.metaobj.shared.mgt.AgentManager;
import org.sakaiproject.metaobj.shared.model.Agent;
import org.sakaiproject.metaobj.shared.model.Id;
import org.sakaiproject.metaobj.shared.model.OspRole;
import org.sakaiproject.thread_local.api.ThreadLocalManager;
import org.sakaiproject.authz.cover.AuthzGroupService;
import org.sakaiproject.site.api.SiteService.SelectionType;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.tool.cover.ToolManager;
import org.theospi.portfolio.security.Authorization;
import org.theospi.portfolio.security.impl.simple.SimpleAuthorizationFacade;
public class WorksiteAwareAuthorizationFacade extends SimpleAuthorizationFacade {
protected final transient Log logger = LogFactory.getLog(getClass());
private AgentManager agentManager = null;
private SecurityBase sakaiSecurityBase;
private ThreadLocalManager threadLocalManager;
private static final String AUTHZ_GROUPS_LIST =
"org.theospi.portfolio.security.impl.sakai.WorksiteAwareAuthorizationFacade.authzGroups";
/**
* @param agent
* @param function
* @param id
*/
public void createAuthorization(Agent agent, String function, Id id) {
// don't want to include roles here otherwise can't explicitly create authz for both role and user
// see bug http://cvs.theospi.org:14443/jira/browse/OSP-459
Authorization auth = getAuthorization(agent, function, id, false);
if (auth == null) {
auth = new Authorization(agent, function, id);
}
getHibernateTemplate().saveOrUpdate(auth);
}
public void deleteAuthorization(Agent agent, String function, Id id) {
Authorization auth = getAuthorization(agent, function, id, false);
if (auth != null) {
getHibernateTemplate().delete(auth);
}
}
public void pushAuthzGroups(Collection authzGroups) {
List authzGroupList = getAuthzGroupsList();
authzGroupList.addAll(authzGroups);
}
public void pushAuthzGroups(String siteId) {
getAuthzGroupsList().add(siteId);
}
protected Authorization getAuthorization(Agent agent, String function, Id id, boolean includeRoles) {
// Try the direct user check first
Authorization userAuthz = super.getAuthorization(agent, function, id);
if (userAuthz == null && includeRoles) {
if (logger.isDebugEnabled())
logger.debug("userAuthz was null, so checking roles, agent, function, id: " + agent.getDisplayName() + "(" + agent.getId().getValue() + "), " + function + ", " + id.getValue());
// Retrieve the set of object-level grants for this object and function.
// Multiple roles in a realm may be permitted, so we use a realm->roles hash.
HashMap<String, List<String>> azgs = new HashMap<String, List<String>>();
for (Authorization authz : (List<Authorization>) findByFunctionId(function, id)) {
Agent a = authz.getAgent();
if (a instanceof OspRole) {
OspRole role = (OspRole) a;
String realmId = role.getSakaiRealm().getId();
if (!azgs.containsKey(realmId)) {
azgs.put(realmId, new ArrayList<String>());
}
if (logger.isDebugEnabled())
logger.debug("Building object grant list, adding role for azg: " + role + ", " + realmId);
azgs.get(realmId).add(role.getRoleName());
}
}
// Compare the permitted roles against the ones granted to this user.
if (azgs.size() > 0) {
Map<String, String> grants = AuthzGroupService.getUserRoles(agent.getId().getValue(), azgs.keySet());
for (Map.Entry entry : grants.entrySet()) {
if (azgs.containsKey(entry.getKey())) {
// Grab the list of permitted roles for this realm, since the user is a member, and compare.
List<String> needed = azgs.get(entry.getKey());
String granted = entry.getValue().toString();
if (needed.contains(granted)) {
if (logger.isDebugEnabled())
logger.debug("Generating realmRole authz - (realmId, role), function, id: (" + entry.getKey() + ", " + granted + "), " + function + ", " + id);
return new Authorization(agentManager.getRealmRole(granted, entry.getKey().toString()), function, id);
}
}
}
}
}
// If we've fallen through, return whatever the result of the user check
return userAuthz;
}
protected Authorization getAuthorization(Agent agent, String function, Id id) {
return getAuthorization(agent, function, id, true);
}
protected List findByAgent(Agent agent) {
Set roles = getAgentRoles(agent);
List authzs = new ArrayList();
for (Iterator i=roles.iterator();i.hasNext();) {
Agent next = (Agent)i.next();
if (next != null) {
authzs.addAll(super.findByAgent((Agent)i.next()));
}
}
authzs.addAll(super.findByAgent(agent));
return authzs;
}
protected List findByAgentFunction(Agent agent, String function) {
Set roles = getAgentRoles(agent);
List authzs = new ArrayList();
for (Iterator i=roles.iterator();i.hasNext();) {
Agent next = (Agent)i.next();
if (next != null) {
authzs.addAll(super.findByAgentFunction(
next, function));
}
}
authzs.addAll(super.findByAgentFunction(agent, function));
return authzs;
}
protected List findByAgentId(Agent agent, Id id) {
Set roles = getAgentRoles(agent);
List authzs = new ArrayList();
for (Iterator i=roles.iterator();i.hasNext();) {
Agent next = (Agent)i.next();
if (next != null) {
authzs.addAll(super.findByAgentId(
(Agent)i.next(), id));
}
}
authzs.addAll(super.findByAgentId(agent, id));
return authzs;
}
protected Set getAgentRoles(Agent agent) {
Set agentRoles = new HashSet();
List authzGroups = getAuthzGroupsList();
for (Iterator i = authzGroups.iterator();i.hasNext();) {
String site = (String)i.next();
agentRoles.addAll(agent.getWorksiteRoles(site));
}
// If this is a user's My Workspace, aggregate roles from all member sites
if ( ToolManager.getCurrentPlacement() != null && SiteService.isUserSite(ToolManager.getCurrentPlacement().getContext()) ) {
List allSites = SiteService.getSites(SelectionType.ACCESS, null, null,
null, null, null);
allSites.addAll ( SiteService.getSites(SelectionType.UPDATE, null, null,
null, null, null) );
Set<Site> siteSet = new HashSet<Site>(allSites);
for (Site site : siteSet) {
agentRoles.addAll(agent.getWorksiteRoles( site.getId() ));
}
// finally, add user agent for user-based aurhorizations
agentRoles.add(agent);
}
// Otherwise just get roles from current worksite
else {
agentRoles.addAll(agent.getWorksiteRoles());
}
return agentRoles;
}
public AgentManager getAgentManager() {
return agentManager;
}
public void setAgentManager(AgentManager agentManager) {
this.agentManager = agentManager;
}
public SecurityBase getSakaiSecurityBase() {
return sakaiSecurityBase;
}
public void setSakaiSecurityBase(SecurityBase sakaiSecurityBase) {
this.sakaiSecurityBase = sakaiSecurityBase;
}
public ThreadLocalManager getThreadLocalManager() {
return threadLocalManager;
}
public void setThreadLocalManager(ThreadLocalManager threadLocalManager) {
this.threadLocalManager = threadLocalManager;
}
protected List getAuthzGroupsList() {
List returned = (List)threadLocalManager.get(AUTHZ_GROUPS_LIST);
if (returned == null) {
returned = new ArrayList();
threadLocalManager.set(AUTHZ_GROUPS_LIST, returned);
}
return returned;
}
}