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-72611] Forbid updating credentials ID for IdCredentials #506

Merged
merged 4 commits into from
Feb 12, 2024

Conversation

yaroslavafenkin
Copy link
Contributor

Another attempt at https://issues.jenkins.io/browse/JENKINS-72611 as #502 caused regressions.

Testing done

Tested interactively, made sure that two credentials cannot have the same ID. Tested interactively with credentials that are not IdCredentials (used this).

Submitter checklist

@yaroslavafenkin yaroslavafenkin requested a review from a team as a code owner January 29, 2024 12:53
@@ -325,6 +326,11 @@ private synchronized boolean updateCredentials(@NonNull Domain domain, @NonNull
checkPermission(CredentialsProvider.UPDATE);
Map<Domain, List<Credentials>> domainCredentialsMap = getDomainCredentialsMap();
if (domainCredentialsMap.containsKey(domain)) {
if (current instanceof IdCredentials && replacement instanceof IdCredentials) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unsure what makes more sense here AND or OR.

Copy link
Member

Choose a reason for hiding this comment

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

depends if we should be able to replace an IdCredential with a non IdCredential
To me adding or removing an ID (replacing an IdCredential with a non IdCredential or vice versa) would sound like a change in the actual Id so OR would make sense.

Any migration from a non IdCredential to IdCredential should occur seemlessly in data migration based on readResolve generating a unique Id on load, and hence this method should not have to worry about that.

But I think either AND or OR is acceptable here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would like to have more opinions here. Maybe @jglick or @daniel-beck ?

Copy link
Member

Choose a reason for hiding this comment

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

Tentatively would prefer || for the same reasons as James argues for it.

@jtnord jtnord requested a review from a team January 29, 2024 14:16
@jtnord
Copy link
Member

jtnord commented Jan 29, 2024

(waiting for resolution of #506 (comment) before merging)

@@ -35,15 +34,19 @@
/**
* A test credentials impl.
*/
public class DummyCredentials extends BaseCredentials implements UsernamePasswordCredentials {
public class DummyCredentials extends BaseStandardCredentials implements UsernamePasswordCredentials {

private final String username;

private final Secret password;

@DataBoundConstructor
Copy link
Member

Choose a reason for hiding this comment

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

Should the old constructor remain the DataBoundConstructor or should that move to the new one? Do we have UI tests that even use this? Should a null ID be a problem?

Copy link
Member

@jtnord jtnord Jan 31, 2024

Choose a reason for hiding this comment

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

Do we have UI tests that even use this

there's a jelly file at least so at some point in time Stephen went to the effort of ensuring the UI at least worked...

<st:include page="id-and-description" class="${descriptor.clazz}"/>

Should a null ID be a problem?

Shouldn;t be as BaseStandardCredentials will generate a uniqueID if null (so long as not one is expecting anything stable here!).

public BaseStandardCredentials(@CheckForNull String id, @CheckForNull String description) {
super();
this.id = IdCredentials.Helpers.fixEmptyId(id);
this.description = Util.fixNull(description);
}

public static String fixEmptyId(@CheckForNull String id) {
return StringUtils.isEmpty(id) ? UUID.randomUUID().toString() : id;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just found out that https://github.com/jenkinsci/credentials-plugin/blob/master/src/test/java/com/cloudbees/plugins/credentials/impl/DummyIdCredentials.java exists. I'll revert the change here and only adapt affected tests to use DummyIdCredentials.java

@@ -457,4 +458,14 @@ public void credentialsSortedByNameInUI() {
assertThat(options.get(0).value, is("2"));
assertThat(options.get(1).value, is("1"));
}

@Test
@Issue("SECURITY-3252")
Copy link
Member

Choose a reason for hiding this comment

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

wrong reference?

Suggested change
@Issue("SECURITY-3252")
@Issue("JENKINS-72611")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, updated in eb2d6ca

@jtnord jtnord enabled auto-merge February 1, 2024 14:37
@jtnord jtnord merged commit e7f2f06 into jenkinsci:master Feb 12, 2024
15 checks passed
@basil
Copy link
Member

basil commented Mar 2, 2024

[ERROR] Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 4.531 s <<< FAILURE! -- in org.jenkinsci.plugins.plaincredentials.BaseTest
[ERROR] org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileBaseTestWithDeprecatedCtor -- Time elapsed: 4.192 s <<< ERROR!
java.lang.IllegalArgumentException: Credentials' IDs do not match, will not update.
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider.updateCredentials(SystemCredentialsProvider.java:331)
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider$StoreImpl.updateCredentials(SystemCredentialsProvider.java:573)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.testCreateUpdateDelete(BaseTest.java:102)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileTest(BaseTest.java:79)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileBaseTestWithDeprecatedCtor(BaseTest.java:64)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:656)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base/java.lang.Thread.run(Thread.java:1583)

[ERROR] org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileBaseTest -- Time elapsed: 0.170 s <<< ERROR!
java.lang.IllegalArgumentException: Credentials' IDs do not match, will not update.
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider.updateCredentials(SystemCredentialsProvider.java:331)
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider$StoreImpl.updateCredentials(SystemCredentialsProvider.java:573)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.testCreateUpdateDelete(BaseTest.java:102)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileTest(BaseTest.java:79)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.secretFileBaseTest(BaseTest.java:59)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:656)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base/java.lang.Thread.run(Thread.java:1583)

[ERROR] org.jenkinsci.plugins.plaincredentials.BaseTest.secretTextBaseTest -- Time elapsed: 0.159 s <<< ERROR!
java.lang.IllegalArgumentException: Credentials' IDs do not match, will not update.
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider.updateCredentials(SystemCredentialsProvider.java:331)
        at com.cloudbees.plugins.credentials.SystemCredentialsProvider$StoreImpl.updateCredentials(SystemCredentialsProvider.java:573)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.testCreateUpdateDelete(BaseTest.java:102)
        at org.jenkinsci.plugins.plaincredentials.BaseTest.secretTextBaseTest(BaseTest.java:54)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.jvnet.hudson.test.JenkinsRule$1.evaluate(JenkinsRule.java:656)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
        at java.base/java.lang.Thread.run(Thread.java:1583)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants