-
Notifications
You must be signed in to change notification settings - Fork 529
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-41348# BlueOcean specific CredentialsProvider #768
Conversation
Provides User store/scoped credentials by using appropriate properties on OrganizationFolder.
Gosh you're fast :) |
@stephenc PTAL, specially at BlueOceanCredentialsProvider.java |
@i386 its been bothering me, better to get it out of the way sooner than later:) We also need similar approach for git ssh keys - these are stored in system store. Will chat with @cliffmeyers tomorrow to get it wrapped with this PR. |
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.
Mostly OK as is, but i'd prefer if there were some changes.
* @author Stephen Connoly | ||
* @author Vivek Pandey | ||
*/ | ||
@Extension(optional = true) |
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.
Not an optional extension.
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 may need to specify an ordinal to ensure your priority is ahead of the standard stores
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.
ack.
*/ | ||
@Extension(optional = true) | ||
public class BlueOceanCredentialsProvider extends CredentialsProvider { | ||
private static final String DISPLAY_NAME = "BlueOcean Folder 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.
🐜 I18N this in a Messages
resource bundle
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.
yeah APIs have i18N missing, maybe good time to get started on it.
@Override | ||
public String getIconFileName() { | ||
return isVisible() | ||
? "/plugin/credentials/images/48x48/folder-store.png" |
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.
🐜 please use a Blue Ocean specific icon
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.
Hmm, I thought this is stock folder credential one and can be used for other CredentialsProvider extension. This is anyway read-only credential provider and is a proxy really. Not sure we really need an icon created for it. @i386?
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 stock icon is for the "stock" FolderCredentialsProvider from the folders plugin. You need your own so that a user/admin sees that the credentials are coming from this proxy/gateway provider
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.
Or if there is way to display name of 'store' in that table, strangely it shows name of the folder? In the image below, top item is added by blueocean and the next is by folder credential provider.
cc:@i386
@Override | ||
public List<Domain> getDomains() { | ||
//XXX: how to get domain from given Credentials object? Maybe attach domain name to AbstractFolder? | ||
return Collections.emptyList(); |
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.
Collections.singletonList(Domain.global())
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.
@stephenc Why global? The credentials it exposes are in user scope.
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.
actually what I see now is that you want something different, you want
Collections.singletonList(/*domain for "blueocean-github-domain"*/)
The domain is about matching the URL the credentials are requested for against the URLs that the credentials are allowed to be used against.
Scope is a different cross-cutting requirement
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 see. So it's more for routing to this proxy. I will give it a try.
|
||
@Override | ||
public boolean hasPermission(@Nonnull Authentication a, @Nonnull Permission permission) { | ||
return abstractFolder.getACL().hasPermission(a,permission); |
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.
may need to tweak this, but ok for now
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.
Do need to tweak this, as this is a read only domain we want to always return false for the Credentials/CREATE
, Credentials/DELETE
, Credentials/MANAGE_DOMAIN
and Credentials/UPDATE
permissions
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.
Agreed.
@Override | ||
public Set<CredentialsScope> getScopes(ModelObject object) { | ||
if(isApplicable(object)){ | ||
return ImmutableSet.of(CredentialsScope.USER); |
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.
Actually you are CredentailsScope.GLOBAL
if we are to be strictly correct... this may require changes in the credentials API to allow you to "clone" a credential while changing it's scope
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 provider is proxy exposing credentials from USER scope, for this reason I exposed it with USER scope. Exposing them with GLOBAL scope sounds incorrect to me.
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.
Because you are not using the authorise project plugin, the authentication will be ACL.SYSTEM so you want the scope GLOBAL as that allows the credential to be used by jobs running as SYSTEM or jobs running as an authentication with the USE_ITEM permission (limited to jobs in the org folder)
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.
@stephenc It seems to be working how it is, but I will change it to GLOBAL. All I am making sure is that its not less secure and these credentials do not get outside of the scope of the org folder they are attached to. Which I think is not the case.
Collections.<DomainRequirement>emptyList() | ||
), | ||
CredentialsMatchers.allOf(CredentialsMatchers.withId(prop.getId()), | ||
CredentialsMatchers.withScope(CredentialsScope.USER)) |
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 am now wondering if perhaps we shouldn't be more explicit and just target the credential stores scoped to the user and bypass the general lookupCredentials
, e.g.
for (CredentialStore store: CredentialsProvider.lookupStores(user)) {
// if store has credentials with id, return credential
}
// return empty list;
as matching based on scope here is ringing some alarm bells
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 can give it try, but I saw other places your concern about using USER scope as not a good idea. I guess I need to understand why this is not a good idea - this provider is really a locked down provider very specific to keys generated by blueocean in user store with USER scope.
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
/** | ||
* @author Vivek Pandey | ||
*/ | ||
public class GithubOrgFolderTest extends PipelineBaseTest { |
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.
Missing a test that the credential gets resolved, see this for inspiration but I do not thing you need to go quite so far as to actually trigger a build. I think you could get away with seeing if the credential can be looked up as SYSTEM using the standard credentials API when you add your property and if you remove the property the credential goes missing again, even though the credential is in "bob"'s user store
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.
Ok, will add a test.
Jenkins.getAuthentication(), | ||
URIRequirementBuilder.fromUri(uri).build()), | ||
CredentialsMatchers.allOf(CredentialsMatchers.withId(credentialId), | ||
CredentialsMatchers.withScope(CredentialsScope.USER)) |
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 is a bad smell, should not need to match based on scope
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.
Why is that? I want to keep it strict and if there is GitHub access key based credentials it better come from USER scope or we reject it.
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.
Still think this is a bad smell. Given that this credentials provider has very specific needs, I suspect we actually want to be directly checking the credential stores for the User
and not bothering with the scope check at all
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.
@stephenc Given I am going to be scanning in context of domain in user store, that is blueocean generated credentials are going to be created in user store in specific domain and searched accordingly, dropping USER scope is fine.
@vivek said:
If you need to handle ssh keys also then actually the |
|
||
public static class FolderPropertyImpl extends AbstractFolderProperty<AbstractFolder<TopLevelItem>> { | ||
private final String user; | ||
private final String id; |
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.
Sounds like you now need this to be a Collection<String>
(probably a Set
) rather than a single value
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.
@stephenc jenkins organization folder is either going to be setup by blueocean either using ssh credential(BasicSSHUserPrivateKey) or GitHub accesskey based credential (StandardUsernamePassword), not both. So why a collection?
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.
Well if doing checkout with ssh keys you will need both the api credentials for scan/index and the ssh key for checkout
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 don't necessarily need both. I can do MBP job creation only using my ssh key. https://gist.github.com/vivek/7a200b9cd6d645a78402b0ce5b1e56a8.
Our UI flow,
- For Git case, we let user create either api key or ssh keys. In case of git, its ssh, or access key (username/password) but not both.
- For GitHub, no ssh key, only GitHub accessKey.
It's looking good and definitely a better approach than stuffing the credentials into the global store, just some polish recommended before merging |
@stephenc applied your suggested changes, tests, i18n etc. except the one related to avoiding USER scope as I think this provider should continue doing it - more strict version of checks. If its a bad idea I want to know why. The other one was keeping an array of credential id - the thing is it's always going to be one credential attached to the org folder (GitHub/BitBucket) or multi-branch pipeline(git). |
…stem) Also refactored helper credential methods at one place.
@cliffmeyers git specific credential creation in user store and git pipeline creation with user store keys implementation is completed. PTAL. In general for this ticket, all cases have been covered. |
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.
Looking a lot better, but I think there are some things you will want to improve before merging
User authenticatedUser = User.current(); | ||
if(authenticatedUser == null){ | ||
throw new ServiceException.UnauthorizedException("Must login to create a pipeline"); | ||
} |
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 probably will need some additional checks here, such as:
- Did the system admin disable the per-user credentials store?
-
Did the system admin disable this Blue Ocean User Credentials Proxy/Gateway credential store
-
Did the system admin block storage of the credential type we need to store in the user credentials store
Probably not a blocker for merging this, but rather something you will need to be aware of and decide what you want to do about it and how to behave if the system admin has made configuration choices about credentials storage that prevent the blue ocean pipeline functionality from working
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.
Good point. I will open another ticket to get it addressed properly as it may need some UX change.
TopLevelItem item = create(Jenkins.getInstance(), getName(), MODE, MultiBranchProjectDescriptor.class); | ||
|
||
if (item instanceof WorkflowMultiBranchProject) { | ||
WorkflowMultiBranchProject project = (WorkflowMultiBranchProject) item; | ||
|
||
if(scmConfig.getCredentialId() != 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.
Safer to use StringUtils.isNotBlank(scmConfig.getCredentialId())
} | ||
|
||
//XXX: set credentialId to empty string if null or we get NPE later on | ||
String credentialId = scmConfig.getCredentialId() == null ? "" : scmConfig.getCredentialId(); |
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.
Or String credentialId = StringUtils.defaultString(scmConfig.getCredentialId())
User authenticatedUser = User.current(); | ||
if(authenticatedUser == null){ | ||
throw new ServiceException.UnauthorizedException("Must login to create a pipeline"); | ||
} |
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.
repeat of my comment w.r.t. the GitPipelineCreateRequest authorization check
|
||
if(githubCredential == null) { | ||
CredentialsUtils.createCredentialsInUserStore( | ||
credential, authenticatedUser, DOMAIN_NAME, new URI(getUri())); |
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.
Will the getUri()
return the GitHub Enterprise URL if the user is creating a pipeline against GHE?
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.
Yes.
@Override | ||
public List<Domain> getDomains() { | ||
//XXX: how to get domain from given Credentials object? Maybe attach domain name to AbstractFolder? | ||
return Collections.emptyList(); |
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.
actually what I see now is that you want something different, you want
Collections.singletonList(/*domain for "blueocean-github-domain"*/)
The domain is about matching the URL the credentials are requested for against the URLs that the credentials are allowed to be used against.
Scope is a different cross-cutting requirement
|
||
@Override | ||
public boolean hasPermission(@Nonnull Authentication a, @Nonnull Permission permission) { | ||
return abstractFolder.getACL().hasPermission(a,permission); |
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.
Do need to tweak this, as this is a read only domain we want to always return false for the Credentials/CREATE
, Credentials/DELETE
, Credentials/MANAGE_DOMAIN
and Credentials/UPDATE
permissions
@Nonnull | ||
@Override | ||
public List<Credentials> getCredentials(@Nonnull Domain domain) { | ||
return BlueOceanCredentialsProvider.getCredentials(Credentials.class, abstractFolder); |
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 (domain == /*domain for "blueocean-github-domain"*/) {
return BlueOceanCredentialsProvider.getCredentials(Credentials.class, abstractFolder);
}
return Collections.emptyList();
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.
@stephenc blueocean allowes credentials to be stored in different domain. For example GitHub credentials could be stored in different domain than git credentials.
@@ -32,6 +33,8 @@ | |||
|
|||
private final CredentialsStoreAction credentialStoreAction; | |||
private final Reachable parent; | |||
public static final String DOMAIN_NAME = "blueocean-domain"; |
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 is a different domain name from that used elsewhere
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.
@stephenc thats right, the way its is currently, GitHub credentials are stored in 'github-domain' got for git keys, UI/client can create credentials in domain of their choice. 'blueocean-domain' is default domain where they get saved. Is this problem?
} | ||
|
||
public static class FolderPropertyImpl extends AbstractFolderProperty<AbstractFolder<TopLevelItem>> { | ||
private final String user; |
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.
- Need a field to store the domain name(s) that this / these credentials are exposed through
- Need a field to store either the
DomainSpecification
or the URI (and instantiate the domain specification on demand)... my preference is to store theDomainSpecification
You also need to solve for the case of GitHub / BitBucket where there is the possibility of both scan credentials and checkout credentials... where you need the two different credentials, to further complicate matters the domain specifications for these will be different, e.g. the SSH key will need to match both the ssh
and git
protocols while the API token used for scanning will need to match http
and https
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 you meant DomainRequirement not DomainSpecification)
On further thought, this is not going to really work as the domain created is only once per user and its treated as storage of different credentials. I am going to skip enforcing domain specification checks. As long as domain in the user's store matches, we use it to access SCM.
All changes are as per discussion on PR
@stephenc I think I have got everything landed here. Last items DomainRequirement/DomainSpecification has been added. It also goes over user credential store with correct impersonation. PTAL so that we can proceed further. BlueOcean store specific icon is another item but it should not block this PR. |
That's why I gave it an 🐜 (which is more a niggle than a bug) :-D Will take a look later today |
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 really need to write the credentials plugin user / implementer and consumer guides
} | ||
return null; | ||
} | ||
|
||
static void validateCredentialId(String credentialId, OrganizationFolder item, GitHubSCMNavigator navigator) throws IOException { | ||
private String GithubCredentialsDomain(String apiUri) { |
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.
ugh... methods start with lowercase character
ErrorMessage.Error.ErrorCodes.INVALID.toString(), "Invalid github API URI: "+e.getMessage())), e); | ||
} | ||
String path = StringUtils.defaultIfBlank(uri.getPath(), "/"); | ||
boolean githubEnterprise = false; |
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.
unnecessary boolean
StandardUsernamePasswordCredentials usernamePasswordCredentials = (StandardUsernamePasswordCredentials) c; | ||
assertEquals(credential.getId(), usernamePasswordCredentials.getId()); | ||
assertEquals(credential.getPassword().getPlainText(),usernamePasswordCredentials.getPassword().getPlainText()); | ||
assertEquals(credential.getUsername(),usernamePasswordCredentials.getUsername()); |
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.
Missing a test where there is a credential with the same ID in the system store, verifying that your proxy store is a higher ordinal and hence will get asked first
public <C extends IdCredentials> ListBoxModel getCredentialIds(@Nonnull Class<C> type, | ||
@Nullable ItemGroup itemGroup, | ||
@Nullable Authentication authentication, | ||
@Nonnull List<DomainRequirement> domainRequirements, |
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 ACKed but did nothing in this method
public <C extends IdCredentials> ListBoxModel getCredentialIds(@Nonnull Class<C> type, | ||
@Nullable ItemGroup itemGroup, | ||
@Nullable Authentication authentication, | ||
@Nonnull List<DomainRequirement> domainRequirements, |
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.
and in fact you kind of got the idea backwards where you applied it in getCredentials
....
The DomainSpecification should be in the property so that you can only return the credential for usage against the GitHub server.
- User enters
https://github.com/jenkinsci/blueocean-plugin
as SCM URL - doFillScanCredentialsItems creates a domain requirements from that URL and asks for all appropriate credentials
- Your provider gets asked for credentials... you need to apply your property's
DomainSpecification
to see if this matches the domain that you are exposing the user's credentials as - Ok, so that matches, now we go and check the user store for credentials with ID (from property) and in a domain matching the
DomainRequirement
of theBlueOceanProxyDomainRequirement
You have done 4, you still need 3 or the users credentials will leak further than intended
|
||
@Override | ||
public boolean hasPermission(@Nonnull Authentication a, @Nonnull Permission permission) { | ||
// its read only so for all permissions other than READ, we return false |
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.
+1
return Result.POSITIVE; | ||
} | ||
} | ||
return Result.NEGATIVE; |
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.
FYI by returning NEGATIVE we prevent the credential from being visible to the user until they are searching with the BlueOceanDomainRequirement
. In other words, BlueOceanDomainRequirement
is MUST HAVE.
If you want the user to be able to use the credential in other contexts without the context being aware of your requirement then you may want to return UNKNOWN
.
@Override | ||
public Result test(@Nonnull DomainRequirement scope) { | ||
if(scope instanceof BlueOceanDomainRequirement){ | ||
if(((BlueOceanDomainRequirement)scope).getValue().equals(DOMAIN_SPECIFICATION)){ |
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.
Redundant test IIUC
public Result test(@Nonnull DomainRequirement scope) { | ||
if(scope instanceof BlueOceanDomainRequirement){ | ||
if(((BlueOceanDomainRequirement)scope).getValue().equals(DOMAIN_SPECIFICATION)){ | ||
return Result.POSITIVE; |
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.
Probably should be PARTIAL
} | ||
|
||
private static List<DomainSpecification> generateDomainSpecifications(@Nullable URI uri){ | ||
if (uri == 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.
@stephenc I think I have all in place. Give a bee if it all looks good, once its in place I can ask Cliff to give it a try before calling it done:)
|
@@ -28,6 +30,11 @@ public GithubEnterpriseScm(Reachable parent) { | |||
return super.getUri()+DEFAULT_ENTERPRISE_API_SUFFIX; | |||
} | |||
|
|||
@Override | |||
public String getCredentialDomainName() { | |||
return DOMAIN_NAME; |
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.
is this needed any more? AFAIK you can just store everything in a domain called blue-ocean-proxy
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.
better to keep these id's in their own domain, for example GitHub enterprise is in it's own domain so is consistent that way.
private static final String DEFAULT_ENTERPRISE_API_SUFFIX = "/api/v3"; | ||
private static final String ID = "github-enterprise"; | ||
static final String DEFAULT_ENTERPRISE_API_SUFFIX = "/api/v3"; | ||
static final String ID = "github-enterprise"; |
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 cannot see from the diff, but are you mixing the github enterprise hostname with the id in case the user has more than one GHE server (e.g. a test and prod 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.
Missed, that let me add that one.
ErrorMessage.Error.ErrorCodes.INVALID.toString(), | ||
"No domain in user credentials found for credentialId: "+ scmConfig.getCredentialId()))); | ||
} | ||
if(domain.test(new DomainRequirement())) { |
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 this is a bug, you should be testing against your BlueOceanDomainRequirement
not DomainRequirement
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.
yes it is, good catch.
} | ||
if(domain.test(new DomainRequirement())) { | ||
((OrganizationFolder) item) | ||
.addProperty( |
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.
does addProperty handle duplicates correctly?
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.
good point, will add validation of this.
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.
No duplicate test needed, this code creates a new org folder and is add property right after creation.
- Also enabled github api tests that gets run if GITHUB_ACCESS_TOKEN jvm property is provided
- github enterprise domain name has hostname suffix - Fixed correct domain requirement
…HUB_ACCESS_TOKEN=$YOUR_GITHUB_AACECSS_TOKEN
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 there are any other issues they can be handled as bugs after merging
@stephenc the one issue we should open is handling case where admin turns off access to user credential provider or disables storing credentials in these providers. and another one is BO provider icon. |
@vivek testing this on my end looks good. Proper access tokens appear to be used during both org scanning and branch scanning, and I've avoided any rate limit exceptions at least for the modest orgs I've been testing with. :) 🐝 |
Provides User store/scoped credentials by using appropriate properties
on OrganizationFolder.
Description
BlueOcean credentials provider is a proxy to credentials stored in user store.
This is how it works:
Changes to credential creation for git pipeline flow (for @cliffmeyers)
curl -v -XPOST -u admin:admin -H ‘content-type: application/json’ http://localhost:8080/jenkins/blue/rest/organizations/jenkins/credentials/user/
There are three changes:
See JENKINS-41348.
Submitter checklist
Reviewer checklist
@reviewbybees