vault/ui/app/adapters/capabilities.js
Chelsea Shaw dcdbacd281
UI: Fix no data read within namespaces (#28311)
* Add test for capabilities within namespace

* update capabilities fetchMultiplePaths so that the resulting records have the non-prefixed path as ID
2024-09-06 13:44:09 -05:00

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;
});
}
}