GFSv0.2.2 Released!!
After the success of the last release, Cubika Labs is glad to announce that the new version of GFS in now available. GFSv0.2.2 includes new functionalities and some fixes.
Among important features you will find the spring-security integration, this was the feature most requested by GFS users.
Although other functionalities that we consider vital for a complete integration are still missing, this is an initial approach and the basis to continue working in the new versions.
Some included improvements in this version are:
- spring-security Integration (we use stark-security)
- Tabs group (Thank you so much Nicolas Domina)
- actions into datagrid
If you want report a bug / improvement or vote our Backlog features’ you are welcome to do it in our Jira
See our Confluence for technical documentation
See our SVN if you want to try the code
See new Screencast
In order to explain how this features work, we are going to write some code for a dummy todo-list app
- Grails 1.1 or major
- GFSv0.2.2
- Flex 3.0.0 or major
FLEX_HOME and GRAILS_HOME must be defined as environment variable!!
Domain Model
1 – Create Project and Install Plugin
gfs@gfs $ grails create-app todo-list
gfs@todo-list $ grails install-plugin \
[path-plugin]/grails-flex-scaffold-0.2.2.zip
#or
gfs@todo-list $ grails install-plugin flex-scaffold
2 – Generate User, Role and Task
#Generets User and Role for spring-security integration
gfs@todo-list $ grails stark-security-install-full
gfs@todo-list $ grails create-domain-class task
3 – Edit User
class User implements UserDetails {
String name
String lastName
String username
String password
String email
static transients = [
'authorities',
'accountNonExpired',
'enabled',
'credentialsNonExpired',
'accountNonLocked'
]
static hasMany = [ roles: Role ]
//Generates TAB "ADM User" that contains User's tab
static groupName = "ADM User"
// Need to eagerly fetch role relations, because they'll be asked for later
// by Spring Security when the hibernate session is no longer available
static mapping = {
roles lazy:false
}
static constraints = {
name(blank:false)
lastName(blank:false)
email(email:true)
username(blank:false)
//Generate 2 textinput to validate password.
password(widget:"password")
roles(inPlace:false)
}
GrantedAuthority[] getAuthorities() {
return roles as GrantedAuthority[]
}
boolean isAccountNonLocked() {
return true
}
def setAccountNonLocked(boolean nonLocked) {}
boolean isCredentialsNonExpired() {
return true
}
def setCredentialsNonExpired(boolean nonExpired) {}
boolean isAccountNonExpired() {
return true
}
def setAccountNonExpired(boolean acctNonExpired) {}
boolean isEnabled() {
return true
}
def setEnabled(boolean enabled) {}
}
4 – Edit Role
class Role implements GrantedAuthority {
String description
String authority
static final ANONYMOUS = 'IS_AUTHENTICATED_ANONYMOUSLY'
// Add your roles here so you can reference them, for instance:
// static final ADMIN_USER = 'ROLE_ADMIN_USER'
// This list holds all roles, convenient when you're declaring controller methods
// that should be available to everybody (see AccessController for instance). When
// you add roles to your system, make sure you add them to this list as well.
static final ALL_ROLES = [ ANONYMOUS ]
//Generates TAB "ADM User" that contains Role's tab
static groupName = "ADM User"
int compareTo(Object o) {
if (o instanceof Role) {
return this.authority.compareTo(o.authority)
}
return 0
}
String toString() {
return authority
}
}
5 – Edit Task
class Task {
String name
String description
Long priority
//multiselection:true - A Checkbox appears in all rows on the first datagrid column
//actions:["postpone"] - show an action button (label=postpone) in each row so you can
//add bussines logic into postpone method at TaskService
//You could declare as many actions buttons as you need eg: actions:["postpone","complete"]
static action = [datagrid:[multiselection:true,actions:["postpone"]]]
static constraints = {
name(blank:false)
priority(widget:"hslider", range:1..10)
description(minSize:5, maxSize:255)
}
}
6 – Add to Config.groovy
gfs.security = true
7 – Edit StarkSecurityConfig.groovy and change:
authorizations = [
'/': Role.ALL_ROLES,
'/js/**': Role.ALL_ROLES,
'/css/**': Role.ALL_ROLES,
'/images/**': Role.ALL_ROLES,
'/j_spring_security_logout': Role.ALL_ROLES
]
to:
authorizations = [
'/**': Role.ALL_ROLES,
'/js/**': Role.ALL_ROLES,
'/css/**': Role.ALL_ROLES,
'/images/**': Role.ALL_ROLES,
'/j_spring_security_logout': Role.ALL_ROLES
]
8 – Edit BootStrap.groovy as below
import org.codehaus.groovy.grails.plugins.starksecurity.PasswordEncoder
class BootStrap {
def init = { servletContext ->
if (!User.findByUsername("admin")) {
def superUser = new User(username: 'admin',
password: PasswordEncoder.encode('admin', 'SHA-256', true),name:"admin",lastName:"admin",
email:"admin@admin.com")
def role = new Role(authority:"ROLE_USER",description:"Role users")
superUser.addToRoles(role)
superUser.save()
}
}
def destroy = {
}
}
9 – Generate Flex Artifacts
gfs@todo-list $ grails generate-all-flex role
gfs@todo-list $ grails generate-all-flex user
gfs@todo-list $ grails generate-all-flex task
10 – Compile Flex and run app
gfs@todo-list $ grails flex-tasks
gfs@todo-list $ grails run-app
11 – Access to application
On the login dialog enter the username and password already setted into BootStrap.groovy (admin/admin for this example).
Tips
For this version, we are not taking care of roles regarding functionality.
If you used FlexBuilder you must set-define=GFS::security,false to true (“-define=GFS::security,true”) in the Flex Compiler options (flex arguments), this property will show login dialog if is setted to true. By default it’s false and in command-line compiling (grails flex-tasks) this property will be retrieved from Config.groovy (gfs.security = [true|false]).
