diff --git a/lib/src/CmsBootstrap.php b/lib/src/CmsBootstrap.php index 48f9a19f..98e0d044 100644 --- a/lib/src/CmsBootstrap.php +++ b/lib/src/CmsBootstrap.php @@ -278,18 +278,12 @@ protected function buildCv(): array { */ protected function loginStandaloneUser() { if (!empty($this->deferredUserToLogin)) { - global $loggedInUserId; - if (class_exists(\Civi\Api4\User::class)) { - $userID = \Civi\Api4\User::get(FALSE) - ->addWhere('username', '=', $this->deferredUserToLogin) - ->addWhere('is_active', '=', 1) - ->execute()->single(); - \CRM_Core_Session::singleton()->set('ufId', $userID); - $loggedInUserId = $userID['contact_id']; - } - if (empty($loggedInUserId)) { - throw new \RuntimeException("Unable to login as '$this->deferredUserToLogin'"); - } + // Note: Standalone always has "authx". + authx_login([ + 'flow' => 'cv_cli', + 'useSession' => FALSE, + 'principal' => ['user' => $this->deferredUserToLogin], + ]); } } @@ -308,8 +302,13 @@ public function bootBackdrop($cmsPath, $cmsUser) { } if ($cmsUser) { + $theUser = \user_load_by_name($cmsUser); + if (!$theUser || $theUser->name !== $cmsUser) { + throw new \RuntimeException("Failed to find Backdrop user ($cmsUser)"); + } + global $user; - $user = \user_load(array('name' => $cmsUser)); + $user = $theUser; } return $this; @@ -618,6 +617,13 @@ protected function ensureUserContact() { \CRM_Core_BAO_UFMatch::synchronize($GLOBALS['current_user'], TRUE, CIVICRM_UF, 'Individual'); break; + case 'Standalone': + // Recall: We're looking at the edge-case where a "User" is defined without corresponding "Contact". + // On Standalone, the *UI* is slightly more effective blocking this edge-case. (But you can still get it via API...) + // In any case, UFMatch::synchronize() doesn't seem to do anything on Standalone. (Maybe b/c special uf-match + // dual-purpose schema?) But for now, there's no point complaining about "Unrecognized UF". + break; + default: $this->log->error("Unrecognized UF: " . CIVICRM_UF); } diff --git a/scripts/check-phar.php b/scripts/check-phar.php index 2bd84fc9..b4519325 100755 --- a/scripts/check-phar.php +++ b/scripts/check-phar.php @@ -29,6 +29,7 @@ assertMatch('lib/src/CmsBootstrap.php', ';JFactory::;'); assertMatch('lib/src/CmsBootstrap.php', ';Drupal::;'); assertMatch('lib/src/CmsBootstrap.php', ';drupal_bootstrap;'); +assertMatch('lib/src/CmsBootstrap.php', ';user_load_by_name;'); assertMatch('lib/src/CmsBootstrap.php', ';user_load;'); assertMatch('lib/src/CmsBootstrap.php', ';wp_set_current_user;'); foreach (['lib/src/Bootstrap.php', 'lib/src/CmsBootstrap.php'] as $file) { diff --git a/src/Util/UrlCommandTrait.php b/src/Util/UrlCommandTrait.php index 3004d866..b6c6508b 100644 --- a/src/Util/UrlCommandTrait.php +++ b/src/Util/UrlCommandTrait.php @@ -91,7 +91,12 @@ protected function createUrls(InputInterface $input, OutputInterface $output, bo $cid = \CRM_Core_Session::getLoggedInContactID(); if (!$cid) { - throw new \RuntimeException('The "--login" option requires specifying an active user/contact ("--user=X").'); + if (empty($input->getOption('user'))) { + throw new \RuntimeException('The "--login" option requires specifying an active user/contact ("--user=X").'); + } + else { + throw new \RuntimeException('The "--login" option requires an active user/contact, but they could not be detected in this environment.'); + } } $token = \Civi::service('crypto.jwt')->encode([ 'exp' => time() + $this->defaultJwtTimeout, diff --git a/tests/Command/HttpCommandTest.php b/tests/Command/HttpCommandTest.php index d8455088..7ccd22bf 100644 --- a/tests/Command/HttpCommandTest.php +++ b/tests/Command/HttpCommandTest.php @@ -22,8 +22,15 @@ public function setUp(): void { $this->cvOk('en authx'); } - public function testAuthorizedGet() { - $body = $this->cvOk("http {$this->login} civicrm/authx/id"); + public static function getBootLevels(): array { + return [['full'], ['cms-full']]; + } + + /** + * @dataProvider getBootLevels + */ + public function testAuthorizedGet(string $bootLevel) { + $body = $this->cvOk("http {$this->login} civicrm/authx/id --level=" . escapeshellarg($bootLevel)); $data = json_decode($body, TRUE); $this->assertTrue(is_numeric($data['contact_id']), "civicrm/authx/id should return current contact. Received: $body");