Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-843 d617759da -> e614bf237


#IGNITE-843 - WIP on server side.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/e614bf23
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/e614bf23
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/e614bf23

Branch: refs/heads/ignite-843
Commit: e614bf2377bc2ad1654fb465fdb23113776a6fb5
Parents: d617759
Author: Alexey Goncharuk <agoncha...@gridgain.com>
Authored: Wed Apr 29 19:15:27 2015 -0700
Committer: Alexey Goncharuk <agoncha...@gridgain.com>
Committed: Wed Apr 29 19:15:27 2015 -0700

----------------------------------------------------------------------
 modules/webconfig/licenses/apache-2.0.txt       | 202 +++++++++++++++++
 modules/webconfig/pom.xml                       | 137 ++++++++++++
 .../server/auth/AjaxAuthenticationHandler.java  |  80 +++++++
 .../server/auth/AuthenticationProviderImpl.java |  62 ++++++
 .../server/auth/UserAuthentication.java         | 103 +++++++++
 .../ClusterConfigurationController.java         |  57 +++++
 .../server/controller/JsonResponseBean.java     |  76 +++++++
 .../server/controller/UsersController.java      | 128 +++++++++++
 .../server/dao/ClusterConfigurationDao.java     |  41 ++++
 .../ignite/webconfig/server/dao/UserDao.java    |  45 ++++
 .../impl/MongoClusterConfigurationDaoImpl.java  |  54 +++++
 .../server/dao/impl/MongoSpringBean.java        | 103 +++++++++
 .../server/dao/impl/MongoUserDaoImpl.java       | 135 ++++++++++++
 .../server/dao/impl/MorphiaSpringBean.java      |  58 +++++
 .../webconfig/server/launcher/Launcher.java     |  44 ++++
 .../server/model/ClusterConfiguration.java      | 117 ++++++++++
 .../ignite/webconfig/server/model/User.java     | 104 +++++++++
 .../main/webapp/WEB-INF/applicationContext.xml  |  53 +++++
 .../src/main/webapp/WEB-INF/main-servlet.xml    |  10 +
 .../webconfig/src/main/webapp/WEB-INF/web.xml   |  40 ++++
 modules/webconfig/src/main/webapp/css/home.css  |  34 +++
 modules/webconfig/src/main/webapp/css/login.css | 217 +++++++++++++++++++
 modules/webconfig/src/main/webapp/home.html     |  26 +++
 modules/webconfig/src/main/webapp/js/home.js    |  20 ++
 modules/webconfig/src/main/webapp/js/login.js   | 170 +++++++++++++++
 modules/webconfig/src/main/webapp/login.html    |  36 +++
 pom.xml                                         |   1 +
 27 files changed, 2153 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/webconfig/licenses/apache-2.0.txt 
