Browse Source

Updates for 3.0.x autorepo support

Rob Winch 13 năm trước cách đây
mục cha
commit
4f993d95b5
100 tập tin đã thay đổi với 1801 bổ sung738 xóa
  1. 11 8
      .gitignore
  2. 1 1
      acl/pom.xml
  3. 11 10
      acl/template.mf
  4. 2 2
      aspects/pom.xml
  5. 16 0
      aspects/template.mf
  6. 34 165
      build.gradle
  7. 27 4
      buildSrc/build.gradle
  8. 0 75
      buildSrc/src/main/groovy/TarUpload.groovy
  9. 108 0
      buildSrc/src/main/groovy/aspectj/AspectJPlugin.groovy
  10. 150 0
      buildSrc/src/main/groovy/bundlor/BundlorPlugin.groovy
  11. 42 7
      buildSrc/src/main/groovy/docbook/DocbookPlugin.groovy
  12. 114 0
      buildSrc/src/main/groovy/emma/EmmaPlugin.groovy
  13. 26 0
      buildSrc/src/main/groovy/gae/GaePlugin.groovy
  14. 1 0
      buildSrc/src/main/resources/META-INF/gradle-plugins/aspectj.properties
  15. 1 0
      buildSrc/src/main/resources/META-INF/gradle-plugins/bundlor.properties
  16. 1 0
      buildSrc/src/main/resources/META-INF/gradle-plugins/emma.properties
  17. 1 0
      buildSrc/src/main/resources/META-INF/gradle-plugins/gae.properties
  18. 1 1
      cas/cas.gradle
  19. 1 1
      cas/pom.xml
  20. 12 12
      cas/template.mf
  21. 17 2
      config/config.gradle
  22. 1 1
      config/pom.xml
  23. 0 0
      config/src/integration-test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java
  24. 27 4
      config/src/integration-test/java/org/springframework/security/config/ldap/LdapServerBeanDefinitionParserTests.java
  25. 27 17
      config/src/integration-test/java/org/springframework/security/config/ldap/LdapUserServiceBeanDefinitionParserTests.java
  26. 17 15
      config/template.mf
  27. 5 1
      core/core.gradle
  28. 1 1
      core/pom.xml
  29. 14 14
      core/template.mf
  30. 143 0
      docs/docs.gradle
  31. 0 17
      docs/faq/faq.gradle
  32. 0 19
      docs/manual/manual.gradle
  33. 1 1
      docs/manual/src/docbook/springsecurity.xml
  34. 1 0
      gradle.properties
  35. 0 47
      gradle/aspectj.gradle
  36. 0 31
      gradle/bundlor.gradle
  37. 63 0
      gradle/ide-integration.gradle
  38. 112 15
      gradle/javaprojects.gradle
  39. 51 0
      gradle/maven-deployment.gradle
  40. BIN
      gradle/wrapper/gradle-wrapper.jar
  41. 6 0
      gradle/wrapper/gradle-wrapper.properties
  42. 164 0
      gradlew
  43. 90 0
      gradlew.bat
  44. 17 0
      itest/context/itest-context.gradle
  45. 1 1
      itest/context/pom.xml
  46. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/HttpNamespaceWithMultipleInterceptorsTests.java
  47. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/HttpPathParameterStrippingTests.java
  48. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/MultiAnnotationTests.java
  49. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/SEC933ApplicationContextTests.java
  50. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/SEC936ApplicationContextTests.java
  51. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/StubUserRepository.java
  52. 0 0
      itest/context/src/integration-test/java/org/springframework/security/integration/python/PythonInterpreterBasedSecurityTests.java
  53. 7 11
      itest/context/src/integration-test/java/org/springframework/security/performance/FilterChainPerformanceTests.java
  54. 0 0
      itest/context/src/integration-test/java/org/springframework/security/performance/ProtectPointcutPerformanceTests.java
  55. 0 0
      itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml
  56. 0 0
      itest/context/src/integration-test/resources/http-extra-fsi-app-context.xml
  57. 0 0
      itest/context/src/integration-test/resources/http-path-param-stripping-app-context.xml
  58. 0 0
      itest/context/src/integration-test/resources/log4j.properties
  59. 0 0
      itest/context/src/integration-test/resources/multi-sec-annotation-app-context.xml
  60. 0 0
      itest/context/src/integration-test/resources/protect-pointcut-performance-app-context.xml
  61. 0 0
      itest/context/src/integration-test/resources/python-method-access-app-context.xml
  62. 0 0
      itest/context/src/integration-test/resources/sec-933-app-context.xml
  63. 0 0
      itest/context/src/integration-test/resources/sec-936-app-context.xml
  64. 0 0
      itest/context/src/integration-test/resources/someMethod.py
  65. 1 1
      itest/misc/pom.xml
  66. 2 2
      itest/pom.xml
  67. 3 2
      itest/web/itest-web.gradle
  68. 1 1
      itest/web/pom.xml
  69. 26 9
      ldap/ldap.gradle
  70. 1 1
      ldap/pom.xml
  71. 49 0
      ldap/src/integration-test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java
  72. 29 48
      ldap/src/integration-test/java/org/springframework/security/ldap/ApacheDSServerIntegrationTests.java
  73. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/DefaultSpringSecurityContextSourceTests.java
  74. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java
  75. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java
  76. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/authentication/PasswordComparisonAuthenticatorTests.java
  77. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java
  78. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/ppolicy/OpenLDAPIntegrationTestSuite.java
  79. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java
  80. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/server/ApacheDSContainerTests.java
  81. 161 0
      ldap/src/integration-test/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulatorTests.java
  82. 0 0
      ldap/src/integration-test/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManagerTests.java
  83. 18 0
      ldap/src/integration-test/resources/logback-test.xml
  84. 0 0
      ldap/src/integration-test/resources/test-server.ldif
  85. 14 14
      ldap/template.mf
  86. 9 3
      openid/openid.gradle
  87. 1 1
      openid/pom.xml
  88. 7 7
      openid/template.mf
  89. 1 0
      parent/parent.gradle
  90. 1 1
      parent/pom.xml
  91. 18 10
      readme.txt
  92. 0 80
      samples/aspectj/pom.xml
  93. 8 49
      samples/cas/Readme.txt
  94. 0 9
      samples/cas/cas.gradle
  95. 0 16
      samples/cas/pom.xml
  96. 125 0
      samples/cas/sample/cassample.gradle
  97. 1 1
      samples/cas/sample/pom.xml
  98. 0 0
      samples/cas/sample/src/main/java/Dummy.java
  99. 0 0
      samples/cas/sample/src/main/webapp/WEB-INF/applicationContext-security.xml
  100. 0 0
      samples/cas/sample/src/main/webapp/WEB-INF/classes/log4j.properties

+ 11 - 8
.gitignore

@@ -1,18 +1,21 @@
 target/
