--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project-shared-configuration>\r
+ <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->\r
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">\r
+ <!--
+Properties that influence various parts of the IDE, especially code formatting and the like.
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->\r
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>default</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>8</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>\r
+ <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>\r
+ </properties>\r
+</project-shared-configuration>\r
--- /dev/null
+<?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/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>org.collectionspace.services.main</artifactId>
+ <groupId>org.collectionspace.services</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.collectionspace.services</groupId>
+ <artifactId>org.collectionspace.services.authentication</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <name>services.authentication</name>
+
+ <properties>
+ <jboss.version>4.2.3.GA</jboss.version>
+ <jboss.ejb.version>3.0</jboss.ejb.version>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+
+ <!-- utilities -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+
+ <!-- javax -->
+ <dependency>
+ <groupId>javax.security</groupId>
+ <artifactId>jaas</artifactId>
+ <version>1.0.01</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>jbosssx</artifactId>
+ <version>4.2.3.GA</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>cspace-services-authn</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+/**\r
+ * Copyright 2009 University of California at Berkeley\r
+ */\r
+package org.collectionspace.authentication;\r
+\r
+import java.lang.reflect.Constructor;\r
+import java.security.Principal;\r
+import java.security.acl.Group;\r
+import java.sql.Connection;\r
+import java.sql.DriverManager;\r
+import java.sql.PreparedStatement;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+\r
+import java.util.HashMap;\r
+import javax.naming.InitialContext;\r
+import javax.security.auth.login.FailedLoginException;\r
+import javax.security.auth.login.LoginException;\r
+import org.jboss.security.SimpleGroup;\r
+import org.jboss.security.SimplePrincipal;\r
+import org.jboss.security.auth.spi.DatabaseServerLoginModule;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class CSpaceDBLoginModule extends DatabaseServerLoginModule {\r
+\r
+ //disabled due to classloading problem\r
+ //private Logger logger = LoggerFactory.getLogger(CSpaceDBLoginModule.class);\r
+ private boolean log = true;\r
+\r
+ private void log(String str) {\r
+ System.out.println(str);\r
+ }\r
+\r
+ protected String getUsersPassword() throws LoginException {\r
+ \r
+ String username = getUsername();\r
+ String password = null;\r
+ Connection conn = null;\r
+ PreparedStatement ps = null;\r
+ ResultSet rs = null;\r
+ InitialContext ctx = null;\r
+ try{\r
+// Properties env = new Properties();\r
+// env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");\r
+// env.setProperty(Context.PROVIDER_URL, "jnp://localhost:1199/");\r
+// env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");\r
+// ctx = new InitialContext(env);\r
+//// ctx = new InitialContext();\r
+// DataSource ds = (DataSource) ctx.lookup(dsJndiName);\r
+// if(ds == null){\r
+// throw new IllegalArgumentException("datasource not found: " + dsJndiName);\r
+// }\r
+// conn = ds.getConnection();\r
+ Class.forName("com.mysql.jdbc.Driver");\r
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cspace", "test", "test");\r
+\r
+ // Get the password\r
+ if(log){\r
+ log("Excuting query: " + principalsQuery + ", with username: " + username);\r
+ }\r
+ ps = conn.prepareStatement(principalsQuery);\r
+ ps.setString(1, username);\r
+ rs = ps.executeQuery();\r
+ if(rs.next() == false){\r
+ if(log){\r
+ log("Query returned no matches from db");\r
+ }\r
+ throw new FailedLoginException("No matching username found");\r
+ }\r
+\r
+ password = rs.getString(1);\r
+ password = convertRawPassword(password);\r
+ if(log){\r
+ log("Obtained user password");\r
+ }\r
+// }catch(NamingException ex){\r
+// LoginException le = new LoginException("Error looking up DataSource from: " + dsJndiName);\r
+// le.initCause(ex);\r
+// throw le;\r
+ }catch(SQLException ex){\r
+ LoginException le = new LoginException("Query failed");\r
+ le.initCause(ex);\r
+ throw le;\r
+ }catch(Exception ex){\r
+ LoginException le = new LoginException("Unknown Exception");\r
+ le.initCause(ex);\r
+ throw le;\r
+ }finally{\r
+ if(rs != null){\r
+ try{\r
+ rs.close();\r
+ }catch(SQLException e){\r
+ }\r
+ }\r
+ if(ps != null){\r
+ try{\r
+ ps.close();\r
+ }catch(SQLException e){\r
+ }\r
+ }\r
+ if(conn != null){\r
+ try{\r
+ conn.close();\r
+ }catch(SQLException ex){\r
+ }\r
+ }\r
+ if(ctx != null){\r
+ try{\r
+ ctx.close();\r
+ }catch(Exception e){\r
+ }\r
+ }\r
+ }\r
+ return password;\r
+ }\r
+\r
+ /** Execute the rolesQuery against the dsJndiName to obtain the roles for\r
+ the authenticated user.\r
+\r
+ @return Group[] containing the sets of roles\r
+ */\r
+ protected Group[] getRoleSets() throws LoginException {\r
+ String username = getUsername();\r
+ if(log){\r
+ log("getRoleSets using rolesQuery: " + rolesQuery + ", username: " + username);\r
+ }\r
+\r
+ Connection conn = null;\r
+ HashMap setsMap = new HashMap();\r
+ PreparedStatement ps = null;\r
+ ResultSet rs = null;\r
+\r
+ try{\r
+// InitialContext ctx = new InitialContext();\r
+// DataSource ds = (DataSource) ctx.lookup(dsJndiName);\r
+// conn = ds.getConnection();\r
+ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/cspace", "root", "admin");\r
+ // Get the user role names\r
+ if(log){\r
+ log("Excuting query: " + rolesQuery + ", with username: " + username);\r
+ }\r
+\r
+ ps =\r
+ conn.prepareStatement(rolesQuery);\r
+ try{\r
+ ps.setString(1, username);\r
+ }catch(ArrayIndexOutOfBoundsException ignore){\r
+ // The query may not have any parameters so just try it\r
+ }\r
+ rs = ps.executeQuery();\r
+ if(rs.next() == false){\r
+ if(log){\r
+ log("No roles found");\r
+ }\r
+// if(aslm.getUnauthenticatedIdentity() == null){\r
+// throw new FailedLoginException("No matching username found in Roles");\r
+// }\r
+ /* We are running with an unauthenticatedIdentity so create an\r
+ empty Roles set and return.\r
+ */\r
+\r
+ Group[] roleSets = {new SimpleGroup("Roles")};\r
+ return roleSets;\r
+ }\r
+\r
+ do{\r
+ String name = rs.getString(1);\r
+ String groupName = rs.getString(2);\r
+ if(groupName == null || groupName.length() == 0){\r
+ groupName = "Roles";\r
+ }\r
+\r
+ Group group = (Group) setsMap.get(groupName);\r
+ if(group == null){\r
+ group = new SimpleGroup(groupName);\r
+ setsMap.put(groupName, group);\r
+ }\r
+\r
+ try{\r
+// Principal p = aslm.createIdentity(name);\r
+ Principal p = createIdentity(name);\r
+ if(log){\r
+ log("Assign user to role " + name);\r
+ }\r
+\r
+ group.addMember(p);\r
+ }catch(Exception e){\r
+ log("Failed to create principal: " + name + " " + e.toString());\r
+ }\r
+\r
+ }while(rs.next());\r
+ } // catch(NamingException ex)\r
+ // {\r
+ // LoginException le = new LoginException("Error looking up DataSource from: "+dsJndiName);\r
+ // le.initCause(ex);\r
+ // throw le;\r
+ // }\r
+ catch(SQLException ex){\r
+ LoginException le = new LoginException("Query failed");\r
+ le.initCause(ex);\r
+ throw le;\r
+ }finally{\r
+ if(rs != null){\r
+ try{\r
+ rs.close();\r
+ }catch(SQLException e){\r
+ }\r
+ }\r
+ if(ps != null){\r
+ try{\r
+ ps.close();\r
+ }catch(SQLException e){\r
+ }\r
+ }\r
+ if(conn != null){\r
+ try{\r
+ conn.close();\r
+ }catch(Exception ex){\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ Group[] roleSets = new Group[setsMap.size()];\r
+ setsMap.values().toArray(roleSets);\r
+ return roleSets;\r
+ }\r
+\r
+ /** Utility method to create a Principal for the given username. This\r
+ * creates an instance of the principalClassName type if this option was\r
+ * specified using the class constructor matching: ctor(String). If\r
+ * principalClassName was not specified, a SimplePrincipal is created.\r
+ *\r
+ * @param username the name of the principal\r
+ * @return the principal instance\r
+ * @throws java.lang.Exception thrown if the custom principal type cannot be created.\r
+ */\r
+ protected Principal createIdentity(String username)\r
+ throws Exception {\r
+ Principal p = null;\r
+ if(principalClassName == null){\r
+ p = new SimplePrincipal(username);\r
+ }else{\r
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();\r
+ Class clazz = loader.loadClass(principalClassName);\r
+ Class[] ctorSig = {String.class};\r
+ Constructor ctor = clazz.getConstructor(ctorSig);\r
+ Object[] ctorArgs = {username};\r
+ p =\r
+ (Principal) ctor.newInstance(ctorArgs);\r
+ }\r
+\r
+ return p;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2009 University of California at Berkeley
+ Licensed under the Educational Community License (ECL), Version 2.0.
+ You may not use this file except in compliance with this License.
+
+ Document : jboss-login-config.xml
+ Created on : June 19, 2009, 9:58 AM
+ Author :
+ Description:
+ jboss config for JAAS DatabaseServerLoginModule
+-->
+<!--
+copy the following snippet into $JBOSS_HOME/server/cspace/conf/login-config.xml
+copy before the "other" application-policy
+-->
+
+ <application-policy name="cspace">
+ <authentication>
+ <login-module code="org.collectionspace.authentication.CSpaceDBLoginModule"
+ flag="required">
+ <module-option name="dsJndiName">java:/CspaceDS</module-option>
+ <module-option name="hashAlgorithm">SHA-256</module-option>
+ <module-option name="ignorePasswordCase">false</module-option>
+ <module-option name="principalsQuery">
+ select passwd from users where username=?
+ </module-option>
+ <module-option name="rolesQuery">
+ select rolename, 'Roles' from users_roles where username=?
+ </module-option>
+ </login-module>
+ </authentication>
+ </application-policy>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2009 University of California at Berkeley
+ Licensed under the Educational Community License (ECL), Version 2.0.
+ You may not use this file except in compliance with this License.
+
+ Document : jboss-web-security-config.xml
+ Created on : June 19, 2009, 9:58 AM
+ Author :
+ Description:
+ jboss-web.xml snippet for config for JAAS
+-->
+
+<!-- copy the following into jboss-web.xml of cspace-services.war -->
+ <!-- All secure web resources will use this security domain -->
+<security-domain>java:/jaas/cspace</security-domain>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2009 University of California at Berkeley
+ Licensed under the Educational Community License (ECL), Version 2.0.
+ You may not use this file except in compliance with this License.
+
+ Document : web-security-config.xml.xml
+ Created on : June 19, 2009, 10:04 AM
+ Author :
+ Description:
+ web.xml snippet for security configuration
+-->
+<!-- copy the following into web.xml of cspace-services.war -->
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>CollectionSpace Services</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>*</role-name>
+ </auth-constraint>
+
+ <user-data-constraint>
+ <transport-guarantee>NONE</transport-guarantee>
+ </user-data-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>CollectionSpace realm</realm-name>
+ </login-config>
\ No newline at end of file
--- /dev/null
+--\r
+-- Copyright 2009 University of California at Berkeley\r
+-- Licensed under the Educational Community License (ECL), Version 2.0.\r
+-- You may not use this file except in compliance with this License.\r
+--\r
+use cspace;\r
+\r
+DROP TABLE IF EXISTS users;\r
+CREATE TABLE users(username VARCHAR(128) PRIMARY KEY, passwd VARCHAR(128) NOT NULL );\r
+CREATE INDEX username_users on users(username);\r
+\r
+DROP TABLE IF EXISTS roles;\r
+CREATE TABLE roles(rolename VARCHAR(128) PRIMARY KEY, rolegroup VARCHAR(128));\r
+CREATE INDEX rolename_roles on roles(rolename);\r
+\r
+DROP TABLE IF EXISTS users_roles;\r
+CREATE TABLE users_roles(username VARCHAR(128) NOT NULL, rolename VARCHAR(128) NOT NULL);\r
+CREATE INDEX username_users_roles on users_roles(username);
\ No newline at end of file
--- /dev/null
+--\r
+-- Copyright 2009 University of California at Berkeley\r
+-- Licensed under the Educational Community License (ECL), Version 2.0.\r
+-- You may not use this file except in compliance with this License.\r
+--\r
+use cspace;\r
+\r
+insert into users (username, passwd) values ('test', 'test');\r
+insert into users (username, passwd) values ('admin', 'admin');\r
+\r
+insert into roles (rolename, rolegroup) values ('collections_manager', 'collections');\r
+insert into roles (rolename, rolegroup) values ('collections_registrar', 'collections');\r
+\r
+insert into users_roles(username, rolename) values ('test', 'collections_manager');\r
+insert into users_roles(username, rolename) values('admin', 'collections_registrar');
\ No newline at end of file
--- /dev/null
+package org.collectionspace.authentication;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
DROP database IF EXISTS jbossdb;\r
CREATE database jbossdb;\r
\r
+--\r
+-- recreate cspace database\r
+--\r
+DROP database IF EXISTS cspace;\r
+CREATE database cspace;\r
+\r
--\r
-- recreate nuxeo database\r
--\r
DROP database IF EXISTS nuxeo;\r
CREATE database nuxeo;\r
\r
+\r
--\r
-- grant privileges to test user on nuxeo and jbossdb databases\r
--\r
GRANT ALL PRIVILEGES ON jbossdb.* TO 'test'@'localhost' IDENTIFIED BY 'test' WITH GRANT OPTION;\r
FLUSH PRIVILEGES;\r
+GRANT ALL PRIVILEGES ON cspace.* TO 'test'@'localhost' IDENTIFIED BY 'test' WITH GRANT OPTION;\r
+FLUSH PRIVILEGES;\r
GRANT ALL PRIVILEGES ON nuxeo.* TO 'test'@'localhost' IDENTIFIED BY 'test' WITH GRANT OPTION;\r
FLUSH PRIVILEGES;\r
\r
--- /dev/null
+-- MySQL Administrator dump 1.4
+--
+-- ------------------------------------------------------
+-- Server version 5.1.31-community
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+
+
+--
+-- Create schema cspace
+--
+
+CREATE DATABASE IF NOT EXISTS cspace;
+USE cspace;
+
+--
+-- Definition of table `roles`
+--
+
+DROP TABLE IF EXISTS `roles`;
+CREATE TABLE `roles` (
+ `rolename` varchar(128) NOT NULL,
+ `rolegroup` varchar(128) DEFAULT NULL,
+ PRIMARY KEY (`rolename`),
+ KEY `rolename_roles` (`rolename`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `roles`
+--
+
+/*!40000 ALTER TABLE `roles` DISABLE KEYS */;
+INSERT INTO `roles` (`rolename`,`rolegroup`) VALUES
+ ('collections_manager','collections'),
+ ('collections_registrar','collections');
+/*!40000 ALTER TABLE `roles` ENABLE KEYS */;
+
+
+--
+-- Definition of table `users`
+--
+
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `username` varchar(128) NOT NULL,
+ `passwd` varchar(128) NOT NULL,
+ PRIMARY KEY (`username`),
+ KEY `username_users` (`username`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `users`
+--
+
+/*!40000 ALTER TABLE `users` DISABLE KEYS */;
+INSERT INTO `users` (`username`,`passwd`) VALUES
+ ('test','n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=');
+/*!40000 ALTER TABLE `users` ENABLE KEYS */;
+
+
+--
+-- Definition of table `users_roles`
+--
+
+DROP TABLE IF EXISTS `users_roles`;
+CREATE TABLE `users_roles` (
+ `username` varchar(128) NOT NULL,
+ `rolename` varchar(128) NOT NULL,
+ KEY `username_users_roles` (`username`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `users_roles`
+--
+
+/*!40000 ALTER TABLE `users_roles` DISABLE KEYS */;
+INSERT INTO `users_roles` (`username`,`rolename`) VALUES
+ ('test','collections_manager');
+/*!40000 ALTER TABLE `users_roles` ENABLE KEYS */;
+
+
+
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;