Skip to content

Commit

Permalink
Bug 1878953: Fix RBAC with upload form and golden images
Browse files Browse the repository at this point in the history
  • Loading branch information
glekner committed Jan 5, 2021
1 parent 56c3de0 commit 63d8fa9
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
Expand Up @@ -24,6 +24,7 @@ import {
PersistentVolumeClaimKind,
ConfigMapKind,
StorageClassResourceKind,
K8sVerb,
} from '@console/internal/module/k8s';
import {
ButtonBar,
Expand All @@ -33,6 +34,7 @@ import {
ExternalLink,
ResourceLink,
useAccessReview2,
useMultipleAccessReviews,
} from '@console/internal/components/utils';
import {
provisionerAccessModeMapping,
Expand Down Expand Up @@ -62,6 +64,7 @@ import { getTemplateOperatingSystems } from '../../../selectors/vm-template/adva
import { FormSelectPlaceholderOption } from '../../form/form-select-placeholder-option';
import {
AccessMode,
TEMPLATE_BASE_IMAGE_NAMESPACE_PARAMETER,
TEMPLATE_TYPE_BASE,
TEMPLATE_TYPE_LABEL,
TEMPLATE_VM_COMMON_NAMESPACE,
Expand All @@ -82,6 +85,7 @@ import {
isConfigMapContainsScModes,
} from '../../../selectors/config-map/sc-defaults';
import { ConfigMapDefaultModesAlert } from '../../Alerts/ConfigMapDefaultModesAlert';
import { getParameterValue } from '../../../selectors/selectors';
import './upload-pvc-form.scss';

const templatesResource: WatchK8sResource = {
Expand Down Expand Up @@ -540,7 +544,35 @@ export const UploadPVCPage: React.FC<UploadPVCPageProps> = (props) => {
const [commonTemplates, loadedTemplates, errorTemplates] = useK8sWatchResource<TemplateKind[]>(
templatesResource,
);
const [goldenPvcs, loadedPvcs, errorPvcs] = useBaseImages(commonTemplates);

const goldenNamespacesResources = React.useMemo(() => {
const goldenNamespaces = [
...new Set(
(commonTemplates || [])
.map((template) => getParameterValue(template, TEMPLATE_BASE_IMAGE_NAMESPACE_PARAMETER))
.filter((ns) => !!ns),
),
];

return goldenNamespaces.map((ns) => ({
group: DataVolumeModel.apiGroup,
resource: DataVolumeModel.plural,
verb: 'create' as K8sVerb,
namespace: ns,
}));
}, [commonTemplates]);

const [goldenAccessReviews, rbacLoading] = useMultipleAccessReviews(goldenNamespacesResources);
const allowedTemplates = commonTemplates.filter((tmp) =>
goldenAccessReviews.some(
(accessReview) =>
accessReview.allowed &&
accessReview.resourceAttributes.namespace ===
getParameterValue(tmp, TEMPLATE_BASE_IMAGE_NAMESPACE_PARAMETER),
),
);

const [goldenPvcs, loadedPvcs, errorPvcs] = useBaseImages(allowedTemplates);
const { uploads, uploadData, uploadProxyURL } = React.useContext(CDIUploadContext);
const [scConfigMap, cmLoaded] = useStorageClassConfigMap();
const [scAllowed, scAllowedLoading] = useAccessReview2({
Expand Down Expand Up @@ -648,7 +680,7 @@ export const UploadPVCPage: React.FC<UploadPVCPageProps> = (props) => {
fileName={fileName}
handleFileChange={handleFileChange}
setIsFileRejected={setIsFileRejected}
commonTemplates={commonTemplates}
commonTemplates={allowedTemplates}
goldenPvcs={goldenPvcs}
osParam={osParam}
isLoading={!loadedTemplates}
Expand All @@ -658,6 +690,7 @@ export const UploadPVCPage: React.FC<UploadPVCPageProps> = (props) => {
/>
<ButtonBar
inProgress={
rbacLoading ||
scAllowedLoading ||
!scLoaded ||
!cmLoaded ||
Expand Down
36 changes: 36 additions & 0 deletions frontend/public/components/utils/rbac.tsx
Expand Up @@ -124,6 +124,37 @@ export const useAccessReview2 = (
return [isAllowed, loading];
};

export const useMultipleAccessReviews = (
multipleResourceAttributes: AccessReviewResourceAttributes[],
impersonate?: boolean,
): [AccessReviewsResult[], boolean] => {
const [loading, setLoading] = React.useState(true);
const [allowedArr, setAllowedArr] = React.useState<AccessReviewsResult[]>([]);

React.useEffect(() => {
const promises = multipleResourceAttributes.map((resourceAttributes) =>
checkAccess(resourceAttributes, impersonate),
);

Promise.all(promises)
.then((values) => {
setLoading(false);
const updatedAllowedArr = values.map<AccessReviewsResult>((result) => ({
resourceAttributes: result.spec.resourceAttributes,
allowed: result.status.allowed,
}));
setAllowedArr(updatedAllowedArr);
})
.catch((e) => {
// eslint-disable-next-line no-console
console.warn('SelfSubjectAccessReview failed', e);
setLoading(false);
});
}, [impersonate, multipleResourceAttributes]);

return [allowedArr, loading];
};

export const useAccessReview = (
resourceAttributes: AccessReviewResourceAttributes,
impersonate?,
Expand Down Expand Up @@ -156,6 +187,11 @@ type RequireCreatePermissionProps = {
children: React.ReactNode;
};

type AccessReviewsResult = {
resourceAttributes: AccessReviewResourceAttributes;
allowed: boolean;
};

export const asAccessReview = (
kindObj: K8sKind,
obj: K8sResourceKind,
Expand Down

0 comments on commit 63d8fa9

Please sign in to comment.