Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionServeController.php
Show First 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | private function serveRequest(AphrontRequest $request) { | ||||
$have_pass = strlen(idx($_SERVER, 'PHP_AUTH_PW')); | $have_pass = strlen(idx($_SERVER, 'PHP_AUTH_PW')); | ||||
if ($have_user && $have_pass) { | if ($have_user && $have_pass) { | ||||
$username = $_SERVER['PHP_AUTH_USER']; | $username = $_SERVER['PHP_AUTH_USER']; | ||||
$password = new PhutilOpaqueEnvelope($_SERVER['PHP_AUTH_PW']); | $password = new PhutilOpaqueEnvelope($_SERVER['PHP_AUTH_PW']); | ||||
// Try Git LFS auth first since we can usually reject it without doing | // Try Git LFS auth first since we can usually reject it without doing | ||||
// any queries, since the username won't match the one we expect or the | // any queries, since the username won't match the one we expect or the | ||||
// request won't be LFS. | // request won't be LFS. | ||||
$viewer = $this->authenticateGitLFSUser($username, $password); | $viewer = $this->authenticateGitLFSUser( | ||||
$username, | |||||
$password, | |||||
$identifier); | |||||
// If that failed, try normal auth. Note that we can use normal auth on | // If that failed, try normal auth. Note that we can use normal auth on | ||||
// LFS requests, so this isn't strictly an alternative to LFS auth. | // LFS requests, so this isn't strictly an alternative to LFS auth. | ||||
if (!$viewer) { | if (!$viewer) { | ||||
$viewer = $this->authenticateHTTPRepositoryUser($username, $password); | $viewer = $this->authenticateHTTPRepositoryUser($username, $password); | ||||
} | } | ||||
if (!$viewer) { | if (!$viewer) { | ||||
▲ Show 20 Lines • Show All 446 Lines • ▼ Show 20 Lines | if ($repository->isGit()) { | ||||
} | } | ||||
} | } | ||||
return $base_path; | return $base_path; | ||||
} | } | ||||
private function authenticateGitLFSUser( | private function authenticateGitLFSUser( | ||||
$username, | $username, | ||||
PhutilOpaqueEnvelope $password) { | PhutilOpaqueEnvelope $password, | ||||
$identifier) { | |||||
// Never accept these credentials for requests which aren't LFS requests. | // Never accept these credentials for requests which aren't LFS requests. | ||||
if (!$this->getIsGitLFSRequest()) { | if (!$this->getIsGitLFSRequest()) { | ||||
return null; | return null; | ||||
} | } | ||||
// If we have the wrong username, don't bother checking if the token | // If we have the wrong username, don't bother checking if the token | ||||
// is right. | // is right. | ||||
if ($username !== DiffusionGitLFSTemporaryTokenType::HTTP_USERNAME) { | if ($username !== DiffusionGitLFSTemporaryTokenType::HTTP_USERNAME) { | ||||
return null; | return null; | ||||
} | } | ||||
// See PHI1123. We need to be able to constrain the token query with | |||||
// "withTokenResources(...)" to take advantage of the key on the table. | |||||
// In this case, the repository PHID is the "resource" we're after. | |||||
amckinley: "resource" | |||||
// In normal workflows, we figure out the viewer first, then use the | |||||
// viewer to load the repository, but that won't work here. Load the | |||||
// repository as the omnipotent viewer, then use the repository PHID to | |||||
// look for a token. | |||||
$omnipotent_viewer = PhabricatorUser::getOmnipotentUser(); | |||||
$repository = id(new PhabricatorRepositoryQuery()) | |||||
->setViewer($omnipotent_viewer) | |||||
->withIdentifiers(array($identifier)) | |||||
->executeOne(); | |||||
if (!$repository) { | |||||
return null; | |||||
} | |||||
$lfs_pass = $password->openEnvelope(); | $lfs_pass = $password->openEnvelope(); | ||||
$lfs_hash = PhabricatorHash::weakDigest($lfs_pass); | $lfs_hash = PhabricatorHash::weakDigest($lfs_pass); | ||||
$token = id(new PhabricatorAuthTemporaryTokenQuery()) | $token = id(new PhabricatorAuthTemporaryTokenQuery()) | ||||
->setViewer(PhabricatorUser::getOmnipotentUser()) | ->setViewer($omnipotent_viewer) | ||||
->withTokenResources(array($repository->getPHID())) | |||||
->withTokenTypes(array(DiffusionGitLFSTemporaryTokenType::TOKENTYPE)) | ->withTokenTypes(array(DiffusionGitLFSTemporaryTokenType::TOKENTYPE)) | ||||
->withTokenCodes(array($lfs_hash)) | ->withTokenCodes(array($lfs_hash)) | ||||
->withExpired(false) | ->withExpired(false) | ||||
->executeOne(); | ->executeOne(); | ||||
if (!$token) { | if (!$token) { | ||||
return null; | return null; | ||||
} | } | ||||
$user = id(new PhabricatorPeopleQuery()) | $user = id(new PhabricatorPeopleQuery()) | ||||
->setViewer(PhabricatorUser::getOmnipotentUser()) | ->setViewer($omnipotent_viewer) | ||||
->withPHIDs(array($token->getUserPHID())) | ->withPHIDs(array($token->getUserPHID())) | ||||
->executeOne(); | ->executeOne(); | ||||
if (!$user) { | if (!$user) { | ||||
return null; | return null; | ||||
} | } | ||||
if (!$user->isUserActivated()) { | if (!$user->isUserActivated()) { | ||||
▲ Show 20 Lines • Show All 549 Lines • Show Last 20 Lines |
"resource"