You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by mg...@apache.org on 2014/12/29 21:13:46 UTC

[4/6] isis git commit: ISIS-987 Provide some sort of mechanism to allow users to self-register for an Isis application.

ISIS-987 Provide some sort of mechanism to allow users to self-register for an Isis application.

Add register (email), verify, register user data flow.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/3bd8294d
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/3bd8294d
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/3bd8294d

Branch: refs/heads/ISIS-987
Commit: 3bd8294d6410b4a02baa9384ba7193f8c12dcf0c
Parents: 46758a3
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Dec 29 17:57:30 2014 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Dec 29 22:13:13 2014 +0200

----------------------------------------------------------------------
 .../wicket/viewer/IsisWicketApplication.java    |   7 +-
 .../viewer/wicket/viewer/IsisWicketModule.java  |   6 +-
 .../registries/pages/PageClassListDefault.java  |   9 +-
 .../wicket/ui/pages/login/IsisSignInPanel.html  |   2 +-
 .../wicket/ui/pages/login/IsisSignInPanel.java  |  24 ++-
 .../wicket/ui/pages/register/RegisterPage.html  |  30 +---
 .../wicket/ui/pages/register/RegisterPage.java  | 117 ++------------
 .../ui/pages/register/RegisterPage.properties   |  30 ++++
 .../wicket/ui/pages/register/RegisterPanel.html |  37 +++++
 .../wicket/ui/pages/register/RegisterPanel.java | 135 ++++++++++++++++
 .../wicket/ui/pages/register/Registree.java     |  49 ++++++
 .../ui/pages/signup/AccountConfirmationMap.java | 154 +++++++++++++++++++
 .../wicket/ui/pages/signup/IsisSignUpPanel.html |  38 -----
 .../wicket/ui/pages/signup/IsisSignUpPanel.java |  73 ---------
 .../ui/pages/signup/RegistrationFormPage.css    | 100 ++++++++++++
 .../ui/pages/signup/RegistrationFormPage.html   |  66 ++++++++
 .../ui/pages/signup/RegistrationFormPage.java   | 140 +++++++++++++++++
 .../signup/RegistrationFormPage.properties      |  25 +++
 .../wicket/ui/pages/signup/SignUpPanel.html     |  34 ++++
 .../wicket/ui/pages/signup/SignUpPanel.java     |  94 +++++++++++
 .../wicket/ui/pages/signup/WicketSignUpPage.css | 100 ------------
 .../ui/pages/signup/WicketSignUpPage.html       |  66 --------
 .../ui/pages/signup/WicketSignUpPage.java       | 140 -----------------
 .../ui/pages/signup/WicketSignUpPage.properties |  25 ---
 .../email/EmailNotificationService.java         |  14 ++
 .../services/email/EmailSendingService.java     |  12 --
 .../email/events/EmailRegistrationEvent.java    |  25 +++
 .../email/events/UserCreationEvent.java         |  23 ---
 .../userreg/UserRegistrationService.java        |   8 +-
 core/runtime/pom.xml                            |  26 ++++
 .../email/EmailNotificationServiceDefault.java  | 106 +++++++++++++
 .../email/EmailSendingServiceDefault.java       |  51 ------
 .../email/EmailVerificationTemplate.html        |  15 ++
 .../webapp/WEB-INF/viewer_wicket.properties     |   6 +
 34 files changed, 1112 insertions(+), 675 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
index 1e12a33..ebb1590 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
@@ -61,6 +61,7 @@ import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.request.cycle.IRequestCycleListener;
 import org.apache.wicket.request.resource.CssResourceReference;
 import org.apache.wicket.settings.IRequestCycleSettings.RenderStrategy;
+import org.apache.wicket.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
@@ -98,6 +99,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2Bootst
 import org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2JsReference;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistryAccessor;
+import org.apache.isis.viewer.wicket.ui.pages.signup.AccountConfirmationMap;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
 import org.apache.isis.viewer.wicket.viewer.integration.isis.DeploymentTypeWicketAbstract;
 import org.apache.isis.viewer.wicket.viewer.integration.isis.WicketServer;
@@ -261,6 +263,10 @@ public class IsisWicketApplication extends AuthenticatedWebApplication implement
 
             configureWicketSourcePlugin();
 
+            // TODO ISIS-987 Either make the API better (no direct access to the map) or use DB records
+            int maxEntries = 1000;
+            setMetaData(AccountConfirmationMap.KEY, new AccountConfirmationMap(maxEntries, Duration.days(1)));
+
             mountPages();
 
             @SuppressWarnings("unused")
@@ -788,5 +794,4 @@ public class IsisWicketApplication extends AuthenticatedWebApplication implement
             cast.setAuthenticationSessionProvider(this);
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketModule.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketModule.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketModule.java
index ed6d736..947e068 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketModule.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketModule.java
@@ -23,8 +23,8 @@ import com.google.inject.AbstractModule;
 import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
 
