Skip to content

Commit

Permalink
add the config to modify the primary user store domain name in consol…
Browse files Browse the repository at this point in the history
…e app
  • Loading branch information
DilshanSenarath committed Jan 1, 2025
1 parent 2236b69 commit 00df8aa
Show file tree
Hide file tree
Showing 52 changed files with 421 additions and 240 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022-2023, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2022-2025, 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 Down Expand Up @@ -72,7 +72,7 @@ const getLicenseHeaderPattern = () => {
const LICENSE_HEADER_DEFAULT_PATTERN = [
"*",
{
pattern: " Copyright \\(c\\) \\b(2019|202[0-4])(?:-(202[0-4]))?, WSO2 LLC. \\(https://www.wso2.com\\).$",
pattern: " Copyright \\(c\\) \\b(2019|202[0-5])(?:-(202[0-5]))?, WSO2 LLC. \\(https://www.wso2.com\\).$",
template: " * Copyright (c) {{year}}, WSO2 LLC. (https://www.wso2.com)."
},
" *",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,9 @@
{% endfor %}
{% endif %}
],
{% if user_store.properties.DomainName is defined %}
"primaryUserStoreDomainName": "{{ user_store.properties.DomainName }}",
{% endif %}
"hiddenUserStores": [
{% if console.ui.hidden_user_stores is defined %}
{% for value in console.ui.hidden_user_stores %}
Expand Down
15 changes: 10 additions & 5 deletions features/admin.administrators.v1/components/all-users-list.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2024-2025, 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 Down Expand Up @@ -170,6 +170,8 @@ export const AllUsersList: React.FunctionComponent<AllUsersListProps> = (props:
const [ loading, setLoading ] = useState(false);

const authenticatedUser: string = useSelector((state: AppState) => state?.auth?.username);
const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

/**
* Set tenant admin.
Expand All @@ -196,7 +198,7 @@ export const AllUsersList: React.FunctionComponent<AllUsersListProps> = (props:
const allowedScopes: string = useSelector((state: AppState) => state?.auth?.allowedScopes);

const handleUserEdit = (user: UserBasicInterface) => {
if (resolveUserstore(user.userName) === userstoresConfig.primaryUserstoreName) {
if (resolveUserstore(user.userName, primaryUserStoreDomainName) === userstoresConfig.primaryUserstoreName) {
history.push(AdministratorConstants.getPaths().get("CUSTOMER_USER_EDIT_PATH").replace(":id", user.id));
} else {
history.push(AdministratorConstants.getPaths().get("COLLABORATOR_USER_EDIT_PATH").replace(":id", user.id));
Expand Down Expand Up @@ -289,7 +291,8 @@ export const AllUsersList: React.FunctionComponent<AllUsersListProps> = (props:
if (user.userName === tenantAdmin) {
return "Owner";
}
if (resolveUserstore(user.userName) === userstoresConfig.primaryUserstoreName) {
if (resolveUserstore(user.userName, primaryUserStoreDomainName)
=== userstoresConfig.primaryUserstoreName) {
return UserAccountTypes.USER;
} else {
return administratorConfig.adminRoleName;
Expand Down Expand Up @@ -599,14 +602,16 @@ export const AllUsersList: React.FunctionComponent<AllUsersListProps> = (props:
attached
negative
>
{ resolveUserstore(deletingUser.userName) === userstoresConfig.primaryUserstoreName
{ resolveUserstore(deletingUser.userName, primaryUserStoreDomainName)
=== userstoresConfig.primaryUserstoreName
? t("user:deleteUser.confirmationModal.message")
: t("extensions:manage.guest.deleteUser.confirmationModal.message")
}
</ConfirmationModal.Message>
<ConfirmationModal.Content data-testid={ `${ testId }-confirmation-modal-content` }>
<div className="modal-alert-wrapper"> { alert && alertComponent }</div>
{ resolveUserstore(deletingUser.userName) === userstoresConfig.primaryUserstoreName
{ resolveUserstore(deletingUser.userName, primaryUserStoreDomainName)
=== userstoresConfig.primaryUserstoreName
? (
deletingUser[SCIMConfigs.scim.enterpriseSchema]?.userSourceId
? t("user:deleteJITUser.confirmationModal.content")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2024-2025, 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 @@ -26,7 +26,6 @@ import { UserRolesList } from "@wso2is/admin.users.v1/components/user-roles-list
import { UserSessions } from "@wso2is/admin.users.v1/components/user-sessions";
import { AdminAccountTypes, UserManagementConstants } from "@wso2is/admin.users.v1/constants/user-management-constants";
import { UserManagementUtils } from "@wso2is/admin.users.v1/utils/user-management-utils";
import { UserstoreConstants } from "@wso2is/core/constants";
import { hasRequiredScopes, isFeatureEnabled } from "@wso2is/core/helpers";

Check failure on line 29 in features/admin.administrators.v1/components/guests/edit-guest-user.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint (STATIC ANALYSIS) (lts/*, 8.7.4)

'hasRequiredScopes' import from '@wso2is/core/helpers' is restricted. Please use "import { useRequiredScopes } from '@wso2is/access-control'" instead. Refer documentation: https://github.com/wso2/identity-apps/blob/master/docs/write-code/PERFORMANCE.md#use-userequiredscopes-hook-instead-of-hasrequiredscopes-function
import { AlertInterface, ProfileInfoInterface, SBACInterface } from "@wso2is/core/models";
import { addAlert } from "@wso2is/core/store";
Expand Down Expand Up @@ -95,6 +94,8 @@ export const EditGuestUser: FunctionComponent<EditGuestUserPropsInterface> = (
const [ adminUserType, setAdminUserType ] = useState<string>(AdminAccountTypes.EXTERNAL);

const authenticatedUserTenanted: string = useSelector((state: AppState) => state?.auth?.username);
const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const authenticatedUser: string = useMemo(() => {
const authenticatedUserComponents: string[] = authenticatedUserTenanted.split("@");
Expand All @@ -120,7 +121,7 @@ export const EditGuestUser: FunctionComponent<EditGuestUserPropsInterface> = (

const userStore: string = user?.userName?.split("/").length > 1
? user?.userName?.split("/")[ 0 ]
: UserstoreConstants.PRIMARY_USER_STORE;
: primaryUserStoreDomainName;

setReadOnlyUserStore(readOnlyUserStores?.includes(userStore?.toString()));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2024-2025, 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 @@ -24,7 +24,6 @@ import {
UserListInterface
} from "@wso2is/admin.core.v1";
import { InvitationStatus, UserInviteInterface } from "@wso2is/admin.users.v1/models";
import { PRIMARY_USERSTORE } from "@wso2is/admin.userstores.v1/constants/user-store-constants";
import { TestableComponentInterface } from "@wso2is/core/models";
import { DocumentationLink, ListLayout, Message, Text, useDocumentation } from "@wso2is/react-components";
import React, { FunctionComponent, ReactElement, useEffect, useState } from "react";
Expand Down Expand Up @@ -97,6 +96,8 @@ const GuestUsersPage: FunctionComponent<GuestUsersPageInterface> = (
const [ isInvitationStatusOptionChanged, setIsInvitationStatusOptionChanged ] = useState<boolean>(false);

const featureConfig: FeatureConfigInterface = useSelector((state: AppState) => state.config.ui.features);
const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

/**
* Show the description message for the first time.
Expand Down Expand Up @@ -191,9 +192,9 @@ const GuestUsersPage: FunctionComponent<GuestUsersPageInterface> = (
useEffect(() => {
if (invitationStatusOption === InvitationStatus.ACCEPTED) {
if (searchQuery == undefined || searchQuery == "") {
getUsersList(listItemLimit, listOffset + 1, null, null, PRIMARY_USERSTORE);
getUsersList(listItemLimit, listOffset + 1, null, null, primaryUserStoreDomainName);
} else {
getUsersList(listItemLimit, listOffset + 1, searchQuery, null, PRIMARY_USERSTORE);
getUsersList(listItemLimit, listOffset + 1, searchQuery, null, primaryUserStoreDomainName);
}
}
}, [ listOffset, listItemLimit ]);
Expand Down Expand Up @@ -271,11 +272,11 @@ const GuestUsersPage: FunctionComponent<GuestUsersPageInterface> = (
setSearchQuery(query);
if (invitationStatusOption === InvitationStatus.ACCEPTED) {
if (query === "userName sw ") {
getUsersList(listItemLimit, listOffset, null, null, PRIMARY_USERSTORE);
getUsersList(listItemLimit, listOffset, null, null, primaryUserStoreDomainName);

return;
}
getUsersList(listItemLimit, listOffset, query, null, PRIMARY_USERSTORE);
getUsersList(listItemLimit, listOffset, query, null, primaryUserStoreDomainName);
}
};

Expand Down Expand Up @@ -457,7 +458,7 @@ const GuestUsersPage: FunctionComponent<GuestUsersPageInterface> = (
readOnlyUserStores={ null }
featureConfig={ featureConfig }
onUserDelete={ () =>
getUsersList(listItemLimit, listOffset, null, null, PRIMARY_USERSTORE)
getUsersList(listItemLimit, listOffset, null, null, primaryUserStoreDomainName)
}
/>)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2024-2025, 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 Down Expand Up @@ -42,7 +42,6 @@ import {
UserListInterface
} from "@wso2is/admin.users.v1/models";
import { UserManagementUtils } from "@wso2is/admin.users.v1/utils";
import { UserstoreConstants } from "@wso2is/core/constants";
import { IdentityAppsApiException } from "@wso2is/core/exceptions";
import { getUserNameWithoutDomain, isFeatureEnabled } from "@wso2is/core/helpers";
import {
Expand Down Expand Up @@ -196,6 +195,8 @@ export const OnboardedGuestUsersList: React.FunctionComponent<OnboardedGuestUser

const authenticatedUser: string = useSelector((state: AppState) => state?.auth?.username);
const isPrivilegedUser: boolean = useSelector((state: AppState) => state.auth.isPrivilegedUser);
const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const saasFeatureStatus : FeatureStatus = useCheckFeatureStatus(FeatureGateConstants.SAAS_FEATURES_IDENTIFIER);

Expand Down Expand Up @@ -490,7 +491,7 @@ export const OnboardedGuestUsersList: React.FunctionComponent<OnboardedGuestUser
icon: (user: UserBasicInterface): SemanticICONS => {
const userStore: string = user?.userName?.split("/").length > 1
? user?.userName?.split("/")[0]
: "PRIMARY";
: primaryUserStoreDomainName;

return (
!hasUserUpdatePermissions
Expand All @@ -507,7 +508,7 @@ export const OnboardedGuestUsersList: React.FunctionComponent<OnboardedGuestUser
popupText: (user: UserBasicInterface): string => {
const userStore: string = user?.userName?.split("/").length > 1
? user?.userName?.split("/")[0]
: "PRIMARY";
: primaryUserStoreDomainName;

return (
!hasUserUpdatePermissions
Expand All @@ -527,7 +528,7 @@ export const OnboardedGuestUsersList: React.FunctionComponent<OnboardedGuestUser
hidden: (user: UserBasicInterface): boolean => {
const userStore: string = user?.userName?.split("/").length > 1
? user?.userName?.split("/")[0]
: UserstoreConstants.PRIMARY_USER_STORE;
: primaryUserStoreDomainName;

return !isFeatureEnabled(featureConfig?.users,
UserManagementConstants.FEATURE_DICTIONARY.get("USER_DELETE"))
Expand Down
7 changes: 4 additions & 3 deletions features/admin.administrators.v1/pages/administrators.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
* Copyright (c) 2024-2025, 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 Down Expand Up @@ -64,7 +64,6 @@ import { UserManagementUtils } from "@wso2is/admin.users.v1/utils";
import { getUserStores } from "@wso2is/admin.userstores.v1/api";
import {
CONSUMER_USERSTORE,
PRIMARY_USERSTORE,
UserStoreManagementConstants
} from "@wso2is/admin.userstores.v1/constants";
import { IdentityAppsError } from "@wso2is/core/errors";
Expand Down Expand Up @@ -161,6 +160,8 @@ const CollaboratorsPage: FunctionComponent<CollaboratorsPageInterface> = (
const authUserTenants: TenantInfo[] = useSelector((state: AppState) => state?.auth?.tenants);
const guestUserFeatureConfig: FeatureAccessConfigInterface = useSelector((state: AppState) =>
state.config.ui.features.guestUser);
const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const hasGuestUserCreatePermissions: boolean = useRequiredScopes(
guestUserFeatureConfig?.scopes?.create
Expand Down Expand Up @@ -251,7 +252,7 @@ const CollaboratorsPage: FunctionComponent<CollaboratorsPageInterface> = (
: searchQuery
),
null,
PRIMARY_USERSTORE,
primaryUserStoreDomainName,
excludedAttributes,
!administratorConfig.enableAdminInvite || invitationStatusOption === InvitationStatus.ACCEPTED
);
Expand Down
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-2025, 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 Down Expand Up @@ -68,6 +68,9 @@ const ApplicationRoleGroups = (props: ApplicationRoleGroupsProps): ReactElement
const { t } = useTranslation();
const dispatch: Dispatch = useDispatch();

const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const featureConfig: FeatureConfigInterface = useSelector((state: AppState) => state.config.ui.features);

const hasApplicationRolesUpdatePermissions: boolean = useRequiredScopes(
Expand Down Expand Up @@ -326,7 +329,7 @@ const ApplicationRoleGroups = (props: ApplicationRoleGroupsProps): ReactElement
id: "type",
key: "type",
render: (group: ApplicationRoleGroupInterface): ReactNode => {
const grpName: string = resolveUserstore(group.name);
const grpName: string = resolveUserstore(group.name, primaryUserStoreDomainName);

if (grpName === CONSUMER_USERSTORE) {
return CONSUMER_USERSTORE;
Expand Down
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-2025, 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 @@ -15,7 +15,8 @@
* specific language governing permissions and limitations
* under the License.
*/
import { UIConstants } from "@wso2is/admin.core.v1";

import { AppState, UIConstants } from "@wso2is/admin.core.v1";
import { CONSUMER_USERSTORE } from "@wso2is/admin.userstores.v1/constants";
import { IdentityAppsApiException } from "@wso2is/core/exceptions";
import { resolveUserstore } from "@wso2is/core/helpers";
Expand All @@ -33,7 +34,7 @@ import {
} from "@wso2is/react-components";
import React, { ChangeEvent, ReactElement, ReactNode, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { Dispatch } from "redux";
import { Grid, Header, Icon, Input } from "semantic-ui-react";
import { useApplicationRoleInvitedUserGroups, useDescendantsOfSubOrg } from "../api/application-roles";
Expand All @@ -57,6 +58,9 @@ const ApplicationRoleInvitedUserGroups = (props: ApplicationRoleGroupsProps): Re
const { t } = useTranslation();
const dispatch: Dispatch = useDispatch();

const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const [ searchQuery, setSearchQuery ] = useState<string>("");
const [ processedGroupsList, setProcessedGroupsList ] = useState<ApplicationRoleGroupInterface[]>([]);
const [ initialGroupsList, setInitialGroupsList ] = useState<ApplicationRoleGroupInterface[]>([]);
Expand Down Expand Up @@ -268,7 +272,7 @@ const ApplicationRoleInvitedUserGroups = (props: ApplicationRoleGroupsProps): Re
id: "type",
key: "type",
render: (group: ApplicationRoleGroupInterface): ReactNode => {
const grpName: string = resolveUserstore(group.name);
const grpName: string = resolveUserstore(group.name, primaryUserStoreDomainName);

if (grpName === CONSUMER_USERSTORE) {
return CONSUMER_USERSTORE;
Expand Down
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-2025, 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,8 +16,11 @@
* under the License.
*/

import { AppState } from "@wso2is/admin.core.v1";
import { getGroupList } from "@wso2is/admin.groups.v1/api";
import { PRIMARY_USERSTORE } from "@wso2is/admin.userstores.v1/constants";
import { IdentifiableComponentInterface, RolesInterface } from "@wso2is/core/models";
import { StringUtils } from "@wso2is/core/utils";
import {
ContentLoader,
Heading,
Expand All @@ -32,6 +35,7 @@ import escapeRegExp from "lodash-es/escapeRegExp";
import isEmpty from "lodash-es/isEmpty";
import React, { FormEvent, ReactElement, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { Grid, Modal } from "semantic-ui-react";
import { ApplicationRoleGroupInterface, ApplicationRoleGroupsAPIResponseInterface } from "../models/application-roles";

Expand Down Expand Up @@ -60,6 +64,9 @@ const AssignGroupWizard = (props: AssignGroupProps): ReactElement => {

const { t } = useTranslation();

const primaryUserStoreDomainName: string = useSelector((state: AppState) =>
state?.config?.ui?.primaryUserStoreDomainName);

const [ isLoading, setLoading ] = useState<boolean>(true);
const [ groupList, setGroupsList ] = useState<RolesInterface[]>([]);
const [ tempGroupList, setTempGroupList ] = useState<RolesInterface[]>([]);
Expand Down Expand Up @@ -205,7 +212,12 @@ const AssignGroupWizard = (props: AssignGroupProps): ReactElement => {
if (group.length > 1) {
return { labelColor: "teal", labelText: group[0].toString() };
} else {
return { labelColor: "olive", labelText: "Primary" };
return {
labelColor: "olive",
labelText: StringUtils.isEqualCaseInsensitive(primaryUserStoreDomainName, PRIMARY_USERSTORE)
? t("console:manage.features.users.userstores.userstoreOptions.primary")
: primaryUserStoreDomainName
};
}
};

Expand Down
Loading

0 comments on commit 00df8aa

Please sign in to comment.