Magnolia Public User Registration (PUR) module allows users of a public Magnolia site to register and access restricted content. You can use the module to register users for custom modules that support personalization and user-specific handling. For example, collect e-mail addresses of subscribers to a newsletter and allow them to manage subscription details after login.

See Setting up PUR on a website for a step-by-step tutorial on using the module.

Installing

Maven is the easiest way to install the module. Add the following to your bundle:

Error rendering macro 'artifact-maven-dependencies-snippet-macro'

com.sun.jersey.api.client.ClientHandlerException: java.net.NoRouteToHostException: No route to host (Host unreachable)

Compatibility and legacy modules

We have been gradually removing the old Content API from our modules since Magnolia 5.6. In Magnolia 5.5 we removed usage of the old old admininterface. If you have custom code which relies on code from the old admininterface or from the old Content API, then you must do one of two things:

  • Update your code for the new version of the public user registration module.
  • Or you can use the magnolia-module-public-user-registration-legacy together with magnolia-module-legacy-admininterface module.

Add the following snippet to your pom file:

Error rendering macro 'artifact-maven-dependencies-snippet-macro'

com.sun.jersey.api.client.ClientHandlerException: java.net.NoRouteToHostException: No route to host (Host unreachable)

User management

Public users are stored and managed in the Security app on the public instance. The system registers the account automatically when a user registers. Whether the user can use the account immediately or not depends on the configured registration strategy.

The user account is only created on the public instance. Make sure to backup this data when using several public instances, the instances or at least the users workspace needs to be clustered in order to share accounts between different instances. Another option is to implement observation based synchronization in order to replicate user accounts across instances.

Prerequisites

The PUR module relies on other modules and system settings. Understanding the module requires a working knowledge of:

  • Form module: Many of the PUR components are configurable forms.
  • Mail module: The module uses the Mail module to send emails. You need to configure SMTP to send mail to registering users. If you don't do this, a public user profile is created when a user registers, but an email to verify the account cannot be sent.

Configuration

PUR configuration is in /modules/public-user-registration/config/configurations.

Example: Provided default configuration.

Nodes and properties:

config

required

Module configuration folder.

configurations

required

Configurations node.

<configuration name>

required

Configuration name. Must match the site name configured in the site definition or the default configuration will be used.

DX Core users can create different configurations for each site. Use extends to make site-specific changes to an existing configuration.

defaultRoles

required

Roles managed by the module.

defaultGroups

required

Groups managed by the module.

registrationStrategy

required

Strategy for user registration.

passwordRetrievalStrategy

required

Strategy for password retrieval.

userProfileConfiguration

required

User profile configuration.

realmName

required

Realm name.

configurationResolver

required

Configuration resolver node.

class

required

Resolves the configuration to use.

DefaultConfigurationResolver finds the correct configuration based on the request URI. For example, /travel/members-area/register.html resolves to travel.

Default roles and groups

Only users defined in defaultRoles and defaultGroups nodes are managed by the module. Default roles and groups are configured in the same way.

 Example:  travel default roles and groups configurations. 

Properties

<configuration name>

required

Name of PUR configuration.

defaultRoles/defaultGroups

required

Default roles/groups node.

<role/group name>

required

Role/Group name.

Property name is arbitrary. Value must match role or group set up in the Security app.

Users in the travel-demo-pur group as assigned the travel-demo-pur role (among others) that provides these Web access permissions. protected is a page that contains content that can only be viewed by registered users, and profile-update contains the User Profile Update form. 

PermissionPath
Get & Post/travel/members/protected*
Get & Post<travel>/members/protected*
Get & Post/travel/members/profile-update*
Get & Post <travel>/members/profile-update*

On registration, a new user is automatically assigned the travel-demo-pur role and can access restricted content. The location of the restricted content can be set in the Login component dialog.

Here's what non-registered and registered users see. 

  

Registration strategies

Registration strategies define how users are registered. Magnolia provides three options:

  • Registration after mail verification.
  • Immediate registration.
  • Admin-supervised registration.

Example: travel registration strategy. 

Properties:

<configuration name>

required

Name of PUR configuration.

registrationStrategy

required

Registration strategy node.

class

required

