Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSCFC4EMSCR-491 Implement MSCR copy in UI continues #186

Merged
merged 4 commits into from
Jun 20, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
MSCD-491 Simplify permissions and implement MSCR copy
maariaw committed Jun 14, 2024
commit 9f86bb7dbb06ba74698ac98b94eaf656e20df524
1 change: 1 addition & 0 deletions mscr-ui/public/locales/en/common.json
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
"finish-editing": "Finish editing",
"invalidate-crosswalk": "Invalidate crosswalk",
"invalidate-schema": "Invalidate schema",
"mscr-copy": "Make MSCR copy",
"publish-crosswalk": "Publish crosswalk",
"publish-schema": "Publish schema",
"revision": "Add new revision"
1 change: 1 addition & 0 deletions mscr-ui/public/locales/fi/common.json
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
"finish-editing": "",
"invalidate-crosswalk": "",
"invalidate-schema": "",
"mscr-copy": "",
"publish-crosswalk": "",
"publish-schema": "",
"revision": ""
1 change: 1 addition & 0 deletions mscr-ui/public/locales/sv/common.json
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
"finish-editing": "",
"invalidate-crosswalk": "",
"invalidate-schema": "",
"mscr-copy": "",
"publish-crosswalk": "",
"publish-schema": "",
"revision": ""
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@ export default function SchemaAndCrosswalkActionMenu({
const [isDeleteConfirmModalOpen, setDeleteConfirmModalOpen] = useState(false);
const [isRemoveConfirmModalOpen, setRemoveConfirmModalOpen] = useState(false);
const [isRevisionModalOpen, setRevisionModalOpen] = useState(false);
const [isMscrCopyModalOpen, setMscrCopyModalOpen] = useState(false);
const [isCrosswalkPublished, setCrosswalkPublished] =
React.useState<boolean>(false);
const [isLatestVersion, setIsLatestVersion] = useState(false);
@@ -202,6 +203,10 @@ export default function SchemaAndCrosswalkActionMenu({
}
}, [metadata.revisions, metadata.pid]);

if (type == ActionMenuTypes.NoEditPermission) {
return renderStubMenu();
}

return (
<>
<ActionMenuWrapper>
@@ -293,6 +298,17 @@ export default function SchemaAndCrosswalkActionMenu({
>
{t('actionmenu.revision')}
</ActionMenuItem>
<ActionMenuItem
className={
type === ActionMenuTypes.Schema ||
type === ActionMenuTypes.SchemaMetadata
? ''
: 'd-none'
}
onClick={() => setMscrCopyModalOpen(true)}
>
{t('actionmenu.mscr-copy')}
</ActionMenuItem>
</ActionMenu>
</ActionMenuWrapper>
<ConfirmModal
@@ -406,6 +422,36 @@ export default function SchemaAndCrosswalkActionMenu({
setVisible={setRevisionModalOpen}
initialData={metadata}
/>
<FormModal
modalType={ModalType.McsrCopy}
contentType={Type.Schema}
visible={isMscrCopyModalOpen}
setVisible={setMscrCopyModalOpen}
initialData={metadata}
/>
</>
);

function renderStubMenu() {
return (
<>
<ActionMenuWrapper>
<ActionMenu buttonText={t('action.actions')}>
<ActionMenuItem
onClick={() => setMscrCopyModalOpen(true)}
>
{t('actionmenu.mscr-copy')}
</ActionMenuItem>
</ActionMenu>
</ActionMenuWrapper>
<FormModal
modalType={ModalType.McsrCopy}
contentType={Type.Schema}
visible={isMscrCopyModalOpen}
setVisible={setMscrCopyModalOpen}
initialData={metadata}
/>
</>
);
}
}
11 changes: 11 additions & 0 deletions mscr-ui/src/common/components/schema/schema.slice.tsx
Original file line number Diff line number Diff line change
@@ -56,6 +56,16 @@ export const schemaApi = createApi({
},
})
}),
putSchemaMscrCopy: builder.mutation<Schema, { pid: string; data: Partial<Metadata> }>({
query: ({pid, data }) => ({
url: `/schema?action=mscrCopyOf&target=${pid}`,
method: 'PUT',
data: data,
headers: {
'content-Type': 'application/json;',
},
}),
}),
patchSchema: builder.mutation<
Metadata,
{
@@ -141,6 +151,7 @@ export const {
useGetSchemasQuery,
usePutSchemaFullMutation,
usePutSchemaRevisionMutation,
usePutSchemaMscrCopyMutation,
usePatchSchemaMutation,
util: { getRunningQueriesThunk },
} = schemaApi;
1 change: 1 addition & 0 deletions mscr-ui/src/common/interfaces/search.interface.ts
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ export enum ActionMenuTypes {
CrosswalkVersionInfo = 'CROSSWALK_VERSIONINFO',
Schema = 'SCHEMA',
SchemaMetadata = 'SCHEMA_METADATA',
NoEditPermission = 'NO_EDIT_PERMISSION',
}

export interface ResultInfo {
133 changes: 40 additions & 93 deletions mscr-ui/src/common/utils/has-permission.tsx
Original file line number Diff line number Diff line change
@@ -9,38 +9,37 @@ import {
import { User } from 'yti-common-ui/interfaces/user.interface';
import { Roles } from '../interfaces/format.interface';

// Need to specify the acctions permitted for each type of user
// Need to specify the actions permitted for each type of user
const actions = [
'CREATE_SCHEMA',
'EDIT_SCHEMA',
'EDIT_SCHEMA_METADATA',
'EDIT_SCHEMA_FILES',
'DELETE_SCHEMA',
'CREATE_CROSSWALK',
'EDIT_CROSSWALK_MAPPINGS',
'EDIT_CROSSWALK_METADATA',
'EDIT_CROSSWALK_FILES',
'DELETE_CROSSWALK',
// 'CREATE_SCHEMA',
// 'EDIT_SCHEMA',
// 'EDIT_SCHEMA_METADATA',
// 'EDIT_SCHEMA_FILES',
// 'DELETE_SCHEMA',
// 'CREATE_CROSSWALK',
// 'EDIT_CROSSWALK_MAPPINGS',
// 'EDIT_CROSSWALK_METADATA',
// 'EDIT_CROSSWALK_FILES',
// 'DELETE_CROSSWALK',
'EDIT_CONTENT',
'MAKE_MSCR_COPY'
] as const;

export type Actions = typeof actions[number];
export type Action = typeof actions[number];

export interface hasPermissionProps {
actions: Actions | Actions[];
targetOrganization?: string;
action: Action;
owner?: string[];
}

export interface checkPermissionProps {
user: User;
actions: Actions[];
targetOrganizations?: string[];
action: Action;
owner?: string[];
}

export default function HasPermission({
actions,
targetOrganization,
action,
owner,
}: hasPermissionProps) {
const { data: authenticatedUser } = useGetAuthenticatedUserQuery();
@@ -66,99 +65,47 @@ export default function HasPermission({
return false;
}

//No Target Organization
if (!targetOrganization) {
if (owner && owner.length) {
//Editing Step as already has owner
return checkEditPermission({
user,
actions: Array.isArray(actions) ? actions : [actions],
owner,
});
}
if (!owner || owner.length == 0) {
return checkPermission({
user,
actions: Array.isArray(actions) ? actions : [actions],
action,
});
}

//If there is target organization
if (owner && owner.length) {
//Editing Step as already has owner
return checkEditPermission({
user,
actions: Array.isArray(actions) ? actions : [actions],
targetOrganizations: [targetOrganization],
owner,
});
}
return checkPermission({
//Content Creation
user,
actions: Array.isArray(actions) ? actions : [actions],
targetOrganizations: [targetOrganization],
action,
owner
});
}

export function checkPermission({
user,
actions,
targetOrganizations,
}: checkPermissionProps) {

const rolesInOrganizations = Object.keys(user.organizationsInRole);

const rolesInTargetOrganizations =
targetOrganizations &&
targetOrganizations
?.flatMap((org) => user.rolesInOrganizations[org])
.filter((t) => t);

// Return true if user is superuser
if (user.superuser) {
return true;
}

// Return true if target organization is undefined and user has admin role
if (rolesInOrganizations.includes(Roles.admin) && !targetOrganizations) {
return true;
}

// console.log(rolesInTargetOrganizations);
// Return true if user has data model editor role in target organization
if (
rolesInTargetOrganizations?.includes(Roles.dataModelEditor)||rolesInTargetOrganizations?.includes(Roles.admin)
) {
return true;
}


return false;
}

export function checkEditPermission({
user,
action,
owner
}: checkPermissionProps) {
if (owner?.includes(user.id)) {
//user is the owner, Check for personal Contents
if (action == 'MAKE_MSCR_COPY') {
return true;
} else {
//Gruop Content

if (owner && user.organizationsInRole[Roles.admin]&& user.organizationsInRole[Roles.admin].includes(owner[0])) {
// User has admin right for this group
return true;
}

if (
owner &&user.organizationsInRole[Roles.dataModelEditor]&&
user.organizationsInRole[Roles.dataModelEditor].includes(owner[0])
) {
} else if (action == 'EDIT_CONTENT') {
if (owner?.includes(user.id)) {
//user is the owner, Check for personal Contents
return true;
} else {
//Group Content
if (owner && user.organizationsInRole[Roles.admin] && user.organizationsInRole[Roles.admin].includes(owner[0])) {
// User has admin right for this group
return true;
}

if (
owner && user.organizationsInRole[Roles.dataModelEditor] &&
user.organizationsInRole[Roles.dataModelEditor].includes(owner[0])
) {
// User has data model editor right for this group
return true;
}
}
}


return false;
}
20 changes: 12 additions & 8 deletions mscr-ui/src/modules/crosswalk-editor/index.tsx
Original file line number Diff line number Diff line change
@@ -150,7 +150,7 @@ export default function CrosswalkEditor({
} = useGetCrosswalkWithRevisionsQuery(crosswalkId);

const hasEditRights = HasPermission({
actions: ['EDIT_CROSSWALK_MAPPINGS'],
action: 'EDIT_CONTENT',
owner: getCrosswalkData?.owner,
});

@@ -723,13 +723,17 @@ export default function CrosswalkEditor({
</Grid>
<Grid item xs={6} className="d-flex justify-content-end">
<div className="mt-3 me-2">
<SchemaAndCrosswalkActionMenu
buttonCallbackFunction={performCallbackFromActionMenu}
metadata={getCrosswalkData}
isMappingsEditModeActive={isEditModeActive}
refetchMetadata={refetchCrosswalkData}
type={ActionMenuTypes.CrosswalkVersionInfo}
></SchemaAndCrosswalkActionMenu>
{hasEditRights &&
<SchemaAndCrosswalkActionMenu
buttonCallbackFunction={
performCallbackFromActionMenu
}
metadata={getCrosswalkData}
isMappingsEditModeActive={isEditModeActive}
refetchMetadata={refetchCrosswalkData}
type={ActionMenuTypes.CrosswalkVersionInfo}
/>
}
</div>
</Grid>
<Grid item xs={12}>
Original file line number Diff line number Diff line change
@@ -9,8 +9,9 @@ export default function MetadataAndFiles(props: {
crosswalkData: CrosswalkWithVersionInfo;
refetch: () => void;
}) {
const hasEditRights = HasPermission({ actions: ['EDIT_CROSSWALK_METADATA'],owner:props.crosswalkData.owner});
const hasFileRights = HasPermission({ actions: ['EDIT_CROSSWALK_FILES'],owner:props.crosswalkData.owner });
const hasEditRights = HasPermission({ action: 'EDIT_CONTENT',owner:props.crosswalkData.owner});
const hasFileRights = HasPermission({ action: 'EDIT_CONTENT',owner:props.crosswalkData.owner });
const hasCopyPermission = HasPermission({action: 'MAKE_MSCR_COPY'});

return (
<>
@@ -19,6 +20,7 @@ export default function MetadataAndFiles(props: {
metadata={props.crosswalkData}
refetchMetadata={props.refetch}
hasEditPermission={hasEditRights}
hasCopyPermission={hasCopyPermission}
/>
<br/>
<MetadataFilesTable
3 changes: 2 additions & 1 deletion mscr-ui/src/modules/form/generate-payload.tsx
Original file line number Diff line number Diff line change
@@ -81,7 +81,8 @@ export default function generatePayload(
}
} else if (
modalType == ModalType.RegisterNewFull ||
modalType == ModalType.RegisterNewMscr
modalType == ModalType.RegisterNewMscr ||
modalType == ModalType.McsrCopy
) {
if (contentType == Type.Schema) {
return schemaPayload;
Loading