From 4555f18c41e47d5b84885d40bf9fb5bc77011e51 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 30 Sep 2019 15:23:45 +0200 Subject: [PATCH] Add auth provider which uses Phabricator The idea is to use it instead of a custom field approach. --- scripts/auth_provider/auth_provider.php | 172 ++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100755 scripts/auth_provider/auth_provider.php diff --git a/scripts/auth_provider/auth_provider.php b/scripts/auth_provider/auth_provider.php new file mode 100755 index 0000000000..02366a2a02 --- /dev/null +++ b/scripts/auth_provider/auth_provider.php @@ -0,0 +1,172 @@ +#!/usr/bin/php + +# AddExternalAuth phabricator /path/to/auth_provider.php +# SetExternalAuthMethod phabricator pipe +# +# +# This method allowed to use this auth provider for SVN DAV. + +$IS_DEBUG = false; +$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__))); +require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php'; + +function initLogging() { + global $IS_DEBUG; + global $argv; + for ($i = 1; $i < count($argv); ++$i) { + if ($argv[$i] == '--debug') { + $IS_DEBUG = true; + } + } +} + +function debugLog(string $text) { + global $IS_DEBUG; + if (!$IS_DEBUG) { + return; + } + print("${text}\n"); +} + +function removeSingleTrailingNewline(string $string) { + if ($string === '') { + return $string; + } + $length = strlen($string); + if ($string[$length - 1] == "\n") { + return substr($string, 0, -1); + } + return $string; +} + +class AuthRequest { + public $user_name; + public $password; + + static function fromStdin() { + $auth_request = new AuthRequest(); + $stdin = fopen('php://stdin', 'r'); + $auth_request->user_name = removeSingleTrailingNewline(fgets($stdin)); + $auth_request->password = removeSingleTrailingNewline(fgets($stdin)); + return $auth_request; + } +}; + +function getUserForAuthRequest(AuthRequest $auth_request) { + if ($auth_request->user_name === '') { + return null; + } + + $username_or_email = $auth_request->user_name; + + $user = id(new PhabricatorUser())->loadOneWhere( + 'username = %s', + $username_or_email); + + if (!$user) { + $user = PhabricatorUser::loadOneWithEmailAddress( + $username_or_email); + } + + return $user; +} + +function createContentSourceForAuth() { + return PhabricatorContentSource::newForSource( + PhabricatorUnitTestContentSource::SOURCECONST); +} + +function isValidAuth(AuthRequest $auth_request) { + debugLog("Begin authentification check for user '$auth_request->user_name'"); + $user = getUserForAuthRequest($auth_request); + if (!$user) { + debugLog("No PhabricatorUser() object found for requested user."); + return false; + } + + $content_source = createContentSourceForAuth(); + $envelope = new PhutilOpaqueEnvelope($auth_request->password); + + $engine = id(new PhabricatorAuthPasswordEngine()) + ->setViewer($user) + ->setContentSource($content_source) + ->setPasswordType(PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT) + ->setObject($user); + + if (!$engine->isValidPassword($envelope)) { + debugLog('Engine reported invalid password.'); + return false; + } + + debugLog('Authentirfication passed.'); + + return true; +} + +function main() { + initLogging(); + $auth_request = AuthRequest::fromStdin(); + if (!isValidAuth($auth_request)) { + exit(1); + } + exit(0); +} + +main(); +?>