+*/src/*/java/META-INF
+*/src/META-INF/
+*/src/*/java/META-INF/
 .classpath
+.springBeans
 .project
+.DS_Store
 .settings/
-*/src/*/java/META-INF
-bin/
-build/
+.idea/
 out/
+bin/
 intellij/
-*.ipr
-*.iws
+build/
 *.log
-*.log.1
-.DS_Store
+*.log.*
 *.iml
+*.ipr
+*.iws
 .gradle/
-gradle.properties
 atlassian-ide-plugin.xml

+ 1 - 1
acl/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <artifactId>spring-security-parent</artifactId>
         <groupId>org.springframework.security</groupId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.springframework.security</groupId>

+ 11 - 10
acl/template.mf

@@ -9,14 +9,15 @@ Ignored-Existing-Headers:
  Import-Package,
  Export-Package
 Import-Template: 
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.springframework.security.core.*;version="[${version}, 3.1.0)",
- org.springframework.security.access.*;version="[${version}, 3.1.0)",
- org.springframework.security.util.*;version="[${version}, 3.1.0)",
- org.springframework.context.*;version="[${spring.version}, 3.1.0)";resolution:=optional, 
- org.springframework.dao.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.jdbc.core.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.transaction.support.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.util.*;version="[${spring.version}, 3.1.0)";resolution:=optional, 
- net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional,
+ org.aopalliance.*;version="${aopAllianceRange}",
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.access.*;version="${secRange}",
+ org.springframework.security.util.*;version="${secRange}",
+ org.springframework.context.*;version="${springRange}";resolution:=optional,
+ org.springframework.dao.*;version="${springRange}";resolution:=optional,
+ org.springframework.jdbc.core.*;version="${springRange}";resolution:=optional,
+ org.springframework.transaction.support.*;version="${springRange}";resolution:=optional,
+ org.springframework.util.*;version="${springRange}";resolution:=optional,
+ net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
  javax.sql.*;version="0";resolution:=optional

+ 2 - 2
aspects/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <packaging>jar</packaging>
     <artifactId>spring-security-aspects</artifactId>
@@ -18,7 +18,7 @@
         <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-core</artifactId>
-            <version>3.0.8.CI-SNAPSHOT</version>
+            <version>@pomVersion@</version>
         </dependency>
     </dependencies>
     <build>

+ 16 - 0
aspects/template.mf

@@ -0,0 +1,16 @@
+Implementation-Title: org.springframework.security.aspects
+Implementation-Version: ${version}
+Bundle-SymbolicName: org.springframework.security.aspects
+Bundle-Name: Spring Security Aspects
+Bundle-Vendor: SpringSource
+Bundle-ManifestVersion: 2
+Bundle-Version: ${version}
+Ignored-Existing-Headers:
+ Import-Package,
+ Export-Package
+Import-Template:
+ org.aspectj.*;version="${aspectjRange}";resolution:=optional,
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.access.intercept.aspectj;version="${secRange}",
+ org.springframework.beans.factory;version="${springRange}"

+ 34 - 165
build.gradle

@@ -1,120 +1,58 @@
 apply plugin: 'base'
 
+description = 'Spring Security'
 allprojects {
-    version = '3.0.8.CI-SNAPSHOT'
-    releaseBuild = version.endsWith('RELEASE')
-    snapshotBuild = version.endsWith('SNAPSHOT')
+    ext.releaseBuild = version.endsWith('RELEASE')
+    ext.snapshotBuild = version.endsWith('SNAPSHOT')
 
     group = 'org.springframework.security'
 
     repositories {
-        mavenRepo name:'Local', urls: "file://" + System.properties['user.home'] + "/.m2/repository"
         mavenCentral()
-        mavenRepo name: 'SpringSource Milestone Repo', urls: 'http://repository.springsource.com/maven/bundles/milestone'
-        mavenRepo name: 'SpringSource Maven Snapshot Repo', urls: 'http://maven.springframework.org/snapshot/'
-        mavenRepo name: 'SpringSource Enterprise Release', urls: 'http://repository.springsource.com/maven/bundles/release'
-        mavenRepo name: 'SpringSource Enterprise External', urls: 'http://repository.springsource.com/maven/bundles/external'
     }
 }
 
+// Set up different subproject lists for individual configuration
+ext.javaProjects = subprojects.findAll { project -> project.name != 'docs' && project.name != 'faq' && project.name != 'manual' }
+ext.sampleProjects = subprojects.findAll { project -> project.name.startsWith('spring-security-samples') }
+ext.itestProjects = subprojects.findAll { project -> project.name.startsWith('itest') }
+ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
+ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj')]
 configure(javaProjects) {
     apply from: "$rootDir/gradle/javaprojects.gradle"
-    apply from: "$rootDir/gradle/maven.gradle"
 }
 
 configure(coreModuleProjects) {
-    apply from: "$rootDir/gradle/bundlor.gradle"
     // Gives better names in structure101 jar diagram
-    sourceSets.main.classesDir = new File(buildDir, "classes/" + project.name.substring("spring-security".length() + 1))
+    sourceSets.main.output.classesDir = new File(buildDir, "classes/" + project.name.substring("spring-security".length() + 1))
+    apply plugin: 'bundlor'
+    bundlor.expansions = bundlorProperties
+    apply from: "$rootDir/gradle/maven-deployment.gradle"
+    apply plugin: 'emma'
 }
 
-configure (aspectjProjects) {
-    apply from: "$rootDir/gradle/aspectj.gradle"
-}
-
-configurations {
-    antlibs
-}
-
-dependencies {
-    antlibs "org.springframework.build:org.springframework.build.aws.ant:3.0.3.RELEASE",
-            "net.java.dev.jets3t:jets3t:0.6.1"
-}
-
-task apidocs(type: Javadoc) {
-    destinationDir = new File(buildDir, 'apidocs')
-    title = "Spring Security $version API"
-    optionsFile = file("$buildDir/tmp/javadoc.options")
-
-    source coreModuleProjects.collect {project ->
-        project.sourceSets.main.allJava
-    }
-
-    classpath = files(coreModuleProjects.collect {project ->
-        project.sourceSets.main.compileClasspath
-    })
-}
-
-task docSiteLogin(type: Login) {
-    if (project.hasProperty('sshHost')) {
-        host = project.property('sshHost')
-    }
+task coreBuild {
+    dependsOn coreModuleProjects*.tasks*.matching { task -> task.name == 'build' }
 }
 
-// Define remoteSiteDir and sshHost in gradle.properties
-def remoteDocsDir = null
-
-if (hasProperty('remoteSiteDir')) {
-    remoteDocsDir="$remoteSiteDir/docs/3.0.x"
-}
-
-task uploadApidocs(type: TarUpload) {
-    dependsOn apidocs
-    classifier = 'apidocs'
-    remoteDir = remoteDocsDir
-    login = docSiteLogin
-
-    into('apidocs') {
-        from apidocs.destinationDir
-    }
-}
-
-def docsDir = new File(project(':manual').buildDir, 'docs')
-
-task uploadDoc(type: TarUpload) {
-    dependsOn ':manual:doc'
-    classifier = 'doc'
-    remoteDir = remoteDocsDir
-    login = docSiteLogin
-
-    into('reference') {
-        from docsDir
-    }
+configure (aspectjProjects) {
+    apply plugin: 'aspectj'
 }
 
-task uploadFaq(type: TarUpload) {
-    dependsOn ':faq:docbookHtmlSingle'
-    classifier = 'faq'
-    if (project.hasProperty('remoteSiteDir')) {
-        remoteDir = project.property('remoteSiteDir')
-    }
-    login = docSiteLogin
-
-    def faqDir = new File(project(':faq').buildDir, 'docs')
-
-    into('faq') {
-        from faqDir
-    }
-}
+// Task for creating the distro zip
 
 task dist(type: Zip) {
+    dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') }
+    classifier = 'dist'
+    evaluationDependsOn(':docs')
     def zipRootDir = "${project.name}-$version"
     into(zipRootDir) {
-        into('docs/apidocs') {
-            from apidocs.destinationDir
+        from(rootDir) {
+            include '*.txt'
         }
-        into('docs/reference') {
-            from docsDir
+        into('docs') {
+            with(project(':docs').apiSpec)
+            with(project(':docs:manual').spec)
         }
         into('dist') {
             from coreModuleProjects.collect {project -> project.libsDir }
@@ -124,83 +62,14 @@ task dist(type: Zip) {
     }
 }
 
-dist {
-    dependsOn apidocs, ':manual:doc', subprojects.collect { "$it.path:assemble" }
-    doLast {
-        ant.checksum(file: archivePath, algorithm: 'SHA1', fileext: '.sha1')
-    }
-}
-
-task uploadDist(type: UploadDist) {
-    archiveFile = dist.archivePath
-    shaFile = "${dist.archivePath}.sha1" as File
-    archiveName = dist.archiveName
-    classpath = configurations.antlibs
-}
-
-def getJavaProjects() {
-    subprojects.findAll {project -> project.name != 'faq' && project.name != 'manual' }
-}
-
-def getSampleProjects() {
-    subprojects.findAll {project -> project.name.startsWith('spring-security-samples') }
-}
-
-def getItestProjects() {
-    subprojects.findAll {project -> project.name.startsWith('itest') }
-}
-
-def getCoreModuleProjects() {
-    javaProjects - sampleProjects - itestProjects - aspectjProjects
-}
-
-def getAspectjProjects() {
-    subprojects.findAll {project -> project.name == 'spring-security-aspects' || project.name == 'spring-security-samples-aspectj'}
+artifacts {
+    archives dist
+    archives project(':docs').docsZip
+    archives project(':docs').schemaZip
 }
 
-class UploadDist extends DefaultTask {
-    @InputFile
-    File shaFile
-
-    @InputFile
-    File archiveFile
-
-    @Input
-    String archiveName
-
-    @InputFiles
-    def classpath
-
-    @TaskAction
-    def upload() {
-        def accessKey = project.s3AccessKey
-        def secretKey = project.s3SecretAccessKey
-        def version = project.version
+apply from: "$rootDir/gradle/ide-integration.gradle"
 
-        project.ant {
-            taskdef(resource: 'org/springframework/build/aws/ant/antlib.xml', classpath: classpath.asPath)
-            s3(accessKey: accessKey, secretKey: secretKey) {
-                upload(bucketName: 'dist.springframework.org', file: archiveFile,
-                        toFile: releaseType() + "/SEC/${archiveName}", publicRead: 'true') {
-                    metadata(name: 'project.name', value: 'Spring Security')
-                    metadata(name: 'release.type', value: releaseType())
-                    metadata(name: 'bundle.version', value: version)
-                    metadata(name: 'package.file.name', value: archiveName)
-                }
-                upload(bucketName: 'dist.springframework.org', file: shaFile,
-                        toFile: releaseType() + "/SEC/${archiveName}.sha1", publicRead: 'true')
-            }
-        }
-    }
-
-    def releaseType() {
-        if (project.releaseBuild) {
-            'release'
-        } else if (project.snapshotBuild) {
-            'snapshot'
-        } else {
-            'milestone'
-        }
-    }
+task wrapper(type: Wrapper) {
+    gradleVersion = '1.1'
 }
-

+ 27 - 4
buildSrc/build.gradle

@@ -1,11 +1,18 @@
 apply plugin: 'groovy'
 
 repositories {
-    mavenRepo name:'localRepo', urls: "file://" + System.properties['user.home'] + "/.m2/repository"
     mavenCentral()
-    mavenRepo name:'Shibboleth Repo', urls:'http://shibboleth.internet2.edu/downloads/maven2'
+    maven {
+        name = 'SpringSource Enterprise Release'
+        url = 'http://repository.springsource.com/maven/bundles/release'
+    }
+    maven {
+        name = 'SpringSource Enterprise External'
+        url = 'http://repository.springsource.com/maven/bundles/external'
+    }
 }
 
+// Docbook Plugin
 dependencies {
     def fopDeps = [ 'org.apache.xmlgraphics:fop:0.95-1@jar',
                     'org.apache.xmlgraphics:xmlgraphics-commons:1.3',
@@ -17,15 +24,31 @@ dependencies {
                     'org.apache.avalon.framework:avalon-framework-api:4.3.1']
     groovy localGroovy()
     compile gradleApi(),
-            'org.apache.xerces:resolver:2.9.1',
+            'xml-resolver:xml-resolver:1.2',
+            'xerces:xercesImpl:2.9.1',
             'saxon:saxon:6.5.3',
-            'org.apache.xerces:xercesImpl:2.9.1',
+            'net.java.dev.jets3t:jets3t:0.6.1',
             fopDeps
 
     runtime 'net.sf.xslthl:xslthl:2.0.1',
             'net.sf.docbook:docbook-xsl:1.75.2:ns-resources@zip'
 }
 
+// GAE
+dependencies {
+    compile 'com.google.appengine:appengine-tools-sdk:1.4.2'
+}
+
+dependencies{
+    compile "emma:emma:2.0.5312"
+}
+
+// Bundlor
+dependencies {
+    compile 'com.springsource.bundlor:com.springsource.bundlor:1.0.0.RELEASE',
+            'com.springsource.bundlor:com.springsource.bundlor.blint:1.0.0.RELEASE'
+}
+
 task ide(type: Copy)  {
     from configurations.runtime
     into 'ide'

+ 0 - 75
buildSrc/src/main/groovy/TarUpload.groovy

@@ -1,75 +0,0 @@
-import org.gradle.api.DefaultTask;
-import org.gradle.api.tasks.*;
-import org.gradle.api.tasks.bundling.Tar;
-import org.gradle.api.tasks.bundling.Compression;
-
-/**
- * Extends the Tar task, uploading the created archive to a remote directory, unpacking and deleting it.
- * Requires Ant ssh (jsch) support.
- */
-class TarUpload extends Tar {
-    @Input
-    String remoteDir
-    Login login
-    @Input
-    String host
-    
-    TarUpload() {
-        compression = Compression.BZIP2
-        if (project.configurations.findByName('antjsch') == null) {
-            project.configurations.add('antjsch')
-            project.dependencies {
-                antjsch 'org.apache.ant:ant-jsch:1.8.1'
-            }
-            def classpath = project.configurations.antjsch.asPath
-            project.ant {
-                taskdef(name: 'scp', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp', classpath: classpath)
-                taskdef(name: 'sshexec', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', classpath: classpath)
-            }
-        }
-    }
-    
-    @TaskAction
-    void copy() {
-        super.copy();
-        upload();
-    }
-    
-    def upload() {
-        String username = login.username
-        String password = login.password
-        String host = login.host
-        project.ant {
-            scp(file: archivePath, todir: "$username@$host:$remoteDir", password: password)
-            sshexec(host: host, username: username, password: password, command: "cd $remoteDir && tar -xjf $archiveName")
-            sshexec(host: host, username: username, password: password, command: "rm $remoteDir/$archiveName")
-        }
-    }
-
-    void setLogin(Login login) {
-        dependsOn(login)
-        this.login = login
-        this.host = login.host
-    }
-}
-
-/**
- * Stores login information for a remote host.
- */
-class Login extends DefaultTask {
-    @Input
-    String host
-    String username
-    String password
-
-    @TaskAction
-    login() {
-        def console = System.console()
-        if (console) {
-            username = console.readLine("\nPlease enter the ssh username for host '$host': ")
-            password = new String(console.readPassword("Please enter the ssh password for '$host': "))
-        } else {
-            logger.error "Unable to access System.console()."
-        }
-    }
-}

+ 108 - 0
buildSrc/src/main/groovy/aspectj/AspectJPlugin.groovy

@@ -0,0 +1,108 @@
+package aspectj
+
+import org.gradle.api.Project
+import org.gradle.api.Plugin
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.logging.LogLevel
+import org.gradle.api.file.FileCollection
+import org.gradle.api.tasks.SourceSet
+import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+
+import org.gradle.plugins.ide.eclipse.GenerateEclipseProject
+import org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath
+import org.gradle.plugins.ide.eclipse.EclipsePlugin
+import org.gradle.plugins.ide.eclipse.model.BuildCommand
+import org.gradle.plugins.ide.eclipse.model.ProjectDependency
+
+/**
+ *
+ * @author Luke Taylor
+ */
+class AspectJPlugin implements Plugin<Project> {
+
+    void apply(Project project) {
+        if (!project.hasProperty('aspectjVersion')) {
+            throw new GradleException("You must set the property 'aspectjVersion' before applying the aspectj plugin")
+        }
+
+        if (project.configurations.findByName('ajtools') == null) {
+            project.configurations.add('ajtools')
+            project.dependencies {
+                ajtools "org.aspectj:aspectjtools:${project.aspectjVersion}"
+                compile "org.aspectj:aspectjrt:${project.aspectjVersion}"
+            }
+        }
+
+        if (project.configurations.findByName('aspectpath') == null) {
+            project.configurations.add('aspectpath')
+        }
+
+        project.tasks.add(name: 'compileJava', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
+            dependsOn project.processResources
+            sourceSet = project.sourceSets.main
+            inputs.files(sourceSet.java.srcDirs)
+            outputs.dir(sourceSet.output.classesDir)
+            aspectPath = project.configurations.aspectpath
+        }
+
+        project.tasks.add(name: 'compileTestJava', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
+            dependsOn project.processTestResources, project.compileJava, project.jar
+            sourceSet = project.sourceSets.test
+            inputs.files(sourceSet.java.srcDirs)
+            outputs.dir(sourceSet.output.classesDir)
+            aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
+        }
+
+        project.tasks.withType(GenerateEclipseProject) {
+            project.eclipse.project.file.whenMerged { p ->
+                p.natures.add(0, 'org.eclipse.ajdt.ui.ajnature')
+                p.buildCommands = [new BuildCommand('org.eclipse.ajdt.core.ajbuilder')]
+            }
+        }
+
+        project.tasks.withType(GenerateEclipseClasspath) {
+            project.eclipse.classpath.file.whenMerged { classpath ->
+                def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
+                    def projectPath = entry.path.replaceAll('/',':')
+println projectPath
+                    project.rootProject.allprojects.find{ p-> 
+                        if(p.plugins.findPlugin(EclipsePlugin)) {
+                             println "    checking " + p.eclipse.project.name
+                             return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
+                        }
+                        false
+                    }
+                }
+                entries.each { entry->
+                    entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
+                }
+            }
+        }
+    }
+}
+
+class Ajc extends DefaultTask {
+    SourceSet sourceSet
+    FileCollection aspectPath
+
+    Ajc() {
+        logging.captureStandardOutput(LogLevel.INFO)
+    }
+
+    @TaskAction
+    def compile() {
+        logger.info("Running ajc ...")
+        ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
+        ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.output.classesDir.absolutePath,
+                source: project.convention.plugins.java.sourceCompatibility,
+                target: project.convention.plugins.java.targetCompatibility,
+                aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
+            sourceroots {
+                sourceSet.java.srcDirs.each {
+                    pathelement(location: it.absolutePath)
+                }
+            }
+        }
+    }
+}

+ 150 - 0
buildSrc/src/main/groovy/bundlor/BundlorPlugin.groovy

