From 2ed41a0964032c6e0c4cb10424092dcc052c73b0 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Mon, 6 Sep 2021 12:10:35 +0200 Subject: [PATCH] new: [oidc] User setting for oidc metadata --- app/Model/AppModel.php | 6 ++- app/Model/UserSetting.php | 52 +++++++++++++++++-- .../Component/Auth/OidcAuthenticate.php | 22 +++++++- db_schema.json | 5 +- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index 549adfcce..52376e8b0 100644 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -83,7 +83,7 @@ class AppModel extends Model 51 => false, 52 => false, 53 => false, 54 => false, 55 => false, 56 => false, 57 => false, 58 => false, 59 => false, 60 => false, 61 => false, 62 => false, 63 => true, 64 => false, 65 => false, 66 => false, 67 => false, 68 => false, - 69 => false, 70 => false, 71 => true, 72 => true, + 69 => false, 70 => false, 71 => true, 72 => true, 73 => false, ); public $advanced_updates_description = array( @@ -1578,6 +1578,10 @@ class AppModel extends Model case 72: $sqlArray[] = "ALTER TABLE `auth_keys` ADD `read_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `expiration`;"; break; + case 73: + $this->__dropIndex('user_settings', 'timestamp'); // index is not used + $sqlArray[] = "ALTER TABLE `user_settings` ADD UNIQUE INDEX `unique_setting` (`user_id`, `setting`)"; + break; case 'fixNonEmptySharingGroupID': $sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; $sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; diff --git a/app/Model/UserSetting.php b/app/Model/UserSetting.php index dbcedc4c3..336f301ee 100644 --- a/app/Model/UserSetting.php +++ b/app/Model/UserSetting.php @@ -1,5 +1,9 @@ [ 'placeholder' => ['clusters'], ], + 'oidc' => [ // Data saved by OIDC plugin + 'restricted' => 'perm_site_admin', + ], ); // massage the data before we send it off for validation before saving anything public function beforeValidate($options = array()) { - parent::beforeValidate(); // add a timestamp if it is not set if (empty($this->data['UserSetting']['timestamp'])) { $this->data['UserSetting']['timestamp'] = time(); @@ -120,7 +126,9 @@ class UserSetting extends AppModel public function afterFind($results, $primary = false) { foreach ($results as $k => $v) { - $results[$k]['UserSetting']['value'] = json_decode($v['UserSetting']['value'], true); + if (isset($v['UserSetting']['value'])) { + $results[$k]['UserSetting']['value'] = json_decode($v['UserSetting']['value'], true); + } } return $results; } @@ -232,8 +240,8 @@ class UserSetting extends AppModel /** * Check whether the event is something the user is interested (to be alerted on) - * @param $user - * @param $event + * @param array $user + * @param array $event * @return bool */ public function checkPublishFilter(array $user, array $event) @@ -392,7 +400,8 @@ class UserSetting extends AppModel 'conditions' => array( 'UserSetting.user_id' => $userSetting['user_id'], 'UserSetting.setting' => $userSetting['setting'] - ) + ), + 'fields' => ['id'], )); if (empty($existingSetting)) { $this->create(); @@ -404,6 +413,39 @@ class UserSetting extends AppModel return true; } + /** + * Set user setting without checking permission. + * @param int $userId + * @param string $setting + * @param mixed $value + * @return array|bool|mixed|null + * @throws Exception + */ + public function setSettingInternal($userId, $setting, $value) + { + $userSetting = [ + 'user_id' => $userId, + 'setting' => $setting, + 'value' => $value, + ]; + + $existingSetting = $this->find('first', array( + 'recursive' => -1, + 'conditions' => array( + 'UserSetting.user_id' => $userId, + 'UserSetting.setting' => $setting, + ), + 'fields' => ['id'], + )); + if (empty($existingSetting)) { + $this->create(); + } else { + $userSetting['id'] = $existingSetting['UserSetting']['id']; + } + + return $this->save($userSetting); + } + /** * @param int $user_id * @param string $setting diff --git a/app/Plugin/OidcAuth/Controller/Component/Auth/OidcAuthenticate.php b/app/Plugin/OidcAuth/Controller/Component/Auth/OidcAuthenticate.php index e48ecc5c9..cf0bdd419 100644 --- a/app/Plugin/OidcAuth/Controller/Component/Auth/OidcAuthenticate.php +++ b/app/Plugin/OidcAuth/Controller/Component/Auth/OidcAuthenticate.php @@ -86,7 +86,7 @@ class OidcAuthenticate extends BaseAuthenticate $this->log($mispUsername, "Unblocking user."); $user['disabled'] = false; } - + $this->storeMetadata($user['id'], $verifiedClaims); $this->log($mispUsername, 'Logged in.'); return $user; } @@ -106,6 +106,8 @@ class OidcAuthenticate extends BaseAuthenticate throw new RuntimeException("Could not save user `$mispUsername` to database."); } + $this->storeMetadata($this->userModel()->id, $verifiedClaims); + $this->log($mispUsername, "Saved in database with ID {$this->userModel()->id}"); $this->log($mispUsername, 'Logged in.'); return $this->_findUser($mispUsername); @@ -227,6 +229,24 @@ class OidcAuthenticate extends BaseAuthenticate return $value; } + /** + * @param int $userId + * @param array $verifiedClaims + * @return array|bool|mixed|null + * @throws Exception + */ + private function storeMetadata($userId, $verifiedClaims) + { + $value = []; + foreach (['sub', 'preferred_username', 'given_name', 'family_name'] as $field) { + if (isset($verifiedClaims[$field])) { + $value[$field] = $verifiedClaims[$field]; + } + } + + return $this->userModel()->UserSetting->setSettingInternal($userId, 'oidc', $value); + } + /** * @param string $username * @param string $message diff --git a/db_schema.json b/db_schema.json index 06e3e4a54..6fadbd82d 100644 --- a/db_schema.json +++ b/db_schema.json @@ -8168,8 +8168,7 @@ "user_settings": { "id": true, "setting": false, - "user_id": false, - "timestamp": false + "user_id": false }, "warninglists": { "id": true @@ -8182,5 +8181,5 @@ "id": true } }, - "db_version": "72" + "db_version": "73" }