public function __construct($status_code, $body, array $headers, $expect = null)
 {
     // NOTE: Avoiding PhutilUTF8StringTruncator here because this isn't lazy
     // and responses may be large.
     if (strlen($body) > 512) {
         $excerpt = substr($body, 0, 512) . '...';
     } else {
         $excerpt = $body;
     }
     $content_type = BaseHTTPFuture::getHeader($headers, 'Content-Type');
     $match = null;
     if (preg_match('/;\\s*charset=([^;]+)/', $content_type, $match)) {
         $encoding = trim($match[1], "\"'");
         try {
             $excerpt = phutil_utf8_convert($excerpt, 'UTF-8', $encoding);
         } catch (Exception $ex) {
         }
     }
     $this->excerpt = phutil_utf8ize($excerpt);
     $this->expect = $expect;
     parent::__construct($status_code);
 }
 private function verifyRemotePermissions($viewer, $revision, $repository)
 {
     $github_user = $this->account->getUsername();
     $github_repo = $this->findGitHubRepo($repository);
     $uri = urisprintf('https://api.github.com/repos/%s/collaborators/%s', $github_repo, $github_user);
     $uri = new PhutilURI($uri);
     $uri->setQueryParam('access_token', $this->getAccessToken());
     list($status, $body, $headers) = id(new HTTPSFuture($uri))->resolve();
     // Likely status codes:
     // 204 No Content: Has permissions. Token might be too weak.
     // 404 Not Found: Not a collaborator.
     // 401 Unauthorized: Token is bad/revoked.
     $no_permission = $status->getStatusCode() == 404;
     if ($no_permission) {
         throw new Exception(pht("You don't have permission to push to this repository. " . "Push permissions for this repository are managed on GitHub."));
     }
     $scopes = BaseHTTPFuture::getHeader($headers, 'X-OAuth-Scopes');
     if (strpos($scopes, 'public_repo') === false) {
         $provider_key = $this->provider->getProviderKey();
         $refresh_token_uri = new PhutilURI("/auth/refresh/{$provider_key}/");
         $refresh_token_uri->setQueryParam('scope', 'public_repo');
         return id(new AphrontDialogView())->setUser($viewer)->setTitle(pht('Stronger token needed'))->appendChild(pht('In order to complete this action, you need a ' . 'stronger GitHub token.'))->setSubmitURI($refresh_token_uri)->addCancelButton('/D' . $revision->getId())->setDisableWorkflowOnSubmit(true)->addSubmitButton(pht('Refresh Account Link'));
     }
 }