Registration class:

  • Mail: Sends the user an email containing a verification link after signup. The link directs to a page containing the Enable User Form component.
  • Always: Enables the registered user immediately. No verification is required.
  • Never: Registers, but does not enable the user. An admin needs to enable the user manually in the Security app

<strategy-specific properties>

 optional

Any properties supported by the used registration class. Only Mail  supports additional properties.

Mail registration strategy

The mail registration strategy sends the user an email containing a verification link after signing up. The link directs to a page containing the Enable User Form component. When the user submits the form the system enables the user's account. 

Example: sportstation email registration strategy.

Properties:

 registrationStrategy

required

Registration strategy node.

emailTemplate

required

Relative path to template used for the email message.

fromEmail

required

Sender email address.

fromName

optional

Sender name .

pagePath

required

Relative path to the page containing the Enable User Form component.

subject

optional

Message subject.

  user-confirmation-email.ftl (Git) (referenced in the emailTemplate property) is a simple script that defines the verification link mailed to the user.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Log in - Magnolia Bitbucket</title><script>
window.WRM=window.WRM||{};window.WRM._unparsedData=window.WRM._unparsedData||{};window.WRM._unparsedErrors=window.WRM._unparsedErrors||{};
WRM._unparsedData["com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:user-keyboard-shortcuts-enabled.data"]="true";
WRM._unparsedData["com.atlassian.analytics.analytics-client:programmatic-analytics-init.programmatic-analytics-data-provider"]="false";
WRM._unparsedData["com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path.context-path"]="\u0022\u0022";
WRM._unparsedData["com.atlassian.plugins.atlassian-clientside-extensions-runtime:runtime.atlassianDevMode"]="false";
WRM._unparsedData["com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:date-format-preference.data"]="\u0022\u0022";
WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:bitbucket.global.theme.data"]="false";
WRM._unparsedData["com.atlassian.analytics.analytics-client:policy-update-init.policy-update-data-provider"]="false";
WRM._unparsedData["com.atlassian.bitbucket.plugins.bitbucket-slack-server-integration-plugin:slack-link-error-resources.slack-link-error"]="{}";
WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:user.time.zone.onboarding.data"]="true";
if(window.WRM._dataArrived)window.WRM._dataArrived();</script>
<link rel="stylesheet" href="/s/c2e7fb6cb0fa3d99cfd1ed5573a5b732-CDN/1015515914/fdb5904/1h5ouvp/a93e8b54a53a5453c42e8c7cfb35551a/_/download/contextbatch/css/_super/batch.css" data-wrm-key="_super" data-wrm-batch-type="context" media="all">
<link rel="stylesheet" href="/s/c3b4ddaba8d3dce9466950696444d252-CDN/1015515914/fdb5904/1h5ouvp/80af30e6da65e29f7038393c9f70794e/_/download/contextbatch/css/bitbucket.page.login,-_super/batch.css" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" media="all">
<link rel="stylesheet" href="/s/a5886b3e3e45b4adb9b9991e2cf18803-CDN/1015515914/fdb5904/1h5ouvp/f4992ec124d5384cd0091fae42c3ca97/_/download/contextbatch/css/bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super/batch.css?slack-enabled=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super" data-wrm-batch-type="context" media="all">
<script src="/s/2fb1765c7438a1e383facff8dd19270a-CDN/1015515914/fdb5904/1h5ouvp/a93e8b54a53a5453c42e8c7cfb35551a/_/download/contextbatch/js/_super/batch.js?locale=en-US" data-wrm-key="_super" data-wrm-batch-type="context" data-initially-rendered></script>
<script src="/s/8fd0897a356f9fee979922482537ec9e-CDN/1015515914/fdb5904/1h5ouvp/80af30e6da65e29f7038393c9f70794e/_/download/contextbatch/js/bitbucket.page.login,-_super/batch.js?locale=en-US" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
<script src="/s/b26a251d5dcc697b8b37326544044035-CDN/1015515914/fdb5904/1h5ouvp/f4992ec124d5384cd0091fae42c3ca97/_/download/contextbatch/js/bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super/batch.js?locale=en-US&amp;slack-enabled=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
<meta name="application-name" content="Bitbucket"><link rel="shortcut icon" type="image/x-icon" href="/s/1015515914/fdb5904/1h5ouvp/1.0/_/download/resources/com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:favicon/favicon.ico" /><link rel="search" href="https://git.magnolia-cms.com/plugins/servlet/opensearch-descriptor" type="application/opensearchdescription+xml" title="Bitbucket code search"/></head><body class="aui-page-focused aui-page-focused-small aui-page-size-small bitbucket-theme user-login"><script type="text/javascript">require('@bitbucket/internal/feature/theme').init();</script><ul id="assistive-skip-links" class="assistive"><li><a href="#content">Skip to content</a></li></ul><div id="page"><!-- start #header --><header id="header" role="banner"><section class="notifications"></section><nav class="aui-header aui-dropdown2-trigger-group" aria-label="site"><div class="aui-header-inner"><div class="aui-header-before"><button class=" aui-dropdown2-trigger app-switcher-trigger aui-dropdown2-trigger-arrowless" aria-controls="app-switcher" aria-haspopup="true" role="button" data-aui-trigger href="#app-switcher"><span class="aui-icon aui-icon-small aui-iconfont-appswitcher">Linked Applications</span></button><div id="app-switcher" class="aui-dropdown2 aui-style-default" role="menu" hidden data-is-user-admin="false" data-is-switcher="true"><div class="app-switcher-loading">Loading&hellip;</div></div></div><div class="aui-header-primary"><span id="logo" class="aui-header-logo bitbucket-header-logo"><a href="https://git.magnolia-cms.com"><img src="/s/1015515914/fdb5904/1h5ouvp/1.0/_/download/resources/com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:bitbucket-logo/images/logo/bitbucket.svg" alt="Bitbucket"/></a></span><ul class="aui-nav"></ul></div><div class="aui-header-secondary"><ul class="aui-nav"><li class=" help-link"title="Help"><a class=" aui-dropdown2-trigger aui-dropdown2-trigger-arrowless" aria-controls="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" aria-haspopup="true" role="button" tabindex="0" data-aui-trigger><span class="aui-icon aui-icon-small aui-icon-small aui-iconfont-question-filled">Help</span></a><div id="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" class="aui-dropdown2 aui-style-default" role="menu" hidden data-aui-dom-container="body"><div class="aui-dropdown2-section help-items-section"><ul class="aui-list-truncate" role="presentation"><li role="presentation"><a href="https://docs.atlassian.com/bitbucketserver/docs-0814/Bitbucket+Data+Center+and+Server+documentation?utm_campaign=in-app-help&amp;amp;utm_medium=in-app-help&amp;amp;utm_source=stash" title="Go to the online documentation for Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:general-help">Online help</a></li><li role="presentation"><a href="https://www.atlassian.com/git?utm_campaign=learn-git&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Learn about Git commands &amp; workflows" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:learn-git">Learn Git</a></li><li role="presentation"><a href="/getting-started"class="getting-started-page-link" title="Overview of Bitbucket features" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:getting-started-page-help-link">Welcome to Bitbucket</a></li><li role="presentation"><a href="/#"class="keyboard-shortcut-link" title="Discover keyboard shortcuts in Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:keyboard-shortcuts-help-link">Keyboard shortcuts</a></li><li role="presentation"><a href="https://go.atlassian.com/bitbucket-server-whats-new?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Learn about what&#39;s new in Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:whats-new-link">What&#39;s new</a></li><li role="presentation"><a href="https://go.atlassian.com/bitbucket-server-community?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Explore the Atlassian community" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:community-link">Community</a></li><li role="presentation"><a href="/about" title="About Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:about">About</a></li></ul></div></div></li><li class=" alerts-menu"title="View system alerts"><a href="#alerts" id="alerts-trigger"class="alerts-menu" title="View system alerts" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:global-alerts-menu-item">Alerts</a></li></ul></div></div> <!-- End .aui-header-inner --></nav> <!-- End .aui-header --></header><!-- End #header --><!-- Start #content --><section id="content" role="main" tabindex="-1" data-timezone="-120" ><div class="aui-page-panel content-body" ><div class="aui-page-panel-inner"><main role="main" id="main" class="aui-page-panel-content" ><h2>Log in</h2><form class="aui top-label prevent-double-submit " action="/j_atl_security_check" method="post" accept-charset="UTF-8"><div class="field-group"><label for="j_username" >Username</label><input class="text long-field" type="text" id="j_username"  name="j_username"  autofocus accesskey="u"/></div><div class="field-group"><label for="j_password" >Password</label><input class="text long-field" type="password" id="j_password"  name="j_password"  accesskey="p"/></div><div class="aui-group"><fieldset class="group checkbox"><div class="checkbox"><input class="checkbox" type="checkbox" id="_atl_remember_me"  name="_atl_remember_me"  checked="checked"  accesskey="r"/><label for="_atl_remember_me" >Keep me logged in</label></div></fieldset></div><div class="aui-group"><input name="next" type="hidden" value="/projects/MODULES/repos/public-user-registration/browse/magnolia-module-pur/src/main/resources/public-user-registration/templates/mail/user-confirmation-email.ftl?at=master&amp;raw"/><input name="queryString" type="hidden" value="next=%2Fprojects%2FMODULES%2Frepos%2Fpublic-user-registration%2Fbrowse%2Fmagnolia-module-pur%2Fsrc%2Fmain%2Fresources%2Fpublic-user-registration%2Ftemplates%2Fmail%2Fuser-confirmation-email.ftl%3Fat%3Dmaster%26raw"/><input class="aui-button aui-button-primary" type="submit" id="submit"  name="submit"  value="Log in" accesskey="s"/><a id="forgot" class="aui-button aui-button-link"  name="forgot" href="/passwordreset" autocomplete="off" tabindex="0">Unable to access your account?</a></div></form></main></div></div></section><!-- End #content --><!-- Start #footer --><footer id="footer" role="contentinfo"><section class="notifications"></section><section class="footer-body"><ul><li data-key="footer.license.free.eval">Git repository management powered by a free <a href="https://www.atlassian.com/software/bitbucket/">Atlassian Bitbucket</a> evaluation license</li></ul><ul><li>Atlassian Bitbucket <span title="fdb5904e84ca72e8d62953007cf5cf6cfcdfebd8" id="product-version" data-commitid="fdb5904e84ca72e8d62953007cf5cf6cfcdfebd8" data-system-build-number="fdb5904"> v8.14.0</span></li><li data-key="footer.links.documentation"><a href="https://docs.atlassian.com/bitbucketserver/docs-0814/Bitbucket+Data+Center+and+Server+documentation?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Documentation</a></li><li data-key="footer.links.jac"><a href="https://jira.atlassian.com/browse/BSERV?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Request a feature</a></li><li data-key="footer.links.about"><a href="/about">About</a></li><li data-key="footer.links.contact.atlassian"><a href="https://www.atlassian.com/company/contact?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Contact Atlassian</a></li></ul><div id="footer-logo"><a href="https://www.atlassian.com/" target="_blank">Atlassian</a></div></section></footer><!-- End #footer --></div><script>require('bitbucket/internal/layout/base/base').onReady(null, "Magnolia Bitbucket" ); require('bitbucket/internal/widget/keyboard-shortcuts/keyboard-shortcuts').onReady();</script><script type="text/javascript">require('bitbucket/internal/page/login/login').onReady();</script></body></html>
Mail registration class adds the userid UUID and regStamp parameters to the URL to verify identity. The verification link looks something like this:


