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 editing credentials ID #502

Merged
merged 1 commit into from Jan 25, 2024

Conversation

yaroslavafenkin
Copy link
Contributor

https://issues.jenkins.io/browse/JENKINS-72611

Testing done

Tested interactively, made sure that two credentials cannot have the same ID.

Submitter checklist

Edit tasklist title
Beta Give feedback Tasklist Submitter checklist, more options

Delete tasklist

Delete tasklist block?
Are you sure? All relationships in this tasklist will be removed.
  1. Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
    Options
  2. Ensure that the pull request title represents the desired changelog entry
    Options
  3. Please describe what you did
    Options
  4. Link to relevant issues in GitHub or Jira
    Options
  5. Link to relevant pull requests, esp. upstream and downstream changes
    Options
  6. Ensure you have provided tests - that demonstrates feature works or fixes the issue
    Options

@@ -323,6 +323,14 @@ private synchronized boolean removeCredentials(@NonNull Domain domain, @NonNull
private synchronized boolean updateCredentials(@NonNull Domain domain, @NonNull Credentials current,
@NonNull Credentials replacement) throws IOException {
checkPermission(CredentialsProvider.UPDATE);

// See IdCredentials.Helper#equals.
Copy link
Member

Choose a reason for hiding this comment

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

FTR

/**
* The contract implementations of {@link #equals(Object)} and {@link #hashCode()} that implementations of
* this class must use as the basis for equality tests and as the hash code.
*
* @since 1.6
*/
final class Helpers {
/**
* Standard {@link #equals(Object)} implementation.
*
* @param self the {@code this} reference.
* @param o the other object.
* @return true if equal.
*/
public static boolean equals(IdCredentials self, Object o) {
if (self == o) {
return true;
}
if (!(o instanceof IdCredentials)) {
return false;
}
IdCredentials that = (IdCredentials) o;
return self.getId().equals(that.getId());
}
/**
* The standard {@link #hashCode()} implementation.
*
* @param self the {@code this} reference.
* @return the hash code.
*/
public static int hashCode(IdCredentials self) {
return self.getId().hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public final int hashCode() {
return IdCredentials.Helpers.hashCode(this);
}
/**
* {@inheritDoc}
*/
@Override
public final boolean equals(Object o) {
return IdCredentials.Helpers.equals(this, o);
}

@jglick jglick merged commit 9b88be1 into jenkinsci:master Jan 25, 2024
15 checks passed
@alecharp
Copy link
Member

Hello, this created a compatibility issue with plain-credentials plugin.
Since this was added, the BaseTest of plain-credentials are failing.


// See IdCredentials.Helper#equals.
// Note: We probably should not assume that all credentials are IdCredentials. We also do this a few lines below in list.indexOf(current) call.
// If this one breaks, that one breaks as well.
Copy link
Member

Choose a reason for hiding this comment

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

how so - the list is of type Credentials not IdCredentials so that would not break with a big bad angry jenkins.
At worst it would not find current, as the list would use equals and it is up to current credential may have been correctly obtained by it's name or otherwise in the code path.

@jtnord
Copy link
Member

jtnord commented Jan 26, 2024

indeed this causes regressions

->
image

failed to update a description of a credential. LoadFocus.com API key

@jglick
Copy link
Member

jglick commented Jan 26, 2024

@jtnord What concrete Credentials implementations are not instanceof IdCredentials? I was under the impression that was essentially impossible and it was only a technicality that getId had not been pushed up into Credentials itself. (How would you even select credentials without an id?)

the BaseTest of plain-credentials are failing

https://github.com/jenkinsci/plain-credentials-plugin/blob/ce8710821f17a043d91b448cf19b8568935d0167/src/test/java/org/jenkinsci/plugins/plaincredentials/BaseTest.java#L107? That just sounds like a meaningless test.

@jtnord
Copy link
Member

jtnord commented Jan 26, 2024

@jtnord What concrete Credentials implementations are not instanceof IdCredentials?

for example -> https://github.com/jenkinsci/loadfocus-jmeter-load-testing-integration-plugin/blob/d2d2af5b0af276932dfb6c8191d3bb13791d6bc7/src/main/java/com/loadfocus/jenkins/impl/LoadCredentialImpl.java there may be companies with other implementations.

I was under the impression that was essentially impossible

Nope this works :)

and it was only a technicality that getId had not been pushed up into Credentials itself. (How would you even select credentials without an id?)

while (result.containsKey("index-" + index)) {
index++;
}
id = "index-" + index;
index++;

you get a dummy ID based on the index in the list. For update and delete.
For usage you may be thinking too much about credentials-binding.

A plugin can perfectly ask for any credential of Type X for domain F and get the list CredentialsProvider.lookupCredentials and then do whatever it wants. (expect there is only one and use the first, or use a custom different method of identifying the suitable one, or just be truly random)

IDs are the future (or the now) but they are not /currently/ mandatory.

the BaseTest of plain-credentials are failing

https://github.com/jenkinsci/plain-credentials-plugin/blob/ce8710821f17a043d91b448cf19b8568935d0167/src/test/java/org/jenkinsci/plugins/plaincredentials/BaseTest.java#L107? That just sounds like a meaningless test.

@jglick
Copy link
Member

jglick commented Jan 26, 2024

Hmm https://github.com/jenkinsci/loadfocus-jmeter-load-testing-integration-plugin/blob/d2d2af5b0af276932dfb6c8191d3bb13791d6bc7/src/main/java/com/loadfocus/jenkins/LoadCredential.java#L13 looks like it was meant to extend IdCredentials. Is that the source of the screenshot above?

expect there is only one and use the first

Are there some examples of this? I can only think of cases where config includes a credentialsId.

🤷 anyway I guess it should be simple enough to fix things up to just ignore non-IdCredentials. Somewhere we should put a compile-time and/or runtime warning about these, because the intent was certainly for all implementations to be IdCredentials.

@jtnord
Copy link
Member

jtnord commented Jan 26, 2024

I guess it should be simple enough to fix things up to just ignore non-IdCredentials

yes - we only need to do the comparison if one or other of the credentials is an IDCredential.

Somewhere we should put a compile-time and/or runtime warning about these, because the intent was certainly for all implementations to be IdCredentials.

if we want to kill non ID based credentials and cleanup the code then I am ok with doing that in a PR that is clearly saying "remove support for obsolete implementations of Credentials" so long as it is just doing that, and we also fixup the knwon fallout (which is not huge but there is some).
I'm not ok with killing it by accident and without release notes or an upgrade path. FTR-> https://issues.jenkins.io/browse/JENKINS-72618 and https://issues.jenkins.io/browse/JENKINS-72617 for LoadCredential

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