@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
79 lines (78 loc) • 2.72 kB
JavaScript
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
/*
* Copyright 2025 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useQuery } from '@tanstack/react-query';
import { useEffect } from 'react';
/** List of valid request verbs. See https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb. */
const VALID_AUTH_VERBS = [
'create',
'get',
'list',
'watch',
'update',
'patch',
'delete',
'deletecollection',
];
/** A component that will only render its children if the user is authorized to perform the specified action on the given resource.
* @param props The props for the component.
*/
export default function AuthVisible(props) {
const { item, authVerb, subresource, namespace, onError, onAuthResult, children } = props;
if (!VALID_AUTH_VERBS.includes(authVerb)) {
console.warn(`Invalid authVerb provided: "${authVerb}". Skipping authorization check.`);
return null;
}
const itemClass = item?._class?.() ?? item;
const itemName = item?.getName?.();
// eslint-disable-next-line react-hooks/rules-of-hooks
const { data } = useQuery({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
subresource,
namespace,
],
queryFn: async () => {
try {
const res = await item.getAuthorization(authVerb, { subresource, namespace }, item.cluster);
return res;
}
catch (e) {
onError?.(e);
}
},
});
const visible = data?.status?.allowed ?? false;
// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => {
if (data) {
onAuthResult?.({
allowed: visible,
reason: data.status?.reason ?? '',
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
if (!visible) {
return null;
}
return _jsx(_Fragment, { children: children });
}