提交 55db82c0 编写于 作者: S Stephen Connolly

Allow control over the creation of different TopLevelItems from the ACL

上级 2dcc16e3
......@@ -31,6 +31,7 @@ import hudson.util.CopyOnWriteMap;
import hudson.util.Function1;
import hudson.util.IOUtils;
import jenkins.model.Jenkins;
import org.acegisecurity.AccessDeniedException;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
......@@ -258,12 +259,17 @@ public abstract class ItemGroupMixIn {
return (TopLevelItem) Items.load(parent, dir);
}
});
acl.getACL().checkCreatePermission(parent, result.getDescriptor());
add(result);
ItemListener.fireOnCreated(result);
Jenkins.getInstance().rebuildDependencyGraphAsync();
return result;
} catch (AccessDeniedException e) {
// if anything fails, delete the config file to avoid further confusion
Util.deleteRecursive(dir);
throw e;
} catch (IOException e) {
// if anything fails, delete the config file to avoid further confusion
Util.deleteRecursive(dir);
......@@ -274,6 +280,7 @@ public abstract class ItemGroupMixIn {
public synchronized TopLevelItem createProject( TopLevelItemDescriptor type, String name, boolean notify )
throws IOException {
acl.checkPermission(Item.CREATE);
acl.getACL().checkCreatePermission(parent, type);
Jenkins.getInstance().getProjectNamingStrategy().checkName(name);
if(parent.getItem(name)!=null)
......
......@@ -29,11 +29,14 @@ import hudson.Extension;
import hudson.XmlFile;
import hudson.model.listeners.ItemListener;
import hudson.remoting.Callable;
import hudson.security.ACL;
import hudson.security.AccessControlled;
import hudson.triggers.Trigger;
import hudson.util.DescriptorList;
import hudson.util.EditDistance;
import hudson.util.XStream2;
import jenkins.model.Jenkins;
import org.acegisecurity.Authentication;
import org.apache.commons.lang.StringUtils;
import java.io.File;
......@@ -112,6 +115,41 @@ public class Items {
return Jenkins.getInstance().<TopLevelItem,TopLevelItemDescriptor>getDescriptorList(TopLevelItem.class);
}
/**
* Returns all the registered {@link TopLevelItemDescriptor}s that the current security principle is allowed to
* create within the specified item group.
*
* @since 1.582
*/
public static List<TopLevelItemDescriptor> all(ItemGroup c) {
return all(Jenkins.getAuthentication(), c);
}
/**
* Returns all the registered {@link TopLevelItemDescriptor}s that the specified security principle is allowed to
* create within the specified item group.
*
* @since 1.582
*/
public static List<TopLevelItemDescriptor> all(Authentication a, ItemGroup c) {
List<TopLevelItemDescriptor> result = new ArrayList<TopLevelItemDescriptor>();
ACL acl;
if (c instanceof AccessControlled) {
acl = ((AccessControlled) c).getACL();
} else if (c instanceof Item) {
acl = ((Item) c).getACL();
} else {
// fall back to root
acl = Jenkins.getInstance().getACL();
}
for (TopLevelItemDescriptor d: all()) {
if (acl.hasCreatePermission(a, c, d) && d.isApplicableIn(c)) {
result.add(d);
}
}
return result;
}
public static TopLevelItemDescriptor getDescriptor(String fqcn) {
return Descriptor.find(all(), fqcn);
}
......
......@@ -61,6 +61,16 @@ public abstract class TopLevelItemDescriptor extends Descriptor<TopLevelItem> {
return true;
}
/**
* {@link TopLevelItemDescriptor}s often may want to limit the scope within which they can be created.
* This method allows the subtype of {@link TopLevelItemDescriptor}s to filter them out.
*
* @since 1.582
*/
public boolean isApplicableIn(ItemGroup parent) {
return true;
}
/**
* Tests if the given instance belongs to this descriptor, in the sense
* that this descriptor can produce items like the given one.
......
......@@ -25,6 +25,8 @@ package hudson.security;
import javax.annotation.Nonnull;
import hudson.remoting.Callable;
import hudson.model.ItemGroup;
import hudson.model.TopLevelItemDescriptor;
import jenkins.security.NonSerializableSecurityContext;
import jenkins.model.Jenkins;
import jenkins.security.NotReallyRoleSensitiveCallable;
......@@ -78,6 +80,44 @@ public abstract class ACL {
*/
public abstract boolean hasPermission(@Nonnull Authentication a, @Nonnull Permission permission);
/**
* Checks if the current security principal has the permission to create top level items within the specified item group.
* <p>
* Note that {@link #SYSTEM} can be passed in as the authentication parameter,
* in which case you should probably just assume it has can create anything.
* <p>
* This is just a convenience function.
* @param c the container of the item.
* @param d the descriptor of the item to be created.
* @throws AccessDeniedException
* if the user doesn't have the permission.
* @since 1.582
*/
public final void checkCreatePermission(@Nonnull ItemGroup c,
@Nonnull TopLevelItemDescriptor d) {
Authentication a = Jenkins.getAuthentication();
if (!hasCreatePermission(a, c, d)) {
throw new AccessDeniedException(Messages.AccessDeniedException2_MissingPermission(a.getName(),
"Item/CREATE/" + d.getDisplayName()));
}
}
/**
* Checks if the given principle has the permission to create top level items within the specified item group.
* <p>
* Note that {@link #SYSTEM} can be passed in as the authentication parameter,
* in which case you should probably just assume it has can create anything.
* @param a the principle.
* @param c the container of the item.
* @param d the descriptor of the item to be created.
* @return false
* if the user doesn't have the permission.
* @since 1.582
*/
public boolean hasCreatePermission(@Nonnull Authentication a, @Nonnull ItemGroup c,
@Nonnull TopLevelItemDescriptor d) {
return true;
}
//
// Sid constants
//
......
......@@ -31,7 +31,9 @@ THE SOFTWARE.
<l:layout norefresh="true" permission="${permission}" title="${%NewJob(it.newPronoun)}">
<st:include page="sidepanel.jelly" />
<l:main-panel>
<j:invokeStatic var="jobs" className="hudson.model.Items" method="all" />
<j:invokeStatic var="jobs" className="hudson.model.Items" method="all">
<j:arg type="hudson.model.ItemGroup" value="${it.ownerItemGroup}"/>
</j:invokeStatic>
<n:form nameTitle="${%JobName(it.newPronoun)}" copyTitle="${%CopyExisting(it.newPronoun)}" showCopyOption="${!empty(app.itemMap)}"
descriptors="${jobs}" checkUrl="${rootURL}/checkJobName" xmlns:n="/lib/hudson/newFromList" />
</l:main-panel>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册