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

Folder specific access rights #70

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -28,6 +28,7 @@
import com.synopsys.arc.jenkins.plugins.ownership.extensions.item_ownership_policy.AssignCreatorPolicy;
import com.synopsys.arc.jenkins.plugins.ownership.extensions.item_ownership_policy.DropOwnershipPolicy;
import com.synopsys.arc.jenkins.plugins.ownership.security.itemspecific.ItemSpecificSecurity;
import org.jenkinsci.plugins.ownership.security.folderspecific.FolderSpecificSecurity;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.ExtensionList;
import hudson.Plugin;
Expand Down Expand Up @@ -78,6 +79,7 @@ public class OwnershipPlugin extends Plugin {
private final List<OwnershipAction> pluginActions = new ArrayList<>();
public String mailResolverClassName;
private ItemSpecificSecurity defaultJobsSecurity;
private FolderSpecificSecurity defaultFoldersSecurity;
private OwnershipPluginConfiguration configuration;

/**
Expand All @@ -101,9 +103,9 @@ public static OwnershipPlugin getInstance() {

@Override
public void start() throws Exception {
load();
load();
reinitActionsList();
Jenkins.getActiveInstance().getActions().addAll(pluginActions);
Jenkins.getActiveInstance().getActions().addAll(pluginActions);
}

@Override
Expand Down Expand Up @@ -140,6 +142,11 @@ public ItemSpecificSecurity getDefaultJobsSecurity() {
return defaultJobsSecurity;
}

@CheckForNull
public FolderSpecificSecurity getDefaultFoldersSecurity() {
return defaultFoldersSecurity;
}

public OwnershipPluginConfiguration getConfiguration() {
return configuration;
}
Expand All @@ -153,6 +160,16 @@ public OwnershipPluginConfiguration getConfiguration() {
public ItemSpecificSecurity.ItemSpecificDescriptor getItemSpecificDescriptor() {
return ItemSpecificSecurity.DESCRIPTOR;
}

/**
* Gets descriptor of FolderSpecificProperty.
* Required for jelly.
* @return Descriptor
*/
@Nonnull
public FolderSpecificSecurity.FolderSpecificDescriptor getFolderSpecificDescriptor() {
return FolderSpecificSecurity.DESCRIPTOR;
}

/**
* {@link OwnershipPlugin} initialization for test suites.
Expand All @@ -162,23 +179,26 @@ public ItemSpecificSecurity.ItemSpecificDescriptor getItemSpecificDescriptor() {
* @param configuration
* @throws IOException
*/
public void configure(boolean requiresConfigureRights, String mailResolverClassName,
ItemSpecificSecurity defaultJobsSecurity,
public void configure(boolean requiresConfigureRights,
String mailResolverClassName,
ItemSpecificSecurity defaultJobsSecurity,
FolderSpecificSecurity defaultFoldersSecurity,
OwnershipPluginConfiguration configuration) throws IOException {
this.requiresConfigureRights = requiresConfigureRights;
this.mailResolverClassName = mailResolverClassName;
this.defaultJobsSecurity = defaultJobsSecurity;
this.defaultFoldersSecurity = defaultFoldersSecurity;
this.configuration = configuration;

reinitActionsList();
save();
save();
Jenkins.getActiveInstance().getActions().addAll(pluginActions);
}

@Override
public void configure(StaplerRequest req, JSONObject formData)
throws IOException, ServletException, Descriptor.FormException {
Jenkins.getActiveInstance().getActions().removeAll(pluginActions);
Jenkins.getActiveInstance().getActions().removeAll(pluginActions);
requiresConfigureRights = formData.getBoolean("requiresConfigureRights");

// Configurations
Expand All @@ -194,9 +214,13 @@ public void configure(StaplerRequest req, JSONObject formData)
if (formData.containsKey("defaultJobsSecurity")) {
this.defaultJobsSecurity = getItemSpecificDescriptor().newInstance(req, formData.getJSONObject("defaultJobsSecurity"));
}

if (formData.containsKey("defaultFoldersSecurity")) {
this.defaultFoldersSecurity = getFolderSpecificDescriptor().newInstance(req, formData.getJSONObject("defaultFoldersSecurity"));
}

reinitActionsList();
save();
save();
Jenkins.getActiveInstance().getActions().addAll(pluginActions);
}

Expand Down
Expand Up @@ -38,6 +38,7 @@
import hudson.model.Job;
import hudson.model.JobProperty;
import hudson.model.User;
import hudson.security.Permission;
import java.io.IOException;
import java.util.Collection;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -142,6 +143,18 @@ public OwnershipInfo getOwnershipInfo(Job<?, ?> job) {
return OwnershipInfo.DISABLED_INFO;
}

@Override
public boolean hasItemSpecificPermission(@Nonnull Job<?, ?> job, String sid, Permission p) {
JobOwnerJobProperty prop = getOwnerProperty(job);
if (prop != null) {
ItemSpecificSecurity sec = prop.getItemSpecificSecurity();
if (sec != null) {
return sec.getPermissionsMatrix().hasPermission(sid, p);
}
}
return false;
}

/**
* Sets the ownership information.
* @param job A job to be modified
Expand Down
Expand Up @@ -23,15 +23,13 @@
*/
package com.synopsys.arc.jenkins.plugins.ownership.security.rolestrategy;

import org.jenkinsci.plugins.ownership.model.OwnershipHelperLocator;
import com.synopsys.arc.jenkins.plugins.ownership.util.AbstractOwnershipHelper;
import com.synopsys.arc.jenkins.plugins.ownership.Messages;
import com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerHelper;
import com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerJobProperty;
import com.synopsys.arc.jenkins.plugins.ownership.security.itemspecific.ItemSpecificSecurity;
import com.synopsys.arc.jenkins.plugins.rolestrategy.Macro;
import com.synopsys.arc.jenkins.plugins.rolestrategy.RoleType;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.model.Job;
import hudson.security.AccessControlled;
import hudson.security.Permission;

Expand Down Expand Up @@ -61,19 +59,12 @@ public boolean IsApplicable(RoleType roleType) {

@Override
public boolean hasPermission(String sid, Permission p, RoleType type, AccessControlled item, Macro macro) {
if (type == RoleType.Project && item instanceof Job) {
Job prj = (Job)item;
JobOwnerJobProperty prop = JobOwnerHelper.getOwnerProperty(prj);

if (prop != null) {
ItemSpecificSecurity sec = prop.getItemSpecificSecurity();
if (sec != null) {
return sec.getPermissionsMatrix().hasPermission(sid, p);
}
if (type == RoleType.Project) {
AbstractOwnershipHelper helper = OwnershipHelperLocator.locate(item);
if (helper != null) {
return helper.hasItemSpecificPermission(item, sid, p);
}
}

return false;
}

}
Expand Up @@ -27,6 +27,7 @@
import com.synopsys.arc.jenkins.plugins.ownership.OwnershipDescription;
import com.synopsys.arc.jenkins.plugins.ownership.OwnershipPlugin;
import hudson.model.User;
import hudson.security.Permission;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -98,7 +99,7 @@ public boolean isDisplayOwnershipSummaryBox(@Nonnull TObjectType item) {

return true;
}

/**
* Gets ownership info of the requested item.
* @param item Item to be described
Expand All @@ -108,7 +109,11 @@ public boolean isDisplayOwnershipSummaryBox(@Nonnull TObjectType item) {
*/
@Nonnull
public abstract OwnershipInfo getOwnershipInfo(@Nonnull TObjectType item);


public boolean hasItemSpecificPermission(@Nonnull TObjectType item, String sid, Permission p) {
return false;
}

/**
* Gets permission required to manage ownership for the item.
* {@link Jenkins#ADMINISTER} by default if not overridden.
Expand Down
81 changes: 69 additions & 12 deletions src/main/java/org/jenkinsci/plugins/ownership/model/folders/FolderOwnershipAction.java 100644 → 100755
Expand Up @@ -29,10 +29,12 @@
import com.synopsys.arc.jenkins.plugins.ownership.OwnershipDescription;
import com.synopsys.arc.jenkins.plugins.ownership.OwnershipPlugin;
import com.synopsys.arc.jenkins.plugins.ownership.util.ui.OwnershipLayoutFormatter;
import org.jenkinsci.plugins.ownership.security.folderspecific.FolderSpecificSecurity;
import hudson.model.Descriptor;
import hudson.security.Permission;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.servlet.ServletException;
import net.sf.json.JSONObject;
Expand All @@ -48,14 +50,20 @@
*/
public class FolderOwnershipAction extends ItemOwnershipAction<AbstractFolder<?>> {

//TODO: May become a problem once we need to make it flexible (not implemented). Move to helper?
private static final OwnershipLayoutFormatter<AbstractFolder<?>> DEFAULT_FOLDER_FORMATTER
= new OwnershipLayoutFormatter.DefaultJobFormatter<>();

public FolderOwnershipAction(@Nonnull AbstractFolder<?> folder) {
super(folder);
}

@Nonnull
@Override
public IOwnershipHelper<AbstractFolder<?>> helper() {
return FolderOwnershipHelper.Instance;
}

public OwnershipLayoutFormatter<AbstractFolder<?>> getLayoutFormatter() {
return FolderOwnershipHelper.Instance.getLayoutFormatter();
}

@Override
public Permission getOwnerPermission() {
return OwnershipPlugin.MANAGE_ITEMS_OWNERSHIP;
Expand All @@ -67,17 +75,41 @@ public Permission getProjectSpecificPermission() {
}

@Override
public boolean actionIsAvailable() {
return getDescribedItem().hasPermission(OwnershipPlugin.MANAGE_ITEMS_OWNERSHIP);
public OwnershipDescription getOwnership() {
return FolderOwnershipHelper.Instance.getOwnershipDescription(getDescribedItem());
}

@Override
public IOwnershipHelper<AbstractFolder<?>> helper() {
return FolderOwnershipHelper.getInstance();

@CheckForNull
public FolderSpecificSecurity getItemSpecificSecurity() {
FolderOwnershipProperty prop = FolderOwnershipHelper.getOwnerProperty(getDescribedItem());
if (prop != null && prop.hasItemSpecificSecurity()) {
return prop.getItemSpecificSecurity();
}
return OwnershipPlugin.getInstance().getDefaultFoldersSecurity();
}

public OwnershipLayoutFormatter<AbstractFolder<?>> getLayoutFormatter() {
return DEFAULT_FOLDER_FORMATTER;
/**
* Checks if the described item has a folder-specific security defined.
* @return true if the item has a folder-specific security
* @since 0.3.1
*/
public boolean hasItemSpecificSecurity() {
FolderOwnershipProperty prop = FolderOwnershipHelper.getOwnerProperty(getDescribedItem());
return prop != null && prop.hasItemSpecificSecurity();
}

/**
* Gets descriptor of folder-specific security page.
* This method is being used by UI.
* @return A descriptor of {@link FolderSpecificSecurity}
*/
public FolderSpecificSecurity.FolderSpecificDescriptor getItemSpecificDescriptor() {
return FolderSpecificSecurity.DESCRIPTOR;
}

@Override
public boolean actionIsAvailable() {
return getDescribedItem().hasPermission(OwnershipPlugin.MANAGE_ITEMS_OWNERSHIP);
}

public HttpResponse doOwnersSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, UnsupportedEncodingException, ServletException, Descriptor.FormException {
Expand All @@ -89,4 +121,29 @@ public HttpResponse doOwnersSubmit(StaplerRequest req, StaplerResponse rsp) thro

return HttpResponses.redirectViaContextPath(getDescribedItem().getUrl());
}

public HttpResponse doProjectSpecificSecuritySubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
getDescribedItem().checkPermission(OwnershipPlugin.MANAGE_ITEMS_OWNERSHIP);
JSONObject form = req.getSubmittedForm();

if (form.containsKey("itemSpecificSecurity")) {
JSONObject jsonSpecificSecurity = req.getSubmittedForm().getJSONObject("itemSpecificSecurity");
FolderSpecificSecurity specific = FolderSpecificSecurity.DESCRIPTOR.newInstance(req, jsonSpecificSecurity);
FolderOwnershipHelper.setProjectSpecificSecurity(getDescribedItem(), specific);
} else { // drop security
FolderOwnershipHelper.setProjectSpecificSecurity(getDescribedItem(), null);
}

return HttpResponses.redirectViaContextPath(getDescribedItem().getUrl());
}

public HttpResponse doRestoreDefaultSpecificSecuritySubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException {
getDescribedItem().checkPermission(OwnershipPlugin.MANAGE_ITEMS_OWNERSHIP);
// Get default security
FolderSpecificSecurity defaultFoldersSecurity = OwnershipPlugin.getInstance().getDefaultFoldersSecurity();
FolderSpecificSecurity val = defaultFoldersSecurity != null ? defaultFoldersSecurity.clone() : null;

FolderOwnershipHelper.setProjectSpecificSecurity(getDescribedItem(), val);
return HttpResponses.redirectViaContextPath(getDescribedItem().getUrl());
}
}