Author: echatellier Date: 2012-10-17 16:58:08 +0200 (Wed, 17 Oct 2012) New Revision: 219 Url: http://nuiton.org/repositories/revision/nuiton-web/219 Log: Update permission management for roles Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RoleAction.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RolePermissionsAction.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserAction.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserRolesAction.java branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/role-permissions.jsp branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/user-roles.jsp branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/struts.xml branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.properties branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.zargo Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java 2012-10-17 14:58:08 UTC (rev 219) @@ -12,7 +12,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.realm.Realm; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; @@ -28,6 +28,8 @@ private static final Log log = LogFactory.getLog(SecurityShiroFilter.class); + protected static final String ANON_LOGIN = "anonymous"; + @Override public void init() throws Exception { @@ -49,15 +51,15 @@ log.info("Overriding shiro realms"); } //DefaultWebEnvironment env = new DefaultWebEnvironment(); - Realm topiaSecurityRealm = new TopiaSecurityRealm(rootContext, config); - DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(topiaSecurityRealm); + Realm realm = new TopiaSecurityRealm(rootContext, config); + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm); setSecurityManager(securityManager); /*FilterChainResolver resolver = getFilterChainResolver(); if (resolver != null) { setFilterChainResolver(resolver); }*/ } - + protected static void initSchema(TopiaContext rootContext) throws TopiaException { TopiaContext transaction = rootContext.beginTransaction(); boolean testTable = TopiaUtil.isSchemaExist(transaction, SecurityUserImpl.class.getName()); @@ -67,6 +69,14 @@ log.info("Create database schema"); } rootContext.createSchema(); + + // create anon user + TopiaContext transaction2 = rootContext.beginTransaction(); + SecurityUserDAO securityUserDAO = SecurityDAOHelper.getSecurityUserDAO(transaction2); + SecurityUser anonUser = securityUserDAO.create(); + anonUser.setLogin(ANON_LOGIN); + transaction2.commitTransaction(); + transaction2.closeContext(); } else { if (log.isDebugEnabled()) { log.debug("Table SecurityUser found, skip schema creation"); @@ -85,27 +95,29 @@ log.debug("Testing permission for user " + subjectUser.getPrincipal()); } + // to have permission, a user must be authenticated + if (!subjectUser.isAuthenticated()) { + subjectUser.login(new UsernamePasswordToken(ANON_LOGIN, "")); + } + // get permission String uri = ((HttpServletRequest)servletRequest).getRequestURI(); - String perm = "url:" + uri; + String perm = "url" + uri.replace('/', ':'); + if (subjectUser.isPermitted(perm)) { if (log.isDebugEnabled()) { log.debug("User is permitted to access " + perm); } super.doFilterInternal(servletRequest, servletResponse, chain); - } else if (uri.equals("/security/login.action") - || uri.startsWith("/js/") - || uri.startsWith("/img/") - || uri.startsWith("/css/")) { - if (log.isDebugEnabled()) { - log.debug("Temp allowing static access " + uri); - } - super.doFilterInternal(servletRequest, servletResponse, chain); } else { if (log.isDebugEnabled()) { log.debug("User is NOT permitted to access " + perm); } - ((HttpServletResponse)servletResponse).sendRedirect("/security/login.action"); + if (ANON_LOGIN.equals(subjectUser.getPrincipal())) { + ((HttpServletResponse)servletResponse).sendRedirect("/security/login.action"); + } else { + ((HttpServletResponse)servletResponse).sendError(401, "Not authorized to access " + uri); + } } } } Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java 2012-10-17 14:58:08 UTC (rev 219) @@ -1,5 +1,11 @@ package org.nuiton.web.security; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.authc.AuthenticationException; @@ -16,9 +22,6 @@ import org.nuiton.topia.TopiaRuntimeException; import org.nuiton.util.ApplicationConfig; import org.nuiton.web.SecurityDAOHelper; -import org.nuiton.web.security.SecurityUser; -import org.nuiton.web.security.SecurityUserDAO; -import org.nuiton.web.security.SecurityUserImpl; public class TopiaSecurityRealm extends AuthorizingRealm { @@ -36,11 +39,12 @@ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { - String login = (String) principals.getPrimaryPrincipal(); + SimpleAuthorizationInfo result = null; - SimpleAuthorizationInfo result = null; + Properties props = config.getFlatOptions(); TopiaContext transaction = null; try { + String login = (String) principals.getPrimaryPrincipal(); transaction = rootContext.beginTransaction(); SecurityUserDAO securityUserDAO = SecurityDAOHelper.getSecurityUserDAO(transaction); @@ -50,15 +54,49 @@ SecurityUser securityUser = securityUserDAO.findByLogin(login); result = new SimpleAuthorizationInfo(); - for (SecurityRole role : securityUser.getRoles()) { + for (SecurityRole role : securityUser.getSecurityRole()) { for (String permission : role.getPermissions()) { - result.addStringPermission(permission); + //result.addStringPermission(permission); if (log.isDebugEnabled()) { log.debug(" - add permission : " + permission); } + + for (String prop : props.stringPropertyNames()) { + if (prop.startsWith("topia.security.permission.")) { + String endProp = StringUtils.removeStart(prop, "topia.security.permission."); + String[] subs = endProp.split("\\."); + if (subs.length == 3) { + if (subs[2].equals("perm")) { + if (subs[1].equals(permission)) { + String perms = props.getProperty(prop); + String[] permTab = perms.split("\\s*\\,\\s*"); + for (String perm : permTab) { + result.addStringPermission(perm); + if (log.isDebugEnabled()) { + log.debug(" - add string permission : " + perm); + } + } + } + } + } + } + } } } + // si seul l'utilisateur anon existe + // on lui offre une promotion + if (login.equals(SecurityShiroFilter.ANON_LOGIN) && securityUserDAO.count() == 1) { + result.addStringPermission("*"); + if (log.isDebugEnabled()) { + log.debug("Grant all rigth (*) because no user exists"); + } + } + + // ajout de l'url de login et logout quand meme !!! + result.addStringPermission("url:security:login.action"); + result.addStringPermission("url:security:logout.action"); + } catch (Exception ex) { } finally { @@ -70,7 +108,7 @@ } } } - + return result; } @@ -79,8 +117,12 @@ UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String login = usernamePasswordToken.getUsername(); - char[] password = usernamePasswordToken.getPassword(); + //char[] password = usernamePasswordToken.getPassword(); + if (log.isDebugEnabled()) { + log.debug("doGetAuthenticationInfo for login : " + login); + } + AuthenticationInfo result = null; TopiaContext transaction = null; try { @@ -88,40 +130,16 @@ SecurityUserDAO securityUserDAO = SecurityDAOHelper.getSecurityUserDAO(transaction); SecurityUser securityUser = securityUserDAO.findByLogin(login); - - if (securityUser == null) { - long count = securityUserDAO.count(); - // si il n'y a aucun utilisateur, le premier utilisateur - // devient un power user, super admin de la mort - if (count == 0) { - if (log.isDebugEnabled()) { - log.debug("Creating new admin user with login : " + login); - } - SecurityRoleDAO securityRoleDAO = SecurityDAOHelper.getSecurityRoleDAO(transaction); - - securityUser = securityUserDAO.create(); - securityUser.setLogin(login); - securityUser.setPassword(String.valueOf(password)); - - // on lui attribut tous les droits - SecurityRole role = securityRoleDAO.create(); - role.setName("admin"); - role.addPermissions("*:*"); - securityUser.addRoles(role); - - transaction.commitTransaction(); + if (securityUser != null) { + if (login.equals(SecurityShiroFilter.ANON_LOGIN)) { + result = new SimpleAuthenticationInfo(securityUser.getLogin(), + "", getName()); } else { - if (log.isDebugEnabled()) { - log.debug(count + " accounts found"); - } + result = new SimpleAuthenticationInfo(securityUser.getLogin(), + securityUser.getPassword(), getName()); } } - if (securityUser != null) { - result = new SimpleAuthenticationInfo(securityUser.getLogin(), - securityUser.getPassword(), getName()); - } - } catch (TopiaException ex) { throw new TopiaRuntimeException(ex); } finally { Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RoleAction.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RoleAction.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RoleAction.java 2012-10-17 14:58:08 UTC (rev 219) @@ -4,6 +4,7 @@ import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; import org.nuiton.topia.TopiaRuntimeException; +import org.nuiton.web.SecurityDAOHelper; import org.nuiton.web.security.SecurityRole; import org.nuiton.web.security.SecurityRoleDAO; import org.nuiton.web.security.SecurityRoleImpl; @@ -39,6 +40,7 @@ try { TopiaContext transaction = rootContext.beginTransaction(); + securityRoleDAO = SecurityDAOHelper.getSecurityRoleDAO(transaction); if (role.getTopiaId() == null) { securityRoleDAO.create(role); } else { Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RolePermissionsAction.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RolePermissionsAction.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/RolePermissionsAction.java 2012-10-17 14:58:08 UTC (rev 219) @@ -1,7 +1,6 @@ package org.nuiton.web.security.actions; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -13,7 +12,6 @@ import org.nuiton.web.SecurityDAOHelper; import org.nuiton.web.security.SecurityRole; import org.nuiton.web.security.SecurityRoleDAO; -import org.nuiton.web.security.SecurityUser; import org.nuiton.web.security.SecurityUserDAO; public class RolePermissionsAction extends AbstractAction { @@ -31,12 +29,10 @@ protected Map<String, String> permissions; /** Id categories with permissions ids. */ protected Map<String, Collection<String>> categoryPermissions; - /** Id permission with permissions strings. */ - protected Map<String, Collection<String>> shiroPerms; protected List<SecurityRole> roles; - protected List<String> userIds; + protected List<String> roleIds; @Override public String input() throws Exception { @@ -48,7 +44,7 @@ categories = new HashMap<String, String>(); permissions = new HashMap<String, String>(); categoryPermissions = new HashMap<String, Collection<String>>(); - shiroPerms = new HashMap<String, Collection<String>>(); + Properties props = config.getFlatOptions(); for (String prop : props.stringPropertyNames()) { if (prop.startsWith("topia.security.permission.")) { @@ -56,22 +52,19 @@ String[] subs = endProp.split("\\."); if (subs.length == 1) { categories.put(subs[0], props.getProperty(prop)); - } else if (subs.length == 2) { - String perms = props.getProperty(prop); - String[] permTab = perms.split("\\s*\\.\\s*"); - Collection<String> permList = Arrays.asList(permTab); - shiroPerms.put(subs[0], permList); } else if (subs.length == 3) { - // name - String name = props.getProperty(prop); - permissions.put(subs[1], name); - // association - Collection<String> categoryPermissionCol = categoryPermissions.get(subs[0]); - if (categoryPermissionCol == null) { - categoryPermissionCol = new ArrayList<String>(); - categoryPermissions.put(subs[0], categoryPermissionCol); + if (subs[2].equals("name")) { + // name + String name = props.getProperty(prop); + permissions.put(subs[1], name); + // association + Collection<String> categoryPermissionCol = categoryPermissions.get(subs[0]); + if (categoryPermissionCol == null) { + categoryPermissionCol = new ArrayList<String>(); + categoryPermissions.put(subs[0], categoryPermissionCol); + } + categoryPermissionCol.add(subs[1]); } - categoryPermissionCol.add(subs[1]); } } } @@ -94,26 +87,28 @@ return categoryPermissions; } + public void setRoleIds(List<String> roleIds) { + this.roleIds = roleIds; + } + @Override public String execute() throws Exception { String result = super.execute(); - if (userIds == null) { + if (roleIds == null) { result = input(); } else { try { TopiaContext transaction = rootContext.beginTransaction(); - securityUserDAO = SecurityDAOHelper.getSecurityUserDAO(transaction); securityRoleDAO = SecurityDAOHelper.getSecurityRoleDAO(transaction); - for (String userId : userIds) { - SecurityUser securityUser = securityUserDAO.findByTopiaId(userId); - securityUser.clearRoles(); + for (String roleId : roleIds) { + SecurityRole securityRole = securityRoleDAO.findByTopiaId(roleId); + securityRole.clearPermissions(); - String[] roleIds = getParameters("roles-" + userId); - if (roleIds != null) { - for (String roleId : roleIds) { - SecurityRole secuRole = securityRoleDAO.findByTopiaId(roleId); - securityUser.addRoles(secuRole); + String[] permissions = getParameters("permissions-" + roleId); + if (permissions != null) { + for (String permission : permissions) { + securityRole.addPermissions(permission); } } } Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserAction.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserAction.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserAction.java 2012-10-17 14:58:08 UTC (rev 219) @@ -9,6 +9,8 @@ import org.nuiton.web.security.SecurityUserDAO; import org.nuiton.web.security.SecurityUserImpl; +import com.opensymphony.xwork2.Preparable; + public class UserAction extends AbstractAction { /** serialVersionUID. */ Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserRolesAction.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserRolesAction.java 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/actions/UserRolesAction.java 2012-10-17 14:58:08 UTC (rev 219) @@ -60,13 +60,13 @@ securityRoleDAO = SecurityDAOHelper.getSecurityRoleDAO(transaction); for (String userId : userIds) { SecurityUser securityUser = securityUserDAO.findByTopiaId(userId); - securityUser.clearRoles(); + securityUser.clearSecurityRole(); String[] roleIds = getParameters("roles-" + userId); if (roleIds != null) { for (String roleId : roleIds) { SecurityRole secuRole = securityRoleDAO.findByTopiaId(roleId); - securityUser.addRoles(secuRole); + securityUser.addSecurityRole(secuRole); } } } Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/role-permissions.jsp =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/role-permissions.jsp 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/role-permissions.jsp 2012-10-17 14:58:08 UTC (rev 219) @@ -12,25 +12,36 @@ <h2>Permissions des rôles</h2> - <form action="<s:url action="user-roles" namespace="/security" />" method="post"> + <form action="<s:url action="role-permissions" namespace="/security" />" method="post"> + <s:iterator value="roles"> + <input type="hidden" name="roleIds" value="<s:property value="topiaId" />" /> + </s:iterator> <table class="secu-roletable"> <tr> <td class="empty" /> <s:iterator value="roles"> - <td><s:property value="name" /></td> + <td><a href="<s:url action='role!input' namespace='/security'> + <s:param name="roleId"><s:property value="topiaId" /></s:param> + </s:url>"> + <s:property value="name" /> + </a></td> </s:iterator> </tr> <s:iterator value="categories.keys" var="category"> <s:set name="categoryName" value="categories.get(#category)" /> <tr> - <td colspan="<s:property value="roles.size() + 1" />"><s:property value="#categoryName" /></td> + <th colspan="<s:property value="roles.size() + 1" />"><s:property value="#categoryName" /></th> </tr> <s:iterator value="categoryPermissions.get(#category)" var="categoryPermission"> <s:set name="permissionName" value="permissions.get(#categoryPermission)" /> <tr> <td><s:property value="#permissionName" /></td> - <s:iterator value="roles"> - <td><input type="checkbox" value="" /></td> + <s:iterator value="roles" var="role"> + <td><input type="checkbox" name="permissions-<s:property value="topiaId" />" + value="<s:property value="#categoryPermission"/>" + <s:if test="#role.permissions.contains(#categoryPermission)" > + checked="checked" + </s:if> /></td> </s:iterator> </tr> </s:iterator> Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/user-roles.jsp =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/user-roles.jsp 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/WEB-INF/security/user-roles.jsp 2012-10-17 14:58:08 UTC (rev 219) @@ -33,7 +33,7 @@ </s:iterator> </tr> <s:iterator value="users" var="user" status="userStatus"> - <input type="hidden" name="userIds" value="<s:property value="topiaId" />" /> + <input type="hidden" name="userIds" value="<s:property value="topiaId" />" /> <tr> <s:if test="#userStatus.first"> <th rowspan="<s:property value="users.size()" />" class="vertical">Utilisateurs</th> @@ -47,9 +47,10 @@ </td> <s:iterator value="roles" var="role"> <td> + <input id="<s:property value="#user.topiaId" /><s:property value="#user.topiaId" />" type="checkbox" name="roles-<s:property value="#user.topiaId" />" value="<s:property value="#role.topiaId" />" - <s:if test="#user.roles.contains(#role)" > + <s:if test="#user.securityRole.contains(#role)" > checked="checked" </s:if> /> </td> Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/struts.xml =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/struts.xml 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/resources/struts.xml 2012-10-17 14:58:08 UTC (rev 219) @@ -15,7 +15,7 @@ <action name="role-permissions" class="org.nuiton.web.security.actions.RolePermissionsAction"> <result name="input">/WEB-INF/security/role-permissions.jsp</result> <result name="success" type="redirectAction"> - <param name="actionName">user-roles</param> + <param name="actionName">role-permissions</param> </result> </action> <action name="role" class="org.nuiton.web.security.actions.RoleAction"> Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.properties =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.properties 2012-10-16 16:31:45 UTC (rev 218) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.properties 2012-10-17 14:58:08 UTC (rev 219) @@ -1,2 +1,3 @@ model.tagvalue.String=text -org.nuiton.web.security.SecurityUser.attribute.roles.tagvalue.lazy=false \ No newline at end of file +org.nuiton.web.security.SecurityUser.attribute.securityRole.tagvalue.lazy=false +org.nuiton.web.security.SecurityRole.attribute.permissions.tagvalue.lazy=false Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/xmi/security.zargo =================================================================== (Binary files differ)
participants (1)
-
echatellier@users.nuiton.org