@@ -0,0 +1,150 @@
+package bundlor
+
+import com.springsource.bundlor.ClassPath
+import com.springsource.bundlor.ManifestGenerator
+import com.springsource.bundlor.ManifestWriter
+import com.springsource.bundlor.blint.ManifestValidator
+import com.springsource.bundlor.blint.support.DefaultManifestValidatorContributorsFactory
+import com.springsource.bundlor.blint.support.StandardManifestValidator
+import com.springsource.bundlor.support.DefaultManifestGeneratorContributorsFactory
+import com.springsource.bundlor.support.StandardManifestGenerator
+import com.springsource.bundlor.support.classpath.FileSystemClassPath
+import com.springsource.bundlor.support.manifestwriter.FileSystemManifestWriter
+import com.springsource.bundlor.support.properties.EmptyPropertiesSource
+import com.springsource.bundlor.support.properties.FileSystemPropertiesSource
+import com.springsource.bundlor.support.properties.PropertiesPropertiesSource
+import com.springsource.bundlor.support.properties.PropertiesSource
+import com.springsource.bundlor.util.BundleManifestUtils
+import com.springsource.util.parser.manifest.ManifestContents
+import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.file.FileCollection
+import org.gradle.api.logging.LogLevel
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+
+/**
+ * @author Luke Taylor
+ */
+class BundlorPlugin implements Plugin<Project> {
+    void apply(Project project) {
+        Task bundlor = project.tasks.add('bundlor', Bundlor.class)
+        bundlor.setDescription('Generates OSGi manifest using bundlor tool')
+        bundlor.dependsOn(project.classes)
+        project.jar.dependsOn bundlor
+    }
+}
+
+public class Bundlor extends DefaultTask {
+    @InputFile
+    @Optional
+    File manifestTemplate
+
+    @OutputDirectory
+    File bundlorDir = new File("${project.buildDir}/bundlor")
+
+    @OutputFile
+    File manifest = project.file("${bundlorDir}/META-INF/MANIFEST.MF")
+
+    @Input
+    Map<String,String> expansions = [:]
+
+    @InputFile
+    @Optional
+    File osgiProfile
+
+    @InputFiles
+    @Optional
+    FileCollection inputPaths
+
+    @Input
+    boolean failOnWarnings = false
+
+    Bundlor() {
+        manifestTemplate = new File(project.projectDir, 'template.mf')
+
+        if (!manifestTemplate.exists()) {
+            logger.info("No bundlor template for project " + project.name)
+            manifestTemplate = null
+        }
+
+        inputPaths = project.files(project.sourceSets.main.output.classesDir)
+
+        if (manifestTemplate != null) {
+            project.jar.manifest.from manifest
+            project.jar.inputs.files manifest
+        }
+    }
+
+    @TaskAction
+    void createManifest() {
+        if (manifestTemplate == null) {
+            return;
+        }
+
+        logging.captureStandardOutput(LogLevel.INFO)
+
+        project.mkdir(bundlorDir)
+
+        //String inputPath = project.sourceSets.main.classesDir
+
+        List<ClassPath> inputClassPath = [] as List;
+
+        ManifestWriter manifestWriter = new FileSystemManifestWriter(project.file(bundlorDir.absolutePath));
+        ManifestContents mfTemplate = BundleManifestUtils.getManifest(manifestTemplate);
+
+        inputPaths.each {f ->
+            inputClassPath.add(new FileSystemClassPath(f))
+        }
+
+        // Must be a better way of doing this...
+        Properties p = new Properties()
+        expansions.each {entry ->
+            p.setProperty(entry.key, entry.value as String)
+        }
+
+        PropertiesSource expansionProps = new PropertiesPropertiesSource(p)
+        PropertiesSource osgiProfileProps = osgiProfile == null ? new EmptyPropertiesSource() :
+            new FileSystemPropertiesSource(osgiProfile);
+
+        ManifestGenerator manifestGenerator = new StandardManifestGenerator(
+                DefaultManifestGeneratorContributorsFactory.create(expansionProps, osgiProfileProps));
+
+        ManifestContents mf = manifestGenerator.generate(mfTemplate, inputClassPath.toArray(new ClassPath[inputClassPath.size()]));
+
+        try {
+            manifestWriter.write(mf);
+        } finally {
+            manifestWriter.close();
+        }
+
+        ManifestValidator manifestValidator = new StandardManifestValidator(DefaultManifestValidatorContributorsFactory.create());
+
+        List<String> warnings = manifestValidator.validate(mf);
+
+        if (warnings.isEmpty()) {
+            return
+        }
+
+        logger.warn("Bundlor Warnings:");
+        for (String warning : warnings) {
+            logger.warn("    " + warning);
+        }
+
+        if (failOnWarnings) {
+            throw new GradleException("Bundlor returned warnings. Please fix manifest template at " + manifestTemplate.absolutePath + " and try again.")
+        }
+    }
+
+    def inputPath(FileCollection paths) {
+        inputPaths = project.files(inputPaths, paths)
+    }
+}

+ 42 - 7
buildSrc/src/main/groovy/docbook/DocbookPlugin.groovy

@@ -48,6 +48,9 @@ class DocbookPlugin implements Plugin<Project> {
         Task docbookFoPdf = project.tasks.add("docbookFoPdf", DocbookFoPdf.class);
         docbookFoPdf.setDescription('Generates PDF output');
         docbookFoPdf.extension = 'fo'
+
+        Task docbook = project.tasks.add("docbook", DefaultTask.class);
+        docbook.dependsOn (docbookHtml, docbookHtmlSingle, docbookFoPdf)
     }
 }
 