http://localhost:8080/magnoliaPublic/sportstation/members/registration/enable-user.html?userId=7dcf398a-793f-48d0-8dbb-a4be08b1101c&amp;regstamp=1452610248796

Password retrieval strategies

Password retrieval strategies define how users retrieve lost or forgotten passwords. Magnolia provides two options:

  • Mail password retrieval: An email with a link to the Password Change form is sent to the user. This is common practice and secure because the mail does not contain a password.
  • A strategy class that does nothing: You can code your own strategy in the Confirmation Email tab of the Forgotten Password dialog. 

Examplesportstation mail password retrieval strategy.

Properties:

passwordRetrievalStrategy

required

Password retrieval strategy node.

class

required

Password retrieval strategy class:

  • MailChangePasswordLinkStrategy: This strategy sends the user a link to the page containing the Password Change component.
  • NOPStrategy: This strategy does nothing. You have the option to code your own strategy in the Confirmation Email tab of the Forgotten Password dialog instead.

emailTemplate

required

Relative path to the template used for the email message.

fromEmail

required

Sender's email.

fromName

optional

Sender's name.

subject

optional

Message subject.

targetPagePath

required

Relative path to the page containing the Password Change component.

tokenExpirationTime

optional, default in 30

Duration (in minutes) that the password change link remains valid.

