From bb4a2b401c490fb6f19edabd89bde460ab8eaacf Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Sun, 10 May 2020 00:03:24 +0100 Subject: [PATCH] persist roles in db; initialize with admin role --- grails-app/conf/application.groovy | 3 ++ grails-app/conf/spring/resources.groovy | 8 +++- grails-app/init/mucats/BootStrap.groovy | 38 +++++++++++++++ .../muwire/mucats/security/RoleService.groovy | 10 ++++ .../mucats/security/UserCreatorService.groovy | 46 +++++++++++++++++++ .../mucats/security/UserRoleService.groovy | 11 +++++ .../muwire/mucats/security/UserService.groovy | 11 +++++ grails-app/views/publish/index.gsp | 5 ++ ...lengeResponseAuthenticationProvider.groovy | 1 - ...reatingAuthenticationSuccessHandler.groovy | 21 ++------- 10 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 grails-app/services/com/muwire/mucats/security/RoleService.groovy create mode 100644 grails-app/services/com/muwire/mucats/security/UserCreatorService.groovy create mode 100644 grails-app/services/com/muwire/mucats/security/UserRoleService.groovy create mode 100644 grails-app/services/com/muwire/mucats/security/UserService.groovy diff --git a/grails-app/conf/application.groovy b/grails-app/conf/application.groovy index 23acd9e..38558c5 100644 --- a/grails-app/conf/application.groovy +++ b/grails-app/conf/application.groovy @@ -1,5 +1,7 @@ + + // mask the default spring login controller grails.plugin.springsecurity.auth.loginFormUrl="/login" grails.plugin.springsecurity.logout.postOnly=false @@ -40,6 +42,7 @@ grails.plugin.springsecurity.filterChain.chainMap = [ grails.plugin.springsecurity.rememberMe.cookieName = "mucats_remember_me" grails.plugin.springsecurity.rememberMe.key = "mucats_key" +grails.plugin.springsecurity.adminUser = "zlatinb@3k2gijdfdcuczkfypfddj4qsnnf744mj" grails.plugin.springsecurity.rememberMe.persistent = true grails.plugin.springsecurity.rememberMe.persistentToken.domainClassName = 'com.muwire.mucats.security.PersistentLogin' diff --git a/grails-app/conf/spring/resources.groovy b/grails-app/conf/spring/resources.groovy index 2da71f4..75e6b65 100644 --- a/grails-app/conf/spring/resources.groovy +++ b/grails-app/conf/spring/resources.groovy @@ -7,7 +7,13 @@ import grails.plugin.springsecurity.web.authentication.rememberme.* // Place your Spring DSL code here beans = { - successHandler(UserCreatingAuthenticationSuccessHandler) + userCreator(UserCreatorService) { + grailsApplication = ref('grailsApplication') + } + + successHandler(UserCreatingAuthenticationSuccessHandler) { + userCreator = ref('userCreator') + } failureHandler(SimpleUrlAuthenticationFailureHandler) { defaultFailureUrl = "/login?error=true" diff --git a/grails-app/init/mucats/BootStrap.groovy b/grails-app/init/mucats/BootStrap.groovy index d9310bc..aa9d7f7 100644 --- a/grails-app/init/mucats/BootStrap.groovy +++ b/grails-app/init/mucats/BootStrap.groovy @@ -1,9 +1,47 @@ package mucats +import org.springframework.beans.factory.annotation.Autowired + +import com.muwire.mucats.security.Role +import com.muwire.mucats.security.RoleService +import com.muwire.mucats.security.User +import com.muwire.mucats.security.UserRoleService +import com.muwire.mucats.security.UserService + +import grails.compiler.GrailsCompileStatic +import grails.config.Config +import grails.core.GrailsApplication +import grails.plugin.springsecurity.SpringSecurityUtils + +@GrailsCompileStatic class BootStrap { + + RoleService roleService + UserService userService + UserRoleService userRoleService def init = { servletContext -> + + List authorities = ['ROLE_USER','ROLE_MODERATOR','ROLE_ADMIN'] + authorities.each { + if ( !roleService.findByAuthority(it)) + roleService.save(it) + } + + + ConfigObject obj = SpringSecurityUtils.securityConfig + String adminUserName = obj.getProperty('adminUser') + User adminUser = userService.findByUsername(adminUserName) + if (adminUser == null) { + adminUser = new User(username : adminUserName) + userService.save(adminUser) + authorities.each { + Role role = roleService.findByAuthority(it) + userRoleService.save(adminUser, role) + } + } } + def destroy = { } } diff --git a/grails-app/services/com/muwire/mucats/security/RoleService.groovy b/grails-app/services/com/muwire/mucats/security/RoleService.groovy new file mode 100644 index 0000000..d6fdf2f --- /dev/null +++ b/grails-app/services/com/muwire/mucats/security/RoleService.groovy @@ -0,0 +1,10 @@ +package com.muwire.mucats.security; + +import grails.gorm.services.Service; + +@Service(Role) +public interface RoleService { + + Role save(String authority); + Role findByAuthority(String authority); +} diff --git a/grails-app/services/com/muwire/mucats/security/UserCreatorService.groovy b/grails-app/services/com/muwire/mucats/security/UserCreatorService.groovy new file mode 100644 index 0000000..e54f6f9 --- /dev/null +++ b/grails-app/services/com/muwire/mucats/security/UserCreatorService.groovy @@ -0,0 +1,46 @@ +package com.muwire.mucats.security + +import org.springframework.context.annotation.DependsOn + +import grails.core.GrailsApplication +import grails.gorm.services.Service +import grails.gorm.transactions.Transactional +import groovy.transform.CompileStatic + +@Transactional +class UserCreatorService { + + GrailsApplication grailsApplication + RoleService roleService + UserRoleService userRoleService + + /** + * @param userName to get or create + * @return the roles for that user name + */ + public synchronized String[] getOrCreate(String userName) { + User user = User.where {username == userName}.get() + if (user == null) { + Role role = getRoleService().findByAuthority("ROLE_USER") + user = new User(username : userName) + user.save() + getUserRoleService().save(user, role) + return ["ROLE_USER"] + } + getUserRoleService().findUserRoles(user).collect {it.role.authority} + } + + UserRoleService getUserRoleService() { + if (this.userRoleService == null) { + userRoleService = grailsApplication.mainContext.userRoleService + } + userRoleService + } + + RoleService getRoleService() { + if (this.roleService == null) { + roleService = grailsApplication.mainContext.roleService + } + roleService + } +} diff --git a/grails-app/services/com/muwire/mucats/security/UserRoleService.groovy b/grails-app/services/com/muwire/mucats/security/UserRoleService.groovy new file mode 100644 index 0000000..e19c0c5 --- /dev/null +++ b/grails-app/services/com/muwire/mucats/security/UserRoleService.groovy @@ -0,0 +1,11 @@ +package com.muwire.mucats.security; + +import java.util.List; + +import grails.gorm.services.Service; + +@Service(UserRole) +public interface UserRoleService { + UserRole save(User user, Role role); + List findUserRoles(User user); +} diff --git a/grails-app/services/com/muwire/mucats/security/UserService.groovy b/grails-app/services/com/muwire/mucats/security/UserService.groovy new file mode 100644 index 0000000..cdda2b1 --- /dev/null +++ b/grails-app/services/com/muwire/mucats/security/UserService.groovy @@ -0,0 +1,11 @@ +package com.muwire.mucats.security; + +import grails.gorm.services.Service; + +@Service(User) +public interface UserService { + + User findByUsername(String username); + + User save(User user); +} diff --git a/grails-app/views/publish/index.gsp b/grails-app/views/publish/index.gsp index ff33464..c5fb7d7 100644 --- a/grails-app/views/publish/index.gsp +++ b/grails-app/views/publish/index.gsp @@ -5,6 +5,11 @@

