-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Apply Maven SettingsDecrypter for encrypted server details #609
Conversation
if (problem.getSeverity() == SettingsProblem.Severity.ERROR | ||
|| problem.getSeverity() == SettingsProblem.Severity.FATAL) { | ||
throw new MojoExecutionException( | ||
"Unable to decrypt settings for " + registry + ": " + problem); |
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 "... decrypt password for ..." is more informative to actual users and has the potential to make them actions on their own.
Looks like you missed updating method call in BuildTarMojo to pass decrypter. But fixed that and built locally and confirm it does indeed decrypt and publish 🎉 |
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.
Nice! Just some small comments.
@@ -44,7 +44,6 @@ | |||
name = BuildDockerMojo.GOAL_NAME, | |||
requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM) | |||
public class BuildDockerMojo extends JibPluginConfiguration { | |||
|
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.
nit: a line removed (we're following a convention of empty line after class definition for this codebase)
@@ -164,6 +166,8 @@ void handleDeprecatedParameters(BuildLogger logger) { | |||
@Parameter(defaultValue = "${project.basedir}/src/main/jib", required = true) | |||
private String extraDirectory; | |||
|
|||
@Nullable @Component protected SettingsDecrypter settingsDecrypter; |
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.
Would this ever be null
?
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'm not sure. nullaway complains without it. I did some searching in the Maven docs but didn't find anything authoritative.
The Github Maven Plugins look up the SettingsDecrypter through the plexus container and guard against a ComponentLookupException
.
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.
Just a native question, is it possible fix encrypted passwords and plain passwords (for different servers) in settings.xml
? If that's true, I just want to make sure settingsDecrypter
handles plain passwords nicely. (I do believe it will.)
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.
Perhaps we should do that as well. The case we should guard against is if the user has an encrypted password and SettingsDecrypter
was null, there should be some error rather than trying to use the encrypted password and failing to authenticate (by which the user thinks the password is wrong but that's not the case)
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 @chanseokoh is asking about ~/.m2/settings.xml
having both encrypted and unencrypted passwords. The default SettingsDecryptor
passes-through unencrypted passwords.
The SettingsDecrypter
could theoretically be replaced. In the worse case, where the SettingsDecrypter
is null
but we have encrypted passwords, we will attempt to authenticate with the encrypted password bytes. But since it was encrypted we won't have divulged anything in the clear. There's no solid way to identity an encrypted vs unencrypted password though.
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.
Mmhmm, I was mostly trying to get at the user experience side, like:
- User sets encrypted password in Maven settings
- We try to decrypt, but
SettingsDecrypter
isnull
, so the password wasn't decrypted - Users sees
401 Unauthorized
and believes their password is wrong
Whereas, I think the better UX would be:
- User sets encrypted password in Maven settings
- We try to decrypt, but
SettingsDecrypter
isnull
, so the password wasn't decrypted, and we give an error - Users sees
failed to decrypt password
(or similar)
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.
The default encryption approach seems to surround the passwords with braces.
We could pass in the mavenBuildLogger
here and if settingsDecrypter == null
and the password starts and ends with braces then issue a warning.
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.
In MavenSettingsServerCredentials#retrieve
right? I might be misunderstanding how SettingsDecrypter
works, but is there any harm in giving the warning just if settingsDecrypter == null
?
} | ||
if (result.getServer() != null) { | ||
registryServer = result.getServer(); | ||
} |
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.
If it is null
, should we error?
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.
SettingsDecrypter
and SettingsDecryptionResult
are under-documented and does not discuss the possible meanings of the return results. SettingsDecryptionResult#getServers()
does note that:
/**
* Gets the decrypted servers.
*
* @return The decrypted server, can be empty but never {@code null}.
*/
List<Server> getServers();
and the implementation of getServer()
returns the first element from getServers()
and null
if there are no servers.
By this point, we have no errors reported from the decryption request, but we have no servers. So one interpretation is: no decryption was required, so use the original server.
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.
Makes sense! Let's maybe add a comment about the null
case meaning no decryption was required.
Just a note @briandealwis, according to Maven docs it is valid to put notes inside the password element, but outside the curly braces. So it is not a safe assumption that encrypted values will start with {
So you'd have to anticipate that in any 'is it encrypted' logic |
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.
Looks good! Just a style comment.
|
||
// pattern cribbed directly from | ||
// https://github.com/sonatype/plexus-cipher/blob/master/src/main/java/org/sonatype/plexus/components/cipher/DefaultPlexusCipher.java | ||
private static final Pattern ENCRYPTED_STRING_PATTERN = |
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.
In this codebase, we're following a convention of organizing classes in the order:
- static->non-static
- members->inner class->constructor->methods
- public->private
- final->nonfinal
So a ENCRYPTED_STRING_PATTERN
would be under CREDENTIAL_SOURCE
, isEncrypted
would be under ENCRYPTED_STRING_PATTERN
.
Oh I forgot to mention to include the CHANGELOG entry too. |
My assumption here is that a decryption error in
MavenSettingsServerCredentials
should fail the build rather than either return the still-encrypted password or returnnull
(i.e., no configured credentials).Unsure about
MavenSettingsServerCredentials
throwing aMojoExecutionException
directly, but it seemed unhelpful to create a new exception class that would be immediately turned into aMojoExecutionException
.Fixes #592