Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable anonymous access to the list of failure causes #31

Merged
merged 5 commits into from
Jan 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since VIEW_PERMISSION is inferred by UPDATE_PERMISSION you should be able to put permission: PluginImpl.VIEW_PERMISSION here for safety.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

l.header(title: _("Failure Cause Management - Confirm Remove"))

def management = CauseManagement.getInstance();
Expand All @@ -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)) {
Expand All @@ -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
Expand All @@ -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())
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
* <i>but not</i> 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
* <i>and</i> 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
* <i>and</i> 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']"));
}
}