diff --git a/src/main/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagement.java b/src/main/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagement.java
index 8b87aed0..33dd2843 100644
--- a/src/main/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagement.java
+++ b/src/main/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagement.java
@@ -115,7 +115,8 @@ public class CauseManagement extends BfaGraphAction {
@Override
public String getIconFileName() {
- if (Hudson.getInstance().hasPermission(PluginImpl.UPDATE_PERMISSION)) {
+ if (Hudson.getInstance().hasPermission(PluginImpl.UPDATE_PERMISSION)
+ || Hudson.getInstance().hasPermission(PluginImpl.VIEW_PERMISSION)) {
return PluginImpl.getDefaultIcon();
} else {
return null;
@@ -126,6 +127,8 @@ public String getIconFileName() {
public String getDisplayName() {
if (Hudson.getInstance().hasPermission(PluginImpl.UPDATE_PERMISSION)) {
return Messages.CauseManagement_DisplayName();
+ } else if (Hudson.getInstance().hasPermission(PluginImpl.VIEW_PERMISSION)) {
+ return Messages.CauseList_DisplayName();
} else {
return null;
}
diff --git a/src/main/java/com/sonyericsson/jenkins/plugins/bfa/PluginImpl.java b/src/main/java/com/sonyericsson/jenkins/plugins/bfa/PluginImpl.java
index befea244..1ca16602 100644
--- a/src/main/java/com/sonyericsson/jenkins/plugins/bfa/PluginImpl.java
+++ b/src/main/java/com/sonyericsson/jenkins/plugins/bfa/PluginImpl.java
@@ -86,6 +86,13 @@ public class PluginImpl extends Plugin {
new Permission(PERMISSION_GROUP, "UpdateCauses",
Messages._PermissionUpdate_Description(), Hudson.ADMINISTER);
+ /**
+ * Permission to view the causes. E.e. Access {@link CauseManagement}.
+ */
+ public static final Permission VIEW_PERMISSION =
+ new Permission(PERMISSION_GROUP, "ViewCauses",
+ Messages._PermissionView_Description(), UPDATE_PERMISSION);
+
/**
* Permission to remove causes.
*/
diff --git a/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/CauseManagement/index.groovy b/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/CauseManagement/index.groovy
index 8018c51b..8abc9d62 100644
--- a/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/CauseManagement/index.groovy
+++ b/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/CauseManagement/index.groovy
@@ -32,7 +32,7 @@ def f = namespace(lib.FormTagLib)
def l = namespace(lib.LayoutTagLib)
def j = namespace(lib.JenkinsTagLib)
-l.layout(permission: PluginImpl.UPDATE_PERMISSION) {
+l.layout(permission: PluginImpl.VIEW_PERMISSION) {
l.header(title: _("Failure Cause Management - Confirm Remove"))
def management = CauseManagement.getInstance();
@@ -55,7 +55,11 @@ l.layout(permission: PluginImpl.UPDATE_PERMISSION) {
+ "z-index: -100;"
+ "background-image: url(\'" + bgImageUrl + "');") {}
- h1(_("Update Failure Causes"))
+ if (h.hasPermission(PluginImpl.UPDATE_PERMISSION)) {
+ h1(_("Update Failure Causes"))
+ } else {
+ h1(_("List of Failure Causes"))
+ }
def shallowCauses = management.getShallowCauses()
if (management.isError(request)) {
@@ -73,28 +77,30 @@ l.layout(permission: PluginImpl.UPDATE_PERMISSION) {
}
//The New Cause link
- div(style: "margin-top: 10px; margin-bottom: 10px; width: 90%;") {
- a(style: "font-weight: bold; "
- + "font-size: larger; "
- + "padding-left: 30px; "
- + "min-height: 30px; "
- + "padding-top: 5px; "
- + "padding-bottom: 5px; "
- + "background-image: url( \'" + newImageUrl + "\'); "
- + "background-position: left center; "
- + "background-repeat: no-repeat;",
- href: "new",
- alt: _("New")) {text(_("Create new"))}
+ if (h.hasPermission(PluginImpl.UPDATE_PERMISSION)) {
+ div(style: "margin-top: 10px; margin-bottom: 10px; width: 90%;") {
+ a(style: "font-weight: bold; "
+ + "font-size: larger; "
+ + "padding-left: 30px; "
+ + "min-height: 30px; "
+ + "padding-top: 5px; "
+ + "padding-bottom: 5px; "
+ + "background-image: url( \'" + newImageUrl + "\'); "
+ + "background-position: left center; "
+ + "background-repeat: no-repeat;",
+ href: "new",
+ alt: _("New")) { text(_("Create new")) }
- if (PluginImpl.getInstance().isGraphsEnabled()) {
- a(style: "font-weight: bold; "
- + "font-size: larger; "
- + "padding-top: 5px; "
- + "padding-bottom: 5px; "
- + "float: right;",
- href: "detailedgraphs",
- alt: _("Graphs/statistics")) {text(_("Graphs/Statistics"))}
- }
+ if (PluginImpl.getInstance().isGraphsEnabled()) {
+ a(style: "font-weight: bold; "
+ + "font-size: larger; "
+ + "padding-top: 5px; "
+ + "padding-bottom: 5px; "
+ + "float: right;",
+ href: "detailedgraphs",
+ alt: _("Graphs/statistics")) { text(_("Graphs/Statistics")) }
+ }
+ }
}
//One time check so we don't do it for every iteration below
@@ -118,7 +124,11 @@ l.layout(permission: PluginImpl.UPDATE_PERMISSION) {
shallowCauses.each{ cause ->
tr {
td{
- a(href: cause.getId()){ text(cause.getName())}
+ if (h.hasPermission(PluginImpl.UPDATE_PERMISSION)) {
+ a(href: cause.getId()) { text(cause.getName()) }
+ } else {
+ text(cause.getName())
+ }
}
td{
text(cause.getCategoriesAsString())
diff --git a/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/Messages.properties b/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/Messages.properties
index c931640f..0d525776 100644
--- a/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/Messages.properties
+++ b/src/main/resources/com/sonyericsson/jenkins/plugins/bfa/Messages.properties
@@ -1,10 +1,12 @@
#I18n messages.
PermissionGroup_Title=Build Failure Analyzer
+PermissionView_Description=View Failure causes.
PermissionUpdate_Description=Add and Update Failure causes.
PermissionRemove_Description=Remove Failure causes.
BuildLogIndication_DisplayName=Build Log Indication
MultilineBuildLogIndication_DisplayName=Multi-Line Build Log Indication
CauseManagement_DisplayName=Failure Cause Management
+CauseList_DisplayName=Failure Causes
ScannerJobProperty_DisplayName=Do not Scan failed builds
LocalFileKnowledgeBase_DisplayName=Jenkins Local
MongoDBKnowledgeBase_DisplayName=Mongo DB
diff --git a/src/test/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagementPermissionTest.java b/src/test/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagementPermissionTest.java
new file mode 100644
index 00000000..94a0948c
--- /dev/null
+++ b/src/test/java/com/sonyericsson/jenkins/plugins/bfa/CauseManagementPermissionTest.java
@@ -0,0 +1,131 @@
+package com.sonyericsson.jenkins.plugins.bfa;
+
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import hudson.model.Hudson;
+import hudson.security.GlobalMatrixAuthorizationStrategy;
+import hudson.security.SecurityRealm;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+
+import javax.servlet.http.HttpServletResponse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests the permissions for the Cause Management.
+ *
+ * @author Damien Coraboeuf
+ */
+public class CauseManagementPermissionTest {
+
+ /**
+ * The Jenkins Rule.
+ */
+ @Rule
+ //CS IGNORE VisibilityModifier FOR NEXT 1 LINES. REASON: Jenkins Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ /**
+ * Configures Jenkins to use security and defines several users with different rights for the
+ * management or view of failure causes.
+ */
+ @Before
+ public void jenkinsConfiguration() {
+ SecurityRealm securityRealm = j.createDummySecurityRealm();
+ j.getInstance().setSecurityRealm(securityRealm);
+
+ GlobalMatrixAuthorizationStrategy authorizationStrategy = new GlobalMatrixAuthorizationStrategy();
+ authorizationStrategy.add(Hudson.READ, "anonymous");
+ authorizationStrategy.add(PluginImpl.VIEW_PERMISSION, "view");
+ authorizationStrategy.add(PluginImpl.UPDATE_PERMISSION, "update");
+ authorizationStrategy.add(PluginImpl.VIEW_PERMISSION, "all");
+ authorizationStrategy.add(PluginImpl.UPDATE_PERMISSION, "all");
+ j.getInstance().setAuthorizationStrategy(authorizationStrategy);
+ }
+
+ /**
+ * Checks that a non authorised user cannot access the failure management page at all.
+ *
+ * @throws java.lang.Exception If Jenkins cannot be accessed
+ */
+ @Test
+ public void notAllowedToUpdateCausesWhenNotGrantedAnything() throws Exception {
+ JenkinsRule.WebClient webClient = j.createWebClient();
+ // Logs in
+ webClient.goTo("");
+ webClient.login("none");
+ // Gets to the Failure Cause page
+ try {
+ webClient.goTo("failure-cause-management");
+ fail("Access to the page should have failed");
+ } catch (FailingHttpStatusCodeException ex) {
+ assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getStatusCode());
+ }
+ }
+
+ /**
+ * Checks that a user granted with "viewCauses" only can access the failure management page
+ * but not create a new failure.
+ *
+ * @throws java.lang.Exception If Jenkins cannot be accessed
+ */
+ @Test
+ public void allowedToViewCausesWhenGrantedOnlyView() throws Exception {
+ JenkinsRule.WebClient webClient = j.createWebClient();
+ // Logs in
+ webClient.goTo("");
+ webClient.login("view");
+ // Gets to the Failure Cause page
+ HtmlPage page = webClient.goTo("failure-cause-management");
+ // Checks we are actually on the page
+ assertNotNull(page.selectSingleNode("//h1[.='List of Failure Causes']"));
+ // Checks the "Create New" button is NOT available
+ assertNull(page.selectSingleNode("//a[.='Create new']"));
+ }
+
+ /**
+ * Checks that a user granted with "updateCauses" only can access the failure management page
+ * and create a new failure.
+ *
+ * @throws java.lang.Exception If Jenkins cannot be accessed
+ */
+ @Test
+ public void allowedToUpdateCausesWhenGrantedOnlyUpdate() throws Exception {
+ JenkinsRule.WebClient webClient = j.createWebClient();
+ // Logs in
+ webClient.goTo("");
+ webClient.login("update");
+ // Gets to the Failure Cause page
+ HtmlPage page = webClient.goTo("failure-cause-management");
+ // Checks we are actually on the page
+ assertNotNull(page.selectSingleNode("//h1[.='Update Failure Causes']"));
+ // Checks the "Create New" button is available
+ assertNotNull(page.selectSingleNode("//a[.='Create new']"));
+ }
+
+ /**
+ * Checks that a user granted with "updateCauses" and "viewCauses" only can access the failure management page
+ * and create a new failure.
+ *
+ * @throws java.lang.Exception If Jenkins cannot be accessed
+ */
+ @Test
+ public void allowedToUpdateCausesWhenGrantedBothUpdateAndView() throws Exception {
+ JenkinsRule.WebClient webClient = j.createWebClient();
+ // Logs in
+ webClient.goTo("");
+ webClient.login("all");
+ // Gets to the Failure Cause page
+ HtmlPage page = webClient.goTo("failure-cause-management");
+ // Checks we are actually on the page
+ assertNotNull(page.selectSingleNode("//h1[.='Update Failure Causes']"));
+ // Checks the "Create New" button is available
+ assertNotNull(page.selectSingleNode("//a[.='Create new']"));
+ }
+}