password-reset-email.ftl  (Git) (referenced in the emailTemplate property) is a simple script that sets the link to the password change form.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Log in - Magnolia Bitbucket</title><script>
window.WRM=window.WRM||{};window.WRM._unparsedData=window.WRM._unparsedData||{};window.WRM._unparsedErrors=window.WRM._unparsedErrors||{};
WRM._unparsedData["com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:user-keyboard-shortcuts-enabled.data"]="true";
WRM._unparsedData["com.atlassian.analytics.analytics-client:programmatic-analytics-init.programmatic-analytics-data-provider"]="false";
WRM._unparsedData["com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path.context-path"]="\u0022\u0022";
WRM._unparsedData["com.atlassian.plugins.atlassian-clientside-extensions-runtime:runtime.atlassianDevMode"]="false";
WRM._unparsedData["com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:date-format-preference.data"]="\u0022\u0022";
WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:bitbucket.global.theme.data"]="false";
WRM._unparsedData["com.atlassian.analytics.analytics-client:policy-update-init.policy-update-data-provider"]="false";
WRM._unparsedData["com.atlassian.bitbucket.plugins.bitbucket-slack-server-integration-plugin:slack-link-error-resources.slack-link-error"]="{}";
WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:user.time.zone.onboarding.data"]="true";
if(window.WRM._dataArrived)window.WRM._dataArrived();</script>
<link rel="stylesheet" href="/s/c2e7fb6cb0fa3d99cfd1ed5573a5b732-CDN/1015515914/fdb5904/1h5ouvp/a93e8b54a53a5453c42e8c7cfb35551a/_/download/contextbatch/css/_super/batch.css" data-wrm-key="_super" data-wrm-batch-type="context" media="all">
<link rel="stylesheet" href="/s/c3b4ddaba8d3dce9466950696444d252-CDN/1015515914/fdb5904/1h5ouvp/80af30e6da65e29f7038393c9f70794e/_/download/contextbatch/css/bitbucket.page.login,-_super/batch.css" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" media="all">
<link rel="stylesheet" href="/s/a5886b3e3e45b4adb9b9991e2cf18803-CDN/1015515914/fdb5904/1h5ouvp/f4992ec124d5384cd0091fae42c3ca97/_/download/contextbatch/css/bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super/batch.css?slack-enabled=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super" data-wrm-batch-type="context" media="all">
<script src="/s/2fb1765c7438a1e383facff8dd19270a-CDN/1015515914/fdb5904/1h5ouvp/a93e8b54a53a5453c42e8c7cfb35551a/_/download/contextbatch/js/_super/batch.js?locale=en-US" data-wrm-key="_super" data-wrm-batch-type="context" data-initially-rendered></script>
<script src="/s/8fd0897a356f9fee979922482537ec9e-CDN/1015515914/fdb5904/1h5ouvp/80af30e6da65e29f7038393c9f70794e/_/download/contextbatch/js/bitbucket.page.login,-_super/batch.js?locale=en-US" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
<script src="/s/b26a251d5dcc697b8b37326544044035-CDN/1015515914/fdb5904/1h5ouvp/f4992ec124d5384cd0091fae42c3ca97/_/download/contextbatch/js/bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super/batch.js?locale=en-US&amp;slack-enabled=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,bitbucket.internal.feature.theme,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
<meta name="application-name" content="Bitbucket"><link rel="shortcut icon" type="image/x-icon" href="/s/1015515914/fdb5904/1h5ouvp/1.0/_/download/resources/com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:favicon/favicon.ico" /><link rel="search" href="https://git.magnolia-cms.com/plugins/servlet/opensearch-descriptor" type="application/opensearchdescription+xml" title="Bitbucket code search"/></head><body class="aui-page-focused aui-page-focused-small aui-page-size-small bitbucket-theme user-login"><script type="text/javascript">require('@bitbucket/internal/feature/theme').init();</script><ul id="assistive-skip-links" class="assistive"><li><a href="#content">Skip to content</a></li></ul><div id="page"><!-- start #header --><header id="header" role="banner"><section class="notifications"></section><nav class="aui-header aui-dropdown2-trigger-group" aria-label="site"><div class="aui-header-inner"><div class="aui-header-before"><button class=" aui-dropdown2-trigger app-switcher-trigger aui-dropdown2-trigger-arrowless" aria-controls="app-switcher" aria-haspopup="true" role="button" data-aui-trigger href="#app-switcher"><span class="aui-icon aui-icon-small aui-iconfont-appswitcher">Linked Applications</span></button><div id="app-switcher" class="aui-dropdown2 aui-style-default" role="menu" hidden data-is-user-admin="false" data-is-switcher="true"><div class="app-switcher-loading">Loading&hellip;</div></div></div><div class="aui-header-primary"><span id="logo" class="aui-header-logo bitbucket-header-logo"><a href="https://git.magnolia-cms.com"><img src="/s/1015515914/fdb5904/1h5ouvp/1.0/_/download/resources/com.atlassian.bitbucket.server.bitbucket-webpack-INTERNAL:bitbucket-logo/images/logo/bitbucket.svg" alt="Bitbucket"/></a></span><ul class="aui-nav"></ul></div><div class="aui-header-secondary"><ul class="aui-nav"><li class=" help-link"title="Help"><a class=" aui-dropdown2-trigger aui-dropdown2-trigger-arrowless" aria-controls="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" aria-haspopup="true" role="button" tabindex="0" data-aui-trigger><span class="aui-icon aui-icon-small aui-icon-small aui-iconfont-question-filled">Help</span></a><div id="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" class="aui-dropdown2 aui-style-default" role="menu" hidden data-aui-dom-container="body"><div class="aui-dropdown2-section help-items-section"><ul class="aui-list-truncate" role="presentation"><li role="presentation"><a href="https://docs.atlassian.com/bitbucketserver/docs-0814/Bitbucket+Data+Center+and+Server+documentation?utm_campaign=in-app-help&amp;amp;utm_medium=in-app-help&amp;amp;utm_source=stash" title="Go to the online documentation for Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:general-help">Online help</a></li><li role="presentation"><a href="https://www.atlassian.com/git?utm_campaign=learn-git&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Learn about Git commands &amp; workflows" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:learn-git">Learn Git</a></li><li role="presentation"><a href="/getting-started"class="getting-started-page-link" title="Overview of Bitbucket features" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:getting-started-page-help-link">Welcome to Bitbucket</a></li><li role="presentation"><a href="/#"class="keyboard-shortcut-link" title="Discover keyboard shortcuts in Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:keyboard-shortcuts-help-link">Keyboard shortcuts</a></li><li role="presentation"><a href="https://go.atlassian.com/bitbucket-server-whats-new?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Learn about what&#39;s new in Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:whats-new-link">What&#39;s new</a></li><li role="presentation"><a href="https://go.atlassian.com/bitbucket-server-community?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Explore the Atlassian community" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:community-link">Community</a></li><li role="presentation"><a href="/about" title="About Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:about">About</a></li></ul></div></div></li><li class=" alerts-menu"title="View system alerts"><a href="#alerts" id="alerts-trigger"class="alerts-menu" title="View system alerts" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:global-alerts-menu-item">Alerts</a></li></ul></div></div> <!-- End .aui-header-inner --></nav> <!-- End .aui-header --></header><!-- End #header --><!-- Start #content --><section id="content" role="main" tabindex="-1" data-timezone="-120" ><div class="aui-page-panel content-body" ><div class="aui-page-panel-inner"><main role="main" id="main" class="aui-page-panel-content" ><h2>Log in</h2><form class="aui top-label prevent-double-submit " action="/j_atl_security_check" method="post" accept-charset="UTF-8"><div class="field-group"><label for="j_username" >Username</label><input class="text long-field" type="text" id="j_username"  name="j_username"  autofocus accesskey="u"/></div><div class="field-group"><label for="j_password" >Password</label><input class="text long-field" type="password" id="j_password"  name="j_password"  accesskey="p"/></div><div class="aui-group"><fieldset class="group checkbox"><div class="checkbox"><input class="checkbox" type="checkbox" id="_atl_remember_me"  name="_atl_remember_me"  checked="checked"  accesskey="r"/><label for="_atl_remember_me" >Keep me logged in</label></div></fieldset></div><div class="aui-group"><input name="next" type="hidden" value="/projects/MODULES/repos/public-user-registration/browse/magnolia-module-pur/src/main/resources/public-user-registration/templates/mail/password-reset-email.ftl?master&amp;raw"/><input name="queryString" type="hidden" value="next=%2Fprojects%2FMODULES%2Frepos%2Fpublic-user-registration%2Fbrowse%2Fmagnolia-module-pur%2Fsrc%2Fmain%2Fresources%2Fpublic-user-registration%2Ftemplates%2Fmail%2Fpassword-reset-email.ftl%3Fmaster%26raw"/><input class="aui-button aui-button-primary" type="submit" id="submit"  name="submit"  value="Log in" accesskey="s"/><a id="forgot" class="aui-button aui-button-link"  name="forgot" href="/passwordreset" autocomplete="off" tabindex="0">Unable to access your account?</a></div></form></main></div></div></section><!-- End #content --><!-- Start #footer --><footer id="footer" role="contentinfo"><section class="notifications"></section><section class="footer-body"><ul><li data-key="footer.license.free.eval">Git repository management powered by a free <a href="https://www.atlassian.com/software/bitbucket/">Atlassian Bitbucket</a> evaluation license</li></ul><ul><li>Atlassian Bitbucket <span title="fdb5904e84ca72e8d62953007cf5cf6cfcdfebd8" id="product-version" data-commitid="fdb5904e84ca72e8d62953007cf5cf6cfcdfebd8" data-system-build-number="fdb5904"> v8.14.0</span></li><li data-key="footer.links.documentation"><a href="https://docs.atlassian.com/bitbucketserver/docs-0814/Bitbucket+Data+Center+and+Server+documentation?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Documentation</a></li><li data-key="footer.links.jac"><a href="https://jira.atlassian.com/browse/BSERV?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Request a feature</a></li><li data-key="footer.links.about"><a href="/about">About</a></li><li data-key="footer.links.contact.atlassian"><a href="https://www.atlassian.com/company/contact?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Contact Atlassian</a></li></ul><div id="footer-logo"><a href="https://www.atlassian.com/" target="_blank">Atlassian</a></div></section></footer><!-- End #footer --></div><script>require('bitbucket/internal/layout/base/base').onReady(null, "Magnolia Bitbucket" ); require('bitbucket/internal/widget/keyboard-shortcuts/keyboard-shortcuts').onReady();</script><script type="text/javascript">require('bitbucket/internal/page/login/login').onReady();</script></body></html>

