Create a new entry or update an existing one.
(self, kvp, name, requester_user, scope=None)
| 318 | return kvp_apis_system + kvp_apis_user |
| 319 | |
| 320 | def put(self, kvp, name, requester_user, scope=None): |
| 321 | """ |
| 322 | Create a new entry or update an existing one. |
| 323 | """ |
| 324 | if not scope or scope == ALL_SCOPE: |
| 325 | # Default to system scope |
| 326 | scope = FULL_SYSTEM_SCOPE |
| 327 | |
| 328 | if not requester_user: |
| 329 | requester_user = UserDB(name=cfg.CONF.system_user.user) |
| 330 | |
| 331 | scope = getattr(kvp, "scope", scope) |
| 332 | scope = get_datastore_full_scope(scope) |
| 333 | self._validate_scope(scope=scope) |
| 334 | |
| 335 | user = getattr(kvp, "user", requester_user.name) or requester_user.name |
| 336 | |
| 337 | rbac_utils = get_rbac_backend().get_utils_class() |
| 338 | |
| 339 | # Validate that the authenticated user is admin if user query param is provided |
| 340 | rbac_utils.assert_user_is_admin_if_user_query_param_is_provided( |
| 341 | user_db=requester_user, user=user, require_rbac=True |
| 342 | ) |
| 343 | |
| 344 | # Set key reference for system or user scope |
| 345 | key_ref = get_key_reference(scope=scope, name=name, user=user) |
| 346 | extra = {"scope": scope, "name": name, "user": user, "key_ref": key_ref} |
| 347 | LOG.debug("PUT /v1/keys/%s", name, extra=extra) |
| 348 | |
| 349 | # Setup a kvp database object used for verifying permission |
| 350 | kvp_db = KeyValuePairDB( |
| 351 | uid="%s:%s:%s" % (ResourceType.KEY_VALUE_PAIR, scope, key_ref), |
| 352 | scope=scope, |
| 353 | name=key_ref, |
| 354 | ) |
| 355 | |
| 356 | # Check that user has permission to the key value pair. |
| 357 | # If RBAC is enabled, this check will verify if user has system role with all access. |
| 358 | # If RBAC is enabled, this check guards against a user accessing another user's kvp. |
| 359 | # If RBAC is enabled, user needs to be explicitly granted permission to set a system kvp. |
| 360 | # The check is sufficient to allow decryption of the system kvp. |
| 361 | rbac_utils.assert_user_has_resource_db_permission( |
| 362 | user_db=requester_user, |
| 363 | resource_db=kvp_db, |
| 364 | permission_type=PermissionType.KEY_VALUE_PAIR_SET, |
| 365 | ) |
| 366 | |
| 367 | # Validate that the pre-encrypted option can only be used by admins |
| 368 | encrypted = getattr(kvp, "encrypted", False) |
| 369 | self._validate_encrypted_query_parameter( |
| 370 | encrypted=encrypted, scope=scope, requester_user=requester_user |
| 371 | ) |
| 372 | |
| 373 | # Acquire a lock to avoid race condition between concurrent API calls |
| 374 | with self._coordinator.get_lock( |
| 375 | self._get_lock_name_for_key(name=key_ref, scope=scope) |
| 376 | ): |
| 377 | try: |
nothing calls this directly
no test coverage detected