Skip to content

Commit

Permalink
Added support for View permissions at the View level rather than only…
Browse files Browse the repository at this point in the history
… at global level
  • Loading branch information
pskumar448 committed Aug 23, 2016
1 parent 4d7e065 commit 079b05c
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 2 deletions.
Expand Up @@ -80,6 +80,7 @@ public class RoleBasedAuthorizationStrategy extends AuthorizationStrategy {
public final static String GLOBAL = "globalRoles";
public final static String PROJECT = "projectRoles";
public final static String SLAVE = "slaveRoles";
public final static String VIEW = "viewRoles";
public final static String MACRO_ROLE = "roleMacros";
public final static String MACRO_USER = "userMacros";

Expand Down Expand Up @@ -138,6 +139,17 @@ public ACL getACL(AbstractItem project) {
public ACL getACL(Computer computer) {
return getACL(SLAVE, computer.getName(), RoleType.Slave, computer);
}

@Override
public ACL getACL(View view) {
return getACL(VIEW, getViewFullName(view), RoleType.View, view);
}

String getViewFullName(View view) {
String n = view.getOwnerItemGroup().getFullName();
if(n.length()==0) return view.getViewName();
else return n+'/'+ view.getViewName();
}

/**
* Used by the container realm.
Expand Down Expand Up @@ -449,7 +461,7 @@ public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData

// If the form contains data, it means the method has been called by plugin
// specifics forms, and we need to handle it.
if (formData.has(GLOBAL) && formData.has(PROJECT) && formData.has(SLAVE) && oldStrategy instanceof RoleBasedAuthorizationStrategy) {
if (formData.has(GLOBAL) && formData.has(PROJECT) && formData.has(SLAVE) && formData.has(VIEW) && oldStrategy instanceof RoleBasedAuthorizationStrategy) {
strategy = new RoleBasedAuthorizationStrategy();

JSONObject globalRoles = formData.getJSONObject(GLOBAL);
Expand Down Expand Up @@ -478,6 +490,7 @@ public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData

ReadRoles(formData, PROJECT, strategy, (RoleBasedAuthorizationStrategy)oldStrategy);
ReadRoles(formData, SLAVE, strategy, (RoleBasedAuthorizationStrategy)oldStrategy);
ReadRoles(formData, VIEW, strategy, (RoleBasedAuthorizationStrategy)oldStrategy);
}
// When called from Hudson Manage panel, but was already on a role-based strategy
else if(oldStrategy instanceof RoleBasedAuthorizationStrategy) {
Expand Down Expand Up @@ -592,6 +605,10 @@ else if (type.equals(SLAVE)) {
groups.remove(PermissionGroup.get(SCM.class));
groups.remove(PermissionGroup.get(Run.class));
}
else if (type.equals(VIEW)) {
groups = new ArrayList<PermissionGroup>();
groups.add(PermissionGroup.get(View.class));
}
else {
groups = null;
}
Expand All @@ -611,6 +628,9 @@ else if(type.equals(PROJECT)) {
else if (type.equals(SLAVE)) {
return p!=Computer.CREATE && p.getEnabled();
}
else if (type.equals(VIEW)) {
return p!=View.CREATE && p.getEnabled();
}
else {
return false;
}
Expand Down
Expand Up @@ -177,4 +177,8 @@ public final RoleType getProjectRoleType() {
public final RoleType getSlaveRoleType() {
return RoleType.Slave;
}

public final RoleType getViewRoleType() {
return RoleType.View;
}
}
Expand Up @@ -35,7 +35,8 @@ public enum RoleType {

Global,
Project,
Slave;
Slave,
View;

/**
* @deprecated Naming convention violation, use {@link #fromString(java.lang.String)}.
Expand Down Expand Up @@ -68,6 +69,10 @@ public static RoleType fromString(String roleName) {
return Slave;
}

if (roleName.equals(RoleBasedAuthorizationStrategy.VIEW)) {
return View;
}

throw new java.lang.IllegalArgumentException("Unexpected roleName=" + roleName);
}

Expand All @@ -84,6 +89,8 @@ public String getStringType() {
return RoleBasedAuthorizationStrategy.PROJECT;
case Slave:
return RoleBasedAuthorizationStrategy.SLAVE;
case View:
return RoleBasedAuthorizationStrategy.VIEW;
default:
throw new java.lang.IllegalArgumentException("Unsupported Role: " + this);
}
Expand Down
Expand Up @@ -37,10 +37,12 @@
<j:set var="globalGrantedRoles" value="${it.strategy.getGrantedRoles(it.strategy.GLOBAL)}"/>
<j:set var="projectGrantedRoles" value="${it.strategy.getGrantedRoles(it.strategy.PROJECT)}"/>
<j:set var="slaveGrantedRoles" value="${it.strategy.getGrantedRoles(it.strategy.SLAVE)}"/>
<j:set var="viewGrantedRoles" value="${it.strategy.getGrantedRoles(it.strategy.VIEW)}"/>

<j:set var="globalSIDs" value="${it.strategy.getSIDs(it.strategy.GLOBAL)}"/>
<j:set var="projectSIDs" value="${it.strategy.getSIDs(it.strategy.PROJECT)}"/>
<j:set var="slaveSIDs" value="${it.strategy.getSIDs(it.strategy.SLAVE)}"/>
<j:set var="viewSIDs" value="${it.strategy.getSIDs(it.strategy.VIEW)}"/>

<j:if test="${empty(descriptorPath)}">
<j:set var="descriptorPath" value="${rootURL}/descriptor/${it.strategy.descriptor.clazz.name}"/>
Expand Down Expand Up @@ -90,6 +92,11 @@
<f:block><st:include page="assign-slave-roles.jelly" optional="true" /></f:block>
</f:rowSet>
</f:section>
<f:section title="${%View roles}">
<f:rowSet name="viewRoles">
<f:block><st:include page="assign-view-roles.jelly" optional="true" /></f:block>
</f:rowSet>
</f:section>
<f:block>
<f:submit value="${%Save}" />
<f:apply />
Expand Down
@@ -0,0 +1,145 @@
<!--
- The MIT License
-
- Copyright (c) 2016, Suresh.
-
- Original file: manage-project-roles.jelly
- Thomas Maurel & Romain Seguy, Manufacture Française des Pneumatiques Michelin
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:local="local">

<j:set var="id" value="${h.generateId()}"/>

<table id="viewRoles" class="center-align global-matrix-authorization-strategy-table" name="data">

<!-- The first row will show grouping -->
<tr class="group-row">
<td class="start" />
<td class="pane-header blank">
${%User/group}
</td>
<j:forEach var="role" items="${viewGrantedRoles}">
<td class="pane-header">
${role.key.name}
</td>
</j:forEach>
<td class="stop" />
</tr>
<j:set var="nbAssignedViewRoles" value="${0}" />
<j:forEach var="sid" items="${viewSIDs}">
<tr name="[${sid}]" class="permission-row">
<local:userRow sid="${sid}" title="${sid}" global="${false}" type="${it.strategy.VIEW}"/>
</tr>
<j:set var="nbAssignedViewRoles" value="${nbAssignedViewRoles+1}" />
</j:forEach>
<tr name="anonymous">
<local:userRow sid="anonymous" title="${%Anonymous}" global="${false}" type="${it.strategy.VIEW}"/>
</tr>
<tr id="${id}" style="display:none" class="permission-row">
<local:userRow global="${false}" type="${it.strategy.VIEW}"/>
</tr>
<!-- The last row is used to repeat the header (if more than 19+1 lines) -->
<j:if test="${nbAssignedViewRoles ge 19}">
<tr class="group-row">
<td class="start" />
<td class="pane-header blank">
${%User/group}
</td>
<j:forEach var="role" items="${viewGrantedRoles}">
<td class="pane-header">
${role.key.name}
</td>
</j:forEach>
<td class="stop" />
</tr>
</j:if>
</table>

<br /><br />
<f:entry title="${%User/group to add}" help="${rootURL}/plugin/role-strategy/help/help-user-group-add.html">
<f:textbox type="text" id="${id}text" />
</f:entry>
<f:entry>
<input type="button" value="${%Add}" id="${id}button"/>
</f:entry>

<script>
var tableHighlighter;
(function() {
<!-- place master outside the DOM tree so that it won't creep into the submitted form -->
var master = document.getElementById('${id}');
var table = master.parentNode;
table.removeChild(master);

makeButton($$('${id}button'), function (e) {
<!-- when 'add' is clicked... -->
var name = $$('${id}text').value;
if(name=="") {
alert("Please enter a role name");
return;
}
if(findElementsBySelector(table,"TR").find(function(n){return n.getAttribute("name")=='['+name+']';})!=null) {
alert("Entry for '"+name+"' already exists");
return;
}

if(document.importNode!=null)
copy = document.importNode(master,true);
else
copy = master.cloneNode(true); <!-- for IE -->
copy.removeAttribute("id");
copy.removeAttribute("style");
copy.childNodes[1].innerHTML = name;
copy.setAttribute("name",'['+name+']');
<j:if test="${nbAssignedViewRoles lt 19}">
table.appendChild(copy);
</j:if>
<j:if test="${nbAssignedViewRoles ge 19}">
table.insertBefore(copy,table.childNodes[table.rows.length-1]);
</j:if>
tableHighlighter.scan(copy);
Behaviour.applySubtree(findAncestor(table,"TABLE"));
});
})();

Event.observe(window, 'load', function(event) {
tableHighlighter = new TableHighlighter('viewRoles', 0, 1);
});

var deleteAssignedViewRole = function(e) {
e.onclick = function() {
var tr = findAncestor(this,"TR");
tr.parentNode.removeChild(tr);
return false;
}
e = null; <!-- avoid memory leak -->
}
Behaviour.register({
"#viewRoles TD.start A" : deleteAssignedViewRole,
"#viewRoles TD.stop A" : deleteAssignedViewRole,
"#viewRoles TR.permission-row" : function(e) {
FormChecker.delayedCheck("${descriptorPath}/checkName?value="+encodeURIComponent(e.getAttribute("name")),"GET",e.childNodes[1]);
}
});
</script>
</j:jelly>
Expand Up @@ -38,6 +38,7 @@
<j:set var="globalGroups" value="${it.strategy.descriptor.getGroups(it.strategy.GLOBAL)}"/>
<j:set var="projectGroups" value="${it.strategy.descriptor.getGroups(it.strategy.PROJECT)}"/>
<j:set var="slaveGroups" value="${it.strategy.descriptor.getGroups(it.strategy.SLAVE)}"/>
<j:set var="viewGroups" value="${it.strategy.descriptor.getGroups(it.strategy.VIEW)}"/>

<d:taglib uri="local">
<d:tag name="roleRow">
Expand Down Expand Up @@ -97,6 +98,13 @@
-->
</f:rowSet>
</f:section>
<f:section title="${%View roles}">
<f:rowSet name="viewRoles">
<f:block><st:include page="manage-view-roles.jelly"
optional="true" />
</f:block>
</f:rowSet>
</f:section>
<f:block>
<f:submit value="${%Save}" />
<f:apply />
Expand Down

0 comments on commit 079b05c

Please sign in to comment.