Просмотр исходного кода

Updates for 3.0.x autorepo support

Rob Winch 13 лет назад
Родитель
Сommit
4f993d95b5
100 измененных файлов с 1801 добавлено и 738 удалено
  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


Некоторые файлы не были показаны из-за большого количества измененных файлов