Simplify project structure
- harmonize module and directory names - optimize Gradle settings - remove unused Grails sample Resolves: #1447
@@ -3,9 +3,9 @@
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files="[\\/]src[\\/]integration-test[\\/]java[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]docs[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]docs[\\/]" checks="InnerTypeLast"/>
|
||||
<suppress files="[\\/]samples[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]samples[\\/].+Application\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files="[\\/]spring-session-docs[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]spring-session-docs[\\/]" checks="InnerTypeLast"/>
|
||||
<suppress files="[\\/]spring-session-samples[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]spring-session-samples[\\/].+Application\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files="SessionRepositoryFilterTests\.java" checks="SpringLambda"/>
|
||||
</suppressions>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
grailsVersion=3.1.4
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
|
||||
// Added by the Spring Security Core plugin:
|
||||
grails.plugin.springsecurity.userLookup.userDomainClassName = 'grails3.redis.session.User'
|
||||
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'grails3.redis.session.UserRole'
|
||||
grails.plugin.springsecurity.authority.className = 'grails3.redis.session.Role'
|
||||
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
|
||||
[pattern: '/', access: ['permitAll']],
|
||||
[pattern: '/error', access: ['permitAll']],
|
||||
[pattern: '/index', access: ['permitAll']],
|
||||
[pattern: '/index.gsp', access: ['permitAll']],
|
||||
[pattern: '/shutdown', access: ['permitAll']],
|
||||
[pattern: '/assets/**', access: ['permitAll']],
|
||||
[pattern: '/**/js/**', access: ['permitAll']],
|
||||
[pattern: '/**/css/**', access: ['permitAll']],
|
||||
[pattern: '/**/images/**', access: ['permitAll']],
|
||||
[pattern: '/**/favicon.ico', access: ['permitAll']]
|
||||
]
|
||||
|
||||
grails.plugin.springsecurity.filterChain.chainMap = [
|
||||
[pattern: '/assets/**', filters: 'none'],
|
||||
[pattern: '/**/js/**', filters: 'none'],
|
||||
[pattern: '/**/css/**', filters: 'none'],
|
||||
[pattern: '/**/images/**', filters: 'none'],
|
||||
[pattern: '/**/favicon.ico', filters: 'none'],
|
||||
[pattern: '/**', filters: 'JOINED_FILTERS']
|
||||
]
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
---
|
||||
hibernate:
|
||||
cache:
|
||||
queries: false
|
||||
use_second_level_cache: true
|
||||
use_query_cache: false
|
||||
region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'
|
||||
|
||||
dataSource:
|
||||
pooled: true
|
||||
jmxExport: true
|
||||
driverClassName: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
|
||||
environments:
|
||||
development:
|
||||
dataSource:
|
||||
dbCreate: create-drop
|
||||
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
test:
|
||||
dataSource:
|
||||
dbCreate: update
|
||||
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
production:
|
||||
dataSource:
|
||||
dbCreate: update
|
||||
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
properties:
|
||||
jmxEnabled: true
|
||||
initialSize: 5
|
||||
maxActive: 50
|
||||
minIdle: 5
|
||||
maxIdle: 25
|
||||
maxWait: 10000
|
||||
maxAge: 600000
|
||||
timeBetweenEvictionRunsMillis: 5000
|
||||
minEvictableIdleTimeMillis: 60000
|
||||
validationQuery: SELECT 1
|
||||
validationQueryTimeout: 3
|
||||
validationInterval: 15000
|
||||
testOnBorrow: true
|
||||
testWhileIdle: true
|
||||
testOnReturn: false
|
||||
jdbcInterceptors: ConnectionState
|
||||
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
|
||||
|
||||
---
|
||||
---
|
||||
grails:
|
||||
profile: web
|
||||
codegen:
|
||||
defaultPackage: grails3.redis.session
|
||||
spring:
|
||||
transactionManagement:
|
||||
proxies: false
|
||||
info:
|
||||
app:
|
||||
name: '@info.app.name@'
|
||||
version: '@info.app.version@'
|
||||
grailsVersion: '@info.app.grailsVersion@'
|
||||
spring:
|
||||
|
||||
groovy:
|
||||
template:
|
||||
check-template-location: false
|
||||
|
||||
---
|
||||
grails:
|
||||
mime:
|
||||
disable:
|
||||
accept:
|
||||
header:
|
||||
userAgents:
|
||||
- Gecko
|
||||
- WebKit
|
||||
- Presto
|
||||
- Trident
|
||||
types:
|
||||
all: '*/*'
|
||||
atom: application/atom+xml
|
||||
css: text/css
|
||||
csv: text/csv
|
||||
form: application/x-www-form-urlencoded
|
||||
html:
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
js: text/javascript
|
||||
json:
|
||||
- application/json
|
||||
- text/json
|
||||
multipartForm: multipart/form-data
|
||||
pdf: application/pdf
|
||||
rss: application/rss+xml
|
||||
text: text/plain
|
||||
hal:
|
||||
- application/hal+json
|
||||
- application/hal+xml
|
||||
xml:
|
||||
- text/xml
|
||||
- application/xml
|
||||
urlmapping:
|
||||
cache:
|
||||
maxsize: 1000
|
||||
controllers:
|
||||
defaultScope: singleton
|
||||
converters:
|
||||
encoding: UTF-8
|
||||
views:
|
||||
default:
|
||||
codec: html
|
||||
gsp:
|
||||
encoding: UTF-8
|
||||
htmlcodec: xml
|
||||
codecs:
|
||||
expression: html
|
||||
scriptlets: html
|
||||
taglib: none
|
||||
staticparts: none
|
||||
endpoints:
|
||||
jmx:
|
||||
unique-names: true
|
||||
@@ -1,23 +0,0 @@
|
||||
import grails.util.BuildSettings
|
||||
import grails.util.Environment
|
||||
|
||||
// See https://logback.qos.ch/manual/groovy.html for details on configuration
|
||||
appender('STDOUT', ConsoleAppender) {
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
|
||||
root(ERROR, ['STDOUT'])
|
||||
|
||||
def targetDir = BuildSettings.TARGET_DIR
|
||||
if (Environment.isDevelopmentMode() && targetDir) {
|
||||
appender("FULL_STACKTRACE", FileAppender) {
|
||||
file = "${targetDir}/stacktrace.log"
|
||||
append = true
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
// Place your Spring DSL code here
|
||||
beans = {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.plugin.springsecurity.annotation.Secured
|
||||
|
||||
class TestController {
|
||||
@Secured('ROLE_ADMIN')
|
||||
def index() { } // Renders `test/index.gsp`
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
class UrlMappings {
|
||||
|
||||
static mappings = {
|
||||
"/$controller/$action?/$id?(.$format)?"{
|
||||
constraints {
|
||||
// apply constraints here
|
||||
}
|
||||
}
|
||||
|
||||
"/"(view:"/index")
|
||||
"500"(view:'/error')
|
||||
"404"(view:'/notFound')
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
@EqualsAndHashCode(includes='authority')
|
||||
@ToString(includes='authority', includeNames=true, includePackage=false)
|
||||
class Role implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
String authority
|
||||
|
||||
Role(String authority) {
|
||||
this()
|
||||
this.authority = authority
|
||||
}
|
||||
|
||||
static constraints = {
|
||||
authority blank: false, unique: true
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
cache true
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
@EqualsAndHashCode(includes='username')
|
||||
@ToString(includes='username', includeNames=true, includePackage=false)
|
||||
class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
transient springSecurityService
|
||||
|
||||
String username
|
||||
String password
|
||||
boolean enabled = true
|
||||
boolean accountExpired
|
||||
boolean accountLocked
|
||||
boolean passwordExpired
|
||||
|
||||
User(String username, String password) {
|
||||
this()
|
||||
this.username = username
|
||||
this.password = password
|
||||
}
|
||||
|
||||
Set<Role> getAuthorities() {
|
||||
UserRole.findAllByUser(this)*.role
|
||||
}
|
||||
|
||||
def beforeInsert() {
|
||||
encodePassword()
|
||||
}
|
||||
|
||||
def beforeUpdate() {
|
||||
if (isDirty('password')) {
|
||||
encodePassword()
|
||||
}
|
||||
}
|
||||
|
||||
protected void encodePassword() {
|
||||
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
|
||||
}
|
||||
|
||||
static transients = ['springSecurityService']
|
||||
|
||||
static constraints = {
|
||||
password blank: false, password: true
|
||||
username blank: false, unique: true
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
password column: '`password`'
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.gorm.DetachedCriteria
|
||||
import groovy.transform.ToString
|
||||
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder
|
||||
|
||||
@ToString(cache=true, includeNames=true, includePackage=false)
|
||||
class UserRole implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
User user
|
||||
Role role
|
||||
|
||||
UserRole(User u, Role r) {
|
||||
this()
|
||||
user = u
|
||||
role = r
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean equals(other) {
|
||||
if (!(other instanceof UserRole)) {
|
||||
return false
|
||||
}
|
||||
|
||||
other.user?.id == user?.id && other.role?.id == role?.id
|
||||
}
|
||||
|
||||
@Override
|
||||
int hashCode() {
|
||||
def builder = new HashCodeBuilder()
|
||||
if (user) builder.append(user.id)
|
||||
if (role) builder.append(role.id)
|
||||
builder.toHashCode()
|
||||
}
|
||||
|
||||
static UserRole get(long userId, long roleId) {
|
||||
criteriaFor(userId, roleId).get()
|
||||
}
|
||||
|
||||
static boolean exists(long userId, long roleId) {
|
||||
criteriaFor(userId, roleId).count()
|
||||
}
|
||||
|
||||
private static DetachedCriteria criteriaFor(long userId, long roleId) {
|
||||
UserRole.where {
|
||||
user == User.load(userId) &&
|
||||
role == Role.load(roleId)
|
||||
}
|
||||
}
|
||||
|
||||
static UserRole create(User user, Role role, boolean flush = false) {
|
||||
def instance = new UserRole(user: user, role: role)
|
||||
instance.save(flush: flush, insert: true)
|
||||
instance
|
||||
}
|
||||
|
||||
static boolean remove(User u, Role r, boolean flush = false) {
|
||||
if (u == null || r == null) return false
|
||||
|
||||
int rowCount = UserRole.where { user == u && role == r }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
|
||||
rowCount
|
||||
}
|
||||
|
||||
static void removeAll(User u, boolean flush = false) {
|
||||
if (u == null) return
|
||||
|
||||
UserRole.where { user == u }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
}
|
||||
|
||||
static void removeAll(Role r, boolean flush = false) {
|
||||
if (r == null) return
|
||||
|
||||
UserRole.where { role == r }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
}
|
||||
|
||||
static constraints = {
|
||||
role validator: { Role r, UserRole ur ->
|
||||
if (ur.user == null || ur.user.id == null) return
|
||||
boolean existing = false
|
||||
UserRole.withNewSession {
|
||||
existing = UserRole.exists(ur.user.id, r.id)
|
||||
}
|
||||
if (existing) {
|
||||
return 'userRole.exists'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
id composite: ['user', 'role']
|
||||
version false
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}]
|
||||
default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL
|
||||
default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number
|
||||
default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address
|
||||
default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}]
|
||||
default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
|
||||
default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}]
|
||||
default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}]
|
||||
default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}]
|
||||
default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}]
|
||||
default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation
|
||||
default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}]
|
||||
default.blank.message=Property [{0}] of class [{1}] cannot be blank
|
||||
default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}]
|
||||
default.null.message=Property [{0}] of class [{1}] cannot be null
|
||||
default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique
|
||||
|
||||
default.paginate.prev=Previous
|
||||
default.paginate.next=Next
|
||||
default.boolean.true=True
|
||||
default.boolean.false=False
|
||||
default.date.format=yyyy-MM-dd HH:mm:ss z
|
||||
default.number.format=0
|
||||
|
||||
default.created.message={0} {1} created
|
||||
default.updated.message={0} {1} updated
|
||||
default.deleted.message={0} {1} deleted
|
||||
default.not.deleted.message={0} {1} could not be deleted
|
||||
default.not.found.message={0} not found with id {1}
|
||||
default.optimistic.locking.failure=Another user has updated this {0} while you were editing
|
||||
|
||||
default.home.label=Home
|
||||
default.list.label={0} List
|
||||
default.add.label=Add {0}
|
||||
default.new.label=New {0}
|
||||
default.create.label=Create {0}
|
||||
default.show.label=Show {0}
|
||||
default.edit.label=Edit {0}
|
||||
|
||||
default.button.create.label=Create
|
||||
default.button.edit.label=Edit
|
||||
default.button.update.label=Update
|
||||
default.button.delete.label=Delete
|
||||
default.button.delete.confirm.message=Are you sure?
|
||||
|
||||
# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
|
||||
typeMismatch.java.net.URL=Property {0} must be a valid URL
|
||||
typeMismatch.java.net.URI=Property {0} must be a valid URI
|
||||
typeMismatch.java.util.Date=Property {0} must be a valid Date
|
||||
typeMismatch.java.lang.Double=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Integer=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Long=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Short=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigDecimal=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigInteger=Property {0} must be a valid number
|
||||
typeMismatch=Property {0} is type-mismatched
|
||||
@@ -1,24 +0,0 @@
|
||||
import grails3.redis.session.*
|
||||
|
||||
class BootStrap {
|
||||
|
||||
def init = { servletContext ->
|
||||
def adminRole = new Role('ROLE_ADMIN').save()
|
||||
def userRole = new Role('ROLE_USER').save()
|
||||
|
||||
def testUser = new User('user', 'password').save()
|
||||
|
||||
UserRole.create testUser, adminRole
|
||||
|
||||
UserRole.withSession {
|
||||
it.flush()
|
||||
it.clear()
|
||||
}
|
||||
|
||||
assert User.count() == 1
|
||||
assert Role.count() == 2
|
||||
assert UserRole.count() == 1
|
||||
}
|
||||
def destroy = {
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.boot.GrailsApp
|
||||
import grails.boot.config.GrailsAutoConfiguration
|
||||
|
||||
class Application extends GrailsAutoConfiguration {
|
||||
static void main(String[] args) {
|
||||
GrailsApp.run(Application, args)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title><g:if env="development">Grails Runtime Exception</g:if><g:else>Error</g:else></title>
|
||||
<meta name="layout" content="main">
|
||||
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
|
||||
</head>
|
||||
<body>
|
||||
<g:if env="development">
|
||||
<g:if test="${Throwable.isInstance(exception)}">
|
||||
<g:renderException exception="${exception}" />
|
||||
</g:if>
|
||||
<g:elseif test="${request.getAttribute('javax.servlet.error.exception')}">
|
||||
<g:renderException exception="${request.getAttribute('javax.servlet.error.exception')}" />
|
||||
</g:elseif>
|
||||
<g:else>
|
||||
<ul class="errors">
|
||||
<li>An error has occurred</li>
|
||||
<li>Exception: ${exception}</li>
|
||||
<li>Message: ${message}</li>
|
||||
<li>Path: ${path}</li>
|
||||
</ul>
|
||||
</g:else>
|
||||
</g:if>
|
||||
<g:else>
|
||||
<ul class="errors">
|
||||
<li>An error has occurred</li>
|
||||
</ul>
|
||||
</g:else>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,8 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Index</title>
|
||||
</head>
|
||||
<body>
|
||||
Left blank, goto <a href="/test">test</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Page Not Found</title>
|
||||
<meta name="layout" content="main">
|
||||
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="errors">
|
||||
<li>Error: Page Not Found (404)</li>
|
||||
<li>Path: ${request.forwardURI}</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Home Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="un">
|
||||
<sec:loggedInUserInfo field='username'/>
|
||||
</div>
|
||||
<div id="session">
|
||||
${session.id}
|
||||
</div>
|
||||
<form action="/logout" method="post">
|
||||
<input type="submit" value="Log Out"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,71 +0,0 @@
|
||||
buildscript {
|
||||
ext {
|
||||
grailsVersion = project.grailsVersion
|
||||
}
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
|
||||
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0"
|
||||
classpath "org.grails.plugins:hibernate4:5.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "eclipse"
|
||||
apply plugin: "idea"
|
||||
apply plugin: "war"
|
||||
apply plugin: "org.grails.grails-web"
|
||||
apply plugin: "org.grails.grails-gsp"
|
||||
apply plugin: "asset-pipeline"
|
||||
apply from: SAMPLE_GRADLE
|
||||
|
||||
ext {
|
||||
grailsVersion = project.grailsVersion
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.grails:grails-bom:$grailsVersion"
|
||||
}
|
||||
applyMavenExclusions false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.springframework.boot:spring-boot-starter-logging"
|
||||
compile "org.springframework.boot:spring-boot-autoconfigure"
|
||||
compile "org.grails:grails-core"
|
||||
compile "org.springframework.boot:spring-boot-starter-actuator"
|
||||
compile "org.springframework.boot:spring-boot-starter-tomcat"
|
||||
compile "org.grails:grails-dependencies"
|
||||
compile "org.grails:grails-web-boot"
|
||||
compile "org.grails.plugins:cache"
|
||||
compile "org.grails.plugins:scaffolding"
|
||||
compile "org.grails.plugins:hibernate4"
|
||||
compile "org.hibernate:hibernate-ehcache"
|
||||
console "org.grails:grails-console"
|
||||
profile "org.grails.profiles:web:3.1.4"
|
||||
runtime "org.grails.plugins:asset-pipeline"
|
||||
runtime "com.h2database:h2"
|
||||
testCompile "org.grails:grails-plugin-testing"
|
||||
testCompile "org.grails.plugins:geb"
|
||||
testCompile "org.assertj:assertj-core"
|
||||
testCompile "org.seleniumhq.selenium:selenium-htmlunit-driver"
|
||||
testCompile "net.sourceforge.htmlunit:htmlunit"
|
||||
|
||||
compile "org.springframework.boot:spring-boot-starter-redis"
|
||||
compile 'org.springframework.session:spring-session:1.1.1.RELEASE'
|
||||
|
||||
compile 'org.grails.plugins:spring-security-core:3.0.4'
|
||||
}
|
||||
|
||||
assets {
|
||||
minifyJs = true
|
||||
minifyCss = true
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample
|
||||
|
||||
import grails.test.mixin.integration.Integration
|
||||
import grails.transaction.Transactional
|
||||
import org.springframework.boot.test.IntegrationTest
|
||||
|
||||
import spock.lang.*
|
||||
import geb.spock.*
|
||||
|
||||
import sample.pages.HomePage
|
||||
import sample.pages.LoginPage
|
||||
import sample.pages.IndexPage
|
||||
import spock.lang.Stepwise
|
||||
import pages.*
|
||||
|
||||
/**
|
||||
* Functional tests for grails 3 and spring-session
|
||||
*
|
||||
* @author Eric Helgeson
|
||||
*/
|
||||
|
||||
@Stepwise
|
||||
@IntegrationTest("server.port:0")
|
||||
@Integration(applicationClass=grails3.redis.session.Application)
|
||||
class HomeSpec extends GebSpec {
|
||||
|
||||
def setup() {
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
}
|
||||
|
||||
void 'Anonymous page not redirected to login'() {
|
||||
when: 'The index page is visited'
|
||||
go '/'
|
||||
|
||||
then: 'Not redirected'
|
||||
at IndexPage
|
||||
}
|
||||
|
||||
void 'Unauthenticated user sent to log in page'() {
|
||||
when: 'The test page is visited'
|
||||
go '/test/index'
|
||||
if(title != 'Login') {
|
||||
println driver.pageSource
|
||||
}
|
||||
|
||||
then: 'The password form is correct'
|
||||
title == 'Login'
|
||||
$('#password')
|
||||
$('#username')
|
||||
}
|
||||
|
||||
void 'Log in views home page'() {
|
||||
when: 'log in successfully'
|
||||
to LoginPage
|
||||
login()
|
||||
|
||||
then: 'sent to original page'
|
||||
at HomePage
|
||||
|
||||
and: 'the username is displayed'
|
||||
username == 'user'
|
||||
|
||||
and: 'session id is not blank'
|
||||
session != ''
|
||||
|
||||
and: 'Spring Session Management is being used'
|
||||
driver.manage().cookies.find { it.name == 'SESSION' }
|
||||
|
||||
and: 'Standard Session is NOT being used'
|
||||
!driver.manage().cookies.find { it.name == 'JSESSIONID' }
|
||||
}
|
||||
|
||||
def 'Log out success'() {
|
||||
when:
|
||||
logout()
|
||||
|
||||
then:
|
||||
at IndexPage
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The home page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class HomePage extends Page {
|
||||
static url = '/test'
|
||||
static at = { assert driver.title == 'Home Page'; true}
|
||||
static content = {
|
||||
username { $('#un').text() }
|
||||
session { $('#session').text() }
|
||||
logout(to:LoginPage) { $('input[type=submit]').click() }
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The Index page
|
||||
*
|
||||
* @author Eric Helgeson
|
||||
*/
|
||||
class IndexPage extends Page {
|
||||
static url = '/'
|
||||
static at = { assert driver.title == 'Index'; true}
|
||||
static content = { }
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The Login Page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class LoginPage extends Page {
|
||||
static url = '/login'
|
||||
static at = { assert driver.title == 'Login'; true}
|
||||
static content = {
|
||||
form { $('form') }
|
||||
submit { $('input[type=submit]') }
|
||||
login(required:false) { user='user', pass='password' ->
|
||||
form.username = user
|
||||
form.password = pass
|
||||
submit.click()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- <logger name="org.springframework.security" level="DEBUG"/> -->
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -1,28 +1,16 @@
|
||||
rootProject.name = 'spring-session-build'
|
||||
|
||||
FileTree buildFiles = fileTree(rootDir) {
|
||||
include '**/*.gradle'
|
||||
exclude 'build', '**/gradle', 'settings.gradle', 'buildSrc', '/build.gradle', '.*', 'out'
|
||||
exclude '**/grails3'
|
||||
gradle.startParameter.projectProperties.get('excludeProjects')?.split(',')?.each { excludeProject ->
|
||||
exclude excludeProject
|
||||
}
|
||||
include 'spring-session-core'
|
||||
include 'spring-session-data-redis'
|
||||
include 'spring-session-docs'
|
||||
include 'spring-session-hazelcast'
|
||||
include 'spring-session-jdbc'
|
||||
|
||||
file('spring-session-samples').eachDirMatch(~/spring-session-sample-.*/) { dir ->
|
||||
include dir.name
|
||||
project(":$dir.name").projectDir = dir
|
||||
}
|
||||
|
||||
String rootDirPath = rootDir.absolutePath + File.separator
|
||||
buildFiles.each { buildFile ->
|
||||
if (buildFile.name == 'build.gradle') {
|
||||
String buildFilePath = buildFile.parentFile.absolutePath
|
||||
String projectPath = buildFilePath.replace(rootDirPath, '').replace(File.separator, ':')
|
||||
include projectPath
|
||||
}
|
||||
else {
|
||||
String projectName = buildFile.name.replace('.gradle', '')
|
||||
String projectPath = ':' + projectName
|
||||
include projectPath
|
||||
def project = findProject("${projectPath}")
|
||||
project.name = projectName
|
||||
project.projectDir = buildFile.parentFile
|
||||
project.buildFileName = buildFile.name
|
||||
}
|
||||
rootProject.children.each { project ->
|
||||
project.buildFileName = "${project.name}.gradle"
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 30 MiB After Width: | Height: | Size: 30 MiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |