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

[JENKINS-19409] - Added option, which makes plugin to convert all SIDs to the lower-case (fixed merge conflicts) #225

Closed
wants to merge 5 commits into from
Closed
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 @@ -25,6 +25,7 @@

package com.michelin.cio.hudson.plugins.rolestrategy;

import com.synopsys.arc.jenkins.plugins.rolestrategy.RoleStrategyProperties;
import com.synopsys.arc.jenkins.plugins.rolestrategy.RoleType;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
Expand Down Expand Up @@ -104,6 +105,7 @@ public class RoleBasedAuthorizationStrategy extends AuthorizationStrategy {
private final RoleMap agentRoles;
private final RoleMap globalRoles;
private final RoleMap itemRoles;
private RoleStrategyProperties globalProperties;

/**
* Create new RoleBasedAuthorizationStrategy.
Expand All @@ -112,6 +114,7 @@ public RoleBasedAuthorizationStrategy() {
agentRoles = new RoleMap();
globalRoles = new RoleMap();
itemRoles = new RoleMap();
globalProperties = RoleStrategyProperties.DEFAULT;
}

/**
Expand All @@ -128,6 +131,35 @@ public RoleBasedAuthorizationStrategy(Map<String, RoleMap> grantedRoles) {

map = grantedRoles.get(PROJECT);
itemRoles = map == null ? new RoleMap() : map;

globalProperties = RoleStrategyProperties.DEFAULT;
}

/**
* Creates a new {@link RoleBasedAuthorizationStrategy}.
*
* @param grantedRoles the roles in the strategy
* @param prop global properties
*/
public RoleBasedAuthorizationStrategy(Map<String, RoleMap> grantedRoles, RoleStrategyProperties prop) {
RoleMap map = grantedRoles.get(SLAVE);
agentRoles = map == null ? new RoleMap() : map;

map = grantedRoles.get(GLOBAL);
globalRoles = map == null ? new RoleMap() : map;

map = grantedRoles.get(PROJECT);
itemRoles = map == null ? new RoleMap() : map;
Comment on lines +144 to +152
Copy link
Contributor

Choose a reason for hiding this comment

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

duplicated code with other constructor. The former should be deprecated and just forward to this one


globalProperties = prop == null ? RoleStrategyProperties.DEFAULT : prop;
}

public RoleStrategyProperties getGlobalProperties() {
return globalProperties;
}

public void setGlobalProperties(RoleStrategyProperties prop) {
globalProperties = prop;
}

/**
Expand All @@ -138,7 +170,8 @@ public RoleBasedAuthorizationStrategy(Map<String, RoleMap> grantedRoles) {
@Override
@NonNull
public SidACL getRootACL() {
return globalRoles.getACL(RoleType.Global, null);
RoleMap root = getRoleMap(RoleType.fromString(GLOBAL));
return root.getACL(RoleType.Global, null, globalProperties.isConvertSidsToLowerCase());
}

/**
Expand Down Expand Up @@ -178,19 +211,22 @@ public ACL getACL(@NonNull Job<?, ?> project) {
@Override
@NonNull
public ACL getACL(@NonNull AbstractItem project) {
return itemRoles.newMatchingRoleMap(project.getFullName()).getACL(RoleType.Project, project).newInheritingACL(getRootACL());
return itemRoles.newMatchingRoleMap(project.getFullName()).getACL(
RoleType.Project, project, globalProperties.isConvertSidsToLowerCase()).newInheritingACL(getRootACL());
}

@Override
@NonNull
public ACL getACL(@NonNull Computer computer) {
return agentRoles.newMatchingRoleMap(computer.getName()).getACL(RoleType.Slave, computer).newInheritingACL(getRootACL());
return agentRoles.newMatchingRoleMap(computer.getName()).getACL(
RoleType.Slave, computer, globalProperties.isConvertSidsToLowerCase()).newInheritingACL(getRootACL());
}

@Override
@NonNull
public ACL getACL(@NonNull Node node) {
return agentRoles.newMatchingRoleMap(node.getNodeName()).getACL(RoleType.Slave, node).newInheritingACL(getRootACL());
return agentRoles.newMatchingRoleMap(node.getNodeName()).getACL(
RoleType.Slave, node, globalProperties.isConvertSidsToLowerCase()).newInheritingACL(getRootACL());
}

/**
Expand Down Expand Up @@ -623,6 +659,9 @@ public void doGetMatchingAgents(@QueryParameter(required = true) String pattern,
* </p>
*/
public static class ConverterImpl implements Converter {

private static final String GLOBAL_PROPERTIES_NODE = "globalProperties";
Copy link
Contributor

Choose a reason for hiding this comment

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

Move that to the outer class so it can be used also in the descriptor


@Override
public boolean canConvert(Class type) {
return type == RoleBasedAuthorizationStrategy.class;
Expand All @@ -632,6 +671,11 @@ public boolean canConvert(Class type) {
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
RoleBasedAuthorizationStrategy strategy = (RoleBasedAuthorizationStrategy) source;

// Marshal properties
writer.startNode(GLOBAL_PROPERTIES_NODE);
context.convertAnother(strategy.getGlobalProperties());
writer.endNode();

// Role maps
Map<RoleType, RoleMap> maps = strategy.getRoleMaps();
for (Map.Entry<RoleType, RoleMap> map : maps.entrySet()) {
Expand Down Expand Up @@ -671,10 +715,19 @@ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingC

@Override
public Object unmarshal(HierarchicalStreamReader reader, final UnmarshallingContext context) {

final Map<String, RoleMap> roleMaps = new HashMap<>();
RoleStrategyProperties props = null;

while (reader.hasMoreChildren()) {
reader.moveDown();

// read global properties
if (reader.getNodeName().equals(GLOBAL_PROPERTIES_NODE)) {
props = (RoleStrategyProperties) context.convertAnother(
context.currentObject(), RoleStrategyProperties.class);
}

// roleMaps
if (reader.getNodeName().equals("roleMap")) {
String type = reader.getAttribute("type");
Expand Down Expand Up @@ -719,7 +772,7 @@ public Object unmarshal(HierarchicalStreamReader reader, final UnmarshallingCont
reader.moveUp();
}

return new RoleBasedAuthorizationStrategy(roleMaps);
return new RoleBasedAuthorizationStrategy(roleMaps, props);
}

protected RoleBasedAuthorizationStrategy create() {
Expand Down Expand Up @@ -895,6 +948,13 @@ public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData
strategy.assignRole(RoleType.Global, adminRole, getCurrentUser());
}

// global properties
if (formData.containsKey("globalProperties")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

use GLOBAL_PROPERTIES_NODE once moved

RoleStrategyProperties prop = req.bindJSON(
RoleStrategyProperties.class, formData.getJSONObject("globalProperties"));
strategy.setGlobalProperties(prop);
}

return strategy;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ public boolean hasRole(@NonNull Role role) {
* @return ACL for the current {@link RoleMap}
*/
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
public SidACL getACL(RoleType roleType, AccessControlled controlledItem) {
return new AclImpl(roleType, controlledItem);
public SidACL getACL(RoleType roleType, AccessControlled controlledItem, boolean ignoresCase) {
return new AclImpl(roleType, controlledItem, ignoresCase);
}

/**
Expand Down Expand Up @@ -533,10 +533,12 @@ private final class AclImpl extends SidACL {

AccessControlled item;
RoleType roleType;
boolean ignoresCase; // Makes SID to convert all SIDs to lower-case

public AclImpl(RoleType roleType, AccessControlled item) {
public AclImpl(RoleType roleType, AccessControlled item, boolean ignoresCase) {
this.item = item;
this.roleType = roleType;
this.ignoresCase = ignoresCase;
}

/**
Expand All @@ -553,7 +555,8 @@ public AclImpl(RoleType roleType, AccessControlled item) {
@Override
@CheckForNull
protected Boolean hasPermission(Sid sid, Permission permission) {
if (RoleMap.this.hasPermission(toString(sid), permission, roleType, item)) {
String effectiveSid = ignoresCase ? toString(sid).toLowerCase() : toString(sid);
if (RoleMap.this.hasPermission(effectiveSid, permission, roleType, item)) {
if (item instanceof Item) {
final ItemGroup parent = ((Item) item).getParent();
if (parent instanceof Item && (Item.DISCOVER.equals(permission) || Item.READ.equals(permission))
Expand All @@ -578,7 +581,7 @@ && shouldCheckParentPermissions()) {
if (auth instanceof RoleBasedAuthorizationStrategy && pns instanceof RoleBasedProjectNamingStrategy) {
RoleBasedAuthorizationStrategy rbas = (RoleBasedAuthorizationStrategy) auth;
RoleMap roleMapProject = rbas.getRoleMap(RoleType.Project);
if (roleMapProject.hasPermission(toString(sid), permission, RoleType.Project, item)) {
if (roleMapProject.hasPermission(effectiveSid, permission, RoleType.Project, item)) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* 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.
*/

package com.synopsys.arc.jenkins.plugins.rolestrategy;

import com.michelin.cio.hudson.plugins.rolestrategy.Messages;
import hudson.Extension;
import hudson.model.Describable;
import hudson.model.Descriptor;
import java.io.Serializable;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Class, which stores global configuration of Role-Strategy security.
*
*/
public class RoleStrategyProperties implements Describable<RoleStrategyProperties>, Serializable {

/* Default value, which preserves legacy behavior */
public static final RoleStrategyProperties DEFAULT = new RoleStrategyProperties(false);

private boolean convertSidsToLowerCase;

@DataBoundConstructor
public RoleStrategyProperties(boolean convertSidsToLowerCase) {
this.convertSidsToLowerCase = convertSidsToLowerCase;
}

public boolean isConvertSidsToLowerCase() {
return convertSidsToLowerCase;
}

@Override
public Descriptor<RoleStrategyProperties> getDescriptor() {
return DESCRIPTOR;
}

public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();

/**
* Default DescriptorImpl.
*/
@Extension
public static final class DescriptorImpl extends Descriptor<RoleStrategyProperties> {

@Override
public String getDisplayName() {
return Messages.RoleStrategyProperties_DisplayName();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ RoleBasedProjectNamingStrategy.NoPattern=Not matches to any pattern from role ba
RoleBasedProjectNamingStrategy.JobNameConventionNotApplyed=\u2018{0}\u2019 does not match the job name convention pattern {1}
RoleBasedProjectNamingStrategy.WhiteSpaceWillBeTrimmed=Leading and trailing whitespace characters will be removed
RoleBasedProjectNamingStrategy.NotConfigured=Role-Based Naming Strategy not enabled
RoleStrategyProperties.DisplayName=Role-Based Strategy Properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
<!--
* The MIT License
*
* Copyright 2013 Oleg Nenashev, Synopsys Inc.
Expand All @@ -20,24 +20,9 @@
* 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.
*/

package com.synopsys.arc.jenkins.plugins.rolestrategy;

import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

/**
* Stub class, which stores jelly files for RoleStrategyPlugin.
*
* @author Oleg Nenashev
* @since 2.1.0
* @deprecated the class is not used anywhere, just a stub
*/
@Deprecated
@Restricted(NoExternalUse.class)
public class RoleStrategyConfigExtension {
public String getCompanyName() {
return "Synopsys";
}
}
-->
<?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">
<f:property field="globalProperties"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
* The MIT License
*
* Copyright 2013 Synopsys Inc., Oleg Nenashev <nenashev@synopsys.com>
*
* 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">
<f:entry field="convertSidsToLowerCase">
<f:checkbox title="${%Convert all sids to lower-case during evaluation}" checked="${it.convertSidsToLowerCase}"/>
</f:entry>
</j:jelly>