From bc529d996eeb4d3ad90e7e004f5150d115e4d2b9 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 28 Oct 2020 01:39:15 -0700 Subject: [PATCH] dev/core#2141 - APIv4 - Add OAuthSysToken.refresh action --- .../Api4/Action/OAuthSysToken/Refresh.php | 87 +++++++++++++++++++ ext/oauth-client/Civi/Api4/OAuthSysToken.php | 12 +++ 2 files changed, 99 insertions(+) create mode 100644 ext/oauth-client/Civi/Api4/Action/OAuthSysToken/Refresh.php diff --git a/ext/oauth-client/Civi/Api4/Action/OAuthSysToken/Refresh.php b/ext/oauth-client/Civi/Api4/Action/OAuthSysToken/Refresh.php new file mode 100644 index 0000000000..043a83b5d2 --- /dev/null +++ b/ext/oauth-client/Civi/Api4/Action/OAuthSysToken/Refresh.php @@ -0,0 +1,87 @@ +threshold >= 0 && \CRM_Utils_Time::getTimeRaw() < $row['expires'] - $this->threshold) { + return $this->filterReturn($row); + } + + $provider = $this->getProvider($row['client_id']); + $newToken = $provider->getAccessToken('refresh_token', [ + 'refresh_token' => $row['refresh_token'], + ]); + + $raw = $newToken->jsonSerialize(); + $row['raw'] = $raw; + foreach ($this->syncFields as $field) { + if (isset($raw[$field])) { + $row[$field] = $raw[$field]; + } + } + + civicrm_api4($this->getEntityName(), 'update', [ + // You may have permission to refresh even if you can't inspect/update secrets directly. + 'checkPermissions' => FALSE, + 'where' => [['id', '=', $row['id']]], + 'values' => \CRM_Utils_Array::subset($row, $this->writeFields), + ])->single(); + + return $this->filterReturn($row); + } + + protected function getProvider($clientId) { + if (!isset($this->providers[$clientId])) { + $client = \Civi\Api4\OAuthClient::get(0)->addWhere('id', '=', $clientId)->execute()->single(); + $this->providers[$clientId] = \Civi::service('oauth2.league')->createProvider($client); + } + return $this->providers[$clientId]; + } + + protected function filterReturn($tokenRecord) { + return $this->checkPermissions ? \CRM_OAuth_BAO_OAuthSysToken::redact($tokenRecord) : $tokenRecord; + } + +} diff --git a/ext/oauth-client/Civi/Api4/OAuthSysToken.php b/ext/oauth-client/Civi/Api4/OAuthSysToken.php index f4bc08a847..8cba88ee10 100644 --- a/ext/oauth-client/Civi/Api4/OAuthSysToken.php +++ b/ext/oauth-client/Civi/Api4/OAuthSysToken.php @@ -10,12 +10,24 @@ namespace Civi\Api4; */ class OAuthSysToken extends Generic\DAOEntity { + /** + * Load and conditionally refresh a stored token. + * + * @param bool $checkPermissions + * @return \Civi\Api4\Action\OAuthSysToken\Refresh + */ + public static function refresh($checkPermissions = TRUE) { + $action = new \Civi\Api4\Action\OAuthSysToken\Refresh(static::class, __FUNCTION__); + return $action->setCheckPermissions($checkPermissions); + } + public static function permissions() { return [ 'meta' => ['access CiviCRM'], 'default' => ['manage OAuth client'], 'delete' => ['manage OAuth client'], 'get' => ['manage OAuth client'], + 'refresh' => ['manage OAuth client'], 'create' => ['manage OAuth client secrets'], 'update' => ['manage OAuth client secrets'], // In theory, there might be cases to 'create' or 'update' an OAuthSysToken -- 2.25.1