瀏覽代碼

Updatable API keys - REST API spec and tests (#88270)

This PR adds REST API spec and YAML test files for the UpdateApiKey
operation.
Nikolaj Volgushev 3 年之前
父節點
當前提交
f42b15bc8c

+ 5 - 0
docs/changelog/88270.yaml

@@ -0,0 +1,5 @@
+pr: 88270
+summary: Updatable API keys - REST API spec and tests
+area: Security
+type: enhancement
+issues: []

+ 38 - 0
rest-api-spec/src/main/resources/rest-api-spec/api/security.update_api_key.json

@@ -0,0 +1,38 @@
+{
+  "security.update_api_key": {
+    "documentation": {
+      "url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-update-api-key.html",
+      "description": "Updates attributes of an existing API key."
+    },
+    "stability": "stable",
+    "visibility": "public",
+    "headers": {
+      "accept": [
+        "application/json"
+      ],
+      "content_type": [
+        "application/json"
+      ]
+    },
+    "url": {
+      "paths": [
+        {
+          "path": "/_security/api_key/{id}",
+          "methods": [
+            "PUT"
+          ],
+          "parts": {
+            "id": {
+              "type": "string",
+              "description": "The ID of the API key to update"
+            }
+          }
+        }
+      ]
+    },
+    "body": {
+      "description": "The API key request to update attributes of an API key.",
+      "required": false
+    }
+  }
+}

+ 2 - 0
x-pack/docs/en/rest-api/security.asciidoc

@@ -70,6 +70,7 @@ without requiring basic authentication:
 * <<security-api-clear-api-key-cache,Clear API key cache>>
 * <<security-api-grant-api-key,Grant API key>>
 * <<security-api-query-api-key,Query API key>>
+* <<security-api-update-api-key,Update API key>>
 
 [discrete]
 [[security-user-apis]]
@@ -188,6 +189,7 @@ include::security/oidc-prepare-authentication-api.asciidoc[]
 include::security/oidc-authenticate-api.asciidoc[]
 include::security/oidc-logout-api.asciidoc[]
 include::security/query-api-key.asciidoc[]
+include::security/update-api-key.asciidoc[]
 include::security/saml-prepare-authentication-api.asciidoc[]
 include::security/saml-authenticate-api.asciidoc[]
 include::security/saml-logout-api.asciidoc[]

+ 5 - 0
x-pack/docs/en/rest-api/security/update-api-key.asciidoc

@@ -0,0 +1,5 @@
+[role="xpack"]
+[[security-api-update-api-key]]
+=== Update API key information API
+
+coming::[8.4.0]

+ 1 - 1
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/20_query.yml

@@ -62,7 +62,7 @@ teardown:
 
   - do:
       security.delete_role:
-        name: "use_role"
+        name: "user_role"
         ignore: 404
 
   - do:

+ 348 - 0
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/30_update.yml

@@ -0,0 +1,348 @@
+---
+setup:
+  - skip:
+      features: [ headers, transform_and_set ]
+
+  - do:
+      cluster.health:
+        wait_for_status: yellow
+
+  - do:
+      security.put_role:
+        name: "user_role"
+        body: >
+          {
+            "cluster": ["manage_own_api_key"],
+            "indices": [
+              {
+                "names": "*",
+                "privileges": ["all"]
+              }
+            ]
+          }
+
+  - do:
+      security.put_user:
+        username: "api_key_user_1"
+        body: >
+          {
+            "password" : "x-pack-test-password",
+            "roles" : [ "user_role" ],
+            "full_name" : "API key user"
+          }
+
+---
+teardown:
+  - do:
+      security.delete_role:
+        name: "user_role"
+        ignore: 404
+
+  - do:
+      security.delete_user:
+        username: "api_key_user_1"
+        ignore: 404
+
+---
+"Test update api key":
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.create_api_key:
+        body: >
+          {
+            "name": "user1-api-key",
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["none"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["read"]
+                  }
+                ]
+              }
+            }
+          }
+  - match: { name: "user1-api-key" }
+  - is_true: id
+  - is_true: api_key
+  - set: { id: user1_key_id }
+  - transform_and_set: { login_creds: "#base64EncodeCredentials(id,api_key)" }
+  - match: { encoded: $login_creds }
+
+  # Check API key does not have requested privileges
+  - do:
+      headers:
+        Authorization: ApiKey ${login_creds}
+      security.has_privileges:
+        user: null
+        body: >
+          {
+            "cluster": ["manage_own_api_key"],
+            "index": [
+              {
+                "names": ["index-a"],
+                "privileges": ["write"]
+              },
+              {
+                "names": ["index-b"],
+                "privileges": ["read"]
+              }
+            ]
+          }
+  - match: { "has_all_requested": false }
+
+  # Update API key to above privileges
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.update_api_key:
+        id: "$user1_key_id"
+        body: >
+          {
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["all"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["write"]
+                  },
+                  {
+                    "names": ["index-b"],
+                    "privileges": ["read"]
+                  }
+                ]
+              }
+            },
+            "metadata": {
+               "letter": "a",
+               "number": 42
+            }
+          }
+  - match: { updated: true }
+
+  # Check updated privileges
+  - do:
+      headers:
+        Authorization: ApiKey ${login_creds}
+      security.has_privileges:
+        user: null
+        body: >
+          {
+            "cluster": ["manage_own_api_key"],
+            "index": [
+              {
+                "names": ["index-a"],
+                "privileges": ["write"]
+              },
+              {
+                "names": ["index-b"],
+                "privileges": ["read"]
+              }
+            ]
+          }
+  - match: { "has_all_requested": true }
+
+  # Check that metadata was updated
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.get_api_key:
+        id: "$user1_key_id"
+        owner: true
+  - length: { "api_keys" : 1 }
+  - match: {
+      "api_keys.0.metadata": {
+          "letter": "a",
+          "number": 42
+      }
+    }
+
+---
+"Test update api key without request fields":
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.create_api_key:
+        body: >
+          {
+            "name": "user1-api-key",
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["all"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["read"]
+                  }
+                ]
+              }
+            },
+            "metadata": {
+              "letter": "a",
+              "number": 42
+            }
+          }
+  - match: { name: "user1-api-key" }
+  - is_true: id
+  - is_true: api_key
+  - set: { id: user1_key_id }
+  - transform_and_set: { login_creds: "#base64EncodeCredentials(id,api_key)" }
+  - match: { encoded: $login_creds }
+
+  # Give user new cluster privilege to test auto update
+  - do:
+      security.put_role:
+        name: "user_role"
+        body: >
+          {
+            "cluster": ["all"],
+            "indices": [
+              {
+                "names": "index-a",
+                "privileges": ["all"]
+              }
+            ]
+          }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.update_api_key:
+        id: "$user1_key_id"
+        body: {}
+  - match: { updated: true }
+
+  # Check update works without a body
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.update_api_key:
+        id: "$user1_key_id"
+  - match: { updated: true }
+
+  # Check metadata did not change
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.get_api_key:
+        id: "$user1_key_id"
+        owner: true
+  - length: { "api_keys": 1 }
+  - match: {
+    "api_keys.0.metadata": {
+      "letter": "a",
+      "number": 42
+    }
+  }
+
+  # Check privileges auto-updated to owner user's
+  - do:
+      headers:
+        Authorization: ApiKey ${login_creds}
+      security.has_privileges:
+        user: null
+        body: >
+          {
+            "cluster": ["all"],
+            "index": [
+              {
+                "names": ["index-a"],
+                "privileges": ["read"]
+              }
+            ]
+          }
+  - match: { "has_all_requested": true }
+
+---
+"Test update api key with empty request fields":
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.create_api_key:
+        body: >
+          {
+            "name": "user1-api-key",
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["none"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["none"]
+                  }
+                ]
+              }
+            },
+            "metadata": {
+              "letter": "a",
+              "number": 42
+            }
+          }
+  - match: { name: "user1-api-key" }
+  - is_true: id
+  - is_true: api_key
+  - set: { id: user1_key_id }
+  - transform_and_set: { login_creds: "#base64EncodeCredentials(id,api_key)" }
+  - match: { encoded: $login_creds }
+
+  # Give user new cluster privilege to test auto update
+  - do:
+      security.put_role:
+        name: "user_role"
+        body: >
+          {
+            "cluster": ["all"],
+            "indices": [
+              {
+                "names": "index-a",
+                "privileges": ["all"]
+              }
+            ]
+          }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.update_api_key:
+        id: "$user1_key_id"
+        body: >
+          {
+            "role_descriptors": {},
+            "metadata": {}
+          }
+  - match: { updated: true }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyXzE6eC1wYWNrLXRlc3QtcGFzc3dvcmQ=" # api_key_user_1
+      security.get_api_key:
+        id: "$user1_key_id"
+        owner: true
+  - length: { "api_keys": 1 }
+  - match: {
+    "api_keys.0.metadata": {}
+  }
+
+  # Check privileges auto-updated to owner user's
+  - do:
+      headers:
+        Authorization: ApiKey ${login_creds}
+      security.has_privileges:
+        user: null
+        body: >
+          {
+            "cluster": ["all"],
+            "index": [
+              {
+                "names": ["index-a"],
+                "privileges": ["read"]
+              }
+            ]
+          }
+  - match: { "has_all_requested": true }