Skip to content

Commit

Permalink
Fixes Jenkins.SYSTEM_READ support (#825)
Browse files Browse the repository at this point in the history
* Fixes Jenkins.SYSTEM_READ support

This fixes readonly configuration support by changing multiple checks to
Jenkins.ADMINISTER to first check Jenkins.SYSTEM_READ then return only
valuable information if user has Jenkins.ADMINISTER

* Convert more calls to check for SYSTEM_READ instead of ADMINISTER

SYSTEM_READ can list existing clouds and configuration, but should not
perform external calls (as the current value will be displayed anyway)
  • Loading branch information
Vlatombe committed Apr 3, 2023
1 parent 2965288 commit a7d2159
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 55 deletions.
31 changes: 16 additions & 15 deletions src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ public String getDisplayName() {

@POST
public FormValidation doCheckCloudName(@QueryParameter String value) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
return FormValidation.ok();
}
try {
Jenkins.checkGoodName(value);
} catch (Failure e) {
Expand Down Expand Up @@ -186,22 +188,21 @@ public ListBoxModel doFillRegionItems(
@QueryParameter String credentialsId)

throws IOException, ServletException {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);

ListBoxModel model = new ListBoxModel();

try {
AWSCredentialsProvider credentialsProvider = createCredentialsProvider(useInstanceProfileForCredentials,
credentialsId);
AmazonEC2 client = AmazonEC2Factory.getInstance().connect(credentialsProvider, determineEC2EndpointURL(altEC2Endpoint));
DescribeRegionsResult regions = client.describeRegions();
List<Region> regionList = regions.getRegions();
for (Region r : regionList) {
String name = r.getRegionName();
model.add(name, name);
if (Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
try {
AWSCredentialsProvider credentialsProvider = createCredentialsProvider(useInstanceProfileForCredentials,
credentialsId);
AmazonEC2 client = AmazonEC2Factory.getInstance().connect(credentialsProvider, determineEC2EndpointURL(altEC2Endpoint));
DescribeRegionsResult regions = client.describeRegions();
List<Region> regionList = regions.getRegions();
for (Region r : regionList) {
String name = r.getRegionName();
model.add(name, name);
}
} catch (SdkClientException ex) {
// Ignore, as this may happen before the credentials are specified
}
} catch (SdkClientException ex) {
// Ignore, as this may happen before the credentials are specified
}
return model;
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/hudson/plugins/ec2/EC2AbstractSlave.java
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,9 @@ public ListBoxModel doFillZoneItems(@QueryParameter boolean useInstanceProfileFo
@QueryParameter String region,
@QueryParameter String roleArn,
@QueryParameter String roleSessionName) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
return new ListBoxModel();
}
AWSCredentialsProvider credentialsProvider = EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId, roleArn, roleSessionName, region);
return fillZoneItems(credentialsProvider, region);
}
Expand Down
49 changes: 27 additions & 22 deletions src/main/java/hudson/plugins/ec2/EC2Cloud.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.cloudbees.plugins.credentials.CredentialsScope;
import com.cloudbees.plugins.credentials.CredentialsStore;
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
import com.cloudbees.plugins.credentials.common.AbstractIdCredentialsListBoxModel;
import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
import com.cloudbees.plugins.credentials.domains.Domain;
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
Expand Down Expand Up @@ -1086,34 +1087,35 @@ public InstanceType[] getInstanceTypes() {

@POST
public FormValidation doCheckUseInstanceProfileForCredentials(@QueryParameter boolean value) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (value) {
try {
new InstanceProfileCredentialsProvider(false).getCredentials();
} catch (AmazonClientException e) {
return FormValidation.error(Messages.EC2Cloud_FailedToObtainCredentialsFromEC2(), e.getMessage());
}
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER) || !value) {
return FormValidation.ok();
}
try {
new InstanceProfileCredentialsProvider(false).getCredentials();
return FormValidation.ok();
} catch (AmazonClientException e) {
return FormValidation.error(Messages.EC2Cloud_FailedToObtainCredentialsFromEC2(), e.getMessage());
}

return FormValidation.ok();
}

@POST
public ListBoxModel doFillSshKeysCredentialsIdItems(@AncestorInPath ItemGroup context, @QueryParameter String sshKeysCredentialsId) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);

StandardListBoxModel result = new StandardListBoxModel();

