From efc0ca3913e9e1a567017fefc78f8d4e9f1b93e1 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Fri, 30 Jul 2010 15:48:02 +0000 Subject: [PATCH] ALF-4106 (ALF-4103): AuditService REST API - Enable/disable auditing and tests - TODO: Use .ftl to generate JSON from model git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21520 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/audit/control.get.desc.xml | 10 ++++ .../repository/audit/control.post.desc.xml | 27 +++++++++ .../repository/audit/control.properties | 3 +- .../web-scripts-application-context.xml | 9 ++- .../scripts/audit/AbstractAuditWebScript.java | 34 ++++++++++- .../{ControlGet.java => AuditControlGet.java} | 48 +++++++++------- .../web/scripts/audit/AuditControlPost.java | 57 +++++++++++++++++++ .../web/scripts/audit/AuditWebScriptTest.java | 36 +++++++++++- 8 files changed, 194 insertions(+), 30 deletions(-) create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.post.desc.xml rename source/java/org/alfresco/repo/web/scripts/audit/{ControlGet.java => AuditControlGet.java} (67%) create mode 100644 source/java/org/alfresco/repo/web/scripts/audit/AuditControlPost.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.get.desc.xml index 75d6f64e56..a80feccc7c 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.get.desc.xml @@ -6,6 +6,16 @@ admin required internal + + + application + Name of the audit application (omit to assume all applications) + + + path + Path within the application (omit to assume application root) + + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.post.desc.xml new file mode 100644 index 0000000000..c359e65d54 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.post.desc.xml @@ -0,0 +1,27 @@ + + Alfresco Audit Service Control + Change the audit status for a given application and path + /api/audit/control/{action}?application={application?}&path={path?} + + admin + required + internal + + + action + Set to 'enable' or 'disable' to change the audit state + + + application + Name of the audit application (omit to assume all applications) + + + path + Path within the application (omit to assume application root) + + + + + + + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.properties b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.properties index c8429d852b..c364f6c653 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.properties +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/audit/control.properties @@ -1,3 +1,4 @@ # Audit Control Web Script I18N audit.err.app.mandatory=Parameter 'app' is mandatory -audit.err.path.startsWith=Parameter 'path', when supplied, must start with '/' \ No newline at end of file +audit.err.path.startsWith=Parameter 'path', when supplied, must start with '/' +audit.err.action.invalid=Parameter 'action' must be either 'enable' or 'disable' \ No newline at end of file diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index e749d8cf03..d3470a62bb 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -812,7 +812,7 @@ parent="abstractWorkflowWebScript"> - + @@ -824,10 +824,15 @@ + + + diff --git a/source/java/org/alfresco/repo/web/scripts/audit/AbstractAuditWebScript.java b/source/java/org/alfresco/repo/web/scripts/audit/AbstractAuditWebScript.java index 929e9d8ce0..b6e9127aa6 100644 --- a/source/java/org/alfresco/repo/web/scripts/audit/AbstractAuditWebScript.java +++ b/source/java/org/alfresco/repo/web/scripts/audit/AbstractAuditWebScript.java @@ -18,6 +18,8 @@ */ package org.alfresco.repo.web.scripts.audit; +import java.util.Map; + import org.alfresco.service.cmr.audit.AuditService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,12 +39,15 @@ public abstract class AbstractAuditWebScript extends AbstractWebScript { public static final String PARAM_APP = "app"; public static final String PARAM_PATH="path"; + public static final String PARAM_ACTION = "action"; public static final String JSON_KEY_APPLICATIONS = "applications"; public static final String JSON_KEY_NAME = "name"; public static final String JSON_KEY_PATH = "path"; public static final String JSON_KEY_ENABLED = "enabled"; + private static enum AuditWebScriptAction {enable, disable}; + /** * Logger that can be used by subclasses. */ @@ -86,16 +91,16 @@ public abstract class AbstractAuditWebScript extends AbstractWebScript } /** * Get the path from the request. If it is mandatory, then a value must have been supplied - * otherwise, at the very least, '/' is returned. + * otherwise null is returned. * @param mandatory true if the parameter is expected - * @return Returns the path or at least '/' (never null) + * @return Returns the path or null if not present */ protected String getPath(WebScriptRequest req) { String paramPath = req.getParameter(PARAM_PATH); if (paramPath == null || paramPath.length() == 0) { - paramPath = "/"; + paramPath = null; } else if (!paramPath.startsWith("/")) { @@ -103,4 +108,27 @@ public abstract class AbstractAuditWebScript extends AbstractWebScript } return paramPath; } + + protected boolean getEnableDisable(WebScriptRequest req) + { + Map templateVars = req.getServiceMatch().getTemplateVars(); + String enableStr = templateVars.get(PARAM_ACTION); + try + { + AuditWebScriptAction action = AuditWebScriptAction.valueOf(enableStr); + switch (action) + { + case enable: + return true; + case disable: + return false; + default: + return false; + } + } + catch (IllegalArgumentException e) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "audit.err.action.invalid"); + } + } } diff --git a/source/java/org/alfresco/repo/web/scripts/audit/ControlGet.java b/source/java/org/alfresco/repo/web/scripts/audit/AuditControlGet.java similarity index 67% rename from source/java/org/alfresco/repo/web/scripts/audit/ControlGet.java rename to source/java/org/alfresco/repo/web/scripts/audit/AuditControlGet.java index e1d0d7b7e0..6d2c6e21da 100644 --- a/source/java/org/alfresco/repo/web/scripts/audit/ControlGet.java +++ b/source/java/org/alfresco/repo/web/scripts/audit/AuditControlGet.java @@ -19,7 +19,6 @@ package org.alfresco.repo.web.scripts.audit; import java.io.IOException; -import java.io.StringWriter; import java.nio.charset.Charset; import java.util.Collections; import java.util.Set; @@ -33,7 +32,7 @@ import org.springframework.extensions.webscripts.json.JSONWriter; * @author Derek Hulley * @since 3.4 */ -public class ControlGet extends AbstractAuditWebScript +public class AuditControlGet extends AbstractAuditWebScript { @Override public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException @@ -43,34 +42,44 @@ public class ControlGet extends AbstractAuditWebScript String app = getApp(req, false); String path = getPath(req); - Set apps = (app == null ? auditService.getAuditApplications() : Collections.singleton(app)); + Set apps = auditService.getAuditApplications(); + + // Check that the application exists + if (app != null) + { + if (apps.contains(app)) + { + apps = Collections.singleton(app); + } + else + { + apps = Collections.emptySet(); + } + } boolean enabledGlobal = auditService.isAuditEnabled(); json.startObject(); { json.writeValue(JSON_KEY_ENABLED, enabledGlobal); - if (apps.size() > 0) + json.startValue(JSON_KEY_APPLICATIONS); { - json.startValue(JSON_KEY_APPLICATIONS); + json.startArray(); { - json.startArray(); + for (String appName : apps) { - for (String appName : apps) + boolean enabled = auditService.isAuditEnabled(appName, path); + json.startObject(); { - boolean enabled = auditService.isAuditEnabled(appName, path); - json.startObject(); - { - json.writeValue(JSON_KEY_NAME, appName); - json.writeValue(JSON_KEY_PATH, path); - json.writeValue(JSON_KEY_ENABLED, enabled); - } - json.endObject(); + json.writeValue(JSON_KEY_NAME, appName); + json.writeValue(JSON_KEY_PATH, path); + json.writeValue(JSON_KEY_ENABLED, enabled); } + json.endObject(); } - json.endArray(); } - json.endValue(); + json.endArray(); } + json.endValue(); } json.endObject(); @@ -82,9 +91,4 @@ public class ControlGet extends AbstractAuditWebScript // res.addHeader("Content-Length", "" + length); // TODO: Do we need this? res.setStatus(Status.STATUS_OK); } - - protected void writeResponse(JSONWriter json) - { - - } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/audit/AuditControlPost.java b/source/java/org/alfresco/repo/web/scripts/audit/AuditControlPost.java new file mode 100644 index 0000000000..3906e82885 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/audit/AuditControlPost.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2005-2010 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.audit; + +import java.io.IOException; + +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; +import org.springframework.extensions.webscripts.WebScriptResponse; + +/** + * @author Derek Hulley + * @since 3.4 + */ +public class AuditControlPost extends AbstractAuditWebScript +{ + @Override + public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException + { + String app = getApp(req, false); + String path = getPath(req); + + boolean enable = getEnableDisable(req); + + if (app == null) + { + // Global operation + auditService.setAuditEnabled(enable); + } + else + { + // Apply to a specific application + auditService.enableAudit(app, path); + } + +// res.setContentType("application/json"); +// res.setContentEncoding(Charset.defaultCharset().displayName()); // TODO: Should be settable on JSONWriter + // res.addHeader("Content-Length", "" + length); // TODO: Do we need this? + res.setStatus(Status.STATUS_OK); + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/audit/AuditWebScriptTest.java b/source/java/org/alfresco/repo/web/scripts/audit/AuditWebScriptTest.java index 85bed65cf1..bf6e9d9395 100644 --- a/source/java/org/alfresco/repo/web/scripts/audit/AuditWebScriptTest.java +++ b/source/java/org/alfresco/repo/web/scripts/audit/AuditWebScriptTest.java @@ -20,6 +20,7 @@ package org.alfresco.repo.web.scripts.audit; import java.util.Set; +import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.web.scripts.BaseWebScriptTest; import org.alfresco.service.cmr.audit.AuditService; @@ -68,6 +69,7 @@ public class AuditWebScriptTest extends BaseWebScriptTest public void testGetIsAuditEnabledGlobally() throws Exception { boolean checkEnabled = auditService.isAuditEnabled(); + Set checkApps = auditService.getAuditApplications(); String url = "/api/audit/control"; TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); @@ -76,12 +78,13 @@ public class AuditWebScriptTest extends BaseWebScriptTest JSONObject json = new JSONObject(response.getContentAsString()); boolean enabled = json.getBoolean("enabled"); assertEquals("Mismatched global audit enabled", checkEnabled, enabled); + JSONArray apps = json.getJSONArray(AbstractAuditWebScript.JSON_KEY_APPLICATIONS); + assertEquals("Incorrect number of applications reported", checkApps.size(), apps.length()); } public void testGetIsAuditEnabledMissingApp() throws Exception { boolean checkEnabled = auditService.isAuditEnabled(); - Set checkApps = auditService.getAuditApplications(); String url = "/api/audit/control?app=xxx"; TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); @@ -93,6 +96,35 @@ public class AuditWebScriptTest extends BaseWebScriptTest assertEquals("Mismatched global audit enabled", checkEnabled, enabled); JSONArray apps = json.getJSONArray(AbstractAuditWebScript.JSON_KEY_APPLICATIONS); // We expect that the unknown application is returned with the others - assertEquals("Incorrect number of applications reported", checkApps.size()+1, apps.length()); + assertEquals("Should not be any apps listed", 0, apps.length()); + } + + public void testSetAuditEnabled() throws Exception + { + boolean checkEnabled = auditService.isAuditEnabled(); + + // We need to set this back after the test + try + { + if (checkEnabled) + { + String url = "/api/audit/control/disable"; + TestWebScriptServer.PostRequest req = new TestWebScriptServer.PostRequest(url, "", MimetypeMap.MIMETYPE_JSON); + sendRequest(req, 200, admin); + } + else + { + String url = "/api/audit/control/enable"; + TestWebScriptServer.PostRequest req = new TestWebScriptServer.PostRequest(url, "", MimetypeMap.MIMETYPE_JSON); + sendRequest(req, 200, admin); + } + + // Check that it worked + testGetIsAuditEnabledGlobally(); + } + finally + { + auditService.setAuditEnabled(checkEnabled); + } } }