You are logged in as

+

You have the following roles:

+
    +
  • User
  • +
  • Moderator
  • +
  • Admin
  • Publish page goes here !

    diff --git a/src/main/groovy/com/muwire/mucats/security/ChallengeResponseAuthenticationProvider.groovy b/src/main/groovy/com/muwire/mucats/security/ChallengeResponseAuthenticationProvider.groovy index dac6621..37c405f 100644 --- a/src/main/groovy/com/muwire/mucats/security/ChallengeResponseAuthenticationProvider.groovy +++ b/src/main/groovy/com/muwire/mucats/security/ChallengeResponseAuthenticationProvider.groovy @@ -29,7 +29,6 @@ class ChallengeResponseAuthenticationProvider implements AuthenticationProvider def spk = cra.getPersona().getDestination().getSigningPublicKey() if (DSAEngine.getInstance().verifySignature(sig, cra.getChallenge(), spk)) { authentication.setAuthenticated(true) - cra.setRoles("ROLE_USER") // TODO: check with db and stuff return cra }else throw new AuthenticationException("invalid response") {} diff --git a/src/main/groovy/com/muwire/mucats/security/UserCreatingAuthenticationSuccessHandler.groovy b/src/main/groovy/com/muwire/mucats/security/UserCreatingAuthenticationSuccessHandler.groovy index 1feb407..e4e29a9 100644 --- a/src/main/groovy/com/muwire/mucats/security/UserCreatingAuthenticationSuccessHandler.groovy +++ b/src/main/groovy/com/muwire/mucats/security/UserCreatingAuthenticationSuccessHandler.groovy @@ -4,14 +4,14 @@ import javax.servlet.ServletException import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse +import org.springframework.context.annotation.Bean import org.springframework.security.core.Authentication import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler -import grails.gorm.transactions.Transactional - -@Transactional class UserCreatingAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { + UserCreatorService userCreator + @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) @@ -19,19 +19,8 @@ class UserCreatingAuthenticationSuccessHandler extends SavedRequestAwareAuthenti ChallengeResponseAuthentication cra = authentication String userName = cra.getPersona().getHumanReadableName() - User user = User.where { username == userName }.get() - if (user == null) { - user = new User(username : userName) - user.save() - Role role = Role.where { authority == "ROLE_USER"}.get() - if (role == null) { - role = new Role(authority : "ROLE_USER") - role.save() - } - UserRole userRole = new UserRole(user : user, role : role) - userRole.save() - } - + String [] roles = userCreator.getOrCreate(userName) + cra.setRoles(roles) super.onAuthenticationSuccess(request, response, authentication) } }