http://localhost:8080/magnoliaPublic/sportstation/members/forgotten-password/password-change?userId=80fc309e-4250-4203-b8be-33bbe1e7fbd2&amp;token=e4dca890d75ee54559bab07e75e457c562ec3c3e&amp;

You can test the password retrieval strategy on the public instance of the Travel demo. Sign up for an account and follow the link in the email to reset your password.

The user profile configuration defines the properties in a user's profile. By default, these are username, password, email and fullname.

Example: default user profile configuration

Properties:

userProfileConfiguration

required

User profile configuration node.

class

required

User profile class.

UserProfile is a basic profile bean that supports the default usernamepasswordemail and fullName properties

Extending the user profile

You can extend UserProfile  and register a custom class in configuration if you need to store more information.

Example: Custom user profile class configuration with additional phoneNumber property.

Properties:

userProfileConfiguration

required

User profile configuration node.

autopopulatedProperties

required

UserProfileConfiguration supports adding custom user profile properties under this node

<custom properties>

optional

Your custom user profile properties, for example phoneNumber.

userProfileClass

required

Custom user profile class.

The default properties are always populated, but you need to write a custom class that extends UserProfile to set the custom properties in the user profile. 

Example: Custom user profile class for handling a phone number.

CustomUserProfile.java
public class CustomUserProfile extends UserProfile {
    private String phoneNumber = "";
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

To test the new property:

