-
Notifications
You must be signed in to change notification settings - Fork 49
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
Use credentials plugin for managing authentication credentials #103
Use credentials plugin for managing authentication credentials #103
Conversation
I'd suggest adding the token bearer authentication in the same PR to reduce rework. |
*/ | ||
@DataBoundConstructor | ||
public ConfluenceSite(URL url, final String username, final String password) { | ||
LOGGER.log(Level.FINER, "ctor args: " + url + ", " + username + ", " + password); | ||
public ConfluenceSite(URL url, final String credentialsId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks binary compatibility.
I suggest you create a new constructor and remove @DataBoundConstructor
from this one mark this one deprecated.
So create a new constructor marked with @DataBoundConstructor
that takes no arguments and then create a @DataBoundSetter
for url
and credentialsId
See why here: https://www.jenkins.io/doc/developer/plugin-development/pipeline-integration/#constructor-vs-setters
/**
*
*
* @deprecated use {@link #new()} instead.
*/
@Deprecated
public ConfluenceSite(URL url, final String username, final String password) {
if (!url.toExternalForm().endsWith("/")) {
try {
url = new URL(url.toExternalForm() + "/");
} catch (MalformedURLException e) {
throw new AssertionError(e); // impossible
}
}
this.url = url;
this.username = hudson.Util.fixEmptyAndTrim(username);
this.password = Secret.fromString(password);
}
@DataBoundConstructor
public ConfluenceSite() {
}
/* ... you have these further below already */
@DataBoundSetter
public void setUrl(@CheckForNull URL url) {
this.url = Util.fixEmptyAndTrim(url);
}
@DataBoundSetter
public void setUrl(@CheckForNull String credentialsId) {
this.credentialsId = Util.fixEmptyAndTrim(credentialsId);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did most exactly that.
@Deprecated | ||
public String getUsername(){ | ||
return username; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setUsername(String username){ | ||
this.username = Util.fixEmptyAndTrim(username); | ||
} | ||
|
||
@Deprecated | ||
public Secret getPassword(){ | ||
return password; | ||
} | ||
|
||
@DataBoundSetter | ||
public void setPassword(Secret password) { | ||
this.password = password; | ||
} | ||
|
||
public void setPassword(String password) { | ||
this.password = Secret.fromString(password); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should add these as they would be considered obsolete and will be hard to remove once added.
Also they definitely should not have @DataBoundSetter
when transient.
@Deprecated | |
public String getUsername(){ | |
return username; | |
} | |
@DataBoundSetter | |
public void setUsername(String username){ | |
this.username = Util.fixEmptyAndTrim(username); | |
} | |
@Deprecated | |
public Secret getPassword(){ | |
return password; | |
} | |
@DataBoundSetter | |
public void setPassword(Secret password) { | |
this.password = password; | |
} | |
public void setPassword(String password) { | |
this.password = Secret.fromString(password); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I was under the impression those were needed for XML serialisation. But they are not.
URIRequirementBuilder.create().build()), | ||
CredentialsMatchers.withId(credentialsId)); | ||
if (credentials != null) { | ||
if (credentials instanceof UsernamePasswordCredentials) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the correct type is StandardUsernamePasswordCredentials
as it is the interface while UsernamePasswordCredentials
is the implementation as far as I recall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are both interfaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now using StandardUsernamePasswordCredentials anyway, to be consistent across all places where credentials are retrieved.
* Keep original constructor as depricated * Use StandardUsernamePasswordCredentials
I addressed your suggestions. More to come tomorrow. |
import hudson.util.Secret; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
||
public final class ConfluenceApiTokenImpl extends BaseStandardCredentials implements ConfluenceApiToken { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to implement our own credential implementation. I think we should just use StringCredentials 😓 Sorry I did not provide enough context.
Which you can get from depending on this plugin without a version since it is in the jenkins plugin BOM: https://plugins.jenkins.io/plain-credentials/ it is broadly installed.
https://github.com/search?q=plain-credentials+org%3Ajenkinsci&type=code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yeah thought about that.
I got my inspiration from the GitLab plugin which does both, implement its own type and support StringCredentials. And I thought "we don't need both", but apparently I chose the "wrong" one.
Should be easy to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For newer implementation I would stick to StringCredentials unless there was a different need for multiple different string typed credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor issue is the star imports. Once we fix those, this is ready.
import com.atlassian.confluence.rest.client.RestClientFactory; | ||
import com.atlassian.confluence.rest.client.authentication.AuthenticatedWebResourceProvider; | ||
import com.cloudbees.plugins.credentials.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would ask if you can undo the star imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
import hudson.model.Descriptor; | ||
import hudson.model.Hudson; | ||
import hudson.Util; | ||
import hudson.model.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@ccHanibal Did you have a chance to test the HPI and see if the token bearer worked? |
@jetersen Tested with my local build and with the v154 hpi. Also tested the automatic migration of username and password after upgrading. All looked good. |
Oh damn it. |
As discussed in #102 this PR makes the plugin use the credentials plugin for managing credentials to confluence sites.
Existing credentials are migrated automatically on jenkins launch.
Also it adds support for credentials in the form of an API token used with Bearer authentication.