From 2933d45eff00c0555f5cd8625f95aa5d5ac9388a Mon Sep 17 00:00:00 2001 From: dhrn Date: Tue, 3 Nov 2020 15:03:43 +0530 Subject: [PATCH] [ACS-777] Email notification for digital workspace --- .../src/main/webapp/images/logo/workspace.png | Bin 0 -> 8294 bytes .../rest/api/SiteMembershipRequests.java | 20 +- .../api/impl/SiteMembershipRequestsImpl.java | 73 +++- .../PersonSiteMembershipRequestsRelation.java | 59 +-- .../repo/invitation/InvitationImpl.java | 59 +-- .../invitation/InvitationServiceImpl.java | 366 +++++++++++------- .../invitation/ModeratedInvitationImpl.java | 52 +-- .../WorkflowModelModeratedInvitation.java | 61 +-- .../activiti/SendModeratedInviteDelegate.java | 81 ++-- .../site/InviteModeratedSender.java | 58 ++- .../repo/invitation/site/InviteSender.java | 111 +++--- .../cmr/invitation/InvitationService.java | 89 +++-- .../main/java/org/alfresco/util/UrlUtil.java | 12 +- .../alfresco/invitation-service-context.xml | 2 + .../messages/templates-messages.properties | 4 + .../workspace/invite-email-moderated.html.ftl | 121 ++++++ .../invitation-moderated-workflow-model.xml | 3 + 17 files changed, 778 insertions(+), 393 deletions(-) create mode 100644 packaging/war/src/main/webapp/images/logo/workspace.png create mode 100644 repository/src/main/resources/alfresco/templates/workspace/invite-email-moderated.html.ftl diff --git a/packaging/war/src/main/webapp/images/logo/workspace.png b/packaging/war/src/main/webapp/images/logo/workspace.png new file mode 100644 index 0000000000000000000000000000000000000000..26c01ad48e29e75541d639a82b026477f8cb56cf GIT binary patch literal 8294 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 b75oa@+)@NJEB-3;SMQgXR*|ZDZyNG{LU`{J literal 0 HcmV?d00001 diff --git a/remote-api/src/main/java/org/alfresco/rest/api/SiteMembershipRequests.java b/remote-api/src/main/java/org/alfresco/rest/api/SiteMembershipRequests.java index fa6892b1df..45609fcab0 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/SiteMembershipRequests.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/SiteMembershipRequests.java @@ -45,15 +45,25 @@ public interface SiteMembershipRequests /** * Create a site membership request for the user 'inviteeId' - * @param inviteeId the site inviteee id + * @param inviteeId the site invite id * @param siteInvite the site invite * @return SiteMembershipRequest */ SiteMembershipRequest createSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite); + + /** + * Create a site membership request for the user 'inviteeId' + * @param inviteeId the site invitee id + * @param siteInvite the site invite + * @param client the client name which is registered to send emails + * @param workspacePath path of workspace deployed location + * @return SiteMembershipRequest + */ + SiteMembershipRequest createSiteMembershipRequest(String inviteeId, final SiteMembershipRequest siteInvite, final String client, final String workspacePath); /** * Update the site membership request for inviteeId and site - * @param inviteeId the site inviteee id + * @param inviteeId the site invite id * @param siteInvite the site invite * @return the updated siteMembershipRequest */ @@ -62,7 +72,7 @@ public interface SiteMembershipRequests /** * Cancel site membership request for invitee and site. * - * @param inviteeId the site inviteee id + * @param inviteeId the site invite id * @param siteId the site id */ void cancelSiteMembershipRequest(String inviteeId, String siteId); @@ -70,7 +80,7 @@ public interface SiteMembershipRequests /** * Get the site membership request for inviteeId and siteId, if it exists. * - * @param inviteeId the site inviteee id + * @param inviteeId the site invite id * @param siteId the site id * @return the site membership request */ @@ -79,7 +89,7 @@ public interface SiteMembershipRequests /** * Get a paged list of site membership requests for inviteeId. * - * @param inviteeId the site inviteee id + * @param inviteeId the site invite id * @param paging paging information * @return a paged list of site membership requests */ diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/SiteMembershipRequestsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/SiteMembershipRequestsImpl.java index 6cc008c731..218f8697a6 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/SiteMembershipRequestsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/SiteMembershipRequestsImpl.java @@ -158,9 +158,9 @@ public class SiteMembershipRequestsImpl implements SiteMembershipRequests } private SiteMembershipRequest inviteToModeratedSite(final String message, final String inviteeId, final String siteId, - final String inviteeRole) + final String inviteeRole, final String clientName, final String workspacePath) { - ModeratedInvitation invitation = invitationService.inviteModerated(message, inviteeId, ResourceType.WEB_SITE, siteId, inviteeRole); + ModeratedInvitation invitation = invitationService.inviteModerated(message, inviteeId, ResourceType.WEB_SITE, siteId, inviteeRole, clientName, workspacePath); SiteMembershipRequest ret = new SiteMembershipRequest(); ret.setId(siteId); @@ -270,7 +270,74 @@ public class SiteMembershipRequestsImpl implements SiteMembershipRequests if(siteVisibility.equals(SiteVisibility.MODERATED)) { - request = inviteToModeratedSite(message, inviteeId, siteId, inviteeRole); + request = inviteToModeratedSite(message, inviteeId, siteId, inviteeRole, null, null); + } + else if(siteVisibility.equals(SiteVisibility.PUBLIC)) + { + request = inviteToPublicSite(siteInfo, message, inviteeId, inviteeRole); + } + else + { + // note: security, no indication that this is a private site + throw new RelationshipResourceNotFoundException(inviteeId, siteId); + } + + return request; + } + + @Override + public SiteMembershipRequest createSiteMembershipRequest(String inviteeId, SiteMembershipRequest siteInvite, String client, String workspacePath) { + SiteMembershipRequest request = null; + + inviteeId = people.validatePerson(inviteeId, true); + + // Note that the order of error checking is important. The server first needs to check for the status 404 + // conditions before checking for status 400 conditions. Otherwise the server is open to a probing attack. + String siteId = siteInvite.getId(); + final SiteInfo siteInfo = sites.validateSite(siteId); + if(siteInfo == null) + { + // site does not exist + throw new RelationshipResourceNotFoundException(inviteeId, siteId); + } + // set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url) + siteId = siteInfo.getShortName(); + + final SiteVisibility siteVisibility = siteInfo.getVisibility(); + + if(siteVisibility.equals(SiteVisibility.PRIVATE)) + { + // note: security, no indication that this is a private site + throw new RelationshipResourceNotFoundException(inviteeId, siteId); + } + + // Is the invitee already a member of the site? + boolean isMember = siteService.isMember(siteId, inviteeId); + if(isMember) + { + // yes + throw new InvalidArgumentException(inviteeId + " is already a member of site " + siteId); + } + + // Is there an outstanding site invite request for the (invitee, site)? + Invitation invitation = getSiteInvitation(inviteeId, siteId); + if(invitation != null) + { + // yes + throw new InvalidArgumentException(inviteeId + " is already invited to site " + siteId); + } + + final String inviteeRole = DEFAULT_ROLE; + String message = siteInvite.getMessage(); + if(message == null) + { + // the invitation service ignores null messages so convert to an empty message. + message = ""; + } + + if(siteVisibility.equals(SiteVisibility.MODERATED)) + { + request = inviteToModeratedSite(message, inviteeId, siteId, inviteeRole, client, workspacePath);; } else if(siteVisibility.equals(SiteVisibility.PUBLIC)) { diff --git a/remote-api/src/main/java/org/alfresco/rest/api/people/PersonSiteMembershipRequestsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/people/PersonSiteMembershipRequestsRelation.java index 3d7c018e26..3537cbc5f3 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/people/PersonSiteMembershipRequestsRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/people/PersonSiteMembershipRequestsRelation.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.rest.api.people; import java.util.ArrayList; @@ -73,7 +73,14 @@ RelationshipResourceAction.Create, RelationshipResourceAc List result = new ArrayList(invites.size()); for(SiteMembershipRequest invite : invites) { - SiteMembershipRequest siteInvite = siteMembershipRequests.createSiteMembershipRequest(personId, invite); + SiteMembershipRequest siteInvite = null; + String client = parameters.getParameter("client"); + String workspacePath = parameters.getParameter("workspacePath"); + if(client != null) { + siteInvite = siteMembershipRequests.createSiteMembershipRequest(personId, invite, client, workspacePath); + } else { + siteInvite = siteMembershipRequests.createSiteMembershipRequest(personId, invite); + } result.add(siteInvite); } return result; diff --git a/repository/src/main/java/org/alfresco/repo/invitation/InvitationImpl.java b/repository/src/main/java/org/alfresco/repo/invitation/InvitationImpl.java index 803a68d46f..5b638ff0f9 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/InvitationImpl.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/InvitationImpl.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.repo.invitation; import java.io.Serializable; @@ -42,6 +42,7 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; public static final String ROLE_KEY = "role"; public static final String CREATED_AT = "createdAt"; public static final String MODIFIED_AT = "modifiedAt"; + public static final String CLIENT_NAME = "clientName"; /** * Unique reference for this invitation @@ -72,6 +73,8 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; private final Date modifiedAt; + private final Date clientName; + public InvitationImpl(Map props) { this.inviteId = (String)props.get(ID_KEY); @@ -82,6 +85,7 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; this.resourceType = type==null ? ResourceType.WEB_SITE : ResourceType.valueOf(type); this.createdAt = (Date)props.get(CREATED_AT); this.modifiedAt = (Date)props.get(MODIFIED_AT); + this.clientName = (Date)props.get(CLIENT_NAME); } /** @@ -122,6 +126,11 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; { return inviteeUserName; } + + public Date getClientName() + { + return clientName; + } public abstract InvitationType getInvitationType(); } diff --git a/repository/src/main/java/org/alfresco/repo/invitation/InvitationServiceImpl.java b/repository/src/main/java/org/alfresco/repo/invitation/InvitationServiceImpl.java index aa3872bb71..41562d8ba2 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/InvitationServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/InvitationServiceImpl.java @@ -1,119 +1,120 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.repo.invitation; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarAcceptUrl; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteTicket; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteeGenPassword; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteeUserName; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviterUserName; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarRejectUrl; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarResourceName; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarRole; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarServerPath; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.action.executer.MailActionExecuter; -import org.alfresco.repo.admin.SysAdminParams; -import org.alfresco.repo.i18n.MessageService; -import org.alfresco.repo.invitation.activiti.SendNominatedInviteDelegate; -import org.alfresco.repo.invitation.site.InviteModeratedSender; -import org.alfresco.repo.invitation.site.InviteNominatedSender; -import org.alfresco.repo.invitation.site.InviteSender; -import org.alfresco.repo.jscript.ScriptNode; -import org.alfresco.repo.model.Repository; -import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy; -import org.alfresco.repo.policy.JavaBehaviour; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.security.authentication.AuthenticationException; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.authentication.PasswordGenerator; -import org.alfresco.repo.security.authentication.UserNameGenerator; -import org.alfresco.repo.site.SiteModel; -import org.alfresco.repo.transaction.TransactionalResourceHelper; -import org.alfresco.repo.workflow.CancelWorkflowActionExecuter; -import org.alfresco.repo.workflow.WorkflowModel; -import org.alfresco.repo.workflow.activiti.ActivitiConstants; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.invitation.Invitation; -import org.alfresco.service.cmr.invitation.Invitation.ResourceType; -import org.alfresco.service.cmr.invitation.InvitationException; -import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden; -import org.alfresco.service.cmr.invitation.InvitationExceptionNotFound; -import org.alfresco.service.cmr.invitation.InvitationExceptionUserError; -import org.alfresco.service.cmr.invitation.InvitationSearchCriteria; -import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType; -import org.alfresco.service.cmr.invitation.InvitationService; -import org.alfresco.service.cmr.invitation.ModeratedInvitation; -import org.alfresco.service.cmr.invitation.NominatedInvitation; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.TemplateService; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.security.MutableAuthenticationService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.cmr.site.SiteInfo; -import org.alfresco.service.cmr.site.SiteService; -import org.alfresco.service.cmr.workflow.WorkflowAdminService; -import org.alfresco.service.cmr.workflow.WorkflowDefinition; -import org.alfresco.service.cmr.workflow.WorkflowException; -import org.alfresco.service.cmr.workflow.WorkflowPath; -import org.alfresco.service.cmr.workflow.WorkflowService; -import org.alfresco.service.cmr.workflow.WorkflowTask; -import org.alfresco.service.cmr.workflow.WorkflowTaskQuery; -import org.alfresco.service.cmr.workflow.WorkflowTaskState; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; -import org.alfresco.util.PropertyCheck; -import org.alfresco.util.UrlUtil; -import org.alfresco.util.collections.CollectionUtils; -import org.alfresco.util.collections.Function; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.extensions.surf.util.I18NUtil; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarAcceptUrl; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteTicket; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteeGenPassword; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviteeUserName; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarInviterUserName; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarRejectUrl; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarResourceName; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarRole; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarServerPath; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.executer.MailActionExecuter; +import org.alfresco.repo.admin.SysAdminParams; +import org.alfresco.repo.client.config.ClientAppConfig; +import org.alfresco.repo.i18n.MessageService; +import org.alfresco.repo.invitation.activiti.SendNominatedInviteDelegate; +import org.alfresco.repo.invitation.site.InviteModeratedSender; +import org.alfresco.repo.invitation.site.InviteNominatedSender; +import org.alfresco.repo.invitation.site.InviteSender; +import org.alfresco.repo.jscript.ScriptNode; +import org.alfresco.repo.model.Repository; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy; +import org.alfresco.repo.policy.JavaBehaviour; +import org.alfresco.repo.policy.PolicyComponent; +import org.alfresco.repo.security.authentication.AuthenticationException; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.security.authentication.PasswordGenerator; +import org.alfresco.repo.security.authentication.UserNameGenerator; +import org.alfresco.repo.site.SiteModel; +import org.alfresco.repo.transaction.TransactionalResourceHelper; +import org.alfresco.repo.workflow.CancelWorkflowActionExecuter; +import org.alfresco.repo.workflow.WorkflowModel; +import org.alfresco.repo.workflow.activiti.ActivitiConstants; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.Invitation.ResourceType; +import org.alfresco.service.cmr.invitation.InvitationException; +import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden; +import org.alfresco.service.cmr.invitation.InvitationExceptionNotFound; +import org.alfresco.service.cmr.invitation.InvitationExceptionUserError; +import org.alfresco.service.cmr.invitation.InvitationSearchCriteria; +import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType; +import org.alfresco.service.cmr.invitation.InvitationService; +import org.alfresco.service.cmr.invitation.ModeratedInvitation; +import org.alfresco.service.cmr.invitation.NominatedInvitation; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.TemplateService; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; +import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.workflow.WorkflowAdminService; +import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.alfresco.service.cmr.workflow.WorkflowException; +import org.alfresco.service.cmr.workflow.WorkflowPath; +import org.alfresco.service.cmr.workflow.WorkflowService; +import org.alfresco.service.cmr.workflow.WorkflowTask; +import org.alfresco.service.cmr.workflow.WorkflowTaskQuery; +import org.alfresco.service.cmr.workflow.WorkflowTaskState; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; +import org.alfresco.util.PropertyCheck; +import org.alfresco.util.UrlUtil; +import org.alfresco.util.collections.CollectionUtils; +import org.alfresco.util.collections.Function; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.surf.util.I18NUtil; /** * Implementation of invitation service. @@ -138,14 +139,16 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli wfVarServerPath,// wfVarAcceptUrl,// wfVarRejectUrl, - InviteNominatedSender.WF_INSTANCE_ID); - - private static final List SEND_INVITE_MODERATED_PROP_NAMES = Arrays.asList( - WorkflowModelModeratedInvitation.wfVarInviteeUserName, - WorkflowModelModeratedInvitation.wfVarInviteeRole, - WorkflowModelModeratedInvitation.wfVarResourceName, - WorkflowModelModeratedInvitation.bpmGroupAssignee, - WorkflowModelModeratedInvitation.wfVarResourceType); + InviteNominatedSender.WF_INSTANCE_ID); + + private static final List SEND_INVITE_MODERATED_PROP_NAMES = Arrays.asList( + WorkflowModelModeratedInvitation.wfVarInviteeUserName, + WorkflowModelModeratedInvitation.wfVarInviteeRole, + WorkflowModelModeratedInvitation.wfVarResourceName, + WorkflowModelModeratedInvitation.bpmGroupAssignee, + WorkflowModelModeratedInvitation.wfVarResourceType, + WorkflowModelModeratedInvitation.wfVarTemplateAssetsUrl, + WorkflowModelModeratedInvitation.wfVarWorkspaceUrl); /** @@ -170,8 +173,9 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli private Repository repositoryHelper; private ServiceRegistry serviceRegistry; private MessageService messageService; - private InviteNominatedSender inviteNominatedSender; + private InviteNominatedSender inviteNominatedSender; private InviteModeratedSender inviteModeratedSender; + private ClientAppConfig clientAppConfig; // maximum number of tries to generate a invitee user name which // does not already belong to an existing person @@ -194,6 +198,11 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli private String moderatedInvitationWorkflowId = WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI; + public void setClientAppConfig(ClientAppConfig clientAppConfig) + { + this.clientAppConfig = clientAppConfig; + } + /** * Set the policy component * @@ -253,7 +262,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli PropertyCheck.mandatory(this, "PolicyComponent", policyComponent); PropertyCheck.mandatory(this, "templateService", templateService); - this.inviteNominatedSender = new InviteNominatedSender(serviceRegistry, repositoryHelper, messageService); + this.inviteNominatedSender = new InviteNominatedSender(serviceRegistry, repositoryHelper, messageService); this.inviteModeratedSender = new InviteModeratedSender(serviceRegistry, repositoryHelper, messageService); // @@ -995,7 +1004,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli query.setTaskName(WorkflowModelModeratedInvitation.WF_ACTIVITI_REVIEW_TASK); // query for invite workflow tasks - List results = new ArrayList(); + List results = new ArrayList(); if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) { query.setTaskName(WorkflowModelModeratedInvitation.WF_ACTIVITI_REVIEW_TASK); @@ -1983,10 +1992,10 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli String emailSubjectKey, Map executionVariables) { sendInviteEmail(inviteNominatedSender, SEND_INVITE_NOMINATED_PROP_NAMES, inviteId, emailTemplateXpath, emailSubjectKey, executionVariables); - } - - private void sendInviteEmail(InviteSender inviteSender, List invitePropNames, String inviteId, String emailTemplateXpath, String emailSubjectKey, Map executionVariables) - { + } + + private void sendInviteEmail(InviteSender inviteSender, List invitePropNames, String inviteId, String emailTemplateXpath, String emailSubjectKey, Map executionVariables) + { if (isSendEmails()) { Map properties = makePropertiesFromContextVariables(executionVariables, invitePropNames); @@ -1997,23 +2006,23 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli properties.put(InviteNominatedSender.WF_INSTANCE_ID, inviteId); inviteSender.sendMail(emailTemplateXpath, emailSubjectKey, properties); - } - } - - - @Override - public void sendModeratedInvitation(String inviteId, String emailTemplateXpath, String emailSubjectKey, Map executionVariables) - { - sendInviteEmail(inviteModeratedSender, SEND_INVITE_MODERATED_PROP_NAMES, inviteId, emailTemplateXpath, emailSubjectKey, executionVariables); - - } - - private String getPackageRef(Map executionVariables) - { - String packageName = WorkflowModel.ASSOC_PACKAGE.toPrefixString(namespaceService).replace(":", "_"); - ScriptNode packageNode = (ScriptNode) executionVariables.get(packageName); - String packageRef = packageNode.getNodeRef().toString(); - return packageRef; + } + } + + + @Override + public void sendModeratedInvitation(String inviteId, String emailTemplateXpath, String emailSubjectKey, Map executionVariables) + { + sendInviteEmail(inviteModeratedSender, SEND_INVITE_MODERATED_PROP_NAMES, inviteId, emailTemplateXpath, emailSubjectKey, executionVariables); + + } + + private String getPackageRef(Map executionVariables) + { + String packageName = WorkflowModel.ASSOC_PACKAGE.toPrefixString(namespaceService).replace(":", "_"); + ScriptNode packageNode = (ScriptNode) executionVariables.get(packageName); + String packageRef = packageNode.getNodeRef().toString(); + return packageRef; } @Override @@ -2042,4 +2051,71 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli { return CollectionUtils.filterKeys((Map) executionVariables, CollectionUtils.containsFilter(propertyNames)); } + + /** + * Start the invitation process for a ModeratedInvitation + * + * @param inviteeComments why does the invitee want access to the resource ? + * @param inviteeUserName who is to be invited + * @param resourceType Invitation .ResourceType what resource type ? + * @param resourceName which resource + * @param inviteeRole which role ? + * @param clientName which client + */ + public ModeratedInvitation inviteModerated(String inviteeComments, String inviteeUserName, + Invitation.ResourceType resourceType, String resourceName, String inviteeRole, String clientName, String workspacePath) + { + if (resourceType == Invitation.ResourceType.WEB_SITE) + { + return startModeratedInvite(inviteeComments, inviteeUserName, resourceType, resourceName, inviteeRole, clientName, workspacePath); + } + throw new InvitationException("unknown resource type"); + } + + /** + * Moderated invitation implementation for given client + * + * @return the new moderated invitation + */ + private ModeratedInvitation startModeratedInvite(String inviteeComments, String inviteeUserName, + Invitation.ResourceType resourceType, String resourceName, String inviteeRole, String clientName, String workspacePath) + { + SiteInfo siteInfo = siteService.getSite(resourceName); + + if (siteService.isMember(resourceName, inviteeUserName)) + { + if (logger.isDebugEnabled()) + logger.debug("Failed - invitee user is already a member of the site."); + + Object objs[] = { inviteeUserName, "", resourceName }; + throw new InvitationExceptionUserError("invitation.invite.already_member", objs); + } + + String roleGroup = siteService.getSiteRoleGroup(resourceName, SiteModel.SITE_MANAGER); + + // get the workflow description + String workflowDescription = generateWorkflowDescription(siteInfo, "invitation.moderated.workflow.description"); + + Map workflowProps = new HashMap(16); + workflowProps.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, workflowDescription); + workflowProps.put(WorkflowModelModeratedInvitation.ASSOC_GROUP_ASSIGNEE, roleGroup); + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_COMMENTS, inviteeComments); + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_ROLE, inviteeRole); + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_USER_NAME, inviteeUserName); + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_NAME, resourceName); + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_TYPE, resourceType.toString()); + + workflowProps.put(WorkflowModelModeratedInvitation.WF_PROP_CLIENT_NAME, clientName); + if(clientName != null && clientAppConfig.getClient(clientName) != null) { + ClientAppConfig.ClientApp client = clientAppConfig.getClient(clientName); + workflowProps.put(WorkflowModelModeratedInvitation.WF_TEMPLATE_ASSETS_URL, client.getTemplateAssetsUrl()); + String workspaceUrl = workspacePath != null ? workspacePath : client.getProperty("workspaceUrl"); + workflowProps.put(WorkflowModelModeratedInvitation.WF_WORKSPACE_URL, workspaceUrl); + } + + // get the moderated workflow + + WorkflowDefinition wfDefinition = getWorkflowDefinition(InvitationWorkflowType.MODERATED); + return (ModeratedInvitation) startWorkflow(wfDefinition, workflowProps); + } } diff --git a/repository/src/main/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java b/repository/src/main/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java index c7e9f27cef..22820764fb 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.repo.invitation; import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_PROP_INVITEE_COMMENTS; @@ -31,6 +31,7 @@ import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_P import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_PROP_MODIFIED_AT; import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_NAME; import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_TYPE; +import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.WF_PROP_CLIENT_NAME; import java.io.Serializable; import java.util.Date; @@ -77,6 +78,7 @@ import org.alfresco.service.namespace.QName; parentProps.put(RESOURCE_TYPE_KEY,(String)props.get(WF_PROP_RESOURCE_TYPE)); parentProps.put(CREATED_AT,(Date)props.get(ContentModel.PROP_CREATED)); parentProps.put(MODIFIED_AT,(Date)props.get(WF_PROP_MODIFIED_AT)); + parentProps.put(CLIENT_NAME,(Date)props.get(WF_PROP_CLIENT_NAME)); return parentProps; } diff --git a/repository/src/main/java/org/alfresco/repo/invitation/WorkflowModelModeratedInvitation.java b/repository/src/main/java/org/alfresco/repo/invitation/WorkflowModelModeratedInvitation.java index 0e63cd06b6..b04bcdd5a8 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/WorkflowModelModeratedInvitation.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/WorkflowModelModeratedInvitation.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.repo.invitation; import org.alfresco.service.namespace.NamespaceService; @@ -66,6 +66,11 @@ public interface WorkflowModelModeratedInvitation public static final QName WF_PROP_REVIEWER= QName.createQName(NAMESPACE_URI, "reviewer"); public static final QName WF_PROP_MODIFIED_AT= QName.createQName(NAMESPACE_URI, "modifiedAt"); + public static final QName WF_PROP_CLIENT_NAME= QName.createQName(NAMESPACE_URI, "clientName"); + public static final QName WF_WORKSPACE_URL = QName.createQName(NAMESPACE_URI, "workspaceUrl"); + public static final QName WF_SHARED_LINK_BASE_URL = QName.createQName(NAMESPACE_URI, "sharedLinkBaseUrl"); + public static final QName WF_TEMPLATE_ASSETS_URL = QName.createQName(NAMESPACE_URI, "templateAssetsUrl"); + // workflow execution context variable names public static final String wfVarInviteeUserName = "imwf_inviteeUserName"; public static final String wfVarInviteeRole = "imwf_inviteeRole"; @@ -73,6 +78,10 @@ public interface WorkflowModelModeratedInvitation public static final String wfVarResourceName = "imwf_resourceName"; public static final String wfVarResourceType = "imwf_resourceType"; public static final String wfVarReviewer = "imwf_reviewer"; - public static final String wfVarReviewComments = "imwf_reviewComments"; + public static final String wfVarReviewComments = "imwf_reviewComments"; public static final String bpmGroupAssignee = "bpm_groupAssignee"; + + public static final String wfVarClientName = "imwf_clientName"; + public static final String wfVarWorkspaceUrl = "imwf_workspaceUrl"; + public static final String wfVarTemplateAssetsUrl = "imwf_templateAssetsUrl"; } diff --git a/repository/src/main/java/org/alfresco/repo/invitation/activiti/SendModeratedInviteDelegate.java b/repository/src/main/java/org/alfresco/repo/invitation/activiti/SendModeratedInviteDelegate.java index 6cc9511a80..0eb78612be 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/activiti/SendModeratedInviteDelegate.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/activiti/SendModeratedInviteDelegate.java @@ -23,38 +23,65 @@ * along with Alfresco. If not, see . * #L% */ -package org.alfresco.repo.invitation.activiti; - -import java.util.Map; - -import org.activiti.engine.delegate.DelegateExecution; -import org.alfresco.repo.workflow.activiti.ActivitiConstants; - -/** - * Activiti delegate that is executed when a invitation request has been sent. - * - * @author Constantin Popa - */ -public class SendModeratedInviteDelegate extends AbstractInvitationDelegate +package org.alfresco.repo.invitation.activiti; + +import java.util.Map; + +import org.activiti.engine.delegate.DelegateExecution; +import org.alfresco.repo.client.config.ClientAppConfig; +import org.alfresco.repo.invitation.WorkflowModelModeratedInvitation; +import org.alfresco.repo.workflow.activiti.ActivitiConstants; +import org.alfresco.util.EmailHelper; + +/** + * Activiti delegate that is executed when a invitation request has been sent. + * + * @author Constantin Popa + */ +public class SendModeratedInviteDelegate extends AbstractInvitationDelegate { private String emailTemplatePath; - public static final String ENTERPRISE_EMAIL_TEMPLATE_PATH = "app:company_home/app:dictionary/app:email_templates/cm:invite/cm:invite-email-moderated.html.ftl"; - - public static final String EMAIL_SUBJECT_KEY = - "invitation.moderated.email.subject"; - - + private ClientAppConfig clientAppConfig; + private EmailHelper emailHelper; + public static final String ENTERPRISE_EMAIL_TEMPLATE_PATH = "app:company_home/app:dictionary/app:email_templates/cm:invite/cm:invite-email-moderated.html.ftl"; + + public static final String EMAIL_SUBJECT_KEY = "invitation.moderated.email.subject"; + private static final String EMAIL_TEMPLATE_REF ="alfresco/templates/workspace/invite-email-moderated.html.ftl"; + + public void setEmailTemplatePath(String emailTemplatePath) { this.emailTemplatePath = emailTemplatePath; } - @Override - public void execute(DelegateExecution execution) throws Exception - { - String invitationId = ActivitiConstants.ENGINE_ID + "$" + execution.getProcessInstanceId(); - Map variables = execution.getVariables(); - invitationService.sendModeratedInvitation(invitationId, emailTemplatePath, EMAIL_SUBJECT_KEY, variables); - } -} + public void setClientAppConfig(ClientAppConfig clientAppConfig) + { + this.clientAppConfig = clientAppConfig; + } + + public void setEmailHelper(EmailHelper emailHelper) + { + this.emailHelper = emailHelper; + } + + @Override + public void execute(DelegateExecution execution) throws Exception + { + String invitationId = ActivitiConstants.ENGINE_ID + "$" + execution.getProcessInstanceId(); + Map variables = execution.getVariables(); + String clientName = (String) variables.get(WorkflowModelModeratedInvitation.wfVarClientName); + + ClientAppConfig.ClientApp clientApp = clientAppConfig.getClient(clientName); + if(clientApp != null) + { + final String path = clientApp.getProperty("inviteModeratedTemplatePath"); + final String templatePath = emailHelper.getEmailTemplate(clientApp.getName(), path, EMAIL_TEMPLATE_REF); + invitationService.sendModeratedInvitation(invitationId, templatePath, EMAIL_SUBJECT_KEY, variables); + } + else + { + invitationService.sendModeratedInvitation(invitationId, emailTemplatePath, EMAIL_SUBJECT_KEY, variables); + } + } +} diff --git a/repository/src/main/java/org/alfresco/repo/invitation/site/InviteModeratedSender.java b/repository/src/main/java/org/alfresco/repo/invitation/site/InviteModeratedSender.java index 6a1f20cbe2..3e29916bd4 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/site/InviteModeratedSender.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/site/InviteModeratedSender.java @@ -23,9 +23,9 @@ * along with Alfresco. If not, see . * #L% */ - -package org.alfresco.repo.invitation.site; - + +package org.alfresco.repo.invitation.site; + import static org.alfresco.repo.invitation.WorkflowModelModeratedInvitation.bpmGroupAssignee; import java.io.Serializable; @@ -47,28 +47,30 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.service.cmr.security.PersonService.PersonInfo; import org.alfresco.util.ModelUtil; +import org.alfresco.util.UrlUtil; import org.apache.commons.lang3.StringUtils; - -/** - * This class is responsible for sending email notifications to site managers informing about users requesting access. - * - * @author Constantin Popa - */ -public class InviteModeratedSender extends InviteSender -{ + +/** + * This class is responsible for sending email notifications to site managers informing about users requesting access. + * + * @author Constantin Popa + */ +public class InviteModeratedSender extends InviteSender +{ private static final String DATA_DICTIONARY_XPATH_PREFIX = "app:"; public static final String WF_PACKAGE = "wf_package"; - public static final String SHARE_PENDING_INVITES_LINK = "{0}/page/site/{1}/pending-invites"; - + public static final String SHARE_PENDING_INVITES_LINK = "{0}/page/site/{1}/pending-invites"; + public static final String WORKSPACE_PENDING_INVITES_LINK = "{0}/#/{1}/members/libraries"; + private static final List INVITE_MODERATED_EXPECTED_PROPERTIES = Arrays.asList( WorkflowModelModeratedInvitation.wfVarInviteeUserName, WorkflowModelModeratedInvitation.wfVarInviteeRole, WorkflowModelModeratedInvitation.wfVarResourceName, WorkflowModelModeratedInvitation.bpmGroupAssignee, - WorkflowModelModeratedInvitation.wfVarResourceType); - - + WorkflowModelModeratedInvitation.wfVarResourceType); + + public InviteModeratedSender(ServiceRegistry services, Repository repository, MessageService messageService) { super(services, repository, messageService); @@ -107,6 +109,8 @@ public class InviteModeratedSender extends InviteSender model.put("inviteeName", StringUtils.join(new String[] { inviteePerson.getFirstName(), inviteePerson.getLastName() }, " ")); model.put("siteName", getSiteName(properties)); model.put("sharePendingInvitesLink", StringUtils.stripStart(getPendingInvitesLink(properties), "/")); + model.put("workspacePendingInvitesLink", StringUtils.stripStart(getWorkSpaceInvitesLink(properties), "/")); + model.put("template_assets_url", getTemplateAssetsLink(properties)); return model; } @@ -116,6 +120,24 @@ public class InviteModeratedSender extends InviteSender properties.get(WorkflowModelModeratedInvitation.wfVarResourceName)); } + protected String getWorkSpaceInvitesLink(Map properties) + { + String path = properties.get(WorkflowModelModeratedInvitation.wfVarWorkspaceUrl); + boolean hasValidBaseUrl = path != null && !StringUtils.isAllBlank(path) && path.length() > 1; + String workspaceUrl = sysAdminParams.getAlfrescoProtocol() + "://" + sysAdminParams.getAlfrescoHost() + ":" + sysAdminParams.getAlfrescoPort() + + ( hasValidBaseUrl ? "/" + path.trim() : ""); + + return MessageFormat.format(WORKSPACE_PENDING_INVITES_LINK, workspaceUrl, properties.get(WorkflowModelModeratedInvitation.wfVarResourceName)); + } + + protected String getTemplateAssetsLink(Map properties) + { + if (properties.get(WorkflowModelModeratedInvitation.wfVarTemplateAssetsUrl) != null) { + return UrlUtil.replaceAlfrescoUrlPlaceholder(properties.get(WorkflowModelModeratedInvitation.wfVarTemplateAssetsUrl), this.sysAdminParams); + } + return UrlUtil.getAlfrescoUrl(this.sysAdminParams); + } + @Override public List getRequiredProperties() { @@ -126,5 +148,5 @@ public class InviteModeratedSender extends InviteSender protected String getWorkflowPropForSiteName() { return WorkflowModelModeratedInvitation.wfVarResourceName; - } -} + } +} diff --git a/repository/src/main/java/org/alfresco/repo/invitation/site/InviteSender.java b/repository/src/main/java/org/alfresco/repo/invitation/site/InviteSender.java index 1caa5193a7..7d82fab60a 100644 --- a/repository/src/main/java/org/alfresco/repo/invitation/site/InviteSender.java +++ b/repository/src/main/java/org/alfresco/repo/invitation/site/InviteSender.java @@ -1,53 +1,54 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.repo.invitation.site; -import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarResourceName; - -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.repo.i18n.MessageService; -import org.alfresco.repo.model.Repository; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.admin.RepoAdminService; -import org.alfresco.service.cmr.invitation.InvitationException; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.cmr.site.SiteInfo; -import org.alfresco.service.cmr.site.SiteService; -import org.alfresco.service.namespace.NamespaceService; +import static org.alfresco.repo.invitation.WorkflowModelNominatedInvitation.wfVarResourceName; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.alfresco.repo.admin.SysAdminParams; +import org.alfresco.repo.i18n.MessageService; +import org.alfresco.repo.model.Repository; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.admin.RepoAdminService; +import org.alfresco.service.cmr.invitation.InvitationException; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.namespace.NamespaceService; /** * Notifies the necessary user(s) of a pending site membership invitation/request. @@ -66,6 +67,7 @@ public abstract class InviteSender protected final FileFolderService fileFolderService; protected final RepoAdminService repoAdminService; protected final NamespaceService namespaceService; + protected final SysAdminParams sysAdminParams; public InviteSender(ServiceRegistry services, Repository repository, MessageService messageService) { @@ -79,6 +81,7 @@ public abstract class InviteSender this.namespaceService = services.getNamespaceService(); this.repository = repository; this.messageService = messageService; + this.sysAdminParams = services.getSysAdminParams(); } /** @@ -88,10 +91,10 @@ public abstract class InviteSender * @param emailSubjectKey the subject of the email * @param properties A Map containing the properties needed to send the email. */ - public abstract void sendMail(String emailTemplateXpath, String emailSubjectKey, Map properties); - - protected abstract Map buildMailTextModel(Map properties); - + public abstract void sendMail(String emailTemplateXpath, String emailSubjectKey, Map properties); + + protected abstract Map buildMailTextModel(Map properties); + protected abstract List getRequiredProperties(); /** @@ -141,8 +144,8 @@ public abstract class InviteSender siteName = siteTitle; } return siteName; - } - - protected abstract String getWorkflowPropForSiteName(); + } + + protected abstract String getWorkflowPropForSiteName(); } diff --git a/repository/src/main/java/org/alfresco/service/cmr/invitation/InvitationService.java b/repository/src/main/java/org/alfresco/service/cmr/invitation/InvitationService.java index 29947ef1f5..6865d469e7 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/invitation/InvitationService.java +++ b/repository/src/main/java/org/alfresco/service/cmr/invitation/InvitationService.java @@ -1,33 +1,33 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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 . - * #L% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 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 . + * #L% + */ package org.alfresco.service.cmr.invitation; import java.util.List; import java.util.Map; - + import org.alfresco.service.Auditable; import org.alfresco.service.NotAuditable; @@ -138,6 +138,19 @@ public interface InvitationService @Auditable(parameters = { "inviteeComments", "inviteeUserName", "resourceType", "resourceName", "inviteeRole" }) public ModeratedInvitation inviteModerated(String inviteeComments, String inviteeUserName, Invitation.ResourceType resourceType, String resourceName, String inviteeRole); + /** + * Start the invitation process for a ModeratedInvitation + * + * @param inviteeUserName who is to be invited + * @param Invitation.ResourceType resourceType what resource type ? + * @param resourceName which resource + * @param inviteeRole which role ? + * @param clientName which client + * @param workspacePath path of the digital workspace + */ + @Auditable(parameters = { "inviteeComments", "inviteeUserName", "resourceType", "resourceName", "inviteeRole", "clientName", "workspacePath" }) + public ModeratedInvitation inviteModerated(String inviteeComments, String inviteeUserName, Invitation.ResourceType resourceType, String resourceName, String inviteeRole, String clientName, String workspacePath); + /** * Update the invitee comments for an existing moderated invitation * @@ -324,17 +337,17 @@ public interface InvitationService * @return true if emails are sent on invite. */ @NotAuditable - boolean isSendEmails(); - - /** - * - * Sends the site join request notification email using the given template, subject localization key, and variables. - * - * @param invitationId - * @param emailTemplateXpath - * @param emailSubjectKey - * @param variables - */ - @Auditable(parameters = { "inviteId" }) + boolean isSendEmails(); + + /** + * + * Sends the site join request notification email using the given template, subject localization key, and variables. + * + * @param invitationId + * @param emailTemplateXpath + * @param emailSubjectKey + * @param variables + */ + @Auditable(parameters = { "inviteId" }) public void sendModeratedInvitation(String invitationId, String emailTemplateXpath, String emailSubjectKey, Map variables); } diff --git a/repository/src/main/java/org/alfresco/util/UrlUtil.java b/repository/src/main/java/org/alfresco/util/UrlUtil.java index 59c9ff0237..f040c31858 100644 --- a/repository/src/main/java/org/alfresco/util/UrlUtil.java +++ b/repository/src/main/java/org/alfresco/util/UrlUtil.java @@ -39,7 +39,8 @@ public class UrlUtil { // ${shareUrl} placeholder public static final Pattern PATTERN = Pattern.compile("\\$\\{shareUrl\\}"); - + // ${alfrescoUrl} placeholder + public static final Pattern REPO_PATTERN = Pattern.compile("\\$\\{alfrescoUrl\\}"); /** * Builds up the Url to Alfresco based on the settings in the * {@link SysAdminParams}. @@ -113,6 +114,15 @@ public class UrlUtil return value; } + public static String replaceAlfrescoUrlPlaceholder(String value, SysAdminParams sysAdminParams) + { + if (value != null) + { + return REPO_PATTERN.matcher(value).replaceAll(getAlfrescoUrl(sysAdminParams)); + } + return value; + } + protected static String buildUrl(String protocol, String host, int port, String context) { StringBuilder url = new StringBuilder(); diff --git a/repository/src/main/resources/alfresco/invitation-service-context.xml b/repository/src/main/resources/alfresco/invitation-service-context.xml index 5609f946b7..3f889afe67 100644 --- a/repository/src/main/resources/alfresco/invitation-service-context.xml +++ b/repository/src/main/resources/alfresco/invitation-service-context.xml @@ -119,5 +119,7 @@ + + diff --git a/repository/src/main/resources/alfresco/messages/templates-messages.properties b/repository/src/main/resources/alfresco/messages/templates-messages.properties index 3c569ce147..5df386bbad 100644 --- a/repository/src/main/resources/alfresco/messages/templates-messages.properties +++ b/repository/src/main/resources/alfresco/messages/templates-messages.properties @@ -97,3 +97,7 @@ templates.generic-email.ftl.salutation=Hi {0}, templates.generic-email.ftl.copy_right=All Rights Reserved. templates.generic-email.ftl.contact_us=Contact Us +#workspace invite-email-moderated.ftl +templates.workspace.invite-email-moderated.html.call-to-action=Join Request +templates.workspace.invite-email-moderated.html.body=has requested to join +templates.workspace.invite-email-moderated.html.action=Review request \ No newline at end of file diff --git a/repository/src/main/resources/alfresco/templates/workspace/invite-email-moderated.html.ftl b/repository/src/main/resources/alfresco/templates/workspace/invite-email-moderated.html.ftl new file mode 100644 index 0000000000..78fcc45c85 --- /dev/null +++ b/repository/src/main/resources/alfresco/templates/workspace/invite-email-moderated.html.ftl @@ -0,0 +1,121 @@ + + + + + + + +

+
+ + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
+ Alfresco +
+ + + + + + +
+

+ Join Request +

+
+
+ + + + + + +
+

+ ${inviteeName} +

+ +

+ ${message("templates.workspace.invite-email-moderated.html.body")} +

+ +

+ ${siteName} +

+ +

+ + + + + + +
+ + ${message("templates.workspace.invite-email-moderated.html.action")} + +
+

+
+
+

+ © 2020 Alfresco Software, Inc. All rights reserved. +

+
+
+
+
+
+ + \ No newline at end of file diff --git a/repository/src/main/resources/alfresco/workflow/invitation-moderated-workflow-model.xml b/repository/src/main/resources/alfresco/workflow/invitation-moderated-workflow-model.xml index 3635efffa9..587340ffa8 100644 --- a/repository/src/main/resources/alfresco/workflow/invitation-moderated-workflow-model.xml +++ b/repository/src/main/resources/alfresco/workflow/invitation-moderated-workflow-model.xml @@ -82,6 +82,9 @@ d:date + + d:text +