You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ch...@apache.org on 2014/06/24 20:50:49 UTC
git commit: adding missing classes for credential store
Repository: airavata
Updated Branches:
refs/heads/master 5c7acf301 -> 4d9b92e5d
adding missing classes for credential store
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/4d9b92e5
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/4d9b92e5
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/4d9b92e5
Branch: refs/heads/master
Commit: 4d9b92e5d829a3bbe0482a30e7accfe3e03fceed
Parents: 5c7acf3
Author: Chathuri Wimalasena <ka...@gmail.com>
Authored: Tue Jun 24 14:50:44 2014 -0400
Committer: Chathuri Wimalasena <ka...@gmail.com>
Committed: Tue Jun 24 14:50:44 2014 -0400
----------------------------------------------------------------------
.../main/resources/airavata-server.properties | 10 +-
.../credential-store-webapp/pom.xml | 154 +++++++++
.../basic/BasicAccessAuthenticator.java | 217 ++++++++++++
.../credentialstore/local/LocalUserStore.java | 339 +++++++++++++++++++
.../main/resources/airavata-server.properties | 332 ++++++++++++++++++
.../src/main/webapp/acs/index.jsp | 44 +++
.../src/main/webapp/images/airavata-logo-2.png | Bin 0 -> 4314 bytes
.../src/main/webapp/user-store/add.jsp | 142 ++++++++
.../src/main/webapp/user-store/index.jsp | 138 ++++++++
.../src/main/webapp/user-store/password.jsp | 157 +++++++++
10 files changed, 1531 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/configuration/server/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties
index 625f7f2..ecc0932 100644
--- a/modules/configuration/server/src/main/resources/airavata-server.properties
+++ b/modules/configuration/server/src/main/resources/airavata-server.properties
@@ -300,10 +300,16 @@ appcatalogserver=org.apache.airavata.api.server.ApplicationCatalogServer
servers=apiserver,appcatalogserver,orchestrator,gfac
#shutdown.trategy=NONE
shutdown.trategy=SELF_TERMINATE
-# credential store specific parameters
-credential.store.keystore.url=../configuration/server/src/main/resources/airavata.jks
+
+
+###--------------------------- Credential Store Specific Parameters---------------------------###
+credential.store.keystore.url=/Users/chathuri/dev/airavata/source/trunk_git/airavata/modules/credential-store-service/credential-store-webapp/keys/credential-store/airavata_sym.jks
credential.store.keystore.alias=airavata
credential.store.keystore.password=airavata
+credential.store.jdbc.url=jdbc:derby://localhost:1527/persistent_data;create=true;user=airavata;password=airavata
+credential.store.jdbc.user=airavata
+credential.store.jdbc.password=airavata
+credential.store.jdbc.driver=org.apache.derby.jdbc.ClientDriver
notifier.enabled=false
#period in milliseconds
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/pom.xml
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/pom.xml b/modules/credential-store-service/credential-store-webapp/pom.xml
new file mode 100644
index 0000000..85f5c23
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/pom.xml
@@ -0,0 +1,154 @@
+<?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. -->
+
+<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">
+
+ <parent>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store-service</artifactId>
+ <version>0.13-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>airavata-credential-store-webapp</artifactId>
+ <packaging>war</packaging>
+ <name>airavata-credential-store-webapp</name>
+ <build>
+ <finalName>credential-store</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <version>${cargo.version}</version>
+ <configuration>
+ <wait>true</wait>
+ <configuration>
+ <properties>
+ <cargo.servlet.port>8443</cargo.servlet.port>
+ <cargo.protocol>https</cargo.protocol>
+ <cargo.tomcat.connector.clientAuth>false</cargo.tomcat.connector.clientAuth>
+ <cargo.tomcat.connector.sslProtocol>TLS</cargo.tomcat.connector.sslProtocol>
+ <cargo.tomcat.connector.keystoreFile>/Users/chathuri/dev/airavata/credential-store/oa4mp/airavata_sym.jks</cargo.tomcat.connector.keystoreFile>
+ <cargo.tomcat.connector.keystorePass>airavata</cargo.tomcat.connector.keystorePass>
+ <cargo.tomcat.ajp.port>9009</cargo.tomcat.ajp.port>
+ <cargo.rmi.port>9099</cargo.rmi.port>
+ <cargo.jvmargs>
+ <![CDATA[-Xdebug -Xrunjdwp:transport=dt_socket,address=${cargo.debug.address},server=y,suspend=${cargo.debug.suspend} -noverify ${javaagent}]]>
+ </cargo.jvmargs>
+ <cargo.tomcat.context.reloadable>true</cargo.tomcat.context.reloadable>
+ </properties>
+ <home>${project.build.directory}/tomcat6x</home>
+ <deployables>
+ <deployable>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store-webapp</artifactId>
+ <type>war</type>
+ <properties>
+ <context>/acs</context>
+ </properties>
+ </deployable>
+ </deployables>
+ </configuration>
+ <container>
+ <containerId>tomcat6x</containerId>
+ <timeout>180000</timeout>
+ <zipUrlInstaller>
+ <url>
+ http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.32/bin/apache-tomcat-6.0.32.tar.gz
+ </url>
+ </zipUrlInstaller>
+ <systemProperties>
+
+ </systemProperties>
+ </container>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derbyclient</artifactId>
+ <version>${derby.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-security</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.6</version>
+ </dependency>
+ <dependency>
+ <groupId>edu.uiuc.ncsa.myproxy</groupId>
+ <artifactId>oa4mp-client-oauth1</artifactId>
+ <version>${oa4mp.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${org.slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ebaysf.web</groupId>
+ <artifactId>cors-filter</artifactId>
+ <version>${ebay.cors.filter}</version>
+ </dependency>
+ </dependencies>
+ <properties>
+ <cargo.version>1.2.1</cargo.version>
+ <cargo.debug.address>8000</cargo.debug.address>
+ <cargo.debug.suspend>y</cargo.debug.suspend>
+ <javaagent />
+ </properties>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/basic/BasicAccessAuthenticator.java
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/basic/BasicAccessAuthenticator.java b/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/basic/BasicAccessAuthenticator.java
new file mode 100644
index 0000000..07ad123
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/basic/BasicAccessAuthenticator.java
@@ -0,0 +1,217 @@
+/*
+ * 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.airavata.credentialstore.basic;
+
+import org.apache.airavata.common.utils.Constants;
+import org.apache.airavata.credentialstore.session.ServletRequestHelper;
+import org.apache.airavata.security.AbstractAuthenticator;
+import org.apache.airavata.security.AuthenticationException;
+import org.apache.airavata.security.UserStoreException;
+import org.w3c.dom.Node;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * This authenticator handles basic access authentication requests. In basic access authentication
+ * we get user name and password as HTTP headers. The password is encoded with base64.
+ * More information @link{http://en.wikipedia.org/wiki/Basic_access_authentication}
+ */
+public class BasicAccessAuthenticator extends AbstractAuthenticator {
+
+
+ private static final String AUTHENTICATOR_NAME = "BasicAccessAuthenticator";
+
+ private ServletRequestHelper servletRequestHelper = new ServletRequestHelper();
+
+ public BasicAccessAuthenticator() {
+ super(AUTHENTICATOR_NAME);
+ }
+
+
+ /**
+ * Returns user name and password as an array. The first element is user name and second is password.
+ *
+ * @param httpServletRequest The servlet request.
+ * @return User name password pair as an array.
+ * @throws AuthenticationException If an error occurred while extracting user name and password.
+ */
+ private String[] getUserNamePassword(HttpServletRequest httpServletRequest) throws AuthenticationException {
+
+ String basicHeader = httpServletRequest.getHeader(ServletRequestHelper.AUTHORISATION_HEADER_NAME);
+
+ if (basicHeader == null) {
+ throw new AuthenticationException("Authorization Required");
+ }
+
+ String[] userNamePasswordArray = basicHeader.split(" ");
+
+ if (userNamePasswordArray == null || userNamePasswordArray.length != 2) {
+ throw new AuthenticationException("Authorization Required");
+ }
+
+ String decodedString = servletRequestHelper.decode(userNamePasswordArray[1]);
+
+ String[] array = decodedString.split(":");
+
+ if (array == null || array.length != 2) {
+ throw new AuthenticationException("Authorization Required");
+ }
+
+ return array;
+
+ }
+
+ @Override
+ protected boolean doAuthentication(Object credentials) throws AuthenticationException {
+ if (this.getUserStore() == null) {
+ throw new AuthenticationException("Authenticator is not initialized. Error processing request.");
+ }
+
+ if (credentials == null)
+ return false;
+
+ HttpServletRequest httpServletRequest = (HttpServletRequest) credentials;
+
+ String[] array = getUserNamePassword(httpServletRequest);
+
+ String userName = array[0];
+ String password = array[1];
+
+ try {
+ return this.getUserStore().authenticate(userName, password);
+
+ } catch (UserStoreException e) {
+ throw new AuthenticationException("Error querying database for session information.", e);
+ }
+ }
+
+
+
+ @Override
+ public void onSuccessfulAuthentication(Object authenticationInfo) {
+
+ HttpServletRequest httpServletRequest = (HttpServletRequest) authenticationInfo;
+
+ try {
+ String[] array = getUserNamePassword(httpServletRequest);
+
+ StringBuilder stringBuilder = new StringBuilder("User : ");
+
+ if (array != null) {
+
+ servletRequestHelper.addUserToSession(array[0], httpServletRequest);
+
+ stringBuilder.append(array[0]).append(" successfully logged into system at ").append(getCurrentTime());
+ log.debug(stringBuilder.toString());
+
+ } else {
+ log.error("System error occurred while extracting user name after authentication. " +
+ "Couldn't extract user name from the request.");
+ }
+ } catch (AuthenticationException e) {
+ log.error("System error occurred while extracting user name after authentication.", e);
+ }
+
+ }
+
+ @Override
+ public void onFailedAuthentication(Object authenticationInfo) {
+
+ HttpServletRequest httpServletRequest = (HttpServletRequest) authenticationInfo;
+
+ try {
+ String[] array = getUserNamePassword(httpServletRequest);
+
+ StringBuilder stringBuilder = new StringBuilder("User : ");
+
+ if (array != null) {
+
+ stringBuilder.append(array[0]).append(" Failed login attempt to system at ").append(getCurrentTime());
+ log.warn(stringBuilder.toString());
+
+ } else {
+ stringBuilder.append("Failed login attempt to system at ").append(getCurrentTime()).append( ". User unknown.");
+ log.warn(stringBuilder.toString());
+ }
+ } catch (AuthenticationException e) {
+ log.error("System error occurred while extracting user name after authentication.", e);
+ }
+ }
+
+ @Override
+ public boolean isAuthenticated(Object credentials) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) credentials;
+
+ HttpSession httpSession = httpServletRequest.getSession();
+
+ boolean seenInSession = false;
+
+ if (httpSession != null) {
+ String user = (String)httpSession.getAttribute(Constants.USER_IN_SESSION);
+ String gateway = (String)httpSession.getAttribute(Constants.GATEWAY_NAME);
+
+ if (user != null && gateway != null) {
+ servletRequestHelper.addToContext(user, gateway);
+ seenInSession = true;
+ }
+ }
+
+ return seenInSession;
+
+ }
+
+ @Override
+ public boolean canProcess(Object credentials) {
+
+ HttpServletRequest httpServletRequest = (HttpServletRequest) credentials;
+
+ return (httpServletRequest.getHeader(ServletRequestHelper.AUTHORISATION_HEADER_NAME) != null);
+ }
+
+
+
+ @Override
+ public void configure(Node node) throws RuntimeException {
+
+ /**
+ <specificConfigurations>
+ <database>
+ <jdbcUrl></jdbcUrl>
+ <databaseDriver></databaseDriver>
+ <userName></userName>
+ <password></password>
+ <userTableName></userTableName>
+ <userNameColumnName></userNameColumnName>
+ <passwordColumnName></passwordColumnName>
+ </database>
+ </specificConfigurations>
+ */
+
+ try {
+ this.getUserStore().configure(node);
+ } catch (UserStoreException e) {
+ throw new RuntimeException("Error while configuring authenticator user store", e);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/local/LocalUserStore.java
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/local/LocalUserStore.java b/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/local/LocalUserStore.java
new file mode 100644
index 0000000..0a2ca83
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/java/org/apache/airavata/credentialstore/local/LocalUserStore.java
@@ -0,0 +1,339 @@
+/*
+ *
+ * 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.airavata.credentialstore.local;
+
+import java.security.NoSuchAlgorithmException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+import org.apache.airavata.common.utils.DBUtil;
+import org.apache.airavata.common.utils.SecurityUtil;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * User store to maintain internal DB database.
+ */
+public class LocalUserStore {
+
+ protected static Logger log = LoggerFactory.getLogger(LocalUserStore.class);
+
+ private DBUtil dbUtil;
+
+ private String hashMethod;
+
+ public LocalUserStore(ServletContext servletContext) throws Exception {
+ // Properties properties = WebAppUtil.getAiravataProperties(servletContext);
+
+ hashMethod = ServerSettings.getSetting("default.registry.password.hash.method");
+
+ dbUtil = new DBUtil(ServerSettings.getSetting("registry.jdbc.url"),
+ ServerSettings.getSetting("registry.jdbc.user"),
+ ServerSettings.getSetting("registry.jdbc.password"),
+ ServerSettings.getSetting("registry.jdbc.driver"));
+
+ }
+
+ public LocalUserStore(DBUtil db) {
+ dbUtil = db;
+ }
+
+ public void addUser(String userName, String password) {
+
+ String sql = "insert into Users values (?, ?)";
+
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+
+ try {
+ connection = dbUtil.getConnection();
+ preparedStatement = connection.prepareStatement(sql);
+
+ preparedStatement.setString(1, userName);
+ preparedStatement.setString(2, SecurityUtil.digestString(password, hashMethod));
+
+ preparedStatement.executeUpdate();
+
+ connection.commit();
+
+ log.debug("User " + userName + " successfully added.");
+
+ } catch (SQLException e) {
+ StringBuilder stringBuilder = new StringBuilder("Error persisting user information.");
+ stringBuilder.append(" user - ").append(userName);
+
+ log.error(stringBuilder.toString(), e);
+
+ throw new RuntimeException(stringBuilder.toString(), e);
+ } catch (NoSuchAlgorithmException e) {
+ String stringBuilder = "Error creating hash value for password.";
+ log.error(stringBuilder, e);
+
+ throw new RuntimeException(stringBuilder, e);
+ } finally {
+
+ dbUtil.cleanup(preparedStatement, connection);
+ }
+
+ }
+
+ protected String getPassword(String userName, Connection connection) {
+
+ String sql = "select password from Users where user_name = ?";
+
+ PreparedStatement preparedStatement = null;
+ ResultSet resultSet = null;
+
+ try {
+ preparedStatement = connection.prepareStatement(sql);
+
+ preparedStatement.setString(1, userName);
+
+ resultSet = preparedStatement.executeQuery();
+
+ if (resultSet.next()) {
+ return resultSet.getString("password");
+ }
+
+ } catch (SQLException e) {
+ StringBuilder stringBuilder = new StringBuilder("Error retrieving credentials for user.");
+ stringBuilder.append("name - ").append(userName);
+
+ log.error(stringBuilder.toString(), e);
+
+ throw new RuntimeException(stringBuilder.toString(), e);
+ } finally {
+
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ log.error("Error closing result set", e);
+ }
+ }
+
+ if (preparedStatement != null) {
+ try {
+ preparedStatement.close();
+ } catch (SQLException e) {
+ log.error("Error closing prepared statement", e);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void changePassword(String userName, String oldPassword, String newPassword) {
+
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+
+ try {
+ connection = dbUtil.getConnection();
+
+ String storedPassword = getPassword(userName, connection);
+
+ String oldDigestedPassword = SecurityUtil.digestString(oldPassword, hashMethod);
+
+ if (storedPassword != null) {
+ if (!storedPassword.equals(oldDigestedPassword)) {
+ throw new RuntimeException("Previous password did not match correctly. Please specify old password"
+ + " correctly.");
+ }
+ }
+
+ String sql = "update Users set password = ? where user_name = ?";
+
+ preparedStatement = connection.prepareStatement(sql);
+
+ preparedStatement.setString(1, SecurityUtil.digestString(newPassword, hashMethod));
+ preparedStatement.setString(2, userName);
+
+ preparedStatement.executeUpdate();
+
+ connection.commit();
+
+ log.debug("Password changed for user " + userName);
+
+ } catch (SQLException e) {
+ StringBuilder stringBuilder = new StringBuilder("Error updating credentials.");
+ stringBuilder.append(" user - ").append(userName);
+
+ log.error(stringBuilder.toString(), e);
+
+ throw new RuntimeException(stringBuilder.toString(), e);
+ } catch (NoSuchAlgorithmException e) {
+ String stringBuilder = "Error creating hash value for password.";
+ log.error(stringBuilder, e);
+
+ throw new RuntimeException(stringBuilder, e);
+ } finally {
+
+ dbUtil.cleanup(preparedStatement, connection);
+ }
+
+ }
+
+ public void changePasswordByAdmin(String userName, String newPassword) {
+
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+
+ try {
+ connection = dbUtil.getConnection();
+
+ String sql = "update Users set password = ? where user_name = ?";
+
+ preparedStatement = connection.prepareStatement(sql);
+
+ preparedStatement.setString(1, SecurityUtil.digestString(newPassword, hashMethod));
+ preparedStatement.setString(2, userName);
+
+ preparedStatement.executeUpdate();
+
+ connection.commit();
+
+ log.debug("Admin changed password of user " + userName);
+
+ } catch (SQLException e) {
+ StringBuilder stringBuilder = new StringBuilder("Error updating credentials.");
+ stringBuilder.append(" user - ").append(userName);
+
+ log.error(stringBuilder.toString(), e);
+
+ throw new RuntimeException(stringBuilder.toString(), e);
+ } catch (NoSuchAlgorithmException e) {
+ String stringBuilder = "Error creating hash value for password.";
+ log.error(stringBuilder, e);
+
+ throw new RuntimeException(stringBuilder, e);
+ } finally {
+
+ dbUtil.cleanup(preparedStatement, connection);
+ }
+
+ }
+
+ public void deleteUser(String userName) {
+
+ String sql = "delete from Users where user_name=?";
+
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+
+ try {
+ connection = dbUtil.getConnection();
+ preparedStatement = connection.prepareStatement(sql);
+
+ preparedStatement.setString(1, userName);
+
+ preparedStatement.executeUpdate();
+
+ connection.commit();
+
+ log.debug("User " + userName + " deleted.");
+
+ } catch (SQLException e) {
+ StringBuilder stringBuilder = new StringBuilder("Error deleting user.");
+ stringBuilder.append("user - ").append(userName);
+
+ log.error(stringBuilder.toString(), e);
+
+ throw new RuntimeException(stringBuilder.toString(), e);
+ } finally {
+ dbUtil.cleanup(preparedStatement, connection);
+ }
+
+ }
+
+ public List<String> getUsers() {
+
+ List<String> userList = new ArrayList<String>();
+
+ String sql = "select user_name from Users";
+
+ PreparedStatement preparedStatement = null;
+ ResultSet resultSet = null;
+ Connection connection = null;
+
+ try {
+
+ connection = dbUtil.getConnection();
+ preparedStatement = connection.prepareStatement(sql);
+
+ resultSet = preparedStatement.executeQuery();
+
+ while (resultSet.next()) {
+ userList.add(resultSet.getString("user_name"));
+ }
+
+ } catch (SQLException e) {
+ String errorString = "Error retrieving Users.";
+ log.error(errorString, e);
+
+ throw new RuntimeException(errorString, e);
+ } finally {
+
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ log.error("Error closing result set", e);
+ }
+ }
+
+ if (preparedStatement != null) {
+ try {
+ preparedStatement.close();
+ } catch (SQLException e) {
+ log.error("Error closing prepared statement", e);
+ }
+ }
+
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ log.error("Error closing connection", e);
+ }
+ }
+ }
+
+ Collections.sort(userList);
+
+ return userList;
+
+ }
+
+ public static String getPasswordRegularExpression() {
+ return "'^[a-zA-Z0-9_-]{6,15}$'";
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
new file mode 100644
index 0000000..5f34f8c
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/resources/airavata-server.properties
@@ -0,0 +1,332 @@
+#
+#
+# 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.
+#
+
+###########################################################################
+#
+# This properties file provides configuration for all Airavata Services:
+# Registry, Workflow Interpreter, GFac, Message Broker, Message Box
+#
+###########################################################################
+
+###########################################################################
+# Airavata Embedded-Tomcat Server Configuration
+###########################################################################
+# By default, tomcat runs on port 80. If the port is changed, it will be
+# have to be specified with port properties. This will be picked up by
+# the registry service to register the service end-points.
+
+port=8080
+
+# Axis2 server automatically picks up IP address from axis configuration,
+# but some DHCP enables machines do not report correct ip addresses,
+# in which case, the IP address can be manually specified.
+
+#ip=192.2.33.12
+
+
+#This property will enable https and stops http, during the url registration, https urls will be stored and
+# http urls will not get registered, because currently airavata supports only one url for each service
+#enable.https=false
+#system properties used by services to register service URLs
+system.gateway=default
+system.user=admin
+system.password=admin
+airavata.server.url=http://localhost:8080/airavata/services/registry
+
+###########################################################################
+# Airavata Registry Configuration
+###########################################################################
+#for derby [AiravataJPARegistry]
+registry.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+registry.jdbc.url=jdbc:derby://localhost:1527/persistent_data;create=true;user=airavata;password=airavata
+# MySql database configuration
+#registry.jdbc.driver=com.mysql.jdbc.Driver
+#registry.jdbc.url=jdbc:mysql://localhost:3306/persistent_data
+registry.jdbc.user=airavata
+registry.jdbc.password=airavata
+start.derby.server.mode=true
+validationQuery=SELECT 1 from CONFIGURATION
+jpa.cache.size=5000
+#jpa.connection.properties=MaxActive=10,MaxIdle=5,MinIdle=2,MaxWait=60000,testWhileIdle=true,testOnBorrow=true
+# Properties to setup registry service
+default.registry.user=admin
+default.registry.password=admin
+default.registry.password.hash.method=SHA
+default.registry.gateway=default
+#for rest [RegistryClient]
+#registry.jdbc.url=http://localhost:9080/airavata-services
+
+###########################################################################
+# Airavata App Catalog DB Configuration
+###########################################################################
+#for derby [AiravataJPARegistry]
+appcatalog.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+appcatalog.jdbc.url=jdbc:derby://localhost:1527/app_catalog;create=true;user=airavata;password=airavata
+# MySql database configuration
+#appcatalog.jdbc.driver=com.mysql.jdbc.Driver
+#appcatalog.jdbc.url=jdbc:mysql://localhost:3306/app_catalog
+appcatalog.jdbc.user=airavata
+appcatalog.jdbc.password=airavata
+appcatalog.validationQuery=SELECT 1 from COMPUTE_RESOURCE
+
+#user defined registry accessor classes
+#class.provenance.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.configuration.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.descriptor.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.project.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.user.workflow.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.published.workflow.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+
+###########################################################################
+# Airavata Workflow Interpreter Configurations
+###########################################################################
+
+runInThread=true
+provenance=true
+provenanceWriterThreadPoolSize=20
+gfac.embedded=true
+
+#
+# Security Configuration used by Airavata Generic Factory Service
+# to interact with Computational Resources.
+#
+
+###########################################################################
+# Airavata GFac MyProxy GSI credentials to access Grid Resources.
+###########################################################################
+gfac=org.apache.airavata.gfac.server.GfacServer
+myproxy.server=myproxy.teragrid.org
+myproxy.username=ogce
+myproxy.password=
+myproxy.life=3600
+# XSEDE Trusted certificates can be downloaded from https://software.xsede.org/security/xsede-certs.tar.gz
+trusted.cert.location=/Users/lahirugunathilake/Downloads/certificates
+# SSH PKI key pair or ssh password can be used SSH based authentication is used.
+# if user specify both password authentication gets the higher preference
+
+################# ---------- For ssh key pair authentication ------------------- ################
+#public.ssh.key=/path to public key for ssh
+#ssh.username=username for ssh connection
+#private.ssh.key=/path to private key file for ssh
+#ssh.keypass=passphrase for the private key
+
+
+################# ---------- For ssh key pair authentication ------------------- ################
+#ssh.username=username for ssh connection
+#ssh.password=Password for ssh connection
+
+
+
+###########################################################################
+# Airavata Message Broker Basic Configurations.
+# the Advanced section provides detailed custom configuration properties.
+###########################################################################
+
+# Default derby database configuration
+broker.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+broker.jdbc.url=jdbc:derby:wsmg;create=true;user=airavata;password=airavata
+
+# Note: This database will only be used if 'broker.storage.type=persistent'
+# is set in advanced properties below.
+# MySql database configuration
+#broker.jdbc.driver=com.mysql.jdbc.Driver
+#broker.jdbc.url=jdbc:mysql://localhost:3306/wsmg?user=airavata&password=airavata
+
+###########################################################################
+# Airavata Message Box Basic Configurations,
+# the Advanced section provides detailed custom configuration properties.
+###########################################################################
+
+# Default derby database
+msgBox.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+msgBox.jdbc.url=jdbc:derby:wsmg;create=true;user=airavata;password=airavata
+
+# MySql database configuration
+#msgBox.jdbc.driver=com.mysql.jdbc.Driver
+#msgBox.jdbc.url=jdbc:mysql://localhost:3306/wsmg?user=airavata&password=airavata
+
+###########################################################################
+# Advance configuration to change service implementations
+###########################################################################
+
+#Update the server context root path if airavata server is deployed under a different context root other than axis2
+server.context-root=airavata-server
+
+#
+# Class which implemented HostScheduler interface. It will determine the which host to submit the request
+#
+host.scheduler=org.apache.airavata.gfac.core.scheduler.impl.SimpleHostScheduler
+
+#
+# Data Service Plugins classes
+#
+datachain.classes= org.apache.airavata.core.gfac.extension.data.RegistryDataService
+
+#
+# Pre execution Plugins classes. For example, GridFTP Input Staging
+#
+prechain.classes= org.apache.airavata.core.gfac.extension.pre.GridFtpInputStaging
+prechain.classes= org.apache.airavata.core.gfac.extension.pre.HttpInputStaging
+
+#
+# Post execution Plugins classes. For example, GridFTP Output Staging
+#
+postchain.classes= org.apache.airavata.core.gfac.extension.post.GridFtpOutputStaging
+postchain.classes= org.apache.airavata.core.gfac.extension.post.OutputRegister
+
+#
+# Advanced Message Broker Configurations
+#
+
+#socket time out in milliseconds for sending messages. (defaults is 20000)
+broker.socket.timeout=60000
+
+broker.storage.type=persistent
+#broker.storage.type=memory
+
+#specifies wether delivery component should be started or not.
+broker.start.delivery.thread=true
+
+#fixed thread pool based delivery
+#broker.delivery.method=pcrew
+
+#dynamic thread pool based delivery
+#broker.delivery.method=parallel
+
+#single thread delivery
+broker.delivery.method=serial
+
+#number of message delivery failures before a url become black listed (default is 2)
+#broker.msg.delivery.retries=2
+
+#time period (in seconds) a url will be kept blacklisted (default is 5 seconds)
+#consumer.expiration.time.gap=5
+
+#maximum number of messages to be send to a one consumer/url at time.
+#applicable if 'broker.delivery.method' is 'pcrew' . (default is 10)
+
+#sending.batch.size=10
+
+#size of the thread pool. only applicable if 'broker.delivery.method' is 'pcrew'. (default is 4)
+#sending.thread.pool.size=4
+
+#
+# Advanced Message Box Configurations
+#
+msgBox.usedatabase=true
+messagePreservationDays=2
+messagePreservationHours=0
+messagePreservationMinutes=0
+messagePerservationIntervalDays=0
+messagePerservationIntervalHours=1
+messagePerservationIntervalMinutes=0
+
+###---------------------------REGISTRY API IMPLEMENTATION---------------------------###
+
+class.registry.accessor=org.apache.airavata.persistance.registry.jpa.impl.AiravataJPARegistry
+#class.registry.accessor=org.apache.airavata.rest.client.RegistryClient
+
+###########################################################################
+# AMQP Notification Configuration
+###########################################################################
+amqp.notification.enable=1
+
+amqp.broker.host=localhost
+amqp.broker.port=5672
+amqp.broker.username=guest
+amqp.broker.password=guest
+
+amqp.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPSenderImpl
+amqp.topic.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPTopicSenderImpl
+amqp.broadcast.sender=org.apache.airavata.wsmg.client.amqp.rabbitmq.AMQPBroadcastSenderImpl
+
+###---------------------------Computational Middleware Configurations---------------------------###
+
+#enable.application.job.status.history=true
+#http://localhost:8080/axis2/services/RegistryService?wsdl
+registry.service.wsdl=http://localhost:${port}/${server.context-root}/services/RegistryService?wsdl
+
+# If false, disables two phase commit when submitting jobs
+TwoPhase=true
+
+
+###---------------------------Monitoring module Configurations---------------------------###
+#This will be the primary monitoring tool which runs in airavata, in future there will be multiple monitoring
+#mechanisms and one would be able to start a monitor
+monitors=org.apache.airavata.gfac.monitor.impl.pull.qstat.QstatMonitor,org.apache.airavata.gfac.monitor.impl.LocalJobMonitor
+#,org.apache.airavata.gfac.monitor.impl.push.amqp.AMQPMonitor
+#This is the amqp related configuration and this lists down the Rabbitmq host, this is an xsede specific configuration
+amqp.hosts=info1.dyn.teragrid.org,info2.dyn.teragrid.org
+proxy.file.path=/Users/lahirugunathilake/Downloads/x509up_u503876
+connection.name=xsede
+activity.listeners=org.apache.airavata.gfac.core.monitor.AiravataJobStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataTaskStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataWorkflowNodeStatusUpdator,org.apache.airavata.gfac.core.monitor.AiravataExperimentStatusUpdator
+
+###---------------------------Orchestrator module Configurations---------------------------###
+job.submitter=org.apache.airavata.orchestrator.core.impl.GFACEmbeddedJobSubmitter
+#job.submitter=org.apache.airavata.orchestrator.core.impl.GFACServiceJobSubmitter
+job.validators=org.apache.airavata.orchestrator.core.validator.impl.SimpleAppDataValidator,org.apache.airavata.orchestrator.core.validator.impl.ExperimentStatusValidator
+submitter.interval=10000
+threadpool.size=10
+start.submitter=true
+embedded.mode=true
+enable.validation=true
+orchestrator=org.apache.airavata.orchestrator.server.OrchestratorServer
+
+###---------------------------API Server module Configurations---------------------------###
+apiserver=org.apache.airavata.api.server.AiravataAPIServer
+
+###---------------------------Application Catalog Server module Configurations---------------------------###
+appcatalogserver=org.apache.airavata.api.server.ApplicationCatalogServer
+
+
+###---------------------------Airavata Server Configurations---------------------------###
+servers=apiserver,appcatalogserver,orchestrator
+#shutdown.trategy=NONE
+shutdown.trategy=SELF_TERMINATE
+
+
+###--------------------------- Credential Store Specific Parameters---------------------------###
+credential.store.keystore.url=/Users/chathuri/dev/airavata/source/trunk_git/airavata/modules/credential-store-service/credential-store-webapp/keys/credential-store/airavata_sym.jks
+credential.store.keystore.alias=airavata
+credential.store.keystore.password=airavata
+credential.store.jdbc.url=jdbc:derby://localhost:1527/persistent_data;create=true;user=airavata;password=airavata
+credential.store.jdbc.user=airavata
+credential.store.jdbc.password=airavata
+credential.store.jdbc.driver=org.apache.derby.jdbc.ClientDriver
+
+notifier.enabled=false
+#period in milliseconds
+notifier.duration=5000
+
+email.server=smtp.googlemail.com
+email.server.port=465
+email.user=airavata
+email.password=xxx
+email.ssl=true
+email.from=airavata@apache.org
+
+apiserver.server.host=localhost
+apiserver.server.port=8930
+apiserver.server.min.threads=30
+app.catalog.server.host=localhost
+app.catalog.server.port=8931
+orchestrator.server.host=localhost
+orchestrator.server.port=8940
+orchestrator.server.min.threads=30
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/webapp/acs/index.jsp
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/webapp/acs/index.jsp b/modules/credential-store-service/credential-store-webapp/src/main/webapp/acs/index.jsp
new file mode 100644
index 0000000..e7626fa
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/webapp/acs/index.jsp
@@ -0,0 +1,44 @@
+<%--
+ ~ 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.
+ --%>
+
+<html>
+<body>
+<h2>Sample Portal</h2>
+<p>This demonstrates how portal can use Credential Store to obtain community credentials ...</p>
+<form name="input" action="../acs-start-servlet" method="post">
+
+ <table border="0">
+ <tr>
+ <td>Gateway Name</td>
+ <td><input type="text" name="gatewayName"></td>
+ </tr>
+ <tr>
+ <td>Portal Username</td>
+ <td><input type="text" name="portalUserName"></td>
+ </tr>
+ <tr>
+ <td>Contact Email</td>
+ <td><input type="text" name="email"></td>
+ </tr>
+ </table>
+
+ <input type="submit" value="Submit">
+</form>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/webapp/images/airavata-logo-2.png
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/webapp/images/airavata-logo-2.png b/modules/credential-store-service/credential-store-webapp/src/main/webapp/images/airavata-logo-2.png
new file mode 100644
index 0000000..4baf51b
Binary files /dev/null and b/modules/credential-store-service/credential-store-webapp/src/main/webapp/images/airavata-logo-2.png differ
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/add.jsp
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/add.jsp b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/add.jsp
new file mode 100644
index 0000000..f37684d
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/add.jsp
@@ -0,0 +1,142 @@
+<%--
+ 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.
+--%>
+<%@ page import="org.apache.airavata.credentialstore.local.LocalUserStore" %>
+
+<html>
+
+<head>
+ <script language="javascript" type="text/javascript">
+ function validatePassword(fld1name, regString) {
+ var stringValue = document.getElementsByName(fld1name)[0].value;
+ var errorMessage = "";
+ if(regString != "null" && !stringValue.match(new RegExp(regString))){
+ errorMessage = "Password does not meet minimum requirements. Password length must be at least 6 " +
+ "characters.";
+ return errorMessage;
+ }else if(regString != "null" && stringValue == ''){
+ return errorMessage;
+ }
+
+ if (stringValue == '') {
+ errorMessage = "Empty passwords are not allowed. Please enter a valid password";
+ return errorMessage;
+ }
+
+ return errorMessage;
+ }
+
+ function validateUsername(fld1name) {
+ var stringValue = document.getElementsByName(fld1name)[0].value;
+ var errorMessage = "";
+
+ if (stringValue == '') {
+ errorMessage = "Empty user names are not allowed. Please enter a valid user name.";
+ return errorMessage;
+ }
+
+ return errorMessage;
+ }
+
+ function checkPasswordsMatching(fld1name, fld2name) {
+
+ var stringValue1 = document.getElementsByName(fld1name)[0].value;
+ var stringValue2 = document.getElementsByName(fld2name)[0].value;
+ var errorMessage = "";
+
+ if (stringValue1 != stringValue2) {
+ errorMessage = "Confirm password does not match with the password. Please re-enter passwords.";
+ return errorMessage;
+ }
+
+ return errorMessage;
+
+ }
+
+ function validate() {
+ var reason = "";
+
+ reason = validateUsername("username");
+
+ if (reason != "") {
+ alert(reason);
+ return false;
+ }
+
+ reason = validatePassword("newPassword", <%=LocalUserStore.getPasswordRegularExpression()%>);
+
+ if (reason != "") {
+ alert(reason);
+ document.getElementsByName("newPassword")[0].clear();
+ return false;
+ }
+
+ reason = checkPasswordsMatching("newPassword", "confirmPassword");
+
+ if (reason != "") {
+ alert(reason);
+ document.getElementsByName("newPassword")[0].clear();
+ document.getElementsByName("confirmPassword")[0].clear();
+ return false;
+ }
+
+ return true;
+ }
+
+ function doProcess() {
+ if (validate() == true) {
+ document.registration.submit();
+ }
+ }
+
+
+ </script>
+</head>
+
+<body>
+<img src="../images/airavata-logo-2.png">
+<h2>Airavata Credential Store - Local User Store</h2>
+<p><b>Manage Local User Store - Add New User</b></p>
+
+<form action="index.jsp" name="registration" method="POST">
+
+ <input type="hidden" name="operation" value="addUser">
+ <table>
+ <tr>
+ <td>User Name</td>
+ <td><input type="text" name="username" maxlength="150"></td>
+ </tr>
+ <tr>
+ <td>Password</td>
+ <td><input type="password" name="newPassword"/></td>
+ </tr>
+ <tr>
+ <td>Re-Type Password</td>
+ <td><input type="password" name="confirmPassword"/></td>
+ </tr>
+ </table>
+
+ <table>
+ <tr>
+ <td><input type="button" value="Add" onclick= 'doProcess()'></td>
+ <td><a href="index.jsp"><input type="button" value="Cancel" name="Cancel"/> </a> </td>
+ </tr>
+ </table>
+
+</form>
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/index.jsp
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/index.jsp b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/index.jsp
new file mode 100644
index 0000000..732c0c7
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/index.jsp
@@ -0,0 +1,138 @@
+<%--
+ 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.
+--%>
+
+<%@ page import = "org.apache.airavata.credentialstore.local.LocalUserStore" %>
+<%@ page import="org.apache.airavata.credentialstore.basic.BasicAccessAuthenticator" %>
+<%@ page import="org.apache.airavata.credentialstore.session.HttpAuthenticatorFilter" %>
+<%@ page import="java.util.List" %>
+<%@ page import="org.apache.airavata.common.utils.Constants" %>
+<%
+
+ LocalUserStore localUserStore = (LocalUserStore)session.getAttribute("LocalUserStore");
+
+ if (localUserStore == null) {
+
+ String operatingUser = (String) session.getAttribute(Constants.USER_IN_SESSION);
+
+ if (operatingUser == null || !operatingUser.equals("admin")) {
+ HttpAuthenticatorFilter.sendUnauthorisedError(response, "Insufficient privileges to perform user operations." +
+ " Only admin user is allowed to perform user operations.");
+
+ return;
+ }
+
+ localUserStore = new LocalUserStore(application);
+
+ session.setAttribute("LocalUserStore", localUserStore);
+ }
+
+ String operation = request.getParameter("operation");
+ if (operation != null) {
+ if (operation.equals("addUser")) {
+ String userName = request.getParameter("username");
+ String password = request.getParameter("newPassword");
+
+ localUserStore.addUser(userName, password);
+ } else if (operation.equals("deleteUser")) {
+ String[] usersToDelete = request.getParameterValues("user-id");
+
+ for (String deleteUser : usersToDelete) {
+ localUserStore.deleteUser(deleteUser);
+ }
+ }
+ }
+
+ List<String> allUsers = localUserStore.getUsers();
+
+%>
+
+<html>
+<head>
+ <script language="javascript" type="text/javascript">
+
+ function validate() {
+ var checkSelected = false;
+ for (var i = 0; i < <%=allUsers.size()%>; i++) {
+ if (document.main["user-id"][i].checked) {
+ checkSelected = true;
+ }
+ }
+ if (checkSelected) {
+ var answer = confirm("Are you sure you want to delete selected users from the system ?");
+ if (answer) {
+ return true;
+ }
+ } else {
+ alert("Select at least one user to delete.");
+ }
+ return false;
+ }
+
+ function doProcess() {
+ if (validate() == true) {
+ document.main.submit();
+ }
+ }
+
+ </script>
+</head>
+<body>
+<img src="../images/airavata-logo-2.png">
+<h2>Airavata REST API - Local User Store</h2>
+<p><b>Manage Local User Store</b></p>
+
+
+<form action="index.jsp" name="main" method="POST">
+ <table>
+ <tr>
+ <td> </td>
+ <td>All Users</td>
+ </tr>
+ <%
+ for (String user : allUsers) {
+ %>
+
+ <tr>
+ <td><input type="checkbox" name="user-id" value="<%=user%>"></td>
+ <td><%=user%>
+ </td>
+ <td><a href="password.jsp?username=<%=user%>">Change Password</a></td>
+ </tr>
+
+ <%
+ }
+ %>
+ </table>
+
+ <br>
+
+ <table width="100">
+ <tr>
+ <td>
+ <a href="add.jsp"><input type="button" value="Add" name="Add"/></a>
+ </td>
+ <td> </td>
+ <input type="hidden" name="operation" value="deleteUser">
+ <td><input type="button" value="Delete" onclick="doProcess()"></td>
+ </tr>
+ </table>
+
+</form>
+
+
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/4d9b92e5/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/password.jsp
----------------------------------------------------------------------
diff --git a/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/password.jsp b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/password.jsp
new file mode 100644
index 0000000..9a316ee
--- /dev/null
+++ b/modules/credential-store-service/credential-store-webapp/src/main/webapp/user-store/password.jsp
@@ -0,0 +1,157 @@
+<%--
+ 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.
+--%>
+
+<%@ page import="org.apache.airavata.credentialstore.local.LocalUserStore" %>
+
+<%
+ String userName = request.getParameter("username");
+ if (userName == null) {
+ response.sendRedirect("index.jsp");
+ }
+
+ String password = request.getParameter("newPassword");
+ String confirmPassword = request.getParameter("confirmPassword");
+
+ if (password != null && confirmPassword != null && password.equals(confirmPassword)) {
+ LocalUserStore localUserStore = (LocalUserStore)session.getAttribute("LocalUserStore");
+ localUserStore.changePasswordByAdmin(userName, password);
+
+ response.sendRedirect("password.jsp?message=\"Password successfully change for user "
+ + userName + "\"&username=" + userName);
+ }
+
+%>
+
+<html>
+<head>
+ <script language="javascript" type="text/javascript">
+ function validatePassword(fld1name, regString) {
+ var stringValue = document.getElementsByName(fld1name)[0].value;
+ var errorMessage = "";
+ if(regString != "null" && !stringValue.match(new RegExp(regString))){
+ errorMessage = "Password does not meet minimum requirements. Password length must be at least 6 " +
+ "characters.";
+ return errorMessage;
+ }else if(regString != "null" && stringValue == ''){
+ return errorMessage;
+ }
+
+ if (stringValue == '') {
+ errorMessage = "Empty passwords are not allowed. Please enter a valid password";
+ return errorMessage;
+ }
+
+ return errorMessage;
+ }
+
+ function validateUsername(fld1name) {
+ var stringValue = document.getElementsByName(fld1name)[0].value;
+ var errorMessage = "";
+
+ if (stringValue == '') {
+ errorMessage = "Empty user names are not allowed. Please enter a valid user name.";
+ return errorMessage;
+ }
+
+ return errorMessage;
+ }
+
+ function checkPasswordsMatching(fld1name, fld2name) {
+
+ var stringValue1 = document.getElementsByName(fld1name)[0].value;
+ var stringValue2 = document.getElementsByName(fld2name)[0].value;
+ var errorMessage = "";
+
+ if (stringValue1 != stringValue2) {
+ errorMessage = "Confirm password does not match with the password. Please re-enter passwords.";
+ return errorMessage;
+ }
+
+ return errorMessage;
+
+ }
+
+ function validate() {
+ var reason = "";
+
+ reason = validatePassword("newPassword", <%=LocalUserStore.getPasswordRegularExpression()%>);
+
+ if (reason != "") {
+ alert(reason);
+ document.getElementsByName("newPassword")[0].clear();
+ return false;
+ }
+
+ reason = checkPasswordsMatching("newPassword", "confirmPassword");
+
+ if (reason != "") {
+ alert(reason);
+ document.getElementsByName("newPassword")[0].clear();
+ document.getElementsByName("confirmPassword")[0].clear();
+ return false;
+ }
+
+ return true;
+ }
+
+ function doProcess() {
+ if (validate() == true) {
+ document.passwordForm.submit();
+ }
+ }
+
+ function displayMessage() {
+ var msg = <%=request.getParameter("message")%>;
+ if (msg != null) {
+ alert(msg);
+ }
+ }
+
+
+ </script>
+</head>
+
+<body onload="displayMessage()">
+<img src="../images/airavata-logo-2.png">
+<h2>Airavata REST API - Local User Store</h2>
+<p><b>Manage Local User Store - Change Password of user - <%=userName%></b></p>
+
+<form action="password.jsp" name="passwordForm" method="POST">
+
+ <input type="hidden" name="username" value="<%=userName%>">
+ <table>
+ <tr>
+ <td>New Password</td>
+ <td><input type="password" name="newPassword"/></td>
+ </tr>
+ <tr>
+ <td>Re-Type Password</td>
+ <td><input type="password" name="confirmPassword"/></td>
+ </tr>
+ </table>
+
+ <table>
+ <tr>
+ <td><input type="button" value="Change" onclick= 'doProcess()'></td>
+ <td><a href="index.jsp"><input type="button" value="Cancel" name="Cancel"/> </a> </td>
+ </tr>
+ </table>
+
+</form>
+
+</body>
+</html>
\ No newline at end of file