Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

implemented security usingthe spring security plugin

  • Loading branch information...
commit 4bbe260289a20839802cf8848908a3135b0558da 1 parent 6243e14
Jettro Coenradie authored
Showing with 1,690 additions and 12 deletions.
  1. +9 −0 MyScheduling-grailsPlugins.iml
  2. +2 −1  application.properties
  3. +51 −0 grails-app/conf/BootStrap.groovy
  4. +5 −1 grails-app/conf/Config.groovy
  5. +10 −0 grails-app/conf/SecurityConfig.groovy
  6. +182 −0 grails-app/controllers/nl/gridshore/scheduling/LoginController.groovy
  7. +15 −0 grails-app/controllers/nl/gridshore/scheduling/LogoutController.groovy
  8. +105 −0 grails-app/controllers/nl/gridshore/scheduling/RequestmapController.groovy
  9. +125 −0 grails-app/controllers/nl/gridshore/scheduling/RoleController.groovy
  10. +155 −2 grails-app/controllers/nl/gridshore/scheduling/UserController.groovy
  11. +15 −0 grails-app/domain/nl/gridshore/scheduling/Requestmap.groovy
  12. +19 −0 grails-app/domain/nl/gridshore/scheduling/Role.groovy
  13. +28 −8 grails-app/domain/nl/gridshore/scheduling/User.groovy
  14. +79 −0 grails-app/views/login/auth.gsp
  15. +6 −0 grails-app/views/login/denied.gsp
  16. +67 −0 grails-app/views/login/openIdAuth.gsp
  17. +53 −0 grails-app/views/requestmap/create.gsp
  18. +63 −0 grails-app/views/requestmap/edit.gsp
  19. +50 −0 grails-app/views/requestmap/list.gsp
  20. +51 −0 grails-app/views/requestmap/show.gsp
  21. +51 −0 grails-app/views/role/create.gsp
  22. +69 −0 grails-app/views/role/edit.gsp
  23. +49 −0 grails-app/views/role/list.gsp
  24. +57 −0 grails-app/views/role/show.gsp
  25. +94 −0 grails-app/views/user/create.gsp
  26. +104 −0 grails-app/views/user/edit.gsp
  27. +49 −0 grails-app/views/user/list.gsp
  28. +76 −0 grails-app/views/user/show.gsp
  29. +17 −0 test/unit/nl/gridshore/scheduling/RequestmapControllerTests.groovy
  30. +17 −0 test/unit/nl/gridshore/scheduling/UserServiceTests.groovy
  31. +17 −0 test/unit/nl/gridshore/scheduling/security/RoleControllerTests.groovy
