/** * Copyright (c) 2011-2014, OpenIoT * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL"). If you do not alter this * notice, a recipient may use your version of this file under the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL for * the specific language governing rights and limitations. * * Contact: OpenIoT mailto: info@openiot.eu */ package org.openiot.security.mgmt; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.ViewScoped; import org.jasig.cas.services.RegisteredService; import org.openiot.lsm.security.oauth.LSMRegisteredServiceImpl; import org.openiot.lsm.security.oauth.mgmt.Permission; import org.openiot.lsm.security.oauth.mgmt.Role; import org.openiot.lsm.security.oauth.mgmt.User; import org.openiot.security.client.OAuthorizationCredentials; import org.openiot.security.client.PermissionsUtil; import org.primefaces.context.RequestContext; /** * @author Mehdi Riahi * */ @ManagedBean @ViewScoped public class ServiceController extends AbstractController { private static final long serialVersionUID = 6553286876974799583L; private List<LSMRegisteredServiceImpl> services; private LSMRegisteredServiceImpl newService; private Map<Long, RegisteredService> allServices; @ManagedProperty(value = "#{securityManagerService}") private SecurityManagerService securityManagerService; private boolean restfulService; private boolean editing; private User user; private long myServiceId; public ServiceController() { } public List<LSMRegisteredServiceImpl> getServices() { if (services == null) { services = new ArrayList<>(); final List<RegisteredService> servicesAll = securityManagerService.getAllServices(); allServices = new HashMap<Long, RegisteredService>(servicesAll.size()); OAuthorizationCredentials credentials = Utils.acUtil.getOAuthorizationCredentials(); for (RegisteredService registeredService : servicesAll) { allServices.put(registeredService.getId(), registeredService); if (Utils.acUtil.hasPermission(PermissionsUtil.SEC_MGMT_SERVICE_MGMT + registeredService.getName())) services.add((LSMRegisteredServiceImpl) registeredService); if (registeredService.getName().equals(credentials.getClientId())) myServiceId = registeredService.getId(); } user = securityManagerService.getUser(credentials.getUserId()); } return services; } public void setSecurityManagerService(SecurityManagerService securityManagerService) { this.securityManagerService = securityManagerService; } public boolean isRestfulService() { return restfulService; } public boolean isEditing() { return editing; } public void removeService(LSMRegisteredServiceImpl service) { securityManagerService.deleteRegisteredService(service.getId()); services.remove(service); allServices.remove(service.getId()); addInfoMessage("Service deleted", service.getName()); } public LSMRegisteredServiceImpl getNewService() { if (newService == null) newService = new LSMRegisteredServiceImpl(); return newService; } public void cancelAddService() { newService = null; editing = false; } public void addService() { addServiceInternal(false); } public void addRestService() { addServiceInternal(true); } public void editing(LSMRegisteredServiceImpl service) { newService = service; editing = true; restfulService = isRestful(service); } public void addServiceInternal(boolean isRest) { boolean serviceAdded = false; if (newService != null && newService.getName().trim().length() > 0) { if (editing || isServiceNameUnique(newService) && isServiceNameValid(newService) && isURLValid(newService, isRest)) { if (isRest) { newService.setServiceId("REST://" + newService.getName()); newService.setTheme(newService.getName() + "_"); } if (!editing) { newService.setEnabled(true); newService.setSsoEnabled(true); newService.setAllowedToProxy(true); newService.setAnonymousAccess(false); newService.setIgnoreAttributes(true); newService.setEvaluationOrder(0); newService = securityManagerService.addRegisteredService(newService); services.add(newService); allServices.put(newService.getId(), newService); createAuthorization(newService); addInfoMessage("New service added", newService.getName()); } else { securityManagerService.addRegisteredService(newService); addInfoMessage("Service updated", newService.getName()); } newService = null; serviceAdded = true; editing = false; } else { if (!editing) addErrorMessage("Adding new service failed", "Service key is not unique or service key or URL is not valid"); else addErrorMessage("Updating service failed", "Service URL is not valid"); } } else { addWarnMessage("There is no new service to add", ""); } RequestContext.getCurrentInstance().addCallbackParam("serviceAdded", serviceAdded); } private void createAuthorization(LSMRegisteredServiceImpl service) { Permission serviceMgmtPerm = new Permission("admin:service_mgmt:" + service.getName(), "Permission for managing service " + service.getName(), myServiceId); Permission perm1 = new Permission(PermissionsUtil.SEC_MGMT_CREATE_PERMISSION + service.getName(), "", myServiceId); Permission perm2 = new Permission(PermissionsUtil.SEC_MGMT_CREATE_ROLE + service.getName(), "", myServiceId); Permission perm3 = new Permission(PermissionsUtil.SEC_MGMT_DEL_PERMISSION + service.getName(), "", myServiceId); Permission perm4 = new Permission(PermissionsUtil.SEC_MGMT_DEL_ROLE + service.getName(), "", myServiceId); Permission perm5 = new Permission(PermissionsUtil.SEC_MGMT_GRANT_ROLE + service.getName(), "", myServiceId); Permission perm6 = new Permission(PermissionsUtil.SEC_MGMT + service.getName(), "", myServiceId); Permission mgmtAllPerm = new Permission(PermissionsUtil.SEC_MGMT_ALL + service.getName(), "", myServiceId); Permission[] perms = new Permission[] { perm1, perm2, perm3, perm4, perm5, perm6 }; Role serviceAdminRole = null; String serviceAdminRoleName = PermissionsUtil.SEC_MGMT_SERVICE_MGMT + service.getName(); boolean isAdmin = Utils.acUtil.hasPermission("*"); if (!isAdmin) { for (Role r : user.getRoles()) { if (r.getServiceId() == service.getId() && r.getName().equals(serviceAdminRoleName)) { serviceAdminRole = r; break; } } } if (serviceAdminRole == null) { serviceAdminRole = new Role(serviceAdminRoleName, "Role for managing service " + service.getName(), myServiceId); if (!isAdmin) user.addRole(serviceAdminRole); } serviceAdminRole.addPermission(serviceMgmtPerm); Role userMgmtRole = new Role("user_mgmt_all:" + service.getName(), "", myServiceId); userMgmtRole.addPermission(mgmtAllPerm); if (!isAdmin) user.addRole(userMgmtRole); securityManagerService.addRole(serviceAdminRole); securityManagerService.addRole(userMgmtRole); if(!isAdmin){ //TODO: replace with an addRoleToUser() or updateUser() method securityManagerService.deleteUser(user.getUsername()); securityManagerService.addUser(user); // clearing the cache in order to see the new permission modifications Utils.acUtil.reset(); } for (Permission perm : perms) securityManagerService.addPermission(perm); } public boolean isRestful(LSMRegisteredServiceImpl service) { restfulService = service.getServiceId().toLowerCase().startsWith("rest://"); return restfulService; } private boolean isURLValid(LSMRegisteredServiceImpl service, boolean isRest) { if (isRest) return true; String serviceURLLowCase = service.getServiceId().toLowerCase(); return serviceURLLowCase.startsWith("http://") || serviceURLLowCase.startsWith("https://"); } public boolean isServiceNameUnique(LSMRegisteredServiceImpl service) { for (RegisteredService r : allServices.values()) if (r.getName().equals(service.getName())) return false; return true; } public boolean isServiceNameValid(LSMRegisteredServiceImpl service) { return !service.getName().matches(".*(\\s|__|/).*"); } }