  1. Add a new field named after the custom property in the registration form, for example phoneNumber.
  2. Publish the form page to the public instance.
  3. Register a new user.
  4. In the Exporter subappexport the user profile to XML (Set Repository=users, Base path=/public) .
  5. Check that the new property is in the exported XML.

PUR components

The module includes all necessary components to implement user registration and related tasks on your site. 

You can view the PUR components in the Members area of the Travel demo .

Components are configured in /modules/public-user-registration/templates/components.

With the exception of login, the components are standard Magnolia forms. They extend the form component and override the standard form processors with custom form processors provided by the module. 

login
  • Displays Login Form component that has:
    • Preconfigured username and password fields.
    • Registration and Forgotten password links.
    • Login button.
  • In the dialog set:
    • Target page: Form can redirect to any page. Typically used to direct to protected content parent page, making content in this tree is only visible to logged-in users.
    • Registration page: Page containing the registration component.
    • Password retrieval page: Page containing the forgottenPassword component.
  • Rendered by login.ftl (Git)

registration
  • Displays User Registration form.
  • Add input fields named username, password, passwordConfirmation, fullName , and email, and a submit button field.
  • Uses RegistrationProcessor to register the user.


userUpdate
  • Displays User Profile Update form.
  • Add input fields named username, fullName, and email, and a submit button field.
  • Uses UserFormModel to prefill the user's data
  • Uses UpdateProcessor to update the user's profile.


forgottenPassword
  • Displays Forgotten Password form.
  • Add input fields named username and email, and a submit button field.
  • Uses PasswordProcessor to verify the user's credentials and retrieve the password retrieval strategy.
  • Processor sends the user an email with a link to the passwordChange component page when MailChangePasswordLinkStrategy is configured as the password retrieval strategy .

passwordChange
  • Displays Password Change form.
  • Add input fields named password and passwordConfirmation, and a submit button field.
  • Uses TokenPasswordProcessor that takes a token from the URL and checks if the token is valid. If it is, the user's password is changed.

enableUser
  • Displays Enable User form.
  • Add a submit button field.
  • Uses EnableUserByUuidProcessor to enable a user's account after retrieving it using the UUID parameter.
  • Use with mail registration strategy to confirm and enable user's account.

(warning) For PUR functionality to work, the input fields must be named exactly as specified in the table above. 

Adding components to templates

You can add the PUR components to any template. 

Example: Template definition with all PUR components in main area.

/my-module/templates/pages/myTemplate.yaml
templateScript: /my-module/templates/pages/my-script.ftl
renderType: freemarker
visible: true
title: My template
areas:
  main:
    availableComponents:
      login:
        id: public-user-registration:components/login
      registration:
         id: public-user-registration:components/registration
      userUpdate:
         id: public-user-registration:components/userUpdate
      forgottenPassword:
         id: public-user-registration:components/forgottenPassword
      passwordChange:
         id: public-user-registration:components/passwordChange
      enableUser:
         id: public-user-registration:components/enableUser

PUR changes in 2.5.1+ 

The module and its configuration includes classes, resources and components that are deprecated in (warning) 2.5.1+ / 5.4.4+. These are maintained for backward compatibility and some are still used in configuration for this purpose. 

Mail registration strategy

The default configuration uses the mail registration strategy, but references a deprecated emailTemplate and pagePath. If you are implementing PUR for the first time and want to use or extend the default configuration, update these properties to:

emailTemplate /public-user-registration/templates/mail/user-confirmation-email.ftl
pagePath Relative path to the page containing the Enable User Form component.*

*pages are deprecated in 5.4.4

Password retrieval strategy

The default configuration uses MailChangePasswordLinkStrategy password retrieval strategy, but references a deprecated emailTemplate. If you are implementing PUR for the first time and want to use or extend the default configuration, update this property to:

emailTemplate/public-user-registration/templates/mail/password-reset-email.ftl

Default roles

The default configuration assigns registered public users the public-user-registration-base and anonymous roles. The base role provides permissions to /pages which are deprecated it 5.4.4. If you are implementing PUR for the first time, follow the pattern used in the Travel demo when setting up permissions.

PUR Components

A new set of components was introduced in 2.5.1. 

This table shows the 2.5.1 components and their equivalent earlier components.

(warning) 2.5.1 +< 2.5.1 (old)
loginuserLogin
registrationuserRegistration
userUpdateprofileUpdate
forgottenPasswordpasswordReminder
passwordChangepasswordChange
enableUser-
#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))