b/modules/webconfig/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/webconfig/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/pom.xml
----------------------------------------------------------------------
diff --git a/modules/webconfig/pom.xml b/modules/webconfig/pom.xml
new file mode 100644
index 0000000..2a618fd
--- /dev/null
+++ b/modules/webconfig/pom.xml
@@ -0,0 +1,137 @@
+<?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.
+-->
+
+<!--
+    POM file.
+-->
+<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";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-webconfig</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <packaging>war</packaging>
+
+    <properties>
+        <jetty.version>8.1.16.v20140903</jetty.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mongodb</groupId>
+            <artifactId>mongo-java-driver</artifactId>
+            <version>2.12.2</version>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>javax.servlet</groupId>-->
+            <!--<artifactId>servlet-api</artifactId>-->
+            <!--<version>2.5</version>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>3.2.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>3.2.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+            <version>3.2.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+            <version>3.2.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-config</artifactId>
+            <version>3.2.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jsp</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>1.8.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mongodb.morphia</groupId>
+            <artifactId>morphia</artifactId>
+            <version>0.108</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.1.3</version>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
+
+        <testResources>
+            <testResource>
+                <directory>src/test/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </testResource>
+        </testResources>
+
+        <plugins>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AjaxAuthenticationHandler.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AjaxAuthenticationHandler.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AjaxAuthenticationHandler.java
new file mode 100644
index 0000000..55d9648
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AjaxAuthenticationHandler.java
@@ -0,0 +1,80 @@
+/*
+ * 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.ignite.webconfig.server.auth;
+
+import org.springframework.security.core.*;
+import org.springframework.security.web.authentication.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.*;
+
+/**
+ *
+ */
+public class AjaxAuthenticationHandler implements 
AuthenticationSuccessHandler, AuthenticationFailureHandler {
+    /** {@inheritDoc} */
+    @Override public void onAuthenticationFailure(
+        HttpServletRequest req,
+        HttpServletResponse res,
+        AuthenticationException e
+    ) throws IOException, ServletException {
+        res.setStatus(HttpServletResponse.SC_OK);
+        res.setContentType("application/json");
+        writeResponse(res.getOutputStream(), null, e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onAuthenticationSuccess(
+        HttpServletRequest req,
+        HttpServletResponse res,
+        Authentication authentication
+    ) throws IOException, ServletException {
+        res.setStatus(HttpServletResponse.SC_OK);
+        res.setContentType("application/json");
+        writeResponse(res.getOutputStream(), authentication, null);
+    }
+
+    /**
+     * @param out Output stream.
+     * @param auth Authentication.
+     * @param e Error, if any.
+     * @throws IOException If failed to write response.
+     */
+    private void writeResponse(OutputStream out, Authentication auth, 
AuthenticationException e) throws IOException {
+        try {
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
+
+            pw.write("{\"success\": ");
+            pw.write(auth == null ? "false" : "true");
+
+            if (e != null) {
+                pw.write(", \"err\": \"");
+                pw.write(e.getMessage());
+                pw.write("\"");
+            }
+
+            pw.write("}");
+
+            pw.flush();
+        }
+        finally {
+            out.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AuthenticationProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AuthenticationProviderImpl.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AuthenticationProviderImpl.java
new file mode 100644
index 0000000..0a44220
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/AuthenticationProviderImpl.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ignite.webconfig.server.auth;
+
+import org.apache.ignite.webconfig.server.dao.*;
+import org.apache.ignite.webconfig.server.model.*;
+import org.springframework.security.authentication.*;
+import org.springframework.security.core.*;
+
+/**
+ *
+ */
+public class AuthenticationProviderImpl implements AuthenticationProvider {
+    /** */
+    private UserDao userDao;
+
+    /**
+     * @param userDao User DAO.
+     */
+    public void setUserDao(UserDao userDao) {
+        this.userDao = userDao;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Authentication authenticate(Authentication 
authentication) throws AuthenticationException {
+        String username = (String) authentication.getPrincipal();
+        String password = (String) authentication.getCredentials();
+
+        User user = userDao.findUser(username, password);
+
+        if (user == null)
+            throw new BadCredentialsException("Invalid username or password: " 
+ username);
+
+        UserAuthentication customAuthentication = new 
UserAuthentication("ROLE_USER", authentication);
+
+        customAuthentication.user(user);
+
+        customAuthentication.setAuthenticated(true);
+
+        return customAuthentication;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean supports(Class<?> authentication) {
+        return 
UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/UserAuthentication.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/UserAuthentication.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/UserAuthentication.java
new file mode 100644
index 0000000..8310447
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/auth/UserAuthentication.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ignite.webconfig.server.auth;
+
+import java.util.*;
+
+import org.apache.ignite.webconfig.server.model.*;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.*;
+
+/**
+ *
+ */
+public class UserAuthentication implements Authentication {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private boolean authenticated;
+
+    /** */
+    private Collection<GrantedAuthority> grantedAuthorities;
+
+    /** */
+    private Authentication authentication;
+
+    /** User. */
+    private User user;
+
+    /**
+     * @param role Role.
+     * @param authentication Authentication.
+     */
+    public UserAuthentication(String role, Authentication authentication) {
+        this.grantedAuthorities = 
Collections.<GrantedAuthority>singletonList(new SimpleGrantedAuthority(role));
+        this.authentication = authentication;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<GrantedAuthority> getAuthorities() {
+        return grantedAuthorities;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getCredentials() {
+        return authentication.getCredentials();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getDetails() {
+        return authentication.getDetails();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getPrincipal() {
+        return authentication.getPrincipal();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isAuthenticated() {
+        return authenticated;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void setAuthenticated(boolean authenticated) throws 
IllegalArgumentException {
+        this.authenticated = authenticated;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return this.getClass().getSimpleName();
+    }
+
+    /**
+     * @return Authenticated user.
+     */
+    public User user() {
+        return user;
+    }
+
+    /**
+     * @param user User.
+     */
+    public void user(User user) {
+        this.user = user;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/ClusterConfigurationController.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/ClusterConfigurationController.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/ClusterConfigurationController.java
new file mode 100644
index 0000000..008b152
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/ClusterConfigurationController.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.webconfig.server.controller;
+
+import org.apache.ignite.webconfig.server.dao.*;
+import org.apache.ignite.webconfig.server.model.*;
+import org.springframework.beans.factory.annotation.*;
+import org.springframework.stereotype.*;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ *
+ */
+@Controller
+@RequestMapping("/configuration")
+public class ClusterConfigurationController {
+    /** Configuration DAO. */
+    @Autowired
+    private ClusterConfigurationDao cfgDao;
+
+    /**
+     * @param cfgDao Configuration DAO.
+     */
+    public void setCfgDao(ClusterConfigurationDao cfgDao) {
+        this.cfgDao = cfgDao;
+    }
+
+    /**
+     * @param cfg Configuration to save.
+     * @return Response body.
+     */
+    @ResponseBody
+    @RequestMapping(value = "save.do", method = RequestMethod.POST)
+    public JsonResponseBean saveConfiguration(@RequestBody 
ClusterConfiguration cfg) {
+        cfg = cfgDao.saveConfiguration(cfg);
+
+        JsonResponseBean res = new JsonResponseBean(true, null);
+
+        res.addField("cfg", cfg);
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/JsonResponseBean.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/JsonResponseBean.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/JsonResponseBean.java
new file mode 100644
index 0000000..36eb993
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/JsonResponseBean.java
@@ -0,0 +1,76 @@
+/*
+ * 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.ignite.webconfig.server.controller;
+
+import org.codehaus.jackson.annotate.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public class JsonResponseBean {
+    /** */
+    @JsonProperty("success")
+    private boolean success;
+
+    /** */
+    @JsonProperty("err")
+    private String err;
+
+    /** */
+    @JsonProperty("data")
+    private Map<String, Object> fields;
+
+    /**
+     * @param success Success flag.
+     * @param err Error message.
+     */
+    public JsonResponseBean(boolean success, String err) {
+        this.success = success;
+        this.err = err;
+    }
+
+    /**
+     * @param key Key.
+     * @param val Value.
+     */
+    public void addField(String key, Object val) {
+        if (fields == null)
+            fields = new HashMap<>();
+
+        fields.put(key, val);
+    }
+
+    /**
+     * @return JSON string.
+     */
+    public String toJson() {
+        StringBuilder sb = new StringBuilder("{\"success\":").append(success)
+                .append(", \"err\":\"").append(err).append("\"");
+
+        if (fields != null) {
+            for (Map.Entry<String, Object> entry : fields.entrySet())
+                sb.append(", 
\"").append(entry.getKey()).append("\":").append(entry.getValue());
+        }
+
+        sb.append("}");
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/UsersController.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/UsersController.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/UsersController.java
new file mode 100644
index 0000000..71444d7
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/controller/UsersController.java
@@ -0,0 +1,128 @@
+/*
+ * 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.ignite.webconfig.server.controller;
+
+import org.apache.ignite.webconfig.server.auth.*;
+import org.apache.ignite.webconfig.server.dao.*;
+import org.apache.ignite.webconfig.server.model.*;
+import org.springframework.beans.factory.annotation.*;
+import org.springframework.http.*;
+import org.springframework.security.authentication.*;
+import org.springframework.security.core.*;
+import org.springframework.security.core.context.*;
+import org.springframework.security.web.authentication.*;
+import org.springframework.stereotype.*;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.*;
+
+/**
+ *
+ */
+@Controller
+@RequestMapping("/users")
+public class UsersController {
+    /** */
+    @Autowired
+    private UserDao userDao;
+
+    /** */
+    @Autowired
+    private AuthenticationManager authenticationManager;
+
+    /**
+     * @param userDao User DAO.
+     */
+    public void setUserDao(UserDao userDao) {
+        this.userDao = userDao;
+    }
+
+    /**
+     * @param authenticationManager Authentication manager.
+     */
+    public void setAuthenticationManager(AuthenticationManager 
authenticationManager) {
+        this.authenticationManager = authenticationManager;
+    }
+
+    /**
+     * @param login User name.
+     * @param password User password.
+     * @param confirmPassword Confirmed user password.
+     * @return Response body.
+     */
+    @ResponseBody
+    @RequestMapping(value = "register.do", method = RequestMethod.POST)
+    public ResponseEntity<String> registerUser(
+        @RequestParam("login") String login,
+        @RequestParam("password") String password,
+        @RequestParam("confirmPassword") String confirmPassword,
+        HttpServletRequest request,
+        HttpServletResponse response) {
+        if (!password.equals(confirmPassword))
+            return new ResponseEntity<>("Passwords do not match.", 
HttpStatus.BAD_REQUEST);
+
+        User user = new User(login);
+
+        user = userDao.createUser(user, password);
+
+        JsonResponseBean res = new JsonResponseBean(user != null, user == null 
? "User with the given login already exists" : "");
+
+        if (user != null) {
+            String username = user.login();
+
+            UsernamePasswordAuthenticationToken token = new 
UsernamePasswordAuthenticationToken(username, password);
+
+            // generate session if one doesn't exist
+            request.getSession();
+
+            token.setDetails(new WebAuthenticationDetails(request));
+
+            Authentication authenticatedUser = 
authenticationManager.authenticate(token);
+
+            
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
+
+            res.addField("user", user.toJson());
+        }
+
+        HttpHeaders hdrs = new HttpHeaders();
+
+        hdrs.setContentType(MediaType.APPLICATION_JSON);
+
+        return new ResponseEntity<>(res.toJson(), hdrs, HttpStatus.OK);
+    }
+
+    /**
+     * @return Response body.
+     */
+    @ResponseBody
+    @RequestMapping(value = "current.do", method = RequestMethod.POST)
+    public ResponseEntity<String> currentUser() {
+        UserAuthentication auth = (UserAuthentication) 
SecurityContextHolder.getContext().getAuthentication();
+
+        JsonResponseBean res = new JsonResponseBean(auth != null, auth == null 
? "Not authenticated" : "");
+
+        if (auth != null)
+            res.addField("user", auth.user().toJson());
+
+        HttpHeaders hdrs = new HttpHeaders();
+
+        hdrs.setContentType(MediaType.APPLICATION_JSON);
+
+        return new ResponseEntity<>(res.toJson(), hdrs, HttpStatus.OK);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/ClusterConfigurationDao.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/ClusterConfigurationDao.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/ClusterConfigurationDao.java
new file mode 100644
index 0000000..7ad029e
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/ClusterConfigurationDao.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ignite.webconfig.server.dao;
+
+import org.apache.ignite.webconfig.server.model.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public interface ClusterConfigurationDao {
+    /**
+     * @return Gets collection of all saved configurations.
+     */
+    public Collection<ClusterConfiguration> allConfigurations();
+
+    /**
+     * @param cfg Cluster configuration to save.
+     */
+    public ClusterConfiguration saveConfiguration(ClusterConfiguration cfg);
+
+    /**
+     * @param cfg Cluster configuration to remove.
+     */
+    public void deleteConfiguration(ClusterConfiguration cfg);
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/UserDao.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/UserDao.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/UserDao.java
new file mode 100644
index 0000000..b5a5c43
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/UserDao.java
@@ -0,0 +1,45 @@
+/*
+ * 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.ignite.webconfig.server.dao;
+
+import org.apache.ignite.webconfig.server.model.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public interface UserDao {
+    /**
+     * @param username Username.
+     * @param password Password.
+     * @return Found user or {@code null}.
+     */
+    public User findUser(String username, String password);
+
+    /**
+     * @param user User to create.
+     * @return Created user.
+     */
+    public User createUser(User user, String password);
+
+    /**
+     * @return Collection of all users.
+     */
+    public Collection<User> allUsers();
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoClusterConfigurationDaoImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoClusterConfigurationDaoImpl.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoClusterConfigurationDaoImpl.java
new file mode 100644
index 0000000..dd4f92e
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoClusterConfigurationDaoImpl.java
@@ -0,0 +1,54 @@
+/*
+ * 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.ignite.webconfig.server.dao.impl;
+
+import org.apache.ignite.webconfig.server.dao.*;
+import org.apache.ignite.webconfig.server.model.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public class MongoClusterConfigurationDaoImpl implements 
ClusterConfigurationDao {
+    /** Morphia spring bean. */
+    private MorphiaSpringBean morphiaSpringBean;
+
+    /**
+     * @param morphiaSpringBean Morphia spring bean.
+     */
+    public void setMorphiaSpringBean(MorphiaSpringBean morphiaSpringBean) {
+        this.morphiaSpringBean = morphiaSpringBean;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<ClusterConfiguration> allConfigurations() {
+        return 
morphiaSpringBean.datastore().find(ClusterConfiguration.class).asList();
+    }
+
+    /** {@inheritDoc} */
+    @Override public ClusterConfiguration 
saveConfiguration(ClusterConfiguration cfg) {
+        morphiaSpringBean.datastore().save(cfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void deleteConfiguration(ClusterConfiguration cfg) {
+        morphiaSpringBean.datastore().delete(cfg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoSpringBean.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoSpringBean.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoSpringBean.java
new file mode 100644
index 0000000..8c7d8cf
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoSpringBean.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ignite.webconfig.server.dao.impl;
+
+import com.mongodb.*;
+import org.springframework.beans.factory.*;
+
+/**
+ * Utility class providing connection to mongo DB.
+ */
+public class MongoSpringBean implements InitializingBean {
+    /** */
+    private String host;
+
+    /** */
+    private int port;
+
+    /** */
+    private String dbName;
+
+    /** Mongo client. */
+    private MongoClient client;
+
+    /** DB instance. */
+    private DB db;
+
+    /** {@inheritDoc} */
+    @Override public void afterPropertiesSet() throws Exception {
+        client = port == 0 ? new MongoClient(host) : new MongoClient(host, 
port);
+
+        db = client.getDB(dbName);
+    }
+
+    /**
+     * @return Host.
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * @param host Host.
+     */
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    /**
+     * @return Port.
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * @param port Port.
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * @return DB name.
+     */
+    public String getDbName() {
+        return dbName;
+    }
+
+    /**
+     * @param dbName DB name.
+     */
+    public void setDbName(String dbName) {
+        this.dbName = dbName;
+    }
+
+    /**
+     * @return Mongo client.
+     */
+    public MongoClient client() {
+        return client;
+    }
+
+    /**
+     * @return Database instance.
+     */
+    public DB db() {
+        return db;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoUserDaoImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoUserDaoImpl.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoUserDaoImpl.java
new file mode 100644
index 0000000..0a9a701
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MongoUserDaoImpl.java
@@ -0,0 +1,135 @@
+/*
+ * 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.ignite.webconfig.server.dao.impl;
+
+import com.mongodb.*;
+import org.apache.ignite.webconfig.server.dao.*;
+import org.apache.ignite.webconfig.server.model.*;
+import org.bson.types.*;
+import org.springframework.beans.factory.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public class MongoUserDaoImpl implements UserDao, InitializingBean {
+    /** */
+    private MongoSpringBean mongo;
+
+    /**
+     * @param mongo Mongo spring bean.
+     */
+    public void setMongo(MongoSpringBean mongo) {
+        this.mongo = mongo;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void afterPropertiesSet() throws Exception {
+        try {
+            mongo.db().getCollection("users").createIndex(new 
BasicDBObject("login", 1), new BasicDBObject("unique", true));
+        }
+        catch (Exception ignored) {
+            // No-op.
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public User findUser(String login, String password) {
+        DBCollection users = db().getCollection("users");
+
+        DBObject search = new BasicDBObject("login", login).append("pass", 
password);
+
+        try (DBCursor cur = users.find(search)) {
+            if (cur.hasNext()) {
+                DBObject user = cur.next();
+
+                return userFromDbObject(user);
+            }
+        }
+
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public User createUser(User user, String password) {
+        try {
+            BasicDBObject usr = new BasicDBObject("login", 
user.login()).append("pass", password);
+
+            db().getCollection("users").insert(usr);
+
+            ObjectId id = (ObjectId)usr.get("_id");
+
+            if (id != null)
+                user.id(id.toHexString());
+
+            return user;
+        }
+        catch (DuplicateKeyException e) {
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<User> allUsers() {
+        Collection<User> res = new ArrayList<>();
+
+        try (DBCursor cur = db().getCollection("users").find()) {
+            while (cur.hasNext()) {
+                DBObject usrObj = cur.next();
+
+                res.add(userFromDbObject(usrObj));
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * @return Mongo database.
+     */
+    private DB db() {
+        return mongo.db();
+    }
+
+    /**
+     * @param obj Object to build user from.
+     * @return User.
+     */
+    private User userFromDbObject(DBObject obj) {
+        User usr = new User((String)obj.get("login"));
+
+        ObjectId id = (ObjectId)obj.get("_id");
+
+        if (id != null)
+            usr.id(id.toHexString());
+
+        return usr;
+    }
+
+    public static void main(String[] args) throws Exception {
+        MongoSpringBean bean = new MongoSpringBean();
+
+        bean.setHost("localhost");
+        bean.setDbName("igniteweb");
+
+        bean.afterPropertiesSet();
+
+//        bean.db().getCollection("users").dropIndexes();
+        bean.db().getCollection("users").remove(new BasicDBObject());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MorphiaSpringBean.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MorphiaSpringBean.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MorphiaSpringBean.java
new file mode 100644
index 0000000..a341339
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/dao/impl/MorphiaSpringBean.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ignite.webconfig.server.dao.impl;
+
+import org.apache.ignite.webconfig.server.model.*;
+import org.mongodb.morphia.*;
+import org.springframework.beans.factory.*;
+
+/**
+ *
+ */
+public class MorphiaSpringBean implements InitializingBean {
+    /** Morphia instance. */
+    private Morphia morphia;
+
+    /** Mongo spring bean. */
+    private MongoSpringBean mongo;
+
+    /** Datastore instance. */
+    private Datastore datastore;
+
+    /**
+     * @param mongo Mongo bean.
+     */
+    public void setMongo(MongoSpringBean mongo) {
+        this.mongo = mongo;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void afterPropertiesSet() throws Exception {
+        morphia = new Morphia();
+
+        morphia.mapPackage(User.class.getPackage().getName());
+
+        datastore = morphia.createDatastore(mongo.client(), mongo.getDbName());
+    }
+
+    /**
+     * @return Datastore.
+     */
+    public Datastore datastore() {
+        return datastore;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/launcher/Launcher.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/launcher/Launcher.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/launcher/Launcher.java
new file mode 100644
index 0000000..6b8a085
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/launcher/Launcher.java
@@ -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.
+ */
+package org.apache.ignite.webconfig.server.launcher;
+
+import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.server.nio.*;
+import org.eclipse.jetty.webapp.*;
+
+/**
+ *
+ */
+public class Launcher {
+    public static void main(String[] args) throws Exception {
+        Server srv = new Server();
+
+        SelectChannelConnector connector = new SelectChannelConnector();
+
+        connector.setPort(9999);
+
+        srv.addConnector(connector);
+
+        WebAppContext ctx = new WebAppContext("src/main/webapp", "/");
+
+        srv.setHandler(ctx);
+
+        srv.start();
+        srv.join();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/ClusterConfiguration.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/ClusterConfiguration.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/ClusterConfiguration.java
new file mode 100644
index 0000000..94c57e3
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/ClusterConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * 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.ignite.webconfig.server.model;
+
+import org.bson.types.*;
+import org.codehaus.jackson.annotate.*;
+import org.mongodb.morphia.annotations.*;
+
+/**
+ *
+ */
+@Entity("clusterConfiguration")
+public class ClusterConfiguration {
+    /** Object ID. */
+    @Id private ObjectId id;
+
+    /** */
+    @JsonProperty("idStr")
+    @Transient private String idStr;
+
+    /** Cluster name. */
+    @JsonProperty("name")
+    private String name;
+
+    /** Max memory. */
+    @JsonProperty("maxMemory")
+    private long maxMemory;
+
+    /**
+     * @return Object ID.
+     */
+    public String id() {
+        return idStr;
+    }
+
+    /**
+     * @param idStr ID string.
+     */
+    public void id(String idStr) {
+        this.idStr = idStr;
+    }
+
+    /**
+     * @return Name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * @param name Name.
+     */
+    public void name(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return Max memory.
+     */
+    public long maxMemory() {
+        return maxMemory;
+    }
+
+    /**
+     * @param maxMemory Max memory.
+     */
+    public void maxMemory(long maxMemory) {
+        this.maxMemory = maxMemory;
+    }
+
+    /**
+     * Pre-persist callback.
+     */
+    @PrePersist
+    public void prePersist() {
+        if (id == null && idStr != null)
+            id = new ObjectId(idStr);
+    }
+
+    /**
+     * Post persist callback.
+     */
+    @PostPersist
+    public void postPersist() {
+        initIdStr();
+    }
+
+    /**
+     * Post-load callback.
+     */
+    @PostLoad
+    public void postLoad() {
+        initIdStr();
+    }
+
+    /**
+     *
+     */
+    private void initIdStr() {
+        if (idStr == null && id != null)
+            idStr = id.toHexString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/User.java
----------------------------------------------------------------------
diff --git 
a/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/User.java
 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/User.java
new file mode 100644
index 0000000..806575c
--- /dev/null
+++ 
b/modules/webconfig/src/main/java/org/apache/ignite/webconfig/server/model/User.java
@@ -0,0 +1,104 @@
+/*
+ * 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.ignite.webconfig.server.model;
+
+/**
+ *
+ */
+public class User {
+    /** */
+    private String id;
+
+    /** */
+    private String login;
+
+    /** */
+    private String name;
+
+    /**
+     *
+     */
+    public User() {
+        // No-op.
+    }
+
+    /**
+     * @param login Login.
+     */
+    public User(String login) {
+        this.login = login;
+    }
+
+    /**
+     * @return ID.
+     */
+    public String id() {
+        return id;
+    }
+
+    /**
+     * @param id ID.
+     */
+    public void id(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return User login.
+     */
+    public String login() {
+        return login;
+    }
+
+    /**
+     * @param login Login.
+     */
+    public void login(String login) {
+        this.login = login;
+    }
+
+    /**
+     * @return User name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * @param name User name.
+     */
+    public void name(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return JSON user representation.
+     */
+    public String toJson() {
+        StringBuilder sb = new StringBuilder("{\"id\":\"").append(id)
+            .append("\", \"login\":\"").append(login)
+            .append("\", \"name\":");
+        if (name == null)
+            sb.append("null");
+        else
+            sb.append("\"").append(name).append("\"");
+
+        sb.append("}");
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/WEB-INF/applicationContext.xml 
b/modules/webconfig/src/main/webapp/WEB-INF/applicationContext.xml
new file mode 100644
index 0000000..9434915
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/WEB-INF/applicationContext.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/security";
+             xmlns:beans="http://www.springframework.org/schema/beans";
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:mvc="http://www.springframework.org/schema/mvc";
+             xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
+                                 
http://www.springframework.org/schema/security 
http://www.springframework.org/schema/security/spring-security-3.2.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd";>
+    <http auto-config="true">
+        <intercept-url pattern="/login.html" 
access="IS_AUTHENTICATED_ANONYMOUSLY"/>
+        <intercept-url pattern="/users/*.do" 
access="IS_AUTHENTICATED_ANONYMOUSLY"/>
+
+        <intercept-url pattern="/**/*.html" access="ROLE_USER"/>
+
+        <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
+
+        <form-login
+            login-page="/login.html"
+            default-target-url="/home.html"
+            login-processing-url="/login.do"
+
+            username-parameter="login"
+            password-parameter="password"
+            authentication-success-handler-ref="authHandler"
+            authentication-failure-handler-ref="authHandler"/>
+        <logout logout-success-url="/login.html" logout-url="/logout.do"/>
+    </http>
+
+    <beans:bean id="authHandler" 
class="org.apache.ignite.webconfig.server.auth.AjaxAuthenticationHandler"/>
+
+    <beans:bean id="customAuthenticationProvider" 
class="org.apache.ignite.webconfig.server.auth.AuthenticationProviderImpl">
+        <beans:property name="userDao" ref="userDao"/>
+    </beans:bean>
+
+    <beans:bean id="userDao" 
class="org.apache.ignite.webconfig.server.dao.impl.MongoUserDaoImpl">
+        <beans:property name="mongo" ref="mongo"/>
+    </beans:bean>
+
+    <beans:bean id="cfgDao" 
class="org.apache.ignite.webconfig.server.dao.impl.MongoClusterConfigurationDaoImpl">
+        <beans:property name="morphiaSpringBean" ref="morphia"/>
+    </beans:bean>
+
+    <beans:bean id="mongo" 
class="org.apache.ignite.webconfig.server.dao.impl.MongoSpringBean">
+        <beans:property name="host" value="localhost"/>
+        <beans:property name="dbName" value="igniteweb"/>
+    </beans:bean>
+
+    <beans:bean id="morphia" 
class="org.apache.ignite.webconfig.server.dao.impl.MorphiaSpringBean">
+        <beans:property name="mongo" ref="mongo"/>
+    </beans:bean>
+
+    <authentication-manager alias="authenticationManager">
+        <authentication-provider ref="customAuthenticationProvider"/>
+    </authentication-manager>
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/WEB-INF/main-servlet.xml
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/WEB-INF/main-servlet.xml 
b/modules/webconfig/src/main/webapp/WEB-INF/main-servlet.xml
new file mode 100644
index 0000000..468f8d3
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/WEB-INF/main-servlet.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/security";
+             xmlns:beans="http://www.springframework.org/schema/beans";
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:mvc="http://www.springframework.org/schema/mvc";
+             xmlns:context="http://www.springframework.org/schema/context";
+             xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
+                                 
http://www.springframework.org/schema/security 
http://www.springframework.org/schema/security/spring-security-3.2.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd";>
+    <mvc:annotation-driven/>
+    <context:component-scan 
base-package="org.apache.ignite.webconfig.server.controller" />
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/WEB-INF/web.xml 
b/modules/webconfig/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..2e16219
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app
+        PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+        "http://java.sun.com/dtd/web-app_2_3.dtd";>
+
+<web-app>
+    <filter>
+        <filter-name>springSecurityFilterChain</filter-name>
+        
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>springSecurityFilterChain</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <listener>
+        
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+    </listener>
+
+    <!-- Servlets -->
+    <servlet>
+        <servlet-name>main</servlet-name>
+        
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+        <init-param>
+            <param-name>serviceURLMapper</param-name>
+            <param-value>serviceURLMapper</param-value>
+        </init-param>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>main</servlet-name>
+        <url-pattern>*.do</url-pattern>
+    </servlet-mapping>
+
+    <!-- Default page to serve -->
+    <welcome-file-list>
+        <welcome-file>login.html</welcome-file>
+    </welcome-file-list>
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/css/home.css
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/css/home.css 
b/modules/webconfig/src/main/webapp/css/home.css
new file mode 100644
index 0000000..785f121
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/css/home.css
@@ -0,0 +1,34 @@
+body {
+    background: rgb(40, 40, 40);
+    color: #ffffff;
+}
+
+#menu {
+    float: left;
+    width: 185px;
+}
+
+#menu ul {
+    margin: 0;
+    padding: 0;
+    list-style-type: none;
+}
+
+#menu ul li a {
+    text-decoration: none;
+    color: white;
+    padding: 10px 11px;
+    display: block;
+}
+
+#menu ul li a:visited {
+    color: white;
+}
+
+#menu ul li a:hover, #menu ul li .current {
+    color: rgb(248, 0, 0);
+}
+
+#container {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/css/login.css
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/css/login.css 
b/modules/webconfig/src/main/webapp/css/login.css
new file mode 100644
index 0000000..be024ca
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/css/login.css
@@ -0,0 +1,217 @@
+/*!
+ * Sign Up/Login Box v0.0.1 (http://codepen.io/koheishingai/FLvgs)
+ * Copyright 2014 Kohei Shingai.
+ * Licensed under MIT
+ */
+
+#sumsk {
+    position: absolute;
+    width: 100%;
+    height: 282px;
+    z-index: 9999;
+    display: none;
+    color: rgba(0, 0, 0, 0.66);
+    text-align: center;
+    line-height: 279px;
+    box-shadow: inset 0px 0px 50px rgba(0, 0, 0, 0.5);
+    text-shadow: 0px 0px rgba(255, 255, 255, 0.57);
+}
+
+#err {
+    margin: 0 37px;
+    color: rgba(68, 68, 68, 0.78);
+    display: none;
+}
+
+#err {
+    margin-top: 13px;
+    margin-bottom: 1px;
+}
+
+#signup,#welcome,#name,#pass,#signupb,#logoutb {
+    transition: all 0.3s ease 0s;
+    -webkit-transition: all 0.3s ease 0s;
+    -moz-transition: all 0.3s ease 0s;
+    -o-transition: all 0.3s ease 0s;
+}
+
+#logint:hover {
+    text-decoration: underline;
+}
+
+#logint {
+    color: rgba(66, 134, 237, 0.78);
+    cursor: pointer;
+    text-decoration: none;
+    width: 100%;
+    margin: -4px 37px;
+    font-size: 14px;
+    position: absolute;
+    left: 0px;
+    bottom: 15px;
+}
+
+#name {
+    -moz-appearance: none;
+    -webkit-appearance: none;
+    padding: 0 8px;
+    margin: 44px auto;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-top: 1px solid silver;
+    -moz-border-radius: 1px;
+    -webkit-border-radius: 1px;
+    border-radius: 1px;
+    color: #838383;
+    width: 409px;
+    display: block;
+    margin-bottom: 10px;
+    z-index: 1;
+    position: relative;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    direction: ltr;
+    height: 44px;
+    font-size: 16px;
+    text-align: left;
+}
+
+#password,#confirmpassword {
+    -moz-appearance: none;
+    -webkit-appearance: none;
+    padding: 0 8px;
+    margin: 16px auto;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-top: 1px solid silver;
+    -moz-border-radius: 1px;
+    -webkit-border-radius: 1px;
+    border-radius: 1px;
+    color: #838383;
+    width: 409px;
+    display: block;
+    margin-bottom: 10px;
+    z-index: 1;
+    position: relative;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    direction: ltr;
+    height: 44px;
+    font-size: 16px;
+    text-align: left;
+}
+
+#name:hover,#pass:hover {
+    border: 1px solid #b9b9b9;
+    -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
+    -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
+    box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
+}
+
+#signup,#welcome {
+    margin: 0px;
+    padding: 3px 0px 9px;
+    color: rgb(255, 255, 255);
+    width: 100%;
+    text-align: center;
+    font-weight: normal;
+    background: rgb(248, 0, 0);
+    font-size: 22px;
+}
+
+#signupb,#logoutb {
+    border: 2px solid #E78282;
+    display: inline-block;
+    line-height: 23px;
+    padding: 5px 18px;
+    -webkit-border-radius: 2px;
+    background: #f37676;
+    font-weight: normal;
+    margin: 10px 0 0 0;
+    color: #fff;
+    position: absolute;
+    right: 9px;
+    bottom: 9px;
+    font-size: 17px;
+    width: 103px;
+    height: 35px;
+    outline: none;
+    cursor: pointer;
+}
+
+#userbox {
+    position: absolute;
+    width: 480px;
+    height: 324px;
+    background: white;
+    top: 50%;
+    margin-top: -174px;
+    left: 50%;
+    margin-left: -240px;
+}
+
+#logmsk {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    z-index: 9999;
+    background: rgb(40, 40, 40);
+    display: none;
+}
+
+body {
+    width: 100%;
+    height: 100%;
+    min-width: 300px;
+    min-height: 500px;
+    overflow: hidden;
+    margin: 0;
+    padding: 0;
+    position: absolute;
+    background: #fff;
+    color: #333;
+}
+
+body,input,select,td,textarea {
+    font-family: "Open Sans",sans-serif;
+}
+
+#header {
+    font: 13px/27px;
+    position: relative;
+    height: 60px;
+    width: 100%;
+    background: #f1f1f1;
+    white-space: nowrap;
+    display: -webkit-flex;
+    display: flex;
+    margin-left: 0!important;
+    margin-right: 0!important;
+}
+
+#login {
+    color: #fff;
+    margin-top: 9px;
+    display: block;
+    height: 40px;
+    width: 40px;
+    -webkit-border-radius: 40px;
+    -moz-border-radius: 40px;
+    -ms-border-radius: 40px;
+    -o-border-radius: 40px;
+    border-radius: 40px;
+    -webkit-transition: all .05s;
+    -moz-transition: all .05s;
+    -o-transition: all .05s;
+    transition: all .05s;
+    background-color: #FFF;
+    position: absolute;
+    right: 12px;
+    cursor: pointer;
+}
+
+#login:hover {
+    background: 0 0;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/home.html
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/home.html 
b/modules/webconfig/src/main/webapp/home.html
new file mode 100644
index 0000000..02bb593
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/home.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Ignite Configuration Tools</title>
+    <link rel="stylesheet" href="css/home.css">
+</head>
+
+<body>
+<script 
src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";></script>
+
+<div id="menu">
+    <ul>
+        <li><a href="#">Clusters</a></li>
+        <li><a href="#">Caches</a></li>
+        <li><a href="#">Persistance</a></li>
+        <li><a href="#">Clients</a></li>
+    </ul>
+</div>
+<div id="container">
+    <input type="button" onclick="saveConfiguration(null, 'myCfg', 10)" 
value="Save"/>
+</div>
+
+<script src="js/home.js"></script>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/js/home.js
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/js/home.js 
b/modules/webconfig/src/main/webapp/js/home.js
new file mode 100644
index 0000000..b217303
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/js/home.js
@@ -0,0 +1,20 @@
+$(function () {
+
+});
+
+function saveConfiguration(id, name, maxMemory) {
+    var cfg = {idStr:id, name: name, maxMemory: maxMemory};
+
+    $.ajax({
+        url : "configuration/save.do",
+        type: "POST",
+        data : JSON.stringify(cfg),
+        contentType: "application/json",
+        success: function(data, textStatus, jqXHR) {
+            alert("Success:" + data);
+        },
+        error: function (jqXHR, textStatus, errorThrown) {
+            alert("Error: " + errorThrown);
+        }
+    });
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/js/login.js
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/js/login.js 
b/modules/webconfig/src/main/webapp/js/login.js
new file mode 100644
index 0000000..2af8a08
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/js/login.js
@@ -0,0 +1,170 @@
+$(function () {
+    var flg = {
+        loginFlag:true,
+        inProgress:false,
+        nameValid: -1,
+        passValid: -1
+    };
+
+    switchLoginSignup(flg.loginFlag);
+
+    $('#logint').click(function () {
+        if (flg.inProgress)
+            return;
+
+        resetFields();
+
+        flg.loginFlag = !flg.loginFlag;
+
+        switchLoginSignup(flg.loginFlag);
+    });
+
+    $("#name").keyup(validateForm());
+    $("#password").keyup(validateForm);
+    $("#confirmpassword").keyup(validateForm);
+
+    function validateForm() {
+        var valid = true;
+        var err = null;
+
+        var name = $('#name');
+
+        var len = name.val().length;
+
+        if (len > 13 || len == 0) {
+            if (len != 0) {
+                name.css('background', 'rgb(255, 214, 190)');
+                err = "ID: Too long"
+            }
+            else
+                name.css('background', 'rgb(255, 255, 255)');
+
+            valid = false;
+        }
+        else
+            name.css('background', 'rgb(255, 255, 255)');
+
+        var pass = $('#password');
+
+        len = pass.val().length;
+
+        if (len > 10 || len == 0) {
+            if (len > 10) {
+                pass.css('background', 'rgb(255, 214, 190)');
+                err = "Password: Too long";
+            }
+            else
+                pass.css('background', 'rgb(255, 255, 255)');
+
+            valid = false;
+        }
+        else
+            pass.css('background', 'rgb(255, 255, 255)');
+
+        if (!flg.loginFlag) {
+            var confPass = $('#confirmpassword');
+
+            len = confPass.val().length;
+
+            if (len > 10 || len == 0) {
+                if (len > 10) {
+                    confPass.css('background', 'rgb(255, 214, 190)');
+                    err = 'Confirm Password: Too long';
+                }
+                else
+                    confPass.css('background', 'rgb(255, 255, 255)');
+
+                valid = false;
+            }
+            else
+                confPass.css('background', 'rgb(255, 255, 255)');
+
+            if (valid) {
+                var passVal = pass.val();
+                var confPassVal = confPass.val();
+
+                if (passVal.length > 0 && confPassVal.length > 0 && !(passVal 
=== confPassVal)) {
+                    err = "Passwords do not match";
+                    valid = false;
+                }
+            }
+        }
+
+        flg.valid = valid;
+
+        if (err != null)
+            $('#err').css('color', 'rgb(255, 57, 19)').text(err).fadeIn();
+        else
+            $("#err").fadeOut();
+
+        if (valid)
+            $('#signupb').css('opacity', '1').css('cursor', 'pointer');
+        else
+            $('#signupb').css('opacity', '0.2').css('cursor', 'default');
+    }
+
+    $('#signupb').click(function () {
+        if (flg.valid && !flg.inProgress) {
+            $('#name, #password, #logint, #err, #signupb').css('opacity', 
'0.2');
+
+            flg.inProgress = true;
+
+            loginOrSignup();
+        }
+    });
+
+    function resetFields() {
+        flg.valid = true;
+        $('#err').hide();
+        $('#name, #password, #logint, #err, #signupb').css('opacity', '1');
+        $('#name').css('background', 'rgb(255, 255, 255)');
+        $('#password').css('background', 'rgb(255, 255, 255)');
+        $('#signupb').css('opacity', '0.2').css('cursor', 'default');
+        $('#name, #password, #confirmpassword').val('')
+    }
+
+    function switchLoginSignup(login) {
+        if (!login) {
+            $('#signup').text('Sign up');
+            $('#signupb').text('Sign up');
+            $('#confirmpassword').fadeIn();
+            $('#logint').text('Login as an existing user')
+        } else {
+            $('#signup').text('Login');
+            $('#signupb').text('Login');
+            $('#confirmpassword').fadeOut();
+            $('#logint').text('Sign up as a new user')
+        }
+    }
+
+    function loginOrSignup() {
+        var formData = {login:$("#name").val(), password:$("#password").val(), 
confirmPassword:$("#confirmpassword").val()};
+        var url = flg.loginFlag == 1 ? "login.do" : "users/register.do";
+
+        $.ajax({
+            url : url,
+            type: "POST",
+            data : formData,
+            success: function(data, textStatus, jqXHR) {
+                flg.inProgress = false;
+
+                if (data.success) {
+                    // Logged in, redirect to home page.
+                    window.location.replace("home.html");
+                }
+                else {
+                    $('#name, #password, #err, #logint, 
#signupb').css('opacity', '1');
+
+                    $("#err").css('color', 'rgb(255, 57, 
19)').text(data.err).fadeIn();
+                }
+            },
+            error: function (jqXHR, textStatus, errorThrown) {
+                $('#name, #password, #logint, #err, #signupb').css('opacity', 
'1');
+
+                $("#err").text("Unexpected error occurred: " + 
errorThrown).fadeIn();
+
+                flg.inProgress = false;
+            }
+        });
+    }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/modules/webconfig/src/main/webapp/login.html
----------------------------------------------------------------------
diff --git a/modules/webconfig/src/main/webapp/login.html 
b/modules/webconfig/src/main/webapp/login.html
new file mode 100644
index 0000000..732d642
--- /dev/null
+++ b/modules/webconfig/src/main/webapp/login.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Ignite Configuration Tools</title>
+    <link rel="stylesheet" href="css/login.css">
+</head>
+
+<body>
+<script 
src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";></script>
+<div id="logmsk" style="display: block;">
+    <div id="userbox">
+        <h1 id="signup" style="background-repeat: initial;">
+            Login
+        </h1>
+
+        <input id="name" placeholder="ID"
+               style="opacity: 1; background-color: rgb(255, 255, 255); 
background-repeat: initial;">
+        <input id="password" type="password" placeholder="Password"
+               style="opacity: 1; background-color: rgb(255, 255, 255); 
background-repeat: initial;">
+
+        <input id="confirmpassword" type="password" placeholder="Confirm 
Password"
+               style="opacity: 1; background-color: rgb(255, 255, 255); 
background-repeat: initial; display: none">
+
+        <p id="err" style="display: none; opacity: 1;">ID:</p>
+
+        <span id="logint" style="opacity: 1;">Sign up as a new user</span>
+        <button id="signupb" style="opacity: 0.2; cursor: 
default;">Login</button>
+    </div>
+</div>
+
+<script src="js/login.js"></script>
+
+</body>
+
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e614bf23/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e1badec..8635f8f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
         <module>modules/slf4j</module>
         <module>modules/jcl</module>
         <module>modules/schema-import</module>
+        <module>modules/webconfig</module>
         <module>modules/codegen</module>
         <module>modules/gce</module>
         <module>modules/cloud</module>

Reply via email to