Skip to content

Commit 9b01208

Browse files
authored
feature #913 Add support for SSO errors coming from the API (eiriksm)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- Hello, thanks for this! I just had a case where a token I used were throwing a runtimeexception because the org in question for the resource, had enforced SAML authentication. This was not something I could explicitly catch and do something with, so here is a PR fixing that. Thanks again, keep up the good work! Commits ------- eec78a7 Add support for SSO errors coming from the API 282fd58 Code style 9a9bec7 phpstan fixes 51b49cb Code style e566606 Add a test for sso required exception 4588ad5 Code style 54cf8f1 Code style
1 parent 307d74e commit 9b01208

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Github\Exception;
4+
5+
/**
6+
* SsoRequiredException.
7+
*/
8+
class SsoRequiredException extends RuntimeException
9+
{
10+
/** @var string */
11+
private $url;
12+
13+
/**
14+
* @param string $url
15+
* @param int $code
16+
* @param \Throwable|null $previous
17+
*/
18+
public function __construct($url, $code = 0, $previous = null)
19+
{
20+
$this->url = $url;
21+
22+
parent::__construct('Resource protected by organization SAML enforcement. You must grant your personal token access to this organization.', $code, $previous);
23+
}
24+
25+
/**
26+
* @return string
27+
*/
28+
public function getUrl()
29+
{
30+
return $this->url;
31+
}
32+
}

lib/Github/HttpClient/Plugin/GithubExceptionThrower.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Github\Exception\ApiLimitExceedException;
66
use Github\Exception\ErrorException;
77
use Github\Exception\RuntimeException;
8+
use Github\Exception\SsoRequiredException;
89
use Github\Exception\TwoFactorAuthenticationRequiredException;
910
use Github\Exception\ValidationFailedException;
1011
use Github\HttpClient\Message\ResponseMediator;
@@ -103,6 +104,16 @@ public function doHandleRequest(RequestInterface $request, callable $next, calla
103104
throw new RuntimeException(implode(', ', $errors), 502);
104105
}
105106

107+
if ((403 === $response->getStatusCode()) && $response->hasHeader('X-GitHub-SSO') && 0 === strpos((string) ResponseMediator::getHeader($response, 'X-GitHub-SSO'), 'required;')) {
108+
// The header will look something like this:
109+
// required; url=https://github.com/orgs/octodocs-test/sso?authorization_request=AZSCKtL4U8yX1H3sCQIVnVgmjmon5fWxks5YrqhJgah0b2tlbl9pZM4EuMz4
110+
// So we strip out the first 14 characters, leaving only the URL.
111+
// @see https://developer.github.com/v3/auth/#authenticating-for-saml-sso
112+
$url = substr((string) ResponseMediator::getHeader($response, 'X-GitHub-SSO'), 14);
113+
114+
throw new SsoRequiredException($url);
115+
}
116+
106117
throw new RuntimeException(isset($content['message']) ? $content['message'] : $content, $response->getStatusCode());
107118
});
108119
}

test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ public static function responseProvider()
136136
),
137137
'exception' => new \Github\Exception\RuntimeException('Something went wrong with executing your query', 502),
138138
],
139+
'Sso required Response' => [
140+
'response' => new Response(
141+
403,
142+
[
143+
'Content-Type' => 'application/json',
144+
'X-GitHub-SSO' => 'required; url=https://github.com/orgs/octodocs-test/sso?authorization_request=AZSCKtL4U8yX1H3sCQIVnVgmjmon5fWxks5YrqhJgah0b2tlbl9pZM4EuMz4',
145+
]
146+
),
147+
'exception' => new \Github\Exception\SsoRequiredException('https://github.com/orgs/octodocs-test/sso?authorization_request=AZSCKtL4U8yX1H3sCQIVnVgmjmon5fWxks5YrqhJgah0b2tlbl9pZM4EuMz4'),
148+
],
139149
'Default handling' => [
140150
'response' => new Response(
141151
555,

0 commit comments

Comments
 (0)