diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index 72813d2765..04195b7564 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -379,6 +379,7 @@ false + jbpm alfresco/workflow/invitation-nominated_processdefinition.xml @@ -386,6 +387,7 @@ false + jbpm alfresco/workflow/invitation-moderated_processdefinition.xml @@ -393,7 +395,6 @@ false - diff --git a/config/alfresco/messages/invitation-service.properties b/config/alfresco/messages/invitation-service.properties index 3c2dd84a7f..c4aa994c65 100644 --- a/config/alfresco/messages/invitation-service.properties +++ b/config/alfresco/messages/invitation-service.properties @@ -1,7 +1,9 @@ +# # Invitation service +# -invitation.error.not_found "Invitation not found invitationId: {0}" - +invitation.error.noworkflow "Invitation workflow not found, workflow name : {0}" +invitation.error.not_found "Invitation not found, invitationId: {0}" +invitation.error.invalid_inviteId_format "Invitation Id not valid format, valid formats are $ : {0}" invitation.cancel.not_site_manager "Current user, {0}, cannot cancel invitation: {1} because they are not a Site Manager for site: {2} - invitation.invite.unable_generate_id "Unable to generate a user name for invitee, which doesn't already belong to someone else firstName:{0} lastName:{1} email:{2}" \ No newline at end of file diff --git a/config/alfresco/workflow/invitation-moderated-workflow-messages.properties b/config/alfresco/workflow/invitation-moderated-workflow-messages.properties index 6e99ac6494..3291337cdd 100644 --- a/config/alfresco/workflow/invitation-moderated-workflow-messages.properties +++ b/config/alfresco/workflow/invitation-moderated-workflow-messages.properties @@ -4,9 +4,23 @@ # Moderated Invitation # -wf_invitation-moderated.workflow.title=Invitation (Moderated) +wf_invitation-moderated.workflow.title=Invitation - Moderated wf_invitation-moderated.workflow.description=Moderated invitation to a resource such as a web site. +wf_invitation-moderated-workflow-model.type.wf_moderatedInvitationSubmitTask.title=Start Invitation +wf_invitation-moderated-workflow-model.type.wf_moderatedInvitationSubmitTask=Start a moderated invitation + wf_invitation-moderated-model.type.approveInvitationTask.title=Approve Invitation wf_invitation-moderated-model.type.approveInvitationTask.description=Approve Invitation +wf_invitation-moderated.node.start.title=Start +wf_invitation-moderated.node.start.description=Start moderated invitation +wf_invitation-moderated.node.review.title=Review Invitation +wf_invitation-moderated.node.review.description=Review moderated invitation +wf_invitation-moderated.node.review.transition.reject.title=Reject +wf_invitation-moderated.node.review.transition.reject.description=Reject +wf_invitation-moderated.node.review.transition.approve.title=Approve +wf_invitation-moderated.node.review.transition.approve.description=Approve +wf_invitation-moderated.node.review.transition.cancel.title=Cancel +wf_invitation-moderated.node.review.transition.cancel.description=Cancel + diff --git a/config/alfresco/workflow/invitation-nominated-workflow-messages.properties b/config/alfresco/workflow/invitation-nominated-workflow-messages.properties index ff7d322552..b637081737 100644 --- a/config/alfresco/workflow/invitation-nominated-workflow-messages.properties +++ b/config/alfresco/workflow/invitation-nominated-workflow-messages.properties @@ -1,40 +1,41 @@ # Display labels for out-of-the-box Site-oriented Workflows # -# Invite Workflow +# Invitation Nominated Workflow # -wf_invite.workflow.title=Invitation (Nominated) -wf_invite.workflow.description=Invitation to a Share Site, nominated by a site manager +wf_invitation-nominated.workflow.title=Invitation - Nominated +wf_invitation-nominated.workflow.description=Invitation to a Share Site, nominated by a site manager # Invite Task Definitions -wf_invite-workflow-model.type.wf_inviteToSiteTask.title=Start Invite -wf_invite-workflow-model.type.wf_inviteToSiteTask.description=Start an invite to a Site -wf_invite-workflow-model.type.wf_invitePendingTask.title=Site Invite -wf_invite-workflow-model.type.wf_invitePendingTask.description=Invite to a Site -wf_invite-workflow-model.type.wf_rejectInviteTask.title=Rejected -wf_invite-workflow-model.type.wf_rejectInviteTask.description=Rejected -wf_invite-workflow-model.type.wf_acceptInviteTask.title=Accepted -wf_invite-workflow-model.type.wf_acceptInviteTask.description=Accepted +wf_invitation-nominated-workflow-model.type.wf_inviteToSiteTask.title=Start task +wf_invitation-nominated-workflow-model.type.wf_inviteToSiteTask.description=Start a nominated invitation +wf_invitation-nominated-workflow-model.type.wf_invitePendingTask.title=Pending invitation +wf_invitation-nominated-workflow-model.type.wf_invitePendingTask.description=Pending invitation +wf_invitation-nominated-workflow-model.type.wf_rejectInviteTask.title=Rejected +wf_invitation-nominated-workflow-model.type.wf_rejectInviteTask.description=Rejected +wf_invitation-nominated-workflow-model.type.wf_acceptInviteTask.title=Accepted +wf_invitation-nominated-workflow-model.type.wf_acceptInviteTask.description=Accepted # Invite Process Definitions - -wf_invite.node.start.title=Start -wf_invite.node.start.description=Start -wf_invite.node.invitePending.title=Invite Pending -wf_invite.node.invitePending.description=Invite Pending -wf_invite.node.invitePending.transition.reject.title=Reject -wf_invite.node.invitePending.transition.reject.description=Reject -wf_invite.node.invitePending.transition.accept.title=Accept -wf_invite.node.invitePending.transition.accept.description=Accept -wf_invite.node.inviteRejected.title=Rejected -wf_invite.node.inviteRejected.description=Rejected -wf_invite.task.wf_rejectInviteTask.title=Rejected -wf_invite.task.wf_rejectInviteTask.description=Rejected -wf_invite.node.inviteAccepted.title=Accepted -wf_invite.node.inviteAccepted.description=Accepted -wf_invite.task.wf_acceptInviteTask.title=Accepted -wf_invite.task.wf_acceptInviteTask.description=Accepted -wf_invite.node.end.title=End -wf_invite.node.end.description=End +wf_invitation-nominated.node.start.title=Start +wf_invitation-nominated.node.start.description=Start +wf_invitation-nominated.node.invitePending.title=Invite Pending +wf_invitation-nominated.node.invitePending.description=Invite Pending +wf_invitation-nominated.node.invitePending.transition.reject.title=Reject +wf_invitation-nominated.node.invitePending.transition.reject.description=Reject +wf_invitation-nominated.node.invitePending.transition.accept.title=Accept +wf_invitation-nominated.node.invitePending.transition.accept.description=Accept +wf_invitation-nominated.node.invitePending.transition.cancel.title=Cancel +wf_invitation-nominated.node.invitePending.transition.cancel.description=Cancel +wf_invitation-nominated.node.inviteRejected.title=Rejected +wf_invitation-nominated.node.inviteRejected.description=Rejected +wf_invitation-nominated.task.wf_rejectInviteTask.title=Rejected +wf_invitation-nominated.task.wf_rejectInviteTask.description=Rejected +wf_invitation-nominated.node.inviteAccepted.title=Accepted +wf_invitation-nominated.node.inviteAccepted.description=Accepted +wf_invitation-nominated.task.wf_acceptInviteTask.title=Accepted +wf_invitation-nominated.task.wf_acceptInviteTask.description=Accepted +wf_invitation-nominated.node.end.title=End +wf_invitation-nominated.node.end.description=End diff --git a/config/alfresco/workflow/invitation-nominated-workflow-model.xml b/config/alfresco/workflow/invitation-nominated-workflow-model.xml index 538924c699..b682747e95 100644 --- a/config/alfresco/workflow/invitation-nominated-workflow-model.xml +++ b/config/alfresco/workflow/invitation-nominated-workflow-model.xml @@ -34,6 +34,9 @@ d:text + + d:text + d:text @@ -49,7 +52,7 @@ d:text - + d:text diff --git a/config/alfresco/workflow/invitation-nominated_processdefinition.xml b/config/alfresco/workflow/invitation-nominated_processdefinition.xml index 83541462a5..c76f143f4b 100644 --- a/config/alfresco/workflow/invitation-nominated_processdefinition.xml +++ b/config/alfresco/workflow/invitation-nominated_processdefinition.xml @@ -2,7 +2,8 @@ - + @@ -40,7 +41,7 @@ args["inviteePersonRef"] = inviteePerson.nodeRef.toString(); args["inviterPersonRef"] = inviterPerson.nodeRef.toString(); args["siteName"] = siteName; - args["inviteeSiteRole"] = wf_inviteeSiteRole; + args["inviteeSiteRole"] = wf_inviteeRole; args["inviteeUserName"] = wf_inviteeUserName; args["inviteeGenPassword"] = wf_inviteeGenPassword; args["acceptLink"] = acceptLink; diff --git a/source/java/org/alfresco/repo/invitation/InvitationImpl.java b/source/java/org/alfresco/repo/invitation/InvitationImpl.java index bc151d4d66..c4e8e26d12 100644 --- a/source/java/org/alfresco/repo/invitation/InvitationImpl.java +++ b/source/java/org/alfresco/repo/invitation/InvitationImpl.java @@ -5,10 +5,8 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; /* package scope */ abstract class InvitationImpl { - /** - * Who is this invitation for - */ - private String inviteeUserName; + + /** * Unique reference for this invitation @@ -48,14 +46,6 @@ import org.alfresco.service.cmr.invitation.Invitation.ResourceType; this.resourceType = resourceType; } - public void setInviteeUserName(String inviteeUserName) { - this.inviteeUserName = inviteeUserName; - } - - public String getInviteeUserName() { - return inviteeUserName; - } - public void setInviteId(String inviteId) { this.inviteId = inviteId; } diff --git a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java index 703f5abd6c..95a3007bbc 100644 --- a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java +++ b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java @@ -26,6 +26,7 @@ package org.alfresco.repo.invitation; import java.io.Serializable; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -48,6 +49,7 @@ import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.alfresco.service.cmr.workflow.WorkflowException; import org.alfresco.service.cmr.workflow.WorkflowInstance; import org.alfresco.service.cmr.workflow.WorkflowPath; import org.alfresco.service.cmr.workflow.WorkflowService; @@ -85,7 +87,65 @@ public class InvitationServiceImpl implements InvitationService // maximum number of tries to generate a invitee user name which // does not already belong to an existing person public static final int MAX_NUM_INVITEE_USER_NAME_GEN_TRIES = 10; + + /** + * Get the names of the workflows which are managed by the invitation service + * @return + */ + public List getInvitationServiceWorkflowNames() + { + List ret = new ArrayList(2); + ret.add(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME); + ret.add(WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME); + return ret; + } + /** + * Start the invitation process for a NominatedInvitation + * + * @param inviteeUserName Alfresco user name of the invitee + * @param Invitation + * @param ResourceType resourceType + * @param resourceName + * @param inviteeRole + * @param serverPath + * @param acceptUrl + * @param rejectUrl + * + * @return the nominated invitation which will contain the invitationId and + * ticket which will uniqely identify this invitation for the rest + * of the workflow. + * + * @throws InvitationException + * @throws InvitationExceptionUserError + * @throws InvitationExceptionForbidden + */ + public NominatedInvitation inviteNominated(String inviteeUserName, + Invitation.ResourceType resourceType, + String resourceName, + String inviteeRole, + String serverPath, + String acceptUrl, + String rejectUrl) + { + // inviteeUserName was specified + NodeRef person = this.personService.getPerson(inviteeUserName); + + Serializable firstNameVal = this.getNodeService().getProperty(person, ContentModel.PROP_FIRSTNAME); + Serializable lastNameVal = this.getNodeService().getProperty(person, ContentModel.PROP_LASTNAME); + Serializable emailVal = this.getNodeService().getProperty(person, ContentModel.PROP_EMAIL); + String firstName = DefaultTypeConverter.INSTANCE.convert( + String.class, firstNameVal); + String lastName = DefaultTypeConverter.INSTANCE.convert( + String.class, lastNameVal); + String email = DefaultTypeConverter.INSTANCE.convert( + String.class, emailVal); + + return inviteNominated(firstName, lastName, email, + inviteeUserName, resourceType, resourceName, inviteeRole, + serverPath, acceptUrl, rejectUrl); + } + /** * Start the invitation process for a NominatedInvitation * @@ -111,11 +171,40 @@ public class InvitationServiceImpl implements InvitationService * @throws InvitationExceptionUserError * @throws InvitationExceptionForbidden */ - public NominatedInvitation inviteNominated(String inviteeFirstName, - String inviteeLastName, String inviteeEmail, - String inviteeUserName, Invitation.ResourceType resourceType, - String resourceName, String inviteeRole, String serverPath, - String acceptUrl, String rejectUrl) + public NominatedInvitation inviteNominated( + String inviteeFirstName, + String inviteeLastName, + String inviteeEmail, + Invitation.ResourceType resourceType, + String resourceName, + String inviteeRole, + String serverPath, + String acceptUrl, + String rejectUrl) + { + return inviteNominated(inviteeFirstName, + inviteeLastName, + inviteeEmail, + null, + resourceType, + resourceName, + inviteeRole, + serverPath, + acceptUrl, + rejectUrl); + } + + // Temporary method + private NominatedInvitation inviteNominated(String inviteeFirstName, + String inviteeLastName, + String inviteeEmail, + String inviteeUserName, + Invitation.ResourceType resourceType, + String resourceName, + String inviteeRole, + String serverPath, + String acceptUrl, + String rejectUrl) { // Validate the request @@ -123,7 +212,7 @@ public class InvitationServiceImpl implements InvitationService if (resourceType == Invitation.ResourceType.WEB_SITE) { - return startInvite(inviteeFirstName, inviteeLastName, inviteeEmail, + return startNominatedInvite(inviteeFirstName, inviteeLastName, inviteeEmail, inviteeUserName, resourceType, resourceName, inviteeRole, serverPath, acceptUrl, rejectUrl); } @@ -151,7 +240,7 @@ public class InvitationServiceImpl implements InvitationService { if (resourceType == Invitation.ResourceType.WEB_SITE) { - return startInvite(inviteeComments, inviteeUserName, resourceType, + return startModeratedInvite(inviteeComments, inviteeUserName, resourceType, resourceName, inviteeRole); } throw new InvitationException("unknown resource type"); @@ -335,10 +424,23 @@ public class InvitationServiceImpl implements InvitationService * * @throws InvitationExceptionNotFound * the invitation does not exist. + * @throws InvitationExceptionUserError * @return the invitation. */ public Invitation getInvitation(String invitationId) { - WorkflowInstance wi = workflowService.getWorkflowById(invitationId); + + validateInvitationId(invitationId); + + WorkflowInstance wi = null; + try + { + wi = workflowService.getWorkflowById(invitationId); + } + catch (WorkflowException we) + { + // Do nothing + } + if (wi == null) { Object objs[] = { invitationId }; throw new InvitationExceptionNotFound("invitation.error.not_found", @@ -363,11 +465,14 @@ public class InvitationServiceImpl implements InvitationService // should also be 0 or 1 if (inviteStartTasks.size() < 1) { - return null; + Object objs[] = { invitationId }; + throw new InvitationExceptionNotFound("invitation.error.not_found", + objs); } else { WorkflowTask task = inviteStartTasks.get(0); NominatedInvitationImpl result = new NominatedInvitationImpl( task.properties); + result.setSentInviteDate(task.path.instance.startDate); result.setInviteId(invitationId); return result; } @@ -836,7 +941,7 @@ public class InvitationServiceImpl implements InvitationService * @param inviteeRole * @return the new moderated invitation */ - private ModeratedInvitation startInvite(String inviteeComments, + private ModeratedInvitation startModeratedInvite(String inviteeComments, String inviteeUserName, Invitation.ResourceType resourceType, String resourceName, String inviteeRole) { @@ -878,10 +983,10 @@ public class InvitationServiceImpl implements InvitationService WorkflowModelModeratedInvitation.WF_PROP_INVITEE_USER_NAME, inviteeUserName); workflowProps.put( - WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME, + WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_NAME, resourceName); workflowProps.put( - WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TYPE, + WorkflowModelModeratedInvitation.WF_PROP_RESOURCE_TYPE, resourceType.toString()); // get the moderated workflow @@ -945,11 +1050,17 @@ public class InvitationServiceImpl implements InvitationService * externally accessible server address of server hosting invite * web scripts */ - private NominatedInvitation startInvite(String inviteeFirstName, - String inviteeLastName, String inviteeEmail, - String inviteeUserName, Invitation.ResourceType resourceType, - String siteShortName, String inviteeSiteRole, String serverPath, - String acceptUrl, String rejectUrl) { + private NominatedInvitation startNominatedInvite( + String inviteeFirstName, + String inviteeLastName, + String inviteeEmail, + String inviteeUserName, + Invitation.ResourceType resourceType, + String siteShortName, + String inviteeSiteRole, + String serverPath, + String acceptUrl, + String rejectUrl) { // get the inviter user name (the name of user web script is executed // under) @@ -1003,7 +1114,8 @@ public class InvitationServiceImpl implements InvitationService // else there are no existing people who have the given invitee // email address // so create invitee person - else { + else + { inviteeUserName = createInviteePerson(inviteeFirstName, inviteeLastName, inviteeEmail); @@ -1013,9 +1125,25 @@ public class InvitationServiceImpl implements InvitationService + inviteeUserName); } } + else + { + // inviteeUserName was specified + NodeRef person = this.personService.getPerson(inviteeUserName); + + Serializable firstNameVal = this.getNodeService().getProperty(person, ContentModel.PROP_FIRSTNAME); + Serializable lastNameVal = this.getNodeService().getProperty(person, ContentModel.PROP_LASTNAME); + Serializable emailVal = this.getNodeService().getProperty(person, ContentModel.PROP_EMAIL); + firstNameVal = DefaultTypeConverter.INSTANCE.convert( + String.class, firstNameVal); + lastNameVal = DefaultTypeConverter.INSTANCE.convert( + String.class, lastNameVal); + emailVal = DefaultTypeConverter.INSTANCE.convert( + String.class, emailVal); + } - // throw web script exception if person is already a member of the given - // site + /** + * throw exception if person is already a member of the given site + */ if (this.siteService.isMember(siteShortName, inviteeUserName)) { if (logger.isDebugEnabled()) logger @@ -1070,6 +1198,9 @@ public class InvitationServiceImpl implements InvitationService workflowProps.put( WorkflowModelNominatedInvitation.WF_PROP_INVITEE_USER_NAME, inviteeUserName); + workflowProps.put( + WorkflowModelNominatedInvitation.WF_PROP_INVITEE_EMAIL, + inviteeEmail); workflowProps.put(WorkflowModel.ASSOC_ASSIGNEE, inviteeNodeRef); workflowProps.put( WorkflowModelNominatedInvitation.WF_PROP_INVITEE_FIRSTNAME, @@ -1087,7 +1218,7 @@ public class InvitationServiceImpl implements InvitationService WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TYPE, resourceType.toString()); workflowProps.put( - WorkflowModelNominatedInvitation.WF_PROP_INVITEE_SITE_ROLE, + WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE, inviteeSiteRole); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_SERVER_PATH, serverPath); @@ -1173,6 +1304,7 @@ public class InvitationServiceImpl implements InvitationService workflowProps); result.setTicket(inviteTicket); result.setInviteId(workflowId); + result.setSentInviteDate(new Date()); return result; } @@ -1195,4 +1327,19 @@ public class InvitationServiceImpl implements InvitationService "invitation.invite.not_site_manager", objs); } } + + /** + * Validator for invitationId + * @param invitationId + */ + private void validateInvitationId(String invitationId) + { + final String ID_SEPERATOR_REGEX = "\\$"; + String[] parts = invitationId.split(ID_SEPERATOR_REGEX); + if (parts.length != 2) + { + Object objs[] = { invitationId }; + throw new InvitationExceptionUserError("invitation.error.invalid_inviteId_format", objs); + } + } } diff --git a/source/java/org/alfresco/repo/invitation/InvitationServiceImplTest.java b/source/java/org/alfresco/repo/invitation/InvitationServiceImplTest.java index 011ff80148..2b9f4237a1 100644 --- a/source/java/org/alfresco/repo/invitation/InvitationServiceImplTest.java +++ b/source/java/org/alfresco/repo/invitation/InvitationServiceImplTest.java @@ -24,13 +24,12 @@ */ package org.alfresco.repo.invitation; +import java.util.Date; import java.util.List; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.MutableAuthenticationDao; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.site.SiteModel; import org.alfresco.service.cmr.invitation.InvitationExceptionUserError; import org.alfresco.service.cmr.invitation.InvitationSearchCriteria; @@ -39,21 +38,13 @@ import org.alfresco.service.cmr.invitation.Invitation; import org.alfresco.service.cmr.invitation.ModeratedInvitation; import org.alfresco.service.cmr.invitation.NominatedInvitation; import org.alfresco.service.cmr.invitation.Invitation.ResourceType; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.ScriptService; -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.AuthorityType; 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.site.SiteVisibility; -import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.util.BaseAlfrescoSpringTest; import org.alfresco.util.PropertyMap; -import junit.framework.TestCase; - /** * * Unit tests of Invitation Service @@ -79,6 +70,10 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest public static String USER_ONE = "InvitationServiceAlice"; public static String USER_TWO = "InvitationServiceBob"; public static String USER_EVE = "InvitationServiceEve"; + public static String USER_ONE_FIRSTNAME = "One" ; + public static String USER_ONE_LASTNAME = "Test"; + public static String USER_ONE_EMAIL = USER_ONE + "@alfrescotesting.com"; + /** * Called during the transaction setup @@ -92,10 +87,10 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest this.authenticationComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent"); this.mutableAuthenticationDao = (MutableAuthenticationDao)this.applicationContext.getBean("authenticationDao"); - createPerson(USER_MANAGER, ""); - createPerson(USER_ONE, ""); - createPerson(USER_TWO, ""); - createPerson(USER_EVE, ""); + createPerson(USER_MANAGER, USER_MANAGER + "@alfrescotesting.com", PERSON_FIRSTNAME, PERSON_LASTNAME); + createPerson(USER_ONE, USER_ONE_EMAIL,USER_ONE_FIRSTNAME, USER_ONE_LASTNAME); + createPerson(USER_TWO, USER_TWO + "@alfrescotesting.com", PERSON_FIRSTNAME, PERSON_LASTNAME); + createPerson(USER_EVE, USER_EVE + "@alfrescotesting.com", PERSON_FIRSTNAME, PERSON_LASTNAME); this.authenticationComponent.setCurrentUser(USER_MANAGER); @@ -158,7 +153,120 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest } /** - * Create a Nominated Invitation + * Test nominated user - new user + * + * @throws Exception + */ + public void testNominatedInvitationNewUser() throws Exception + { + Date startDate = new java.util.Date(); + + String inviteeFirstName = PERSON_FIRSTNAME; + String inviteeLastName = PERSON_LASTNAME; + String inviteeEmail = "123"; + String inviteeUserName = null; + Invitation.ResourceType resourceType = Invitation.ResourceType.WEB_SITE; + String resourceName = SITE_SHORT_NAME_INVITE; + String inviteeRole = SiteModel.SITE_COLLABORATOR; + String serverPath = "wibble"; + String acceptUrl = "froob"; + String rejectUrl = "marshmallow"; + + this.authenticationComponent.setCurrentUser(USER_MANAGER); + + NominatedInvitation nominatedInvitation = invitationService.inviteNominated( + inviteeFirstName, + inviteeLastName, + inviteeEmail, + resourceType, + resourceName, + inviteeRole, + serverPath, + acceptUrl, + rejectUrl) ; + + assertNotNull("nominated invitation is null", nominatedInvitation); + String inviteId = nominatedInvitation.getInviteId(); + assertEquals("first name wrong", inviteeFirstName, nominatedInvitation.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, nominatedInvitation.getInviteeLastName()); + assertEquals("email name wrong", inviteeEmail, nominatedInvitation.getInviteeEmail()); + + // Generated User Name should be returned + inviteeUserName = nominatedInvitation.getInviteeUserName(); + assertNotNull("generated user name is null", inviteeUserName); + // sentInviteDate should be set to today + { + Date sentDate = nominatedInvitation.getSentInviteDate(); + assertTrue("sentDate wrong - too early", sentDate.after(startDate)); + assertTrue("sentDate wrong - too late", sentDate.before(new Date(new Date().getTime()+ 1))); + } + + assertEquals("resource type name wrong", resourceType, nominatedInvitation.getResourceType()); + assertEquals("resource name wrong", resourceName, nominatedInvitation.getResourceName()); + assertEquals("role name wrong", inviteeRole, nominatedInvitation.getRoleName()); + assertEquals("server path wrong", serverPath, nominatedInvitation.getServerPath()); + assertEquals("accept URL wrong", acceptUrl, nominatedInvitation.getAcceptUrl()); + assertEquals("reject URL wrong", rejectUrl, nominatedInvitation.getRejectUrl()); + + /** + * Now we have an invitation get it and check the details have been returned correctly. + */ + { + NominatedInvitation invitation = (NominatedInvitation)invitationService.getInvitation(inviteId); + + assertNotNull("invitation is null", invitation); + assertEquals("invite id wrong", inviteId, invitation.getInviteId()); + assertEquals("first name wrong", inviteeFirstName, invitation.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, invitation.getInviteeLastName()); + assertEquals("user name wrong", inviteeUserName, invitation.getInviteeUserName()); + assertEquals("resource type name wrong", resourceType, invitation.getResourceType()); + assertEquals("resource name wrong", resourceName, invitation.getResourceName()); + assertEquals("role name wrong", inviteeRole, invitation.getRoleName()); + assertEquals("server path wrong", serverPath, invitation.getServerPath()); + assertEquals("accept URL wrong", acceptUrl, invitation.getAcceptUrl()); + assertEquals("reject URL wrong", rejectUrl, invitation.getRejectUrl()); + + Date sentDate = invitation.getSentInviteDate(); + // sentInviteDate should be set to today + assertTrue("sentDate wrong too early", sentDate.after(startDate)); + assertTrue("sentDate wrong - too late", sentDate.before(new Date(new Date().getTime()+ 1))); + } + + /** + * Search for the new invitation + */ + List invitations = invitationService.listPendingInvitationsForResource(resourceType, resourceName); + assertTrue("invitations is empty", !invitations.isEmpty()); + + NominatedInvitation firstInvite = (NominatedInvitation)invitations.get(0); + assertEquals("invite id wrong", inviteId, firstInvite.getInviteId()); + assertEquals("first name wrong", inviteeFirstName, firstInvite.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, firstInvite.getInviteeLastName()); + assertEquals("user name wrong", inviteeUserName, firstInvite.getInviteeUserName()); + + /** + * Now accept the invitation + */ + NominatedInvitation acceptedInvitation = (NominatedInvitation)invitationService.accept(firstInvite.getInviteId(), firstInvite.getTicket()); + assertEquals("invite id wrong", firstInvite.getInviteId(), acceptedInvitation.getInviteId()); + assertEquals("first name wrong", inviteeFirstName, acceptedInvitation.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, acceptedInvitation.getInviteeLastName()); + assertEquals("user name wrong", inviteeUserName, acceptedInvitation.getInviteeUserName()); + + List it4 = invitationService.listPendingInvitationsForResource(resourceType, resourceName); + assertTrue("invitations is not empty", it4.isEmpty()); + + /** + * Now verify access control list + */ + String roleName = siteService.getMembersRole(resourceName, inviteeUserName); + assertEquals("role name wrong", roleName, inviteeRole); + siteService.removeMembership(resourceName, inviteeUserName); + } + + + /** + * Create a Nominated Invitation (for existing user, USER_ONE) * read it. * search for it * cancel it @@ -171,12 +279,13 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest * read it. * accept it */ - public void testNominatedInvitation() throws Exception + public void testNominatedInvitationExistingUser() throws Exception { - String inviteeFirstName = PERSON_FIRSTNAME; - String inviteeLastName = PERSON_LASTNAME; - String inviteeEmail = "123"; - String inviteeUserName = "invitee@alfrescotesting.com"; + String inviteeUserName = USER_ONE; + String inviteeEmail = USER_ONE_EMAIL; + String inviteeFirstName = USER_ONE_FIRSTNAME; + String inviteeLastName = USER_ONE_LASTNAME; + Invitation.ResourceType resourceType = Invitation.ResourceType.WEB_SITE; String resourceName = SITE_SHORT_NAME_INVITE; String inviteeRole = SiteModel.SITE_COLLABORATOR; @@ -186,9 +295,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest this.authenticationComponent.setCurrentUser(USER_MANAGER); - NominatedInvitation nominatedInvitation = invitationService.inviteNominated(inviteeFirstName, - inviteeLastName, - inviteeEmail, + NominatedInvitation nominatedInvitation = invitationService.inviteNominated( inviteeUserName, resourceType, resourceName, @@ -199,8 +306,6 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest assertNotNull("nominated invitation is null", nominatedInvitation); String inviteId = nominatedInvitation.getInviteId(); - assertEquals("first name wrong", inviteeFirstName, nominatedInvitation.getInviteeFirstName()); - assertEquals("last name wrong", inviteeLastName, nominatedInvitation.getInviteeLastName()); assertEquals("user name wrong", inviteeUserName, nominatedInvitation.getInviteeUserName()); assertEquals("resource type name wrong", resourceType, nominatedInvitation.getResourceType()); assertEquals("resource name wrong", resourceName, nominatedInvitation.getResourceName()); @@ -209,6 +314,11 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest assertEquals("accept URL wrong", acceptUrl, nominatedInvitation.getAcceptUrl()); assertEquals("reject URL wrong", rejectUrl, nominatedInvitation.getRejectUrl()); + // These values should be read from the person record + assertEquals("first name wrong", inviteeFirstName, nominatedInvitation.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, nominatedInvitation.getInviteeLastName()); + assertEquals("email name wrong", inviteeEmail, nominatedInvitation.getInviteeEmail()); + /** * Now we have an invitation get it and check the details have been returned correctly. */ @@ -216,9 +326,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest assertNotNull("invitation is null", invitation); assertEquals("invite id wrong", inviteId, invitation.getInviteId()); - assertEquals("first name wrong", inviteeFirstName, invitation.getInviteeFirstName()); - assertEquals("last name wrong", inviteeLastName, invitation.getInviteeLastName()); - assertEquals("user name wrong", inviteeUserName, invitation.getInviteeUserName()); + assertEquals("user name wrong", inviteeUserName, nominatedInvitation.getInviteeUserName()); assertEquals("resource type name wrong", resourceType, invitation.getResourceType()); assertEquals("resource name wrong", resourceName, invitation.getResourceName()); assertEquals("role name wrong", inviteeRole, invitation.getRoleName()); @@ -226,6 +334,11 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest assertEquals("accept URL wrong", acceptUrl, invitation.getAcceptUrl()); assertEquals("reject URL wrong", rejectUrl, invitation.getRejectUrl()); + // These values should have been read from the DB + assertEquals("first name wrong", inviteeFirstName, invitation.getInviteeFirstName()); + assertEquals("last name wrong", inviteeLastName, invitation.getInviteeLastName()); + assertEquals("email name wrong", inviteeEmail, invitation.getInviteeEmail()); + /** * Search for the new invitation */ @@ -256,9 +369,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest /** * Now invite and reject */ - NominatedInvitation secondInvite = invitationService.inviteNominated(inviteeFirstName, - inviteeLastName, - inviteeEmail, + NominatedInvitation secondInvite = invitationService.inviteNominated( inviteeUserName, resourceType, resourceName, @@ -269,8 +380,6 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest NominatedInvitation rejectedInvitation = (NominatedInvitation)invitationService.cancel(secondInvite.getInviteId()); assertEquals("invite id wrong", secondInvite.getInviteId(), rejectedInvitation.getInviteId()); - assertEquals("first name wrong", inviteeFirstName, rejectedInvitation.getInviteeFirstName()); - assertEquals("last name wrong", inviteeLastName, rejectedInvitation.getInviteeLastName()); assertEquals("user name wrong", inviteeUserName, rejectedInvitation.getInviteeUserName()); List it3 = invitationService.listPendingInvitationsForResource(resourceType, resourceName); @@ -279,9 +388,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest /** * Now invite and accept */ - NominatedInvitation thirdInvite = invitationService.inviteNominated(inviteeFirstName, - inviteeLastName, - inviteeEmail, + NominatedInvitation thirdInvite = invitationService.inviteNominated( inviteeUserName, resourceType, resourceName, @@ -517,7 +624,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest */ try { - invitationService.approve(invitationId, "No Way Hosea!"); + invitationService.reject(invitationId, "No Way Hosea!"); assertTrue("excetion not thrown", false); } @@ -532,7 +639,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest * Reject the invitation */ this.authenticationComponent.setCurrentUser(USER_MANAGER); - invitationService.approve(invitationId, "Go away!"); + invitationService.reject(invitationId, "Go away!"); /** * Negative test @@ -584,9 +691,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest inviteeRole); String oneId = invitationOne.getInviteId(); - NominatedInvitation invitationTwo = invitationService.inviteNominated(inviteeFirstName, - inviteeLastName, - inviteeEmail, + NominatedInvitation invitationTwo = invitationService.inviteNominated( USER_ONE, resourceType, SITE_SHORT_NAME_RED, @@ -596,9 +701,7 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest rejectUrl) ; String twoId = invitationTwo.getInviteId(); - NominatedInvitation invitationThree = invitationService.inviteNominated(inviteeFirstName, - inviteeLastName, - inviteeEmail, + NominatedInvitation invitationThree = invitationService.inviteNominated( USER_ONE, resourceType, SITE_SHORT_NAME_BLUE, @@ -683,11 +786,11 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest } catch (Exception e) { - + // should have gone here } } - private void createPerson(String userName, String emailAddress) + private void createPerson(String userName, String emailAddress, String firstName, String lastName) { // if user with given user name doesn't already exist then create user if (this.authenticationService.authenticationExists(userName) == false) @@ -704,8 +807,8 @@ public class InvitationServiceImplTest extends BaseAlfrescoSpringTest // create person properties PropertyMap personProps = new PropertyMap(); personProps.put(ContentModel.PROP_USERNAME, userName); - personProps.put(ContentModel.PROP_FIRSTNAME, PERSON_FIRSTNAME); - personProps.put(ContentModel.PROP_LASTNAME, PERSON_LASTNAME); + personProps.put(ContentModel.PROP_FIRSTNAME, firstName); + personProps.put(ContentModel.PROP_LASTNAME, lastName); personProps.put(ContentModel.PROP_EMAIL, emailAddress); personProps.put(ContentModel.PROP_JOBTITLE, PERSON_JOBTITLE); personProps.put(ContentModel.PROP_ORGANIZATION, PERSON_ORG); diff --git a/source/java/org/alfresco/repo/invitation/ModeratedActionApprove.java b/source/java/org/alfresco/repo/invitation/ModeratedActionApprove.java index 496d6c8581..6a5de1fbda 100644 --- a/source/java/org/alfresco/repo/invitation/ModeratedActionApprove.java +++ b/source/java/org/alfresco/repo/invitation/ModeratedActionApprove.java @@ -53,13 +53,6 @@ public class ModeratedActionApprove extends JBPMSpringActionHandler final String reviewer = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarReviewer); final String reviewComments = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarReviewComments); - System.out.println("resourceType=" + resourceType); - System.out.println("resourceName=" + resourceName); - System.out.println("role=" + inviteeRole); - System.out.println("inviteeUserName=" + inviteeUserName); - System.out.println("reviewer=" + reviewer); - System.out.println("reviewComments=" + reviewComments); - /** * Add invitee to the site */ @@ -67,7 +60,9 @@ public class ModeratedActionApprove extends JBPMSpringActionHandler { public Object doWork() throws Exception { - siteService.setMembership(resourceName, inviteeUserName, inviteeRole); + // Add the new user to the web site + siteService.setMembership(resourceName, inviteeUserName, inviteeRole); + return null; } diff --git a/source/java/org/alfresco/repo/invitation/ModeratedActionReject.java b/source/java/org/alfresco/repo/invitation/ModeratedActionReject.java index 5d7e64757f..aab9d333b4 100644 --- a/source/java/org/alfresco/repo/invitation/ModeratedActionReject.java +++ b/source/java/org/alfresco/repo/invitation/ModeratedActionReject.java @@ -1,7 +1,6 @@ package org.alfresco.repo.invitation; -import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation; import org.alfresco.repo.security.authentication.MutableAuthenticationDao; import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; import org.alfresco.service.ServiceRegistry; @@ -40,6 +39,13 @@ public class ModeratedActionReject extends JBPMSpringActionHandler @SuppressWarnings("unchecked") public void execute(final ExecutionContext executionContext) throws Exception { - System.out.println("Reject woz ere!"); + final String resourceType = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarResourceType); + final String resourceName = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarResourceName); + final String inviteeUserName = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarInviteeUserName); + final String inviteeRole = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarInviteeRole); + final String reviewer = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarReviewer); + final String reviewComments = (String)executionContext.getVariable(WorkflowModelModeratedInvitation.wfVarReviewComments); + + } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java b/source/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java index d3f3b556a4..843bb3a582 100644 --- a/source/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java +++ b/source/java/org/alfresco/repo/invitation/ModeratedInvitationImpl.java @@ -25,7 +25,6 @@ package org.alfresco.repo.invitation; import org.alfresco.service.cmr.invitation.ModeratedInvitation; -import org.alfresco.service.cmr.invitation.Invitation.ResourceType; import org.alfresco.service.namespace.QName; import java.io.Serializable; @@ -44,14 +43,15 @@ import java.util.Map; private String roleName; private String inviteeComments; + private String inviteeUserName; public ModeratedInvitationImpl() { super(); } - public ModeratedInvitationImpl(Map workflowProps) - { + public ModeratedInvitationImpl(Map workflowProps) + { super(); setInviteeUserName((String)workflowProps.get(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_USER_NAME)); @@ -62,8 +62,7 @@ import java.util.Map; } roleName = (String)workflowProps.get(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_ROLE); inviteeComments = (String)workflowProps.get(WorkflowModelModeratedInvitation.WF_PROP_INVITEE_COMMENTS); - - } + } public void setRoleName(String roleName) @@ -86,5 +85,16 @@ import java.util.Map; this.inviteeComments = inviteeComments; } + public InvitationType getInvitationType() { + return InvitationType.MODERATED; + } + public void setInviteeUserName(String inviteeUserName) { + this.inviteeUserName = inviteeUserName; + } + + public String getInviteeUserName() { + return inviteeUserName; + } + } diff --git a/source/java/org/alfresco/repo/invitation/NominatedInvitationImpl.java b/source/java/org/alfresco/repo/invitation/NominatedInvitationImpl.java index 7ed0d1e01b..34da607f78 100644 --- a/source/java/org/alfresco/repo/invitation/NominatedInvitationImpl.java +++ b/source/java/org/alfresco/repo/invitation/NominatedInvitationImpl.java @@ -27,6 +27,8 @@ package org.alfresco.repo.invitation; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.invitation.Invitation; import org.alfresco.service.cmr.invitation.NominatedInvitation; +import org.alfresco.service.cmr.invitation.Invitation.InvitationType; +import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.namespace.QName; import java.io.Serializable; @@ -54,6 +56,11 @@ import java.util.Map; private Date sentInviteDate; private String ticket; + /** + * Who is this invitation for + */ + private String inviteeUserName; + /** * create a new nominated invitation */ @@ -68,6 +75,7 @@ import java.util.Map; setInviteeUserName((String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_USER_NAME)); inviteeFirstName = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_FIRSTNAME); inviteeLastName = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_LASTNAME); + inviteeEmail = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_EMAIL); // inviteePassword = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_GEN_PASSWORD); setResourceName( (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME)); @@ -75,12 +83,13 @@ import java.util.Map; { setResourceType(ResourceType.valueOf((String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TYPE))); } - roleName = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_SITE_ROLE); + roleName = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE); serverPath = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_SERVER_PATH); acceptUrl = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_ACCEPT_URL); rejectUrl = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_REJECT_URL); ticket = (String)workflowProps.get(WorkflowModelNominatedInvitation.WF_PROP_INVITE_TICKET); - + + } public void setInviteeFirstName(String inviteeFirstName) { @@ -154,4 +163,17 @@ import java.util.Map; return roleName; } + public InvitationType getInvitationType() { + return InvitationType.NOMINATED; + + } + + public void setInviteeUserName(String inviteeUserName) { + this.inviteeUserName = inviteeUserName; + } + + public String getInviteeUserName() { + return inviteeUserName; + } + } diff --git a/source/java/org/alfresco/repo/invitation/WorkflowModelNominatedInvitation.java b/source/java/org/alfresco/repo/invitation/WorkflowModelNominatedInvitation.java index 3babc725c9..3a80347921 100644 --- a/source/java/org/alfresco/repo/invitation/WorkflowModelNominatedInvitation.java +++ b/source/java/org/alfresco/repo/invitation/WorkflowModelNominatedInvitation.java @@ -34,10 +34,10 @@ import org.alfresco.service.namespace.QName; public interface WorkflowModelNominatedInvitation { // process name - public static final QName WF_PROCESS_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invite"); + public static final QName WF_PROCESS_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitation-nominated"); // workflow definition name - public static final String WORKFLOW_DEFINITION_NAME = "jbpm$wf:invite"; + public static final String WORKFLOW_DEFINITION_NAME = "jbpm$wf:invitation-nominated"; // tasks public static final QName WF_INVITE_TASK_INVITE_TO_SITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteToSiteTask"); @@ -60,12 +60,12 @@ public interface WorkflowModelNominatedInvitation { public static final QName WF_PROP_INVITE_TICKET = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteTicket"); public static final QName WF_PROP_INVITER_USER_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviterUserName"); public static final QName WF_PROP_INVITEE_USER_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeUserName"); + public static final QName WF_PROP_INVITEE_EMAIL = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeEmail"); public static final QName WF_PROP_INVITEE_FIRSTNAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeFirstName"); public static final QName WF_PROP_INVITEE_LASTNAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeLastName"); public static final QName WF_PROP_RESOURCE_TYPE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "resourceType"); public static final QName WF_PROP_RESOURCE_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "resourceName"); - public static final QName WF_PROP_INVITEE_SITE_ROLE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeSiteRole"); - public static final QName WF_PROP_SENT_INVITE_DATE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "sentInviteDate"); + public static final QName WF_PROP_INVITEE_ROLE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeRole"); public static final QName WF_PROP_INVITEE_GEN_PASSWORD = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeGenPassword"); // workflow execution context variable names @@ -74,6 +74,6 @@ public interface WorkflowModelNominatedInvitation { public static final String wfVarResourceName = "wf_resourceName"; public static final String wfVarResourceType = "wf_resourceType"; public static final String wfVarWorkflowInstanceId = "workflowinstanceid"; - public static final String wfVarRole = "wf_inviteeSiteRole"; + public static final String wfVarRole = "wf_inviteeRole"; } diff --git a/source/java/org/alfresco/repo/invitation/script/ScriptInvitation.java b/source/java/org/alfresco/repo/invitation/script/ScriptInvitation.java new file mode 100644 index 0000000000..4fec8ccf1d --- /dev/null +++ b/source/java/org/alfresco/repo/invitation/script/ScriptInvitation.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.repo.invitation.script; + +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.InvitationService; + +/** + * Java script invitation for the Java Script API + * + * @author mrogers + */ +public class ScriptInvitation +{ + private Invitation invitation; + private InvitationService invitationService; + + public ScriptInvitation(Invitation invitation, InvitationService invitationService) + { + this.invitation = invitation; + this.invitationService = invitationService; + } + + public String getInviteId() + { + return invitation.getInviteId(); + } + + public String getInvitationType() + { + return invitation.getInvitationType().toString(); + } + + public String getResourceName() + { + return invitation.getResourceName(); + } + + public String getResourceType() + { + return invitation.getResourceType().toString(); + } + + protected Invitation getInvitation() + { + return invitation; + } + + protected InvitationService getInvitationService() + { + return invitationService; + } +} diff --git a/source/java/org/alfresco/repo/invitation/script/ScriptInvitationFactory.java b/source/java/org/alfresco/repo/invitation/script/ScriptInvitationFactory.java new file mode 100644 index 0000000000..5c94df8679 --- /dev/null +++ b/source/java/org/alfresco/repo/invitation/script/ScriptInvitationFactory.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.repo.invitation.script; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.InvitationService; +import org.alfresco.service.cmr.invitation.ModeratedInvitation; +import org.alfresco.service.cmr.invitation.NominatedInvitation; + +public class ScriptInvitationFactory +{ + public static ScriptInvitation toScriptInvitation(Invitation invitation, InvitationService invitationService) + { + if(invitation instanceof NominatedInvitation) + { + return new ScriptNominatedInvitation(invitation, invitationService); + } + + if(invitation instanceof ModeratedInvitation) + { + return new ScriptModeratedInvitation(invitation, invitationService); + } + + throw new AlfrescoRuntimeException("unknown invitation type"); + } +} diff --git a/source/java/org/alfresco/repo/invitation/script/ScriptModeratedInvitation.java b/source/java/org/alfresco/repo/invitation/script/ScriptModeratedInvitation.java new file mode 100644 index 0000000000..13dd3c2795 --- /dev/null +++ b/source/java/org/alfresco/repo/invitation/script/ScriptModeratedInvitation.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.repo.invitation.script; + +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.InvitationService; +import org.alfresco.service.cmr.invitation.ModeratedInvitation; +import org.alfresco.service.cmr.invitation.NominatedInvitation; + +/** + * Java script moderated invitation for the Java Script API + * + * @author mrogers + */ +public class ScriptModeratedInvitation extends ScriptInvitation implements java.io.Serializable +{ + + /** + * + */ + private static final long serialVersionUID = 4285823431857215500L; + + public ScriptModeratedInvitation(Invitation invitation, InvitationService invitationService) + { + super(invitation, invitationService); + } + + + public void approve(String reason) + { + getInvitationService().approve(getInviteId(), reason); + } + + public void reject(String reason) + { + getInvitationService().reject(getInviteId(), reason); + } + + public void cancel() + { + getInvitationService().cancel(getInviteId()); + } + + /** + * Which role to be added with + * @return the roleName + */ + public String getRoleName() + { + return ((ModeratedInvitation)getInvitation()).getRoleName(); + } + + /** + * The invitee comments - why does the invitee want access ? + * @return invitee comments + */ + public String getInviteeComments() + { + return ((ModeratedInvitation)getInvitation()).getInviteeComments(); + } + + /** + * The inviteeUserName + * @return the invitee user name + */ + public String getInviteeUserName() + { + return ((ModeratedInvitation)getInvitation()).getInviteeUserName(); + } +} diff --git a/source/java/org/alfresco/repo/invitation/script/ScriptNominatedInvitation.java b/source/java/org/alfresco/repo/invitation/script/ScriptNominatedInvitation.java new file mode 100644 index 0000000000..e32fc51c24 --- /dev/null +++ b/source/java/org/alfresco/repo/invitation/script/ScriptNominatedInvitation.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.repo.invitation.script; + + +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.InvitationService; +import org.alfresco.service.cmr.invitation.NominatedInvitation; +import org.alfresco.util.ISO8601DateFormat; + +import java.util.Date; + +/** + * Java script moderated invitation for the Java Script API + * + * @author mrogers + */ +public class ScriptNominatedInvitation extends ScriptInvitation implements java.io.Serializable +{ + /** + * + */ + private static final long serialVersionUID = 6079656007339750930L; + + /** + * + */ + + public ScriptNominatedInvitation(Invitation invitation, InvitationService invitationService) + { + super(invitation, invitationService); + } + + + public void accept(String reason) + { + getInvitationService().accept(getInviteId(), reason); + } + + public void reject(String reason) + { + getInvitationService().reject(getInviteId(), reason); + } + + public void cancel() + { + getInvitationService().cancel(getInviteId()); + } + + /** + * Which role to be added with + * @return the roleName + */ + public String getRoleName() + { + return ((NominatedInvitation)getInvitation()).getRoleName(); + } + + public String getInviteeUserName() + { + return ((NominatedInvitation)getInvitation()).getInviteeUserName(); + } + + /** + * Which role to be added with + * @return the roleName + */ + public Date getSentInviteDate() + { + return ((NominatedInvitation)getInvitation()).getSentInviteDate(); + } + + public String getSentInviteDateAsISO8601() + { + return ISO8601DateFormat.format(getSentInviteDate()); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/invitation/site/InviteHelper.java b/source/java/org/alfresco/repo/invitation/site/InviteHelper.java index 47c2c8b4ca..815785e27f 100644 --- a/source/java/org/alfresco/repo/invitation/site/InviteHelper.java +++ b/source/java/org/alfresco/repo/invitation/site/InviteHelper.java @@ -139,7 +139,7 @@ public class InviteHelper final String inviteeUserNameProp = (String) startInviteTask.properties.get( WorkflowModelNominatedInvitation.WF_PROP_INVITEE_USER_NAME); final String role = (String) startInviteTask.properties.get( - WorkflowModelNominatedInvitation.WF_PROP_INVITEE_SITE_ROLE); + WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE); final String siteShortNameProp = (String) startInviteTask.properties.get( WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME); diff --git a/source/java/org/alfresco/repo/site/script/Site.java b/source/java/org/alfresco/repo/site/script/Site.java index 1382fd1ff5..37e9c2b203 100644 --- a/source/java/org/alfresco/repo/site/script/Site.java +++ b/source/java/org/alfresco/repo/site/script/Site.java @@ -29,6 +29,9 @@ import java.util.List; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.invitation.InvitationSearchCriteriaImpl; +import org.alfresco.repo.invitation.script.ScriptInvitation; +import org.alfresco.repo.invitation.script.ScriptInvitationFactory; import org.alfresco.repo.jscript.ContentAwareScriptableQNameMap; import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.repo.jscript.ScriptableHashMap; @@ -40,6 +43,11 @@ import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.site.SiteModel; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.cmr.invitation.Invitation; +import org.alfresco.service.cmr.invitation.InvitationException; +import org.alfresco.service.cmr.invitation.InvitationSearchCriteria; +import org.alfresco.service.cmr.invitation.InvitationService; +import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; @@ -47,6 +55,9 @@ import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.namespace.QName; import org.alfresco.util.ParameterCheck; +import org.alfresco.wcm.asset.AssetInfo; +import org.alfresco.wcm.sandbox.script.Asset; +import org.mozilla.javascript.NativeObject; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; @@ -594,6 +605,113 @@ public class Site implements Serializable return this.customProperties; } + /** + * Create new moderated invitation to this web site + * @return the new invitation + */ + public ScriptInvitation inviteModerated(String inviteeComments, String inviteeUserName, String inviteeRole) + { + InvitationService invitationService = serviceRegistry.getInvitationService(); + Invitation invitation = invitationService.inviteModerated(inviteeComments, inviteeUserName, Invitation.ResourceType.WEB_SITE, getShortName(), inviteeRole); + return ScriptInvitationFactory.toScriptInvitation(invitation, invitationService); + } + + /** + * Create new nominated invitation to this web site + * @return the new invitation + */ + public ScriptInvitation inviteNominated(String inviteeFirstName, String inviteeLastName, String inviteeEmail, String inviteeRole, String serverPath, String acceptUrl, String rejectUrl) + { + InvitationService invitationService = serviceRegistry.getInvitationService(); + Invitation invitation = invitationService.inviteNominated(inviteeFirstName, inviteeLastName, inviteeEmail, Invitation.ResourceType.WEB_SITE, getShortName(), inviteeRole, serverPath, acceptUrl, rejectUrl); + return ScriptInvitationFactory.toScriptInvitation(invitation, invitationService); + } + + /** + * Create new nominated invitation to this web site + * @return the new invitation + */ + public ScriptInvitation inviteNominated(String inviteeUserName, String inviteeRole, String serverPath, String acceptUrl, String rejectUrl) + { + InvitationService invitationService = serviceRegistry.getInvitationService(); + Invitation invitation = invitationService.inviteNominated(inviteeUserName, Invitation.ResourceType.WEB_SITE, getShortName(), inviteeRole, serverPath, acceptUrl, rejectUrl); + return ScriptInvitationFactory.toScriptInvitation(invitation, invitationService); + } + + /** + * Get an invitation to this web site + * @return the invitation or null if it does not exist + */ + public ScriptInvitation getInvitation(String invitationId) + { + InvitationService invitationService = serviceRegistry.getInvitationService(); + try + { + Invitation invitation = invitationService.getInvitation(invitationId); + return ScriptInvitationFactory.toScriptInvitation(invitation, invitationService); + } + catch (InvitationException e) + { + return null; + } + } + + /** + * list the outstanding invitations for this site + * + * Map of name / invitation + */ + public ScriptInvitation[] listInvitations() + { + InvitationService invitationService = serviceRegistry.getInvitationService(); + + List invitations = invitationService.listPendingInvitationsForResource(Invitation.ResourceType.WEB_SITE, getShortName()); + ScriptInvitation[] ret = new ScriptInvitation[invitations.size()]; + int i = 0; + for(Invitation item : invitations) + { + ret[i++] = ScriptInvitationFactory.toScriptInvitation(item, invitationService); + } + return ret; + } + + /** + * List the open invitations for this web site. + * props specifies optional properties to be searched. + * + * @param props inviteeUserName + * + * @return the invitations + */ + public ScriptInvitation[] listInvitations(Scriptable props) + { + + InvitationService invitationService = serviceRegistry.getInvitationService(); + + InvitationSearchCriteriaImpl crit = new InvitationSearchCriteriaImpl(); + crit.setResourceName(getShortName()); + crit.setResourceType(Invitation.ResourceType.WEB_SITE); + + if (props.has("inviteeUserName", props)) + { + crit.setInvitee((String)props.get("inviteeUserName", props)); + } + if (props.has("invitationType", props)) + { + String invitationType = (String)props.get("inviteeUserName", props); + crit.setInvitationType(InvitationType.valueOf(invitationType)); + } + + List invitations = invitationService.searchInvitation(crit); + ScriptInvitation[] ret = new ScriptInvitation[invitations.size()]; + int i = 0; + for(Invitation item : invitations) + { + ret[i++] = ScriptInvitationFactory.toScriptInvitation(item, invitationService); + } + return ret; + } + /** * Custom property helper class * diff --git a/source/java/org/alfresco/service/cmr/invitation/Invitation.java b/source/java/org/alfresco/service/cmr/invitation/Invitation.java index 8fa29130de..80149bad02 100644 --- a/source/java/org/alfresco/service/cmr/invitation/Invitation.java +++ b/source/java/org/alfresco/service/cmr/invitation/Invitation.java @@ -46,6 +46,16 @@ public interface Invitation WEB_SITE } + /** + * What type of invitation are we? + * (Just Web site for now) + */ + enum InvitationType + { + NOMINATED, + MODERATED + } + /** * What sort of resource is it, for example a WEB_SITE? * @return the resource type @@ -58,16 +68,16 @@ public interface Invitation */ public String getResourceName(); - /** - * Who is this invitation for ? - * @return the user name of the invitee - */ - public String getInviteeUserName(); - /** * What is the unique reference for this invitation ? * @return the unique reference for this invitation */ public String getInviteId(); + /** + * What sort of invitation is this ? + */ + public InvitationType getInvitationType(); + + } diff --git a/source/java/org/alfresco/service/cmr/invitation/InvitationService.java b/source/java/org/alfresco/service/cmr/invitation/InvitationService.java index 2d803379d5..72181963ec 100644 --- a/source/java/org/alfresco/service/cmr/invitation/InvitationService.java +++ b/source/java/org/alfresco/service/cmr/invitation/InvitationService.java @@ -38,14 +38,48 @@ import java.util.List; */ public interface InvitationService { + /** + * Get the names of the workflows managed by the invitation service. + * + * @return the names of the workkflows managed by the invitation service. + */ + public List getInvitationServiceWorkflowNames(); /** - * Start the invitation process for a NominatedInvitation + * Start the invitation process for a NominatedInvitation for a user who does not yet have an Alfresco User Name + * + * @param inviteeUserName Alfresco user name of who should be invited + * @param ResourceType resourceType + * @param resourceName + * @param inviteeRole + * @param serverPath + * @param acceptUrl + * @param rejectUrl + * + * @return the nominated invitation which will contain the invitationId and + * ticket which will uniqely identify this invitation for the rest + * of the workflow. + * + * @throws InvitationException + * @throws InvitationExceptionUserError + * @throws InvitationExceptionForbidden + */ + public NominatedInvitation inviteNominated( + String inviteeUserName, + Invitation.ResourceType resourceType, + String resourceName, + String inviteeRole, + String serverPath, + String acceptUrl, + String rejectUrl) ; + + /** + * Start the invitation process for a NominatedInvitation for a user who does not yet have an + * Alfresco User NameA new user name will be generated as part of the invitation process. * * @param inviteeFirstName * @param inviteeLastName * @param inviteeEmail - * @param inviteeUserName the alfresco user name of the invitee, may be null for a new user * @param Invitation.ResourceType resourceType * @param resourceName * @param inviteeRole @@ -64,7 +98,6 @@ public interface InvitationService String inviteeFirstName, String inviteeLastName, String inviteeEmail, - String inviteeUserName, Invitation.ResourceType resourceType, String resourceName, String inviteeRole, diff --git a/source/java/org/alfresco/service/cmr/invitation/ModeratedInvitation.java b/source/java/org/alfresco/service/cmr/invitation/ModeratedInvitation.java index e6956e2803..66a0bc9369 100644 --- a/source/java/org/alfresco/service/cmr/invitation/ModeratedInvitation.java +++ b/source/java/org/alfresco/service/cmr/invitation/ModeratedInvitation.java @@ -36,13 +36,7 @@ package org.alfresco.service.cmr.invitation; * @author mrogers */ public interface ModeratedInvitation extends Invitation -{ - /** - * Which resource to be invited to? - * @return the resource name. - */ - public String getResourceName(); - +{ /** * Which role to be added with * @return the roleName @@ -54,5 +48,11 @@ public interface ModeratedInvitation extends Invitation * @return invitee comments */ public String getInviteeComments(); + + /** + * Who wants to be added + * @return inviteeUserName + */ + public String getInviteeUserName(); } diff --git a/source/java/org/alfresco/service/cmr/invitation/NominatedInvitation.java b/source/java/org/alfresco/service/cmr/invitation/NominatedInvitation.java index 7c198ffb20..865e35f1b6 100644 --- a/source/java/org/alfresco/service/cmr/invitation/NominatedInvitation.java +++ b/source/java/org/alfresco/service/cmr/invitation/NominatedInvitation.java @@ -39,6 +39,7 @@ import java.util.Date; */ public interface NominatedInvitation extends Invitation { + public String getInviteeUserName(); public String getInviteeFirstName();