3131import com .cloudbees .plugins .credentials .CredentialsProvider ;
3232import com .cloudbees .plugins .credentials .common .StandardCredentials ;
3333import com .cloudbees .plugins .credentials .common .StandardListBoxModel ;
34- import com .cloudbees .plugins .credentials .common .StandardUsernameCredentials ;
3534import com .cloudbees .plugins .credentials .common .StandardUsernamePasswordCredentials ;
3635import com .cloudbees .plugins .credentials .domains .DomainRequirement ;
3736import com .cloudbees .plugins .credentials .domains .URIRequirementBuilder ;
5251import java .net .MalformedURLException ;
5352import java .net .Proxy ;
5453import java .net .URL ;
55- import java .util .HashMap ;
56- import java .util .Iterator ;
57- import java .util .List ;
58- import java .util .Map ;
59- import java .util .Random ;
60- import java .util .WeakHashMap ;
54+ import java .util .*;
6155import java .util .concurrent .TimeUnit ;
6256import java .util .logging .Level ;
6357import java .util .logging .Logger ;
6660import jenkins .model .Jenkins ;
6761import jenkins .scm .api .SCMSourceOwner ;
6862import org .apache .commons .lang .StringUtils ;
69- import org .jenkinsci .plugins .gitclient .GitClient ;
7063import org .jenkinsci .plugins .github .config .GitHubServerConfig ;
64+ import org .jenkinsci .plugins .plaincredentials .StringCredentials ;
7165import org .kohsuke .github .GHRateLimit ;
7266import org .kohsuke .github .GitHub ;
7367import org .kohsuke .github .GitHubBuilder ;
@@ -82,7 +76,7 @@ public class Connector {
8276
8377 private static final Map <Details , GitHub > githubs = new HashMap <>();
8478 private static final Map <GitHub , Integer > usage = new HashMap <>();
85- private static final Map <TaskListener , Map <GitHub ,Void >> checked = new WeakHashMap <>();
79+ private static final Map <TaskListener , Map <GitHub , Void >> checked = new WeakHashMap <>();
8680 private static final double MILLIS_PER_HOUR = TimeUnit .HOURS .toMillis (1 );
8781 private static final Random ENTROPY = new Random ();
8882 private static final String SALT = Long .toHexString (ENTROPY .nextLong ());
@@ -122,9 +116,9 @@ public static ListBoxModel listScanCredentials(@CheckForNull Item context, Strin
122116 ? Tasks .getDefaultAuthenticationOf ((Queue .Task ) context )
123117 : ACL .SYSTEM ,
124118 context ,
125- StandardUsernameCredentials .class ,
119+ StandardCredentials .class ,
126120 githubDomainRequirements (apiUri ),
127- githubScanCredentialsMatcher ()
121+ githubCredentialsMatcher ()
128122 );
129123 }
130124
@@ -158,7 +152,7 @@ public static FormValidation checkScanCredentials(@CheckForNull Item context, St
158152 if (!scanCredentialsId .isEmpty ()) {
159153 ListBoxModel options = listScanCredentials (context , apiUri );
160154 boolean found = false ;
161- for (ListBoxModel .Option b : options ) {
155+ for (ListBoxModel .Option b : options ) {
162156 if (scanCredentialsId .equals (b .value )) {
163157 found = true ;
164158 break ;
@@ -231,24 +225,23 @@ public static StandardCredentials lookupScanCredentials(@CheckForNull Item conte
231225 return null ;
232226 } else {
233227 return CredentialsMatchers .firstOrNull (
234- CredentialsProvider .lookupCredentials (
235- StandardUsernameCredentials .class ,
236- context ,
237- context instanceof Queue .Task
238- ? Tasks .getDefaultAuthenticationOf ((Queue .Task ) context )
239- : ACL .SYSTEM ,
240- githubDomainRequirements (apiUri )
241- ),
242- CredentialsMatchers .allOf (CredentialsMatchers .withId (scanCredentialsId ), githubScanCredentialsMatcher ())
228+ CredentialsProvider .lookupCredentials (
229+ StandardCredentials .class ,
230+ context ,
231+ context instanceof Queue .Task
232+ ? Tasks .getDefaultAuthenticationOf ((Queue .Task ) context )
233+ : ACL .SYSTEM ,
234+ githubDomainRequirements (apiUri )),
235+ CredentialsMatchers .allOf (CredentialsMatchers .withId (scanCredentialsId ), githubCredentialsMatcher ())
243236 );
244237 }
245238 }
246239
247240 /**
248241 * Retained for binary compatibility only.
249242 *
250- * @param context the context.
251- * @param apiUri the API endpoint.
243+ * @param context the context.
244+ * @param apiUri the API endpoint.
252245 * @return the {@link StandardCredentials} or {@code null}
253246 * @deprecated use {@link #listCheckoutCredentials(Item, String)}
254247 */
@@ -271,22 +264,25 @@ public static ListBoxModel listCheckoutCredentials(@CheckForNull Item context, S
271264 result .includeEmptyValue ();
272265 result .add ("- same as scan credentials -" , GitHubSCMSource .DescriptorImpl .SAME );
273266 result .add ("- anonymous -" , GitHubSCMSource .DescriptorImpl .ANONYMOUS );
274- return result .includeMatchingAs (
267+ result .includeMatchingAs (
275268 context instanceof Queue .Task
276269 ? Tasks .getDefaultAuthenticationOf ((Queue .Task ) context )
277270 : ACL .SYSTEM ,
278271 context ,
279- StandardUsernameCredentials .class ,
272+ StandardCredentials .class ,
280273 githubDomainRequirements (apiUri ),
281- GitClient . CREDENTIALS_MATCHER
274+ githubCredentialsMatcher ()
282275 );
276+ return result ;
283277 }
284278
285- public static @ Nonnull GitHub connect (@ CheckForNull String apiUri , @ CheckForNull StandardCredentials credentials ) throws IOException {
279+ public static @ Nonnull
280+ GitHub connect (@ CheckForNull String apiUri , @ CheckForNull StandardCredentials credentials ) throws IOException {
286281 String apiUrl = Util .fixEmptyAndTrim (apiUri );
287282 apiUrl = apiUrl != null ? apiUrl : GitHubServerConfig .GITHUB_URL ;
288- String username ;
289- String password ;
283+ String username = null ;
284+ String password = null ;
285+ String token = null ;
290286 String hash ;
291287 if (credentials == null ) {
292288 username = null ;
@@ -297,8 +293,10 @@ public static ListBoxModel listCheckoutCredentials(@CheckForNull Item context, S
297293 username = c .getUsername ();
298294 password = c .getPassword ().getPlainText ();
299295 hash = Util .getDigestOf (password + SALT ); // want to ensure pooling by credential
296+ } else if (credentials instanceof StringCredentials ) {
297+ token = ((StringCredentials ) credentials ).getSecret ().getPlainText ();
298+ hash = Util .getDigestOf (token + SALT );
300299 } else {
301- // TODO OAuth support
302300 throw new IOException ("Unsupported credential type: " + credentials .getClass ().getName ());
303301 }
304302 synchronized (githubs ) {
@@ -326,6 +324,8 @@ public static ListBoxModel listCheckoutCredentials(@CheckForNull Item context, S
326324
327325 if (username != null ) {
328326 gb .withPassword (username , password );
327+ } else if (token != null ) {
328+ gb .withOAuthToken (token );
329329 }
330330
331331 hub = gb .build ();
@@ -365,9 +365,11 @@ public static void release(@CheckForNull GitHub hub) {
365365 }
366366 }
367367
368- private static CredentialsMatcher githubScanCredentialsMatcher () {
369- // TODO OAuth credentials
370- return CredentialsMatchers .anyOf (CredentialsMatchers .instanceOf (StandardUsernamePasswordCredentials .class ));
368+ private static CredentialsMatcher githubCredentialsMatcher () {
369+ return CredentialsMatchers .anyOf (
370+ CredentialsMatchers .instanceOf (StandardUsernamePasswordCredentials .class ),
371+ CredentialsMatchers .instanceOf (StringCredentials .class )
372+ );
371373 }
372374
373375 static List <DomainRequirement > githubDomainRequirements (String apiUri ) {
@@ -378,7 +380,6 @@ static List<DomainRequirement> githubDomainRequirements(String apiUri) {
378380 * Uses proxy if configured on pluginManager/advanced page
379381 *
380382 * @param host GitHub's hostname to build proxy to
381- *
382383 * @return proxy to use it in connector. Should not be null as it can lead to unexpected behaviour
383384 */
384385 @ Nonnull
@@ -413,12 +414,13 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException {
413414
414415 };
415416
416- /*package*/ static void checkConnectionValidity (String apiUri , @ NonNull TaskListener listener ,
417- StandardCredentials credentials ,
418- GitHub github )
417+ /*package*/
418+ static void checkConnectionValidity (String apiUri , @ NonNull TaskListener listener ,
419+ StandardCredentials credentials ,
420+ GitHub github )
419421 throws IOException {
420422 synchronized (githubs ) {
421- Map <GitHub ,Void > hubs = checked .get (listener );
423+ Map <GitHub , Void > hubs = checked .get (listener );
422424 if (hubs != null && hubs .containsKey (github )) {
423425 // only check if not already in use
424426 return ;
@@ -439,8 +441,8 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException {
439441 listener .getLogger ().println (GitHubConsoleNote .create (
440442 System .currentTimeMillis (),
441443 String .format ("Connecting to %s using %s" ,
442- apiUri == null ? GitHubSCMSource .GITHUB_URL : apiUri ,
443- CredentialsNameProvider .name (credentials ))
444+ apiUri == null ? GitHubSCMSource .GITHUB_URL : apiUri ,
445+ CredentialsNameProvider .name (credentials ))
444446 ));
445447 } else {
446448 listener .getLogger ().println (GitHubConsoleNote .create (System .currentTimeMillis (), String .format (
@@ -472,7 +474,7 @@ static void checkApiRateLimit(@NonNull TaskListener listener, GitHub github)
472474 rateLimit .remaining , rateLimit .remaining - ideal , rateLimit .limit ,
473475 Util .getTimeSpanString (rateLimitResetMillis )
474476 )));
475- } else if (rateLimit .remaining < ideal ) {
477+ } else if (rateLimit .remaining < ideal ) {
476478 check = true ;
477479 final long expiration ;
478480 if (rateLimit .remaining < buffer ) {
0 commit comments