Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/factor/PhabricatorTOTPAuthFactor.php
| Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | public function processAddFactorForm( | ||||
| $uri = urisprintf( | $uri = urisprintf( | ||||
| 'otpauth://totp/%s:%s?secret=%s&issuer=%s', | 'otpauth://totp/%s:%s?secret=%s&issuer=%s', | ||||
| $issuer, | $issuer, | ||||
| $user->getUsername(), | $user->getUsername(), | ||||
| $secret, | $secret, | ||||
| $issuer); | $issuer); | ||||
| $qrcode = $this->renderQRCode($uri); | $qrcode = $this->newQRCode($uri); | ||||
| $form->appendChild($qrcode); | $form->appendChild($qrcode); | ||||
| $form->appendChild( | $form->appendChild( | ||||
| id(new AphrontFormStaticControl()) | id(new AphrontFormStaticControl()) | ||||
| ->setLabel(pht('Key')) | ->setLabel(pht('Key')) | ||||
| ->setValue(phutil_tag('strong', array(), $secret))); | ->setValue(phutil_tag('strong', array(), $secret))); | ||||
| $form->appendInstructions( | $form->appendInstructions( | ||||
| ▲ Show 20 Lines • Show All 283 Lines • ▼ Show 20 Lines | $code = ((ord($hash[$offset + 0]) & 0x7F) << 24) | | ||||
| ((ord($hash[$offset + 3]) ) ); | ((ord($hash[$offset + 3]) ) ); | ||||
| $code = ($code % 1000000); | $code = ($code % 1000000); | ||||
| $code = str_pad($code, 6, '0', STR_PAD_LEFT); | $code = str_pad($code, 6, '0', STR_PAD_LEFT); | ||||
| return $code; | return $code; | ||||
| } | } | ||||
| /** | |||||
| * @phutil-external-symbol class QRcode | |||||
| */ | |||||
| private function renderQRCode($uri) { | |||||
| $root = dirname(phutil_get_library_root('phabricator')); | |||||
| require_once $root.'/externals/phpqrcode/phpqrcode.php'; | |||||
| $lines = QRcode::text($uri); | |||||
| $total_width = 240; | |||||
| $cell_size = floor($total_width / count($lines)); | |||||
| $rows = array(); | |||||
| foreach ($lines as $line) { | |||||
| $cells = array(); | |||||
| for ($ii = 0; $ii < strlen($line); $ii++) { | |||||
| if ($line[$ii] == '1') { | |||||
| $color = '#000'; | |||||
| } else { | |||||
| $color = '#fff'; | |||||
| } | |||||
| $cells[] = phutil_tag( | |||||
| 'td', | |||||
| array( | |||||
| 'width' => $cell_size, | |||||
| 'height' => $cell_size, | |||||
| 'style' => 'background: '.$color, | |||||
| ), | |||||
| ''); | |||||
| } | |||||
| $rows[] = phutil_tag('tr', array(), $cells); | |||||
| } | |||||
| return phutil_tag( | |||||
| 'table', | |||||
| array( | |||||
| 'style' => 'margin: 24px auto;', | |||||
| ), | |||||
| $rows); | |||||
| } | |||||
| private function getTimestepDuration() { | private function getTimestepDuration() { | ||||
| return 30; | return 30; | ||||
| } | } | ||||
| private function getCurrentTimestep() { | private function getCurrentTimestep() { | ||||
| $duration = $this->getTimestepDuration(); | $duration = $this->getTimestepDuration(); | ||||
| return (int)(PhabricatorTime::getNow() / $duration); | return (int)(PhabricatorTime::getNow() / $duration); | ||||
| } | } | ||||
| Show All 21 Lines | foreach ($timesteps as $timestep) { | ||||
| if (phutil_hashes_are_identical($code, $expect_code)) { | if (phutil_hashes_are_identical($code, $expect_code)) { | ||||
| return $timestep; | return $timestep; | ||||
| } | } | ||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| private function getChallengeResponseParameterName( | |||||
| PhabricatorAuthFactorConfig $config) { | |||||
| return $this->getParameterName($config, 'totpcode'); | |||||
| } | |||||
| private function getChallengeResponseFromRequest( | |||||
| PhabricatorAuthFactorConfig $config, | |||||
| AphrontRequest $request) { | |||||
| $name = $this->getChallengeResponseParameterName($config); | |||||
| $value = $request->getStr($name); | |||||
| $value = (string)$value; | |||||
| $value = trim($value); | |||||
| return $value; | |||||
| } | |||||
| protected function newMFASyncTokenProperties(PhabricatorUser $user) { | protected function newMFASyncTokenProperties(PhabricatorUser $user) { | ||||
| return array( | return array( | ||||
| 'secret' => self::generateNewTOTPKey(), | 'secret' => self::generateNewTOTPKey(), | ||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||