diff --git a/src/main/java/org/kohsuke/github/GHOTPRequiredException.java b/src/main/java/org/kohsuke/github/GHOTPRequiredException.java new file mode 100644 index 000000000..757e3139f --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHOTPRequiredException.java @@ -0,0 +1,5 @@ +package org.kohsuke.github; + +public class GHOTPRequiredException extends GHIOException { +//... +} diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index b2a2a2f9b..c96173f71 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -758,8 +758,11 @@ class Requester { IOUtils.closeQuietly(es); } } - if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds - throw e; + if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 Unauthorized == bad creds + if(uc.getHeaderField("X-GitHub-OTP") != null) + throw (IOException) new GHOTPRequiredException().withResponseHeaderFields(uc).initCause(e); + else + throw e; // usually org.kohsuke.github.HttpException (which extends IOException) if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) { root.rateLimitHandler.onError(e,uc); diff --git a/src/test/java/org/kohsuke/github/Github2faTest.java b/src/test/java/org/kohsuke/github/Github2faTest.java index 5762d8cc4..8529a7cba 100644 --- a/src/test/java/org/kohsuke/github/Github2faTest.java +++ b/src/test/java/org/kohsuke/github/Github2faTest.java @@ -33,7 +33,7 @@ public class Github2faTest extends AbstractGitHubWireMockTest { GHAuthorization token=null; try { token = gitHub.createToken(asList, nameOfToken, "this is a test token created by a unit test"); - }catch (IOException ex) { + }catch (GHOTPRequiredException ex) { //ex.printStackTrace(); // under 2fa mode this exception is expected, and is necessary // as the exception is called, GitHub will generate and send an OTP to the users SMS