diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/events/raiseevent.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/events/raiseevent.get.desc.xml new file mode 100644 index 0000000000..cde3cb67a0 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/events/raiseevent.get.desc.xml @@ -0,0 +1,10 @@ + + alfresco-browser-event + Raises an alfresco browser event, e.g /api/events/mysite/documentdetails/view + /api/events/{siteId}/{component}/{action} + /api/events/{component}/{action} + argument + user + required + internal + diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index fd9fe71055..1dde0bc7bf 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1581,6 +1581,12 @@ + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/events/RaiseBrowserEventGet.java b/source/java/org/alfresco/repo/web/scripts/events/RaiseBrowserEventGet.java new file mode 100644 index 0000000000..c1ebe85be2 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/events/RaiseBrowserEventGet.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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 . + */ +package org.alfresco.repo.web.scripts.events; + +import java.io.IOException; +import java.util.Map; + +import org.alfresco.repo.events.EventPublisher; +import org.alfresco.repo.security.permissions.AccessDeniedException; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.springframework.extensions.webscripts.AbstractWebScript; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; +import org.springframework.extensions.webscripts.WebScriptResponse; +import org.springframework.util.StringUtils; + +/** +* Raises an alfresco browser event, e.g /api/events/mysite/documentdetails/view +* +* @author Gethin James +* @since 5.0 + */ +public class RaiseBrowserEventGet extends AbstractWebScript +{ + private EventPublisher eventPublisher; + private SiteService siteService; + + public void setEventPublisher(EventPublisher eventPublisher) + { + this.eventPublisher = eventPublisher; + } + public void setSiteService(SiteService siteService) + { + this.siteService = siteService; + } + + @Override + public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException + { + Map templateVars = req.getServiceMatch().getTemplateVars(); + SiteInfo siteInfo = null; + String component = null; + String action = null; + + if (templateVars != null) + { + if (templateVars.containsKey("siteId")) + { + //Validates the site id + siteInfo = siteService.getSite(templateVars.get("siteId")); + if (siteInfo == null) + { + throw new AccessDeniedException("No such site: " + templateVars.get("siteId")); + } + + } + component = templateVars.get("component"); + action = templateVars.get("action"); + } + + String attributes = req.getParameter("attributes"); + if (attributes != null) + { + if (!validJsonMap(attributes)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Invalid JSON Object: " + attributes); + } + } + + if (StringUtils.hasText(component) && StringUtils.hasText(action)) + { + eventPublisher.publishBrowserEvent(req, siteInfo==null?null:siteInfo.getShortName(), component, action, attributes); + } + + res.setStatus(Status.STATUS_OK); + } + + /** + * Validate Json to ensure its a Map. + * @param attributes jsonmap + * @return boolean true if valid + */ + private boolean validJsonMap(String attributes) + { + try + { + @SuppressWarnings("unused") + JSONObject json = new JSONObject(new JSONTokener(attributes)); + return true; + } + catch (JSONException error) + { + return false; + } + + } + +} diff --git a/source/test-java/org/alfresco/repo/web/scripts/events/RaiseEventTest.java b/source/test-java/org/alfresco/repo/web/scripts/events/RaiseEventTest.java new file mode 100644 index 0000000000..ebb8a42f36 --- /dev/null +++ b/source/test-java/org/alfresco/repo/web/scripts/events/RaiseEventTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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 . + */ +package org.alfresco.repo.web.scripts.events; + +import java.util.List; + +import org.alfresco.events.types.BrowserEvent; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.events.EventPublisherForTestingOnly; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.site.SiteModel; +import org.alfresco.repo.web.scripts.BaseWebScriptTest; +import org.alfresco.service.cmr.security.MutableAuthenticationService; +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.util.PropertyMap; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; + +/** + * Tests the {@link RaiseBrowserEventGet} endpoint + */ +public class RaiseEventTest extends BaseWebScriptTest +{ + + private static final String USER_ONE = "RaiseEventTestuser1"; + private static final String SITE_EVENTS_TEST = "RaiseEventTestSite"; + private static final String GET_URL = "/api/events/"; + + private EventPublisherForTestingOnly eventPublisher; + private AuthenticationComponent authenticationComponent; + private SiteService siteService; + private MutableAuthenticationService authenticationService; + private PersonService personService; + + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + this.authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent"); + this.siteService = (SiteService)getServer().getApplicationContext().getBean("SiteService"); + this.eventPublisher = (EventPublisherForTestingOnly)getServer().getApplicationContext().getBean("eventPublisher"); + this.authenticationService = (MutableAuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService"); + this.personService = (PersonService)getServer().getApplicationContext().getBean("PersonService"); + this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); + + // Create test site + // - only create the site if it doesn't already exist + SiteInfo siteInfo = this.siteService.getSite(SITE_EVENTS_TEST); + if (siteInfo == null) + { + this.siteService.createSite("RaiseEventSitePreset", SITE_EVENTS_TEST, SITE_EVENTS_TEST+" Title", "SiteDescription", SiteVisibility.PRIVATE); + } + + createUser(USER_ONE, SiteModel.SITE_COLLABORATOR); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + + // admin user required to delete user + this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); + + SiteInfo siteInfo = this.siteService.getSite(SITE_EVENTS_TEST); + if (siteInfo != null) + { + // delete invite site + siteService.deleteSite(SITE_EVENTS_TEST); + } + + // delete the users + deleteUser(USER_ONE); + } + + /** + * Tests GET requests to create browser events. + * + * @throws Exception + */ + public void testRaiseEvent() throws Exception + { + sendRequest(new GetRequest(GET_URL+"mypage/edit"), Status.STATUS_OK); + sendRequest(new GetRequest(GET_URL), Status.STATUS_NOT_FOUND); + sendRequest(new GetRequest(GET_URL+"mypage"), Status.STATUS_NOT_FOUND); + sendRequest(new GetRequest(GET_URL+SITE_EVENTS_TEST+"/sitepage/view"), Status.STATUS_OK); + sendRequest(new GetRequest(GET_URL+SITE_EVENTS_TEST+"/sitepage/view?attributes=xyz"), Status.STATUS_BAD_REQUEST); + sendRequest(new GetRequest(GET_URL+SITE_EVENTS_TEST+"/specialpage/view?attributes={\"source\": \"bob\", \"target\": \"hope\"}"), Status.STATUS_OK); + + List browserEvents = eventPublisher.getQueueByType(BrowserEvent.class); + int found = 0; + for (BrowserEvent be : browserEvents) + { + if ("mypage".equals(be.getComponent())) + { + found ++; + assertEquals("edit", be.getAction()); + continue; + } + + if ("sitepage".equals(be.getComponent())) + { + found ++; + assertEquals(SITE_EVENTS_TEST, be.getSiteId()); + assertEquals("view", be.getAction()); + continue; + } + + if ("specialpage".equals(be.getComponent())) + { + found ++; + assertEquals(SITE_EVENTS_TEST, be.getSiteId()); + assertEquals("view", be.getAction()); + assertEquals("{\"source\": \"bob\", \"target\": \"hope\"}", be.getAttributes()); + continue; + } + } + assertEquals(3, found); //Found and validated 3 events. + + } + + private void createUser(String userName, String role) + { + // if user with given user name doesn't already exist then create user + if (this.authenticationService.authenticationExists(userName) == false) + { + // create user + this.authenticationService.createAuthentication(userName, "password".toCharArray()); + + // create person properties + PropertyMap personProps = new PropertyMap(); + personProps.put(ContentModel.PROP_USERNAME, userName); + personProps.put(ContentModel.PROP_FIRSTNAME, "FirstName123"); + personProps.put(ContentModel.PROP_LASTNAME, "LastName123"); + personProps.put(ContentModel.PROP_EMAIL, "FirstName123.LastName123@email.com"); + personProps.put(ContentModel.PROP_JOBTITLE, "JobTitle123"); + personProps.put(ContentModel.PROP_JOBTITLE, "Organisation123"); + + // create person node for user + this.personService.createPerson(personProps); + } + + // add the user as a member with the given role + this.siteService.setMembership(SITE_EVENTS_TEST, userName, role); + } + private void deleteUser(String userName) + { + personService.deletePerson(userName); + if (this.authenticationService.authenticationExists(userName)) + { + this.authenticationService.deleteAuthentication(userName); + } + } + +}