@@ -69,6 +72,8 @@ public class Docbook extends DefaultTask {
 
     String admonGraphicsPath;
 
+    String imgSrcPath;
+
     @InputDirectory
     File sourceDirectory = new File(project.getProjectDir(), "src/docbook");
 
@@ -87,7 +92,7 @@ public class Docbook extends DefaultTask {
         factory.setXIncludeAware(XIncludeAware);
         docsDir.mkdirs();
 
-        File srcFile = new File(sourceDirectory, sourceFileName);
+        File srcFile = new File(filterDocbookSources(sourceDirectory), sourceFileName);
         String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + suffix + '.' + extension;
 
         File outputFile = new File(getDocsDir(), outputFilename);
@@ -112,11 +117,15 @@ public class Docbook extends DefaultTask {
             }
 
             transformer.setParameter("highlight.xslthl.config", new File(highlightingDir, "xslthl-config.xml").toURI().toURL());
+        }
 
-            if (admonGraphicsPath != null) {
-                transformer.setParameter("admon.graphics", "1");
-                transformer.setParameter("admon.graphics.path", admonGraphicsPath);
-            }
+        if (admonGraphicsPath != null) {
+            transformer.setParameter("admon.graphics", "1");
+            transformer.setParameter("admon.graphics.path", admonGraphicsPath);
+        }
+
+        if (imgSrcPath != null) {
+            transformer.setParameter("img.src.path", imgSrcPath);
         }
 
         preTransform(transformer, srcFile, outputFile);
@@ -126,6 +135,32 @@ public class Docbook extends DefaultTask {
         postTransform(outputFile);
     }
 
+    /**
+    * @param sourceDir directory of unfiltered sources
+    * @return directory of filtered sources
+    * @author Chris Beams
+    */
+   private File filterDocbookSources(File sourceDir) {
+       def docbookWorkDir = new File("${project.buildDir}/reference-work")
+
+       docbookWorkDir.mkdirs()
+
+       // copy everything but springsecurity.xml
+       project.copy {
+           into(docbookWorkDir)
+           from(sourceDir) { exclude '**/springsecurity.xml' }
+       }
+       // copy index.xml and expand ${...} variables along the way
+       // e.g.: ${version} needs to be replaced in the header
+       project.copy {
+           into(docbookWorkDir)
+           from(sourceDir) { include '**/springsecurity.xml' }
+           expand(version: "${project.version}")
+       }
+
+       return docbookWorkDir
+   }
+
     private void extractHighlightFiles(File toDir) {
         URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
         URL[] urls = cl.getURLs();
@@ -254,9 +289,9 @@ class DocbookFoPdf extends Docbook {
             }
         }
 
-        if (!foFile.delete()) {
+/*        if (!foFile.delete()) {
             logger.warn("Failed to delete 'fo' file " + foFile);
-        }
+        }*/
     }
 
     private File getPdfOutputFile(File foFile) {

+ 114 - 0
buildSrc/src/main/groovy/emma/EmmaPlugin.groovy

@@ -0,0 +1,114 @@
+package emma;
+
+import org.gradle.api.*
+import org.gradle.api.tasks.testing.Test
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.Input
+import com.vladium.emma.instr.InstrProcessor
+import com.vladium.emma.report.ReportProcessor
+import org.gradle.api.tasks.InputFiles
+import com.vladium.util.XProperties;
+
+/**
+ *
+ * @author Luke Taylor
+ */
+class EmmaPlugin implements Plugin<Project> {
+
+    void apply(Project project) {
+        Project rootProject = project.rootProject
+        def emmaMetaDataFile = "${rootProject.buildDir}/emma/emma.em"
+        def emmaCoverageFile = "${rootProject.buildDir}/emma/emma.ec"
+
+        if (project.configurations.findByName('emma_rt') == null) {
+            project.configurations.add('emma_rt')
+            project.dependencies {
+                emma_rt 'emma:emma:2.0.5312'
+            }
+        }
+
+        project.task('emmaInstrument') {
+            dependsOn project.classes
+
+            doFirst {
+                InstrProcessor processor = InstrProcessor.create ();
+                String[] classesDirPath = [project.sourceSets.main.output.classesDir.absolutePath]
+
+                processor.setInstrPath(classesDirPath, false);
+                processor.setOutMode(InstrProcessor.OutMode.OUT_MODE_COPY);
+                processor.setInstrOutDir("${project.buildDir}/emma/classes");
+                processor.setMetaOutFile(emmaMetaDataFile);
+                processor.setMetaOutMerge(true);
+                //processor.setInclExclFilter (null);
+                processor.run();
+            }
+        }
+
+        // Modify test tasks in the project to generate coverage data
+        project.afterEvaluate {
+            if (project.hasProperty('coverage') && ['on','true'].contains(project.properties.coverage)) {
+                project.tasks.withType(Test.class).each { task ->
+                    task.dependsOn project.emmaInstrument
+                    task.configure() {
+                        jvmArgs '-Dsec.log.level=DEBUG', "-Demma.coverage.out.file=$emmaCoverageFile"
+                        jvmArgs '-Demma.verbosity.level=quiet'
+                    }
+                    task.doFirst {
+                        classpath = project.files("${project.buildDir}/emma/classes") + project.configurations.emma_rt + classpath
+                    }
+                }
+            }
+        }
+
+        List<Task> reportTasks = rootProject.getTasksByName('coverageReport', false) as List;
+        CoverageReport task;
+
+        if (reportTasks.isEmpty()) {
+            task = rootProject.tasks.add('coverageReport', CoverageReport.class);
+            task.dataPath = [emmaMetaDataFile, emmaCoverageFile];
+        } else {
+            task = reportTasks[0];
+        }
+
+        task.modules.add(project);
+    }
+}
+
+class CoverageReport extends DefaultTask {
+    @Input
+    List<Project> modules = [];
+
+    @Input
+    String[] dataPath;
+
+    @TaskAction
+    void generateReport() {
+        def buildDir = project.rootProject.buildDir
+
+        if (!buildDir.exists()) {
+            throw new GradleException("No coverage data. Run gradle with -Pcoverage=on if using coverageReport");
+        }
+
+        ReportProcessor processor = ReportProcessor.create ();
+        processor.setDataPath(dataPath)
+
+        def srcPath = []
+        modules.each {module->
+            module.sourceSets.main.java.srcDirs.each {
+                srcPath.add(it.absolutePath)
+            }
+        }
+
+        processor.setSourcePath(srcPath as String[]);
+
+
+        def types = ['txt', 'html']
+        processor.setReportTypes(types as String[]);
+        XProperties properties = new XProperties();
+        properties.setProperty('report.html.out.file', "$buildDir/emma/coverage.html");
+        properties.setProperty('report.txt.out.file', "$buildDir/emma/coverage.txt");
+        processor.setPropertyOverrides(properties)
+
+        processor.run()
+    }
+}

+ 26 - 0
buildSrc/src/main/groovy/gae/GaePlugin.groovy

@@ -0,0 +1,26 @@
+package gae;
+
+import com.google.appengine.tools.admin.AppCfg
+import org.gradle.api.*;
+
+class GaePlugin implements Plugin<Project> {
+    public void apply(Project project) {
+        if (!project.hasProperty('appEngineSdkRoot')) {
+            println "'appEngineSdkRoot' must be set in gradle.properties"
+        } else {
+            System.setProperty('appengine.sdk.root', project.property('appEngineSdkRoot'))
+        }
+
+        File explodedWar = new File(project.buildDir, "gae-exploded")
+
+        project.task('gaeDeploy') << {
+            AppCfg.main("update", explodedWar.toString())
+        }
+
+        project.gaeDeploy.dependsOn project.war
+
+        project.war.doLast {
+            ant.unzip(src: project.war.archivePath, dest: explodedWar)
+        }
+    }
+}

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/aspectj.properties

@@ -0,0 +1 @@
+implementation-class=aspectj.AspectJPlugin

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/bundlor.properties

@@ -0,0 +1 @@
+implementation-class=bundlor.BundlorPlugin

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/emma.properties

@@ -0,0 +1 @@
+implementation-class=emma.EmmaPlugin

+ 1 - 0
buildSrc/src/main/resources/META-INF/gradle-plugins/gae.properties

@@ -0,0 +1 @@
+implementation-class=gae.GaePlugin

+ 1 - 1
cas/cas.gradle

@@ -10,4 +10,4 @@ dependencies {
             "net.sf.ehcache:ehcache:$ehcacheVersion"
 
     provided 'javax.servlet:servlet-api:2.5'
-}            
+}

+ 1 - 1
cas/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-cas-client</artifactId>
     <name>Spring Security - CAS support</name>

+ 12 - 12
cas/template.mf

@@ -5,18 +5,18 @@ Bundle-Name: Spring Security CAS
 Bundle-Vendor: SpringSource
 Bundle-Version: ${version}
 Bundle-ManifestVersion: 2
-Ignored-Existing-Headers: 
+Ignored-Existing-Headers:
  Import-Package,
  Export-Package
-Import-Template: 
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.jasig.cas.client.*;version="[3.1.1,3.2)",
- org.springframework.security.core.*;version="[${version}, 3.1.0)",
- org.springframework.security.authentication.*;version="[${version}, 3.1.0)",
- org.springframework.security.web.*;version="[${version}, 3.1.0)", 
- org.springframework.beans.factory;version="[${spring.version}, 3.1.0)",
- org.springframework.context.*;version="[${spring.version}, 3.1.0)",
- org.springframework.dao;version="[${spring.version}, 3.1.0)",
- org.springframework.util;version="[${spring.version}, 3.1.0)", 
- net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional, 
+Import-Template:
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.jasig.cas.client.*;version="${casRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.authentication.*;version="${secRange}",
+ org.springframework.security.web.*;version="${secRange}",
+ org.springframework.beans.factory;version="${springRange}",
+ org.springframework.context.*;version="${springRange}",
+ org.springframework.dao;version="${springRange}",
+ org.springframework.util;version="${springRange}",
+ net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
  javax.servlet.*;version="0"

+ 17 - 2
config/config.gradle

@@ -17,8 +17,23 @@ dependencies {
 
     testCompile project(':spring-security-ldap'),
                 project(':spring-security-openid'),
-                files(this.project(':spring-security-core').sourceSets.test.classesDir),
+                project(':spring-security-core').sourceSets.test.output,
                 'javax.annotation:jsr250-api:1.0',
                 "org.springframework.ldap:spring-ldap-core:$springLdapVersion",
-                "org.springframework:spring-jdbc:$springVersion"
+                "org.springframework:spring-expression:$springVersion",
+                "org.springframework:spring-jdbc:$springVersion",
+                "org.springframework:spring-tx:$springVersion",
+                'org.spockframework:spock-core:0.6-groovy-1.8',
+                "org.slf4j:jcl-over-slf4j:$slf4jVersion"
+    testCompile('org.openid4java:openid4java-nodeps:0.9.6') {
+       exclude group: 'com.google.code.guice', module: 'guice'
+    }
+
+
+    testRuntime "hsqldb:hsqldb:$hsqlVersion",
+                "cglib:cglib-nodep:2.2"
+}
+
+integrationTest {
+    systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
 }

+ 1 - 1
config/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <packaging>jar</packaging>
     <artifactId>spring-security-config</artifactId>

+ 0 - 0
config/src/test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java → config/src/integration-test/java/org/springframework/security/config/ldap/LdapProviderBeanDefinitionParserTests.java


+ 27 - 4
config/src/test/java/org/springframework/security/config/ldap/LdapServerBeanDefinitionParserTests.java → config/src/integration-test/java/org/springframework/security/config/ldap/LdapServerBeanDefinitionParserTests.java

@@ -1,14 +1,31 @@
+/*
+ * Copyright 2002-2012 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
+ *
+ * http://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 org.springframework.security.config.ldap;
 
+import static org.junit.Assert.*;
+
 import org.junit.After;
 import org.junit.Test;
 import org.springframework.ldap.core.LdapTemplate;
 import org.springframework.security.config.BeanIds;
 import org.springframework.security.config.util.InMemoryXmlApplicationContext;
 import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
+import org.springframework.security.ldap.server.ApacheDSContainer;
+import org.springframework.test.util.ReflectionTestUtils;
 
 /**
  * @author Luke Taylor
+ * @author Rob Winch
  */
 public class LdapServerBeanDefinitionParserTests {
     InMemoryXmlApplicationContext appCtx;
@@ -23,7 +40,7 @@ public class LdapServerBeanDefinitionParserTests {
 
     @Test
     public void embeddedServerCreationContainsExpectedContextSourceAndData() {
-        appCtx = new InMemoryXmlApplicationContext("<ldap-server />");
+        appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif'/>");
 
         DefaultSpringSecurityContextSource contextSource = (DefaultSpringSecurityContextSource) appCtx.getBean(BeanIds.CONTEXT_SOURCE);
 
@@ -35,8 +52,8 @@ public class LdapServerBeanDefinitionParserTests {
     @Test
     public void useOfUrlAttributeCreatesCorrectContextSource() {
         // Create second "server" with a url pointing at embedded one
-        appCtx = new InMemoryXmlApplicationContext("<ldap-server port='33388'/>" +
-                "<ldap-server id='blah' url='ldap://127.0.0.1:33388/dc=springframework,dc=org' />");
+        appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif' port='33388'/>" +
+                "<ldap-server ldif='classpath:test-server.ldif' id='blah' url='ldap://127.0.0.1:33388/dc=springframework,dc=org' />");
 
         // Check the default context source is still there.
         appCtx.getBean(BeanIds.CONTEXT_SOURCE);
@@ -58,6 +75,12 @@ public class LdapServerBeanDefinitionParserTests {
         template.lookup("uid=pg,ou=gorillas");
     }
 
+    @Test
+    public void defaultLdifFileIsSuccessful() {
+        appCtx = new InMemoryXmlApplicationContext(
+                "<ldap-server/>");
+        ApacheDSContainer dsContainer = appCtx.getBean(ApacheDSContainer.class);
 
-
+        assertEquals("classpath*:*.ldif", ReflectionTestUtils.getField(dsContainer, "ldifResources"));
+    }
 }

+ 27 - 17
config/src/test/java/org/springframework/security/config/ldap/LdapUserServiceBeanDefinitionParserTests.java → config/src/integration-test/java/org/springframework/security/config/ldap/LdapUserServiceBeanDefinitionParserTests.java

@@ -1,17 +1,24 @@
+/*
+ * Copyright 2002-2012 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
+ *
+ * http://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 org.springframework.security.config.ldap;
 
 import static org.junit.Assert.*;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.*;
 import static org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser.*;
 
-import java.util.Set;
-
-import org.junit.After;
-import org.junit.Test;
-import org.springframework.security.config.ldap.LdapUserServiceBeanDefinitionParser;
+import org.junit.*;
 import org.springframework.security.config.util.InMemoryXmlApplicationContext;
 import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
@@ -24,8 +31,11 @@ import org.springframework.security.ldap.userdetails.Person;
 import org.springframework.security.ldap.userdetails.PersonContextMapper;
 import org.w3c.dom.Element;
 
+import java.util.*;
+
 /**
  * @author Luke Taylor
+ * @author Rob Winch
  */
 public class LdapUserServiceBeanDefinitionParserTests {
     private InMemoryXmlApplicationContext appCtx;
@@ -50,12 +60,12 @@ public class LdapUserServiceBeanDefinitionParserTests {
 
     @Test
     public void minimalConfigurationIsParsedOk() throws Exception {
-        setContext("<ldap-user-service user-search-filter='(uid={0})' /><ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org' />");
+        setContext("<ldap-user-service user-search-filter='(uid={0})' /><ldap-server ldif='classpath:test-server.ldif' url='ldap://127.0.0.1:343/dc=springframework,dc=org' />");
     }
 
     @Test
     public void userServiceReturnsExpectedData() throws Exception {
-        setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-search-filter='member={0}' /><ldap-server />");
+        setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
 
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails ben = uds.loadUserByUsername("ben");
@@ -70,7 +80,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
         setContext("<ldap-user-service id='ldapUDS' " +
                 "       user-search-base='ou=otherpeople' " +
                 "       user-search-filter='(cn={0})' " +
-                "       group-search-filter='member={0}' /><ldap-server />");
+                "       group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
 
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails joe = uds.loadUserByUsername("Joe Smeth");
@@ -86,7 +96,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
                 "     group-search-filter='member={0}' role-prefix='PREFIX_'/>" +
                 "<ldap-user-service id='ldapUDSNoPrefix' " +
                 "     user-search-filter='(uid={0})' " +
-                "     group-search-filter='member={0}' role-prefix='none'/><ldap-server />");
+                "     group-search-filter='member={0}' role-prefix='none'/><ldap-server ldif='classpath:test-server.ldif'/>");
 
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails ben = uds.loadUserByUsername("ben");
@@ -101,21 +111,21 @@ public class LdapUserServiceBeanDefinitionParserTests {
 
     @Test
     public void differentGroupRoleAttributeWorksAsExpected() throws Exception {
-        setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server />");
+        setContext("<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' group-role-attribute='ou' group-search-filter='member={0}' /><ldap-server ldif='classpath:test-server.ldif'/>");
 
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails ben = uds.loadUserByUsername("ben");
 
         Set<String> authorities = AuthorityUtils.authorityListToSet(ben.getAuthorities());
         assertEquals(3, authorities.size());
-        assertTrue(authorities.contains(new GrantedAuthorityImpl("ROLE_DEVELOPER")));
+        assertTrue(authorities.contains("ROLE_DEVELOPER"));
 
     }
 
     @Test
     public void isSupportedByAuthenticationProviderElement() {
         setContext(
-                "<ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org'/>" +
+                "<ldap-server url='ldap://127.0.0.1:343/dc=springframework,dc=org' ldif='classpath:test-server.ldif'/>" +
                 "<authentication-manager>" +
                 "  <authentication-provider>" +
                 "    <ldap-user-service user-search-filter='(uid={0})' />" +
@@ -126,7 +136,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
     @Test
     public void personContextMapperIsSupported() {
         setContext(
-                "<ldap-server />" +
+                "<ldap-server ldif='classpath:test-server.ldif'/>" +
                 "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='person'/>");
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails ben = uds.loadUserByUsername("ben");
@@ -136,7 +146,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
     @Test
     public void inetOrgContextMapperIsSupported() {
         setContext(
-                "<ldap-server id='someServer'/>" +
+                "<ldap-server id='someServer' ldif='classpath:test-server.ldif'/>" +
                 "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='inetOrgPerson'/>");
         UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
         UserDetails ben = uds.loadUserByUsername("ben");
@@ -146,7 +156,7 @@ public class LdapUserServiceBeanDefinitionParserTests {
     @Test
     public void externalContextMapperIsSupported() {
         setContext(
-                "<ldap-server id='someServer'/>" +
+                "<ldap-server id='someServer' ldif='classpath:test-server.ldif'/>" +
                 "<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-context-mapper-ref='mapper'/>" +
                 "<b:bean id='mapper' class='"+ InetOrgPersonContextMapper.class.getName() +"'/>");
 

+ 17 - 15
config/template.mf

@@ -5,22 +5,24 @@ Bundle-Name: Spring Security Namespace Configuration
 Bundle-Vendor: SpringSource
 Bundle-Version: ${version}
 Bundle-ManifestVersion: 2
-Ignored-Existing-Headers: 
+Ignored-Existing-Headers:
  Import-Package,
  Export-Package
-Import-Template: 
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.aspectj.*;version="[1.6.0, 1.7.0)";resolution:=optional, 
- org.springframework.security.access.*;version="[${version}, 3.1.0)",
- org.springframework.security.authentication.*;version="[${version}, 3.1.0)",
- org.springframework.security.core.*;version="[${version}, 3.1.0)", 
- org.springframework.security.util;version="[${version}, 3.1.0)",
- org.springframework.security.web.*;version="[${version}, 3.1.0)";resolution:=optional,
- org.springframework.aop.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.beans.*;version="[${spring.version}, 3.1.0)",
- org.springframework.context.*;version="[${spring.version}, 3.1.0)",
- org.springframework.core.*;version="[${spring.version}, 3.1.0)",
- org.springframework.util.*;version="[${spring.version}, 3.1.0)",
- javax.servlet;version="0";resolution:=optional,
+Import-Template:
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.aspectj.*;version="${aspectjRange}";resolution:=optional,
+ org.springframework.security.access.*;version="${secRange}",
+ org.springframework.security.authentication.*;version="${secRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.util;version="${secRange}",
+ org.springframework.security.provisioning;version="${secRange}",
+ org.springframework.security.web.*;version="${secRange}";resolution:=optional,
+ org.springframework.aop.*;version="${springRange}";resolution:=optional,
+ org.springframework.beans.*;version="${springRange}",
+ org.springframework.context.*;version="${springRange}",
+ org.springframework.core.*;version="${springRange}",
+ org.springframework.web.*;version="${springRange}",
+ org.springframework.util.*;version="${springRange}",
+ javax.servlet.*;version="0";resolution:=optional,
  javax.naming.directory;version="0";resolution:=optional,
  org.w3c.dom;version="0";resolution:=optional

+ 5 - 1
core/core.gradle

@@ -17,5 +17,9 @@ dependencies {
     runtime 'hsqldb:hsqldb:1.8.0.10'
 
     testCompile 'commons-collections:commons-collections:3.2',
-                "org.springframework:spring-test:$springVersion"
+                "org.springframework:spring-test:$springVersion",
+                "org.slf4j:jcl-over-slf4j:$slf4jVersion"
+
+    testRuntime "hsqldb:hsqldb:$hsqlVersion",
+                "cglib:cglib-nodep:$cglibVersion"
 }

+ 1 - 1
core/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <packaging>jar</packaging>
     <artifactId>spring-security-core</artifactId>

+ 14 - 14
core/template.mf

@@ -9,20 +9,20 @@ Ignored-Existing-Headers:
  Import-Package,
  Export-Package
 Import-Template: 
- org.aopalliance.*;version="[1.0.0, 2.0.0)",
- org.aspectj.*;version="[1.6.0, 1.7.0)";resolution:=optional,
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.springframework.aop.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.beans.*;version="[${spring.version}, 3.1.0)",
- org.springframework.context.*;version="[${spring.version}, 3.1.0)",
- org.springframework.core.*;version="[${spring.version}, 3.1.0)",
- org.springframework.expression.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.remoting.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.dao.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.jdbc.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.transaction.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.util;version="[${spring.version}, 3.1.0)",
- net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional, 
+ org.aopalliance.*;version="${aopAllianceRange}",
+ org.aspectj.*;version="${aspectjRange}";resolution:=optional,
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.springframework.aop.*;version="${springRange}";resolution:=optional,
+ org.springframework.beans.*;version="${springRange}",
+ org.springframework.context.*;version="${springRange}",
+ org.springframework.core.*;version="${springRange}",
+ org.springframework.expression.*;version="${springRange}";resolution:=optional,
+ org.springframework.remoting.*;version="${springRange}";resolution:=optional,
+ org.springframework.dao.*;version="${springRange}";resolution:=optional,
+ org.springframework.jdbc.*;version="${springRange}";resolution:=optional,
+ org.springframework.transaction.*;version="${springRange}";resolution:=optional,
+ org.springframework.util;version="${springRange}",
+ net.sf.ehcache.*;version="${ehcacheRange}";resolution:=optional,
  javax.annotation.security.*;version="0";resolution:=optional,
  javax.crypto.*;version="0";resolution:=optional,
  javax.security.auth.*;version="0";resolution:=optional,

+ 143 - 0
docs/docs.gradle

@@ -0,0 +1,143 @@
+    // Docbook and Javadoc building and uploading tasks
+apply plugin: 'base'
+
+task docs {
+    dependsOn 'manual:docbook', 'faq:docbookHtmlSingle', 'apidocs'
+}
+
+subprojects {
+    apply plugin: 'base'
+    apply plugin: 'docbook'
+
+    docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl')
+}
+
+project('faq') {
+    defaultTasks 'docbookHtmlSingle'
+    [docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'faq.xml'
+    docbookHtmlSingle.suffix = ''
+
+    ext.spec = copySpec {
+        into ('faq') {
+            from("$buildDir/docs")
+            from("$projectDir/src/resources")
+        }
+    }
+}
+
+project('manual') {
+    defaultTasks 'docbookHtml', 'docbookHtmlSingle', 'docbookFoPdf'
+    [docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'springsecurity.xml'
+
+    docbookHtml.stylesheet = new File(projectDir, 'src/xsl/html-custom.xsl')
+    docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl')
+    docbookFoPdf.stylesheet = new File(projectDir, 'src/xsl/pdf-custom.xsl')
+    def imagesDir = new File(projectDir, 'src/docbook/images');
+//    docbookFoPdf.admonGraphicsPath = "${imagesDir}/"
+    docbookFoPdf.imgSrcPath = "${projectDir}/src/docbook/"
+
+    ext.spec = copySpec {
+        into ('reference') {
+            from("$buildDir/docs")
+            from("$projectDir/src/resources")
+        }
+        into ('reference/images') {
+            from (imagesDir)
+        }
+    }
+}
+
+task reference (type: Copy) {
+    dependsOn 'manual:docbook'
+    destinationDir = buildDir
+    with(project('manual').spec)
+}
+
+task apidocs(type: Javadoc) {
+    destinationDir = new File(buildDir, 'apidocs')
+    title = "Spring Security $version API"
+
+    source coreModuleProjects.collect { project ->
+        project.sourceSets.main.allJava
+    }
+
+    classpath = files(coreModuleProjects.collect { project ->
+        project.sourceSets.main.compileClasspath
+    })
+}
+
+apidocs.options.outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
+
+apidocs.options.links = [
+    "http://static.springframework.org/spring/docs/3.0.x/javadoc-api",
+    "http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
+    "http://download.oracle.com/javase/6/docs/api/"
+]
+
+apidocs.options.groups = [
+    'Spring Security Core':[
+        'org.springframework.security.core*',
+        'org.springframework.security.authentication*',
+        'org.springframework.security.access*',
+        'org.springframework.security.remoting*',
+        'org.springframework.security.provisioning*',
+        'org.springframework.security.util*'],
+    'Spring Security Web':['org.springframework.security.web*'],
+    'Spring Security LDAP':['org.springframework.security.ldap*'],
+    'Spring Security Crypto':['org.springframework.security.crypto*'],
+    'Spring Security OpenID':['org.springframework.security.openid*'],
+    'Spring Security CAS':['org.springframework.security.cas*'],
+    'Spring Security ACL':['org.springframework.security.acls*'],
+    'Spring Security Config':['org.springframework.security.config*'],
+    'Spring Security Taglibs':['org.springframework.security.taglibs*'],
+
+]
+
+ext.apiSpec = copySpec {
+    into('apidocs') {
+        from(apidocs.destinationDir)
+    }
+}
+
+assemble.dependsOn = [apidocs, 'manual:docbook']
+
+task docsZip(type: Zip) {
+    dependsOn docs
+    group = 'Distribution'
+    baseName = rootProject.name
+    classifier = 'docs'
+    description = "Builds -${classifier} archive containing api and reference " +
+        "for deployment at static.springframework.org/spring-security/site/docs."
+
+    with(project(':docs').apiSpec)
+    with(project(':docs:manual').spec)
+    with(project(':docs:faq').spec)
+}
+
+task schemaZip(type: Zip) {
+    group = 'Distribution'
+    baseName = rootProject.name
+    classifier = 'schema'
+    description = "Builds -${classifier} archive containing all " +
+        "XSDs for deployment at static.springframework.org/schema."
+
+    coreModuleProjects.each { module ->
+        def Properties schemas = new Properties();
+
+        module.sourceSets.main.resources.find {
+            it.path.endsWith('META-INF/spring.schemas')
+        }?.withInputStream { schemas.load(it) }
+
+        for (def key : schemas.keySet()) {
+            def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
+            assert shortName != key
+            File xsdFile = module.sourceSets.main.resources.find {
+                it.path.endsWith(schemas.get(key))
+            }
+            assert xsdFile != null
+            into (shortName) {
+                from xsdFile.path
+            }
+        }
+    }
+}

+ 0 - 17
docs/faq/faq.gradle

@@ -1,17 +0,0 @@
-apply plugin: 'base'
-apply plugin: 'docbook'
-
-defaultTasks 'docbookHtmlSingle'
-
-[docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'faq.xml'
-
-docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl')
-docbookHtmlSingle.suffix = ''
-
-docbookHtmlSingle.doLast {
-    resourcesDir = new File(projectDir, 'src/resources')
-    ant {
-        docsDir = new File(buildDir, 'docs')
-        copy(toDir: docsDir) {fileset(dir: resourcesDir)}
-    }
-}

+ 0 - 19
docs/manual/manual.gradle

@@ -1,19 +0,0 @@
-apply plugin: 'base'
-apply plugin: 'docbook'
-
-[docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'springsecurity.xml';
-
-docbookHtml.stylesheet = new File(projectDir, 'src/xsl/html-custom.xsl')
-docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl')
-docbookFoPdf.stylesheet = new File(projectDir, 'src/xsl/pdf-custom.xsl')
-def imagesDir = new File(projectDir, 'src/docbook/images');
-docbookFoPdf.admonGraphicsPath = "${imagesDir}/"
-
-task doc (dependsOn: [docbookHtml, docbookHtmlSingle, docbookFoPdf]) << {
-    resourcesDir = new File(projectDir, 'src/resources')
-    ant {
-        docsDir = new File(buildDir, 'docs')
-        copy(toDir: docsDir) {fileset(dir: resourcesDir)}
-        copy(toDir: new File(docsDir, 'images')) {fileset(dir: imagesDir)}
-    }
-}

+ 1 - 1
docs/manual/src/docbook/springsecurity.xml

@@ -10,7 +10,7 @@
       </author>
     </authorgroup>
     <productname>Spring Security</productname>
-    <releaseinfo>3.0.7.RELEASE</releaseinfo>
+    <releaseinfo>${version}</releaseinfo>
   </info>
   <toc/>
   <preface xml:id="preface">

+ 1 - 0
gradle.properties

@@ -0,0 +1 @@
+version=3.0.8.CI-SNAPSHOT

+ 0 - 47
gradle/aspectj.gradle

@@ -1,47 +0,0 @@
-apply plugin: 'java'
-
-configurations {
-    ajtools
-    aspectpath
-}
-
-dependencies {
-    ajtools "org.aspectj:aspectjtools:$aspectjVersion"
-    compile "org.aspectj:aspectjrt:$aspectjVersion"
-}
-
-task compileJava(overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
-    dependsOn processResources
-    sourceSet = sourceSets.main
-    aspectPath = configurations.aspectpath
-}
-
-task compileTestJava(overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
-    dependsOn processTestResources, compileJava, jar
-    sourceSet = sourceSets.test
-    aspectPath = files(configurations.aspectpath, jar.archivePath)
-}
-
-class Ajc extends DefaultTask {
-    @Input
-    SourceSet sourceSet
-
-    @Input
-    FileCollection aspectPath
-
-    @TaskAction
-    def compile() {
-        println "Running ajc ..."
-        ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
-        ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.classesDir.absolutePath,
-                source: project.convention.plugins.java.sourceCompatibility,
-                target: project.convention.plugins.java.targetCompatibility,
-                aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
-            sourceroots {
-                sourceSet.java.srcDirs.each {
-                    pathelement(location: it.absolutePath)
-                }
-            }
-        }
-    }
-}

+ 0 - 31
gradle/bundlor.gradle

@@ -1,31 +0,0 @@
-apply plugin: 'java'
-
-configurations {
-    bundlor
-}
-
-dependencies {
-    bundlor 'com.springsource.bundlor:com.springsource.bundlor.ant:1.0.0.RELEASE',
-            'com.springsource.bundlor:com.springsource.bundlor:1.0.0.RELEASE',
-            'com.springsource.bundlor:com.springsource.bundlor.blint:1.0.0.RELEASE'
-}
-
-task bundlor(dependsOn: compileJava) {
-    onlyIf {
-        dependsOnTaskDidWork()
-    }
-    doFirst {
-        ant.taskdef(resource: 'com/springsource/bundlor/ant/antlib.xml', classpath: configurations.bundlor.asPath)
-        File template = new File(projectDir, 'template.mf')
-        mkdir("$buildDir/bundlor")
-        if (template.exists()) {
-            ant.bundlor(inputPath: sourceSets.main.classesDir, outputPath: "$buildDir/bundlor", manifestTemplatePath: template) {
-                property(name: 'version', value: "$version")
-                property(name: 'spring.version', value: "$springVersion")
-            }
-            jar.manifest.from("$buildDir/bundlor/META-INF/MANIFEST.MF")
-        }
-    }
-}
-
-jar.dependsOn bundlor

+ 63 - 0
gradle/ide-integration.gradle

@@ -0,0 +1,63 @@
+apply plugin: 'idea'
+
+configure(javaProjects) {
+    apply plugin: 'eclipse-wtp'
+
+    eclipse.classpath.downloadSources = true
+
+    // GRADLE-1116
+    project.eclipse.classpath.file.whenMerged { classpath ->
+        classpath.entries.removeAll { entry -> entry.path.endsWith('/build/classes/test') }
+    }
+
+    // GRADLE-1422
+    project.eclipseClasspath.doFirst {
+       // delay adding whenMerged till the entryAttributes are added (must be the last whenMerged)
+       project.eclipse.classpath.file.whenMerged { classpath ->
+           def includeDeps = project.configurations.getByName('runtime').collect {f -> f.absolutePath } as Set
+           classpath.entries.each { cp ->
+               if(cp instanceof org.gradle.plugins.ide.eclipse.model.Library) {
+                   def include = includeDeps.contains(cp.path)
+                   def attr = 'org.eclipse.jst.component.dependency'
+                   if(!include) {
+                       cp.entryAttributes.remove(attr)
+                   }
+               }
+           }
+       }
+    }
+
+    tasks.withType(org.gradle.plugins.ide.eclipse.GenerateEclipseWtpComponent) {
+        project.eclipse.classpath.file.whenMerged { classpath->
+            project.eclipse.wtp.component.file.whenMerged { wtpComponent ->
+                wtpComponent.contextPath = project.tasks.findByName('jettyRun')?.contextPath?.replaceFirst('/','')
+            }
+        }
+    }
+}
+
+// STS-2723
+project(':spring-security-samples-aspectj') {
+    task afterEclipseImport {
+        ext.srcFile = file('.classpath')
+        inputs.file srcFile
+        outputs.dir srcFile
+
+        onlyIf { srcFile.exists() }
+
+        doLast {
+            def classpath = new XmlParser().parse(srcFile)
+
+            classpath.classpathentry.findAll{ it.@path == '/spring-security-aspects' }.each { node ->
+                if(node.children().size() == 0) {
+                    def attrs = new Node(node,'attributes')
+                    def adjtAttr = new Node(attrs,'attributes',[name: 'org.eclipse.ajdt.aspectpath', value: 'org.eclipse.ajdt.aspectpath'])
+                    node.appendNode(adjtAttr)
+                }
+            }
+
+            def writer = new FileWriter(srcFile)
+            new XmlNodePrinter(new PrintWriter(writer)).print(classpath)
+        }
+    }
+}

+ 112 - 15
gradle/javaprojects.gradle

@@ -1,24 +1,73 @@
 apply plugin: 'java'
 apply plugin: 'eclipse'
 
-springVersion = '3.0.3.RELEASE'
-springLdapVersion = '1.3.0.RELEASE'
-ehcacheVersion = '1.6.2'
-aspectjVersion = '1.6.8'
-apacheDsVersion = '1.5.5'
-jstlVersion = '1.1.2'
-jettyVersion = '6.1.22'
-hsqlVersion = '1.8.0.10'
-slf4jVersion = '1.6.1'
-logbackVersion = '0.9.29'
+sourceCompatibility = 1.5
+targetCompatibility = 1.5
+ext.springVersion = '3.0.7.RELEASE'
+ext.springLdapVersion = '1.3.1.RELEASE'
+ext.ehcacheVersion = '1.6.2'
+ext.aspectjVersion = '1.6.10'
+ext.apacheDsVersion = '1.5.5'
+ext.jstlVersion = '1.2'
+ext.jettyVersion = '6.1.26'
+ext.hsqlVersion = '1.8.0.10'
+ext.slf4jVersion = '1.6.1'
+ext.logbackVersion = '0.9.29'
+ext.cglibVersion = '2.2'
+ext.powerMockVersion = '1.4.12'
 
+ext.bundlorProperties = [
+    version: version,
+    secRange: "[$version, 3.1.0)",
+    springRange: "[$springVersion, 3.1.0)",
+    aspectjRange: '[1.6.0, 1.7.0)',
+    casRange: '[3.1.1, 3.2.0)',
+    cloggingRange: '[1.0.4, 2.0.0)',
+    ehcacheRange: '[1.4.1, 2.5.0)',
+    openid4javaRange: '[0.9.5, 1.0.0)',
+    springLdapRange: '[1.3.0,1.4.0)',
+    apacheDSRange: '[1.5.5, 1.6)',
+    apacheDSSharedRange: '[0.9.15, 1.0)',
+    ldapSdkRange: '[4.1, 5.0)',
+    aopAllianceRange: '[1.0.0, 2.0.0)'
+]
 configurations {
+    // Configuration which is ONLY used for compileJava and will not be inherited by any others
+    // Revisit post Gradle 1.0
+    compileOnly
+    // Used to identify deps which should be marked as "provided" in maven poms
     provided
-    compile.extendsFrom provided
+    testCompile.extendsFrom provided
+    compile.transitive = false
+    testCompile.transitive = false
 }
 
+// Integration test setup
+configurations {
+    integrationTestCompile {
+        extendsFrom testCompile
+    }
+    integrationTestRuntime {
+        extendsFrom integrationTestCompile, testRuntime
+    }
+}
+sourceSets {
+    integrationTest {
+        java.srcDir file('src/integration-test/java')
+        resources.srcDir file('src/integration-test/resources')
+        compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile
+        runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime
+    }
+}
+task integrationTest(type: Test, dependsOn: jar) {
+    testClassesDir = sourceSets.integrationTest.output.classesDir
+    logging.captureStandardOutput(LogLevel.INFO)
+    classpath = sourceSets.integrationTest.runtimeClasspath
+    maxParallelForks = 1
+//    testReport = false
+}
 dependencies {
-    compile 'commons-logging:commons-logging:1.1.1'
+    compileOnly 'commons-logging:commons-logging:1.1.1'
 
     compile ("org.springframework:spring-core:$springVersion") {
         exclude(group: 'commons-logging', module: 'commons-logging')
@@ -31,12 +80,60 @@ dependencies {
             'org.hamcrest:hamcrest-core:1.1',
             'org.hamcrest:hamcrest-library:1.1',
             "org.springframework:spring-test:$springVersion"
+    // Use slf4j/logback for logging
+    testRuntime "org.slf4j:jcl-over-slf4j:$slf4jVersion",
+                "ch.qos.logback:logback-classic:$logbackVersion"
 }
 
+[configurations.runtime, configurations.default]*.exclude(module: 'commons-logging')
+sourceSets.main.compileClasspath += configurations.compileOnly
+sourceSets.main.compileClasspath += configurations.provided
+[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
 test {
-    onlyIf {
-        !project.hasProperty('skipTests')
+    jvmArgs = ['-ea', '-Xmx500m']
+    maxParallelForks = guessMaxForks()
+    logging.captureStandardOutput(LogLevel.INFO)
+    testReport = false
+}
+def guessMaxForks() {
+    int processors = Runtime.runtime.availableProcessors()
+    return Math.max(2, (int) (processors / 2))
+}
+javadoc {
+    title = "Spring Security $version API"
+    source = sourceSets.main.allJava
+    classpath +=  configurations.compileOnly + configurations.provided
+    options {
+        memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
+        author = true
+        header = project.name
+        outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
+        links = [
+            "http://static.springframework.org/spring/docs/3.0.x/javadoc-api",
+            "http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/",
+            "http://download.oracle.com/javase/6/docs/api/"
+        ]
+        groups = [
+            'Spring Security Core':[
+                'org.springframework.security.core*',
+                'org.springframework.security.authentication*',
+                'org.springframework.security.access*',
+                'org.springframework.security.remoting*',
+                'org.springframework.security.provisioning*',
+                'org.springframework.security.util*'],
+            'Spring Security Web':['org.springframework.security.web*'],
+            'Spring Security LDAP':['org.springframework.security.ldap*'],
+            'Spring Security Crypto':['org.springframework.security.crypto*'],
+            'Spring Security OpenID':['org.springframework.security.openid*'],
+            'Spring Security CAS':['org.springframework.security.cas*'],
+            'Spring Security ACL':['org.springframework.security.acls*'],
+            'Spring Security Config':['org.springframework.security.config*'],
+            'Spring Security Taglibs':['org.springframework.security.taglibs*'],
+        ]
     }
-    jvmArgs = ['-ea', '-Xms128m', '-Xmx500m', '-XX:MaxPermSize=128m']
 }
 
+task javadocJar(type: Jar) {
+    classifier = 'javadoc'
+    from javadoc
+}

+ 51 - 0
gradle/maven-deployment.gradle

@@ -0,0 +1,51 @@
+import org.apache.tools.ant.filters.ReplaceTokens
+
+apply plugin: 'maven'
+
+// Create a source jar for uploading
+task sourceJar(type: Jar) {
+    classifier = 'sources'
+    from sourceSets.main.java.srcDirs
+    include '**/*.java', '**/*.aj'
+}
+
+// Configuration for SpringSource s3 maven deployer
+configurations {
+    deployerJars
+}
+dependencies {
+    deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE"
+}
+
+// Remove the archive configuration from the runtime configuration, so that anything added to archives
+// (such as the source jar) is no longer included in the runtime classpath
+configurations.default.extendsFrom = [configurations.runtime] as Set
+// Add the main jar into the default configuration
+artifacts { 'default' jar }
+
+install {
+    customizePom(repositories.mavenInstaller.pom, project)
+}
+
+if(project != project(":spring-security-parent")) {
+    install.dependsOn ':spring-security-parent:install'
+    artifacts {
+        archives sourceJar
+        archives javadocJar
+    }
+}
+
+task generatePom(type: Copy) {
+    from 'pom.xml'
+    into 'build/'
+    filter(ReplaceTokens, tokens: [pomVersion : project.properties.version])
+}
+install.dependsOn generatePom
+
+def customizePom(pom, gradleProject) {
+    pom.withXml { provider ->
+        def builder = provider.asString()
+        builder.length = 0 // delete existing content
+        builder.append(file("build/pom.xml").text)
+    }
+}

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Tue Oct 02 08:45:52 CDT 2012
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.1-bin.zip

+ 164 - 0
gradlew

@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS="-Xmx1024M -XX:MaxPermSize=256M"
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/"
+APP_HOME="`pwd -P`"
+cd "$SAVED"
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=-Xmx1024M -XX:MaxPermSize=256M
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 17 - 0
itest/context/itest-context.gradle

@@ -0,0 +1,17 @@
+System.setProperty('python.cachedir.skip', 'true')
+
+dependencies {
+    compile     project(':spring-security-core'),
+                'aopalliance:aopalliance:1.0',
+                'org.python:jython:2.5.0',
+                "org.springframework:spring-context:$springVersion",
+                "org.springframework:spring-aop:$springVersion",
+                "org.springframework:spring-tx:$springVersion",
+                "org.springframework:spring-beans:$springVersion"
+
+    testCompile project(':spring-security-web'),
+                'javax.servlet:servlet-api:2.5',
+                "org.springframework:spring-web:$springVersion"
+    testRuntime project(':spring-security-config')
+
+}

+ 1 - 1
itest/context/pom.xml

@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-itest</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-itest-context</artifactId>
     <name>Spring Security - Miscellaneous Application Context Integration Tests</name>

+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/HttpNamespaceWithMultipleInterceptorsTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/HttpNamespaceWithMultipleInterceptorsTests.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/HttpPathParameterStrippingTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/HttpPathParameterStrippingTests.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/MultiAnnotationTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/MultiAnnotationTests.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/SEC933ApplicationContextTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/SEC933ApplicationContextTests.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/SEC936ApplicationContextTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/SEC936ApplicationContextTests.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/StubUserRepository.java → itest/context/src/integration-test/java/org/springframework/security/integration/StubUserRepository.java


+ 0 - 0
itest/context/src/test/java/org/springframework/security/integration/python/PythonInterpreterBasedSecurityTests.java → itest/context/src/integration-test/java/org/springframework/security/integration/python/PythonInterpreterBasedSecurityTests.java


+ 7 - 11
itest/context/src/test/java/org/springframework/security/performance/FilterChainPerformanceTests.java → itest/context/src/integration-test/java/org/springframework/security/performance/FilterChainPerformanceTests.java

@@ -1,14 +1,6 @@
 package org.springframework.security.performance;
 
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.http.HttpSession;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -26,6 +18,9 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.util.StopWatch;
 
+import javax.servlet.http.HttpSession;
+import java.util.*;
+
 /**
  *
  * @author Luke Taylor
@@ -34,8 +29,9 @@ import org.springframework.util.StopWatch;
 @ContextConfiguration(locations={"/filter-chain-performance-app-context.xml"})
 @RunWith(SpringJUnit4ClassRunner.class)
 public class FilterChainPerformanceTests {
-    private static final int N_INVOCATIONS = 1000;
-    private static final int N_AUTHORITIES = 200;
+    // Adjust as required
+    private static final int N_INVOCATIONS = 1; // 1000
+    private static final int N_AUTHORITIES = 2; // 200
     private static StopWatch sw = new StopWatch("Filter Chain Performance Tests");
 
     private final UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken("bob", "bobspassword", createRoles(N_AUTHORITIES));

+ 0 - 0
itest/context/src/test/java/org/springframework/security/performance/ProtectPointcutPerformanceTests.java → itest/context/src/integration-test/java/org/springframework/security/performance/ProtectPointcutPerformanceTests.java


+ 0 - 0
itest/context/src/test/resources/filter-chain-performance-app-context.xml → itest/context/src/integration-test/resources/filter-chain-performance-app-context.xml


+ 0 - 0
itest/context/src/test/resources/http-extra-fsi-app-context.xml → itest/context/src/integration-test/resources/http-extra-fsi-app-context.xml


+ 0 - 0
itest/context/src/test/resources/http-path-param-stripping-app-context.xml → itest/context/src/integration-test/resources/http-path-param-stripping-app-context.xml


+ 0 - 0
itest/context/src/test/resources/log4j.properties → itest/context/src/integration-test/resources/log4j.properties


+ 0 - 0
itest/context/src/test/resources/multi-sec-annotation-app-context.xml → itest/context/src/integration-test/resources/multi-sec-annotation-app-context.xml


+ 0 - 0
itest/context/src/test/resources/protect-pointcut-performance-app-context.xml → itest/context/src/integration-test/resources/protect-pointcut-performance-app-context.xml


+ 0 - 0
itest/context/src/test/resources/python-method-access-app-context.xml → itest/context/src/integration-test/resources/python-method-access-app-context.xml


+ 0 - 0
itest/context/src/test/resources/sec-933-app-context.xml → itest/context/src/integration-test/resources/sec-933-app-context.xml


+ 0 - 0
itest/context/src/test/resources/sec-936-app-context.xml → itest/context/src/integration-test/resources/sec-936-app-context.xml


+ 0 - 0
itest/context/src/test/resources/someMethod.py → itest/context/src/integration-test/resources/someMethod.py


+ 1 - 1
itest/misc/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-itest</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-itest-misc</artifactId>
     <name>Spring Security - Miscellaneous Integration Tests</name>

+ 2 - 2
itest/pom.xml

@@ -3,12 +3,12 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-itest</artifactId>
     <name>Spring Security - Integration Tests</name>
     <packaging>pom</packaging>
-    <version>3.0.8.CI-SNAPSHOT</version>
+    <version>@pomVersion@</version>
     <modules>
         <module>web</module>
         <!-- module>webflow</module-->

+ 3 - 2
itest/web/itest-web.gradle

@@ -21,10 +21,11 @@ dependencies {
                 'net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2'
 }
 
-test {
+integrationTest {
     useTestNG();
     options {
         jvmArgs = ["-ea", '-Xms128m', '-Xmx500m']
         systemProperties = ['webapp.dir': "$projectDir/src/main/webapp"]
     }
-}
+    maxParallelForks = 1
+}

+ 1 - 1
itest/web/pom.xml

@@ -4,7 +4,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-itest</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-itest-web</artifactId>
     <name>Spring Security - Web Integration Tests</name>

+ 26 - 9
ldap/ldap.gradle

@@ -1,25 +1,42 @@
 // Ldap build file
 
-test.exclude('**/OpenLDAPIntegrationTestSuite.class')
 
-dependencies {
-    compile project(':spring-security-core'),
-            "org.springframework:spring-beans:$springVersion",
-            "org.springframework:spring-context:$springVersion",
-            "org.springframework:spring-tx:$springVersion",
+def apacheds_libs = [
             "org.apache.directory.server:apacheds-core:$apacheDsVersion",
             "org.apache.directory.server:apacheds-core-entry:$apacheDsVersion",
             "org.apache.directory.server:apacheds-protocol-shared:$apacheDsVersion",
             "org.apache.directory.server:apacheds-protocol-ldap:$apacheDsVersion", 
             "org.apache.directory.server:apacheds-server-jndi:$apacheDsVersion",
-            'org.apache.directory.shared:shared-ldap:0.9.15',
+         'org.apache.directory.shared:shared-ldap:0.9.15'
+]
+dependencies {
+    compile project(':spring-security-core'),
+            "org.springframework:spring-beans:$springVersion",
+            "org.springframework:spring-context:$springVersion",
+            "org.springframework:spring-tx:$springVersion",
             'ldapsdk:ldapsdk:4.1'
+    apacheds_libs.collect {
+        compile (it) {
+            exclude group: 'org.slf4j'
+        }
+    }
     compile ("org.springframework.ldap:spring-ldap-core:$springLdapVersion") {
         exclude(group: 'commons-logging', module: 'commons-logging')
         exclude(group: 'org.springframework', module: 'spring-core')
         exclude(group: 'org.springframework', module: 'spring-tx')
         exclude(group: 'org.springframework', module: 'spring-beans')
     }
+}
 
-    runtime 'org.slf4j:slf4j-log4j12:1.4.3'
-}
+integrationTest {
+    include('**/ApacheDSServerIntegrationTests.class')
+//    exclude('**/OpenLDAPIntegrationTestSuite.class')
+    maxParallelForks = 1
+    systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
+}
+// Runs a server for running the integration tests against (from an IDE, for example)
+task(ldapServer, dependsOn: 'integrationTestClasses', type: JavaExec) {
+    classpath = sourceSets.integrationTest.runtimeClasspath
+    main = 'org.springframework.security.ldap.ApacheDSServerIntegrationTests'
+    systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
+}

+ 1 - 1
ldap/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <packaging>jar</packaging>
     <artifactId>spring-security-ldap</artifactId>

+ 49 - 0
ldap/src/integration-test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java

@@ -0,0 +1,49 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * 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
+ *
+ *     http://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 org.springframework.security.ldap;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+
+/**
+ * Based on class borrowed from Spring Ldap project.
+ *
+ * @author Luke Taylor
+ */
+public abstract class AbstractLdapIntegrationTests {
+    private static DefaultSpringSecurityContextSource contextSource;
+
+    protected AbstractLdapIntegrationTests() {
+    }
+
+    @BeforeClass
+    public static void startServer() throws Exception {
+        contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
+     // OpenLDAP configuration
+//             contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
+//             contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
+//             contextSource.setPassword("password");
+             contextSource.afterPropertiesSet();
+    }
+
+    @Before
+    public void onSetUp() throws Exception {
+    }
+
+    public BaseLdapPathContextSource getContextSource() {
+        return contextSource;
+    }
+}

+ 29 - 48
ldap/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/ApacheDSServerIntegrationTests.java

@@ -1,59 +1,40 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * 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
- *
- *     http://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 org.springframework.security.ldap;
 
-import javax.naming.Binding;
-import javax.naming.ContextNotEmptyException;
-import javax.naming.Name;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
-import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.junit.*;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.springframework.security.ldap.authentication.BindAuthenticatorTests;
+import org.springframework.security.ldap.authentication.PasswordComparisonAuthenticatorTests;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearchTests;
 import org.springframework.security.ldap.server.ApacheDSContainer;
+import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulatorTests;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsManagerTests;
 
 /**
- * Based on class borrowed from Spring Ldap project.
- *
  * @author Luke Taylor
  */
-public abstract class AbstractLdapIntegrationTests {
-//    private static InMemoryXmlApplicationContext appContext;
+@RunWith(Suite.class)
+@Suite.SuiteClasses( {
+        BindAuthenticatorTests.class,
+        PasswordComparisonAuthenticatorTests.class,
+        FilterBasedLdapUserSearchTests.class,
+        DefaultLdapAuthoritiesPopulatorTests.class,
+        LdapUserDetailsManagerTests.class,
+        DefaultSpringSecurityContextSourceTests.class,
+        SpringSecurityLdapTemplateTests.class
+}
+)
+public final class ApacheDSServerIntegrationTests {
     private static ApacheDSContainer server;
-    private static DefaultSpringSecurityContextSource contextSource;
-
-    protected AbstractLdapIntegrationTests() {
-    }
 
     @BeforeClass
     public static void startServer() throws Exception {
-        contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
 // OpenLDAP configuration
 //        contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
 //        contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
 //        contextSource.setPassword("password");
-        contextSource.afterPropertiesSet();
         server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
+        server.setPort(53389);
         server.afterPropertiesSet();
     }
 
@@ -64,11 +45,15 @@ public abstract class AbstractLdapIntegrationTests {
         }
     }
 
-    @Before
-    public void onSetUp() throws Exception {
+    /**
+     * Main class to allow server to be started from gradle script
+     */
+    public static void main(String[] args) throws Exception {
+        ApacheDSContainer server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
+        server.afterPropertiesSet();
     }
 
-
+/*
     @After
     public final void reloadServerDataIfDirty() throws Exception {
         ClassPathResource ldifs = new ClassPathResource("test-server.ldif");
@@ -91,11 +76,6 @@ public abstract class AbstractLdapIntegrationTests {
         }
     }
 
-    public BaseLdapPathContextSource getContextSource() {
-        return contextSource;
-    }
-
-
     private void clearSubContexts(DirContext ctx, Name name) throws NamingException {
 
         NamingEnumeration<Binding> enumeration = null;
@@ -124,4 +104,5 @@ public abstract class AbstractLdapIntegrationTests {
             }
         }
     }
+    */
 }

+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/DefaultSpringSecurityContextSourceTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/DefaultSpringSecurityContextSourceTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/authentication/BindAuthenticatorTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/authentication/PasswordComparisonAuthenticatorTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/authentication/PasswordComparisonAuthenticatorTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/ppolicy/OpenLDAPIntegrationTestSuite.java → ldap/src/integration-test/java/org/springframework/security/ldap/ppolicy/OpenLDAPIntegrationTestSuite.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java


+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/server/ApacheDSContainerTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/server/ApacheDSContainerTests.java


+ 161 - 0
ldap/src/integration-test/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulatorTests.java

@@ -0,0 +1,161 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * 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
+ *
+ *     http://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 org.springframework.security.ldap.userdetails;
+
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.ldap.AbstractLdapIntegrationTests;
+
+import java.util.*;
+
+
+/**
+ *
+ * @author Luke Taylor
+ */
+@SuppressWarnings({"deprecation"})
+public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegrationTests {
+    private DefaultLdapAuthoritiesPopulator populator;
+    //~ Methods ========================================================================================================
+
+    @Before
+    public void setUp() throws Exception {
+        populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), "ou=groups");
+        populator.setIgnorePartialResultException(false);
+    }
+
+    @Test
+    public void defaultRoleIsAssignedWhenSet() {
+        populator.setDefaultRole("ROLE_USER");
+        assertSame(getContextSource(), populator.getContextSource());
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("cn=notfound"));
+
+        Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(ctx, "notfound");
+        assertEquals(1, authorities.size());
+        assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_USER"));
+    }
+
+    @Test
+    public void nullSearchBaseIsAccepted() throws Exception {
+        populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), null);
+        populator.setDefaultRole("ROLE_USER");
+
+        Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(
+                new DirContextAdapter(new DistinguishedName("cn=notused")), "notused");
+        assertEquals(1, authorities.size());
+        assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_USER"));
+    }
+
+    @Test
+    public void groupSearchReturnsExpectedRoles() {
+        populator.setRolePrefix("ROLE_");
+        populator.setGroupRoleAttribute("ou");
+        populator.setSearchSubtree(true);
+        populator.setSearchSubtree(false);
+        populator.setConvertToUpperCase(true);
+        populator.setGroupSearchFilter("(member={0})");
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
+
+        Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "ben"));
+
+        assertEquals("Should have 2 roles", 2, authorities.size());
+
+        assertTrue(authorities.contains("ROLE_DEVELOPER"));
+        assertTrue(authorities.contains("ROLE_MANAGER"));
+    }
+
+    @Test
+    public void useOfUsernameParameterReturnsExpectedRoles() {
+        populator.setGroupRoleAttribute("ou");
+        populator.setConvertToUpperCase(true);
+        populator.setGroupSearchFilter("(ou={1})");
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
+
+        Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
+
+        assertEquals("Should have 1 role", 1, authorities.size());
+        assertTrue(authorities.contains("ROLE_MANAGER"));
+    }
+
+    @Test
+    public void subGroupRolesAreNotFoundByDefault() {
+        populator.setGroupRoleAttribute("ou");
+        populator.setConvertToUpperCase(true);
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
+
+        Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
+
+        assertEquals("Should have 2 roles", 2, authorities.size());
+        assertTrue(authorities.contains("ROLE_MANAGER"));
+        assertTrue(authorities.contains("ROLE_DEVELOPER"));
+    }
+
+    @Test
+    public void subGroupRolesAreFoundWhenSubtreeSearchIsEnabled() {
+        populator.setGroupRoleAttribute("ou");
+        populator.setConvertToUpperCase(true);
+        populator.setSearchSubtree(true);
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org"));
+
+        Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "manager"));
+
+        assertEquals("Should have 3 roles", 3, authorities.size());
+        assertTrue(authorities.contains("ROLE_MANAGER"));
+        assertTrue(authorities.contains("ROLE_SUBMANAGER"));
+        assertTrue(authorities.contains("ROLE_DEVELOPER"));
+    }
+
+    @Test
+    public void extraRolesAreAdded() throws Exception {
+        populator = new DefaultLdapAuthoritiesPopulator(getContextSource(), null) {
+            @Override
+            protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) {
+                return new HashSet<GrantedAuthority>(AuthorityUtils.createAuthorityList("ROLE_EXTRA"));
+            }
+        };
+
+        Collection<GrantedAuthority> authorities = populator.getGrantedAuthorities(
+                new DirContextAdapter(new DistinguishedName("cn=notused")), "notused");
+        assertEquals(1, authorities.size());
+        assertTrue(AuthorityUtils.authorityListToSet(authorities).contains("ROLE_EXTRA"));
+    }
+
+    @Test
+    public void userDnWithEscapedCharacterParameterReturnsExpectedRoles() {
+        populator.setGroupRoleAttribute("ou");
+        populator.setConvertToUpperCase(true);
+        populator.setGroupSearchFilter("(member={0})");
+
+        DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("cn=mouse\\, jerry,ou=people,dc=springframework,dc=org"));
+
+        Set<String> authorities = AuthorityUtils.authorityListToSet(populator.getGrantedAuthorities(ctx, "notused"));
+
+        assertEquals("Should have 1 role", 1, authorities.size());
+        assertTrue(authorities.contains("ROLE_MANAGER"));
+    }
+}

+ 0 - 0
ldap/src/test/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManagerTests.java → ldap/src/integration-test/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManagerTests.java


+ 18 - 0
ldap/src/integration-test/resources/logback-test.xml

@@ -0,0 +1,18 @@
+<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="${sec.log.level}:-WARN"/>
+  <logger name="org.apache.directory" level="ERROR"/>
+  <logger name="JdbmTable" level="INFO"/>
+  <logger name="JdbmIndex" level="INFO"/>
+  <logger name="org.apache.mina" level="WARN"/>
+
+  <root level="${root.level}:-WARN">
+    <appender-ref ref="STDOUT" />
+  </root>
+
+</configuration>

+ 0 - 0
ldap/src/test/resources/test-server.ldif → ldap/src/integration-test/resources/test-server.ldif


+ 14 - 14
ldap/template.mf

@@ -9,18 +9,18 @@ Ignored-Existing-Headers:
  Import-Package,
  Export-Package
 Import-Template: 
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.apache.directory.server.*;version="[1.5.5, 1.6)";resolution:=optional,
- org.apache.directory.shared.ldap.*;version="[0.9.15, 1.0)";resolution:=optional,
- org.springframework.ldap.*;version="[1.3.0,1.4.0)",
- org.springframework.security.core.*;version="[${version}, 3.1.0)",
- org.springframework.security.authentication.*;version="[${version}, 3.1.0)",
- org.springframework.security.provisioning.*;version="[${version}, 3.1.0)",
- org.springframework.security.util;version="[${version}, 3.1.0)", 
- org.springframework.beans.*;version="[${spring.version}, 3.1.0)",
- org.springframework.context.*;version="[${spring.version}, 3.1.0)", 
- org.springframework.core.io.*;version="[${spring.version}, 3.1.0)",
- org.springframework.dao.*;version="[${spring.version}, 3.1.0)";resolution:=optional,
- org.springframework.util.*;version="[${spring.version}, 3.1.0)",
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.apache.directory.server.*;version="${apacheDSRange}";resolution:=optional,
+ org.apache.directory.shared.ldap.*;version="${apacheDSSharedRange}";resolution:=optional,
+ org.springframework.ldap.*;version="${springLdapRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.authentication.*;version="${secRange}",
+ org.springframework.security.provisioning.*;version="${secRange}",
+ org.springframework.security.util;version="${secRange}",
+ org.springframework.beans.*;version="${springRange}",
+ org.springframework.context.*;version="${springRange}",
+ org.springframework.core.io.*;version="${springRange}",
+ org.springframework.dao.*;version="${springRange}";resolution:=optional,
+ org.springframework.util.*;version="${springRange}",
  javax.naming.*;version="0";resolution:=optional,
- netscape.ldap.ber.stream;version="[4.1, 5.0)";resolution:=optional
+ netscape.ldap.ber.stream;version="${ldapSdkRange}";resolution:=optional

+ 9 - 3
openid/openid.gradle

@@ -3,14 +3,20 @@
 dependencies {
     compile project(':spring-security-core'),
             project(':spring-security-web'),
-            'org.openid4java:openid4java-nodeps:0.9.5',
             "org.springframework:spring-aop:$springVersion",
+            "org.springframework:spring-tx:$springVersion",
             "org.springframework:spring-context:$springVersion",
             "org.springframework:spring-beans:$springVersion",
-            "org.springframework:spring-tx:$springVersion",
             "org.springframework:spring-web:$springVersion"
 
+    // openid4java has a compile time dep on guice with a group
+    // name which is different from the maven central one.
+    // We use the maven central version here instead.
+    compile('org.openid4java:openid4java-nodeps:0.9.6') {
+       exclude group: 'com.google.code.guice', module: 'guice'
+    }
+    compile 'com.google.inject:guice:2.0'
     provided 'javax.servlet:servlet-api:2.5'
 
-    runtime 'commons-httpclient:commons-httpclient:3.1'
+    runtime 'org.apache.httpcomponents:httpclient:4.1.1'
 }

+ 1 - 1
openid/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <artifactId>spring-security-openid</artifactId>
     <name>Spring Security - OpenID support</name>

+ 7 - 7
openid/template.mf

@@ -9,11 +9,11 @@ Ignored-Existing-Headers:
  Import-Package,
  Export-Package
 Import-Template: 
- org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
- org.springframework.security.core.*;version="[${version}, 3.1.0)",
- org.springframework.security.authentication.*;version="[${version}, 3.1.0)",
- org.springframework.security.web.*;version="[${version}, 3.1.0)", 
- org.springframework.beans.factory;version="[${spring.version}, 3.1.0)",
- org.springframework.util;version="[${spring.version}, 3.1.0)",
- org.openid4java.*;version="[0.9.5, 1.0.0)",
+ org.apache.commons.logging.*;version="${cloggingRange}",
+ org.springframework.security.core.*;version="${secRange}",
+ org.springframework.security.authentication.*;version="${secRange}",
+ org.springframework.security.web.*;version="${secRange}",
+ org.springframework.beans.factory;version="${springRange}",
+ org.springframework.util;version="${springRange}",
+ org.openid4java.*;version="${openid4javaRange}",
  javax.servlet.*;version="0"

+ 1 - 0
parent/parent.gradle

@@ -0,0 +1 @@
+[sourceJar,javadoc,javadocJar]*.enabled = false

+ 1 - 1
pom.xml → parent/pom.xml

@@ -3,7 +3,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-parent</artifactId>
-    <version>3.0.8.CI-SNAPSHOT</version>
+    <version>@pomVersion@</version>
     <name>Spring Security</name>
     <packaging>pom</packaging>
 

+ 18 - 10
readme.txt

@@ -6,19 +6,22 @@
 OVERVIEW
 -------------------------------------------------------------------------------
 
-Spring Security provides security services for
-The Spring Framework (http://www.springframework.org).
+Spring Security provides security services for the Spring Framework
+(http://www.springframework.org). Spring Security 3.1 requires Spring 3.0.3 as
+a minimum and also requires Java 5.
 
 For a detailed list of features and access to the latest release, please visit
 http://www.springframework.org/projects/.
 
+Spring Security is released under an Apache 2.0 license. See the accompanying
+license.txt file.
 
 -------------------------------------------------------------------------------
 BUILDING
 -------------------------------------------------------------------------------
 
-Spring Security is built using Maven. Please read the "Building from Source" page
-at http://static.springframework.org/spring-security/site/.
+Please read the "Building from Source" page at
+http://static.springframework.org/spring-security/site/.
 
 -------------------------------------------------------------------------------
 DOCUMENTATION
@@ -33,7 +36,7 @@ QUICK START
 -------------------------------------------------------------------------------
 
 We recommend you visit http://static.springframework.org/spring-security/site and 
-read the "Suggested Steps" page.
+read the "Getting Started" page.
 
 -------------------------------------------------------------------------------
 MAVEN REPOSITORY DOWNLOADS
@@ -44,11 +47,11 @@ Release jars for the project are available from the central maven repository
 http://repo1.maven.org/maven2/org/springframework/security/
 
 Note that milestone releases and snapshots are not uploaded to the central
-repository, but can be obtained from te Spring milestone repository.
-This blog article has full details on how to download milestone or snapshot
-jars or use them in a Maven-based project build:
-
-http://blog.springsource.com/main/2007/09/18/maven-artifacts-2/
+repository, but can be obtained from the Spring milestone repository, using the
+maven repository http://maven.springframework.org/snapshot/. You can't browse this
+URL directly, but there is a separate browser interface. Check the downloads page
+for more information
+http://static.springsource.org/spring-security/site/downloads.html
 
 
 -------------------------------------------------------------------------------
@@ -69,4 +72,9 @@ located at the Spring Community's forum site:
 Links to the forums, and other useful resources are
 available from the web site.
 
+-------------------------------------------------------------------------------
+CONTRIBUTING
+-------------------------------------------------------------------------------
 
+Contributions are welcome. Please refer to the Contributor Guidelines for details
+  https://github.com/SpringSource/spring-security/wiki/Contributor-Guidelines

+ 0 - 80
samples/aspectj/pom.xml

@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.springframework.security</groupId>
-        <artifactId>spring-security-parent</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
-    </parent>
-    <artifactId>spring-security-samples-aspectj</artifactId>
-    <packaging>jar</packaging>
-    <name>Spring Security Sample AspectJ</name>
-    <dependencies>
-
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.6</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-config</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-aspects</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>aspectj-maven-plugin</artifactId>
-                <version>1.2</version>
-                <dependencies>
-                    <!--
-                        NB: You must use Maven 2.0.9 or above or these
-                        are ignored (see MNG-2972)
-                    -->
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjrt</artifactId>
-                        <version>1.6.8</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.aspectj</groupId>
-                        <artifactId>aspectjtools</artifactId>
-                        <version>1.6.8</version>
-                    </dependency>
-                </dependencies>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>compile</goal>
-                            <goal>test-compile</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <configuration>
-                    <aspectLibraries>
-                        <aspectLibrary>
-                            <groupId>org.springframework.security</groupId>
-                            <artifactId>spring-security-aspects</artifactId>
-                        </aspectLibrary>
-                    </aspectLibraries>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>

+ 8 - 49
samples/cas/Readme.txt

@@ -1,53 +1,12 @@
-There are two subdirectories in this project;
+To run a CAS server and client application, just execute the command
 
-server - this is not a real maven sub-project in the sense that it builds anything. It is just here to allow you to
-         conveniently run the CAS server using the maven Jetty plugin with our preconfigured SSL certificates.
-
-client - this contains the actual sample web application which uses the cas server for authentication. It uses the same
-         certificates. In practice, the CAS server would likely be running on a different machine and both client and
-         server would have different certificates issued to the server hostname.
-
-Running the CAS Server
------------------------
-
-You first need to download the CAS server 3.3.5 distribution from
-
-http://www.ja-sig.org/products/cas/downloads/index.html
-
-You only need the modules/cas-server-webapp-3.3.5.war web application file from the distribution. Copy this to the
-"server" directory inside the one that contains this readme file (i.e. copy it to samples/cas/server).
-
-You can then run the CAS server (from the same) by executing the maven command
-
-mvn jetty:run-war
-
-This will start the server on
-
-https://localhost:9443/cas
-
-If you point your browser at this URL, you should see the CAS login screen.
-
-
-Running the Client Application
--------------------------------
-
-Leave the server running and start up a separate command window to run the sample application. Change to the directory
-samples/cas/client and execute the command
-
-mvn jetty:run
-
-
-This should start the sample application on
-
-http://localhost:8080/cas-sample/
-
-Try to access the secure page (as with the other samples) and you should be redirected to the CAS server to log in. Note
-that the sample authentication module that comes with the CAS server webapp will authenticate any user whose password
-matches the username. So you have to log in here as rod/rod, dianne/dianne etc. Obviously the usernames must still match
-those listed in the application's user-service. 
-
-
-$Id$
+./gradlew cas
 
+from the project root directory. You should then be able to point your browser at
 
+https://localhost:8443/cas-sample/
 
+to view the sample application. On attempting to access a secure page,
+you'll be redirected to the CAS server where you can log in with one of
+the usernames from the sample application context (enter the username in the
+password field too, to authenticate to CAS in testing mode).

+ 0 - 9
samples/cas/cas.gradle

@@ -1,9 +0,0 @@
-apply plugin: 'war'
-apply plugin: 'jetty'
-
-dependencies {
-    runtime project(':spring-security-core'),
-            project(':spring-security-web'),
-            project(':spring-security-config'),
-            'log4j:log4j:1.2.15@jar'
-}

+ 0 - 16
samples/cas/pom.xml

@@ -1,16 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.springframework.security</groupId>
-        <artifactId>spring-security-samples</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
-    </parent>
-    <groupId>org.springframework.security</groupId>
-    <artifactId>spring-security-samples-cas</artifactId>
-    <name>Spring Security - CAS Sample Parent</name>
-    <packaging>pom</packaging>
-    <modules>
-        <module>client</module>
-        <module>server</module>
-    </modules>
-</project>

+ 125 - 0
samples/cas/sample/cassample.gradle

@@ -0,0 +1,125 @@
+// CAS sample build file
+
+apply plugin: 'war'
+apply plugin: 'jetty'
+apply plugin: 'groovy'
+
+def excludeModules = ['spring-security-acl', 'jsr250-api', 'spring-jdbc', 'spring-tx']
+def jettyVersion = '7.1.6.v20100715'
+def keystore = "$rootDir/samples/certificates/server.jks"
+def password = 'password'
+
+configurations {
+    casServer
+    excludeModules.each {name ->
+        runtime.exclude module: name
+    }
+
+    runtime.exclude group: 'org.aspectj'
+
+    integrationTestCompile.extendsFrom groovy
+}
+
+sourceSets {
+    test.resources.exclude 'GebConfig.groovy'
+    integrationTest.groovy.srcDir file('src/integration-test/groovy')
+}
+
+eclipse.classpath.plusConfigurations += configurations.integrationTestRuntime
+
+dependencies {
+    groovy 'org.codehaus.groovy:groovy:1.8.7'
+
+    providedCompile 'javax.servlet:servlet-api:2.5@jar'
+
+    compile project(':spring-security-core'),
+            project(':spring-security-cas-client'),
+            "org.jasig.cas.client:cas-client-core:3.1.12"
+
+    runtime project(':spring-security-web'),
+            project(':spring-security-config'),
+            "org.slf4j:jcl-over-slf4j:$slf4jVersion",
+            "ch.qos.logback:logback-classic:$logbackVersion"
+
+    integrationTestCompile project(':spring-security-cas-client'),
+                   'org.seleniumhq.selenium:selenium-htmlunit-driver:2.25.0',
+                   'org.spockframework:spock-core:0.6-groovy-1.8',
+                   'org.codehaus.geb:geb-spock:0.7.2',
+                   'commons-httpclient:commons-httpclient:3.1',
+                   "org.eclipse.jetty:jetty-server:$jettyVersion",
+                   "org.eclipse.jetty:jetty-servlet:$jettyVersion"
+}
+
+[jettyRun, jettyRunWar]*.configure {
+    contextPath = "/cas-sample"
+    def httpConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector').newInstance()
+    httpConnector.port = 8080
+    httpConnector.confidentialPort = 8443
+    def httpsConnector = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector').newInstance()
+    httpsConnector.port = 8443
+    httpsConnector.keystore = httpsConnector.truststore = keystore
+    httpsConnector.keyPassword = httpsConnector.trustPassword = password
+
+    connectors = [httpConnector, httpsConnector]
+    doFirst() {
+        System.setProperty('cas.server.host', casServer().httpsHost)
+        System.setProperty('cas.service.host', jettyRunWar.httpsHost)
+    }
+}
+
+task cas (dependsOn: [jettyRunWar]) {
+    jettyRunWar.dependsOn(':spring-security-samples-casserver:casServer')
+}
+
+task casServer(dependsOn: ':spring-security-samples-casserver:casServer') {
+}
+
+integrationTest.dependsOn cas
+integrationTest.doFirst {
+    def casServiceHost = jettyRunWar.httpsHost
+    systemProperties['cas.server.host'] = casServer().httpsHost
+    systemProperties['cas.service.host'] = casServiceHost
+    systemProperties['geb.build.baseUrl'] = 'https://'+casServiceHost+'/cas-sample/'
+    systemProperties['geb.build.reportsDir'] = 'build/geb-reports'
+    systemProperties['jar.path'] = jar.archivePath
+    systemProperties['javax.net.ssl.trustStore'] = keystore
+    systemProperties['javax.net.ssl.trustStorePassword'] = password
+}
+
+gradle.taskGraph.whenReady {graph ->
+    def casServer = casServer()
+    [casServer,jettyRunWar]*.metaClass*.getHttpsConnector {->
+        def sslSocketConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.security.SslSocketConnector')
+        delegate.connectors.find { it in sslSocketConnClass }
+    }
+    [casServer,jettyRunWar]*.metaClass*.getHttpsHost {->
+        "localhost:"+delegate.httpsConnector.port
+    }
+    jettyRunWar.metaClass.getHttpConnector {->
+        def channelConnClass = jettyRunWar.class.classLoader.loadClass('org.mortbay.jetty.nio.SelectChannelConnector')
+        delegate.connectors.find { it in channelConnClass }
+    }
+    if (graph.hasTask(cas)) {
+        casServer.daemon = true
+    }
+    if(graph.hasTask(integrationTest)) {
+        tasks.getByPath(':spring-security-samples-casserver:casServerOverlay').logLevel = 'ERROR'
+        jettyRunWar.additionalRuntimeJars += file("src/integration-test/resources")
+
+        jettyRunWar.daemon = true
+        jettyRunWar.httpConnector.port = availablePort()
+        jettyRunWar.httpsConnector.port = jettyRunWar.httpConnector.confidentialPort = availablePort()
+        casServer.httpsConnector.port = availablePort()
+    }
+}
+
+def casServer() {
+    tasks.getByPath(':spring-security-samples-casserver:casServer')
+}
+
+def availablePort() {
+    ServerSocket server = new ServerSocket(0)
+    int port = server.localPort
+    server.close()
+    port
+}

+ 1 - 1
samples/cas/client/pom.xml → samples/cas/sample/pom.xml

@@ -3,7 +3,7 @@
     <parent>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-samples-cas</artifactId>
-        <version>3.0.8.CI-SNAPSHOT</version>
+        <version>@pomVersion@</version>
     </parent>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-samples-cas-client</artifactId>

+ 0 - 0
samples/cas/client/src/main/java/Dummy.java → samples/cas/sample/src/main/java/Dummy.java


+ 0 - 0
samples/cas/client/src/main/webapp/WEB-INF/applicationContext-security.xml → samples/cas/sample/src/main/webapp/WEB-INF/applicationContext-security.xml


+ 0 - 0
samples/cas/client/src/main/webapp/WEB-INF/classes/log4j.properties → samples/cas/sample/src/main/webapp/WEB-INF/classes/log4j.properties


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác