fix(access-control): set user id when private (#8839)

pull/9115/head
Chaim Lev-Ari 2023-06-22 21:12:49 +07:00 committed by GitHub
parent e91b4f5c83
commit 4c8af378af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 20 deletions

View File

@ -6,7 +6,7 @@ import {
Subscription, Subscription,
} from '@/react/azure/types'; } from '@/react/azure/types';
import { parseAccessControlFormData } from '@/react/portainer/access-control/utils'; import { parseAccessControlFormData } from '@/react/portainer/access-control/utils';
import { useUser } from '@/react/hooks/useUser'; import { useCurrentUser } from '@/react/hooks/useUser';
import { useProvider } from '@/react/azure/queries/useProvider'; import { useProvider } from '@/react/azure/queries/useProvider';
import { useResourceGroups } from '@/react/azure/queries/useResourceGroups'; import { useResourceGroups } from '@/react/azure/queries/useResourceGroups';
import { useSubscriptions } from '@/react/azure/queries/useSubscriptions'; import { useSubscriptions } from '@/react/azure/queries/useSubscriptions';
@ -37,7 +37,7 @@ export function useFormState(
resourceGroups: Record<string, ResourceGroup[]> = {}, resourceGroups: Record<string, ResourceGroup[]> = {},
providers: Record<string, ProviderViewModel> = {} providers: Record<string, ProviderViewModel> = {}
) { ) {
const { isAdmin } = useUser(); const { isAdmin, user } = useCurrentUser();
const subscriptionOptions = subscriptions.map((s) => ({ const subscriptionOptions = subscriptions.map((s) => ({
value: s.subscriptionId, value: s.subscriptionId,
@ -67,7 +67,7 @@ export function useFormState(
cpu: 1, cpu: 1,
ports: [{ container: 80, host: 80, protocol: 'TCP' }], ports: [{ container: 80, host: 80, protocol: 'TCP' }],
allocatePublicIP: true, allocatePublicIP: true,
accessControl: parseAccessControlFormData(isAdmin), accessControl: parseAccessControlFormData(isAdmin, user.Id),
}; };
return { return {

View File

@ -31,7 +31,7 @@ interface Args {
function Template({ userRole }: Args) { function Template({ userRole }: Args) {
const isAdmin = userRole === Role.Admin; const isAdmin = userRole === Role.Admin;
const defaults = parseAccessControlFormData(isAdmin); const defaults = parseAccessControlFormData(isAdmin, 0);
const [value, setValue] = useState(defaults); const [value, setValue] = useState(defaults);

View File

@ -3,7 +3,7 @@ import clsx from 'clsx';
import { useMutation } from 'react-query'; import { useMutation } from 'react-query';
import { object } from 'yup'; import { object } from 'yup';
import { useUser } from '@/react/hooks/useUser'; import { useCurrentUser } from '@/react/hooks/useUser';
import { notifySuccess } from '@/portainer/services/notifications'; import { notifySuccess } from '@/portainer/services/notifications';
import { EnvironmentId } from '@/react/portainer/environments/types'; import { EnvironmentId } from '@/react/portainer/environments/types';
@ -43,7 +43,7 @@ export function AccessControlPanelForm({
onCancelClick, onCancelClick,
onUpdateSuccess, onUpdateSuccess,
}: Props) { }: Props) {
const { isAdmin } = useUser(); const { isAdmin, user } = useCurrentUser();
const updateAccess = useMutation( const updateAccess = useMutation(
(variables: AccessControlFormData) => (variables: AccessControlFormData) =>
@ -64,7 +64,11 @@ export function AccessControlPanelForm({
); );
const initialValues = { const initialValues = {
accessControl: parseAccessControlFormData(isAdmin, resourceControl), accessControl: parseAccessControlFormData(
isAdmin,
user.Id,
resourceControl
),
}; };
return ( return (

View File

@ -3,6 +3,25 @@ import { ResourceControlOwnership, ResourceControlType } from './types';
import { parseAccessControlFormData } from './utils'; import { parseAccessControlFormData } from './utils';
describe('parseAccessControlFormData', () => { describe('parseAccessControlFormData', () => {
test('when ownership is private and resource is supplied, authorizedUsers should be UserAccess', () => {
const resourceControl = buildResourceControl(
ResourceControlOwnership.PRIVATE
);
resourceControl.UserAccesses = [{ UserId: 1, AccessLevel: 1 }];
const actual = parseAccessControlFormData(false, 1, resourceControl);
expect(actual.authorizedUsers).toContain(1);
expect(actual.authorizedUsers).toHaveLength(1);
});
test('when not admin and no resource control, ownership should be set to private and authorizedUsers is only currentUserId', () => {
const actual = parseAccessControlFormData(false, 1);
expect(actual.ownership).toBe(ResourceControlOwnership.PRIVATE);
expect(actual.authorizedUsers).toContain(1);
expect(actual.authorizedUsers).toHaveLength(1);
});
[ [
ResourceControlOwnership.ADMINISTRATORS, ResourceControlOwnership.ADMINISTRATORS,
ResourceControlOwnership.RESTRICTED, ResourceControlOwnership.RESTRICTED,
@ -12,7 +31,7 @@ describe('parseAccessControlFormData', () => {
test(`when resource control supplied, if user is not admin, will change ownership to rc ownership (${ownership})`, () => { test(`when resource control supplied, if user is not admin, will change ownership to rc ownership (${ownership})`, () => {
const resourceControl = buildResourceControl(ownership); const resourceControl = buildResourceControl(ownership);
const actual = parseAccessControlFormData(false, resourceControl); const actual = parseAccessControlFormData(false, 0, resourceControl);
expect(actual.ownership).toBe(resourceControl.Ownership); expect(actual.ownership).toBe(resourceControl.Ownership);
}); });
}); });
@ -25,13 +44,13 @@ describe('parseAccessControlFormData', () => {
test(`when resource control supplied and user is admin, if resource ownership is ${ownership} , will change ownership to rc ownership`, () => { test(`when resource control supplied and user is admin, if resource ownership is ${ownership} , will change ownership to rc ownership`, () => {
const resourceControl = buildResourceControl(ownership); const resourceControl = buildResourceControl(ownership);
const actual = parseAccessControlFormData(true, resourceControl); const actual = parseAccessControlFormData(true, 0, resourceControl);
expect(actual.ownership).toBe(resourceControl.Ownership); expect(actual.ownership).toBe(resourceControl.Ownership);
}); });
}); });
test('when isAdmin and resource control not supplied, ownership should be set to Administrator', () => { test('when isAdmin and resource control not supplied, ownership should be set to Administrator', () => {
const actual = parseAccessControlFormData(true); const actual = parseAccessControlFormData(true, 0);
expect(actual.ownership).toBe(ResourceControlOwnership.ADMINISTRATORS); expect(actual.ownership).toBe(ResourceControlOwnership.ADMINISTRATORS);
}); });
@ -41,7 +60,7 @@ describe('parseAccessControlFormData', () => {
ResourceControlOwnership.PRIVATE ResourceControlOwnership.PRIVATE
); );
const actual = parseAccessControlFormData(true, resourceControl); const actual = parseAccessControlFormData(true, 0, resourceControl);
expect(actual.ownership).toBe(ResourceControlOwnership.RESTRICTED); expect(actual.ownership).toBe(ResourceControlOwnership.RESTRICTED);
}); });

View File

@ -45,24 +45,42 @@ export function parseOwnershipParameters(
}; };
} }
export function defaultValues(
isAdmin: boolean,
currentUserId: UserId
): AccessControlFormData {
if (!isAdmin) {
return {
ownership: ResourceControlOwnership.PRIVATE,
authorizedTeams: [],
authorizedUsers: [currentUserId],
};
}
return {
ownership: ResourceControlOwnership.ADMINISTRATORS,
authorizedTeams: [],
authorizedUsers: [],
};
}
export function parseAccessControlFormData( export function parseAccessControlFormData(
isAdmin: boolean, isAdmin: boolean,
currentUserId: UserId,
resourceControl?: ResourceControlViewModel resourceControl?: ResourceControlViewModel
): AccessControlFormData { ): AccessControlFormData {
let ownership = if (!resourceControl) {
resourceControl?.Ownership || ResourceControlOwnership.PRIVATE; return defaultValues(isAdmin, currentUserId);
if (isAdmin) { }
if (!resourceControl) {
ownership = ResourceControlOwnership.ADMINISTRATORS; let ownership = resourceControl.Ownership;
} else if (ownership === ResourceControlOwnership.PRIVATE) { if (isAdmin && ownership === ResourceControlOwnership.PRIVATE) {
ownership = ResourceControlOwnership.RESTRICTED; ownership = ResourceControlOwnership.RESTRICTED;
}
} }
let authorizedTeams: TeamId[] = []; let authorizedTeams: TeamId[] = [];
let authorizedUsers: UserId[] = []; let authorizedUsers: UserId[] = [];
if ( if (
resourceControl &&
[ [
ResourceControlOwnership.PRIVATE, ResourceControlOwnership.PRIVATE,
ResourceControlOwnership.RESTRICTED, ResourceControlOwnership.RESTRICTED,