mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-22 07:01:09 +02:00
* Add test for capabilities within namespace * update capabilities fetchMultiplePaths so that the resulting records have the non-prefixed path as ID
84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import AdapterError from '@ember-data/adapter/error';
|
|
import { set } from '@ember/object';
|
|
import ApplicationAdapter from './application';
|
|
import { sanitizePath, sanitizeStart } from 'core/utils/sanitize-path';
|
|
|
|
export default class CapabilitiesAdapter extends ApplicationAdapter {
|
|
pathForType() {
|
|
return 'capabilities-self';
|
|
}
|
|
|
|
/*
|
|
users don't always have access to the capabilities-self endpoint in the current namespace,
|
|
this can happen when logging in to a namespace and then navigating to a child namespace.
|
|
adding "relativeNamespace" to the path and/or "this.namespaceService.userRootNamespace"
|
|
to the request header ensures we are querying capabilities-self in the user's root namespace,
|
|
which is where they are most likely to have their policy/permissions.
|
|
*/
|
|
_formatPath(path) {
|
|
const { relativeNamespace } = this.namespaceService;
|
|
if (!relativeNamespace) {
|
|
return path;
|
|
}
|
|
// ensure original path doesn't have leading slash
|
|
return `${relativeNamespace}/${sanitizeStart(path)}`;
|
|
}
|
|
|
|
async findRecord(store, type, id) {
|
|
const paths = [this._formatPath(id)];
|
|
return this.ajax(this.buildURL(type), 'POST', {
|
|
data: { paths },
|
|
namespace: sanitizePath(this.namespaceService.userRootNamespace),
|
|
}).catch((e) => {
|
|
if (e instanceof AdapterError) {
|
|
set(e, 'policyPath', 'sys/capabilities-self');
|
|
}
|
|
throw e;
|
|
});
|
|
}
|
|
|
|
queryRecord(store, type, query) {
|
|
const { id } = query;
|
|
if (!id) {
|
|
return;
|
|
}
|
|
return this.findRecord(store, type, id).then((resp) => {
|
|
resp.path = id;
|
|
return resp;
|
|
});
|
|
}
|
|
|
|
query(store, type, query) {
|
|
const pathMap = query?.paths.reduce((mapping, path) => {
|
|
const withNs = this._formatPath(path);
|
|
if (withNs) {
|
|
mapping[withNs] = path;
|
|
}
|
|
return mapping;
|
|
}, {});
|
|
|
|
return this.ajax(this.buildURL(type), 'POST', {
|
|
data: { paths: Object.keys(pathMap) },
|
|
namespace: sanitizePath(this.namespaceService.userRootNamespace),
|
|
})
|
|
.then((queryResult) => {
|
|
if (queryResult) {
|
|
// send the pathMap with the response so the serializer can normalize the paths to be relative to the namespace
|
|
queryResult.pathMap = pathMap;
|
|
}
|
|
return queryResult;
|
|
})
|
|
.catch((e) => {
|
|
if (e instanceof AdapterError) {
|
|
set(e, 'policyPath', 'sys/capabilities-self');
|
|
}
|
|
throw e;
|
|
});
|
|
}
|
|
}
|