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(), | ||||
); | ); | ||||
} | } | ||||
} | } |