diff --git a/app/Model/AuthKey.php b/app/Model/AuthKey.php index e1caa4e10..0cc354ec5 100644 --- a/app/Model/AuthKey.php +++ b/app/Model/AuthKey.php @@ -104,6 +104,12 @@ class AuthKey extends AppModel if (isset($val['AuthKey']['allowed_ips'])) { $results[$key]['AuthKey']['allowed_ips'] = JsonTool::decode($val['AuthKey']['allowed_ips']); } + if (isset($val['AuthKey']['unique_ips'])) { + $results[$key]['AuthKey']['unique_ips'] = JsonTool::decode($val['AuthKey']['unique_ips']); + } else { + $results[$key]['AuthKey']['unique_ips'] = []; + } + } return $results; } @@ -117,6 +123,13 @@ class AuthKey extends AppModel $this->data['AuthKey']['allowed_ips'] = JsonTool::encode($this->data['AuthKey']['allowed_ips']); } } + if (isset($this->data['AuthKey']['unique_ips'])) { + if (empty($this->data['AuthKey']['unique_ips'])) { + $this->data['AuthKey']['unique_ips'] = null; + } else { + $this->data['AuthKey']['unique_ips'] = JsonTool::encode($this->data['AuthKey']['unique_ips']); + } + } return true; } @@ -162,12 +175,24 @@ class AuthKey extends AppModel $possibleAuthkeys = $this->find('all', [ 'recursive' => -1, - 'fields' => ['id', 'authkey', 'user_id', 'expiration', 'allowed_ips', 'read_only'], + 'fields' => ['id', 'authkey', 'user_id', 'expiration', 'allowed_ips', 'read_only', 'unique_ips'], 'conditions' => $conditions, ]); $passwordHasher = $this->getHasher(); foreach ($possibleAuthkeys as $possibleAuthkey) { - if ($passwordHasher->check($authkey, $possibleAuthkey['AuthKey']['authkey'])) { + if ($passwordHasher->check($authkey, $possibleAuthkey['AuthKey']['authkey'])) { // valid authkey + // store IP in db if not there yet + $remote_ip = $this->_remoteIp(); + $update_db_ip = true; + if (is_array($possibleAuthkey['AuthKey']['unique_ips']) && in_array($remote_ip, $possibleAuthkey['AuthKey']['unique_ips'])) { + $update_db_ip = false; // IP already seen, skip saving in DB + } else { // first time an IP is seen for this API key + $possibleAuthkey['AuthKey']['unique_ips'][] = $remote_ip; + } + if ($update_db_ip) { + $this->save($possibleAuthkey); + } + // fetch user $user = $this->User->getAuthUser($possibleAuthkey['AuthKey']['user_id']); if ($user) { $user = $this->setUserData($user, $possibleAuthkey); diff --git a/app/View/AuthKeys/index.ctp b/app/View/AuthKeys/index.ctp index 0fc6e0dd8..358434eeb 100644 --- a/app/View/AuthKeys/index.ctp +++ b/app/View/AuthKeys/index.ctp @@ -73,6 +73,10 @@ 'name' => __('Allowed IPs'), 'data_path' => 'AuthKey.allowed_ips', ], + [ + 'name' => __('Seen IPs'), + 'data_path' => 'AuthKey.unique_ips' + ] ], 'title' => empty($ajax) ? __('Authentication key Index') : false, 'description' => empty($ajax) ? __('A list of API keys bound to a user.') : false, diff --git a/app/View/AuthKeys/view.ctp b/app/View/AuthKeys/view.ctp index ff9c8262d..47ef91b17 100644 --- a/app/View/AuthKeys/view.ctp +++ b/app/View/AuthKeys/view.ctp @@ -48,7 +48,7 @@ echo $this->element('genericElements/SingleViews/single_view', [ 'type' => 'custom', 'function' => function (array $data) { if (is_array($data['AuthKey']['allowed_ips'])) { - return implode("
", array_map('h', $data['AuthKey']['allowed_ips'])); + return implode("
", array_map('h', $data['AuthKey']['allowed_ips'])); } return __('All'); } @@ -83,9 +83,14 @@ echo $this->element('genericElements/SingleViews/single_view', [ 'requirement' => isset($keyUsage), ], [ - 'key' => __('Unique IPs'), - 'raw' => $uniqueIps, - 'requirement' => isset($keyUsage), + 'key' => __('Seen IPs'), + 'type' => 'custom', + 'function' => function (array $data) { + if (is_array($data['AuthKey']['unique_ips'])) { + return implode("
", array_map('h', $data['AuthKey']['unique_ips'])); + } + return ''; + } ] ], ]);