-import org.apache.isis.applib.services.email.EmailSendingService;
-import org.apache.isis.core.runtime.services.email.EmailSendingServiceDefault;
+import org.apache.isis.applib.services.email.EmailNotificationService;
+import org.apache.isis.core.runtime.services.email.EmailNotificationServiceDefault;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ImageResourceCache;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistrar;
@@ -70,7 +70,7 @@ public class IsisWicketModule extends AbstractModule {
         bind(ComponentFactoryRegistrar.class).to(ComponentFactoryRegistrarDefault.class);
         bind(ImageResourceCache.class).to(ImageResourceCacheClassPath.class);
         bind(WicketViewerSettings.class).to(WicketViewerSettingsDefault.class);
-        bind(EmailSendingService.class).to(EmailSendingServiceDefault.class);
+        bind(EmailNotificationService.class).to(EmailNotificationServiceDefault.class);
 
         bind(String.class).annotatedWith(Names.named("applicationName")).toInstance("Apache Isis Wicket Viewer");
         bind(String.class).annotatedWith(Names.named("applicationCss")).toProvider(Providers.of((String)null));

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
index f5ba6c7..7e91d1f 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/pages/PageClassListDefault.java
@@ -31,7 +31,8 @@ import org.apache.isis.viewer.wicket.ui.pages.actionprompt.ActionPromptPage;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
 import org.apache.isis.viewer.wicket.ui.pages.home.HomePage;
 import org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage;
-import org.apache.isis.viewer.wicket.ui.pages.signup.WicketSignUpPage;
+import org.apache.isis.viewer.wicket.ui.pages.register.RegisterPage;
+import org.apache.isis.viewer.wicket.ui.pages.signup.RegistrationFormPage;
 import org.apache.isis.viewer.wicket.ui.pages.standalonecollection.StandaloneCollectionPage;
 import org.apache.isis.viewer.wicket.ui.pages.value.ValuePage;
 import org.apache.isis.viewer.wicket.ui.pages.voidreturn.VoidReturnPage;
@@ -106,21 +107,21 @@ public class PageClassListDefault implements PageClassList {
      * For subclassing if required.
      */
     protected Class<? extends Page> getSignUpPageClass() {
-        return WicketSignUpPage.class;
+        return RegistrationFormPage.class;
     }
 
     /**
      * For subclassing if required.
      */
     protected Class<? extends Page> getSignUpVerifyPageClass() {
-        return WicketSignUpPage.class;
+        return RegisterPage.class;
     }
 
     /**
      * For subclassing if required.
      */
     protected Class<? extends Page> getForgotPasswordPageClass() {
-        return WicketSignUpPage.class;
+        return RegistrationFormPage.class;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.html
index bd6dcf3..b521539 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.html
@@ -42,7 +42,7 @@
                     <button type="button" class="btn btn-block btn-link"><wicket:message key="forgotPasswordLinkLabel"/></button>
                 </div>
 
-                <div class="form-group">
+                <div class="form-group" wicket:enclosure="signUpLink">
                     <a wicket:id="signUpLink" class="btn btn-block btn-info"><wicket:message key="signUpButtonLabel"/></a>
                 </div>
             </form>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.java
index 146add6..b9695f2 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/IsisSignInPanel.java
@@ -23,8 +23,12 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel
 
 import javax.inject.Inject;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
 import org.apache.wicket.authroles.authentication.panel.SignInPanel;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.isis.applib.services.userreg.UserRegistrationService;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.internal.InitialisationSession;
 import org.apache.isis.viewer.wicket.model.models.PageType;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 
@@ -63,9 +67,25 @@ public class IsisSignInPanel extends SignInPanel {
     protected void onInitialize() {
         super.onInitialize();
 
-        getSignInForm().addOrReplace(new BookmarkablePageLink<Void>("signUpLink", pageClassRegistry.getPageClass(PageType.SIGN_UP)));
+        addSignUpLink("signUpLink");
 
-        addOrReplace(new NotificationPanel("feedback"));
+        addNotificationPanel("feedback");
+    }
+
+    protected void addNotificationPanel(String id) {
+        addOrReplace(new NotificationPanel(id));
+    }
+
+    protected void addSignUpLink(String id) {
+        // TODO ISIS-987 is this the correct way to check for the service availability here ? Open a session, etc.
+        IsisContext.openSession(new InitialisationSession());
+        Class<? extends Page> signUpPageClass = pageClassRegistry.getPageClass(PageType.SIGN_UP);
+        BookmarkablePageLink<Void> signUpLink = new BookmarkablePageLink<>(id, signUpPageClass);
+        final UserRegistrationService userRegistrationService = IsisContext.getPersistenceSession().getServicesInjector().lookupService(UserRegistrationService.class);
+        signUpLink.setVisibilityAllowed(true);//userRegistrationService != null);
+        IsisContext.closeSession();
+
+        getSignInForm().addOrReplace(signUpLink);
     }
 
     private MarkupContainer getSignInForm() {

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.html
index ff9e8dc..176a2fe 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.html
@@ -19,7 +19,7 @@
   under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"  
-      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"  
+      xmlns:wicket="http://wicket.apache.org"
       xml:lang="en"  
       lang="en">
     <head>
@@ -55,32 +55,8 @@
 
             <div class="row">
                 <div class="registerPanel col-sm-offset-4 col-sm-4">
-                    <h2><xwicket:message key="registerHeader">Register</xwicket:message></h2>
-                    <div>
-                        <form wicket:id="registerForm">
-                            <table>
-                                <tr>
-                                    <td align="right">Username:</td>
-                                    <td>
-                                        <label wicket:id="username"></label>
-                                    </td>
-                                </tr>
-                                <tr>
-                                    <td align="right">Password:</td>
-                                    <td>
-                                        <input wicket:id="password" type="password"/>
-                                    </td>
-                                </tr>
-                                <tr>
-                                    <td></td>
-                                    <td>
-                                        <input type="submit" name="submit" value="Register"/>
-                                        <input type="reset" value="Reset"/>
-                                    </td>
-                                </tr>
-                            </table>
-                        </form>
-                    </div>
+                    <h2><wicket:message key="registerHeader">Register</wicket:message></h2>
+                    <div wicket:id="content"></div>
                 </div>
             </div>
             <div wicket:id="exceptionStackTrace" class="exceptionStackTrace"></div>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.java
index 722bcb4..1b77911 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.java
@@ -23,7 +23,6 @@ import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import org.apache.wicket.Application;
 import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
 import org.apache.wicket.markup.head.CssReferenceHeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
@@ -32,17 +31,10 @@ import org.apache.wicket.markup.head.PriorityHeaderItem;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.PasswordTextField;
-import org.apache.wicket.markup.html.form.StatelessForm;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.string.StringValue;
-import org.apache.isis.applib.services.userreg.UserRegistrationService;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.internal.InitialisationSession;
-import org.apache.isis.core.runtime.system.transaction.TransactionalClosure;
 import org.apache.isis.viewer.wicket.ui.errors.ExceptionModel;
 import org.apache.isis.viewer.wicket.ui.errors.ExceptionStackTracePanel;
 import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
@@ -56,7 +48,6 @@ public class RegisterPage extends WebPage {
 
     private static final String ID_PAGE_TITLE = "pageTitle";
     private static final String ID_APPLICATION_NAME = "applicationName";
-    private static final String REGISTER_FORM = "registerForm";
 
     private static final String ID_EXCEPTION_STACK_TRACE = "exceptionStackTrace";
 
@@ -93,7 +84,7 @@ public class RegisterPage extends WebPage {
 
 
     public RegisterPage() {
-        this(null);
+        this(new PageParameters());
     }
 
     public RegisterPage(final PageParameters parameters) {
@@ -102,16 +93,16 @@ public class RegisterPage extends WebPage {
 
     public RegisterPage(final PageParameters parameters, ExceptionModel exceptionModel) {
 
-        // TODO: the idea here is that the page would be called with some sort of encrypted parameter that within it
-        // would include the username ... perhaps the email address IS the username?
-        final StringValue userNameValue = parameters.get("username");
-
-        // TODO: need some sort of validation in case there is no value available
-        setUsername(userNameValue.toString(""));
-
         addPageTitle();
         addApplicationName();
-        add(new RegisterForm(REGISTER_FORM));
+
+        final StringValue uuidValue = parameters.get(0);
+        if (uuidValue.isEmpty()) {
+            // TODO ISIS-987 Add feedback explaining why there is no form
+            addOrReplace(new WebMarkupContainer("content"));
+        } else {
+            addOrReplace(new RegisterPanel("content", uuidValue.toString()));
+        }
 
         if(exceptionModel != null) {
             add(new ExceptionStackTracePanel(ID_EXCEPTION_STACK_TRACE, exceptionModel));
@@ -145,96 +136,6 @@ public class RegisterPage extends WebPage {
     }
 
 
-    /**
-     * Sign in form.
-     */
-    public final class RegisterForm extends StatelessForm<RegisterPage>
-    {
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Constructor.
-         *
-         * @param id
-         *            id of the form component
-         */
-        public RegisterForm(final String id)
-        {
-            super(id);
-
-            setModel(new CompoundPropertyModel<>(RegisterPage.this));
-
-            // TODO: this needs tidying up substantially in the UI
-            add(new Label("username", Model.of(getUsername())));
-            add(new PasswordTextField("password"));
-
-        }
-
-        /**
-         * @see org.apache.wicket.markup.html.form.Form#onSubmit()
-         */
-        @Override
-        public final void onSubmit()
-        {
-            IsisContext.openSession(new InitialisationSession());
-
-            // TODO: need to add a link on the login page to register.
-            // TODO: however, if there is no UserRegistrationService domain service available, then should suppress the link to get to the registration page.
-            final UserRegistrationService userRegistrationService = IsisContext.getPersistenceSession().getServicesInjector().lookupService(UserRegistrationService.class);
-
-            IsisContext.getTransactionManager().executeWithinTransaction(new TransactionalClosure() {
-                @Override
-                public void preExecute() {
-                }
-
-                @Override
-                public void execute() {
-                    userRegistrationService.registerUser(username, password);
-                }
-
-                @Override
-                public void onSuccess() {
-                }
-
-                @Override
-                public void onFailure() {
-                }
-            });
-
-            IsisContext.closeSession();
-
-            // TODO: more error handling here... eg what if the username is already in use.
-            signIn(getUsername(), getPassword());
-            setResponsePage(getApplication().getHomePage());
-        }
-        private boolean signIn(String username, String password)
-        {
-            return AuthenticatedWebSession.get().signIn(username, password);
-        }
-    }
-
-
-    private String username;
-    public String getPassword()
-    {
-        return password;
-    }
-    public void setPassword(final String password)
-    {
-        this.password = password;
-    }
-
-    private String password;
-    public String getUsername()
-    {
-        return username;
-    }
-    public void setUsername(final String username)
-    {
-        this.username = username;
-    }
-
-
 
     // ///////////////////////////////////////////////////
     // System components

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.properties
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.properties b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.properties
new file mode 100644
index 0000000..f17f74e
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPage.properties
@@ -0,0 +1,30 @@
+#
+#  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.
+#
+
+registerHeader=Register
+usernameLabel=Username
+usernamePlaceholder=Username
+emailLabel=Email
+emailPlaceholder=Enter email
+passwordLabel=Password
+passwordPlaceholder=Enter password
+verifyPasswordLabel=Verify password
+verifyPasswordPlaceholder=Verify password
+registerButtonLabel=Register
+resetButtonLabel=Reset

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.html
new file mode 100644
index 0000000..5a3b73b
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org">
+    <head lang="en">
+        <meta charset="UTF-8">
+        <title></title>
+    </head>
+    <body>
+        <wicket:panel>
+            <div wicket:id="feedback"></div>
+
+            <form wicket:id="registerForm" role="form">
+                <div class="form-group">
+                    <label wicket:for="username"><wicket:message key="usernameLabel"/></label>
+                    <input type="text" class="form-control" wicket:id="username" wicket:message="placeholder:usernamePlaceholder"/>
+                </div>
+
+                <div class="form-group">
+                    <label wicket:for="password"><wicket:message key="passwordLabel"/></label>
+                    <input type="password" class="form-control" wicket:id="password" wicket:message="placeholder:passwordPlaceholder"/>
+                </div>
+
+                <div class="form-group">
+                    <label wicket:for="verifyPassword"><wicket:message key="verifyPasswordLabel"/></label>
+                    <input type="password" class="form-control" wicket:id="verifyPassword" wicket:message="placeholder:verifyPasswordPlaceholder"/>
+                </div>
+
+                <div class="form-group">
+                    <label wicket:for="email"><wicket:message key="emailLabel"/></label>
+                    <input type="text" class="form-control" wicket:id="email" readonly/>
+                </div>
+
+                <button type="submit" class="btn btn-primary btn-sm"><wicket:message key="registerButtonLabel"/></button>
+                <button type="reset" class="btn btn-default btn-sm"><wicket:message key="resetButtonLabel"/></button>
+            </form>
+        </wicket:panel>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.java
new file mode 100644
index 0000000..729ff68
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/RegisterPanel.java
@@ -0,0 +1,135 @@
+package org.apache.isis.viewer.wicket.ui.pages.register;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+
+import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.RequiredTextField;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.isis.applib.services.userreg.UserRegistrationService;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.internal.InitialisationSession;
+import org.apache.isis.core.runtime.system.transaction.TransactionalClosure;
+import org.apache.isis.viewer.wicket.ui.pages.signup.AccountConfirmationMap;
+
+/**
+ * TODO ISIS-987 Add javadoc
+ */
+public class RegisterPanel extends Panel {
+
+    private static final String REGISTER_FORM = "registerForm";
+
+    public RegisterPanel(String id, String uuid) {
+        super(id);
+
+        add(new RegisterForm(REGISTER_FORM, uuid));
+
+        add(new NotificationPanel("feedback"));
+    }
+
+
+    /**
+     * Register user form.
+     */
+    private static class RegisterForm extends StatelessForm<Registree>
+    {
+        private static final long serialVersionUID = 1L;
+
+        private final String uuid;
+
+        /**
+         * Constructor.
+         *
+         * @param id
+         *            id of the form component
+         */
+        public RegisterForm(final String id, final String uuid)
+        {
+            super(id);
+
+            this.uuid = uuid;
+
+            String email = getEmail();
+
+            final Registree registree = new Registree();
+            registree.setEmail(email);
+
+            setModel(new CompoundPropertyModel<>(registree));
+
+            add(new RequiredTextField<String>("username"));
+
+            PasswordTextField password = new PasswordTextField("password");
+            add(password);
+            PasswordTextField verifyPassword = new PasswordTextField("verifyPassword");
+            add(verifyPassword);
+            add(new EqualPasswordInputValidator(password, verifyPassword));
+
+            // use RO model to prevent changing the email
+            add(new TextField<>("email", new AbstractReadOnlyModel<String>() {
+                @Override
+                public String getObject() {
+                    return registree.getEmail();
+                }
+            }));
+        }
+
+        @Override
+        public final void onSubmit()
+        {
+            IsisContext.openSession(new InitialisationSession());
+
+            final Registree registree = getModelObject();
+
+            // TODO: need to add a link on the login page to register.
+            // TODO: however, if there is no UserRegistrationService domain service available, then should suppress the link to get to the registration page.
+            final UserRegistrationService userRegistrationService = IsisContext.getPersistenceSession().getServicesInjector().lookupService(UserRegistrationService.class);
+
+            IsisContext.getTransactionManager().executeWithinTransaction(new TransactionalClosure() {
+                @Override
+                public void preExecute() {
+                }
+
+                @Override
+                public void execute() {
+                    userRegistrationService.registerUser(registree.getUsername(), registree.getPassword(), registree.getEmail());
+                    removeAccountConfirmation();
+                }
+
+                @Override
+                public void onSuccess() {
+                }
+
+                @Override
+                public void onFailure() {
+                }
+            });
+
+            IsisContext.closeSession();
+
+            // TODO: more error handling here... eg what if the username is already in use.
+            signIn(registree.getUsername(), registree.getPassword());
+            setResponsePage(getApplication().getHomePage());
+        }
+
+        private boolean signIn(String username, String password)
+        {
+            return AuthenticatedWebSession.get().signIn(username, password);
+        }
+
+        private String getEmail() {
+            AccountConfirmationMap accountConfirmationMap = getApplication().getMetaData(AccountConfirmationMap.KEY);
+            return accountConfirmationMap.get(uuid);
+        }
+
+        private void removeAccountConfirmation() {
+            AccountConfirmationMap accountConfirmationMap = getApplication().getMetaData(AccountConfirmationMap.KEY);
+            accountConfirmationMap.remove(uuid);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/Registree.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/Registree.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/Registree.java
new file mode 100644
index 0000000..41a6718
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/register/Registree.java
@@ -0,0 +1,49 @@
+package org.apache.isis.viewer.wicket.ui.pages.register;
+
+import java.io.Serializable;
+
+/**
+ * A model object for {@link org.apache.isis.viewer.wicket.ui.pages.register.RegisterPanel}
+ */
+public class Registree implements Serializable {
+
+    private String username;
+    private String password;
+    private String verifyPassword;
+    private String email;
+
+    public String getUsername()
+    {
+        return username;
+    }
+
+    public void setUsername(final String username)
+    {
+        this.username = username;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+    public void setPassword(final String password)
+    {
+        this.password = password;
+    }
+
+    public String getVerifyPassword() {
+        return verifyPassword;
+    }
+
+    public void setVerifyPassword(String verifyPassword) {
+        this.verifyPassword = verifyPassword;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/AccountConfirmationMap.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/AccountConfirmationMap.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/AccountConfirmationMap.java
new file mode 100644
index 0000000..0cb64a8
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/AccountConfirmationMap.java
@@ -0,0 +1,154 @@
+/*
+ * 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.isis.viewer.wicket.ui.pages.signup;
+
+import java.util.Map;
+
+import org.apache.wicket.MetaDataKey;
+import org.apache.wicket.util.collections.MostRecentlyUsedMap;
+import org.apache.wicket.util.time.Duration;
+import org.apache.wicket.util.time.Time;
+
+/**
+ * A map that contains the emails to be verified. It has a constraint on the maximum entries that it
+ * can contain, and a constraint on the duration of time an entry is considered valid/non-expired
+ */
+public class AccountConfirmationMap extends MostRecentlyUsedMap<String, Object>
+{
+	private static final long serialVersionUID = 1L;
+
+	public static final MetaDataKey<AccountConfirmationMap> KEY = new MetaDataKey<AccountConfirmationMap>() {
+	};
+
+	/**
+	 * The actual object that is stored as a value of the map. It wraps the email and
+	 * assigns it a creation time.
+	 */
+	private static class Value
+	{
+		/** the original email to store */
+		private String email;
+
+		/** the time when this email is stored */
+		private Time creationTime;
+	}
+
+	/**
+	 * The duration of time before a {@link Value} is considered as expired
+	 */
+	private final Duration lifetime;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param maxEntries
+	 *            how much entries this map can contain
+	 * @param lifetime
+	 *            the duration of time to keep an entry in the map before considering it expired
+	 */
+	public AccountConfirmationMap(int maxEntries, Duration lifetime)
+	{
+		super(maxEntries);
+
+		this.lifetime = lifetime;
+	}
+
+	@Override
+	protected synchronized boolean removeEldestEntry(java.util.Map.Entry<String, Object> eldest)
+	{
+		boolean removed = super.removeEldestEntry(eldest);
+		if (removed == false)
+		{
+			Value value = (Value)eldest.getValue();
+			if (value != null)
+			{
+				Duration elapsedTime = Time.now().subtract(value.creationTime);
+				if (lifetime.lessThanOrEqual(elapsedTime))
+				{
+					removedValue = value.email;
+					removed = true;
+				}
+			}
+		}
+		return removed;
+	}
+
+	@Override
+	public String put(String key, Object bufferedResponse)
+	{
+		if (!(bufferedResponse instanceof String))
+		{
+			throw new IllegalArgumentException(AccountConfirmationMap.class.getSimpleName() +
+				" can store only instances of " + String.class.getSimpleName());
+		}
+
+		Value value = new Value();
+		value.creationTime = Time.now();
+		value.email = (String)bufferedResponse;
+
+		Value oldValue;
+		synchronized (this)
+		{
+			oldValue = (Value)super.put(key, value);
+		}
+
+		return oldValue != null ? oldValue.email : null;
+	}
+
+	@Override
+	public String get(Object key)
+	{
+		String result = null;
+		Value value;
+		synchronized (this)
+		{
+			value = (Value)super.get(key);
+		}
+		if (value != null)
+		{
+			Duration elapsedTime = Time.now().subtract(value.creationTime);
+			if (lifetime.greaterThan(elapsedTime))
+			{
+				result = value.email;
+			}
+			else
+			{
+				// expired, remove it
+				remove(key);
+			}
+		}
+		return result;
+	}
+
+	@Override
+	public String remove(Object key)
+	{
+		Value removedValue;
+		synchronized (this)
+		{
+			removedValue = (Value)super.remove(key);
+		}
+
+		return removedValue != null ? removedValue.email : null;
+	}
+
+	@Override
+	public void putAll(Map<? extends String, ?> m)
+	{
+		throw new UnsupportedOperationException();
+	}
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.html
deleted file mode 100644
index b1fa69f..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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.
--->
-<html xmlns:wicket="http://wicket.apache.org">
-    <body>
-        <wicket:panel>
-            <span wicket:id="feedback"></span>
-
-            <form wicket:id="signUpForm" role="form">
-                <div class="form-group">
-                    <label wicket:for="email"><wicket:message key="emailLabel"/></label>
-                    <input type="text" class="form-control" wicket:id="email" wicket:message="placeholder:emailPlaceholder"/>
-                </div>
-                <div class="form-group">
-                    <label wicket:for="password"><wicket:message key="signUpPasswordLabel"/></label>
-                    <input type="password" class="form-control" wicket:id="password" wicket:message="placeholder:passwordPlaceholder"/>
-                </div>
-
-                <button type="submit" wicket:id="signUp" class="btn btn-primary"><wicket:message key="signUpButtonLabel"/></button>
-            </form>
-
-        </wicket:panel>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.java
deleted file mode 100644
index e52ba2a..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/IsisSignUpPanel.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  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.isis.viewer.wicket.ui.pages.signup;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
-
-import javax.inject.Inject;
-import org.apache.wicket.markup.html.form.Button;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.PasswordTextField;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.validation.validator.EmailAddressValidator;
-import org.apache.isis.applib.services.email.EmailSendingService;
-import org.apache.isis.applib.services.email.events.UserCreationEvent;
-
-/**
- * A panel with a form for creation of new users
- */
-public class IsisSignUpPanel extends Panel {
-
-    /**
-     * Constructor
-     *
-     * @param id
-     *            the component id
-     */
-    public IsisSignUpPanel(final String id) {
-        super(id);
-
-        addOrReplace(new NotificationPanel("feedback"));
-
-        Form<Void> form = new Form<>("signUpForm");
-        addOrReplace(form);
-
-        final TextField<String> emailField = new TextField<>("email", Model.of(""));
-        emailField.add(EmailAddressValidator.getInstance());
-        final PasswordTextField passwordField = new PasswordTextField("password", Model.of(""));
-        Button signUpButton = new Button("signUp") {
-            @Override
-            public void onSubmit() {
-                super.onSubmit();
-
-                String email = emailField.getModelObject();
-                String password = passwordField.getModelObject();
-
-                emailService.send(new UserCreationEvent(email, password));
-            }
-        };
-        form.add(emailField, passwordField, signUpButton);
-    }
-
-    @Inject
-    private EmailSendingService emailService;
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.css
new file mode 100644
index 0000000..3727ba1
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.css
@@ -0,0 +1,100 @@
+/*
+ *  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.
+ */
+
+
+#header .applicationName {
+	display:none;
+}
+ 
+ .loginPanel {
+	width:310px;
+	background-color:#FFFFFF;
+	padding:20px;
+	border-radius:4px;
+	-moz-border-radius:4px;
+	-webkit-border-radius:4px;
+	margin-bottom:1%;
+	position:absolute;
+	clear:both;
+	height:200px;
+	left:50%;
+	top:50%;
+	margin-left:-175px;
+	margin-top:-100px;
+ }
+ 
+ .loginPanel h2 {
+ 	color:#423D37;
+ 	font-size:1.6em;
+ 	letter-spacing:0px;
+ 	line-height:150%;
+ 	margin-bottom:10px;
+ }
+ 
+ .loginPanel table {
+ 	width:100%;
+}
+
+.loginPanel table tr td {
+	padding:5px 0px;
+	text-align:left !important;
+}
+
+.loginPanel form input[type=text],
+.loginPanel form input[type=password] {
+	border-radius:4px;
+	-moz-borer-radius:4px;
+	-webkit-border-radius:4px;
+	padding:6px;
+	background-color:#F0EFEA;
+	border:1px solid #F0EFEA;
+	border-top:1px solid #CCCBC7;
+}
+
+
+.loginPanel form input[type=submit] {
+    background-color: #20B5C2;
+    border: 0 none;
+    border-radius: 4px 4px 4px 4px;
+    color: #FFFFFF;
+    cursor: pointer;
+    display: inline-block;
+    font-size: 0.9em;
+    padding: 5px 10px;
+}
+
+.loginPanel form input[type=reset] {
+    background-color: #E4E4DB;
+    border: 0 none;
+    border-radius: 4px 4px 4px 4px;
+    color: #46423C;
+    cursor: pointer;
+    display: inline-block;
+    font-size: 0.9em;
+    padding: 5px 10px;
+    text-transform: uppercase;
+}
+
+.loginPanel table tr td {
+	color:#46423C;
+}
+
+.wicketSignInPanel .mainMessage {
+	margin-top: 550px;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.html
new file mode 100644
index 0000000..5eefa4e
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.html
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<!--
+  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 xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org"
+      xml:lang="en"  
+      lang="en">
+    <head>
+        <wicket:header-items/>
+        <title wicket:id="pageTitle"></title>
+    </head>
+    <body>
+        <div id="container" class="wicketSignInPanel container-fluid">
+            <div class="jumbotron" style="background-color: transparent">
+
+                <div class="row">
+                    <div class="col-sm-12">&#160;</div>
+                </div>
+                <div class="row">
+                    <div class="col-sm-12">&#160;</div>
+                </div>
+                <div class="row">
+                    <div class="col-sm-12">&#160;</div>
+                </div>
+
+                <div class="row">
+                    <div class="headerContainer col-sm-offset-4 col-sm-4">
+                        <h1 wicket:id="applicationName" class="applicationName">[application name]</h1>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="col-sm-12">&#160;</div>
+                </div>
+                <div class="row">
+                    <div class="col-sm-12">&#160;</div>
+                </div>
+
+                <div class="row">
+                    <div class="loginPanel col-sm-offset-4 col-sm-4">
+                        <h2><wicket:message key="signUpHeader"/></h2>
+                        <div wicket:id="signUpPanel"></div>
+                    </div>
+                </div>
+            </div>
+            <div wicket:id="exceptionStackTrace" class="exceptionStackTrace"></div>
+        </div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.java
new file mode 100644
index 0000000..bb31c4a
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.java
@@ -0,0 +1,140 @@
+/*
+ *  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.isis.viewer.wicket.ui.pages.signup;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import org.apache.wicket.Application;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.head.CssReferenceHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem;
+import org.apache.wicket.markup.head.PriorityHeaderItem;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.ui.errors.ExceptionModel;
+import org.apache.isis.viewer.wicket.ui.errors.ExceptionStackTracePanel;
+import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
+
+/**
+ * Boilerplate, pick up our HTML and CSS.
+ */
+public class RegistrationFormPage extends WebPage {
+    
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_PAGE_TITLE = "pageTitle";
+    private static final String ID_APPLICATION_NAME = "applicationName";
+
+    private static final String ID_EXCEPTION_STACK_TRACE = "exceptionStackTrace";
+
+    /**
+     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
+     */
+    @Inject
+    @Named("applicationName")
+    private String applicationName;
+
+    /**
+     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
+     */
+    @Inject
+    @Named("applicationCss")
+    private String applicationCss;
+
+    /**
+     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
+     */
+    @Inject
+    @Named("applicationJs")
+    private String applicationJs;
+
+    /**
+     * If set by {@link org.apache.isis.viewer.wicket.ui.pages.PageAbstract}.
+     */
+    private static ExceptionModel getAndClearExceptionModelIfAny() {
+        ExceptionModel exceptionModel = PageAbstract.EXCEPTION.get();
+        PageAbstract.EXCEPTION.remove();
+        return exceptionModel;
+    }
+
+    public RegistrationFormPage() {
+        this(null);
+    }
+
+    public RegistrationFormPage(final PageParameters parameters) {
+        this(parameters, getAndClearExceptionModelIfAny());
+    }
+
+    public RegistrationFormPage(final PageParameters parameters, ExceptionModel exceptionModel) {
+        addPageTitle();
+        addApplicationName();
+        addSignInPanel();
+
+        if(exceptionModel != null) {
+            add(new ExceptionStackTracePanel(ID_EXCEPTION_STACK_TRACE, exceptionModel));
+        } else {
+            add(new WebMarkupContainer(ID_EXCEPTION_STACK_TRACE).setVisible(false));
+        }
+    }
+
+    private MarkupContainer addPageTitle() {
+        return add(new Label(ID_PAGE_TITLE, applicationName));
+    }
+
+    private void addApplicationName() {
+        add(new Label(ID_APPLICATION_NAME, applicationName));
+    }
+
+    protected SignUpPanel addSignInPanel() {
+        final SignUpPanel signInPanel = new SignUpPanel("signUpPanel");
+        add(signInPanel);
+        return signInPanel;
+    }
+
+    @Override
+    public void renderHead(IHeaderResponse response) {
+        super.renderHead(response);
+        response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(Application.get().getJavaScriptLibrarySettings().getJQueryReference())));
+        
+        if(applicationCss != null) {
+            response.render(CssReferenceHeaderItem.forUrl(applicationCss));
+        }
+        if(applicationJs != null) {
+            response.render(JavaScriptReferenceHeaderItem.forUrl(applicationJs));
+        }
+    }
+
+
+ 
+    // ///////////////////////////////////////////////////
+    // System components
+    // ///////////////////////////////////////////////////
+
+    protected IsisConfiguration getConfiguration() {
+        return IsisContext.getConfiguration();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.properties
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.properties b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.properties
new file mode 100644
index 0000000..046b998
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/RegistrationFormPage.properties
@@ -0,0 +1,25 @@
+#
+#  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.
+#
+
+signUpHeader=Sign Up
+emailLabel=Email
+emailPlaceholder=Enter email
+signUpPasswordLabel=Password
+passwordPlaceholder=Enter password
+signUpButtonLabel=Sign Up

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.html
new file mode 100644
index 0000000..77a9f3d
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+    <body>
+        <wicket:panel>
+            <span wicket:id="feedback"></span>
+
+            <form wicket:id="signUpForm" role="form">
+                <div class="form-group">
+                    <label wicket:for="email"><wicket:message key="emailLabel"/></label>
+                    <input type="text" class="form-control" wicket:id="email" wicket:message="placeholder:emailPlaceholder"/>
+                </div>
+
+                <button type="submit" wicket:id="signUp" class="btn btn-primary"><wicket:message key="signUpButtonLabel"/></button>
+            </form>
+
+        </wicket:panel>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.java
new file mode 100644
index 0000000..5ae14cf
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/SignUpPanel.java
@@ -0,0 +1,94 @@
+/*
+ *  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.isis.viewer.wicket.ui.pages.signup;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+
+import java.util.UUID;
+import javax.inject.Inject;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.UrlRenderer;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.validation.validator.EmailAddressValidator;
+import org.apache.isis.applib.services.email.EmailNotificationService;
+import org.apache.isis.applib.services.email.events.EmailRegistrationEvent;
+import org.apache.isis.viewer.wicket.ui.pages.register.RegisterPage;
+
+/**
+ * A panel with a form for creation of new users
+ */
+public class SignUpPanel extends Panel {
+
+    /**
+     * Constructor
+     *
+     * @param id
+     *            the component id
+     */
+    public SignUpPanel(final String id) {
+        super(id);
+
+        addOrReplace(new NotificationPanel("feedback"));
+
+        StatelessForm<Void> form = new StatelessForm<>("signUpForm");
+        addOrReplace(form);
+
+        final TextField<String> emailField = new TextField<>("email", Model.of(""));
+        emailField.add(EmailAddressValidator.getInstance());
+
+        Button signUpButton = new Button("signUp") {
+            @Override
+            public void onSubmit() {
+                super.onSubmit();
+
+                String email = emailField.getModelObject();
+                String confirmationUrl = createUrl(email);
+
+                emailService.send(new EmailRegistrationEvent(email, confirmationUrl));
+            }
+        };
+        form.add(emailField, signUpButton);
+    }
+
+    private String createUrl(String email) {
+        String uuid = UUID.randomUUID().toString();
+        uuid = uuid.replace("-", "");
+
+        // TODO mgrigorov: either improve the API or use a DB table for this
+        AccountConfirmationMap accountConfirmationMap = getApplication().getMetaData(AccountConfirmationMap.KEY);
+        accountConfirmationMap.put(uuid, email);
+
+        PageParameters parameters = new PageParameters();
+        parameters.set(0, uuid);
+        CharSequence relativeUrl = urlFor(RegisterPage.class, parameters);
+        UrlRenderer urlRenderer = getRequestCycle().getUrlRenderer();
+        String fullUrl = urlRenderer.renderFullUrl(Url.parse(relativeUrl));
+
+        return fullUrl;
+    }
+
+    @Inject
+    private EmailNotificationService emailService;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.css
deleted file mode 100644
index 3727ba1..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.css
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *  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.
- */
-
-
-#header .applicationName {
-	display:none;
-}
- 
- .loginPanel {
-	width:310px;
-	background-color:#FFFFFF;
-	padding:20px;
-	border-radius:4px;
-	-moz-border-radius:4px;
-	-webkit-border-radius:4px;
-	margin-bottom:1%;
-	position:absolute;
-	clear:both;
-	height:200px;
-	left:50%;
-	top:50%;
-	margin-left:-175px;
-	margin-top:-100px;
- }
- 
- .loginPanel h2 {
- 	color:#423D37;
- 	font-size:1.6em;
- 	letter-spacing:0px;
- 	line-height:150%;
- 	margin-bottom:10px;
- }
- 
- .loginPanel table {
- 	width:100%;
-}
-
-.loginPanel table tr td {
-	padding:5px 0px;
-	text-align:left !important;
-}
-
-.loginPanel form input[type=text],
-.loginPanel form input[type=password] {
-	border-radius:4px;
-	-moz-borer-radius:4px;
-	-webkit-border-radius:4px;
-	padding:6px;
-	background-color:#F0EFEA;
-	border:1px solid #F0EFEA;
-	border-top:1px solid #CCCBC7;
-}
-
-
-.loginPanel form input[type=submit] {
-    background-color: #20B5C2;
-    border: 0 none;
-    border-radius: 4px 4px 4px 4px;
-    color: #FFFFFF;
-    cursor: pointer;
-    display: inline-block;
-    font-size: 0.9em;
-    padding: 5px 10px;
-}
-
-.loginPanel form input[type=reset] {
-    background-color: #E4E4DB;
-    border: 0 none;
-    border-radius: 4px 4px 4px 4px;
-    color: #46423C;
-    cursor: pointer;
-    display: inline-block;
-    font-size: 0.9em;
-    padding: 5px 10px;
-    text-transform: uppercase;
-}
-
-.loginPanel table tr td {
-	color:#46423C;
-}
-
-.wicketSignInPanel .mainMessage {
-	margin-top: 550px;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.html
deleted file mode 100644
index 5942a93..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<!--
-  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 xmlns="http://www.w3.org/1999/xhtml"  
-      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"  
-      xml:lang="en"  
-      lang="en">
-    <head>
-        <wicket:header-items/>
-        <title wicket:id="pageTitle"></title>
-    </head>
-    <body>
-        <div id="container" class="wicketSignInPanel container-fluid">
-            <div class="jumbotron" style="background-color: transparent">
-
-                <div class="row">
-                    <div class="col-sm-12">&#160;</div>
-                </div>
-                <div class="row">
-                    <div class="col-sm-12">&#160;</div>
-                </div>
-                <div class="row">
-                    <div class="col-sm-12">&#160;</div>
-                </div>
-
-                <div class="row">
-                    <div class="headerContainer col-sm-offset-4 col-sm-4">
-                        <h1 wicket:id="applicationName" class="applicationName">[application name]</h1>
-                    </div>
-                </div>
-
-                <div class="row">
-                    <div class="col-sm-12">&#160;</div>
-                </div>
-                <div class="row">
-                    <div class="col-sm-12">&#160;</div>
-                </div>
-
-                <div class="row">
-                    <div class="loginPanel col-sm-offset-4 col-sm-4">
-                        <h2><wicket:message key="signUpHeader"/></h2>
-                        <div wicket:id="signUpPanel"></div>
-                    </div>
-                </div>
-            </div>
-            <div wicket:id="exceptionStackTrace" class="exceptionStackTrace"></div>
-        </div>
-    </body>
-</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.java
deleted file mode 100644
index 82479d2..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  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.isis.viewer.wicket.ui.pages.signup;
-
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
-import org.apache.wicket.Application;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.markup.head.CssReferenceHeaderItem;
-import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.markup.head.JavaScriptHeaderItem;
-import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem;
-import org.apache.wicket.markup.head.PriorityHeaderItem;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.isis.core.commons.config.IsisConfiguration;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.viewer.wicket.ui.errors.ExceptionModel;
-import org.apache.isis.viewer.wicket.ui.errors.ExceptionStackTracePanel;
-import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
-
-/**
- * Boilerplate, pick up our HTML and CSS.
- */
-public class WicketSignUpPage extends WebPage {
-    
-    private static final long serialVersionUID = 1L;
-
-    private static final String ID_PAGE_TITLE = "pageTitle";
-    private static final String ID_APPLICATION_NAME = "applicationName";
-
-    private static final String ID_EXCEPTION_STACK_TRACE = "exceptionStackTrace";
-
-    /**
-     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
-     */
-    @Inject
-    @Named("applicationName")
-    private String applicationName;
-
-    /**
-     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
-     */
-    @Inject
-    @Named("applicationCss")
-    private String applicationCss;
-
-    /**
-     * {@link com.google.inject.Inject}ed when {@link #init() initialized}.
-     */
-    @Inject
-    @Named("applicationJs")
-    private String applicationJs;
-
-    /**
-     * If set by {@link org.apache.isis.viewer.wicket.ui.pages.PageAbstract}.
-     */
-    private static ExceptionModel getAndClearExceptionModelIfAny() {
-        ExceptionModel exceptionModel = PageAbstract.EXCEPTION.get();
-        PageAbstract.EXCEPTION.remove();
-        return exceptionModel;
-    }
-
-    public WicketSignUpPage() {
-        this(null);
-    }
-
-    public WicketSignUpPage(final PageParameters parameters) {
-        this(parameters, getAndClearExceptionModelIfAny());
-    }
-
-    public WicketSignUpPage(final PageParameters parameters, ExceptionModel exceptionModel) {
-        addPageTitle();
-        addApplicationName();
-        addSignInPanel();
-
-        if(exceptionModel != null) {
-            add(new ExceptionStackTracePanel(ID_EXCEPTION_STACK_TRACE, exceptionModel));
-        } else {
-            add(new WebMarkupContainer(ID_EXCEPTION_STACK_TRACE).setVisible(false));
-        }
-    }
-
-    private MarkupContainer addPageTitle() {
-        return add(new Label(ID_PAGE_TITLE, applicationName));
-    }
-
-    private void addApplicationName() {
-        add(new Label(ID_APPLICATION_NAME, applicationName));
-    }
-
-    protected IsisSignUpPanel addSignInPanel() {
-        final IsisSignUpPanel signInPanel = new IsisSignUpPanel("signUpPanel");
-        add(signInPanel);
-        return signInPanel;
-    }
-
-    @Override
-    public void renderHead(IHeaderResponse response) {
-        super.renderHead(response);
-        response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(Application.get().getJavaScriptLibrarySettings().getJQueryReference())));
-        
-        if(applicationCss != null) {
-            response.render(CssReferenceHeaderItem.forUrl(applicationCss));
-        }
-        if(applicationJs != null) {
-            response.render(JavaScriptReferenceHeaderItem.forUrl(applicationJs));
-        }
-    }
-
-
- 
-    // ///////////////////////////////////////////////////
-    // System components
-    // ///////////////////////////////////////////////////
-
-    protected IsisConfiguration getConfiguration() {
-        return IsisContext.getConfiguration();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.properties
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.properties b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.properties
deleted file mode 100644
index 046b998..0000000
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/signup/WicketSignUpPage.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#  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.
-#
-
-signUpHeader=Sign Up
-emailLabel=Email
-emailPlaceholder=Enter email
-signUpPasswordLabel=Password
-passwordPlaceholder=Enter password
-signUpButtonLabel=Sign Up

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailNotificationService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailNotificationService.java b/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailNotificationService.java
new file mode 100644
index 0000000..255bad4
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailNotificationService.java
@@ -0,0 +1,14 @@
+package org.apache.isis.applib.services.email;
+
+import java.io.Serializable;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.email.events.EmailRegistrationEvent;
+
+/**
+ * TODO ISIS-987 Javadoc
+ */
+public interface EmailNotificationService extends Serializable {
+
+    @Programmatic
+    boolean send(EmailRegistrationEvent emailRegistrationEvent);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailSendingService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailSendingService.java b/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailSendingService.java
deleted file mode 100644
index 31b845b..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/email/EmailSendingService.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.apache.isis.applib.services.email;
-
-import java.io.Serializable;
-import org.apache.isis.applib.services.email.events.UserCreationEvent;
-
-/**
- *
- */
-public interface EmailSendingService extends Serializable {
-
-    void send(UserCreationEvent userCreationEvent);
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/applib/src/main/java/org/apache/isis/applib/services/email/events/EmailRegistrationEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/email/events/EmailRegistrationEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/email/events/EmailRegistrationEvent.java
new file mode 100644
index 0000000..87d0306
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/email/events/EmailRegistrationEvent.java
@@ -0,0 +1,25 @@
+package org.apache.isis.applib.services.email.events;
+
+/**
+ * An event send to all services interested in user registration
+ */
+public class EmailRegistrationEvent {
+    
+    private final String email;
+    private final String confirmationUrl;
+
+    public EmailRegistrationEvent(
+        final String email,
+        final String confirmationUrl) {
+        this.email = email;
+        this.confirmationUrl = confirmationUrl;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public String getConfirmationUrl() {
+        return confirmationUrl;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/applib/src/main/java/org/apache/isis/applib/services/email/events/UserCreationEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/email/events/UserCreationEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/email/events/UserCreationEvent.java
deleted file mode 100644
index 058b56c..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/email/events/UserCreationEvent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.apache.isis.applib.services.email.events;
-
-/**
- *
- */
-public class UserCreationEvent {
-    
-    private final String email;
-    private final String password;
-
-    public UserCreationEvent(String email, String password) {
-        this.email = email;
-        this.password = password;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/applib/src/main/java/org/apache/isis/applib/services/userreg/UserRegistrationService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/userreg/UserRegistrationService.java b/core/applib/src/main/java/org/apache/isis/applib/services/userreg/UserRegistrationService.java
index af3a70a..53efe16 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/userreg/UserRegistrationService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/userreg/UserRegistrationService.java
@@ -23,5 +23,11 @@ import org.apache.isis.applib.annotation.Programmatic;
 public interface UserRegistrationService {
 
     @Programmatic
-    void registerUser(String username, String password);
+    void registerUser(String username, String password, String emailAddress);
+
+    @Programmatic
+    boolean userExists(String username);
+
+    @Programmatic
+    boolean emailExists(String emailAddress);
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3bd8294d/core/runtime/pom.xml
----------------------------------------------------------------------
diff --git a/core/runtime/pom.xml b/core/runtime/pom.xml
index e110f27..caad3d4 100644
--- a/core/runtime/pom.xml
+++ b/core/runtime/pom.xml
@@ -179,11 +179,37 @@
 		    <scope>provided</scope>
         </dependency>
 
+        <!-- Email Notification Service -->
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-email</artifactId>
             <version>1.3.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.mail</groupId>
+                    <artifactId>mail</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+            <version>1.4.7</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.activation</groupId>
+                    <artifactId>activation</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.activation</groupId>
+            <artifactId>activation</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <!-- Email Notification Service -->
+
     </dependencies>
 </project>