9 MyScheduling-grailsPlugins.iml
View
@@ -16,6 +16,13 @@
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
+ <content url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2">
+ <sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/src/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/src/groovy" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/grails-app/controllers" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/grails-app/services" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/grails-app/taglib" isTestSource="false" />
+ </content>
<content url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/bubbling-2.1.1">
<sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/bubbling-2.1.1/src/groovy" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/bubbling-2.1.1/grails-app/taglib" isTestSource="false" />
@@ -59,9 +66,11 @@
<root url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/grails-ui-1.2-SNAPSHOT/lib" />
<root url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/db-util-0.4/lib" />
<root url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/mail-0.9/lib" />
+ <root url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
+ <jarDirectory url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/acegi-0.5.2/lib" recursive="false" />
<jarDirectory url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/db-util-0.4/lib" recursive="false" />
<jarDirectory url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/grails-ui-1.2-SNAPSHOT/lib" recursive="false" />
<jarDirectory url="file://$MODULE_DIR$/../../.grails/1.2.0/projects/MyScheduling/plugins/joda-time-0.5/lib" recursive="false" />
3  application.properties
View
@@ -1,9 +1,10 @@
#Grails Metadata file
-#Sun Jan 03 08:18:48 CET 2010
+#Mon Jan 04 13:06:10 CET 2010
app.grails.version=1.2.0
app.name=MyScheduling
app.servlet.version=2.4
app.version=0.1
+plugins.acegi=0.5.2
plugins.bubbling=2.1.1
plugins.db-util=0.4
plugins.grails-ui=1.2-SNAPSHOT
51 grails-app/conf/BootStrap.groovy
View
@@ -1,8 +1,13 @@
import nl.gridshore.scheduling.Person
import nl.gridshore.scheduling.Project
+import nl.gridshore.scheduling.Role
+import nl.gridshore.scheduling.Requestmap
+import nl.gridshore.scheduling.User
class BootStrap {
+ def authenticateService
+
def init = { servletContext ->
def jettro = new Person(name:'Jettro',partTimeFactor:1)
jettro.save()
@@ -24,6 +29,52 @@ class BootStrap {
jettro.addToProjects newsfeed
jettro.addToProjects cqrs4j
allard.addToProjects cqrs4j
+ roberto.addToProjects newsfeed
+
+ // security
+ // roles
+ def roleAdmin = new Role(authority:"ROLE_ADMIN",description:"admin")
+ roleAdmin.save()
+ def roleSysAdmin = new Role(authority:"ROLE_SYSADMIN",description:"sysadmin")
+ roleSysAdmin.save()
+
+ // request maps
+ def securePerson = new Requestmap(url:"/person/**",configAttribute:"ROLE_ADMIN")
+ securePerson.save()
+ def secureProject = new Requestmap(url:"/project/**",configAttribute:"ROLE_ADMIN")
+ secureProject.save()
+ def secureUser = new Requestmap(url:"/user/**",configAttribute:"ROLE_ADMIN")
+ secureUser.save()
+ def secureRole = new Requestmap(url:"/role/**",configAttribute:"ROLE_SYSADMIN")
+ secureRole.save()
+ def secureRequestmap = new Requestmap(url:"/requestmap/**",configAttribute:"ROLE_SYSADMIN")
+ secureRequestmap.save()
+
+ // users
+ def passwdAdmin = authenticateService.encodePassword('admin')
+ def admin = new User(
+ username:"admin",
+ userRealName:"Administrator",
+ passwd:passwdAdmin,
+ enabled:true,
+ email:"admin@myscheduling",
+ emailShow:true,
+ description:'Can be used to do administrative tasks')
+ admin.save()
+ admin.addToAuthorities roleAdmin
+
+ def passwdSysadmin = authenticateService.encodePassword('sysadmin')
+ def sysadmin = new User(
+ username:"sysadmin",
+ userRealName:"System Administrator",
+ passwd:passwdSysadmin,
+ enabled:true,
+ email:"sysadmin@myscheduling",
+ emailShow:true,
+ description:'Can be used to do system administrative tasks')
+ sysadmin.save()
+ sysadmin.addToAuthorities roleAdmin
+ sysadmin.addToAuthorities roleSysAdmin
}
def destroy = {
}
6 grails-app/conf/Config.groovy
View
@@ -103,4 +103,8 @@ log4j = {
}
-
+
+
+//log4j.logger.org.springframework.security='off,stdout'
+
+//log4j.logger.org.springframework.security='off,stdout'
10 grails-app/conf/SecurityConfig.groovy
View
@@ -0,0 +1,10 @@
+security {
+
+ // see DefaultSecurityConfig.groovy for all settable/overridable properties
+
+ active = true
+
+ loginUserDomainClass = "nl.gridshore.scheduling.User"
+ authorityDomainClass = "nl.gridshore.scheduling.Role"
+ requestMapClass = "nl.gridshore.scheduling.Requestmap"
+}
182 grails-app/controllers/nl/gridshore/scheduling/LoginController.groovy
View
@@ -0,0 +1,182 @@
+package nl.gridshore.scheduling
+
+import org.codehaus.groovy.grails.plugins.springsecurity.RedirectUtils
+import org.grails.plugins.springsecurity.service.AuthenticateService
+
+import org.springframework.security.AuthenticationTrustResolverImpl
+import org.springframework.security.DisabledException
+import org.springframework.security.context.SecurityContextHolder as SCH
+import org.springframework.security.ui.AbstractProcessingFilter
+import org.springframework.security.ui.webapp.AuthenticationProcessingFilter
+import org.springframework.security.context.SecurityContextHolder
+
+/**
+ * Login Controller (Example).
+ */
+class LoginController {
+
+ /**
+ * Dependency injection for the authentication service.
+ */
+ def authenticateService
+
+ /**
+ * Dependency injection for OpenIDConsumer.
+ */
+ def openIDConsumer
+
+ /**
+ * Dependency injection for OpenIDAuthenticationProcessingFilter.
+ */
+ def openIDAuthenticationProcessingFilter
+
+ private final authenticationTrustResolver = new AuthenticationTrustResolverImpl()
+
+ def index = {
+ if (isLoggedIn()) {
+ redirect uri: '/'
+ }
+ else {
+ redirect action: auth, params: params
+ }
+ }
+
+ /**
+ * Show the login page.
+ */
+ def auth = {
+
+ nocache response
+
+ if (isLoggedIn()) {
+ redirect uri: '/'
+ return
+ }
+
+ String view
+ String postUrl
+ def config = authenticateService.securityConfig.security
+ if (config.useOpenId) {
+ view = 'openIdAuth'
+ postUrl = "${request.contextPath}/login/openIdAuthenticate"
+ }
+ else if (config.useFacebook) {
+ view = 'facebookAuth'
+ postUrl = "${request.contextPath}${config.facebook.filterProcessesUrl}"
+ }
+ else {
+ view = 'auth'
+ postUrl = "${request.contextPath}${config.filterProcessesUrl}"
+ }
+
+ render view: view, model: [postUrl: postUrl]
+ }
+
+ /**
+ * Form submit action to start an OpenID authentication.
+ */
+ def openIdAuthenticate = {
+ String openID = params['j_username']
+ try {
+ String returnToURL = RedirectUtils.buildRedirectUrl(
+ request, response, openIDAuthenticationProcessingFilter.filterProcessesUrl)
+ String redirectUrl = openIDConsumer.beginConsumption(request, openID, returnToURL)
+ redirect url: redirectUrl
+ }
+ catch (org.springframework.security.ui.openid.OpenIDConsumerException e) {
+ log.error "Consumer error: $e.message", e
+ redirect url: openIDAuthenticationProcessingFilter.authenticationFailureUrl
+ }
+ }
+
+ // Login page (function|json) for Ajax access.
+ def authAjax = {
+ nocache(response)
+ //this is example:
+ render """
+ <script type='text/javascript'>
+ (function() {
+ loginForm();
+ })();
+ </script>
+ """
+ }
+
+ /**
+ * The Ajax success redirect url.
+ */
+ def ajaxSuccess = {
+ nocache(response)
+ render '{success: true}'
+ }
+
+ /**
+ * Show denied page.
+ */
+ def denied = {
+ if (isLoggedIn() && authenticationTrustResolver.isRememberMe(SecurityContextHolder.context?.authentication)) {
+ // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
+ redirect action: full, params: params
+ }
+ }
+
+ /**
+ * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
+ */
+ def full = {
+ render view: 'auth', params: params,
+ model: [hasCookie: authenticationTrustResolver.isRememberMe(SecurityContextHolder.context?.authentication)]
+ }
+
+ // Denial page (data|view|json) for Ajax access.
+ def deniedAjax = {
+ //this is example:
+ render "{error: 'access denied'}"
+ }
+
+ /**
+ * login failed
+ */
+ def authfail = {
+
+ def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
+ def msg = ''
+ def exception = session[AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY]
+ if (exception) {
+ if (exception instanceof DisabledException) {
+ msg = "[$username] is disabled."
+ }
+ else {
+ msg = "[$username] wrong username/password."
+ }
+ }
+
+ if (isAjax()) {
+ render "{error: '${msg}'}"
+ }
+ else {
+ flash.message = msg
+ redirect action: auth, params: params
+ }
+ }
+
+ /**
+ * Check if logged in.
+ */
+ private boolean isLoggedIn() {
+ return authenticateService.isLoggedIn()
+ }
+
+ private boolean isAjax() {
+ return authenticateService.isAjax(request)
+ }
+
+ /** cache controls */
+ private void nocache(response) {
+ response.setHeader('Cache-Control', 'no-cache') // HTTP 1.1
+ response.addDateHeader('Expires', 0)
+ response.setDateHeader('max-age', 0)
+ response.setIntHeader ('Expires', -1) //prevents caching at the proxy server
+ response.addHeader('cache-Control', 'private') //IE5.x only
+ }
+}
15 grails-app/controllers/nl/gridshore/scheduling/LogoutController.groovy
View
@@ -0,0 +1,15 @@
+package nl.gridshore.scheduling
+/**
+ * Logout Controller (Example).
+ */
+class LogoutController {
+ static navigation = [group:'sitemenu',order:30]
+
+ /**
+ * Index action. Redirects to the Spring security logout uri.
+ */
+ def index = {
+ // TODO put any pre-logout code here
+ redirect(uri: '/j_spring_security_logout')
+ }
+}
105 grails-app/controllers/nl/gridshore/scheduling/RequestmapController.groovy
View
@@ -0,0 +1,105 @@
+package nl.gridshore.scheduling
+
+class RequestmapController {
+
+ def authenticateService
+
+ // the delete, save and update actions only accept POST requests
+ static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
+
+ def index = {
+ redirect action: list, params: params
+ }
+
+ def list = {
+ if (!params.max) {
+ params.max = 10
+ }
+ [requestmapList: Requestmap.list(params)]
+ }
+
+ def show = {
+ def requestmap = Requestmap.get(params.id)
+ if (!requestmap) {
+ flash.message = "Requestmap not found with id $params.id"
+ redirect action:list
+ return
+ }
+ [requestmap: requestmap]
+ }
+
+ def delete = {
+ def requestmap = Requestmap.get(params.id)
+ if (!requestmap) {
+ flash.message = "Requestmap not found with id $params.id"
+ redirect action:list
+ return
+ }
+
+ requestmap.delete()
+
+ authenticateService.clearCachedRequestmaps()
+
+ flash.message = "Requestmap $params.id deleted."
+ redirect(action: list)
+ }
+
+ def edit = {
+ def requestmap = Requestmap.get(params.id)
+ if (!requestmap) {
+ flash.message = "Requestmap not found with id $params.id"
+ redirect(action: list)
+ return
+ }
+
+ [requestmap: requestmap]
+ }
+
+ /**
+ * Update action, called when an existing Requestmap is updated.
+ */
+ def update = {
+
+ def requestmap = Requestmap.get(params.id)
+ if (!requestmap) {
+ flash.message = "Requestmap not found with id $params.id"
+ redirect(action: edit, id :params.id)
+ return
+ }
+
+ long version = params.version.toLong()
+ if (requestmap.version > version) {
+ requestmap.errors.rejectValue 'version', "requestmap.optimistic.locking.failure",
+ "Another user has updated this Requestmap while you were editing."
+ render view: 'edit', model: [requestmap: requestmap]
+ return
+ }
+
+ requestmap.properties = params
+ if (requestmap.save()) {
+ authenticateService.clearCachedRequestmaps()
+ redirect action: show, id: requestmap.id
+ }
+ else {
+ render view: 'edit', model: [requestmap: requestmap]
+ }
+ }
+
+ def create = {
+ [requestmap: new Requestmap(params)]
+ }
+
+ /**
+ * Save action, called when a new Requestmap is created.
+ */
+ def save = {
+ def requestmap = new Requestmap(params)
+ if (requestmap.save()) {
+ authenticateService.clearCachedRequestmaps()
+ redirect action: show, id: requestmap.id
+ }
+ else {
+ render view: 'create', model: [requestmap: requestmap]
+ }
+ }
+}
125 grails-app/controllers/nl/gridshore/scheduling/RoleController.groovy
View
@@ -0,0 +1,125 @@
+package nl.gridshore.scheduling
+
+import nl.gridshore.scheduling.Role
+import nl.gridshore.scheduling.Requestmap
+
+/**
+ * Authority Controller.
+ */
+class RoleController {
+
+ // the delete, save and update actions only accept POST requests
+ static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
+
+ def authenticateService
+
+ def index = {
+ redirect action: list, params: params
+ }
+
+ /**
+ * Display the list authority page.
+ */
+ def list = {
+ if (!params.max) {
+ params.max = 10
+ }
+ [authorityList: Role.list(params)]
+ }
+
+ /**
+ * Display the show authority page.
+ */
+ def show = {
+ def authority = Role.get(params.id)
+ if (!authority) {
+ flash.message = "Role not found with id $params.id"
+ redirect action: list
+ return
+ }
+
+ [authority: authority]
+ }
+
+ /**
+ * Delete an authority.
+ */
+ def delete = {
+ def authority = Role.get(params.id)
+ if (!authority) {
+ flash.message = "Role not found with id $params.id"
+ redirect action: list
+ return
+ }
+
+ authenticateService.deleteRole(authority)
+
+ flash.message = "Role $params.id deleted."
+ redirect action: list
+ }
+
+ /**
+ * Display the edit authority page.
+ */
+ def edit = {
+ def authority = Role.get(params.id)
+ if (!authority) {
+ flash.message = "Role not found with id $params.id"
+ redirect action: list
+ return
+ }
+
+ [authority: authority]
+ }
+
+ /**
+ * Authority update action.
+ */
+ def update = {
+
+ def authority = Role.get(params.id)
+ if (!authority) {
+ flash.message = "Role not found with id $params.id"
+ redirect action: edit, id: params.id
+ return
+ }
+
+ long version = params.version.toLong()
+ if (authority.version > version) {
+ authority.errors.rejectValue 'version', 'authority.optimistic.locking.failure',
+ 'Another user has updated this Role while you were editing.'
+ render view: 'edit', model: [authority: authority]
+ return
+ }
+
+ if (authenticateService.updateRole(authority, params)) {
+ authenticateService.clearCachedRequestmaps()
+ redirect action: show, id: authority.id
+ }
+ else {
+ render view: 'edit', model: [authority: authority]
+ }
+ }
+
+ /**
+ * Display the create new authority page.
+ */
+ def create = {
+ [authority: new Role()]
+ }
+
+ /**
+ * Save a new authority.
+ */
+ def save = {
+
+ def authority = new Role()
+ authority.properties = params
+ if (authority.save()) {
+ redirect action: show, id: authority.id
+ }
+ else {
+ render view: 'create', model: [authority: authority]
+ }
+ }
+}
157 grails-app/controllers/nl/gridshore/scheduling/UserController.groovy
View
@@ -1,6 +1,7 @@
package nl.gridshore.scheduling
class UserController {
+
static navigation = [
group:'tabs',
order:200,
@@ -10,5 +11,157 @@ class UserController {
]
]
- def scaffold = true
-}
+ def authenticateService
+
+ // the delete, save and update actions only accept POST requests
+ static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']
+
+ def index = {
+ redirect action: list, params: params
+ }
+
+ def list = {
+ if (!params.max) {
+ params.max = 10
+ }
+ [personList: User.list(params)]
+ }
+
+ def show = {
+ def person = User.get(params.id)
+ if (!person) {
+ flash.message = "User not found with id $params.id"
+ redirect action: list
+ return
+ }
+ List roleNames = []
+ for (role in person.authorities) {
+ roleNames << role.authority
+ }
+ roleNames.sort { n1, n2 ->
+ n1 <=> n2
+ }
+ [person: person, roleNames: roleNames]
+ }
+
+ /**
+ * Person delete action. Before removing an existing person,
+ * he should be removed from those authorities which he is involved.
+ */
+ def delete = {
+
+ def person = User.get(params.id)
+ if (person) {
+ def authPrincipal = authenticateService.principal()
+ //avoid self-delete if the logged-in user is an admin
+ if (!(authPrincipal instanceof String) && authPrincipal.username == person.username) {
+ flash.message = "You can not delete yourself, please login as another admin and try again"
+ }
+ else {
+ //first, delete this person from People_Authorities table.
+ Role.findAll().each { it.removeFromPeople(person) }
+ person.delete()
+ flash.message = "User $params.id deleted."
+ }
+ }
+ else {
+ flash.message = "User not found with id $params.id"
+ }
+
+ redirect action: list
+ }
+
+ def edit = {
+
+ def person = User.get(params.id)
+ if (!person) {
+ flash.message = "User not found with id $params.id"
+ redirect action: list
+ return
+ }
+
+ return buildPersonModel(person)
+ }
+
+ /**
+ * Person update action.
+ */
+ def update = {
+
+ def person = User.get(params.id)
+ if (!person) {
+ flash.message = "User not found with id $params.id"
+ redirect action: edit, id: params.id
+ return
+ }
+
+ long version = params.version.toLong()
+ if (person.version > version) {
+ person.errors.rejectValue 'version', "person.optimistic.locking.failure",
+ "Another user has updated this User while you were editing."
+ render view: 'edit', model: buildPersonModel(person)
+ return
+ }
+
+ def oldPassword = person.passwd
+ person.properties = params
+ if (!params.passwd.equals(oldPassword)) {
+ person.passwd = authenticateService.encodePassword(params.passwd)
+ }
+ if (person.save()) {
+ Role.findAll().each { it.removeFromPeople(person) }
+ addRoles(person)
+ redirect action: show, id: person.id
+ }
+ else {
+ render view: 'edit', model: buildPersonModel(person)
+ }
+ }
+
+ def create = {
+ [person: new User(params), authorityList: Role.list()]
+ }
+
+ /**
+ * Person save action.
+ */
+ def save = {
+
+ def person = new User()
+ person.properties = params
+ person.passwd = authenticateService.encodePassword(params.passwd)
+ if (person.save()) {
+ addRoles(person)
+ redirect action: show, id: person.id
+ }
+ else {
+ render view: 'create', model: [authorityList: Role.list(), person: person]
+ }
+ }
+
+ private void addRoles(person) {
+ for (String key in params.keySet()) {
+ if (key.contains('ROLE') && 'on' == params.get(key)) {
+ Role.findByAuthority(key).addToPeople(person)
+ }
+ }
+ }
+
+ private Map buildPersonModel(person) {
+
+ List roles = Role.list()
+ roles.sort { r1, r2 ->
+ r1.authority <=> r2.authority
+ }
+ Set userRoleNames = []
+ for (role in person.authorities) {
+ userRoleNames << role.authority
+ }
+ LinkedHashMap<Role, Boolean> roleMap = [:]
+ for (role in roles) {
+ roleMap[(role)] = userRoleNames.contains(role.authority)
+ }
+
+ return [person: person, roleMap: roleMap]
+ }
+}
15 grails-app/domain/nl/gridshore/scheduling/Requestmap.groovy
View
@@ -0,0 +1,15 @@
+package nl.gridshore.scheduling
+
+/**
+ * Request Map domain class.
+ */
+class Requestmap {
+
+ String url
+ String configAttribute
+
+ static constraints = {
+ url(blank: false, unique: true)
+ configAttribute(blank: false)
+ }
+}
19 grails-app/domain/nl/gridshore/scheduling/Role.groovy
View
@@ -0,0 +1,19 @@
+package nl.gridshore.scheduling
+
+/**
+ * Authority domain class.
+ */
+class Role {
+
+ static hasMany = [people: User]
+
+ /** description */
+ String description
+ /** ROLE String */
+ String authority
+
+ static constraints = {
+ authority(blank: false, unique: true)
+ description()
+ }
+}
36 grails-app/domain/nl/gridshore/scheduling/User.groovy
View
@@ -1,15 +1,35 @@
package nl.gridshore.scheduling
+/**
+ * User domain class.
+ */
class User {
- String username
- // TODO find out if it is possible to use sha1 encoding of the password
- String password
+ static transients = ['pass']
+ static hasMany = [authorities: Role]
+ static belongsTo = Role
- static constraints = {
- }
+ /** Username */
+ String username
+ /** User Real Name*/
+ String userRealName
+ /** MD5 Password */
+ String passwd
+ /** enabled */
+ boolean enabled
- String toString() {
- return username
- }
+ String email
+ boolean emailShow
+ /** description */
+ String description = ''
+
+ /** plain password to create a MD5 password */
+ String pass = '[secret]'
+
+ static constraints = {
+ username(blank: false, unique: true)
+ userRealName(blank: false)
+ passwd(blank: false)
+ enabled()
+ }
}
79 grails-app/views/login/auth.gsp
View
@@ -0,0 +1,79 @@
+<head>
+<meta name='layout' content='main' />
+<title>Login</title>
+<style type='text/css' media='screen'>
+#login {
+ margin:15px 0px; padding:0px;
+ text-align:center;
+}
+#login .inner {
+ width:260px;
+ margin:0px auto;
+ text-align:left;
+ padding:10px;
+ border-top:1px dashed #499ede;
+ border-bottom:1px dashed #499ede;
+ background-color:#EEF;
+}
+#login .inner .fheader {
+ padding:4px;margin:3px 0px 3px 0;color:#2e3741;font-size:14px;font-weight:bold;
+}
+#login .inner .cssform p {
+ clear: left;
+ margin: 0;
+ padding: 5px 0 8px 0;
+ padding-left: 105px;
+ border-top: 1px dashed gray;
+ margin-bottom: 10px;
+ height: 1%;
+}
+#login .inner .cssform input[type='text'] {
+ width: 120px;
+}
+#login .inner .cssform label {
+ font-weight: bold;
+ float: left;
+ margin-left: -105px;
+ width: 100px;
+}
+#login .inner .login_message {color:red;}
+#login .inner .text_ {width:120px;}
+#login .inner .chk {height:12px;}
+</style>
+</head>
+
+<body>
+ <div id='login'>
+ <div class='inner'>
+ <g:if test='${flash.message}'>
+ <div class='login_message'>${flash.message}</div>
+ </g:if>
+ <div class='fheader'>Please Login..</div>
+ <form action='${postUrl}' method='POST' id='loginForm' class='cssform'>
+ <p>
+ <label for='j_username'>Login ID</label>
+ <input type='text' class='text_' name='j_username' id='j_username' value='${request.remoteUser}' />
+ </p>
+ <p>
+ <label for='j_password'>Password</label>
+ <input type='password' class='text_' name='j_password' id='j_password' />
+ </p>
+ <p>
+ <label for='remember_me'>Remember me</label>
+ <input type='checkbox' class='chk' name='_spring_security_remember_me' id='remember_me'
+ <g:if test='${hasCookie}'>checked='checked'</g:if> />
+ </p>
+ <p>
+ <input type='submit' value='Login' />
+ </p>
+ </form>
+ </div>
+ </div>
+<script type='text/javascript'>
+<!--
+(function(){
+ document.forms['loginForm'].elements['j_username'].focus();
+})();
+// -->
+</script>
+</body>
6 grails-app/views/login/denied.gsp
View
@@ -0,0 +1,6 @@
+<meta name='layout' content='main' />
+<title>Denied</title>
+
+<div class='body'>
+ <div class='errors'>Sorry, you're not authorized to view this page.</div>
+</div>
67 grails-app/views/login/openIdAuth.gsp
View
@@ -0,0 +1,67 @@
+<head>
+<meta name='layout' content='main' />
+<title>Login</title>
+<style type='text/css' media='screen'>
+#login {
+ margin:15px 0px; padding:0px;
+ text-align:center;
+}
+#login .inner {
+ width:260px;
+ margin:0px auto;
+ text-align:left;
+ padding:10px;
+ border-top:1px dashed #499ede;
+ border-bottom:1px dashed #499ede;
+ background-color:#EEF;
+}
+#login .inner .fheader {
+ padding:4px;margin:3px 0px 3px 0;color:#2e3741;font-size:14px;font-weight:bold;
+}
+#login .inner .cssform p{
+ clear: left;
+ margin: 0;
+ padding: 5px 0 8px 0;
+ padding-left: 105px;
+ border-top: 1px dashed gray;
+ margin-bottom: 10px;
+ height: 1%;
+}
+#login .inner .cssform input[type='text']{
+ width: 120px;
+}
+#login .inner .cssform label{
+ font-weight: bold;
+ float: left;
+ margin-left: -105px;
+ width: 100px;
+}
+#login .inner .login_message {color:red;}
+#login .inner .text_ {width:120px;}
+</style>
+</head>
+
+<body>
+ <div id='login'>
+ <div class='inner'>
+ <g:if test='${flash.message}'>
+ <div class='login_message'>${flash.message}</div>
+ </g:if>
+ <div class='fheader'>Please Login..</div>
+ <form action='${postUrl}' method='POST' id='loginForm' class='cssform'>
+ <p>
+ <label for='j_username'>OpenID Identity</label>
+ <input type='text' class='text_' name='j_username' />
+ </p>
+ <p>
+ <input type='submit' value='Login' />
+ </p>
+ </form>
+ </div>
+ </div>
+<script type='text/javascript'>
+(function(){
+ document.forms['loginForm'].elements['j_username'].focus();
+})();
+</script>
+</body>
53 grails-app/views/requestmap/create.gsp
View
@@ -0,0 +1,53 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Create Requestmap</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Requestmap List</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Create Requestmap</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${requestmap}">
+ <div class="errors">
+ <g:renderErrors bean="${requestmap}" as="list" />
+ </div>
+ </g:hasErrors>
+ <g:form action="save">
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="url">URL Pattern:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:requestmap,field:'url','errors')}">
+ <input type="text" id="url" name="url" value="${requestmap.url?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="configAttribute">Role (comma-delimited):</label></td>
+ <td valign="top" class="value ${hasErrors(bean:requestmap,field:'configAttribute','errors')}">
+ <input type="text" id="configAttribute" name="configAttribute" value="${requestmap.configAttribute?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><input class="save" type="submit" value="Create" /></span>
+ </div>
+
+ </g:form>
+
+ </div>
+</body>
63 grails-app/views/requestmap/edit.gsp
View
@@ -0,0 +1,63 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Edit Requestmap</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Requestmap List</g:link></span>
+ <span class="menuButton"><g:link class="create" action="create">New Requestmap</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Edit Requestmap</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${requestmap}">
+ <div class="errors">
+ <g:renderErrors bean="${requestmap}" as="list" />
+ </div>
+ </g:hasErrors>
+
+ <div class="prop">
+ <span class="name">ID:</span>
+ <span class="value">${requestmap.id}</span>
+ </div>
+
+ <g:form>
+ <input type="hidden" name="id" value="${requestmap.id}" />
+ <input type="hidden" name="version" value="${requestmap.version}" />
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="url">URL Pattern:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:requestmap,field:'url','errors')}">
+ <input type="text" id="url" name="url" value="${requestmap.url?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="configAttribute">Roles (comma-delimited):</label></td>
+ <td valign="top" class="value ${hasErrors(bean:requestmap,field:'configAttribute','errors')}">
+ <input type="text" name='configAttribute' value="${requestmap.configAttribute}"/>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><g:actionSubmit class="save" value="Update" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </div>
+
+ </g:form>
+
+ </div>
+</body>
50 grails-app/views/requestmap/list.gsp
View
@@ -0,0 +1,50 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Requestmap List</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="create" action="create">New Requestmap</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Requestmap List</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="list">
+ <table>
+ <thead>
+ <tr>
+ <g:sortableColumn property="id" title="ID" />
+ <g:sortableColumn property="url" title="URL Pattern" />
+ <g:sortableColumn property="configAttribute" title="Roles" />
+ <th>&nbsp;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${requestmapList}" status="i" var="requestmap">
+ <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
+ <td>${requestmap.id}</td>
+ <td>${requestmap.url?.encodeAsHTML()}</td>
+ <td>${requestmap.configAttribute}</td>
+ <td class="actionButtons">
+ <span class="actionButton">
+ <g:link action="show" id="${requestmap.id}">Show</g:link>
+ </span>
+ </td>
+ </tr>
+ </g:each>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="paginateButtons">
+ <g:paginate total="${nl.gridshore.scheduling.Requestmap.count()}" />
+ </div>
+
+ </div>
+</body>
51 grails-app/views/requestmap/show.gsp
View
@@ -0,0 +1,51 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Show Requestmap</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Requestmap List</g:link></span>
+ <span class="menuButton"><g:link class="create" action="create">New Requestmap</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Show Requestmap</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name">ID:</td>
+ <td valign="top" class="value">${requestmap.id}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">URL:</td>
+ <td valign="top" class="value">${requestmap.url}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Roles:</td>
+ <td valign="top" class="value">${requestmap.configAttribute}</td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <g:form>
+ <input type="hidden" name="id" value="${requestmap.id}" />
+ <span class="button"><g:actionSubmit class="edit" value="Edit" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </g:form>
+ </div>
+
+ </div>
+</body>
51 grails-app/views/role/create.gsp
View
@@ -0,0 +1,51 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Create Role</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Role List</g:link></span>
+ </div>
+
+ <div class="body">
+
+ <h1>Create Role</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${authority}">
+ <div class="errors">
+ <g:renderErrors bean="${authority}" as="list" />
+ </div>
+ </g:hasErrors>
+
+ <g:form action="save">
+ <div class="dialog">
+ <table>
+ <tbody>
+ <tr class="prop">
+ <td valign="top" class="name"><label for="authority">Role Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:authority,field:'authority','errors')}">
+ <input type="text" id="authority" name="authority" value="${authority?.authority?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="description">Description:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:authority,field:'description','errors')}">
+ <input type="text" id="description" name="description" value="${authority?.description?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><input class="save" type="submit" value="Create" /></span>
+ </div>
+ </g:form>
+ </div>
+</body>
69 grails-app/views/role/edit.gsp
View
@@ -0,0 +1,69 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Edit Role</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Role List</g:link></span>
+ <span class="menuButton"><g:link class="create" action="create">New Role</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Edit Role</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${authority}">
+ <div class="errors">
+ <g:renderErrors bean="${authority}" as="list" />
+ </div>
+ </g:hasErrors>
+ <div class="prop">
+ <span class="name">ID:</span>
+ <span class="value">${authority.id}</span>
+ </div>
+ <g:form>
+ <input type="hidden" name="id" value="${authority.id}" />
+ <input type="hidden" name="version" value="${authority.version}" />
+ <div class="dialog">
+ <table>
+ <tbody>
+ <tr class="prop">
+ <td valign="top" class="name"><label for="authority">Role Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:authority,field:'authority','errors')}">
+ <input type="text" id="authority" name="authority" value="${authority.authority?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="description">Description:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:authority,field:'description','errors')}">
+ <input type="text" id="description" name="description" value="${authority.description?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="people">People:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:authority,field:'people','errors')}">
+ <ul>
+ <g:each var="p" in="${authority.people?}">
+ <li>${p}</li>
+ </g:each>
+ </ul>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><g:actionSubmit class="save" value="Update" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </div>
+
+ </g:form>
+ </div>
+</body>
49 grails-app/views/role/list.gsp
View
@@ -0,0 +1,49 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Role List</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="create" action="create">New Role</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Role List</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="list">
+ <table>
+ <thead>
+ <tr>
+ <g:sortableColumn property="id" title="ID" />
+ <g:sortableColumn property="authority" title="Role Name" />
+ <g:sortableColumn property="description" title="Description" />
+ <th>&nbsp;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${authorityList}" status="i" var="authority">
+ <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
+ <td>${authority.id}</td>
+ <td>${authority.authority?.encodeAsHTML()}</td>
+ <td>${authority.description?.encodeAsHTML()}</td>
+ <td class="actionButtons">
+ <span class="actionButton">
+ <g:link action="show" id="${authority.id}">Show</g:link>
+ </span>
+ </td>
+ </tr>
+ </g:each>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="paginateButtons">
+ <g:paginate total="${nl.gridshore.scheduling.Role.count()}" />
+ </div>
+ </div>
+</body>
57 grails-app/views/role/show.gsp
View
@@ -0,0 +1,57 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Show Role</title>
+</head>
+
+<body>
+
+ <div class="nav">
+ <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
+ <span class="menuButton"><g:link class="list" action="list">Role List</g:link></span>
+ <span class="menuButton"><g:link class="create" action="create">New Role</g:link></span>
+ </div>
+
+ <div class="body">
+ <h1>Show Role</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name">ID:</td>
+ <td valign="top" class="value">${authority.id}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Role Name:</td>
+ <td valign="top" class="value">${authority.authority}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Description:</td>
+ <td valign="top" class="value">${authority.description}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">People:</td>
+ <td valign="top" class="value">${authority.people}</td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <g:form>
+ <input type="hidden" name="id" value="${authority?.id}" />
+ <span class="button"><g:actionSubmit class="edit" value="Edit" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </g:form>
+ </div>
+
+ </div>
+
+</body>
94 grails-app/views/user/create.gsp
View
@@ -0,0 +1,94 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Create User</title>
+</head>
+
+<body>
+
+ <div class="body">
+ <h1>Create User</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${person}">
+ <div class="errors">
+ <g:renderErrors bean="${person}" as="list" />
+ </div>
+ </g:hasErrors>
+ <g:form action="save">
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="username">Login Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'username','errors')}">
+ <input type="text" id="username" name="username" value="${person.username?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="userRealName">Full Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'userRealName','errors')}">
+ <input type="text" id="userRealName" name="userRealName" value="${person.userRealName?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="passwd">Password:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'passwd','errors')}">
+ <input type="password" id="passwd" name="passwd" value="${person.passwd?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="enabled">Enabled:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'enabled','errors')}">
+ <g:checkBox name="enabled" value="${person.enabled}" ></g:checkBox>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="description">Description:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'description','errors')}">
+ <input type="text" id="description" name="description" value="${person.description?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="email">Email:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'email','errors')}">
+ <input type="text" id="email" name="email" value="${person.email?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="emailShow">Show Email:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'emailShow','errors')}">
+ <g:checkBox name="emailShow" value="${person.emailShow}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name" align="left">Assign Roles:</td>
+ </tr>
+
+ <g:each in="${authorityList}">
+ <tr>
+ <td valign="top" class="name" align="left">${it.authority.encodeAsHTML()}</td>
+ <td align="left"><g:checkBox name="${it.authority}"/></td>
+ </tr>
+ </g:each>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><input class="save" type="submit" value="Create" /></span>
+ </div>
+
+ </g:form>
+
+ </div>
+</body>
104 grails-app/views/user/edit.gsp
View
@@ -0,0 +1,104 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Edit User</title>
+</head>
+
+<body>
+ <div class="body">
+ <h1>Edit User</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${person}">
+ <div class="errors">
+ <g:renderErrors bean="${person}" as="list" />
+ </div>
+ </g:hasErrors>
+
+ <div class="prop">
+ <span class="name">ID:</span>
+ <span class="value">${person.id}</span>
+ </div>
+
+ <g:form>
+ <input type="hidden" name="id" value="${person.id}" />
+ <input type="hidden" name="version" value="${person.version}" />
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="username">Login Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'username','errors')}">
+ <input type="text" id="username" name="username" value="${person.username?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="userRealName">Full Name:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'userRealName','errors')}">
+ <input type="text" id="userRealName" name="userRealName" value="${person.userRealName?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="passwd">Password:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'passwd','errors')}">
+ <input type="password" id="passwd" name="passwd" value="${person.passwd?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="enabled">Enabled:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'enabled','errors')}">
+ <g:checkBox name="enabled" value="${person.enabled}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="description">Description:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'description','errors')}">
+ <input type="text" id="description" name="description" value="${person.description?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="email">Email:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'email','errors')}">
+ <input type="text" id="email" name="email" value="${person?.email?.encodeAsHTML()}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="emailShow">Show Email:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'emailShow','errors')}">
+ <g:checkBox name="emailShow" value="${person.emailShow}"/>
+ </td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name"><label for="authorities">Roles:</label></td>
+ <td valign="top" class="value ${hasErrors(bean:person,field:'authorities','errors')}">
+ <ul>
+ <g:each var="entry" in="${roleMap}">
+ <li>${entry.key.authority.encodeAsHTML()}
+ <g:checkBox name="${entry.key.authority}" value="${entry.value}"/>
+ </li>
+ </g:each>
+ </ul>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <span class="button"><g:actionSubmit class="save" value="Update" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </div>
+
+ </g:form>
+
+ </div>
+</body>
49 grails-app/views/user/list.gsp
View
@@ -0,0 +1,49 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>User List</title>
+</head>
+
+<body>
+
+ <div class="body">
+ <h1>User List</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="list">
+ <table>
+ <thead>
+ <tr>
+ <g:sortableColumn property="id" title="Id" />
+ <g:sortableColumn property="username" title="Login Name" />
+ <g:sortableColumn property="userRealName" title="Full Name" />
+ <g:sortableColumn property="enabled" title="Enabled" />
+ <g:sortableColumn property="description" title="Description" />
+ <th>&nbsp;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${personList}" status="i" var="person">
+ <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
+ <td>${person.id}</td>
+ <td>${person.username?.encodeAsHTML()}</td>
+ <td>${person.userRealName?.encodeAsHTML()}</td>
+ <td>${person.enabled?.encodeAsHTML()}</td>
+ <td>${person.description?.encodeAsHTML()}</td>
+ <td class="actionButtons">
+ <span class="actionButton">
+ <g:link action="show" id="${person.id}">Show</g:link>
+ </span>
+ </td>
+ </tr>
+ </g:each>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="paginateButtons">
+ <g:paginate total="${nl.gridshore.scheduling.User.count()}" />
+ </div>
+
+ </div>
+</body>
76 grails-app/views/user/show.gsp
View
@@ -0,0 +1,76 @@
+<head>
+ <meta name="layout" content="main" />
+ <title>Show User</title>
+</head>
+
+<body>
+
+ <div class="body">
+ <h1>Show User</h1>
+ <g:if test="${flash.message}">
+ <div class="message">${flash.message}</div>
+ </g:if>
+ <div class="dialog">
+ <table>
+ <tbody>
+
+ <tr class="prop">
+ <td valign="top" class="name">ID:</td>
+ <td valign="top" class="value">${person.id}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Login Name:</td>
+ <td valign="top" class="value">${person.username?.encodeAsHTML()}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Full Name:</td>
+ <td valign="top" class="value">${person.userRealName?.encodeAsHTML()}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Enabled:</td>
+ <td valign="top" class="value">${person.enabled}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Description:</td>
+ <td valign="top" class="value">${person.description?.encodeAsHTML()}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Email:</td>
+ <td valign="top" class="value">${person.email?.encodeAsHTML()}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Show Email:</td>
+ <td valign="top" class="value">${person.emailShow}</td>
+ </tr>
+
+ <tr class="prop">
+ <td valign="top" class="name">Roles:</td>
+ <td valign="top" class="value">
+ <ul>
+ <g:each in="${roleNames}" var='name'>
+ <li>${name}</li>
+ </g:each>
+ </ul>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </div>
+
+ <div class="buttons">
+ <g:form>
+ <input type="hidden" name="id" value="${person.id}" />
+ <span class="button"><g:actionSubmit class="edit" value="Edit" /></span>
+ <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
+ </g:form>
+ </div>
+
+ </div>
+</body>
17 test/unit/nl/gridshore/scheduling/RequestmapControllerTests.groovy
View
@@ -0,0 +1,17 @@
+package nl.gridshore.scheduling
+
+import grails.test.*
+
+class RequestmapControllerTests extends ControllerUnitTestCase {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
17 test/unit/nl/gridshore/scheduling/UserServiceTests.groovy
View
@@ -0,0 +1,17 @@
+package nl.gridshore.scheduling
+
+import grails.test.*
+
+class UserServiceTests extends GrailsUnitTestCase {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
17 test/unit/nl/gridshore/scheduling/security/RoleControllerTests.groovy
View
@@ -0,0 +1,17 @@
+package nl.gridshore.scheduling.security
+
+import grails.test.*
+
+class RoleControllerTests extends ControllerUnitTestCase {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.