/** * Copyright (C) 2014 KAIST * @author Janggwan Im <limg00n@kaist.ac.kr> */ package org.fosstrak.ale.server.ac; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.namespace.QName; import org.apache.log4j.Logger; import org.fosstrak.ale.server.ALEApplicationContext; import org.fosstrak.ale.server.ALESettings; import org.fosstrak.ale.wsdl.aleac.epcglobal.ClientIdentityValidationExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.DuplicateClientIdentityExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.DuplicatePermissionExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.DuplicateRoleExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.ImplementationExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.NoSuchClientIdentityExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.NoSuchPermissionExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.NoSuchRoleExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.PermissionValidationExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.RoleValidationExceptionResponse; import org.fosstrak.ale.wsdl.aleac.epcglobal.UnsupportedOperationExceptionResponse; import org.fosstrak.ale.xsd.ale.epcglobal.ACClientCredential; import org.fosstrak.ale.xsd.ale.epcglobal.ACClientIdentity; import org.fosstrak.ale.xsd.ale.epcglobal.ACPermission; import org.fosstrak.ale.xsd.ale.epcglobal.ACRole; import org.fosstrak.ale.xsd.ale.epcglobal.ACClientIdentity.Credentials; import org.fosstrak.ale.xsd.ale.epcglobal.ACClientIdentity.RoleNames; import org.fosstrak.ale.xsd.ale.epcglobal.ACPermission.Instances; import org.fosstrak.ale.xsd.ale.epcglobal.ACRole.PermissionNames; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * This class implements ALE Access Control API * * @author Janggwan Im <limg00n@kaist.ac.kr> * */ @Service("aleac") public class ALEACImpl { /** * logger. */ private static final Logger LOG = Logger.getLogger(ALEACImpl.class); public RoleBasedAccessController rbac;// = new FortressRBACClient(); private String loggedInId = null; @Autowired private ALESettings aleSettings; @Autowired public void setAleSettings(ALESettings aleSettings) { this.aleSettings = aleSettings; } public ALESettings getAleSettings() { return aleSettings; } public List<String> getPermissionNames() throws org.fosstrak.ale.exception.SecurityException { List<String> toReturn = new ArrayList<String>(); List<Permission> listPerm = findPermissions(""); for(Permission p : listPerm) { toReturn.add(p.getObjectName()); } return toReturn; } public void definePermission(String permName, ACPermission perm) throws org.fosstrak.ale.exception.SecurityException, PermissionValidationExceptionResponse, DuplicatePermissionExceptionResponse { if(perm.getPermissionClass().equalsIgnoreCase("Method")) { for(String instanceName : perm.getInstances().getInstance()) { // for example, instanceName = "ALE.*" if(instanceName.equalsIgnoreCase("*")) { } else { String[] instanceStr = instanceName.split("\\."); if(instanceStr.length == 1) { if(!instanceStr[0].equalsIgnoreCase("ALE") && !instanceStr[0].equalsIgnoreCase("ALECC") && !instanceStr[0].equalsIgnoreCase("ALETM") && !instanceStr[0].equalsIgnoreCase("ALELR") && !instanceStr[0].equalsIgnoreCase("ALEAC")) { throw new PermissionValidationExceptionResponse("invalid instance name"); } } else if(instanceStr.length > 2){ throw new PermissionValidationExceptionResponse("invalid instance name"); } else { if(!instanceStr[0].equalsIgnoreCase("ALE") && !instanceStr[0].equalsIgnoreCase("ALECC") && !instanceStr[0].equalsIgnoreCase("ALETM") && !instanceStr[0].equalsIgnoreCase("ALELR") && !instanceStr[0].equalsIgnoreCase("ALEAC")) { throw new PermissionValidationExceptionResponse("invalid instance name"); } } } } List<Permission> listPerm = findPermissions(permName); boolean exist = false; for(Permission p : listPerm) { if(p.getObjectName().equalsIgnoreCase(permName)) { exist = true; } } if(exist) throw new DuplicatePermissionExceptionResponse("permission already exists"); for(String instanceName : perm.getInstances().getInstance()) { rbac.addPermObj(permName); rbac.definePermission(permName, instanceName); } } else { throw new PermissionValidationExceptionResponse("invalid permission class"); } } public void updatePermission(String permName, ACPermission perm) throws org.fosstrak.ale.exception.SecurityException, PermissionValidationExceptionResponse, NoSuchPermissionExceptionResponse { if(!perm.getPermissionClass().equalsIgnoreCase("Method")) throw new PermissionValidationExceptionResponse("invalid permission class"); List<Permission> listPerm = findPermissions(permName); boolean noSuchPerm = true; for(Permission p : listPerm) { if(p.getObjectName().equalsIgnoreCase(permName)) { noSuchPerm = false; } } if(noSuchPerm) throw new NoSuchPermissionExceptionResponse("no such permission"); String permObjName = permName; for(String permOpName : perm.getInstances().getInstance()) { Set<String> roles = new HashSet<String>(); rbac.updatePermission(permObjName, permOpName, roles); } } public ACPermission getPermission(String permName) throws org.fosstrak.ale.exception.SecurityException, NoSuchPermissionExceptionResponse { ACPermission toReturn = new ACPermission(); List<Permission> listPerm = findPermissions(permName); if(listPerm.size() == 0) throw new NoSuchPermissionExceptionResponse("no such permission"); toReturn.setPermissionClass("Method"); toReturn.setInstances(new Instances()); for(Permission p : listPerm) { toReturn.getInstances().getInstance().add(p.getOpName()); } return toReturn; } public void undefinePermission(String permName) throws org.fosstrak.ale.exception.SecurityException, NoSuchPermissionExceptionResponse { List<Permission> listPerm = findPermissions(permName); boolean exist = false; for(Permission p : listPerm) { if(p.getObjectName().equalsIgnoreCase(permName)) { exist = true; } } if(!exist) throw new NoSuchPermissionExceptionResponse("no such permission"); rbac.deletePermObj(permName); } public List<String> getRoleNames() throws org.fosstrak.ale.exception.SecurityException { List<String> toReturn = new ArrayList<String>(); List<Role> listRole = findRoles(""); for(Role r : listRole) { toReturn.add(r.getName()); } return toReturn; } public void defineRole(String roleName, ACRole role) throws org.fosstrak.ale.exception.SecurityException, RoleValidationExceptionResponse, DuplicateRoleExceptionResponse { List<Role> rlist = findRoles(roleName); boolean exist = false; for(Role r : rlist) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(exist) throw new DuplicateRoleExceptionResponse("role to define already exists"); // add permission PermissionNames listPermName = (PermissionNames) role.getPermissionNames(); if(listPermName.getPermissionName() != null) { List<String> listPerms = (List<String>) listPermName.getPermissionName(); for(String permName : listPerms) { List<Permission> perms = findPermissions(permName); exist = false; for(Permission p : perms) { if(p.getObjectName().equalsIgnoreCase(permName)) { exist = true; } } if(!exist) throw new RoleValidationExceptionResponse("no such permission"); rbac.defineRole(roleName); for(Permission p : perms) { String opName = p.getOpName(); rbac.assignPermissionToRole(roleName, permName, opName); } } } } public void updateRole(String roleName, ACRole role) throws org.fosstrak.ale.exception.SecurityException, NoSuchRoleExceptionResponse, RoleValidationExceptionResponse { List<Role> rlist = findRoles(roleName); boolean exist = false; for(Role r : rlist) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); List<Permission> plist = findPermissions(""); for(Permission p : plist) { if(p != null && p.getRoles() != null && p.getRoles().contains(roleName)) { deassignPermissionToRole(roleName, p.getObjectName(), p.getOpName()); } } for(String permName : role.getPermissionNames().getPermissionName()) { List<Permission> perms = findPermissions(permName); exist = false; for(Permission p : perms) { if(p.getObjectName().equalsIgnoreCase(permName)) { exist = true; } } if(!exist) throw new RoleValidationExceptionResponse("no such permission"); for(Permission p : perms) { String opName = p.getOpName(); rbac.assignPermissionToRole(roleName, permName, opName); } } } public ACRole getRole(String roleName) throws org.fosstrak.ale.exception.SecurityException, NoSuchRoleExceptionResponse { List<Role> listRole = findRoles(roleName); boolean exist = false; for(Role r : listRole) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); if(listRole != null && listRole.get(0) != null && listRole.get(0).getName().equals(roleName)) { ACRole acRole = new ACRole(); acRole.setPermissionNames(new PermissionNames()); List<Permission> plist = findPermissions(""); for(Permission p : plist) { if(p != null && p.getRoles() != null && p.getRoles().contains(roleName)) { acRole.getPermissionNames().getPermissionName().add(p.getObjectName()); } } return acRole; } return null; } public void undefineRole(String roleName) throws org.fosstrak.ale.exception.SecurityException, NoSuchRoleExceptionResponse { List<Role> listRole = findRoles(roleName); boolean exist = false; for(Role r : listRole) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); rbac.undefineRole(roleName); } public void addPermissions(String roleName, List<String> permissionNames) throws org.fosstrak.ale.exception.SecurityException, NoSuchPermissionExceptionResponse, NoSuchRoleExceptionResponse { List<Role> listRole = findRoles(roleName); boolean exist = false; for(Role r : listRole) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); for(String permName : permissionNames) { List<Permission> perms = findPermissions(permName); if(perms.size() == 0) throw new NoSuchPermissionExceptionResponse("no such permission"); for(Permission p : perms) { String opName = p.getOpName(); rbac.assignPermissionToRole(roleName, permName, opName); } } } public void setPermissions(String roleName, List<String> permissionNames) throws UnsupportedOperationExceptionResponse { throw new UnsupportedOperationExceptionResponse(); } public void removePermissions(String roleName, List<String> permissionNames) throws org.fosstrak.ale.exception.SecurityException, NoSuchRoleExceptionResponse, NoSuchPermissionExceptionResponse { List<Role> listRole = findRoles(roleName); boolean exist = false; for(Role r : listRole) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); for(String permName : permissionNames) { List<Permission> perms = findPermissions(permName); exist = false; for(Permission p : perms) { if(p.getObjectName().equalsIgnoreCase(permName)) { exist = true; } } if(!exist) throw new NoSuchPermissionExceptionResponse("no such permission"); for(Permission p : perms) { if(p.getObjectName().equalsIgnoreCase(permName)) { String opName = p.getOpName(); rbac.deassignPermissionToRole(roleName, permName, opName); } } } } public List<String> getClientIdentityNames() throws org.fosstrak.ale.exception.SecurityException { List<String> toReturn = new ArrayList<String>(); List<User> listUser = findClients(""); for(User u : listUser) { toReturn.add(u.getUserId()); } return toReturn; } public void defineClientIdentity(String identityName, ACClientIdentity id) throws org.fosstrak.ale.exception.SecurityException, ClientIdentityValidationExceptionResponse, DuplicateClientIdentityExceptionResponse { List<User> listUser = findClients(identityName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equals(identityName)) { exist = true; } } if(exist) throw new DuplicateClientIdentityExceptionResponse("clientId to define already exists"); ACClientCredential credential = id.getCredentials().getCredential().get(0); List<String> listRoleNames = null; if(id.getRoleNames() != null) { listRoleNames = id.getRoleNames().getRoleName(); List<Role> rlist = findRoles(""); for(String roleName : listRoleNames) { exist = false; for(Role r : rlist) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new ClientIdentityValidationExceptionResponse("no such role"); } } String password = credential.getOtherAttributes().get(new QName("password")); defineClientid(identityName, password, listRoleNames); } public void updateClientIdentity(String identityName, ACClientIdentity id) throws org.fosstrak.ale.exception.SecurityException, NoSuchClientIdentityExceptionResponse, ClientIdentityValidationExceptionResponse { List<User> listUser = findClients(identityName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equals(identityName)) { exist = true; } } if(!exist) throw new NoSuchClientIdentityExceptionResponse("no such client"); List<String> listRoleNames = null; if(id.getRoleNames() != null) { listRoleNames = id.getRoleNames().getRoleName(); List<Role> rlist = findRoles(""); for(String roleName : listRoleNames) { exist = false; for(Role r : rlist) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new ClientIdentityValidationExceptionResponse("no such role"); } } updateClientid(identityName, id.getCredentials().getCredential().get(0).getOtherAttributes().get(new QName("password")), id.getRoleNames().getRoleName()); } public ACClientIdentity getClientIdentity(String identityName) throws org.fosstrak.ale.exception.SecurityException, NoSuchClientIdentityExceptionResponse { List<User> listUser = findClients(identityName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equals(identityName)) { exist = true; } } if(!exist) throw new NoSuchClientIdentityExceptionResponse("no such client"); if(listUser != null && listUser.get(0) != null && listUser.get(0).getUserId().equals(identityName)) { User u = listUser.get(0); ACClientIdentity toReturn = new ACClientIdentity(); toReturn.setRoleNames(new RoleNames()); toReturn.setCredentials(new Credentials()); ACClientCredential e = new ACClientCredential(); //e.getOtherAttributes().put(new QName("password"), u.getPassword().toString()); toReturn.getCredentials().getCredential().add(e); for(String ur : u.getRoles()) { toReturn.getRoleNames().getRoleName().add(ur); } return toReturn; } return null; } public List<String> getClientPermissionNames(String clientId) throws org.fosstrak.ale.exception.SecurityException, ImplementationExceptionResponse { throw new ImplementationExceptionResponse("not supported"); /* List<String> toReturn = new ArrayList<String>(); List<User> listUser = findClients(clientId); for(User u : listUser) { for(UserRole r : u.getRoles()) { r.get } //toReturn.getString().add(u.getRoles()); } return toReturn; */ } public void undefineClientIdentity(String identityName) throws org.fosstrak.ale.exception.SecurityException, NoSuchClientIdentityExceptionResponse { List<User> listUser = findClients(identityName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equals(identityName)) { exist = true; } } if(!exist) throw new NoSuchClientIdentityExceptionResponse("no such client"); undefineClientid(identityName); } public void addRoles(String identityName, List<String> roleNames) throws org.fosstrak.ale.exception.SecurityException, NoSuchClientIdentityExceptionResponse, NoSuchRoleExceptionResponse { List<User> listUser = findClients(identityName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equalsIgnoreCase(identityName)) { exist = true; } } if(!exist) throw new NoSuchClientIdentityExceptionResponse("no such client"); for(String roleName : roleNames) { List<Role> listRole = findRoles(roleName); exist = false; for(Role r : listRole) { if(r.getName().equalsIgnoreCase(roleName)) { exist = true; } } if(!exist) throw new NoSuchRoleExceptionResponse("no such role"); } for(String roleName : roleNames) { assignRoleToClientid(identityName, roleName); } } public void removeRoles(String idName, List<String> roleNames) throws org.fosstrak.ale.exception.SecurityException, NoSuchClientIdentityExceptionResponse { List<User> listUser = findClients(idName); boolean exist = false; for(User u : listUser) { if(u.getUserId().equalsIgnoreCase(idName)) { exist = true; } } if(!exist) throw new NoSuchClientIdentityExceptionResponse("no such client"); for(String roleName : roleNames) { deassignRoleToClientid(idName, roleName); } } public void setRoles(String identityName, List<String> roleNames) throws UnsupportedOperationExceptionResponse { throw new UnsupportedOperationExceptionResponse(); } private void defineClientid(String idName, String password, List<String> listRoleNames) throws org.fosstrak.ale.exception.SecurityException { rbac.defineClientid(idName, password, listRoleNames); } private void undefineClientid(String idName) throws org.fosstrak.ale.exception.SecurityException { rbac.undefineClientid(idName); } private void defineRole(String roleName) throws org.fosstrak.ale.exception.SecurityException { rbac.defineRole(roleName); } private void deassignPermissionToRole(String roleName, String permObjName, String permOpName) throws org.fosstrak.ale.exception.SecurityException { rbac.deassignPermissionToRole(roleName, permObjName, permOpName); } private void assignRoleToClientid(String userId, String roleName) throws org.fosstrak.ale.exception.SecurityException { rbac.assignRoleToClientid(userId, roleName); } private void deassignRoleToClientid(String userId, String roleName) throws org.fosstrak.ale.exception.SecurityException { rbac.deassignRoleToClientid(userId, roleName); } private List<org.fosstrak.ale.server.ac.User> findClients(String clientName) throws org.fosstrak.ale.exception.SecurityException { return rbac.findUsers(clientName); } private List<org.fosstrak.ale.server.ac.Role> findRoles(String roleName) throws org.fosstrak.ale.exception.SecurityException { return rbac.findRoles(roleName); } private List<org.fosstrak.ale.server.ac.Permission> findPermissions(String permName) throws org.fosstrak.ale.exception.SecurityException { return rbac.findPermissions(permName, ""); } private List<org.fosstrak.ale.server.ac.Permission> findPermissionsByOpname(String opName) throws org.fosstrak.ale.exception.SecurityException { return rbac.findPermissions("", opName); } private void updateClientid(String idName, String password, List<String> listRoleNames) throws org.fosstrak.ale.exception.SecurityException { rbac.updateClientid(idName, password, listRoleNames); } private void updatePermission(String permObjName, String permOpName, Set<String> roles) throws org.fosstrak.ale.exception.SecurityException { rbac.updatePermission(permObjName, permOpName, roles); } public boolean login(String userId, String password) throws org.fosstrak.ale.exception.SecurityException { if(aleSettings.getFortressEnable().equalsIgnoreCase("true")) { if(rbac == null) rbac = new FortressRBACClient(); } else { if(rbac == null) rbac = new LocalRBAC(); } rbac.createSession(userId, password); setLoggedInId(userId); return true; } public void checkAccess(String apiName, String methodName) throws org.fosstrak.ale.exception.SecurityException { if(aleSettings.getFortressEnable().equalsIgnoreCase("true")) { if(loggedInId.equals("admin")) return; List<String> listOp = getSupportedOperations(); if(listOp.contains("*")) { return; } String permOpName = apiName+"."+methodName; if(listOp.contains(permOpName)) { return; } throw new org.fosstrak.ale.exception.SecurityException(permOpName+" is not authorized for the user "+loggedInId); /* if(loggedInId.equals("admin")) return; List<Permission> permList = findPermissionsByOpname(permOpName); boolean permExist = false; System.out.println("permList:"+findPermissionsByOpname("").get(0)); for(Permission p : permList) { if(permOpName.equalsIgnoreCase(p.getOpName())) { String permObjName = p.getObjectName(); try { if(fortress.checkAccess(permObjName, "*")) return; if(!fortress.checkAccess(permObjName, permOpName)) { throw new org.fosstrak.ale.exception.SecurityException(permObjName+"."+permOpName+" is not authorized for the user "+loggedInId); } permExist = true; } catch (SecurityException e) { throw new org.fosstrak.ale.exception.SecurityException(e.getMessage()); } } } if(!permExist) { throw new org.fosstrak.ale.exception.SecurityException(apiName+"."+methodName+" is not authorized for the user "+loggedInId); } */ } return; } public static ALEACImpl getInstance() { return ALEApplicationContext.getBean(ALEACImpl.class); } public String getLoggedInId() { return loggedInId; } public void setLoggedInId(String loggedInId) { this.loggedInId = loggedInId; } public String getStandardVersion() { return "1.1"; } public String getVendorVersion() { return ""; } public List<String> getSupportedOperations() { List<String> toReturn = new ArrayList<String>(); try { List<User> listUser = rbac.findUsers(loggedInId); for(User u : listUser) { if(u.getUserId().equals(loggedInId)) { for(String ur : u.getRoles()) { String roleName = ur; List<Permission> listPerm = rbac.findPermissions("", ""); for(Permission p : listPerm) { if(p.getRoles().contains(roleName)) { toReturn.add(p.getOpName()); } } } } } } catch (org.fosstrak.ale.exception.SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } toReturn.add("getStandardVersion"); toReturn.add("getVendorVersion"); toReturn.add("getSupportedOperations"); return toReturn; } }