Skip to content

Commit

Permalink
authx - Allow civicrm/ajax/rest to accept auth params akin to `exte…
Browse files Browse the repository at this point in the history
…rn/rest.php`
  • Loading branch information
totten committed Apr 9, 2021
1 parent 43e4c62 commit d458b6b
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
42 changes: 42 additions & 0 deletions ext/authx/Civi/Authx/LegacyRestAuthenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\Authx;

use GuzzleHttp\Psr7\Response;

/**
* Historically, 'extern/rest.php' and 'civicrm/ajax/rest' were similar interfaces
* based on the same controller, but they used different authentication styles.
*
* This authenticator is activated if one requests 'civicrm/ajax/rest' using the
* authentication style of 'extern/rest.php'.
*
* @package Civi\Authx
*/
class LegacyRestAuthenticator extends Authenticator {

protected function reject($message = 'Authentication failed') {
$data = ["error_message" => "FATAL: $message", "is_error" => 1];
$r = new Response(200, ['Content-Type' => 'text/javascript'], json_encode($data));
\CRM_Utils_System::sendResponse($r);
}

protected function login(AuthenticatorTarget $tgt) {
parent::login($tgt);
\Civi::dispatcher()->addListener('hook_civicrm_permission_check', function ($e) {
if ($e->permission === 'access AJAX API') {
$e->granted = TRUE;
}
});
}

}
4 changes: 4 additions & 0 deletions ext/authx/authx.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
_authx_redact(['_authx']);
}
}

if (count($e->args) > 2 && $e->args[1] === 'ajax' && $e->args[2] === 'rest' && (!empty($_REQUEST['api_key']) || !empty($_REQUEST['key']))) {
return (new \Civi\Authx\LegacyRestAuthenticator())->auth($e, ['flow' => 'legacyrest', 'cred' => 'Bearer ' . $_REQUEST['api_key'] ?? '', 'siteKey' => $_REQUEST['key'] ?? NULL]);
}
});

/**
Expand Down
7 changes: 6 additions & 1 deletion ext/authx/settings/authx.setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
$_authx_settings = function() {
$flows = ['param', 'header', 'xheader', 'login', 'auto'];
$flows = ['param', 'header', 'xheader', 'login', 'auto', 'legacyrest'];
$basic = [
'group_name' => 'CiviCRM Preferences',
'group' => 'authx',
Expand Down Expand Up @@ -76,6 +76,11 @@
],
];
}

// Override defaults for a few specific elements
$s['authx_legacyrest_cred']['default'] = ['jwt', 'api_key'];
$s['authx_legacyrest_user']['default'] = 'require';

return $s;
};

Expand Down
45 changes: 45 additions & 0 deletions tests/phpunit/E2E/Extern/AuthxRestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

/**
* Verify that the REST API bindings correctly parse and authenticate requests.
*
* @group e2e
*/
class E2E_Extern_AuthxRestTest extends E2E_Extern_BaseRestTest {

public static function setUpBeforeClass() {
parent::setUpBeforeClass();
\Civi\Test::e2e()
->install(['authx'])
->callback(
function() {
\CRM_Utils_System::synchronizeUsers();
},
'synchronizeUsers'
)
->apply();
}

protected function getRestUrl() {
return CRM_Utils_System::url('civicrm/ajax/rest', NULL, TRUE, NULL, FALSE, TRUE);
}

public function apiTestCases() {
$r = parent::apiTestCases();
$r = array_filter($r, function($case) {
// The 'civicrm/ajax/rest' end-point does not support '?q' inputs.
return !isset($case[0]['q']);
});
return $r;
}

}

0 comments on commit d458b6b

Please sign in to comment.