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>&nbsp;</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>&nbsp;</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