/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you 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 the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>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.apereo.portal.spring.security.evaluator; import java.io.Serializable; import javax.servlet.http.HttpServletRequest; import org.apereo.portal.layout.dlm.remoting.IGroupListHelper; import org.apereo.portal.layout.dlm.remoting.JsonEntityBean; import org.apereo.portal.portlets.groupselector.EntityEnum; import org.apereo.portal.security.IAuthorizationPrincipal; import org.apereo.portal.security.IPermission; import org.apereo.portal.security.IPerson; import org.apereo.portal.security.IPersonManager; import org.apereo.portal.security.PersonFactory; import org.apereo.portal.services.AuthorizationService; import org.apereo.portal.url.IPortalRequestUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; /** * PortalPermissionEvaluator provides support for Spring EL hasPermission expressions in method * security annotations. This current implementation is an early attempt at connecting the uPortal * permissions framework to Spring Security and will need future adjustment and expansion. * */ public class PortalPermissionEvaluator implements PermissionEvaluator { @Autowired private IPortalRequestUtils portalRequestUtils; @Autowired private IPersonManager personManager; private IGroupListHelper groupListHelper; @Autowired public void setGroupListHelper(IGroupListHelper groupListHelper) { this.groupListHelper = groupListHelper; } private AuthorizationService authorizationService; @Override public boolean hasPermission( Authentication authentication, Object targetDomainObject, Object permission) { if (authorizationService == null) { authorizationService = AuthorizationService.instance(); } final IAuthorizationPrincipal principal = getAuthorizationPrincipal(authentication); String targetId = null; if (targetDomainObject instanceof String) { // Assume it already represents a valid uPortal permission target targetId = (String) targetDomainObject; } else if (targetDomainObject instanceof JsonEntityBean) { // JsonEntityBean objects now have a targetString member targetId = ((JsonEntityBean) targetDomainObject).getTargetString(); } // if the permission is already an AuthorizableActivity, go ahead and // use it AuthorizableActivity activity = null; if (permission instanceof AuthorizableActivity) { activity = (AuthorizableActivity) permission; } // if the permission is a string, allow our local method to try and // translate it into a permission relevant to the provided target else if (permission instanceof String) { String activityName = (String) permission; activity = getViewActivity(activityName, (JsonEntityBean) targetDomainObject); } else { throw new RuntimeException( "Unable to determine permission target id for type " + targetDomainObject.getClass()); } if (activity != null) { final boolean hasPermission = principal.hasPermission( activity.getOwnerFname(), activity.getActivityFname(), targetId); return hasPermission; } else { return false; } } @Override public boolean hasPermission( Authentication authentication, Serializable targetId, String targetType, Object permission) { if (authorizationService == null) { authorizationService = AuthorizationService.instance(); } final IAuthorizationPrincipal principal = getAuthorizationPrincipal(authentication); // if the permission is already an AuthorizableActivity, go ahead and // use it AuthorizableActivity activity = null; if (permission instanceof AuthorizableActivity) { activity = (AuthorizableActivity) permission; } // if the permission is a string, allow our local method to try and // translate it into a permission relevant to the provided target else if (permission instanceof String && targetId instanceof String) { String activityName = (String) permission; activity = getViewActivity(activityName, (String) targetId); } if (activity != null) { final boolean hasPermission = principal.hasPermission( activity.getOwnerFname(), activity.getActivityFname(), targetId.toString()); return hasPermission; } else { return false; } } /* * Implementation */ /** Prepare a uPortal IAuthorizationPrincipal based in the Spring principal */ private IAuthorizationPrincipal getAuthorizationPrincipal(Authentication authentication) { String username = PersonFactory.GUEST_USERNAMES.get(0); // default -- first unauthenticated user Object authPrincipal = authentication.getPrincipal(); if (authPrincipal instanceof UserDetails) { // User is authenticated UserDetails userDetails = (UserDetails) authPrincipal; username = userDetails.getUsername(); } else { // Which guest user are we? final HttpServletRequest req = portalRequestUtils.getCurrentPortalRequest(); final IPerson person = personManager.getPerson(req); username = person.getUserName(); } return authorizationService.newPrincipal(username, IPerson.class); } private AuthorizableActivity getViewActivity( final String activityKey, final JsonEntityBean entity) { if (entity != null && activityKey.equals("VIEW")) { final EntityEnum type = entity.getEntityType(); if (type.isGroup()) { return new AuthorizableActivity( IPermission.PORTAL_GROUPS, IPermission.VIEW_GROUP_ACTIVITY); } else if (type.equals(EntityEnum.PERSON)) { return new AuthorizableActivity( IPermission.PORTAL_USERS, IPermission.VIEW_USER_ACTIVITY); } else if (type.equals(EntityEnum.PORTLET)) { return new AuthorizableActivity( IPermission.PORTAL_SUBSCRIBE, IPermission.PORTLET_SUBSCRIBER_ACTIVITY); } } return null; } private AuthorizableActivity getViewActivity(final String activityKey, final String target) { final JsonEntityBean entity = groupListHelper.getEntityForPrincipal(target); return getViewActivity(activityKey, entity); } }