{"action":"created","issue":{"url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/1525","labels_url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/1525/labels{/name}","comments_url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/1525/comments","events_url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/1525/events","html_url":"https://github.com/jhipster/generator-jhipster/issues/1525","id":80272439,"number":1525,"title":"User management","user":{"login":"moifort","id":4958079,"avatar_url":"https://avatars.githubusercontent.com/u/4958079?v=3","gravatar_id":"","url":"https://api.github.com/users/moifort","html_url":"https://github.com/moifort","followers_url":"https://api.github.com/users/moifort/followers","following_url":"https://api.github.com/users/moifort/following{/other_user}","gists_url":"https://api.github.com/users/moifort/gists{/gist_id}","starred_url":"https://api.github.com/users/moifort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/moifort/subscriptions","organizations_url":"https://api.github.com/users/moifort/orgs","repos_url":"https://api.github.com/users/moifort/repos","events_url":"https://api.github.com/users/moifort/events{/privacy}","received_events_url":"https://api.github.com/users/moifort/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":74,"created_at":"2015-05-24T21:09:53Z","updated_at":"2015-07-25T09:22:46Z","closed_at":null,"body":"Hello the community,\r\n\r\nI would like to know if it's will be interesting to implement in Jhipster the user management functionality. The idea is to provide for administrator user an interface to manage all the users.\r\n\r\nWe can start to implement some mains functions like:\r\n- Display all user with summary informations\r\n- Allow the admin user to modify setting for a specific user:\r\n  - Change first name\r\n  - Change last name\r\n  - Change email\r\n  - Activate/Disable an user\r\n  - Change default language\r\n  - Change authorities \r\n\r\nI already make a prototype for my application:\r\n\r\n![capture d ecran 2015-05-24 a 23 04 54](https://cloud.githubusercontent.com/assets/4958079/7789674/5886e426-0269-11e5-94de-d19bdff4e8d5.png)\r\n\r\n![capture d ecran 2015-05-24 a 23 05 07](https://cloud.githubusercontent.com/assets/4958079/7789677/719aaad8-0269-11e5-86ce-23d8f6b474e5.png)\r\n \r\nThibaut."},"comment":{"url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/comments/124825429","html_url":"https://github.com/jhipster/generator-jhipster/issues/1525#issuecomment-124825429","issue_url":"https://api.github.com/repos/jhipster/generator-jhipster/issues/1525","id":124825429,"user":{"login":"deepu105","id":1107223,"avatar_url":"https://avatars.githubusercontent.com/u/1107223?v=3","gravatar_id":"","url":"https://api.github.com/users/deepu105","html_url":"https://github.com/deepu105","followers_url":"https://api.github.com/users/deepu105/followers","following_url":"https://api.github.com/users/deepu105/following{/other_user}","gists_url":"https://api.github.com/users/deepu105/gists{/gist_id}","starred_url":"https://api.github.com/users/deepu105/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deepu105/subscriptions","organizations_url":"https://api.github.com/users/deepu105/orgs","repos_url":"https://api.github.com/users/deepu105/repos","events_url":"https://api.github.com/users/deepu105/events{/privacy}","received_events_url":"https://api.github.com/users/deepu105/received_events","type":"User","site_admin":false},"created_at":"2015-07-25T09:22:46Z","updated_at":"2015-07-25T09:22:46Z","body":"I have removed some specific business logic code also the `AfterInvocationManager ` may not be required. Its needed only if you want to filter returned objects with some logic\r\n```\r\n/**\r\n * Custom method security configuration\r\n * Created by Dee on 7/7/2015.\r\n */\r\n@Configuration\r\n@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true, mode = AdviceMode.PROXY)\r\n@EnableAspectJAutoProxy\r\npublic class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {\r\n\r\n    public AccessDecisionManager accessDecisionManager() {\r\n        CustomAccessDecisionManager accessDecisionManager = new CmsAccessDecisionManager();\r\n        return accessDecisionManager;\r\n    }\r\n\r\n    public AfterInvocationManager afterInvocationManager() {\r\n        CustomAfterInvocationManager afterInvocationManager = new CmsAfterInvocationManager();\r\n        return afterInvocationManager;\r\n    }\r\n\r\n}\r\n```\r\n\r\n```\r\n/**\r\n * Custom Access decision manager for method security\r\n * Created by Dee on 7/7/2015.\r\n */\r\npublic class CustomAccessDecisionManager implements AccessDecisionManager {\r\n\r\n    private final Logger log = LoggerFactory.getLogger(CustomAccessDecisionManager .class);\r\n\r\n    @Override\r\n    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {\r\n        ConfigAttribute configAttribute = SecurityUtils.getSingleConfigAttribute(configAttributes);\r\n\r\n        MethodInvocation methodInvocation = (MethodInvocation) object;\r\n\r\n        try {\r\n            if(authentication != null) {\r\n                User user = SecurityUtils.getCurrentUser(authentication);\r\n\r\n                SecureRules secureRules = null;\r\n                RequestMapping requestMapping = null;\r\n                for (Annotation annotation : methodInvocation.getMethod().getDeclaredAnnotations()) {\r\n                    if(annotation instanceof SecureRules){\r\n                        secureRules = (SecureRules) annotation;\r\n                    }else if(annotation instanceof RequestMapping){\r\n                        requestMapping = (RequestMapping) annotation;\r\n                    }\r\n                }\r\n\r\n                String method = SecurityUtils.getHttpMethod(secureRules, requestMapping);\r\n                String sectionName = SecurityUtils.getReqPath(configAttribute);\r\n\r\n                SecureRules.Rule[] rules = secureRules != null ? secureRules.rules() : new SecureRules.Rule[]{SecureRules.Rule.NONE};\r\n\r\n                if (user != null && ! hasAccessToSection(cmsUser, method, sectionName ,methodInvocation, rules, configAttribute)) {\r\n                    throw new AccessDeniedException(\"EX::User does not have enough privileges to access this method\");\r\n                }\r\n            }\r\n\r\n        } catch (ClassCastException e) {\r\n            throw new IllegalStateException();\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public boolean supports(ConfigAttribute attribute) {\r\n        return false;\r\n    }\r\n\r\n    @Override\r\n    public boolean supports(Class<?> clazz) {\r\n        return clazz.equals(MethodInvocation.class);\r\n    }\r\n    /**\r\n     * checks if the section has grants in any roles for the user\r\n     * @param user\r\n     * @param methodInvocation\r\n     * @param rules\r\n     *@param configAttribute  @return\r\n     */\r\n    private boolean hasAccessToSection(User user, String method, String sectionName, MethodInvocation methodInvocation, SecureRules.Rule[] rules, ConfigAttribute configAttribute) {\r\n\r\n        Map<String, SectionDTO> validSections = user.getValidSections();\r\n        if(validSections !=null && !validSections.isEmpty()) {\r\n            SectionDTO validSection = validSections.get(sectionName);\r\n            if (validSection != null && hasGrants(validSection, method) && isNotRestricted(user, validSection, rules, methodInvocation)) {\r\n                log.debug(\"Role has access to section:{} \", validSection);\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * checks for grant for HTTP methods\r\n     * GET = 1 = VIEW,\r\n     * POST = 2 = CREATE,\r\n     * PUT = 3 = EDIT,\r\n     * DELETE = 4 = DELETE\r\n     *\r\n     * @param section\r\n     * @param method\r\n     * @return\r\n     */\r\n    private boolean hasGrants(SectionDTO section, String method) {\r\n        int grant = 0;\r\n        switch (method){\r\n            case \"GET\":\r\n            case \"VIEW\":\r\n                grant = 1; break;\r\n            case \"POST\":\r\n            case \"CREATE\":\r\n                grant = 2; break;\r\n            case \"PUT\":\r\n            case \"EDIT\":\r\n                grant = 3; break;\r\n            case \"DELETE\":\r\n                grant = 4; break;\r\n            default:\r\n                grant = 0;\r\n        }\r\n\r\n        return section.getGrant() >= grant;\r\n    }\r\n\r\n}\r\n```"}}