Skip to content

Commit 6b1cca8

Browse files
committed
fix ldap tests to not depend on external services
1 parent f7102d6 commit 6b1cca8

File tree

8 files changed

+231
-55
lines changed

8 files changed

+231
-55
lines changed

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ projectVersion=7.0.0-SNAPSHOT
2020
grailsVersion=7.0.0-SNAPSHOT
2121
javaVersion=17
2222

23+
unboundidLdapSdk=7.0.2
2324
apacheDsVersion=1.5.4
2425
asciidoctorGradlePluginVersion=4.0.4
2526
casClientCoreVersion=4.0.4

plugin-ldap/examples/custom-user-details-context-mapper/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ dependencies {
3737
implementation 'org.webjars:bootstrap:4.1.3'
3838
implementation 'org.webjars:jquery:3.3.1'
3939

40+
// to not depend on an external ldap server
41+
implementation "com.unboundid:unboundid-ldapsdk:$unboundidLdapSdk"
42+
4043
runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-grails'
4144
runtimeOnly 'com.h2database:h2'
4245
runtimeOnly 'com.zaxxer:HikariCP'

plugin-ldap/examples/custom-user-details-context-mapper/grails-app/conf/application.groovy

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ grails {
4747
authorityJoinClassName = 'com.test.UserRole'
4848
}
4949

50-
// http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
5150
ldap {
5251
context {
53-
managerDn = 'cn=read-only-admin,dc=example,dc=com'
54-
managerPassword = 'password'
55-
server = 'ldap://ldap.forumsys.com:389/' //'ldap://[ip]:[port]/'
52+
managerDn = 'cn=admin,dc=example,dc=com'
53+
managerPassword = 'secret'
54+
server = System.getProperty('grails.test.ldap.url')
5655
}
5756
authorities {
5857
ignorePartialResultException = true
@@ -61,7 +60,7 @@ grails {
6160
defaultRole = 'ROLE_USER'
6261
}
6362
search {
64-
base = 'dc=example,dc=com'
63+
base = 'ou=people,dc=example,dc=com'
6564
}
6665
}
6766
}

plugin-ldap/examples/custom-user-details-context-mapper/grails-app/init/com/test/Application.groovy

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,70 @@
1919

2020
package com.test
2121

22+
import com.unboundid.ldap.listener.InMemoryDirectoryServer
23+
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig
24+
import com.unboundid.ldap.listener.InMemoryListenerConfig
25+
import com.unboundid.ldap.sdk.Attribute
26+
import com.unboundid.ldap.sdk.Entry
2227
import grails.boot.GrailsApp
2328
import grails.boot.config.GrailsAutoConfiguration
2429

2530
import groovy.transform.CompileStatic
2631

2732
@CompileStatic
2833
class Application extends GrailsAutoConfiguration {
34+
static InMemoryDirectoryServer directoryServer
2935
static void main(String[] args) {
36+
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig('dc=example,dc=com')
37+
config.addAdditionalBindCredentials('cn=admin,dc=example,dc=com', 'secret')
38+
config.setListenerConfigs(
39+
InMemoryListenerConfig.createLDAPConfig(
40+
'default',
41+
null,
42+
0,
43+
null,
44+
false,
45+
false
46+
)
47+
)
48+
49+
directoryServer = new InMemoryDirectoryServer(config)
50+
Entry base = new Entry(
51+
"dc=example,dc=com",
52+
new Attribute("objectClass", "top", "domain"),
53+
new Attribute("dc", "example"))
54+
directoryServer.add(base)
55+
56+
Entry people = new Entry(
57+
"ou=people,dc=example,dc=com",
58+
new Attribute("objectClass", "top", "organizationalUnit"),
59+
new Attribute("ou", "people"));
60+
directoryServer.add(people)
61+
62+
Entry jane = new Entry(
63+
"uid=jane,ou=people,dc=example,dc=com",
64+
new Attribute("objectClass", "inetOrgPerson"),
65+
new Attribute("uid", "jane"),
66+
new Attribute("cn", "Jane Doe"),
67+
new Attribute("sn", "Doe"),
68+
new Attribute("mail", "jane@example.com"),
69+
new Attribute("telephoneNumber", "+1 555 111 2222"),
70+
new Attribute("userPassword", "password")
71+
)
72+
directoryServer.add(jane)
73+
74+
directoryServer.startListening()
75+
76+
System.setProperty('grails.test.ldap.url', "ldap://localhost:${directoryServer.getListenPort()}" as String)
77+
3078
GrailsApp.run(Application, args)
3179
}
80+
81+
@Override
82+
void onShutdown(Map<String, Object> event) {
83+
if(directoryServer) {
84+
directoryServer.close()
85+
directoryServer = null
86+
}
87+
}
3288
}

plugin-ldap/examples/custom-user-details-context-mapper/src/integration-test/groovy/com/test/CustomUserDetailsContextMapperFunctionalSpec.groovy

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
package com.test
2121

22+
import grails.plugin.geb.ContainerGebConfiguration
2223
import grails.testing.mixin.integration.Integration
2324
import pages.IndexPage
2425
import pages.SecureSuperuserPage
2526
import pages.SecureUserPage
2627

2728
@Integration
29+
@ContainerGebConfiguration(reporting = true)
2830
class CustomUserDetailsContextMapperFunctionalSpec extends AbstractSecurityFunctionalSpec {
2931

3032
void 'secured urls are not visible without auth'() {
@@ -49,13 +51,15 @@ class CustomUserDetailsContextMapperFunctionalSpec extends AbstractSecurityFunct
4951
assertContentContains 'Please Login'
5052

5153
when:
52-
login 'galileo', 'password'
54+
report("At Login")
55+
login 'jane', 'password'
5356

5457
then:
5558
at SecureUserPage
59+
report("At secured")
5660

5761
and:
58-
assertContentContains('galileo@ldap.forumsys.com')
62+
assertContentContains('jane@example.com')
5963

6064
when:
6165
logout()

plugin-ldap/examples/retrieve-group-roles/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ dependencies {
3636
implementation 'org.webjars:bootstrap:4.1.3'
3737
implementation 'org.webjars:jquery:3.3.1'
3838

39+
// to not depend on an external ldap server
40+
implementation "com.unboundid:unboundid-ldapsdk:$unboundidLdapSdk"
41+
3942
runtimeOnly 'com.bertramlabs.plugins:asset-pipeline-grails'
4043
runtimeOnly 'com.h2database:h2'
4144
runtimeOnly 'com.zaxxer:HikariCP'

plugin-ldap/examples/retrieve-group-roles/grails-app/conf/application.groovy

Lines changed: 47 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,53 +18,52 @@
1818
*/
1919

2020
grails {
21-
plugin {
22-
springsecurity {
23-
authority {
24-
className = 'com.test.Role'
25-
}
26-
controllerAnnotations.staticRules = [
27-
[pattern: '/', access: 'permitAll'],
28-
[pattern: '/logoff', access: 'permitAll'],
29-
[pattern: '/error', access: 'permitAll'],
30-
[pattern: '/index', access: 'permitAll'],
31-
[pattern: '/index.gsp', access: 'permitAll'],
32-
[pattern: '/shutdown', access: 'permitAll'],
33-
[pattern: '/assets/**', access: 'permitAll'],
34-
[pattern: '/secure/users', access: 'permitAll'],
35-
[pattern: '/**/js/**', access: 'permitAll'],
36-
[pattern: '/**/css/**', access: 'permitAll'],
37-
[pattern: '/**/images/**', access: 'permitAll'],
38-
[pattern: '/**/favicon.ico', access: 'permitAll']
39-
]
40-
password.algorithm = 'SHA-256'
41-
rememberMe {
42-
persistent = true
43-
persistentToken.domainClassName = 'com.test.PersistentLogin'
44-
}
45-
userLookup {
46-
userDomainClassName = 'com.test.User'
47-
authorityJoinClassName = 'com.test.UserRole'
48-
}
21+
plugin {
22+
springsecurity {
23+
authority {
24+
className = 'com.test.Role'
25+
}
26+
controllerAnnotations.staticRules = [
27+
[pattern: '/', access: 'permitAll'],
28+
[pattern: '/logoff', access: 'permitAll'],
29+
[pattern: '/error', access: 'permitAll'],
30+
[pattern: '/index', access: 'permitAll'],
31+
[pattern: '/index.gsp', access: 'permitAll'],
32+
[pattern: '/shutdown', access: 'permitAll'],
33+
[pattern: '/assets/**', access: 'permitAll'],
34+
[pattern: '/secure/users', access: 'permitAll'],
35+
[pattern: '/**/js/**', access: 'permitAll'],
36+
[pattern: '/**/css/**', access: 'permitAll'],
37+
[pattern: '/**/images/**', access: 'permitAll'],
38+
[pattern: '/**/favicon.ico', access: 'permitAll']
39+
]
40+
password.algorithm = 'SHA-256'
41+
rememberMe {
42+
persistent = true
43+
persistentToken.domainClassName = 'com.test.PersistentLogin'
44+
}
45+
userLookup {
46+
userDomainClassName = 'com.test.User'
47+
authorityJoinClassName = 'com.test.UserRole'
48+
}
4949

50-
// http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
51-
ldap {
52-
context {
53-
managerDn = 'cn=read-only-admin,dc=example,dc=com'
54-
managerPassword = 'password'
55-
server = 'ldap://ldap.forumsys.com:389/' //'ldap://[ip]:[port]/'
56-
}
57-
authorities {
58-
ignorePartialResultException = true
59-
retrieveGroupRoles = true
60-
groupSearchBase='ou=mathematicians,dc=example,dc=com'
61-
retrieveDatabaseRoles = true
62-
defaultRole = 'ROLE_USER'
63-
}
64-
search {
65-
base = 'dc=example,dc=com'
66-
}
67-
}
68-
}
69-
}
50+
ldap {
51+
context {
52+
managerDn = 'cn=admin,dc=example,dc=com'
53+
managerPassword = 'secret'
54+
server = System.getProperty('grails.test.ldap.url')
55+
}
56+
authorities {
57+
ignorePartialResultException = true
58+
retrieveGroupRoles = true
59+
groupSearchBase = 'ou=mathematicians,dc=example,dc=com'
60+
retrieveDatabaseRoles = true
61+
defaultRole = 'ROLE_USER'
62+
}
63+
search {
64+
base = 'dc=example,dc=com'
65+
}
66+
}
67+
}
68+
}
7069
}

plugin-ldap/examples/retrieve-group-roles/grails-app/init/com/test/Application.groovy

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,125 @@
1919

2020
package com.test
2121

22+
import com.unboundid.ldap.listener.InMemoryDirectoryServer
23+
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig
24+
import com.unboundid.ldap.listener.InMemoryListenerConfig
25+
import com.unboundid.ldap.sdk.Attribute
26+
import com.unboundid.ldap.sdk.Entry
2227
import grails.boot.GrailsApp
2328
import grails.boot.config.GrailsAutoConfiguration
2429

2530
import groovy.transform.CompileStatic
2631

2732
@CompileStatic
2833
class Application extends GrailsAutoConfiguration {
34+
static InMemoryDirectoryServer directoryServer
35+
static private Entry scientistsUnit
36+
2937
static void main(String[] args) {
38+
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig('dc=example,dc=com')
39+
config.addAdditionalBindCredentials('cn=admin,dc=example,dc=com', 'secret')
40+
config.setListenerConfigs(
41+
InMemoryListenerConfig.createLDAPConfig(
42+
'default',
43+
null,
44+
0,
45+
null,
46+
false,
47+
false
48+
)
49+
)
50+
51+
directoryServer = new InMemoryDirectoryServer(config)
52+
Entry base = new Entry(
53+
'dc=example,dc=com',
54+
new Attribute('objectClass', 'top', 'domain'),
55+
new Attribute('dc', 'example'))
56+
directoryServer.add(base)
57+
58+
Entry people = new Entry(
59+
'ou=people,dc=example,dc=com',
60+
new Attribute('objectClass', 'top', 'organizationalUnit'),
61+
new Attribute('ou', 'people'));
62+
directoryServer.add(people)
63+
64+
def mathematiciansUnit = new Entry('ou=mathematicians,dc=example,dc=com',
65+
new Attribute('objectClass', 'top', 'organizationalUnit'),
66+
new Attribute('ou', 'mathematicians'))
67+
directoryServer.add(mathematiciansUnit)
68+
69+
scientistsUnit = new Entry('ou=scientists,dc=example,dc=com',
70+
new Attribute('objectClass', 'top', 'organizationalUnit'),
71+
new Attribute('ou', 'scientists'))
72+
directoryServer.add(scientistsUnit)
73+
74+
Entry jane = new Entry(
75+
'uid=jane,ou=people,dc=example,dc=com',
76+
new Attribute('objectClass', 'inetOrgPerson'),
77+
new Attribute('uid', 'jane'),
78+
new Attribute('cn', 'Jane Doe'),
79+
new Attribute('sn', 'Doe'),
80+
new Attribute('mail', 'jane@example.com'),
81+
new Attribute('telephoneNumber', '+1 555 111 2222'),
82+
new Attribute('userPassword', 'password')
83+
)
84+
directoryServer.add(jane)
85+
86+
for (String uid : ['riemann', 'gauss', 'euler', 'euclid']) {
87+
directoryServer.add(new Entry(
88+
"uid=${uid},ou=mathematicians,dc=example,dc=com" as String,
89+
new Attribute('objectClass', 'inetOrgPerson'),
90+
new Attribute('uid', uid),
91+
new Attribute('cn', uid.substring(0, 1).toUpperCase() + uid.substring(1)),
92+
new Attribute('sn', uid.substring(0, 1).toUpperCase() + uid.substring(1)),
93+
new Attribute('userPassword', 'password')
94+
))
95+
}
96+
97+
Entry mathGroup = new Entry(
98+
'cn=mathematicians,ou=mathematicians,dc=example,dc=com',
99+
new Attribute('objectClass', 'top', 'groupOfUniqueNames'),
100+
new Attribute('cn', 'mathematicians'),
101+
new Attribute('uniqueMember',
102+
'uid=riemann,ou=mathematicians,dc=example,dc=com',
103+
'uid=gauss,ou=mathematicians,dc=example,dc=com',
104+
'uid=euler,ou=mathematicians,dc=example,dc=com',
105+
'uid=euclid,ou=mathematicians,dc=example,dc=com'))
106+
directoryServer.add(mathGroup)
107+
108+
for (String uid : ['einstein', 'newton', 'galieleo', 'tesla']) {
109+
directoryServer.add(new Entry(
110+
"uid=${uid},ou=scientists,dc=example,dc=com" as String,
111+
new Attribute('objectClass', 'inetOrgPerson'),
112+
new Attribute('uid', uid),
113+
new Attribute('cn', uid.substring(0, 1).toUpperCase() + uid.substring(1)),
114+
new Attribute('sn', uid.substring(0, 1).toUpperCase() + uid.substring(1)),
115+
new Attribute('userPassword', 'password')
116+
))
117+
}
118+
Entry scientistGroup = new Entry(
119+
'cn=scientists,ou=scientists,dc=example,dc=com',
120+
new Attribute('objectClass', 'top', 'groupOfUniqueNames'),
121+
new Attribute('cn', 'scientists'),
122+
new Attribute('uniqueMember',
123+
'uid=einstein,ou=scientists,dc=example,dc=com',
124+
'uid=newton,ou=scientists,dc=example,dc=com',
125+
'uid=galieleo,ou=scientists,dc=example,dc=com',
126+
'uid=tesla,ou=scientists,dc=example,dc=com'))
127+
directoryServer.add(scientistGroup)
128+
129+
directoryServer.startListening()
130+
131+
System.setProperty('grails.test.ldap.url', "ldap://localhost:${directoryServer.getListenPort()}" as String)
132+
30133
GrailsApp.run(Application, args)
31134
}
135+
136+
@Override
137+
void onShutdown(Map<String, Object> event) {
138+
if (directoryServer) {
139+
directoryServer.close()
140+
directoryServer = null
141+
}
142+
}
32143
}

0 commit comments

Comments
 (0)