return result
.includeMatchingAs(Jenkins.getAuthentication(), context, SSHUserPrivateKey.class, Collections.<DomainRequirement>emptyList(), CredentialsMatchers.always())
.includeMatchingAs(ACL.SYSTEM, context, SSHUserPrivateKey.class, Collections.<DomainRequirement>emptyList(), CredentialsMatchers.always())
.includeCurrentValue(sshKeysCredentialsId);
AbstractIdCredentialsListBoxModel result = new StandardListBoxModel();
if (Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
result = result
.includeMatchingAs(Jenkins.getAuthentication(), context, SSHUserPrivateKey.class, Collections.<DomainRequirement>emptyList(), CredentialsMatchers.always())
.includeMatchingAs(ACL.SYSTEM, context, SSHUserPrivateKey.class, Collections.<DomainRequirement>emptyList(), CredentialsMatchers.always())
.includeCurrentValue(sshKeysCredentialsId);
}
return result;
}

@RequirePOST
public FormValidation doCheckSshKeysCredentialsId(@AncestorInPath ItemGroup context, @QueryParameter String value) throws IOException, ServletException {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);

if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
// Don't do anything if the user is only reading the configuration
return FormValidation.ok();
}
if (value == null || value.isEmpty()){
return FormValidation.error("No ssh credentials selected");
}
Expand Down Expand Up @@ -1163,9 +1165,10 @@ public FormValidation doCheckSshKeysCredentialsId(@AncestorInPath ItemGroup cont
@POST
protected FormValidation doTestConnection(@AncestorInPath ItemGroup context, URL ec2endpoint, boolean useInstanceProfileForCredentials, String credentialsId, String sshKeysCredentialsId, String roleArn, String roleSessionName, String region)
throws IOException, ServletException {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
return FormValidation.ok();
}
try {

SSHUserPrivateKey sshCredential = getSshCredential(sshKeysCredentialsId, context);
String privateKey = "";
if (sshCredential != null) {
Expand Down Expand Up @@ -1196,7 +1199,9 @@ protected FormValidation doTestConnection(@AncestorInPath ItemGroup context, URL

@RequirePOST
public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) {
return new StandardListBoxModel();
}
return new StandardListBoxModel()
.includeEmptyValue()
.includeMatchingAs(ACL.SYSTEM, context, AmazonWebServicesCredentials.class, Collections.emptyList(), CredentialsMatchers.always());
Expand Down
29 changes: 12 additions & 17 deletions src/main/java/hudson/plugins/ec2/EC2Step.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,25 @@ public String getDisplayName() {

@POST
public ListBoxModel doFillCloudItems() {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
Jenkins.get().checkPermission(Jenkins.SYSTEM_READ);
ListBoxModel r = new ListBoxModel();
r.add("", "");
Jenkins.CloudList clouds = jenkins.model.Jenkins.get().clouds;
for (Cloud cList : clouds) {
if (cList instanceof AmazonEC2Cloud) {
r.add(cList.getDisplayName(), cList.getDisplayName());
}
}
Jenkins.get().clouds
.getAll(AmazonEC2Cloud.class)
.forEach(c -> r.add(c.getDisplayName(), c.getDisplayName()));
return r;
}

@POST
public ListBoxModel doFillTemplateItems(@QueryParameter String cloud) {
Jenkins.get().checkPermission(Jenkins.ADMINISTER);
cloud = Util.fixEmpty(cloud);
public ListBoxModel doFillTemplateItems(@QueryParameter String cloudName) {
Jenkins.get().checkPermission(Jenkins.SYSTEM_READ);
ListBoxModel r = new ListBoxModel();
for (Cloud cList : jenkins.model.Jenkins.get().clouds) {
if (cList.getDisplayName().equals(cloud)) {
List<SlaveTemplate> templates = ((AmazonEC2Cloud) cList).getTemplates();
for (SlaveTemplate template : templates) {
for (String labelList : template.labels.split(" ")) {
r.add(labelList + " (AMI: " + template.getAmi() + ", REGION: " + ((AmazonEC2Cloud) cList).getRegion() + ", TYPE: " + template.type.name() + ")", labelList);
}
Cloud cloud = Jenkins.get().getCloud(Util.fixEmpty(cloudName));
if (cloud instanceof AmazonEC2Cloud) {
AmazonEC2Cloud ec2Cloud = (AmazonEC2Cloud) cloud;
for (SlaveTemplate template : ec2Cloud.getTemplates()) {
for (String labelList : template.labels.split(" ")) {
r.add(labelList + " (AMI: " + template.getAmi() + ", REGION: " + ec2Cloud.getRegion() + ", TYPE: " + template.type.name() + ")", labelList);
}
}
}
Expand Down

0 comments on commit a7d2159

Please sign in to comment.