mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-01 14:41:46 +00:00
ACA-4619: fixed dynamic client app config. That is to get the resolved url based on the client name.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -26,10 +26,12 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.client.config;
|
package org.alfresco.repo.client.config;
|
||||||
|
|
||||||
|
import org.alfresco.repo.admin.SysAdminParams;
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
import org.alfresco.util.UrlUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.slf4j.Logger;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||||
|
|
||||||
@@ -41,6 +43,7 @@ import java.util.Properties;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class picks up all the loaded properties passed to it and uses a naming
|
* This class picks up all the loaded properties passed to it and uses a naming
|
||||||
@@ -59,25 +62,35 @@ import java.util.concurrent.ConcurrentMap;
|
|||||||
* for example, <i>sharedLinkBaseUrl</i> and <i>templateAssetsUrl</i> properties, then the following
|
* for example, <i>sharedLinkBaseUrl</i> and <i>templateAssetsUrl</i> properties, then the following
|
||||||
* needs to be put into a properties file.
|
* needs to be put into a properties file.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>repo.client-app.MyClientName.sharedLinkBaseUrl=http://localhost:8080/MyClientName/s</li>
|
* <li>{@code repo.client-app.MyClientName.sharedLinkBaseUrl=http://localhost:8080/MyClientName/s}</li>
|
||||||
* <li>repo.client-app.MyClientName.templateAssetsUrl=http://localhost:8080/MyClientName/assets</li>
|
* <li>{@code repo.client-app.MyClientName.templateAssetsUrl=http://localhost:8080/MyClientName/assets}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* The default property file is <b>alfresco/client/config/repo-clients-apps.properties</b> which
|
* The default property file is <b>alfresco/client/config/repo-clients-apps.properties</b> which
|
||||||
* could be overridden (or add new clients) by <b>alfresco-global</b> properties file.
|
* could be overridden (or add new clients) by <b>alfresco-global</b> properties file.
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> The {@literal <clientName>Url} is a special property which can be used as a placeholder.
|
||||||
|
* For example,
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code repo.client-app.MyClientName.MyClientNameUrl=${repoBaseUrl}/entrypoint}</li>
|
||||||
|
* <li>{@code repo.client-app.MyClientName.somePropName=${MyClientNameUrl}/some-page}</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
*/
|
*/
|
||||||
public class ClientAppConfig extends AbstractLifecycleBean
|
public class ClientAppConfig extends AbstractLifecycleBean
|
||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(ClientAppConfig.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ClientAppConfig.class);
|
||||||
|
|
||||||
public static final String PREFIX = "repo.client-app.";
|
public static final String PREFIX = "repo.client-app.";
|
||||||
public static final String PROP_TEMPLATE_ASSETS_URL = "templateAssetsUrl";
|
public static final String PROP_TEMPLATE_ASSETS_URL = "templateAssetsUrl";
|
||||||
|
|
||||||
|
public static final String SHARE_PLACEHOLDER = "${shareUrl}";
|
||||||
|
|
||||||
private Properties defaultProperties;
|
private Properties defaultProperties;
|
||||||
private Properties globalProperties;
|
private Properties globalProperties;
|
||||||
|
|
||||||
private ConcurrentMap<String, ClientApp> clients = new ConcurrentHashMap<>();
|
private final ConcurrentMap<String, ClientApp> clients = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public ClientAppConfig()
|
public ClientAppConfig()
|
||||||
{
|
{
|
||||||
@@ -117,6 +130,17 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
return clients.get(name);
|
return clients.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a client with the given name exists or not.
|
||||||
|
*
|
||||||
|
* @param name the name of the client to check
|
||||||
|
* @return true if the client with the given name exists; false otherwise
|
||||||
|
*/
|
||||||
|
public boolean exists(String name)
|
||||||
|
{
|
||||||
|
return clients.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBootstrap(ApplicationEvent event)
|
protected void onBootstrap(ApplicationEvent event)
|
||||||
{
|
{
|
||||||
@@ -127,9 +151,9 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
processPropertyKeys(mergedProperties, clientsNames, propsNames);
|
processPropertyKeys(mergedProperties, clientsNames, propsNames);
|
||||||
clients.putAll(processClients(clientsNames, propsNames, mergedProperties));
|
clients.putAll(processClients(clientsNames, propsNames, mergedProperties));
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (LOGGER.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("All bootstrapped repo clients apps: " + clients);
|
LOGGER.debug("All bootstrapped repo clients apps: " + clients);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +256,7 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
}
|
}
|
||||||
if (StringUtils.isEmpty(templateAssetsUrl) && config.isEmpty())
|
if (StringUtils.isEmpty(templateAssetsUrl) && config.isEmpty())
|
||||||
{
|
{
|
||||||
logger.warn("Client-app [" + clientName + "] can not be registered as it needs at least one property with a valid value.");
|
LOGGER.warn("Client-app [" + clientName + "] can not be registered as it needs at least one property with a valid value.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// As the required values are valid, create the client data
|
// As the required values are valid, create the client data
|
||||||
@@ -275,7 +299,7 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
private void logMalformedPropertyKey(String propName, String reason)
|
private void logMalformedPropertyKey(String propName, String reason)
|
||||||
{
|
{
|
||||||
reason = (StringUtils.isBlank(reason)) ? "" : " " + reason;
|
reason = (StringUtils.isBlank(reason)) ? "" : " " + reason;
|
||||||
logger.warn("Ignoring client app config (malformed property key) [" + propName + "]." + reason);
|
LOGGER.warn("Ignoring client app config (malformed property key) [" + propName + "]." + reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logMalformedPropertyKey(String propName)
|
private void logMalformedPropertyKey(String propName)
|
||||||
@@ -285,9 +309,9 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
|
|
||||||
private void logInvalidPropertyValue(String propName, String propValue)
|
private void logInvalidPropertyValue(String propName, String propValue)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (LOGGER.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Ignoring client app config (invalid value) [" + propValue + "] for the property:" + propName);
|
LOGGER.debug("Ignoring client app config (invalid value) [" + propValue + "] for the property:" + propName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,13 +322,18 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
|
|
||||||
public static class ClientApp
|
public static class ClientApp
|
||||||
{
|
{
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ClientApp.class);
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final String clientUrlPropKey;
|
||||||
|
private final Pattern clientUrlPlaceholderPattern;
|
||||||
private final String templateAssetsUrl;
|
private final String templateAssetsUrl;
|
||||||
private final Map<String, String> properties;
|
private final Map<String, String> properties;
|
||||||
|
|
||||||
public ClientApp(String name, String templateAssetsUrl, Map<String, String> properties)
|
public ClientApp(String name, String templateAssetsUrl, Map<String, String> properties)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.clientUrlPropKey = name + "Url"; // E.g. 'workspaceUrl' in 'repo.client-app.workspace.workspaceUrl'
|
||||||
|
this.clientUrlPlaceholderPattern = Pattern.compile("\\$\\{" + clientUrlPropKey + '}'); // E.g. ${workspaceUrl}
|
||||||
this.templateAssetsUrl = templateAssetsUrl;
|
this.templateAssetsUrl = templateAssetsUrl;
|
||||||
this.properties = new HashMap<>(properties);
|
this.properties = new HashMap<>(properties);
|
||||||
}
|
}
|
||||||
@@ -314,11 +343,77 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getClientUrlPropKey()
|
||||||
|
{
|
||||||
|
return clientUrlPropKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientUrl()
|
||||||
|
{
|
||||||
|
String url = properties.get(getClientUrlPropKey());
|
||||||
|
if (StringUtils.isEmpty(url) && "share".equals(name))
|
||||||
|
{
|
||||||
|
return SHARE_PLACEHOLDER;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the client URL that has one of the following defined URL placeholders:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@literal ${repoBaseUrl}}</li>
|
||||||
|
* <li>{@literal ${shareUrl}}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param sysAdminParams SysAdminParams object to retrieve configurable system parameters
|
||||||
|
* @return the resolved property value if applicable
|
||||||
|
*/
|
||||||
|
public String getResolvedClientUrl(SysAdminParams sysAdminParams)
|
||||||
|
{
|
||||||
|
String resolvedUrl;
|
||||||
|
String clientUrl = getClientUrl();
|
||||||
|
if (!StringUtils.isEmpty(clientUrl) && clientUrl.contains(SHARE_PLACEHOLDER))
|
||||||
|
{
|
||||||
|
resolvedUrl = UrlUtil.replaceShareUrlPlaceholder(clientUrl, sysAdminParams);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolvedUrl = UrlUtil.replaceRepoBaseUrlPlaceholder(clientUrl, sysAdminParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("Resolved clientUrl [" + clientUrl + "] to [" + resolvedUrl + "] for the client: " + name);
|
||||||
|
return resolvedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pattern getClientUrlPlaceholderPattern()
|
||||||
|
{
|
||||||
|
return clientUrlPlaceholderPattern;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTemplateAssetsUrl()
|
public String getTemplateAssetsUrl()
|
||||||
{
|
{
|
||||||
return templateAssetsUrl;
|
return templateAssetsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the template assets URL that has the following defined URL placeholder:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@literal ${<clientName>Url}}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param sysAdminParams SysAdminParams object to retrieve configurable system parameters
|
||||||
|
* @return the resolved property value if applicable
|
||||||
|
*/
|
||||||
|
public String getResolvedTemplateAssetsUrl(SysAdminParams sysAdminParams)
|
||||||
|
{
|
||||||
|
String resolvedUrl = UrlUtil.replaceUrlPlaceholder(getClientUrlPlaceholderPattern(), getTemplateAssetsUrl(),
|
||||||
|
getResolvedClientUrl(sysAdminParams));
|
||||||
|
|
||||||
|
LOGGER.debug("Resolved template assets [" + getTemplateAssetsUrl() + "] URL to [" + resolvedUrl
|
||||||
|
+ "] for the client: " + name);
|
||||||
|
return resolvedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, String> getProperties()
|
public Map<String, String> getProperties()
|
||||||
{
|
{
|
||||||
return Collections.unmodifiableMap(properties);
|
return Collections.unmodifiableMap(properties);
|
||||||
@@ -329,6 +424,27 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
return properties.get(propName);
|
return properties.get(propName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the property that has the following defined URL placeholder:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@literal ${<clientName>Url}}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param propName the property name to search for
|
||||||
|
* @param sysAdminParams SysAdminParams object to retrieve configurable system parameters
|
||||||
|
* @return the resolved property value if applicable
|
||||||
|
*/
|
||||||
|
public String getResolvedProperty(String propName, SysAdminParams sysAdminParams)
|
||||||
|
{
|
||||||
|
String property = getProperty(propName);
|
||||||
|
String resolvedProp = UrlUtil.replaceUrlPlaceholder(getClientUrlPlaceholderPattern(), property,
|
||||||
|
getResolvedClientUrl(sysAdminParams));
|
||||||
|
|
||||||
|
LOGGER.debug("Resolved [" + property + "] URL to [" + resolvedProp + "] for the [" + propName
|
||||||
|
+ "] property of the client: " + name);
|
||||||
|
return resolvedProp;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
@@ -356,6 +472,8 @@ public class ClientAppConfig extends AbstractLifecycleBean
|
|||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder(250);
|
final StringBuilder sb = new StringBuilder(250);
|
||||||
sb.append("ClientApp [name=").append(name)
|
sb.append("ClientApp [name=").append(name)
|
||||||
|
.append(", clientUrlPropKey=").append(clientUrlPropKey)
|
||||||
|
.append(", clientUrlPlaceholderPattern=").append(clientUrlPlaceholderPattern.pattern())
|
||||||
.append(", templateAssetsUrl=").append(templateAssetsUrl)
|
.append(", templateAssetsUrl=").append(templateAssetsUrl)
|
||||||
.append(", properties=").append(properties)
|
.append(", properties=").append(properties)
|
||||||
.append(']');
|
.append(']');
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -1875,7 +1875,6 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
|
|||||||
* @param siteName
|
* @param siteName
|
||||||
* @param role
|
* @param role
|
||||||
* @param runAsUser
|
* @param runAsUser
|
||||||
* @param siteService
|
|
||||||
* @param overrideExisting
|
* @param overrideExisting
|
||||||
*/
|
*/
|
||||||
public void addSiteMembership(final String invitee, final String siteName, final String role, final String runAsUser, final boolean overrideExisting)
|
public void addSiteMembership(final String invitee, final String siteName, final String role, final String runAsUser, final boolean overrideExisting)
|
||||||
@@ -2111,11 +2110,11 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
|
|||||||
workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_TYPE, resourceType.toString());
|
workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_TYPE, resourceType.toString());
|
||||||
|
|
||||||
workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_CLIENT_NAME, clientName);
|
workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_CLIENT_NAME, clientName);
|
||||||
if(clientName != null && clientAppConfig.getClient(clientName) != null)
|
if(clientName != null && clientAppConfig.exists(clientName))
|
||||||
{
|
{
|
||||||
ClientAppConfig.ClientApp client = clientAppConfig.getClient(clientName);
|
ClientAppConfig.ClientApp client = clientAppConfig.getClient(clientName);
|
||||||
workflowProps.put(WorkflowModelModeratedInvitation.WF_TEMPLATE_ASSETS_URL, client.getTemplateAssetsUrl());
|
workflowProps.put(WorkflowModelModeratedInvitation.WF_TEMPLATE_ASSETS_URL, client.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
workflowProps.put(WorkflowModelModeratedInvitation.WF_WORKSPACE_URL, client.getProperty("workspaceUrl"));
|
workflowProps.put(WorkflowModelModeratedInvitation.WF_WORKSPACE_URL, client.getResolvedClientUrl(sysAdminParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the moderated workflow
|
// get the moderated workflow
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -72,7 +72,7 @@ public class SendModeratedInviteDelegate extends AbstractInvitationDelegate
|
|||||||
Map<String, Object> variables = execution.getVariables();
|
Map<String, Object> variables = execution.getVariables();
|
||||||
String clientName = (String) variables.get(WorkflowModelModeratedInvitation.wfVarClientName);
|
String clientName = (String) variables.get(WorkflowModelModeratedInvitation.wfVarClientName);
|
||||||
|
|
||||||
if(clientName != null && clientAppConfig.getClient(clientName) != null)
|
if(clientName != null && clientAppConfig.exists(clientName))
|
||||||
{
|
{
|
||||||
ClientAppConfig.ClientApp clientApp = clientAppConfig.getClient(clientName);
|
ClientAppConfig.ClientApp clientApp = clientAppConfig.getClient(clientName);
|
||||||
final String path = clientApp.getProperty("inviteModeratedTemplatePath");
|
final String path = clientApp.getProperty("inviteModeratedTemplatePath");
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -934,13 +934,13 @@ public class QuickShareServiceImpl implements QuickShareService,
|
|||||||
Map<String, Serializable> templateModel = new HashMap<>(6);
|
Map<String, Serializable> templateModel = new HashMap<>(6);
|
||||||
templateModel.put(FTL_SENDER_FIRST_NAME, senderFirstName);
|
templateModel.put(FTL_SENDER_FIRST_NAME, senderFirstName);
|
||||||
templateModel.put(FTL_SENDER_LAST_NAME, senderLastName);
|
templateModel.put(FTL_SENDER_LAST_NAME, senderLastName);
|
||||||
final String sharedNodeUrl = getUrl(clientApp.getProperty(CONFIG_SHARED_LINK_BASE_URL), CONFIG_SHARED_LINK_BASE_URL)
|
String resolvedUrl = getUrl(clientApp.getResolvedProperty(CONFIG_SHARED_LINK_BASE_URL, sysAdminParams), CONFIG_SHARED_LINK_BASE_URL);
|
||||||
+ '/' + emailRequest.getSharedId();
|
final String sharedNodeUrl = resolvedUrl + '/' + emailRequest.getSharedId();
|
||||||
|
|
||||||
templateModel.put(FTL_SHARED_NODE_URL, sharedNodeUrl);
|
templateModel.put(FTL_SHARED_NODE_URL, sharedNodeUrl);
|
||||||
templateModel.put(FTL_SHARED_NODE_NAME, emailRequest.getSharedNodeName());
|
templateModel.put(FTL_SHARED_NODE_NAME, emailRequest.getSharedNodeName());
|
||||||
templateModel.put(FTL_SENDER_MESSAGE, emailRequest.getSenderMessage());
|
templateModel.put(FTL_SENDER_MESSAGE, emailRequest.getSenderMessage());
|
||||||
final String templateAssetsUrl = getUrl(clientApp.getTemplateAssetsUrl(), ClientAppConfig.PROP_TEMPLATE_ASSETS_URL);
|
final String templateAssetsUrl = getUrl(clientApp.getResolvedTemplateAssetsUrl(sysAdminParams), ClientAppConfig.PROP_TEMPLATE_ASSETS_URL);
|
||||||
templateModel.put(FTL_TEMPLATE_ASSETS_URL, templateAssetsUrl);
|
templateModel.put(FTL_TEMPLATE_ASSETS_URL, templateAssetsUrl);
|
||||||
|
|
||||||
// Set the email details
|
// Set the email details
|
||||||
@@ -1048,8 +1048,7 @@ public class QuickShareServiceImpl implements QuickShareService,
|
|||||||
{
|
{
|
||||||
url = url.substring(0, url.length() - 1);
|
url = url.substring(0, url.length() - 1);
|
||||||
}
|
}
|
||||||
// Replace '${shareUrl} placeholder if it does exist.
|
return url;
|
||||||
return UrlUtil.replaceShareUrlPlaceholder(url, sysAdminParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getDefaultIfNull(T defaultValue, T newValue)
|
private <T> T getDefaultIfNull(T defaultValue, T newValue)
|
||||||
|
@@ -32,13 +32,11 @@ import org.alfresco.repo.client.config.ClientAppNotFoundException;
|
|||||||
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetPasswordDetails;
|
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetPasswordDetails;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated from 7.1.0
|
|
||||||
* Reset password service.
|
* Reset password service.
|
||||||
*
|
*
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
* @since 5.2.1
|
* @since 5.2.1
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public interface ResetPasswordService
|
public interface ResetPasswordService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@@ -2,23 +2,23 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
* provided under the following open source license terms:
|
* provided under the following open source license terms:
|
||||||
*
|
*
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
@@ -61,8 +61,8 @@ import org.alfresco.util.ParameterCheck;
|
|||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.alfresco.util.UrlUtil;
|
import org.alfresco.util.UrlUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.slf4j.Logger;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.extensions.surf.util.I18NUtil;
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
import org.springframework.extensions.webscripts.WebScriptException;
|
import org.springframework.extensions.webscripts.WebScriptException;
|
||||||
|
|
||||||
@@ -74,17 +74,15 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated from 7.1.0
|
*
|
||||||
* *
|
|
||||||
* Reset password implementation based on workflow.
|
* Reset password implementation based on workflow.
|
||||||
*
|
*
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
* @since 5.2.1
|
* @since 5.2.1
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public class ResetPasswordServiceImpl implements ResetPasswordService
|
public class ResetPasswordServiceImpl implements ResetPasswordService
|
||||||
{
|
{
|
||||||
private static final Log LOGGER = LogFactory.getLog(ResetPasswordServiceImpl.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ResetPasswordServiceImpl.class);
|
||||||
|
|
||||||
private static final String TIMER_END = "PT1H";
|
private static final String TIMER_END = "PT1H";
|
||||||
private static final String WORKFLOW_DESCRIPTION_KEY = "resetpasswordwf_resetpassword.resetpassword.workflow.description";
|
private static final String WORKFLOW_DESCRIPTION_KEY = "resetpasswordwf_resetpassword.resetpassword.workflow.description";
|
||||||
@@ -196,6 +194,7 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
ParameterCheck.mandatoryString("clientName", clientName);
|
ParameterCheck.mandatoryString("clientName", clientName);
|
||||||
|
|
||||||
String userEmail = validateUserAndGetEmail(userId);
|
String userEmail = validateUserAndGetEmail(userId);
|
||||||
|
validateClient(clientName);
|
||||||
|
|
||||||
// Get the (latest) workflow definition for reset-password.
|
// Get the (latest) workflow definition for reset-password.
|
||||||
WorkflowDefinition wfDefinition = workflowService.getDefinitionByName(WorkflowModelResetPassword.WORKFLOW_DEFINITION_NAME);
|
WorkflowDefinition wfDefinition = workflowService.getDefinitionByName(WorkflowModelResetPassword.WORKFLOW_DEFINITION_NAME);
|
||||||
@@ -342,8 +341,9 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
}
|
}
|
||||||
else if (!username.equals(userId))
|
else if (!username.equals(userId))
|
||||||
{
|
{
|
||||||
throw new InvalidResetPasswordWorkflowException("The given user id [" + userId + "] does not match the person's user id [" + username
|
throw new InvalidResetPasswordWorkflowException(
|
||||||
+ "] who requested the password reset.");
|
"The given user id [" + userId + "] does not match the person's user id [" + username
|
||||||
|
+ "] who requested the password reset.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,12 +352,16 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
{
|
{
|
||||||
ParameterCheck.mandatoryString("clientName", clientName);
|
ParameterCheck.mandatoryString("clientName", clientName);
|
||||||
|
|
||||||
ClientApp clientApp = clientAppConfig.getClient(clientName);
|
validateClient(clientName);
|
||||||
if (clientApp == null)
|
return clientAppConfig.getClient(clientName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateClient(String clientName)
|
||||||
|
{
|
||||||
|
if (!clientAppConfig.exists(clientName))
|
||||||
{
|
{
|
||||||
throw new ClientAppNotFoundException("Client was not found [" + clientName + "]");
|
throw new ClientAppNotFoundException("Client was not found [" + clientName + "]");
|
||||||
}
|
}
|
||||||
return clientApp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -383,9 +387,9 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
.setUserName(userName)
|
.setUserName(userName)
|
||||||
.setUserEmail(toEmail)
|
.setUserEmail(toEmail)
|
||||||
.setTemplatePath(templatePath)
|
.setTemplatePath(templatePath)
|
||||||
.setTemplateAssetsUrl(clientApp.getTemplateAssetsUrl())
|
|
||||||
.setEmailSubject(emailSubject)
|
.setEmailSubject(emailSubject)
|
||||||
.setTemplateModel(emailTemplateModel);
|
.setTemplateModel(emailTemplateModel)
|
||||||
|
.setClientApp(clientApp);
|
||||||
|
|
||||||
sendEmail(emailRequest);
|
sendEmail(emailRequest);
|
||||||
}
|
}
|
||||||
@@ -400,7 +404,7 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
final String userName = (String) execution.getVariable(WorkflowModelResetPassword.WF_PROP_USERNAME_ACTIVITI);
|
final String userName = (String) execution.getVariable(WorkflowModelResetPassword.WF_PROP_USERNAME_ACTIVITI);
|
||||||
|
|
||||||
// But we cannot get the password from the execution as we have intentionally not stored the password there.
|
// But we cannot get the password from the execution as we have intentionally not stored the password there.
|
||||||
// Instead we recover the password from the specific task in which it was set.
|
// Instead, we recover the password from the specific task in which it was set.
|
||||||
List<Task> activitiTasks = activitiTaskService.createTaskQuery().taskDefinitionKey(WorkflowModelResetPassword.TASK_RESET_PASSWORD)
|
List<Task> activitiTasks = activitiTaskService.createTaskQuery().taskDefinitionKey(WorkflowModelResetPassword.TASK_RESET_PASSWORD)
|
||||||
.processInstanceId(execution.getProcessInstanceId()).list();
|
.processInstanceId(execution.getProcessInstanceId()).list();
|
||||||
if (activitiTasks.size() != 1)
|
if (activitiTasks.size() != 1)
|
||||||
@@ -448,9 +452,9 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
.setUserName(userName)
|
.setUserName(userName)
|
||||||
.setUserEmail(userEmail)
|
.setUserEmail(userEmail)
|
||||||
.setTemplatePath(templatePath)
|
.setTemplatePath(templatePath)
|
||||||
.setTemplateAssetsUrl(clientApp.getTemplateAssetsUrl())
|
|
||||||
.setEmailSubject(emailSubject)
|
.setEmailSubject(emailSubject)
|
||||||
.setTemplateModel(emailTemplateModel);
|
.setTemplateModel(emailTemplateModel)
|
||||||
|
.setClientApp(clientApp);
|
||||||
|
|
||||||
sendEmail(emailRequest);
|
sendEmail(emailRequest);
|
||||||
}
|
}
|
||||||
@@ -460,7 +464,9 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
// Prepare the email
|
// Prepare the email
|
||||||
Map<String, Serializable> templateModel = new HashMap<>();
|
Map<String, Serializable> templateModel = new HashMap<>();
|
||||||
// Replace '${shareUrl}' placeholder if it does exist.
|
// Replace '${shareUrl}' placeholder if it does exist.
|
||||||
final String templateAssetsUrl = getUrl(emailRequest.getTemplateAssetsUrl(), ClientAppConfig.PROP_TEMPLATE_ASSETS_URL);
|
ClientApp clientApp = emailRequest.getClientApp();
|
||||||
|
final String templateAssetsUrl = getUrl(clientApp.getResolvedTemplateAssetsUrl(sysAdminParams),
|
||||||
|
ClientAppConfig.PROP_TEMPLATE_ASSETS_URL, clientApp.getName());
|
||||||
templateModel.put(FTL_TEMPLATE_ASSETS_URL, templateAssetsUrl);
|
templateModel.put(FTL_TEMPLATE_ASSETS_URL, templateAssetsUrl);
|
||||||
if (emailRequest.getTemplateModel() != null)
|
if (emailRequest.getTemplateModel() != null)
|
||||||
{
|
{
|
||||||
@@ -489,11 +495,11 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
actionService.executeAction(mailAction, null, false, sendEmailAsynchronously);
|
actionService.executeAction(mailAction, null, false, sendEmailAsynchronously);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl(String url, String propName)
|
private String getUrl(String url, String propName, String clientName)
|
||||||
{
|
{
|
||||||
if (url == null)
|
if (StringUtils.isEmpty(url))
|
||||||
{
|
{
|
||||||
LOGGER.warn("The url for the property [" + propName + "] is not configured.");
|
LOGGER.warn("The url for the property [" + propName + "] is not configured for the client: " + clientName);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,7 +507,7 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
{
|
{
|
||||||
url = url.substring(0, url.length() - 1);
|
url = url.substring(0, url.length() - 1);
|
||||||
}
|
}
|
||||||
return UrlUtil.replaceShareUrlPlaceholder(url, sysAdminParams);
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getResetPasswordEmailTemplate(ClientApp clientApp)
|
protected String getResetPasswordEmailTemplate(ClientApp clientApp)
|
||||||
@@ -521,22 +527,23 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder(100);
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
|
||||||
String pageUrl = clientApp.getProperty("resetPasswordPageUrl");
|
String pageUrl = clientApp.getResolvedProperty("resetPasswordPageUrl", sysAdminParams);
|
||||||
if (StringUtils.isEmpty(pageUrl))
|
if (StringUtils.isEmpty(pageUrl))
|
||||||
{
|
{
|
||||||
sb.append(UrlUtil.getShareUrl(sysAdminParams));
|
sb.append(UrlUtil.getShareUrl(sysAdminParams));
|
||||||
|
LOGGER.warn("'resetPasswordPageUrl' property is not set for the client [" + clientApp.getName() + "]. The default base url of Share will be used [" + sb + "]");
|
||||||
|
|
||||||
LOGGER.warn("'resetPasswordPageUrl' property is not set for the client [" + clientApp.getName()
|
|
||||||
+ "]. The default base url of Share will be used [" + sb.toString() + "]");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We pass an empty string as we know that the pageUrl is not null
|
// We pass an empty string as we know that the pageUrl is not null
|
||||||
sb.append(getUrl(pageUrl, ""));
|
sb.append(getUrl(pageUrl, "resetPasswordPageUrl", clientApp.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("?key=").append(key)
|
sb.append("?key=")
|
||||||
.append("&id=").append(BPMEngineRegistry.createGlobalId(ActivitiConstants.ENGINE_ID, id));
|
.append(key)
|
||||||
|
.append("&id=")
|
||||||
|
.append(BPMEngineRegistry.createGlobalId(ActivitiConstants.ENGINE_ID, id));
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
@@ -616,10 +623,10 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
private String userEmail;
|
private String userEmail;
|
||||||
private String fromEmail;
|
private String fromEmail;
|
||||||
private String templatePath;
|
private String templatePath;
|
||||||
private String templateAssetsUrl;
|
|
||||||
private Map<String, Serializable> templateModel;
|
private Map<String, Serializable> templateModel;
|
||||||
private String emailSubject;
|
private String emailSubject;
|
||||||
private boolean ignoreSendFailure = true;
|
private boolean ignoreSendFailure = true;
|
||||||
|
private ClientApp clientApp;
|
||||||
|
|
||||||
public String getUserName()
|
public String getUserName()
|
||||||
{
|
{
|
||||||
@@ -665,17 +672,6 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTemplateAssetsUrl()
|
|
||||||
{
|
|
||||||
return templateAssetsUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResetPasswordEmailDetails setTemplateAssetsUrl(String templateAssetsUrl)
|
|
||||||
{
|
|
||||||
this.templateAssetsUrl = templateAssetsUrl;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Serializable> getTemplateModel()
|
public Map<String, Serializable> getTemplateModel()
|
||||||
{
|
{
|
||||||
return templateModel;
|
return templateModel;
|
||||||
@@ -709,18 +705,29 @@ public class ResetPasswordServiceImpl implements ResetPasswordService
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClientApp getClientApp()
|
||||||
|
{
|
||||||
|
return clientApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResetPasswordEmailDetails setClientApp(ClientApp clientApp)
|
||||||
|
{
|
||||||
|
this.clientApp = clientApp;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder(250);
|
final StringBuilder sb = new StringBuilder(300);
|
||||||
sb.append("ResetPasswordEmailDetails [userName=").append(userName)
|
sb.append("ResetPasswordEmailDetails [userName=").append(userName)
|
||||||
.append(", userEmail=").append(userEmail)
|
.append(", userEmail=").append(userEmail)
|
||||||
.append(", fromEmail=").append(fromEmail)
|
.append(", fromEmail=").append(fromEmail)
|
||||||
.append(", templatePath=").append(templatePath)
|
.append(", templatePath=").append(templatePath)
|
||||||
.append(", templateAssetsUrl=").append(templateAssetsUrl)
|
|
||||||
.append(", templateModel=").append(templateModel)
|
.append(", templateModel=").append(templateModel)
|
||||||
.append(", emailSubject=").append(emailSubject)
|
.append(", emailSubject=").append(emailSubject)
|
||||||
.append(", ignoreSendFailure=").append(ignoreSendFailure)
|
.append(", ignoreSendFailure=").append(ignoreSendFailure)
|
||||||
|
.append(", clientApp=").append(clientApp)
|
||||||
.append(']');
|
.append(']');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@@ -29,12 +29,10 @@ package org.alfresco.repo.workflow;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated from 7.1.0
|
|
||||||
*
|
*
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
* @since 5.2.1
|
* @since 5.2.1
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public interface WorkflowModelResetPassword
|
public interface WorkflowModelResetPassword
|
||||||
{
|
{
|
||||||
// namespace
|
// namespace
|
||||||
|
@@ -2,23 +2,23 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
* provided under the following open source license terms:
|
* provided under the following open source license terms:
|
||||||
*
|
*
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
@@ -32,43 +32,62 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Alfresco URL related utility functions.
|
* Alfresco URL related utility functions.
|
||||||
*
|
*
|
||||||
* @since 3.5
|
* @since 3.5
|
||||||
*/
|
*/
|
||||||
public class UrlUtil
|
public class UrlUtil
|
||||||
{
|
{
|
||||||
// ${shareUrl} placeholder
|
// ${shareUrl} placeholder
|
||||||
public static final Pattern PATTERN = Pattern.compile("\\$\\{shareUrl\\}");
|
public static final Pattern PATTERN = Pattern.compile("\\$\\{shareUrl\\}");
|
||||||
|
|
||||||
// ${alfrescoUrl} placeholder
|
// ${alfrescoUrl} placeholder
|
||||||
public static final Pattern REPO_PATTERN = Pattern.compile("\\$\\{alfrescoUrl\\}");
|
public static final Pattern REPO_PATTERN = Pattern.compile("\\$\\{alfrescoUrl\\}");
|
||||||
|
|
||||||
|
// ${repoBaseUrl} placeholder
|
||||||
|
public static final Pattern REPO_BASE_PATTERN = Pattern.compile("\\$\\{repoBaseUrl\\}");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds up the Url to Alfresco based on the settings in the
|
* Builds up the Url to Alfresco root url based on the settings in the
|
||||||
* {@link SysAdminParams}.
|
* {@link SysAdminParams}.
|
||||||
* @return Alfresco Url such as https://col.ab.or.ate/alfresco/
|
* @return Alfresco base Url such as {@code https://col.ab.or.ate}
|
||||||
* or http://localhost:8080/alfresco/
|
* or {@code http://localhost:8080}
|
||||||
|
*/
|
||||||
|
public static String getAlfrescoBaseUrl(SysAdminParams sysAdminParams)
|
||||||
|
{
|
||||||
|
return buildBaseUrl(
|
||||||
|
sysAdminParams.getAlfrescoProtocol(),
|
||||||
|
sysAdminParams.getAlfrescoHost(),
|
||||||
|
sysAdminParams.getAlfrescoPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds up the Url to Alfresco context based on the settings in the
|
||||||
|
* {@link SysAdminParams}.
|
||||||
|
* @return Alfresco Url such as {@code https://col.ab.or.ate/alfresco}
|
||||||
|
* or {@code http://localhost:8080/alfresco}
|
||||||
*/
|
*/
|
||||||
public static String getAlfrescoUrl(SysAdminParams sysAdminParams)
|
public static String getAlfrescoUrl(SysAdminParams sysAdminParams)
|
||||||
{
|
{
|
||||||
return buildUrl(
|
return buildUrl(
|
||||||
sysAdminParams.getAlfrescoProtocol(),
|
sysAdminParams.getAlfrescoProtocol(),
|
||||||
sysAdminParams.getAlfrescoHost(),
|
sysAdminParams.getAlfrescoHost(),
|
||||||
sysAdminParams.getAlfrescoPort(),
|
sysAdminParams.getAlfrescoPort(),
|
||||||
sysAdminParams.getAlfrescoContext());
|
sysAdminParams.getAlfrescoContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds up the Url to Share based on the settings in the
|
* Builds up the Url to Share based on the settings in the
|
||||||
* {@link SysAdminParams}.
|
* {@link SysAdminParams}.
|
||||||
* @return Alfresco Url such as https://col.ab.or.ate/share/
|
* @return Alfresco Url such as {@code https://col.ab.or.ate/share}
|
||||||
* or http://localhost:8081/share/
|
* or {@code http://localhost:8081/share}
|
||||||
*/
|
*/
|
||||||
public static String getShareUrl(SysAdminParams sysAdminParams)
|
public static String getShareUrl(SysAdminParams sysAdminParams)
|
||||||
{
|
{
|
||||||
return buildUrl(
|
return buildUrl(
|
||||||
sysAdminParams.getShareProtocol(),
|
sysAdminParams.getShareProtocol(),
|
||||||
sysAdminParams.getShareHost(),
|
sysAdminParams.getShareHost(),
|
||||||
sysAdminParams.getSharePort(),
|
sysAdminParams.getSharePort(),
|
||||||
sysAdminParams.getShareContext());
|
sysAdminParams.getShareContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -80,8 +99,8 @@ public class UrlUtil
|
|||||||
/**
|
/**
|
||||||
* Builds URL to Api-Explorer based on the request only if the URL property is not provided
|
* Builds URL to Api-Explorer based on the request only if the URL property is not provided
|
||||||
* {@link SysAdminParams}.
|
* {@link SysAdminParams}.
|
||||||
* @return Rest-Api Url such as https://col.ab.or.ate/api-explorer/
|
* @return Rest-Api Url such as {@code https://col.ab.or.ate/api-explorer}
|
||||||
* or http://localhost:8082/api-explorer/
|
* or {@code http://localhost:8082/api-explorer}
|
||||||
*/
|
*/
|
||||||
public static String getApiExplorerUrl(SysAdminParams sysAdminParams, String requestURL, String requestURI)
|
public static String getApiExplorerUrl(SysAdminParams sysAdminParams, String requestURL, String requestURI)
|
||||||
{
|
{
|
||||||
@@ -124,6 +143,12 @@ public class UrlUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static String buildUrl(String protocol, String host, int port, String context)
|
protected static String buildUrl(String protocol, String host, int port, String context)
|
||||||
|
{
|
||||||
|
String baseUrl = buildBaseUrl(protocol, host, port);
|
||||||
|
return baseUrl + '/' + context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String buildBaseUrl(String protocol, String host, int port)
|
||||||
{
|
{
|
||||||
StringBuilder url = new StringBuilder();
|
StringBuilder url = new StringBuilder();
|
||||||
url.append(protocol);
|
url.append(protocol);
|
||||||
@@ -142,8 +167,33 @@ public class UrlUtil
|
|||||||
url.append(':');
|
url.append(':');
|
||||||
url.append(port);
|
url.append(port);
|
||||||
}
|
}
|
||||||
url.append('/');
|
|
||||||
url.append(context);
|
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the repo base url placeholder, namely {@literal ${repoBaseUrl}}, with value based on the settings in the
|
||||||
|
* {@link SysAdminParams}.
|
||||||
|
*
|
||||||
|
* @param value the string value which contains the repoBase url placeholder
|
||||||
|
* @param sysAdminParams the {@code SysAdminParams} object
|
||||||
|
* @return if the given {@code value} contains repoBase url placeholder,
|
||||||
|
* the placeholder is replaced with repoBase url; otherwise, the given {@code value} is simply returned
|
||||||
|
*/
|
||||||
|
public static String replaceRepoBaseUrlPlaceholder(String value, SysAdminParams sysAdminParams)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
return REPO_BASE_PATTERN.matcher(value).replaceAll(getAlfrescoBaseUrl(sysAdminParams));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String replaceUrlPlaceholder(Pattern pattern, String value, String replacement)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
return pattern.matcher(value).replaceAll(replacement);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
# a NodeRef of the template
|
# a NodeRef of the template
|
||||||
# a class path of the template
|
# a class path of the template
|
||||||
|
|
||||||
# template assets url for share client
|
# template assets url for share client. i.e. The source url for the images/logs within the email
|
||||||
repo.client-app.share.templateAssetsUrl=${shareUrl}/res/components/images/
|
repo.client-app.share.templateAssetsUrl=${shareUrl}/res/components/images
|
||||||
# shared-link (quickShare) base url
|
# shared-link (quickShare) base url
|
||||||
repo.client-app.share.sharedLinkBaseUrl=${shareUrl}/s
|
repo.client-app.share.sharedLinkBaseUrl=${shareUrl}/s
|
||||||
# shared-link email template path
|
# shared-link email template path
|
||||||
@@ -20,6 +20,14 @@ repo.client-app.share.resetPasswordPageUrl=${shareUrl}/page/reset-password
|
|||||||
repo.client-app.share.confirmResetPasswordTemplatePath=
|
repo.client-app.share.confirmResetPasswordTemplatePath=
|
||||||
|
|
||||||
### Digital workspace template configurations
|
### Digital workspace template configurations
|
||||||
|
repo.client-app.workspace.workspaceUrl=${repoBaseUrl}/workspace
|
||||||
repo.client-app.workspace.inviteModeratedTemplatePath=
|
repo.client-app.workspace.inviteModeratedTemplatePath=
|
||||||
repo.client-app.workspace.workspaceUrl=workspace
|
# template assets url for workspace client. i.e. The source url for the images/logs within the email
|
||||||
repo.client-app.workspace.templateAssetsUrl=${alfrescoUrl}/images
|
repo.client-app.workspace.templateAssetsUrl=${workspaceUrl}/images
|
||||||
|
|
||||||
|
# reset password request email template path
|
||||||
|
repo.client-app.workspace.requestResetPasswordTemplatePath=alfresco/templates/reset-password-email-templates/forgot-password-email-template.ftl
|
||||||
|
# reset password UI page url
|
||||||
|
repo.client-app.workspace.resetPasswordPageUrl=${workspaceUrl}/reset-password
|
||||||
|
# reset password confirmation email template path
|
||||||
|
repo.client-app.workspace.confirmResetPasswordTemplatePath=
|
||||||
|
@@ -250,7 +250,8 @@ import org.junit.runners.Suite;
|
|||||||
org.alfresco.repo.event2.RepoEvent2UnitSuite.class,
|
org.alfresco.repo.event2.RepoEvent2UnitSuite.class,
|
||||||
|
|
||||||
org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class,
|
org.alfresco.util.schemacomp.SchemaDifferenceHelperUnitTest.class,
|
||||||
org.alfresco.repo.tagging.TaggingServiceImplUnitTest.class
|
org.alfresco.repo.tagging.TaggingServiceImplUnitTest.class,
|
||||||
|
org.alfresco.repo.client.config.ClientAppConfigUnitTest.class
|
||||||
})
|
})
|
||||||
public class AllUnitTestsSuite
|
public class AllUnitTestsSuite
|
||||||
{
|
{
|
||||||
|
@@ -31,16 +31,12 @@ import static org.junit.Assert.assertNotNull;
|
|||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import org.alfresco.repo.client.config.ClientAppConfig.ClientApp;
|
import org.alfresco.repo.client.config.ClientAppConfig.ClientApp;
|
||||||
import org.alfresco.service.cmr.repository.TemporalSourceOptions;
|
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.testing.category.LuceneTests;
|
import org.alfresco.util.testing.category.LuceneTests;
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -53,15 +49,15 @@ import java.util.Map;
|
|||||||
@Category(LuceneTests.class)
|
@Category(LuceneTests.class)
|
||||||
public class ClientAppConfigTest
|
public class ClientAppConfigTest
|
||||||
{
|
{
|
||||||
private ApplicationContext context;
|
|
||||||
private ClientAppConfig clientAppConfig;
|
private ClientAppConfig clientAppConfig;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
ApplicationContextHelper.closeApplicationContext();
|
ApplicationContextHelper.closeApplicationContext();
|
||||||
context = ApplicationContextHelper.getApplicationContext(new String[] { ApplicationContextHelper.CONFIG_LOCATIONS[0],
|
ApplicationContext context = ApplicationContextHelper.getApplicationContext(
|
||||||
"classpath:org/alfresco/repo/client/config/test-repo-clients-apps-context.xml" });
|
new String[] { ApplicationContextHelper.CONFIG_LOCATIONS[0],
|
||||||
|
"classpath:org/alfresco/repo/client/config/test-repo-clients-apps-context.xml" });
|
||||||
|
|
||||||
clientAppConfig = context.getBean("clientAppConfigTest", ClientAppConfig.class);
|
clientAppConfig = context.getBean("clientAppConfigTest", ClientAppConfig.class);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,266 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.client.config;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.alfresco.repo.admin.SysAdminParams;
|
||||||
|
import org.alfresco.repo.client.config.ClientAppConfig.ClientApp;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jamal Kaabi-Mofrad
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ClientAppConfigUnitTest
|
||||||
|
{
|
||||||
|
private ClientAppConfig clientAppConfig;
|
||||||
|
@Mock
|
||||||
|
private SysAdminParams sysAdminParams;
|
||||||
|
|
||||||
|
private AtomicBoolean initialised;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception
|
||||||
|
|
||||||
|
{ // This in not initialised yet. i.e. the properties are not processed yet.
|
||||||
|
// The processing will start when you call the 'onBootstrap()' method
|
||||||
|
clientAppConfig = buildClientAppConfig();
|
||||||
|
|
||||||
|
initialised = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("http");
|
||||||
|
when(sysAdminParams.getAlfrescoHost()).thenReturn("localhost");
|
||||||
|
when(sysAdminParams.getAlfrescoPort()).thenReturn(8080);
|
||||||
|
|
||||||
|
when(sysAdminParams.getShareProtocol()).thenReturn("http");
|
||||||
|
when(sysAdminParams.getShareHost()).thenReturn("localhost");
|
||||||
|
when(sysAdminParams.getSharePort()).thenReturn(8081);
|
||||||
|
when(sysAdminParams.getShareContext()).thenReturn("share");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientAppConfig buildClientAppConfig()
|
||||||
|
{
|
||||||
|
Properties defaultProps = getWorkspaceAppProperties();
|
||||||
|
defaultProps.putAll(getCoolAppProperties());
|
||||||
|
defaultProps.putAll(getShareProperties());
|
||||||
|
Properties globalProps = new Properties();
|
||||||
|
|
||||||
|
ClientAppConfig config = new ClientAppConfig();
|
||||||
|
config.setDefaultProperties(defaultProps);
|
||||||
|
config.setGlobalProperties(globalProps);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWorkspaceClient()
|
||||||
|
{
|
||||||
|
ClientApp client = getClientApp("workspace");
|
||||||
|
assertEquals("workspace", client.getName());
|
||||||
|
assertEquals("${workspaceUrl}/images", client.getTemplateAssetsUrl());
|
||||||
|
assertEquals("${repoBaseUrl}/workspace", client.getClientUrl());
|
||||||
|
assertEquals("workspaceUrl", client.getClientUrlPropKey());
|
||||||
|
assertEquals("\\$\\{workspaceUrl}", client.getClientUrlPlaceholderPattern()
|
||||||
|
.pattern());
|
||||||
|
|
||||||
|
Map<String, String> properties = client.getProperties();
|
||||||
|
assertNotNull(properties);
|
||||||
|
assertNull("Not Set", properties.get("inviteModeratedTemplatePath"));
|
||||||
|
assertEquals("alfresco/templates/test-email-templates/test-email-template.ftl",
|
||||||
|
properties.get("requestResetPasswordTemplatePath"));
|
||||||
|
assertEquals("${workspaceUrl}/reset-password", properties.get("resetPasswordPageUrl"));
|
||||||
|
assertEquals("some/path", properties.get("confirmResetPasswordTemplatePath"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCoolAppClient()
|
||||||
|
{
|
||||||
|
ClientApp client = getClientApp("coolApp");
|
||||||
|
assertEquals("coolApp", client.getName());
|
||||||
|
assertEquals("${coolAppUrl}/images", client.getTemplateAssetsUrl());
|
||||||
|
assertEquals("http://localhost:8090/cool-app", client.getClientUrl());
|
||||||
|
assertEquals("coolAppUrl", client.getClientUrlPropKey());
|
||||||
|
assertEquals("\\$\\{coolAppUrl}", client.getClientUrlPlaceholderPattern()
|
||||||
|
.pattern());
|
||||||
|
|
||||||
|
Map<String, String> properties = client.getProperties();
|
||||||
|
assertNotNull(properties);
|
||||||
|
assertEquals("${coolAppUrl}/page-one/page-two", properties.get("testPropUrl"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveWorkspacePlaceholders()
|
||||||
|
{
|
||||||
|
ClientApp client = getClientApp("workspace");
|
||||||
|
// Raw properties
|
||||||
|
assertEquals("${repoBaseUrl}/workspace", client.getClientUrl());
|
||||||
|
assertEquals("workspaceUrl", client.getClientUrlPropKey());
|
||||||
|
assertEquals("\\$\\{workspaceUrl}", client.getClientUrlPlaceholderPattern()
|
||||||
|
.pattern());
|
||||||
|
assertEquals("${workspaceUrl}/images", client.getTemplateAssetsUrl());
|
||||||
|
assertEquals("${workspaceUrl}/reset-password", client.getProperty("resetPasswordPageUrl"));
|
||||||
|
|
||||||
|
// Resolved properties
|
||||||
|
// String clientUrl = UrlUtil.replaceRepoBaseUrlPlaceholder(client.getClientUrl(), sysAdminParams);
|
||||||
|
assertEquals("http://localhost:8080/workspace", client.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8080/workspace/images", client.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8080/workspace/reset-password",
|
||||||
|
client.getResolvedProperty("resetPasswordPageUrl", sysAdminParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveCoolAppPlaceholders()
|
||||||
|
{
|
||||||
|
ClientApp client = getClientApp("coolApp");
|
||||||
|
// Resolved properties
|
||||||
|
assertEquals("http://localhost:8090/cool-app", client.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8090/cool-app/images", client.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8090/cool-app/page-one/page-two",
|
||||||
|
client.getResolvedProperty("testPropUrl", sysAdminParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveSharePlaceholders()
|
||||||
|
{
|
||||||
|
ClientApp client = getClientApp("share");
|
||||||
|
// Resolved properties
|
||||||
|
assertEquals("http://localhost:8081/share", client.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8081/share/res/components/images",
|
||||||
|
client.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8081/share/page/reset-password",
|
||||||
|
client.getResolvedProperty("resetPasswordPageUrl", sysAdminParams));
|
||||||
|
assertEquals("http://localhost:8081/share/s", client.getResolvedProperty("sharedLinkBaseUrl", sysAdminParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClientsPropertiesOverride()
|
||||||
|
{
|
||||||
|
Properties globalProps = new Properties();
|
||||||
|
globalProps.put("repo.client-app.workspace.workspaceUrl", "https://develop.envalfresco.com/#");
|
||||||
|
globalProps.put("repo.client-app.share.shareUrl", "https://develop.envalfresco.com/share");
|
||||||
|
globalProps.put("repo.client-app.coolApp.coolAppUrl", "https://develop.envalfresco.com/eval/cool-app");
|
||||||
|
|
||||||
|
clientAppConfig.setGlobalProperties(globalProps);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Workspace client URL Override
|
||||||
|
*/
|
||||||
|
ClientApp workspaceClient = getClientApp("workspace");
|
||||||
|
// Resolved properties
|
||||||
|
assertEquals("https://develop.envalfresco.com/#", workspaceClient.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/#/images",
|
||||||
|
workspaceClient.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/#/reset-password",
|
||||||
|
workspaceClient.getResolvedProperty("resetPasswordPageUrl", sysAdminParams));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Share client URL Override
|
||||||
|
*/
|
||||||
|
ClientApp shareClient = getClientApp("share");
|
||||||
|
// Resolved properties
|
||||||
|
assertEquals("https://develop.envalfresco.com/share", shareClient.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/share/res/components/images",
|
||||||
|
shareClient.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/share/page/reset-password",
|
||||||
|
shareClient.getResolvedProperty("resetPasswordPageUrl", sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/share/s",
|
||||||
|
shareClient.getResolvedProperty("sharedLinkBaseUrl", sysAdminParams));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* coolApp client URL Override
|
||||||
|
*/
|
||||||
|
ClientApp coolAppClient = getClientApp("coolApp");
|
||||||
|
// Resolved properties
|
||||||
|
assertEquals("https://develop.envalfresco.com/eval/cool-app",
|
||||||
|
coolAppClient.getResolvedClientUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/eval/cool-app/images",
|
||||||
|
coolAppClient.getResolvedTemplateAssetsUrl(sysAdminParams));
|
||||||
|
assertEquals("https://develop.envalfresco.com/eval/cool-app/page-one/page-two",
|
||||||
|
coolAppClient.getResolvedProperty("testPropUrl", sysAdminParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getWorkspaceAppProperties()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("repo.client-app.workspace.inviteModeratedTemplatePath", "");
|
||||||
|
props.put("repo.client-app.workspace.workspaceUrl", "${repoBaseUrl}/workspace");
|
||||||
|
props.put("repo.client-app.workspace.templateAssetsUrl", "${workspaceUrl}/images");
|
||||||
|
props.put("repo.client-app.workspace.requestResetPasswordTemplatePath",
|
||||||
|
"alfresco/templates/test-email-templates/test-email-template.ftl");
|
||||||
|
props.put("repo.client-app.workspace.resetPasswordPageUrl", "${workspaceUrl}/reset-password");
|
||||||
|
props.put("repo.client-app.workspace.confirmResetPasswordTemplatePath", "some/path");
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getShareProperties()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("repo.client-app.share.templateAssetsUrl", "${shareUrl}/res/components/images");
|
||||||
|
props.put("repo.client-app.share.resetPasswordPageUrl", "${shareUrl}/page/reset-password");
|
||||||
|
props.put("repo.client-app.share.sharedLinkBaseUrl", "${shareUrl}/s");
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getCoolAppProperties()
|
||||||
|
{
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("repo.client-app.coolApp.coolAppUrl", "http://localhost:8090/cool-app");
|
||||||
|
props.put("repo.client-app.coolApp.templateAssetsUrl", "${coolAppUrl}/images");
|
||||||
|
props.put("repo.client-app.coolApp.testPropUrl", "${coolAppUrl}/page-one/page-two");
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientApp getClientApp(String clientName)
|
||||||
|
{
|
||||||
|
if (!initialised.get())
|
||||||
|
{
|
||||||
|
clientAppConfig.onBootstrap(null);
|
||||||
|
initialised.set(true);
|
||||||
|
}
|
||||||
|
Map<String, ClientApp> clients = clientAppConfig.getClients();
|
||||||
|
assertFalse(clients.isEmpty());
|
||||||
|
assertTrue(clientName + " client is expected.", clientAppConfig.exists(clientName));
|
||||||
|
ClientApp client = clients.get(clientName);
|
||||||
|
assertNotNull(clientName + " client can't be null.", client);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
@@ -30,6 +30,9 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.admin.SysAdminParams;
|
||||||
|
import org.alfresco.repo.client.config.ClientAppConfig;
|
||||||
|
import org.alfresco.repo.client.config.ClientAppConfig.ClientApp;
|
||||||
import org.alfresco.repo.client.config.ClientAppNotFoundException;
|
import org.alfresco.repo.client.config.ClientAppNotFoundException;
|
||||||
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.InvalidResetPasswordWorkflowException;
|
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.InvalidResetPasswordWorkflowException;
|
||||||
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetPasswordDetails;
|
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetPasswordDetails;
|
||||||
@@ -47,6 +50,7 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
import org.alfresco.util.TestHelper;
|
import org.alfresco.util.TestHelper;
|
||||||
|
import org.alfresco.util.UrlUtil;
|
||||||
import org.alfresco.util.email.EmailUtil;
|
import org.alfresco.util.email.EmailUtil;
|
||||||
import org.alfresco.util.test.junitrules.ApplicationContextInit;
|
import org.alfresco.util.test.junitrules.ApplicationContextInit;
|
||||||
import org.alfresco.util.test.junitrules.RunAsFullyAuthenticatedRule;
|
import org.alfresco.util.test.junitrules.RunAsFullyAuthenticatedRule;
|
||||||
@@ -88,9 +92,12 @@ public class ResetPasswordServiceImplTest
|
|||||||
private static PersonService personService;
|
private static PersonService personService;
|
||||||
private static Properties globalProperties;
|
private static Properties globalProperties;
|
||||||
private static WorkflowService workflowService;
|
private static WorkflowService workflowService;
|
||||||
|
private static ClientAppConfig clientAppConfig;
|
||||||
|
private static SysAdminParams sysAdminParams;
|
||||||
|
|
||||||
private static TestPerson testPerson;
|
private static TestPerson testPerson1;
|
||||||
private static EmailUtil emailUtil;
|
private static TestPerson testPerson2;
|
||||||
|
private static EmailUtil emailUtil;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initStaticData() throws Exception
|
public static void initStaticData() throws Exception
|
||||||
@@ -103,36 +110,57 @@ public class ResetPasswordServiceImplTest
|
|||||||
personService = APP_CONTEXT_INIT.getApplicationContext().getBean("personService", PersonService.class);
|
personService = APP_CONTEXT_INIT.getApplicationContext().getBean("personService", PersonService.class);
|
||||||
globalProperties = APP_CONTEXT_INIT.getApplicationContext().getBean("global-properties", Properties.class);
|
globalProperties = APP_CONTEXT_INIT.getApplicationContext().getBean("global-properties", Properties.class);
|
||||||
workflowService = APP_CONTEXT_INIT.getApplicationContext().getBean("WorkflowService", WorkflowService.class);
|
workflowService = APP_CONTEXT_INIT.getApplicationContext().getBean("WorkflowService", WorkflowService.class);
|
||||||
|
clientAppConfig = APP_CONTEXT_INIT.getApplicationContext().getBean("clientAppConfig", ClientAppConfig.class);
|
||||||
|
sysAdminParams = APP_CONTEXT_INIT.getApplicationContext().getBean("sysAdminParams", SysAdminParams.class);
|
||||||
emailUtil = new EmailUtil(APP_CONTEXT_INIT.getApplicationContext());
|
emailUtil = new EmailUtil(APP_CONTEXT_INIT.getApplicationContext());
|
||||||
emailUtil.reset();
|
emailUtil.reset();
|
||||||
|
|
||||||
String userName = "jane.doe" + System.currentTimeMillis();
|
String userName1 = "jane.doe" + System.currentTimeMillis();
|
||||||
testPerson = new TestPerson()
|
testPerson1 = new TestPerson()
|
||||||
.setUserName(userName)
|
.setUserName(userName1)
|
||||||
.setFirstName("Jane")
|
.setFirstName("Jane")
|
||||||
.setLastName("doe")
|
.setLastName("Doe")
|
||||||
.setPassword("password")
|
.setPassword("password")
|
||||||
.setEmail(userName + "@example.com");
|
.setEmail(userName1 + "@example.com");
|
||||||
|
|
||||||
|
String userName2 = "sara.blogs" + System.currentTimeMillis();
|
||||||
|
testPerson2 = new TestPerson()
|
||||||
|
.setUserName(userName2)
|
||||||
|
.setFirstName("Sara")
|
||||||
|
.setLastName("Blogs")
|
||||||
|
.setPassword("password")
|
||||||
|
.setEmail(userName2 + "@example.com");
|
||||||
|
|
||||||
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
transactionHelper.doInTransaction((RetryingTransactionCallback<Void>) () ->
|
transactionHelper.doInTransaction((RetryingTransactionCallback<Void>) () ->
|
||||||
{
|
{
|
||||||
createUser(testPerson);
|
createUser(testPerson1);
|
||||||
|
createUser(testPerson2);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
// Restore authentication to pre-test state.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AuthenticationUtil.popAuthentication();
|
||||||
|
}
|
||||||
|
catch(EmptyStackException e)
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void cleanUp()
|
public static void cleanUp()
|
||||||
{
|
{
|
||||||
resetPasswordService.setSendEmailAsynchronously(Boolean.valueOf(
|
resetPasswordService.setSendEmailAsynchronously(Boolean.parseBoolean(
|
||||||
globalProperties.getProperty("system.reset-password.sendEmailAsynchronously")));
|
globalProperties.getProperty("system.reset-password.sendEmailAsynchronously")));
|
||||||
resetPasswordService.setDefaultEmailSender((String) globalProperties.get("system.email.sender.default"));
|
resetPasswordService.setDefaultEmailSender((String) globalProperties.get("system.email.sender.default"));
|
||||||
|
|
||||||
AuthenticationUtil.setRunAsUserSystem();
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
transactionHelper.doInTransaction(() ->
|
transactionHelper.doInTransaction(() ->
|
||||||
{
|
{
|
||||||
personService.deletePerson(testPerson.userName);
|
personService.deletePerson(testPerson1.userName);
|
||||||
|
personService.deletePerson(testPerson2.userName);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -157,21 +185,21 @@ public class ResetPasswordServiceImplTest
|
|||||||
public void testResetPassword() throws Exception
|
public void testResetPassword() throws Exception
|
||||||
{
|
{
|
||||||
// Try the credential before change of password
|
// Try the credential before change of password
|
||||||
authenticateUser(testPerson.userName, testPerson.password);
|
authenticateUser(testPerson1.userName, testPerson1.password);
|
||||||
|
|
||||||
// Make sure to run as system
|
// Make sure to run as system
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
AuthenticationUtil.setRunAsUserSystem();
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
|
|
||||||
// Request password reset
|
// Request password reset
|
||||||
resetPasswordService.requestReset(testPerson.userName, "share");
|
resetPasswordService.requestReset(testPerson1.userName, "share");
|
||||||
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
||||||
// Check the email
|
// Check the email
|
||||||
MimeMessage msg = emailUtil.getLastEmail();
|
MimeMessage msg = emailUtil.getLastEmail();
|
||||||
assertNotNull("There should be an email.", msg);
|
assertNotNull("There should be an email.", msg);
|
||||||
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
||||||
// Check the recipient is the person who requested the reset password
|
// Check the recipient is the person who requested the reset password
|
||||||
assertEquals(testPerson.email, msg.getAllRecipients()[0].toString());
|
assertEquals(testPerson1.email, msg.getAllRecipients()[0].toString());
|
||||||
//Check the sender is what we set as default
|
//Check the sender is what we set as default
|
||||||
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
||||||
// There should be a subject
|
// There should be a subject
|
||||||
@@ -192,7 +220,7 @@ public class ResetPasswordServiceImplTest
|
|||||||
emailUtil.reset();
|
emailUtil.reset();
|
||||||
// Now that we have got the email, try to reset the password
|
// Now that we have got the email, try to reset the password
|
||||||
ResetPasswordDetails passwordDetails = new ResetPasswordDetails()
|
ResetPasswordDetails passwordDetails = new ResetPasswordDetails()
|
||||||
.setUserId(testPerson.userName)
|
.setUserId(testPerson1.userName)
|
||||||
.setPassword("newPassword")
|
.setPassword("newPassword")
|
||||||
.setWorkflowId(pair.getFirst())
|
.setWorkflowId(pair.getFirst())
|
||||||
.setWorkflowKey(pair.getSecond());
|
.setWorkflowKey(pair.getSecond());
|
||||||
@@ -204,7 +232,7 @@ public class ResetPasswordServiceImplTest
|
|||||||
assertNotNull("There should be an email.", msg);
|
assertNotNull("There should be an email.", msg);
|
||||||
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
||||||
// Check the recipient is the person who requested the reset password
|
// Check the recipient is the person who requested the reset password
|
||||||
assertEquals(testPerson.email, msg.getAllRecipients()[0].toString());
|
assertEquals(testPerson1.email, msg.getAllRecipients()[0].toString());
|
||||||
// Check the sender is what we set as default
|
// Check the sender is what we set as default
|
||||||
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
||||||
// There should be a subject
|
// There should be a subject
|
||||||
@@ -215,12 +243,12 @@ public class ResetPasswordServiceImplTest
|
|||||||
assertEquals(msg.getSubject(), I18NUtil.getMessage(emailSubjectKey));
|
assertEquals(msg.getSubject(), I18NUtil.getMessage(emailSubjectKey));
|
||||||
|
|
||||||
// Try the old credential
|
// Try the old credential
|
||||||
TestHelper.assertThrows(() -> authenticateUser(testPerson.userName, testPerson.password),
|
TestHelper.assertThrows(() -> authenticateUser(testPerson1.userName, testPerson1.password),
|
||||||
AuthenticationException.class,
|
AuthenticationException.class,
|
||||||
"As the user changed her password, the authentication should have failed.");
|
"As the user changed her password, the authentication should have failed.");
|
||||||
|
|
||||||
// Try the new credential
|
// Try the new credential
|
||||||
authenticateUser(testPerson.userName, "newPassword");
|
authenticateUser(testPerson1.userName, "newPassword");
|
||||||
|
|
||||||
// Make sure to run as system
|
// Make sure to run as system
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
@@ -237,12 +265,12 @@ public class ResetPasswordServiceImplTest
|
|||||||
public void testRequestResetPasswordInvalid() throws Exception
|
public void testRequestResetPasswordInvalid() throws Exception
|
||||||
{
|
{
|
||||||
// Request password reset
|
// Request password reset
|
||||||
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson.userName, null),
|
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson1.userName, null),
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
"Client name is mandatory.");
|
"Client name is mandatory.");
|
||||||
|
|
||||||
// Request password reset
|
// Request password reset
|
||||||
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson.userName, "TestClient" + System.currentTimeMillis()),
|
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson1.userName, "TestClient" + System.currentTimeMillis()),
|
||||||
ClientAppNotFoundException.class,
|
ClientAppNotFoundException.class,
|
||||||
"Client is not found.");
|
"Client is not found.");
|
||||||
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
||||||
@@ -260,23 +288,23 @@ public class ResetPasswordServiceImplTest
|
|||||||
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
||||||
|
|
||||||
// Disable the user
|
// Disable the user
|
||||||
enableUser(testPerson.userName, false);
|
enableUser(testPerson1.userName, false);
|
||||||
|
|
||||||
// Request password reset
|
// Request password reset
|
||||||
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson.userName, "share"),
|
TestHelper.assertThrows(() -> resetPasswordService.requestReset(testPerson1.userName, "share"),
|
||||||
ResetPasswordWorkflowInvalidUserException.class,
|
ResetPasswordWorkflowInvalidUserException.class,
|
||||||
"user is disabled.");
|
"user is disabled.");
|
||||||
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
||||||
|
|
||||||
// Enable the user
|
// Enable the user
|
||||||
enableUser(testPerson.userName, true);
|
enableUser(testPerson1.userName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResetPasswordInvalid() throws Exception
|
public void testResetPasswordInvalid() throws Exception
|
||||||
{
|
{
|
||||||
// Request password reset
|
// Request password reset
|
||||||
resetPasswordService.requestReset(testPerson.userName, "share");
|
resetPasswordService.requestReset(testPerson1.userName, "share");
|
||||||
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
||||||
// Check the email
|
// Check the email
|
||||||
MimeMessage msg = emailUtil.getLastEmail();
|
MimeMessage msg = emailUtil.getLastEmail();
|
||||||
@@ -307,7 +335,7 @@ public class ResetPasswordServiceImplTest
|
|||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
"User id is mandatory.");
|
"User id is mandatory.");
|
||||||
|
|
||||||
passwordDetails.setUserId(testPerson.userName)
|
passwordDetails.setUserId(testPerson1.userName)
|
||||||
.setPassword(null); // Password is not provided
|
.setPassword(null); // Password is not provided
|
||||||
TestHelper.assertThrows(() -> resetPasswordService.initiateResetPassword(passwordDetails),
|
TestHelper.assertThrows(() -> resetPasswordService.initiateResetPassword(passwordDetails),
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
@@ -363,7 +391,7 @@ public class ResetPasswordServiceImplTest
|
|||||||
// Set the duration for 1 second
|
// Set the duration for 1 second
|
||||||
resetPasswordService.setTimerEnd("PT1S");
|
resetPasswordService.setTimerEnd("PT1S");
|
||||||
// Request password reset
|
// Request password reset
|
||||||
resetPasswordService.requestReset(testPerson.userName, "share");
|
resetPasswordService.requestReset(testPerson1.userName, "share");
|
||||||
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
||||||
|
|
||||||
// Check the reset password url.
|
// Check the reset password url.
|
||||||
@@ -377,7 +405,7 @@ public class ResetPasswordServiceImplTest
|
|||||||
emailUtil.reset();
|
emailUtil.reset();
|
||||||
// Now that we have got the email, try to reset the password
|
// Now that we have got the email, try to reset the password
|
||||||
ResetPasswordDetails passwordDetails = new ResetPasswordDetails()
|
ResetPasswordDetails passwordDetails = new ResetPasswordDetails()
|
||||||
.setUserId(testPerson.userName)
|
.setUserId(testPerson1.userName)
|
||||||
.setPassword("newPassword")
|
.setPassword("newPassword")
|
||||||
.setWorkflowId(pair.getFirst())
|
.setWorkflowId(pair.getFirst())
|
||||||
.setWorkflowKey(pair.getSecond());
|
.setWorkflowKey(pair.getSecond());
|
||||||
@@ -396,6 +424,110 @@ public class ResetPasswordServiceImplTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResetPasswordForClientWorkspace() throws Exception
|
||||||
|
{
|
||||||
|
// Try the credential before change of password
|
||||||
|
authenticateUser(testPerson2.userName, testPerson2.password);
|
||||||
|
|
||||||
|
// Make sure to run as system
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
|
|
||||||
|
// Request password reset
|
||||||
|
resetPasswordService.requestReset(testPerson2.userName, "workspace");
|
||||||
|
assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
|
||||||
|
// Check the email
|
||||||
|
MimeMessage msg = emailUtil.getLastEmail();
|
||||||
|
assertNotNull("There should be an email.", msg);
|
||||||
|
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
||||||
|
// Check the recipient is the person who requested the reset password
|
||||||
|
assertEquals(testPerson2.email, msg.getAllRecipients()[0].toString());
|
||||||
|
//Check the sender is what we set as default
|
||||||
|
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
||||||
|
// There should be a subject
|
||||||
|
assertNotNull("There should be a subject.", msg.getSubject());
|
||||||
|
// Check the default email subject - (check that we are sending the right email)
|
||||||
|
String emailSubjectKey = getDeclaredField(SendResetPasswordEmailDelegate.class, "EMAIL_SUBJECT_KEY");
|
||||||
|
assertNotNull(emailSubjectKey);
|
||||||
|
assertEquals(msg.getSubject(), I18NUtil.getMessage(emailSubjectKey));
|
||||||
|
|
||||||
|
// Check the reset password url.
|
||||||
|
String resetPasswordUrl = (String) emailUtil.getLastEmailTemplateModelValue("reset_password_url");
|
||||||
|
assertNotNull("Wrong email is sent.", resetPasswordUrl);
|
||||||
|
// Get the workflow id and key
|
||||||
|
Pair<String, String> pair = getWorkflowIdAndKeyFromUrl(resetPasswordUrl);
|
||||||
|
assertNotNull("Workflow Id can't be null.", pair.getFirst());
|
||||||
|
assertNotNull("Workflow Key can't be null.", pair.getSecond());
|
||||||
|
|
||||||
|
emailUtil.reset();
|
||||||
|
// Now that we have got the email, try to reset the password
|
||||||
|
ResetPasswordDetails passwordDetails = new ResetPasswordDetails()
|
||||||
|
.setUserId(testPerson2.userName)
|
||||||
|
.setPassword("strongPassword")
|
||||||
|
.setWorkflowId(pair.getFirst())
|
||||||
|
.setWorkflowKey(pair.getSecond());
|
||||||
|
|
||||||
|
resetPasswordService.initiateResetPassword(passwordDetails);
|
||||||
|
assertEquals("A reset password confirmation email should have been sent.", 1, emailUtil.getSentCount());
|
||||||
|
// Check the email
|
||||||
|
msg = emailUtil.getLastEmail();
|
||||||
|
assertNotNull("There should be an email.", msg);
|
||||||
|
assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
|
||||||
|
// Check the recipient is the person who requested the reset password
|
||||||
|
assertEquals(testPerson2.email, msg.getAllRecipients()[0].toString());
|
||||||
|
// Check the sender is what we set as default
|
||||||
|
assertEquals(DEFAULT_SENDER, msg.getFrom()[0].toString());
|
||||||
|
// There should be a subject
|
||||||
|
assertNotNull("There should be a subject.", msg.getSubject());
|
||||||
|
// Check the default email subject - (check that we are sending the right email)
|
||||||
|
emailSubjectKey = getDeclaredField(SendResetPasswordConfirmationEmailDelegate.class, "EMAIL_SUBJECT_KEY");
|
||||||
|
assertNotNull(emailSubjectKey);
|
||||||
|
assertEquals(msg.getSubject(), I18NUtil.getMessage(emailSubjectKey));
|
||||||
|
|
||||||
|
// Try the old credential
|
||||||
|
TestHelper.assertThrows(() -> authenticateUser(testPerson2.userName, testPerson2.password),
|
||||||
|
AuthenticationException.class,
|
||||||
|
"As the user changed her password, the authentication should have failed.");
|
||||||
|
|
||||||
|
// Try the new credential
|
||||||
|
authenticateUser(testPerson2.userName, "strongPassword");
|
||||||
|
|
||||||
|
// Make sure to run as system
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
AuthenticationUtil.setRunAsUserSystem();
|
||||||
|
emailUtil.reset();
|
||||||
|
// Try reset again with the used workflow
|
||||||
|
TestHelper.assertThrows(() -> resetPasswordService.initiateResetPassword(passwordDetails),
|
||||||
|
InvalidResetPasswordWorkflowException.class,
|
||||||
|
"The workflow instance is not active (it has already been used).");
|
||||||
|
assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateResetPasswordUrl()
|
||||||
|
{
|
||||||
|
/* Out of the box we have share and workspace registered as the clients.
|
||||||
|
* See: alfresco/client/config/repo-clients-apps.properties file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Share client
|
||||||
|
ClientApp share = clientAppConfig.getClient("share");
|
||||||
|
String shareResetPasswordUrl =
|
||||||
|
resetPasswordService.createResetPasswordUrl(share, "workflow-id-123", "workflow-key-123");
|
||||||
|
String shareExpectedUrl = UrlUtil.getShareUrl(sysAdminParams)
|
||||||
|
+ "/page/reset-password?key=workflow-key-123&id=activiti$workflow-id-123";
|
||||||
|
assertEquals(shareExpectedUrl, shareResetPasswordUrl);
|
||||||
|
|
||||||
|
// Workspace client
|
||||||
|
ClientApp workspace = clientAppConfig.getClient("workspace");
|
||||||
|
String workspaceResetPasswordUrl =
|
||||||
|
resetPasswordService.createResetPasswordUrl(workspace, "workflow-id-456", "workflow-key-456");
|
||||||
|
String workspaceExpectedUrl = UrlUtil.getAlfrescoBaseUrl(sysAdminParams)
|
||||||
|
+ "/workspace/reset-password?key=workflow-key-456&id=activiti$workflow-id-456";
|
||||||
|
assertEquals(workspaceExpectedUrl, workspaceResetPasswordUrl);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isActive(String workflowId)
|
private boolean isActive(String workflowId)
|
||||||
{
|
{
|
||||||
WorkflowInstance workflowInstance = workflowService.getWorkflowById(workflowId);
|
WorkflowInstance workflowInstance = workflowService.getWorkflowById(workflowId);
|
||||||
|
Reference in New Issue
Block a user