Browse Source

Intercept auth rejections requiring an OTP token

Chris Smith 11 years ago
parent
commit
be5e4b1589
1 changed files with 28 additions and 0 deletions
  1. 28 0
      src/Composer/Util/GitHub.php

+ 28 - 0
src/Composer/Util/GitHub.php

@@ -111,6 +111,34 @@ class GitHub
                 )));
             } catch (TransportException $e) {
                 if (in_array($e->getCode(), array(403, 401))) {
+                    // 401 when authentication was supplied, handle 2FA if required.
+                    if ($this->io->hasAuthentication($originUrl)) {
+                        $headerNames = array_map(function($header) {
+                            return strstr($header, ':', true);
+                        }, $e->getHeaders());
+
+                        if ($key = array_search('X-GitHub-OTP', $headerNames)) {
+                            $headers = $e->getHeaders();
+                            list($required, $method) = array_map('trim', explode(';', substr(strstr($headers[$key], ':'), 1)));
+
+                            if ('required' === $required) {
+                                $this->io->write('Two-factor Authentication');
+
+                                if ('app' === $method) {
+                                    $this->io->write('Open the two-factor authentication app on your device to view your authentication code and verify your identity.');
+                                }
+
+                                if ('sms' === $method) {
+                                    // @todo
+                                }
+
+                                $otp = $this->io->ask('Authentication Code: ');
+
+                                continue;
+                            }
+                        }
+                    }
+
                     $this->io->write('Invalid credentials.');
                     continue;
                 }