You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2012/07/05 14:10:06 UTC
svn commit: r1357570 [6/34] - in /ace/sandbox/marrs: cnf/ cnf/ext/ cnf/lib/
cnf/releaserepo/ cnf/repo/ cnf/repo/.obrcache/
cnf/repo/.obrcache/http%3A%2F%2Fbundles.bndtools.org.s3.amazonaws.com%2Fcom.jcraft.jsch/
cnf/repo/.obrcache/http%3A%2F%2Fbundles....
Added: ace/sandbox/marrs/cnf/repo/rocoto/rocoto-6.1.0.jar
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/cnf/repo/rocoto/rocoto-6.1.0.jar?rev=1357570&view=auto
==============================================================================
Binary file - no diff available.
Propchange: ace/sandbox/marrs/cnf/repo/rocoto/rocoto-6.1.0.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: ace/sandbox/marrs/cnf/repo/slf4j.api/slf4j.api-1.5.11.jar
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/cnf/repo/slf4j.api/slf4j.api-1.5.11.jar?rev=1357570&view=auto
==============================================================================
Binary file - no diff available.
Propchange: ace/sandbox/marrs/cnf/repo/slf4j.api/slf4j.api-1.5.11.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: ace/sandbox/marrs/cnf/repo/slf4j.simple/slf4j.simple-1.5.11.jar
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/cnf/repo/slf4j.simple/slf4j.simple-1.5.11.jar?rev=1357570&view=auto
==============================================================================
Binary file - no diff available.
Propchange: ace/sandbox/marrs/cnf/repo/slf4j.simple/slf4j.simple-1.5.11.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: ace/sandbox/marrs/org.apache.ace.ant.tasks/build.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.ant.tasks/build.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.ant.tasks/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.ant.tasks/build.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+<!-- be sure to run 'mvn install' to create the library before trying this -->
+<project name="sample-build" default="build">
+ <!-- defines the deployment package task as 'dp' -->
+ <taskdef name="dp" classname="org.apache.ace.ant.deploymentpackage.DeploymentPackageTask" classpath="target/org.apache.ace.ant.tasks-0.8.1-SNAPSHOT.jar:../ace-builder/target/org.apache.ace.builder-0.8.1-SNAPSHOT.jar" />
+
+ <!-- builds a deployment package based on some existing jar files -->
+ <target name="build">
+ <dp name="org.apache.ace.dp.sample" version="1.0.0" dir=".." destination="sample-dp.jar">
+ <!-- uses two completely arbitrary bundles -->
+ <orderedinclude name="ace-log-listener/target/org.apache.ace.log.listener-0.8.1-SNAPSHOT.jar" />
+ <orderedinclude name="ace-log/target/org.apache.ace.log-0.8.1-SNAPSHOT.jar" />
+ <include name="ace-range-api/target/org.apache.ace.range.api-0.8.1-SNAPSHOT.jar" />
+ </dp>
+ </target>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.ant.tasks/pom.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.ant.tasks/pom.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.ant.tasks/pom.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.ant.tasks/pom.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>ace-pom</artifactId>
+ <version>0.8.1-SNAPSHOT</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.ace.ant.tasks</artifactId>
+
+ <version>0.8.1-SNAPSHOT</version>
+ <name>Apache ACE :: Ant Tasks</name>
+ <description>Collection of Ant tasks for integrating Apache ACE into your development environment.</description>
+ <packaging>jar</packaging>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-ant-tasks</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-ant-tasks</developerConnection>
+ <url>http://svn.apache.org/repos/asf/ace/trunk/ace-ant-tasks</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.8.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>org.apache.ace.builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.ant.tasks/src/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.ant.tasks/src/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.ant.tasks/src/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java (added)
+++ ace/sandbox/marrs/org.apache.ace.ant.tasks/src/org/apache/ace/ant/deploymentpackage/DeploymentPackageTask.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.ant.deploymentpackage;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ace.builder.DeploymentPackageBuilder;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+
+/**
+ * Ant task that creates a deployment package out of a set of bundles.
+ */
+public class DeploymentPackageTask extends MatchingTask {
+ /** The destination deployment package file. */
+ private File m_destination;
+ /** The name of the deployment package. */
+ private String m_name;
+ /** The version of the deployment package. */
+ private String m_version;
+ /** The base directory to scan for files. */
+ private File m_dir;
+
+ public void setDir (File dir) {
+ m_dir = dir;
+ }
+
+ public void setName(String name) {
+ m_name = name;
+ }
+
+ public void setVersion(String version) {
+ m_version = version;
+ }
+
+ public void setDestination(File destination) {
+ m_destination = destination;
+ }
+
+ List<OrderedInclude> orderedIncludes = new ArrayList<OrderedInclude>();
+
+ public OrderedInclude createOrderedInclude() {
+ OrderedInclude i = new OrderedInclude();
+ orderedIncludes.add(i);
+ return i;
+ }
+
+ public static class OrderedInclude {
+ private String m_name;
+ public OrderedInclude() {}
+ public void setName(String name) {
+ m_name = name;
+ }
+ public String getName() {
+ return m_name;
+ }
+ }
+
+ private String[] findFiles(File dir, String pattern) {
+ List<String> found = new ArrayList<String>();
+ findFiles(dir, "", pattern, found);
+ return found.toArray(new String[found.size()]);
+ }
+
+ private void findFiles(File base, String dir, String pattern, List<String> files) {
+ File[] entries = new File(base, dir).listFiles();
+ for (File f : entries) {
+ if (f.isDirectory()) {
+ String newDir = dir.equals("") ? f.getName() : dir + File.separator + f.getName();
+ findFiles(base, newDir, pattern, files);
+ }
+ else if (f.isFile()) {
+ File df = new File(dir, f.getName());
+ if (df.toString().matches(pattern)) {
+ files.add(df.toString());
+ }
+ }
+ }
+ }
+
+ public void execute() throws BuildException {
+ if (m_dir == null) {
+ throw new BuildException("dir must be specified");
+ }
+ if (m_name == null) {
+ throw new BuildException("name must be specified");
+ }
+ if (m_version == null) {
+ throw new BuildException("version must be specified");
+ }
+ if (m_destination == null) {
+ throw new BuildException("destination must be specified");
+ }
+ log("dir = " + m_dir, Project.MSG_DEBUG);
+
+ DirectoryScanner ds = getDirectoryScanner(m_dir);
+ String[] unorderedIncludes = ds.getIncludedFiles();
+ List<String> files = new ArrayList<String>();
+ for (int i = 0; i < orderedIncludes.size(); i++) {
+ String pattern = orderedIncludes.get(i).getName();
+ String[] filez2 = findFiles(m_dir, pattern);
+ for (String f : filez2) {
+ files.add(f);
+ }
+ }
+ for (int i = 0; i < unorderedIncludes.length; i++) {
+ if (!files.contains(unorderedIncludes[i])) {
+ files.add(unorderedIncludes[i]);
+ }
+ }
+
+ for (String file : files) {
+ log("Found file: " + file);
+ }
+
+ try {
+ DeploymentPackageBuilder dp = DeploymentPackageBuilder.createDeploymentPackage(m_name, m_version);
+ for (String file : files) {
+ dp.addBundle(new URL("file://" + m_dir.getAbsolutePath() + "/" + file));
+ }
+ dp.generate(new FileOutputStream(m_destination));
+ }
+ catch (Exception e) {
+ throw new BuildException("Error building deployment package: " + e.getMessage(), e);
+ }
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/.classpath
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/.classpath?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/.classpath (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/.classpath Thu Jul 5 12:09:30 2012
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/.project
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/.project?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/.project (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/.project Thu Jul 5 12:09:30 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.authentication.api</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/bnd.bnd?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/bnd.bnd (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/bnd.bnd Thu Jul 5 12:09:30 2012
@@ -0,0 +1,2 @@
+-buildpath: osgi.cmpn
+Export-Package: org.apache.ace.authentication.api
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/build.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/build.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/build.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+ <import file="../cnf/build.xml"/>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/pom.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/pom.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/pom.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/pom.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>ace-pom</artifactId>
+ <version>0.8.1-SNAPSHOT</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.ace.authentication.api</artifactId>
+
+ <name>Apache ACE :: Authentication :: API</name>
+ <description>Provides the API for the authentication service.</description>
+ <packaging>bundle</packaging>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-authentication-api</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-authentication-api</developerConnection>
+ <url>http://svn.apache.org/repos/asf/ace/trunk/ace-authentication-api</url>
+ </scm>
+
+ <properties>
+ <import.package>
+ org.osgi.service.useradmin
+ </import.package>
+ <export.package>
+ org.apache.ace.authentication.api;version=${project.version}
+ </export.package>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ </dependencies>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationProcessor.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationProcessor.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationProcessor.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationProcessor.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authentication.api;
+
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * Provides a pluggable authentication processor, responsible for the actual authentication of a
+ * user based on given context information.
+ * <p>
+ * When multiple authentication processors are implemented and used for the authentication process,
+ * an order in which they should be used is determined based on their <em>service ranking</em>.
+ * </p>
+ */
+public interface AuthenticationProcessor {
+
+ /**
+ * Returns whether or not this authentication processor can handle the given context
+ * information.
+ * <p>
+ * NOTE: this method does not need to perform the actual authentication!
+ * </p>
+ * <p>
+ * For example, for an implementation that authenticates a user based on its username
+ * and password might check whether the given context information consists of two
+ * strings.
+ * </p>
+ *
+ * @param context the context information to check, should never be <code>null</code> or an
+ * empty array.
+ * @return <code>true</code> if this authentication processor can handle the given context
+ * information, <code>false</code> otherwise.
+ * @throws IllegalArgumentException in case the given context was <code>null</code> or an empty array;
+ * @throws NullPointerException in case the given array contains <code>null</code> as element(s).
+ */
+ boolean canHandle(Object... context);
+
+ /**
+ * Authenticates a user based on the given context information.
+ *
+ * @param userAdmin the user admin service, to use for verifying/retrieving user information,
+ * cannot be <code>null</code>;
+ * @param context the context information to authenticate the user with, should never be
+ * <code>null</code> or an empty array.
+ * @return the authenticated user, or <code>null</code> if authentication failed.
+ * @throws IllegalArgumentException in case the given context was <code>null</code> or an empty array;
+ * @throws NullPointerException in case the given array contains <code>null</code> as element(s).
+ */
+ User authenticate(UserAdmin userAdmin, Object... context);
+}
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationService.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationService.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationService.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/AuthenticationService.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authentication.api;
+
+import org.osgi.service.useradmin.User;
+
+/**
+ * Provides a generic and pluggable authentication service.
+ * <p>
+ * This service provides the front end to all services that wish to authenticate a user. In short,
+ * this service will look up all available {@link AuthenticationProcessor}s and use them to perform
+ * the actual authentication.
+ * </p>
+ *
+ * @see AuthenticationProcessor
+ */
+public interface AuthenticationService {
+
+ /**
+ * Authenticates a user based on the given context information.
+ * <p>
+ * The context information can be any kind of object, hence it is not exactly typed. As this
+ * service is pluggable, it is up to the authentication processors to interpret the context
+ * information.
+ * </p>
+ * <p>
+ * Implementations can decide on the strategy of authentication, whether all participating
+ * authentication processors <b>must</b> or <b>may</b> match.<br/>
+ * If multiple authentication processors are found, they <b>must</b> be ordered on their
+ * <em>service.ranking</em> property. The one with the higest service ranking is used first,
+ * and so on.
+ * </p>
+ *
+ * @param context the context information, cannot be <code>null</code> or an empty array.
+ * @return an authenticated {@link User}, or <code>null</code> if authentication failed
+ * (or otherwise was not possible).
+ * @throws IllegalArgumentException in case the given context was <code>null</code> or an empty array;
+ * @throws NullPointerException in case the given array contains <code>null</code> as element(s).
+ */
+ User authenticate(Object... context);
+}
Added: ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/packageinfo
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/packageinfo?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/packageinfo (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication.api/src/org/apache/ace/authentication/api/packageinfo Thu Jul 5 12:09:30 2012
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.authentication/.classpath
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/.classpath?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/.classpath (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/.classpath Thu Jul 5 12:09:30 2012
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" output="bin_test" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/sandbox/marrs/org.apache.ace.authentication/.project
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/.project?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/.project (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/.project Thu Jul 5 12:09:30 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.authentication</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added: ace/sandbox/marrs/org.apache.ace.authentication/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/bnd.bnd?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/bnd.bnd (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/bnd.bnd Thu Jul 5 12:09:30 2012
@@ -0,0 +1,8 @@
+-buildpath: org.apache.ace.authentication.api;version=latest,\
+ osgi.core,\
+ osgi.cmpn,\
+ org.apache.felix.dependencymanager,\
+ org.mockito.mockito-all,\
+ org.apache.ace.util;version=latest
+Private-Package: org.apache.ace.authentication.impl
+Bundle-Activator: org.apache.ace.authentication.impl.Activator
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.authentication/build.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/build.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/build.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+ <import file="../cnf/build.xml"/>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authentication/pom.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/pom.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/pom.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/pom.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>ace-pom</artifactId>
+ <version>0.8.1-SNAPSHOT</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.ace.authentication</artifactId>
+
+ <name>Apache ACE :: Authentication :: Impl</name>
+ <description>Provides a generic implementation of the authentication service.</description>
+ <packaging>bundle</packaging>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-authentication</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-authentication</developerConnection>
+ <url>http://svn.apache.org/repos/asf/ace/trunk/ace-authentication</url>
+ </scm>
+
+ <properties>
+ <import.package>
+ org.apache.ace.authentication.api;version="[0.8,1.0)",
+ org.apache.felix.dm,
+ org.osgi.framework,
+ org.osgi.service.log,
+ org.osgi.service.useradmin
+ </import.package>
+ <export.package>
+ org.apache.ace.authentication.api;version=${project.version};-split-package:=merge-first;provide:=true
+ </export.package>
+ <private.package>
+ org.apache.ace.authentication.impl
+ </private.package>
+ <bundle.activator>org.apache.ace.authentication.impl.Activator</bundle.activator>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>org.apache.ace.authentication.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>org.apache.ace.util</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/Activator.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/Activator.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/Activator.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authentication.impl;
+
+import org.apache.ace.authentication.api.AuthenticationProcessor;
+import org.apache.ace.authentication.api.AuthenticationService;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * Provides a bundle activator for the {@link AuthenticationServiceImpl}.
+ */
+public class Activator extends DependencyActivatorBase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(BundleContext context, DependencyManager manager) throws Exception {
+// @formatter:off
+ manager.add(createComponent()
+ .setInterface(AuthenticationService.class.getName(), null)
+ .setImplementation(new AuthenticationServiceImpl())
+ .add(createServiceDependency()
+ .setRequired(true)
+ .setService(UserAdmin.class))
+ .add(createServiceDependency()
+ .setRequired(false)
+ .setService(LogService.class))
+ .add(createServiceDependency()
+ .setRequired(false)
+ .setService(AuthenticationProcessor.class)
+ .setCallbacks("addAuthenticationProcessor", "removeAuthenticationProcessor"))
+ );
+// @formatter:on
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+ // Nop
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/AuthenticationServiceImpl.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/AuthenticationServiceImpl.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/AuthenticationServiceImpl.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/src/org/apache/ace/authentication/impl/AuthenticationServiceImpl.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authentication.impl;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.ace.authentication.api.AuthenticationProcessor;
+import org.apache.ace.authentication.api.AuthenticationService;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * Provides a basic implementation for {@link AuthenticationService} that returns the first matching user.
+ */
+public class AuthenticationServiceImpl implements AuthenticationService {
+
+ /**
+ * Provides a small container for {@link AuthenticationProcessor} instances.
+ */
+ private static class AuthenticationProcessorHolder implements Comparable<AuthenticationProcessorHolder> {
+ private final ServiceReference m_serviceRef;
+ private final WeakReference<AuthenticationProcessor> m_processor;
+
+ public AuthenticationProcessorHolder(ServiceReference serviceRef, AuthenticationProcessor processor) {
+ m_serviceRef = serviceRef;
+ m_processor = new WeakReference<AuthenticationProcessor>(processor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(AuthenticationProcessorHolder other) {
+ ServiceReference thatServiceRef = other.m_serviceRef;
+ ServiceReference thisServiceRef = m_serviceRef;
+ // Sort in reverse order so that the highest rankings come first...
+ return thatServiceRef.compareTo(thisServiceRef);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof AuthenticationProcessorHolder)) {
+ return false;
+ }
+ AuthenticationProcessorHolder other = (AuthenticationProcessorHolder) obj;
+ return m_serviceRef.equals(other.m_serviceRef);
+ }
+
+ /**
+ * @return the {@link AuthenticationProcessor}, can be <code>null</code> if it has been GC'd before this method call.
+ */
+ public AuthenticationProcessor getAuthenticationProcessor() {
+ return m_processor.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return m_serviceRef.hashCode() ^ m_processor.hashCode();
+ }
+ }
+
+ private volatile UserAdmin m_userAdmin;
+ private volatile LogService m_log;
+
+ private final List<AuthenticationProcessorHolder> m_processors;
+
+ /**
+ * Creates a new {@link AuthenticationServiceImpl} instance.
+ */
+ public AuthenticationServiceImpl() {
+ m_processors = new ArrayList<AuthenticationServiceImpl.AuthenticationProcessorHolder>();
+ }
+
+ /**
+ * Creates a new {@link AuthenticationServiceImpl} instance.
+ */
+ AuthenticationServiceImpl(LogService log) {
+ m_log = log;
+ m_processors = new ArrayList<AuthenticationServiceImpl.AuthenticationProcessorHolder>();
+ }
+
+ /**
+ * Authenticates a user based on the given context information.
+ * <p>
+ * This implementation returns the first {@link User}-object that is returned by a {@link AuthenticationProcessor} instance that can handle the given context.
+ * </p>
+ */
+ public User authenticate(Object... context) {
+ if (context == null || context.length == 0) {
+ throw new IllegalArgumentException("Invalid context!");
+ }
+
+ User result = null;
+
+ m_log.log(LogService.LOG_DEBUG, "Authenticating user for: " + context);
+
+ final List<AuthenticationProcessor> processors = getProcessors(context);
+
+ int size = processors.size();
+ for (int i = 0; i < size; i++) {
+ result = processors.get(i).authenticate(m_userAdmin, context);
+ if (result != null) {
+ m_log.log(LogService.LOG_DEBUG, "Authenticated user (" + context + ") as: " + result.getName());
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns all applicable {@link AuthenticationProcessor}s for the given context.
+ *
+ * @param context the context for which to return all applicable authentication processors, cannot be <code>null</code> or an empty array.
+ * @return an array of applicable authentication processors, never <code>null</code>.
+ */
+ final List<AuthenticationProcessor> getProcessors(Object... context) {
+ final List<AuthenticationProcessorHolder> processors;
+ synchronized (m_processors) {
+ processors = new ArrayList<AuthenticationProcessorHolder>(m_processors);
+ }
+ // Sort on service ranking...
+ Collections.sort(processors);
+
+ int size = processors.size();
+
+ List<AuthenticationProcessor> result = new ArrayList<AuthenticationProcessor>(size);
+ for (int i = 0; i < size; i++) {
+ AuthenticationProcessor authenticationProcessor = processors.get(i).getAuthenticationProcessor();
+ // Can be null if it is already GC'd for some reason...
+ if ((authenticationProcessor != null) && authenticationProcessor.canHandle(context)) {
+ result.add(authenticationProcessor);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Called by {@link DependencyManager} upon adding a new {@link AuthenticationProcessor}.
+ *
+ * @param serviceRef the service reference of the authentication processor to add;
+ * @param processor the authentication processor to add.
+ */
+ protected void addAuthenticationProcessor(ServiceReference serviceRef, AuthenticationProcessor processor) {
+ synchronized (m_processors) {
+ m_processors.add(new AuthenticationProcessorHolder(serviceRef, processor));
+ }
+ }
+
+ /**
+ * Called by {@link DependencyManager} upon removal of a {@link AuthenticationProcessor}.
+ *
+ * @param serviceRef the service reference of the authentication processor to remove;
+ * @param processor the authentication processor to remove.
+ */
+ protected void removeAuthenticationProcessor(ServiceReference serviceRef, AuthenticationProcessor processor) {
+ synchronized (m_processors) {
+ m_processors.remove(new AuthenticationProcessorHolder(serviceRef, processor));
+ }
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authentication/test/org/apache/ace/authentication/impl/AuthenticationServiceImplTest.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authentication/test/org/apache/ace/authentication/impl/AuthenticationServiceImplTest.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authentication/test/org/apache/ace/authentication/impl/AuthenticationServiceImplTest.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authentication/test/org/apache/ace/authentication/impl/AuthenticationServiceImplTest.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authentication.impl;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.ace.authentication.api.AuthenticationProcessor;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Test cases for {@link AuthenticationServiceImpl}.
+ */
+public class AuthenticationServiceImplTest {
+
+ private LogService m_log;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() {
+ m_log = mock(LogService.class);
+ }
+
+ /**
+ * Tests that an exception is thrown if a null context is given.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class)
+ public void testAuthenticateFailsWithNullContext() {
+ new AuthenticationServiceImpl().authenticate((Object[]) null);
+ }
+
+ /**
+ * Tests that without any authentication processors, no authentication will take place.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateFailsWithoutAuthProcessors() {
+ assert createAuthenticationService().authenticate("foo", "bar") == null;
+ }
+
+ /**
+ * Tests that an exception is thrown if no context is given.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class)
+ public void testAuthenticateFailsWithoutContext() {
+ new AuthenticationServiceImpl().authenticate();
+ }
+
+ /**
+ * Tests that with a single authentication processors, no authentication will take place if it is the wrong context.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateFailsWithSingleAuthProcessorAndWrongContext() {
+ AuthenticationServiceImpl authService = createAuthenticationService();
+
+ AuthenticationProcessor authProc = mock(AuthenticationProcessor.class);
+ when(authProc.canHandle(anyString())).thenReturn(Boolean.TRUE);
+
+ registerAuthProcessor(authService, authProc);
+
+ assert authService.authenticate("foo", "bar") == null;
+ }
+
+ /**
+ * Tests that with multiple authentication processors, authentication will take place if it is given the correct context.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateSucceedsWithMultipleAuthProcessors() {
+ Date now = new Date();
+
+ User user1 = mock(User.class);
+ User user2 = mock(User.class);
+
+ AuthenticationProcessor authProc1 = mock(AuthenticationProcessor.class);
+ when(authProc1.canHandle(any())).thenAnswer(new Answer<Boolean>() {
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ return (args.length == 1 && args[0] instanceof Date);
+ }
+ });
+ when(authProc1.authenticate(Mockito.<UserAdmin>any(), eq(now))).thenReturn(user1);
+
+ AuthenticationProcessor authProc2 = mock(AuthenticationProcessor.class);
+ when(authProc2.canHandle(anyString())).thenAnswer(new Answer<Boolean>() {
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ return (args.length == 1 && args[0] instanceof String);
+ }
+ });
+ when(authProc2.authenticate(Mockito.<UserAdmin>any(), eq("foo"))).thenReturn(user2);
+
+ AuthenticationServiceImpl authService = createAuthenticationService();
+
+ registerAuthProcessor(authService, authProc1);
+ registerAuthProcessor(authService, authProc2);
+
+ User result = authService.authenticate("foo");
+ assert result != null;
+ assert user2 == result;
+
+ result = authService.authenticate(now);
+ assert result != null;
+ assert user1 == result;
+ }
+
+ /**
+ * Tests that with a single authentication processors, authentication will take place if it is given the correct context.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateSucceedsWithSingleAuthProcessorAndCorrectContext() {
+ AuthenticationServiceImpl authService = createAuthenticationService();
+
+ User user = mock(User.class);
+
+ AuthenticationProcessor authProc = mock(AuthenticationProcessor.class);
+ when(authProc.canHandle(anyString())).thenReturn(Boolean.TRUE);
+ when(authProc.authenticate(Mockito.<UserAdmin>any(), eq("foo"))).thenReturn(user);
+
+ registerAuthProcessor(authService, authProc);
+
+ assert authService.authenticate("foo") != null;
+ }
+
+ /**
+ * Tests that with multiple authentication processors, the correct ones are returned based on the given context.
+ */
+ @Test(groups = { UNIT })
+ public void testGetProcessorsSelectsCorrectProcessorsBasedOnContext() {
+ Date now = new Date();
+
+ User user1 = mock(User.class);
+ User user2 = mock(User.class);
+
+ AuthenticationProcessor authProc1 = mock(AuthenticationProcessor.class);
+ when(authProc1.canHandle(any())).thenAnswer(new Answer<Boolean>() {
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ return (args.length == 1 && args[0] instanceof Date);
+ }
+ });
+ when(authProc1.authenticate(Mockito.<UserAdmin>any(), eq(now))).thenReturn(user1);
+
+ AuthenticationProcessor authProc2 = mock(AuthenticationProcessor.class);
+ when(authProc2.canHandle(anyString())).thenAnswer(new Answer<Boolean>() {
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ return (args.length == 1 && args[0] instanceof String);
+ }
+ });
+ when(authProc2.authenticate(Mockito.<UserAdmin>any(), eq("foo"))).thenReturn(user2);
+
+ AuthenticationServiceImpl authService = createAuthenticationService();
+
+ registerAuthProcessor(authService, authProc1);
+ registerAuthProcessor(authService, authProc2);
+
+ List<AuthenticationProcessor> processors = authService.getProcessors("foo");
+ assert processors != null;
+ assert 1 == processors.size();
+
+ processors = authService.getProcessors(now);
+ assert processors != null;
+ assert 1 == processors.size();
+
+ processors = authService.getProcessors(new Object());
+ assert processors != null;
+ assert processors.isEmpty();
+ }
+
+ /**
+ * @return a new {@link AuthenticationServiceImpl} instance, never <code>null</code>.
+ */
+ private AuthenticationServiceImpl createAuthenticationService() {
+ return new AuthenticationServiceImpl(m_log);
+ }
+
+ /**
+ * @param authService
+ * @param authProcessor
+ */
+ private void registerAuthProcessor(AuthenticationServiceImpl authService, AuthenticationProcessor authProcessor) {
+ ServiceReference sr = mock(ServiceReference.class);
+ authService.addAuthenticationProcessor(sr, authProcessor);
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.classpath
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.classpath?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.classpath (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.classpath Thu Jul 5 12:09:30 2012
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" output="bin_test" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.project
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.project?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.project (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/.project Thu Jul 5 12:09:30 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.authenticationprocessor.basicauth</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/bnd.bnd?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/bnd.bnd (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/bnd.bnd Thu Jul 5 12:09:30 2012
@@ -0,0 +1,12 @@
+-buildpath: osgi.core,\
+ osgi.cmpn,\
+ org.apache.ace.util;version=latest,\
+ org.apache.ace.authentication.api;version=latest,\
+ javax.servlet,\
+ org.apache.felix.dependencymanager,\
+ ../cnf/lib/commons-codec-1.4.jar;version=file,\
+ org.mockito.mockito-all
+Private-Package: org.apache.ace.authenticationprocessor.basicauth,\
+ org.apache.commons.codec,\
+ org.apache.commons.codec.binary
+Bundle-Activator: org.apache.ace.authenticationprocessor.basicauth.Activator
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/build.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/build.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/build.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+ <import file="../cnf/build.xml"/>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/pom.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/pom.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/pom.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/pom.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>ace-pom</artifactId>
+ <version>0.8.1-SNAPSHOT</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.ace.authenticationprocessor.basicauth</artifactId>
+
+ <name>Apache ACE :: Authentication :: HTTP Basic Auth</name>
+ <description>Provides an authentication processor that can handle HTTP basic authentication.</description>
+ <packaging>bundle</packaging>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-authentication-basicauth</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-authentication-basicauth</developerConnection>
+ <url>http://svn.apache.org/repos/asf/ace/trunk/ace-authentication-basicauth</url>
+ </scm>
+
+ <properties>
+ <import.package>
+ org.apache.ace.authentication.api,
+ javax.servlet.http,
+ org.apache.felix.dm,
+ org.osgi.framework,
+ org.osgi.service.cm,
+ org.osgi.service.useradmin
+ </import.package>
+ <private.package>
+ org.apache.ace.authenticationprocessor.basicauth,
+ org.apache.commons.codec,
+ org.apache.commons.codec.binary
+ </private.package>
+ <bundle.activator>org.apache.ace.authenticationprocessor.basicauth.Activator</bundle.activator>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>org.apache.ace.authentication.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ace</groupId>
+ <artifactId>org.apache.ace.util</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/Activator.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/Activator.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/Activator.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/Activator.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authenticationprocessor.basicauth;
+
+import java.util.Properties;
+
+import org.apache.ace.authentication.api.AuthenticationProcessor;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ * Provides a bundle activator for the {@link BasicHttpAuthenticationProcessor}.
+ */
+public class Activator extends DependencyActivatorBase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(BundleContext context, DependencyManager manager) throws Exception {
+ Properties props = new Properties();
+ props.put(Constants.SERVICE_PID, BasicHttpAuthenticationProcessor.PID);
+
+// @formatter:off
+ manager.add(createComponent()
+ .setInterface(new String[]{ AuthenticationProcessor.class.getName(), ManagedService.class.getName() }, props)
+ .setImplementation(new BasicHttpAuthenticationProcessor())
+ );
+// @formatter:on
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+ // Nop
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessor.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessor.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessor.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/src/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessor.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authenticationprocessor.basicauth;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Dictionary;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.ace.authentication.api.AuthenticationProcessor;
+import org.apache.commons.codec.binary.Base64;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * Provides an {@link AuthenticationProcessor} that implements basic HTTP authentication and looks
+ * up a user in the {@link UserAdmin} service using (by default, can be configured otherwise) the
+ * keys "username" and "password".
+ */
+public class BasicHttpAuthenticationProcessor implements AuthenticationProcessor, ManagedService {
+
+ public static final String PID = "org.apache.ace.authenticationprocessor.basicauth";
+
+ /** The name of the HTTP-header used for HTTP authentication. */
+ static final String AUTHORIZATION_HEADER = "Authorization";
+
+ static final String PROPERTY_KEY_USERNAME = "key.username";
+ static final String PROPERTY_KEY_PASSWORD = "key.password";
+
+ private static final String DEFAULT_PROPERTY_KEY_USERNAME = "username";
+ private static final String DEFAULT_PROPERTY_KEY_PASSWORD = "password";
+
+ private volatile String m_keyUsername = DEFAULT_PROPERTY_KEY_USERNAME;
+ private volatile String m_keyPassword = DEFAULT_PROPERTY_KEY_PASSWORD;
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canHandle(Object... context) {
+ if (context == null || context.length == 0) {
+ throw new IllegalArgumentException("Invalid context!");
+ }
+
+ return (context[0] instanceof HttpServletRequest);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public User authenticate(UserAdmin userAdmin, Object... context) {
+ final HttpServletRequest request = (HttpServletRequest) context[0];
+
+ String header = request.getHeader(AUTHORIZATION_HEADER);
+ if (header == null || header.length() < 6) {
+ // No authorization header obtained; cannot authorize...
+ return null;
+ }
+
+ // Form = 'Basic ' + base64 encoded credentials
+ String packedCredentials = decodeBase64(header);
+ if (packedCredentials == null) {
+ // No credentials obtained; cannot authenticate...
+ return null;
+ }
+
+ // Form = <user>:<password>
+ String[] credentials = packedCredentials.split(":");
+ if (credentials.length != 2) {
+ // A colon should always be present!
+ return null;
+ }
+
+ User user = getUser(userAdmin, credentials[0]);
+ if (user == null || !user.hasCredential(m_keyPassword, credentials[1])) {
+ // Invalid/unknown user!
+ return null;
+ }
+
+ return user;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void updated(Dictionary dictionary) throws ConfigurationException {
+ if (dictionary != null) {
+ String keyUsername = (String) dictionary.get(PROPERTY_KEY_USERNAME);
+ if (keyUsername == null || "".equals(keyUsername.trim())) {
+ throw new ConfigurationException(PROPERTY_KEY_USERNAME, "Missing property");
+ }
+
+ String keyPassword = (String) dictionary.get(PROPERTY_KEY_PASSWORD);
+ if (keyPassword == null || "".equals(keyPassword.trim())) {
+ throw new ConfigurationException(PROPERTY_KEY_PASSWORD, "Missing property");
+ }
+
+ m_keyUsername = keyUsername;
+ m_keyPassword = keyPassword;
+ }
+ else {
+ m_keyUsername = DEFAULT_PROPERTY_KEY_USERNAME;
+ m_keyPassword = DEFAULT_PROPERTY_KEY_PASSWORD;
+ }
+ }
+
+ /**
+ * Decodes a given base64-encoded string.
+ *
+ * @param header the base64 encoded header to decode.
+ * @return the base64 decoded string, can be <code>null</code>.
+ */
+ private String decodeBase64(String header) {
+ byte[] array = Base64.decodeBase64(header.substring(6));
+ if (array == null) {
+ return null;
+ }
+
+ try {
+ return new String(array, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e) {
+ // Should never occur, as Java is always capable of handling UTF-8!
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Searches for a user with a given name.
+ * <p>
+ * This method first looks whether there's a user with the property
+ * "m_keyUsername" that matches the given username, if not found, it will
+ * try to retrieve a role with the given name.
+ * </p>
+ *
+ * @param userAdmin the {@link UserAdmin} service to get users from;
+ * @param name the name of the user to retrieve.
+ * @return a {@link User}, can be <code>null</code> if no such user is found.
+ */
+ private User getUser(UserAdmin userAdmin, String name) {
+ Role user = null;
+ if (m_keyUsername != null) {
+ user = userAdmin.getUser(m_keyUsername, name);
+ }
+ if (user == null) {
+ user = userAdmin.getRole(name);
+ }
+ return (user instanceof User) ? (User) user : null;
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/test/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessorTest.java
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/test/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessorTest.java?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/test/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessorTest.java (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.basicauth/test/org/apache/ace/authenticationprocessor/basicauth/BasicHttpAuthenticationProcessorTest.java Thu Jul 5 12:09:30 2012
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ace.authenticationprocessor.basicauth;
+
+import static org.apache.ace.authenticationprocessor.basicauth.BasicHttpAuthenticationProcessor.AUTHORIZATION_HEADER;
+import static org.apache.ace.authenticationprocessor.basicauth.BasicHttpAuthenticationProcessor.PROPERTY_KEY_PASSWORD;
+import static org.apache.ace.authenticationprocessor.basicauth.BasicHttpAuthenticationProcessor.PROPERTY_KEY_USERNAME;
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.binary.Base64;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Test cases for {@link BasicHttpAuthenticationProcessor}.
+ */
+public class BasicHttpAuthenticationProcessorTest {
+
+ private UserAdmin m_userAdmin;
+ private HttpServletRequest m_servletRequest;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() {
+ m_userAdmin = mock(UserAdmin.class);
+ m_servletRequest = mock(HttpServletRequest.class);
+ }
+
+ /**
+ * Tests that a null authentication header will yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateEmptyAuthenticationHeaderYieldsNull() {
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result == null : "Expected no result!";
+ }
+
+ /**
+ * Tests that an invalid authentication header will yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateInvalidAuthenticationHeaderYieldsNull() {
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn(createAuthHeaderValue("bob"));
+
+ User user = mock(User.class);
+ when(user.getName()).thenReturn("bob");
+ when(user.hasCredential(eq("password"), eq("secret"))).thenReturn(Boolean.TRUE);
+
+ when(m_userAdmin.getUser(eq("username"), eq("bob"))).thenReturn(user);
+
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result == null : "Expected no result!";
+ }
+
+ /**
+ * Tests that a known user with an invalid password will yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateKnownUserWithInvalidPasswordYieldsNull() {
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn(createAuthHeaderValue("bob:secret"));
+
+ User user = mock(User.class);
+ when(user.getName()).thenReturn("bob");
+ when(user.hasCredential(eq("password"), eq("otherSecret"))).thenReturn(Boolean.TRUE);
+
+ when(m_userAdmin.getUser(eq("username"), eq("bob"))).thenReturn(user);
+
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result == null : "Expected no result!";
+ }
+
+ /**
+ * Tests that a known user will not yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateKnownUserYieldsValidResult() {
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn(createAuthHeaderValue("bob:secret"));
+
+ User user = mock(User.class);
+ when(user.getName()).thenReturn("bob");
+ when(user.hasCredential(eq("password"), eq("secret"))).thenReturn(Boolean.TRUE);
+
+ when(m_userAdmin.getUser(eq("username"), eq("bob"))).thenReturn(user);
+
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result != null : "Expected a valid user to be returned!";
+
+ assert "bob".equals(user.getName()) : "Expected user bob to be returned!";
+ }
+
+ /**
+ * Tests that a non Base64 authentication header will yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateNonBase64AuthenticationHeaderYieldsNull() {
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn("foo");
+
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result == null : "Expected no result!";
+ }
+
+ /**
+ * Tests that a class cast exception is thrown for invalid context when calling authenticate.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = ClassCastException.class)
+ public void testAuthenticateThrowsClassCastForInvalidContext() {
+ new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, new Object());
+ }
+
+ /**
+ * Tests that an unknown user will yield null.
+ */
+ @Test(groups = { UNIT })
+ public void testAuthenticateUnknownUserYieldsNull() {
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn(createAuthHeaderValue("alice:secret"));
+
+ User result = new BasicHttpAuthenticationProcessor().authenticate(m_userAdmin, m_servletRequest);
+ assert result == null : "Expected no result!";
+ }
+
+ /**
+ * Tests that canHandle yields false for any object other than {@link HttpServletRequest}.
+ */
+ @Test(groups = { UNIT })
+ public void testCanHandleDoesAcceptServletRequest() {
+ assert new BasicHttpAuthenticationProcessor().canHandle(mock(HttpServletRequest.class));
+ }
+
+ /**
+ * Tests that canHandle throws an {@link IllegalArgumentException} for an empty context.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class)
+ public void testCanHandleDoesNotAcceptEmptyArray() {
+ new BasicHttpAuthenticationProcessor().canHandle(new Object[0]);
+ }
+
+ /**
+ * Tests that canHandle throws an {@link IllegalArgumentException} for a null context.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class)
+ public void testCanHandleDoesNotAcceptNull() {
+ new BasicHttpAuthenticationProcessor().canHandle((Object[]) null);
+ }
+
+ /**
+ * Tests that canHandle yields false for any object other than {@link HttpServletRequest}.
+ */
+ @Test(groups = { UNIT })
+ public void testCanHandleDoesNotAcceptUnhandledContext() {
+ assert new BasicHttpAuthenticationProcessor().canHandle(new Object()) == false;
+ }
+
+ /**
+ * Tests that updated throws an exception for missing "key.username" property.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = ConfigurationException.class)
+ public void testUpdatedDoesNotAcceptEmptyKeyUsername() throws ConfigurationException {
+ Properties props = new Properties();
+ props.put(PROPERTY_KEY_USERNAME, "");
+ props.put(PROPERTY_KEY_PASSWORD, "foo");
+
+ new BasicHttpAuthenticationProcessor().updated(props);
+ }
+
+ /**
+ * Tests that updated throws an exception for missing "key.username" property.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = ConfigurationException.class)
+ public void testUpdatedDoesNotAcceptMissingKeyUsername() throws ConfigurationException {
+ Properties props = new Properties();
+ props.put(PROPERTY_KEY_PASSWORD, "foo");
+
+ new BasicHttpAuthenticationProcessor().updated(props);
+ }
+
+ /**
+ * Tests that updated throws an exception for missing "key.password" property.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = ConfigurationException.class)
+ public void testUpdatedDoesNotAcceptMissingKeyPassword() throws ConfigurationException {
+ Properties props = new Properties();
+ props.put(PROPERTY_KEY_USERNAME, "foo");
+
+ new BasicHttpAuthenticationProcessor().updated(props);
+ }
+
+ /**
+ * Tests that updated throws an exception for missing "key.password" property.
+ */
+ @Test(groups = { UNIT }, expectedExceptions = ConfigurationException.class)
+ public void testUpdatedDoesNotAcceptEmptyKeyPassword() throws ConfigurationException {
+ Properties props = new Properties();
+ props.put(PROPERTY_KEY_USERNAME, "foo");
+ props.put(PROPERTY_KEY_PASSWORD, "");
+
+ new BasicHttpAuthenticationProcessor().updated(props);
+ }
+
+ /**
+ * Tests that updated does not throw an exception for a correct configuration.
+ */
+ @Test(groups = { UNIT })
+ public void testUpdatedDoesAcceptCorrectProperties() throws ConfigurationException {
+ final String keyUsername = "foo";
+ final String keyPassword = "bar";
+
+ Properties props = new Properties();
+ props.put(PROPERTY_KEY_USERNAME, keyUsername);
+ props.put(PROPERTY_KEY_PASSWORD, keyPassword);
+
+ BasicHttpAuthenticationProcessor processor = new BasicHttpAuthenticationProcessor();
+
+ processor.updated(props);
+
+ // Test whether we can use the new properties...
+ when(m_servletRequest.getHeader(AUTHORIZATION_HEADER)).thenReturn(createAuthHeaderValue("bob:secret"));
+
+ User user = mock(User.class);
+ when(user.getName()).thenReturn("bob");
+ when(user.hasCredential(eq(keyPassword), eq("secret"))).thenReturn(Boolean.TRUE);
+
+ when(m_userAdmin.getUser(eq(keyUsername), eq("bob"))).thenReturn(user);
+
+ User result = processor.authenticate(m_userAdmin, m_servletRequest);
+ assert result != null : "Expected a valid user to be returned!";
+
+ assert "bob".equals(user.getName()) : "Expected user bob to be returned!";
+ }
+
+
+ /**
+ * @return the basic authentication header, never <code>null</code>.
+ */
+ private String createAuthHeaderValue(String credentials) {
+ return "Basic " + new Base64().encodeToString(credentials.getBytes());
+ }
+}
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.classpath
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.classpath?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.classpath (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.classpath Thu Jul 5 12:09:30 2012
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" output="bin_test" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.project
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.project?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.project (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/.project Thu Jul 5 12:09:30 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.authenticationprocessor.clientcert</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/bnd.bnd?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/bnd.bnd (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/bnd.bnd Thu Jul 5 12:09:30 2012
@@ -0,0 +1,10 @@
+-buildpath: osgi.core,\
+ osgi.cmpn,\
+ javax.servlet,\
+ org.apache.ace.authentication.api;version=latest,\
+ org.apache.ace.util;version=latest,\
+ ../cnf/lib/bcprov-jdk14-140.jar;version=file,\
+ org.apache.felix.dependencymanager,\
+ org.mockito.mockito-all
+Private-Package: org.apache.ace.authenticationprocessor.clientcert
+Bundle-Activator: org.apache.ace.authenticationprocessor.clientcert.Activator
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/build.xml
URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/build.xml?rev=1357570&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.authenticationprocessor.clientcert/build.xml Thu Jul 5 12:09:30 2012
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+ <import file="../cnf/build.xml"/>
+</project>