Skip to content

Commit

Permalink
Added checkbox to registration form for University Supervisor
Browse files Browse the repository at this point in the history
- new Domain class RoleRequest
  - RoleRequest is created when registrating, but is enabled after confirming account.
- Added new notifications when creating, approving or declining RoleRequest
- RoleRequests can be found under Members tab
  - Members tab now has 2 tabs inside, Members and RoleRequests
  - Only Admin can approve, decline RoleRequest
  • Loading branch information
pehala committed Nov 16, 2016
1 parent ae57881 commit 9434754
Show file tree
Hide file tree
Showing 21 changed files with 704 additions and 55 deletions.
4 changes: 4 additions & 0 deletions grails-app/conf/BootStrap.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,17 @@ class BootStrap {
enabled: true,
roles: [Role.STUDENT]
).save(flush: true)
new RoleRequest(applicant: example2, status: AppStatus.PENDING, enabled: true).save(flush: true)

def example3 = new User(
email: '[email protected]',
fullName: 'Example Tri',
password: "example3",
enabled: true,
roles: [Role.STUDENT]
).save(flush: true)
new RoleRequest(applicant: example3, status: AppStatus.PENDING, enabled: true).save(flush: true)

def supervisor1 = new User(
email: '[email protected]',
fullName: 'Supervisor Jedna',
Expand Down
7 changes: 6 additions & 1 deletion grails-app/conf/TestBootStrap.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,12 @@ they are done with their thesis and application management.''',
//Invalid Applications
new Application(applicant: example2, topic: tmsTopic,
university: first, note: 'I want to do it', type: Type.BACHELOR, status: AppStatus.PENDING).save(flush: true)
}

//Role requests
new RoleRequest(applicant: example1, status: AppStatus.PENDING, enabled: true).save(flush: true)
new RoleRequest(applicant: example2, status: AppStatus.PENDING, enabled: true).save(flush: true)
new RoleRequest(applicant: example3, status: AppStatus.DECLINED, enabled: true).save(flush: true)
}
}
}
}
127 changes: 127 additions & 0 deletions grails-app/controllers/com/redhat/theses/RoleRequestController.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package com.redhat.theses

import com.redhat.theses.auth.User
import com.redhat.theses.auth.Role
import com.redhat.theses.events.RoleRequestEvent
import grails.plugins.springsecurity.Secured
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils

class RoleRequestController {

/**
* Dependency injection of com.redhat.theses.FilterService
*/
def filterService

/**
* Dependency injection of grails.plugins.springsecurity.SpringSecurityService
*/
def springSecurityService

static defaultAction = "list"

@Secured(['ROLE_ADMIN'])
def list() {
if (!params.filter) {
params.filter = [:]
}
if (!params?.filtering) {
params.filter << [status: AppStatus.PENDING]
}
else {
params.type = [applicant: [fullName: "ilike"]]
}
params.filter << [enabled: true]

def requestInstanceList = filterService.filter(params, RoleRequest)
def requestInstanceTotal = filterService.count(params, RoleRequest)

[requestInstanceList: requestInstanceList, requestInstanceTotal: requestInstanceTotal]
}

def show(Integer id) {
def requestInstance = RoleRequest.get(id)

if (!requestInstance) {
flash.message = message(code: 'request.not.found', args: [id])
redirect(action: "list")
return
}

def user = springSecurityService.currentUser

if (!SpringSecurityUtils.ifAnyGranted('ROLE_ADMIN') && user != requestInstance.applicant) {
flash.message = message(code: 'security.denied.message')
redirect(action: 'list')
return
}

def canManage = SpringSecurityUtils.ifAnyGranted('ROLE_ADMIN')

[requestInstance: requestInstance, canManage: canManage]
}

@Secured('ROLE_ADMIN')
def decline(Long id) {
def requestInstance = RoleRequest.get(id)
if (!requestInstance) {
flash.message = message(code: 'request.not.found', args: [id])
redirect(action: 'list')
return
}

User user = springSecurityService.currentUser

if (!SpringSecurityUtils.ifAnyGranted('ROLE_ADMIN')) {

flash.message = message(code: 'security.denied.message')
redirect(action: 'list')
return
}

requestInstance.status = AppStatus.DECLINED

if (!requestInstance.save()) {
flash.message = message(code: 'request.save.error')
redirect(uri:'/')
return
}

event("RoleRequestDeclined", new RoleRequestEvent(requestInstance, user))
flash.message = message(code: 'request.declined', args: [id])
redirect(action: 'list')
}

@Secured('ROLE_ADMIN')
def approve(Long id) {
def requestInstance = RoleRequest.get(id)
if (!requestInstance) {
flash.message = message(code: 'request.not.found', args: [id])
redirect(action: 'list')
return
}

User user = springSecurityService.currentUser

if (!SpringSecurityUtils.ifAnyGranted('ROLE_ADMIN')) {

flash.message = message(code: 'security.denied.message')
redirect(action: 'list')
return
}

requestInstance.status = AppStatus.APPROVED

requestInstance.applicant.roles.add(Role.SUPERVISOR)

if (!requestInstance.save() || !requestInstance.applicant.save()) {
flash.message = message(code: 'request.save.error')
redirect(uri:'/')
return
}

event("RoleRequestApproved", new RoleRequestEvent(requestInstance, user))
flash.message = message(code: 'request.approved', args: [id])
redirect(action: 'list')
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.redhat.theses.auth

import com.redhat.theses.util.Util
import com.redhat.theses.AppStatus
import com.redhat.theses.RoleRequest

class RegistrationController {

Expand Down Expand Up @@ -54,17 +56,30 @@ class RegistrationController {
render(view: "index", model: [registrationCommand: registrationCommand, config: configuration.getConfig()])
return
}

def createRoleRequest = params.supervisorRequest && !Util.hasAnyDomain(user.email, configuration.defaultSupervisors)

if (createRoleRequest) {
new RoleRequest(applicant: user, status: AppStatus.PENDING, enabled: false).save()
}

log.info("User ${user.email} registration completed.")

redirect(action: 'complete')
redirect(action: 'complete', params: [isSupervisor: createRoleRequest])
}

def complete() {
def content = message(code: 'registration.complete.message')

if (params.isSupervisor == "true") {
content += "</br></br>" + message(code: 'registration.complete.request.message')
}

render view: '/emailConfirmation/lifecycle', model: [
redirect: false,
title: message(code: 'registration.complete.title'),
header: message(code: 'registration.complete.header'),
content: message(code: 'registration.complete.message')
content: content
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class UserController {

static defaultAction = "list"

@Secured(['ROLE_ADMIN'])
def list(Integer max) {
params.max = Util.max(max, MAX_USERS)

Expand Down
10 changes: 10 additions & 0 deletions grails-app/domain/com/redhat/theses/RoleRequest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.redhat.theses;

import com.redhat.theses.auth.User

class RoleRequest {

User applicant
AppStatus status
boolean enabled
}
19 changes: 19 additions & 0 deletions grails-app/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ user.accountExpired.label=Account Expired
user.accountLocked.label=Account Locked
user.roles.label=Roles
user.role.label=Role
user.list.label=List of Members
user.passwordExpired.label=Password Expired
user.sendMail.label=I want to receive mail from my subscriptions
user.list.manage.label=Manage Users
Expand Down Expand Up @@ -271,6 +272,17 @@ application.topic.disabled=You cannot apply for this topic because the topic is

application.status.select.label=-- select status --

# ROLE REQUEST
request.no.requests.found=No Role Requests found
request.list.label=List of Role Requests
request.show.title=Role Request - {0}
request.subject.approved=You have been given University Supervisor permissions.
request.subject.declined=Your request for University Supervisor permissions has been declined.
request.approved=Role Request #{0} has been approved
request.declined=Role Request #{0} has been declined
request.not.found=Role Request with id {0} was not found
request.save.error=Unable to save Role Request, please try again later.

# COMMENT
comment.label=Comment
comment.title=Comments
Expand Down Expand Up @@ -472,6 +484,10 @@ feed.thesis.created=User <a href="{1}">{0}</a> created new thesis <a href="{3}">
feed.thesis.updated=User <a href="{1}">{0}</a> updated thesis <a href="{3}">{2}</a>.
feed.thesis.deleted=User <a href="{1}">{0}</a> deleted topic <strong>{2}</strong>.

feed.request.created=User <a href="{1}">{0}</a> asked for University Supervisor <a href="{2}">permissions</a>.
feed.request.approved=User <a href="{1}">{0}</a> has given you University Supervisor permissions as you requested.
feed.request.declined=Your request for University Supervisor permissions has been declined by <a href="{1}">{0}</a>.

feed.comment.created=User <a href="{1}">{0}</a> commented on <a href="{3}">{2}</a>.

feed.application.created=User <a href="{1}">{0}</a> created <a href="{2}">new application</a> for topic <a href="{4}">{3}</a>.
Expand Down Expand Up @@ -700,11 +716,13 @@ registration.register.button=Register

registration.allowedEmails.message=Please use your <strong>university</strong> email address. You can register with email address hosted at the following internet domains:
registration.complete.title=Your account has been created
registration.complete.request.message=Administrator was also notified and will review your request to have University Supervisor permissions.
registration.complete.header=Your account has been created
registration.complete.message=Your account has been created and a confirmation email has been send to your email address, please confirm your registration within 24 hours by clicking on the link in the sent email.
registration.confirmed.title=Your registration is confirmed
registration.confirmed.header=Your registration is confirmed
registration.confirmed.message=You have successfully confirmed your account. You will be redirected to the login page shortly.
registration.supervisor.request=I am Supervisor from university

# Profile
profile.edit.title=Edit Profile
Expand Down Expand Up @@ -781,3 +799,4 @@ info.filter.user=Filter members by user's full name or email. You may also put i
info.filter.topic=Filter topics by title/description/lead paragraph in English, technical supervisor's full name, academic supervisor's full name or university name. You may put in only a part of the full name or title. By default, this page shows only enabled topics, you can show also disabled topic by unchecking option 'Show only enabled topics'.
info.filter.thesis=Filter thesis by one of the following fields. You may also put in only a part of the title/academic supervisor's full name/asignee's full name.
info.filter.application=Filter applications by applicant's full name, topic title (primary title, i.e. title in english) or status. You may also put in only a part of applicant's full name or topic's title.
info.filter.request=Filter applications by applicant's full name or status.
19 changes: 19 additions & 0 deletions grails-app/i18n/messages_cs.properties
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ user.accountExpired.label=Účet vypršel
user.accountLocked.label=Účet zablokován
user.roles.label=Role
user.role.label=Role
user.list.label=Uživatelé
user.passwordExpired.label=Heslo vypršelo
user.sendMail.label=Odesílat emaily z mých odběrů
user.list.manage.label=Spravovat uživatele
Expand Down Expand Up @@ -270,6 +271,17 @@ application.topic.disabled=Nemůžete podat přihlášku pro toto téma, protož

application.status.select.label=-- vyberte stav přihlášky --

# ROLE REQUEST
request.no.requests.found=Žádné Žádosti o pravomoce nenalezeny.
request.list.label=Žádosti o pravomoce
request.show.title=Žádost o pravomoce - {0}
request.subject.approved=Byly ti přiděleny práva Univerzitního vedoucího.
request.subject.declined=Váš požadavek na práva Univerzitního vedoucího byl zamítnut.
request.approved=Žádost o pravomoce #{0} byla schálena
request.declined=Žádost o pravomoce #{0} byla zamítnuta
request.not.found=Žádost o pravomoce s id {0} nebyla nalezena
request.save.error=Nepodařilo se uložit Žádost o pravomoce, zkuste to prosím později.

# COMMENT
comment.label=Komentář
comment.title=Komentáře
Expand Down Expand Up @@ -467,6 +479,10 @@ feed.topic.created=Uživatel <a href="{1}">{0}</a> vytvořil nové téma <a href
feed.topic.updated=Uživatel <a href="{1}">{0}</a> upravil téma <a href="{3}">{2}</a>.
feed.topic.deleted=Uživatel <a href="{1}">{0}</a> smazal téma <strong>{2}</strong>.

feed.request.created=Uživatel <a href="{1}">{0}</a> požádal o <a href="{2}">práva</a> Univerzitního vedoucího.
feed.request.approved=Uživatel <a href="{1}">{0}</a> Vám přidělil práva Univerzitního vedoucího, jak jste si přál.
feed.request.declined=Váš požadavek o práva Univerzitního vedoucího byl zamítnut uživatelem <a href="{1}">{0}</a>.

feed.thesis.created=Uživatel <a href="{1}">{0}</a> vytvořil novou kvalifikační práci <a href="{3}">{2}</a>.
feed.thesis.updated=Uživatel <a href="{1}">{0}</a> upravil kvalifikační práci <a href="{3}">{2}</a>.
feed.thesis.deleted=Uživatel <a href="{1}">{0}</a> smazal kvalifikační práci <strong>{2}</strong>.
Expand Down Expand Up @@ -700,9 +716,11 @@ registration.allowedEmails.message=Prosím použíjte svůj <strong>univerzitní
registration.complete.title=Váš účet byl vytvořen
registration.complete.header=Váš účet byl vytvořen
registration.complete.message=Váš účet byl vytvořen a potvrzující email byl odeslán na vaši emailovou adresu, prosím potvrďte vaši registraci do 24 hodin kliknutím na odkaz v odeslaném emailu.
registration.complete.request.message=Administrátor byl upozorněn a zhodnotí Váš požadavek na práva Univerzitního vedoucího.
registration.confirmed.title=Vaše registrace byla úspěšně potvrzena
registration.confirmed.header=Vaše registrace byla úspěšně potvrzena
registration.confirmed.message=Úspěšně jste potvrdil vaši registraci. Za moment budete přesměrováni na přihlašovací stránku.
registration.supervisor.request=Jsem Univerzitní vedoucí

# Profile
profile.edit.title=Upravení profilu
Expand Down Expand Up @@ -779,3 +797,4 @@ info.filter.user=Uživatele lze filtrovat podle jejich jména nebo e-mailové ad
info.filter.topic=Témata můžete filtrovat podle primárního názvu/popisu/perexu, jména technického vedoucího, podle univerzitního vedoucího nebo jména univerzity. Můžete také zadat pouze část jména nebo názvu. Tato stránka zobrazuje standardně pouze povolená témata, pokud potřebujete zobrazit i zakázaná témata, odškrtněte možnost &bdquo;Zobrazit pouze povolená témata&rdquo;.
info.filter.thesis=Kvalifikační práce můžete filtrovat jedním z následujících polí. Při filtrování lze také zadat pouze část názvu nebo jména.
info.filter.application=Přihlášky můžete filtrovat podle primárního názvu témata (tj. anglického názvu), podle jména uživatele, který přihlášku podal, nebo podle stavu přihlášky. Lze také zadat pouze část jména nebo názvu. Standardně se zobrazují pouze přihlášky, které ještě nejsou schválené.
info.filter.request=Přihlášky můžete filtrovat podle jména uživatele a stavu požadavku.
2 changes: 2 additions & 0 deletions grails-app/migrations/changelog.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ databaseChangeLog = {
include file: 'application-approved-replaced-by-status.groovy'

include file: 'add-links-to-theses.groovy'

include file: 'roleRequest.groovy'
}
34 changes: 34 additions & 0 deletions grails-app/migrations/roleRequest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
databaseChangeLog = {

changeSet(author: "phala (generated)", id: "1472640506724-1") {
createTable(tableName: "role_request") {
column(name: "id", type: "int8") {
constraints(nullable: "false", primaryKey: "true", primaryKeyName: "role_requestPK")
}

column(name: "version", type: "int8") {
constraints(nullable: "false")
}

column(name: "applicant_id", type: "int8") {
constraints(nullable: "false")
}

column(name: "enabled", type: "bool") {
constraints(nullable: "false")
}

column(name: "status", type: "varchar(255)") {
constraints(nullable: "false")
}
}
}

changeSet(author: "phala (generated)", id: "1472640506724-3") {
dropIndex(indexName: "unique_applicant_id", tableName: "application")
}

changeSet(author: "phala (generated)", id: "1472640506724-2") {
addForeignKeyConstraint(baseColumnNames: "applicant_id", baseTableName: "role_request", constraintName: "FK581F43C67E712562", deferrable: "false", initiallyDeferred: "false", referencedColumnNames: "id", referencedTableName: "user", referencesUniqueColumn: "false")
}
}
Loading

0 comments on commit 9434754

Please sign in to comment.