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

Added Github App Credentials support #87

Closed

Conversation

jon-schuck-MA
Copy link

@jon-schuck-MA jon-schuck-MA commented Mar 5, 2021

I added support for Github App Credentials from the github-branch-source plugin. The github-branch-source plugin is optional and the credentials will only will be created when the plugin is installed.

  • [X ] Make sure you are opening from a topic/feature/bugfix branch (right side) and not your master branch!
  • [X ] Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

}

try {
Class githubCredentials = Class.forName("org.jenkinsci.plugins.github_branch_source.GitHubAppCredentials");
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you point to other examples of credentials being constructed using reflection, if there are examples out there? Obviously anything using reflection warrants scrutiny, so I'd feel more comfortable about this if I can see that a pattern is being followed.

Copy link
Author

@jon-schuck-MA jon-schuck-MA Mar 10, 2021

Choose a reason for hiding this comment

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

Hi Chris, I wanted to use reflection to have a weak dependency on the github-branch-source plugin and avoid forcing the user to install two plugins. Here is an example of another plugin interacting with github-branch-source

pipeline-model-definition-plugin
pipeline-model-definition-plugin

Copy link
Contributor

Choose a reason for hiding this comment

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

I remembered that Jenkins also has an idiomatic way of using optional dependencies in code the straightforward way - without reflection - where you put the @Extension(optional = true) annotation on the classes that use the optional dependencies. This suppresses the ClassNotFound errors when that class is loaded and the dependency plugin is not present on the system. If you can find the right place to add this annotation I think it would be an improvement on the reflection approach.

Example here: 06ad79e#diff-2a94427d0a60f95532b13490458755d1ef9201c662e932df503ac6014f1fd3a9R27

Copy link
Author

Choose a reason for hiding this comment

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

Ok, I moved the GithubCredentialsFactory into it a new class that uses @extension(optional = true). I Also created a test that mimics StandardUsernamePasswordCredentialsIT. I can't test the password retrieval because the GithbAppCredentials uses api.github.com/app inside the method, because I was able to add tests for the functionality that doesn't use the password.

@chriskilding
Copy link
Contributor

Like the idea and always happy to add new credential types, providing the optional dependency mechanism can be solved.

Would you be able to add an integration test suite along the lines of https://github.com/jenkinsci/aws-secrets-manager-credentials-provider-plugin/blob/master/src/test/java/io/jenkins/plugins/credentials/secretsmanager/StandardUsernamePasswordCredentialsIT.java for the new credential type?

@chriskilding
Copy link
Contributor

Hmm, good catch that it's making a call out to api.github.com. Gonna have to find some way to mock or stub that in the tests. Are there any good JUnit GitHub API mocks out there?

.around(secretsManager);

@BeforeClass
public static void GitHubAppCredentialsExists() {

Choose a reason for hiding this comment

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

I detect that this code is problematic. According to the Bad practice (BAD_PRACTICE), Nm: Method names should start with a lower case letter (NM_METHOD_NAMING_CONVENTION).
Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

Copy link
Author

Choose a reason for hiding this comment

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

I mocked the getPassword method to run the test. I couldn't find anything that already exists for Github Api though.

Choose a reason for hiding this comment

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

It is code-style advice.

@chriskilding
Copy link
Contributor

The stub of getPassword() looks alright 👍

@jon-schuck-MA
Copy link
Author

Is there something else I need to add?

// Then
assertThat(after)
.hasUsername(before.getUsername())
.hasId(before.getId());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you test the retrieval of the password / secret field? We need this to ensure that snapshotting of the secret value works correctly, which is necessary for distributed Jenkins setups. You might need to write a custom AssertJ matcher, see these classes for examples:

Copy link
Author

Choose a reason for hiding this comment

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

Ok, I added a new Assert for GithubAppCredentials, and we can test the private key with the snapshot now.

Copy link
Author

Choose a reason for hiding this comment

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

Is there anything else that needs to be added?

@chriskilding
Copy link
Contributor

FYI all the builds are failing at the moment because some of the existing credential type tests - somehow - use the PBEWithSHA1AndDESede algorithm (which I guess is coming from some library code, maybe in Bouncycastle). OpenJDK 8u292 removed the PBEWithSHA1AndDESede algorithm (https://bugs.openjdk.java.net/browse/JDK-8266261). This was a bug and they will add it back to the next OpenJDK release. Then the tests should pass again.

@cyrilgdn
Copy link

Hi,
Any chance to get this feature released 🙏 ?

@trispad
Copy link

trispad commented Mar 3, 2022

@jon-schuck-MA any chance of taking this to done?

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.

None yet

5 participants