Skip to content

Commit

Permalink
AlaSecured annotations can now be applied to "property" style control…
Browse files Browse the repository at this point in the history
…ler actions, including webflow actions
  • Loading branch information
davidbairdala authored and davidbairdala committed Jul 15, 2014
1 parent 920a3d8 commit 28d4390
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 24 deletions.
2 changes: 1 addition & 1 deletion AlaWebThemeGrailsPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import grails.util.Holders

class AlaWebThemeGrailsPlugin {
// the plugin version
def version = "0.8"
def version = "0.8.1"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "2.1 > *"
// the other plugins this plugin depends on
Expand Down
4 changes: 2 additions & 2 deletions application.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Grails Metadata file
#Thu May 15 09:16:05 EST 2014
app.grails.version=2.3.8
#Tue Jul 15 14:07:18 EST 2014
app.grails.version=2.3.11
app.name=ala-web-theme
app.servlet.version=2.5
2 changes: 1 addition & 1 deletion grails-app/conf/BuildConfig.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ grails.project.dependency.resolution = {
plugins {
runtime ":jquery:1.7.1"
runtime ":resources:1.2.1"
compile(":tomcat:7.0.50",
compile(":tomcat:7.0.54",
":release:3.0.1") {
export = false
}
Expand Down
59 changes: 40 additions & 19 deletions grails-app/conf/au/org/ala/web/AlaSecuredFilters.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -23,53 +23,74 @@ class AlaSecuredFilters {
}

String methodName = actionName ?: "index"
// The action annotation may be applied to either a method or a property
AlaSecured actionAnnotation = null
// Look for a method on the controller whose name matches the action...
Method method = cClazz.getMethods().find { method -> method.name == methodName && Modifier.isPublic(method.getModifiers()) }

AlaSecured ca = cClazz.getAnnotation(AlaSecured)
AlaSecured ma = method?.getAnnotation(AlaSecured)
AlaSecured sa = ma ?: ca
if (sa) {
if (method) {
actionAnnotation = method.getAnnotation(AlaSecured)
} else {
// if a method could not be found, look for a property (private field) on the class, for when actions are declared in this style:
// def action = { ... }
def field = cClazz.declaredFields.find { it.name == methodName }
// If a field could not be found, it may be a spring web flow action, so look for that (name suffixed with "Flow")...
if (!field) {
def target = "${methodName}Flow"
field = cClazz.declaredFields.find { it.name == target }
}

if (field) {
actionAnnotation = field.getAnnotation(AlaSecured)
}
}

// Action annotations trump class annotations
AlaSecured classAnnotation = cClazz.getAnnotation(AlaSecured)
AlaSecured effectiveAnnotation = actionAnnotation ?: classAnnotation

if (effectiveAnnotation) {

boolean error = false

if (sa.value()) {
if (sa.anyRole() && sa.notRoles()) {
if (effectiveAnnotation.value()) {
if (effectiveAnnotation.anyRole() && effectiveAnnotation.notRoles()) {
throw new IllegalArgumentException("Only one of anyRole and notRoles should be specified")
}

def roles = sa.value().toList()
def roles = effectiveAnnotation.value().toList()

if (sa.anyRole() && !securityPrimitives.isAnyGranted(roles)) {
if (effectiveAnnotation.anyRole() && !securityPrimitives.isAnyGranted(roles)) {
error = true
} else if (sa.notRoles() && !securityPrimitives.isNotGranted(roles)) {
} else if (effectiveAnnotation.notRoles() && !securityPrimitives.isNotGranted(roles)) {
error = true
} else if (!sa.anyRole() && !securityPrimitives.isAllGranted(roles)) {
} else if (!effectiveAnnotation.anyRole() && !securityPrimitives.isAllGranted(roles)) {
error = true
}
} else {
log.warn "No roles specified for @AlaSecured, controller ${controllerName}, action ${actionName}"
}

if (error) {
if (sa.message()) {
flash.errorMessage = sa.message()
if (effectiveAnnotation.message()) {
flash.errorMessage = effectiveAnnotation.message()
}

if (params.returnTo) {
redirect(url: params.returnTo)
} else if (sa.statusCode() != 0) {
render(status: sa.statusCode())
} else if (sa.redirectUri()) {
redirect(uri: sa.redirectUri())
} else if (effectiveAnnotation.statusCode() != 0) {
render(status: effectiveAnnotation.statusCode())
} else if (effectiveAnnotation.redirectUri()) {
redirect(uri: effectiveAnnotation.redirectUri())
} else {
def redirectController = sa.redirectController()
def redirectController = effectiveAnnotation.redirectController()
if (!redirectController) {
if (!ma) {
if (!actionAnnotation) {
log.warn('Redirecting to the current controller with a Controller level @AlaSecured, this is likely to result in a redirect loop!')
}
redirectController = controllerName
}
redirect(controller: redirectController, action: sa.redirectAction())
redirect(controller: redirectController, action: effectiveAnnotation.redirectAction())
}
return false
}
Expand Down
2 changes: 1 addition & 1 deletion src/java/au/org/ala/web/AlaSecured.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
* @author Simon Bear ([email protected])
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
Expand Down

0 comments on commit 28d4390

Please sign in to comment.