Skip to content

Commit

Permalink
Merge pull request #6861 from DonOmalVindula/fix/26115
Browse files Browse the repository at this point in the history
  • Loading branch information
DonOmalVindula committed Sep 3, 2024
2 parents 4b7ce35 + 48f0d46 commit d30abf1
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 48 deletions.
7 changes: 7 additions & 0 deletions .changeset/dirty-grapes-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@wso2is/admin.extensions.v1": patch
"@wso2is/admin.groups.v1": patch
"@wso2is/theme": patch
---

Add config to disable add/delete actions for remote userstores
5 changes: 2 additions & 3 deletions features/admin.extensions.v1/configs/groups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import { GroupConfig } from "./models";

export const groupConfig: GroupConfig = {
addGroupWizard: {
showUserstoreDropdown: true
}
allowGroupAddForRemoteUserstores: true,
allowGroupDeleteForRemoteUserstores: true
};
24 changes: 3 additions & 21 deletions features/admin.extensions.v1/configs/models/group.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2021, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2021-2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand All @@ -16,26 +16,8 @@
* under the License.
*/

import { GroupsInterface } from "@wso2is/admin.groups.v1";

export interface GroupConfig {
addGroupWizard: {
requiredSteps?: string[];
showUserstoreDropdown?: boolean;
subHeading?: string;
submitStep?: string;
};
editGroups?: {
basicTab: {
showGroupNameLabel: boolean;
userstore: (groupObject: GroupsInterface) => string;
};
basicTabName: string;
showRolesTab: boolean;
};
groupsList?: {
description: string;
filterGroups: (groupResources: GroupsInterface[]) => GroupsInterface[];
showUserstoreDropdown: boolean;
};
allowGroupAddForRemoteUserstores: boolean;
allowGroupDeleteForRemoteUserstores: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2023-2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand All @@ -23,7 +23,7 @@ import {
UserStoreProperty,
history
} from "@wso2is/admin.core.v1";
import { userstoresConfig } from "@wso2is/admin.extensions.v1";
import { groupConfig, userstoresConfig } from "@wso2is/admin.extensions.v1";
import {
AlertInterface,
AlertLevels,
Expand Down Expand Up @@ -97,7 +97,10 @@ export const BasicGroupDetails: FunctionComponent<BasicGroupProps> = (props: Bas

const userStore: string = groupObject?.displayName?.split("/")?.length > 1
? groupObject.displayName.split("/")[0]
: SharedUserStoreConstants.PRIMARY_USER_STORE;
: userstoresConfig.primaryUserstoreName;

const isUserstoreDeleteDisabled: boolean = !groupConfig?.allowGroupDeleteForRemoteUserstores
&& userStore !== userstoresConfig.primaryUserstoreName;

useEffect(() => {
if (groupObject && groupObject.displayName.indexOf("/") !== -1) {
Expand All @@ -115,7 +118,7 @@ export const BasicGroupDetails: FunctionComponent<BasicGroupProps> = (props: Bas
const validateGroupNamePattern = async (): Promise<string> => {
let userStoreRegEx: string = "";

if (userStore !== SharedUserStoreConstants.PRIMARY_USER_STORE) {
if (userStore !== userstoresConfig.primaryUserstoreName) {
await SharedUserStoreUtils.getUserStoreRegEx(userStore,
SharedUserStoreConstants.USERSTORE_REGEX_PROPERTIES.RolenameRegEx)
.then((response: string) => {
Expand Down Expand Up @@ -352,7 +355,7 @@ export const BasicGroupDetails: FunctionComponent<BasicGroupProps> = (props: Bas
</EmphasizedSegment>
<Divider hidden />
{
!isReadOnly && (
!isReadOnly && !isUserstoreDeleteDisabled && (
<DangerZoneGroup sectionHeader="Danger Zone">
<DangerZone
actionTitle={
Expand Down
44 changes: 28 additions & 16 deletions features/admin.groups.v1/components/group-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
* under the License.
*/

import { Show } from "@wso2is/access-control";
import { Show, useRequiredScopes } from "@wso2is/access-control";
import {
AppConstants,
AppState,
FeatureConfigInterface,
UIConstants,
getEmptyPlaceholderIllustrations,
history
} from "@wso2is/admin.core.v1";
import { hasRequiredScopes, isFeatureEnabled } from "@wso2is/core/helpers";
import { userstoresConfig } from "@wso2is/admin.extensions.v1";
import { isFeatureEnabled } from "@wso2is/core/helpers";
import { LoadableComponentInterface, SBACInterface, TestableComponentInterface } from "@wso2is/core/models";
import {
AnimatedAvatar,
Expand All @@ -41,7 +41,6 @@ import {
import moment, { Moment } from "moment";
import React, { ReactElement, ReactNode, SyntheticEvent, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { Header, Icon, Label, SemanticICONS } from "semantic-ui-react";
import { GroupConstants } from "../constants";
import { GroupsInterface } from "../models";
Expand Down Expand Up @@ -102,6 +101,14 @@ interface GroupListProps extends SBACInterface<FeatureConfigInterface>,
* Indicates whether the currently selected user store is read-only or not.
*/
isReadOnlyUserStore?: boolean;
/**
* Flag to show/hide the delete action in the userstore list.
*/
isUserstoreDeleteDisabled?: boolean;
/**
* Flag to show/hide the add action in the userstore list.
*/
isUserstoreAddDisabled?: boolean;
}

/**
Expand All @@ -128,16 +135,19 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
showListItemActions,
showMetaContent,
isReadOnlyUserStore,
isUserstoreAddDisabled,
isUserstoreDeleteDisabled,
[ "data-testid" ]: testId
} = props;

const { t } = useTranslation();

const allowedScopes: string = useSelector((state: AppState) => state?.auth?.allowedScopes);

const [ showGroupDeleteConfirmation, setShowDeleteConfirmationModal ] = useState<boolean>(false);
const [ currentDeletedGroup, setCurrentDeletedGroup ] = useState<GroupsInterface>();

const hasGroupsUpdatePermission: boolean = useRequiredScopes(featureConfig?.groups?.scopes?.update);
const hasGroupsDeletePermission: boolean = useRequiredScopes(featureConfig?.groups?.scopes?.delete);

const handleGroupEdit = (groupId: string): void => {
history.push(AppConstants.getPaths().get("GROUP_EDIT").replace(":id", groupId));
};
Expand Down Expand Up @@ -214,7 +224,7 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
return (
<EmptyPlaceholder
data-testid={ `${ testId }-empty-list-empty-placeholder` }
action={ !isReadOnlyUserStore && (
action={ !isReadOnlyUserStore && !isUserstoreAddDisabled && (
<Show
when={ featureConfig?.groups?.scopes?.create }
>
Expand All @@ -231,14 +241,14 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
image={ getEmptyPlaceholderIllustrations().newList }
imageSize="tiny"
title={
isReadOnlyUserStore
(isReadOnlyUserStore || isUserstoreAddDisabled)
? t("roles:list.emptyPlaceholders.emptyRoleList.emptyRoles",
{ type: "groups" })
: t("roles:list.emptyPlaceholders.emptyRoleList.title",
{ type: "group" })
}
subtitle={
isReadOnlyUserStore
(isReadOnlyUserStore || isUserstoreAddDisabled)
? [
t("roles:list.emptyPlaceholders.emptyRoleList.subtitles.0",
{ type: "groups" })
Expand Down Expand Up @@ -341,11 +351,11 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
icon: (group: GroupsInterface): SemanticICONS => {
const userStore: string = group?.displayName?.split("/").length > 1
? group?.displayName?.split("/")[0]
: "PRIMARY";
: userstoresConfig?.primaryUserstoreName;

return !isFeatureEnabled(featureConfig?.groups,
GroupConstants.FEATURE_DICTIONARY.get("GROUP_UPDATE"))
|| !hasRequiredScopes(featureConfig?.groups, featureConfig?.groups?.scopes?.update, allowedScopes)
|| !hasGroupsUpdatePermission
|| readOnlyUserStores?.includes(userStore.toString())
? "eye"
: "pencil alternate";
Expand All @@ -355,11 +365,11 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
popupText: (group: GroupsInterface): string => {
const userStore: string = group?.displayName?.split("/").length > 1
? group?.displayName?.split("/")[0]
: "PRIMARY";
: userstoresConfig?.primaryUserstoreName;

return !isFeatureEnabled(featureConfig?.groups,
GroupConstants.FEATURE_DICTIONARY.get("GROUP_UPDATE"))
|| !hasRequiredScopes(featureConfig?.groups, featureConfig?.groups?.scopes?.update, allowedScopes)
|| !hasGroupsUpdatePermission
|| readOnlyUserStores?.includes(userStore.toString())
? t("common:view")
: t("common:edit");
Expand All @@ -372,10 +382,12 @@ export const GroupList: React.FunctionComponent<GroupListProps> = (props: GroupL
hidden: (group: GroupsInterface): boolean => {
const userStore: string = group?.displayName?.split("/").length > 1
? group?.displayName?.split("/")[0]
: "PRIMARY";
: userstoresConfig?.primaryUserstoreName;

return !hasRequiredScopes(featureConfig?.groups, featureConfig?.groups?.scopes?.delete, allowedScopes)
|| readOnlyUserStores?.includes(userStore.toString());
return !hasGroupsDeletePermission
|| readOnlyUserStores?.includes(userStore.toString())
|| isReadOnlyUserStore
|| isUserstoreDeleteDisabled;
},
icon: (): SemanticICONS => "trash alternate",
onClick: (e: SyntheticEvent, group: GroupsInterface): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export const GroupBasics: FunctionComponent<GroupBasicProps> = (props: GroupBasi
>
<Grid>
{
groupConfig?.addGroupWizard?.showUserstoreDropdown && (
groupConfig?.allowGroupAddForRemoteUserstores && (
<GridRow>
<RootOnlyComponent>
<GridColumn mobile={ 16 } tablet={ 16 } computer={ 10 }>
Expand Down
11 changes: 10 additions & 1 deletion features/admin.groups.v1/pages/groups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
getAUserStore,
getEmptyPlaceholderIllustrations
} from "@wso2is/admin.core.v1";
import { commonConfig, userstoresConfig } from "@wso2is/admin.extensions.v1/configs";
import { commonConfig, groupConfig, userstoresConfig } from "@wso2is/admin.extensions.v1/configs";
import { RootOnlyComponent } from "@wso2is/admin.organizations.v1/components";
import { useGetCurrentOrganizationType } from "@wso2is/admin.organizations.v1/hooks/use-get-organization-type";
import { getUserStoreList } from "@wso2is/admin.userstores.v1/api";
Expand Down Expand Up @@ -109,6 +109,11 @@ const GroupsPage: FunctionComponent<any> = (): ReactElement => {
mutate: mutateGroupsFetchRequest
} = useGroupList(userStore, "members,roles", searchQuery, true);

const isUserstoreDeleteDisabled: boolean = !groupConfig?.allowGroupDeleteForRemoteUserstores
&& userStore !== userstoresConfig.primaryUserstoreName;
const isUserstoreAddDisabled: boolean = !groupConfig?.allowGroupAddForRemoteUserstores
&& userStore !== userstoresConfig.primaryUserstoreName;

/**
* Indicates whether the currently selected user store is read-only or not.
*/
Expand Down Expand Up @@ -298,6 +303,8 @@ const GroupsPage: FunctionComponent<any> = (): ReactElement => {
<PageLayout
action={
(!isGroupsListRequestLoading && paginatedGroups?.length > 0)
&& !isUserstoreAddDisabled
&& !isReadOnlyUserStore
&& (
<Show
when={ featureConfig?.groups?.scopes?.create }
Expand Down Expand Up @@ -430,6 +437,8 @@ const GroupsPage: FunctionComponent<any> = (): ReactElement => {
readOnlyUserStores={ readOnlyUserStoresList }
featureConfig={ featureConfig }
isReadOnlyUserStore={ isReadOnlyUserStore }
isUserstoreAddDisabled={ isUserstoreAddDisabled }
isUserstoreDeleteDisabled={ isUserstoreDeleteDisabled }
/>)
}
</ListLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,6 @@ TODO : Move values to separate variables and cleanup styles.

.scroll-container {
height: calc(100vh - 450px);
min-width: 800px;
font-family: "Gilmer";
font-style: normal;
font-weight: 400;
Expand Down Expand Up @@ -1904,6 +1903,7 @@ TODO : Move values to separate variables and cleanup styles.
.email-template-resource-tab-pane {
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
pointer-events: none;
}

.email-template-preview {
Expand Down

0 comments on commit d30abf1

Please sign in to comment.