@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve handling of "Deny" responses from Duo

Summary:
Ref T13231. See <https://discourse.phabricator-community.org/t/duo-integration-crashes-if-user-is-not-enrolled-and-enrollment-is-disabled/2340/5>

(There's an actual bug here, although I'm not sure exactly what's going on on the Duo side in the report.)

Test Plan:
To reproduce this, I was only able to actually "Deny" my account explicitly in Duo.

- With "Deny", tried to add a factor. Got a nice helpful error message.
- Undenied, added a factor, re-denied, tried to pass an MFA gate. Got another nice helpful error message.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13231

Differential Revision: https://secure.phabricator.com/D20065

+27 -5
+11 -3
src/applications/auth/factor/PhabricatorAuthFactor.php
··· 147 147 $viewer, 148 148 $challenges); 149 149 150 - if ($new_challenges instanceof PhabricatorAuthFactorResult) { 150 + if ($this->isAuthResult($new_challenges)) { 151 151 unset($unguarded); 152 152 return $new_challenges; 153 153 } ··· 200 200 return $result; 201 201 } 202 202 203 - if (!($result instanceof PhabricatorAuthFactorResult)) { 203 + if (!$this->isAuthResult($result)) { 204 204 throw new Exception( 205 205 pht( 206 206 'Expected "newResultFromIssuedChallenges()" to return null or '. ··· 232 232 $request, 233 233 $challenges); 234 234 235 - if (!($result instanceof PhabricatorAuthFactorResult)) { 235 + if (!$this->isAuthResult($result)) { 236 236 throw new Exception( 237 237 pht( 238 238 'Expected "newResultFromChallengeResponse()" to return an object '. ··· 408 408 $provider, 409 409 $user); 410 410 411 + if ($this->isAuthResult($properties)) { 412 + return $properties; 413 + } 414 + 411 415 foreach ($properties as $key => $value) { 412 416 $sync_token->setTemporaryTokenProperty($key, $value); 413 417 } ··· 553 557 ->withUserPHIDs(array($user->getPHID())) 554 558 ->withFactorProviderPHIDs(array($provider->getPHID())) 555 559 ->execute(); 560 + } 561 + 562 + final protected function isAuthResult($object) { 563 + return ($object instanceof PhabricatorAuthFactorResult); 556 564 } 557 565 558 566 }
+16 -2
src/applications/auth/factor/PhabricatorDuoAuthFactor.php
··· 157 157 PhabricatorUser $user) { 158 158 159 159 $token = $this->loadMFASyncToken($provider, $request, $form, $user); 160 + if ($this->isAuthResult($token)) { 161 + $form->appendChild($this->newAutomaticControl($token)); 162 + return; 163 + } 160 164 161 165 $enroll = $token->getTemporaryTokenProperty('duo.enroll'); 162 166 $duo_id = $token->getTemporaryTokenProperty('duo.user-id'); ··· 350 354 351 355 $external_uri = null; 352 356 $result_code = $result['response']['result']; 357 + $status_message = $result['response']['status_msg']; 353 358 switch ($result_code) { 354 359 case 'auth': 355 360 case 'allow': ··· 376 381 return $this->newResult() 377 382 ->setIsError(true) 378 383 ->setErrorMessage( 379 - pht('Your account is not permitted to access this system.')); 384 + pht( 385 + 'Your Duo account ("%s") is not permitted to access this '. 386 + 'system. Contact your Duo administrator for help. '. 387 + 'The Duo preauth API responded with status message ("%s"): %s', 388 + $duo_user, 389 + $result_code, 390 + $status_message)); 380 391 } 381 392 382 393 // Duo's "/enroll" API isn't repeatable for the same username. If we're ··· 476 487 ->setIsError(true) 477 488 ->setErrorMessage( 478 489 pht( 479 - 'Duo has denied you access. Duo status message ("%s"): %s', 490 + 'Your Duo account ("%s") is not permitted to access this '. 491 + 'system. Contact your Duo administrator for help. The Duo '. 492 + 'preauth API responded with status message ("%s"): %s', 493 + $duo_user, 480 494 $next_step, 481 495 $status_message)); 482 496 }