diff --git a/app/client/cypress/e2e/Regression/ClientSide/Branding/Branding_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Branding/Branding_spec.js index fe7929010443..ae4149c48ff8 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Branding/Branding_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Branding/Branding_spec.js @@ -40,17 +40,17 @@ describe("Branding", { tags: ["@tag.Settings"] }, () => { let favicon; let shades = {}; - it("1. check if localStorage is populated with tenantConfig values", () => { + it("1. check if localStorage is populated with organizationConfig values", () => { if (CURRENT_REPO === REPO.CE) { - const tenantConfig = localStorage.getItem("tenantConfig"); + const organizationConfig = localStorage.getItem("organizationConfig"); - expect(tenantConfig).to.be.null; + expect(organizationConfig).to.be.null; } if (CURRENT_REPO === REPO.EE) { - const tenantConfig = localStorage.getItem("tenantConfig"); + const organizationConfig = localStorage.getItem("organizationConfig"); - expect(tenantConfig).to.not.be.null; + expect(organizationConfig).to.not.be.null; } }); @@ -123,10 +123,10 @@ describe("Branding", { tags: ["@tag.Settings"] }, () => { ); }); - it("4. Check if localStorage is populated with tenantConfig values & form cannot be submitted", () => { + it("4. Check if localStorage is populated with organizationConfig values & form cannot be submitted", () => { if (CURRENT_REPO === REPO.CE) { - const tenantConfig = localStorage.getItem("tenantConfig"); - expect(tenantConfig).to.be.null; + const organizationConfig = localStorage.getItem("organizationConfig"); + expect(organizationConfig).to.be.null; cy.get(locators.submitButton).should("be.disabled"); } diff --git a/app/client/src/ce/AppRouter.tsx b/app/client/src/ce/AppRouter.tsx index 9e78b3b25e53..6d4f72eea78c 100644 --- a/app/client/src/ce/AppRouter.tsx +++ b/app/client/src/ce/AppRouter.tsx @@ -52,7 +52,7 @@ import SignupSuccess from "pages/setup/SignupSuccess"; import type { ERROR_CODES } from "ee/constants/ApiConstants"; import TemplatesListLoader from "pages/Templates/loader"; import { getCurrentUser as getCurrentUserSelector } from "selectors/usersSelectors"; -import { getTenantPermissions } from "ee/selectors/tenantSelectors"; +import { getOrganizationPermissions } from "ee/selectors/organizationSelectors"; import useBrandingTheme from "utils/hooks/useBrandingTheme"; import RouteChangeListener from "RouteChangeListener"; import { initCurrentPage } from "../actions/initActions"; @@ -71,7 +71,7 @@ export const loadingIndicator = ; export function Routes() { const user = useSelector(getCurrentUserSelector); - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); useFeatureFlagOverride(); @@ -102,7 +102,7 @@ export function Routes() { : getAdminSettingsPath( isFeatureEnabled, user?.isSuperUser || false, - tenantPermissions, + organizationPermissions, ) } /> @@ -161,7 +161,7 @@ export default function AppRouter() { const isLoading = isConsolidatedPageLoading; - // hide the top loader once the tenant is loaded + // hide the top loader once the organization is loaded useEffect(() => { if (!isLoading) { const loader = document.getElementById("loader") as HTMLDivElement; diff --git a/app/client/src/ce/actions/organizationActions.ts b/app/client/src/ce/actions/organizationActions.ts new file mode 100644 index 000000000000..e65b80af230f --- /dev/null +++ b/app/client/src/ce/actions/organizationActions.ts @@ -0,0 +1,21 @@ +import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; +import type { UpdateOrganizationConfigRequest } from "ee/api/OrganizationApi"; +import type { ApiResponse } from "api/ApiResponses"; + +export const getCurrentOrganization = ( + isBackgroundRequest = true, + organizationConfig?: ApiResponse, +) => ({ + type: ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG, + payload: { + isBackgroundRequest, + organizationConfig, + }, +}); + +export const updateOrganizationConfig = ( + payload: UpdateOrganizationConfigRequest, +) => ({ + type: ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG, + payload, +}); diff --git a/app/client/src/ce/actions/tenantActions.ts b/app/client/src/ce/actions/tenantActions.ts deleted file mode 100644 index 6e4668f936dd..000000000000 --- a/app/client/src/ce/actions/tenantActions.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; -import type { UpdateTenantConfigRequest } from "ee/api/TenantApi"; -import type { ApiResponse } from "api/ApiResponses"; - -export const getCurrentTenant = ( - isBackgroundRequest = true, - tenantConfig?: ApiResponse, -) => ({ - type: ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG, - payload: { - isBackgroundRequest, - tenantConfig, - }, -}); - -export const updateTenantConfig = (payload: UpdateTenantConfigRequest) => ({ - type: ReduxActionTypes.UPDATE_TENANT_CONFIG, - payload, -}); diff --git a/app/client/src/ce/api/OrganizationApi.ts b/app/client/src/ce/api/OrganizationApi.ts new file mode 100644 index 000000000000..4476731652af --- /dev/null +++ b/app/client/src/ce/api/OrganizationApi.ts @@ -0,0 +1,46 @@ +import type { AxiosPromise, AxiosRequestConfig } from "axios"; + +import Api from "api/Api"; +import type { ApiResponse } from "api/ApiResponses"; + +export type FetchCurrentOrganizationConfigResponse = ApiResponse<{ + userPermissions: string[]; + organizationConfiguration: Record; + new: boolean; +}>; + +export type UpdateOrganizationConfigResponse = ApiResponse<{ + organizationConfiguration: Record; +}>; + +export interface UpdateOrganizationConfigRequest { + organizationConfiguration: Record; + needsRefresh?: boolean; + isOnlyOrganizationSettings?: boolean; + apiConfig?: AxiosRequestConfig; +} + +export class OrganizationApi extends Api { + static tenantsUrl = "v1/tenants"; + + static async fetchCurrentOrganizationConfig(): Promise< + AxiosPromise + > { + return Api.get(`${OrganizationApi.tenantsUrl}/current`); + } + + static async updateOrganizationConfig( + request: UpdateOrganizationConfigRequest, + ): Promise> { + return Api.put( + `${OrganizationApi.tenantsUrl}`, + request.organizationConfiguration, + null, + { + ...(request.apiConfig || {}), + }, + ); + } +} + +export default OrganizationApi; diff --git a/app/client/src/ce/api/TenantApi.ts b/app/client/src/ce/api/TenantApi.ts deleted file mode 100644 index 81560d029f8e..000000000000 --- a/app/client/src/ce/api/TenantApi.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { AxiosPromise, AxiosRequestConfig } from "axios"; - -import Api from "api/Api"; -import type { ApiResponse } from "api/ApiResponses"; - -export type FetchCurrentTenantConfigResponse = ApiResponse<{ - userPermissions: string[]; - tenantConfiguration: Record; - new: boolean; -}>; - -export type UpdateTenantConfigResponse = ApiResponse<{ - tenantConfiguration: Record; -}>; - -export interface UpdateTenantConfigRequest { - tenantConfiguration: Record; - needsRefresh?: boolean; - isOnlyTenantSettings?: boolean; - apiConfig?: AxiosRequestConfig; -} - -export class TenantApi extends Api { - static tenantsUrl = "v1/tenants"; - - static async fetchCurrentTenantConfig(): Promise< - AxiosPromise - > { - return Api.get(`${TenantApi.tenantsUrl}/current`); - } - - static async updateTenantConfig( - request: UpdateTenantConfigRequest, - ): Promise> { - return Api.put( - `${TenantApi.tenantsUrl}`, - request.tenantConfiguration, - null, - { - ...(request.apiConfig || {}), - }, - ); - } -} - -export default TenantApi; diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index bacbf4ce3d6b..769eebc4977a 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -1197,19 +1197,21 @@ const AppSettingsActionTypes = { "UPDATE_APP_SETTINGS_PANE_SELECTED_TAB", }; -const TenantActionTypes = { - FETCH_CURRENT_TENANT_CONFIG: "FETCH_CURRENT_TENANT_CONFIG", - FETCH_CURRENT_TENANT_CONFIG_SUCCESS: "FETCH_CURRENT_TENANT_CONFIG_SUCCESS", - UPDATE_TENANT_CONFIG: "UPDATE_TENANT_CONFIG", - UPDATE_TENANT_CONFIG_SUCCESS: "UPDATE_TENANT_CONFIG_SUCCESS", +const OrganizationActionTypes = { + FETCH_CURRENT_ORGANIZATION_CONFIG: "FETCH_CURRENT_ORGANIZATION_CONFIG", + FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS: + "FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS", + UPDATE_ORGANIZATION_CONFIG: "UPDATE_ORGANIZATION_CONFIG", + UPDATE_ORGANIZATION_CONFIG_SUCCESS: "UPDATE_ORGANIZATION_CONFIG_SUCCESS", FETCH_PRODUCT_ALERT_INIT: "FETCH_PRODUCT_ALERT_INIT", FETCH_PRODUCT_ALERT_SUCCESS: "FETCH_PRODUCT_ALERT_SUCCESS", UPDATE_PRODUCT_ALERT_CONFIG: "UPDATE_PRODUCT_ALERT_CONFIG", }; -const TenantActionErrorTypes = { - FETCH_CURRENT_TENANT_CONFIG_ERROR: "FETCH_CURRENT_TENANT_CONFIG_ERROR", - UPDATE_TENANT_CONFIG_ERROR: "UPDATE_TENANT_CONFIG_ERROR", +const OrganizationActionErrorTypes = { + FETCH_CURRENT_ORGANIZATION_CONFIG_ERROR: + "FETCH_CURRENT_ORGANIZATION_CONFIG_ERROR", + UPDATE_ORGANIZATION_CONFIG_ERROR: "UPDATE_ORGANIZATION_CONFIG_ERROR", FETCH_PRODUCT_ALERT_FAILED: "FETCH_PRODUCT_ALERT_FAILED", }; @@ -1290,7 +1292,7 @@ export const ReduxActionTypes = { ...SnippingModeActionTypes, ...TableWidgetActionsTypes, ...TemplateActionsTypes, - ...TenantActionTypes, + ...OrganizationActionTypes, ...ThemeActionTypes, ...UserAuthActionTypes, ...UserProfileActionTypes, @@ -1320,7 +1322,7 @@ export const ReduxActionErrorTypes = { ...PlatformActionErrorTypes, ...PluginActionErrorTypes, ...TemplateActionErrorTypes, - ...TenantActionErrorTypes, + ...OrganizationActionErrorTypes, ...UserAuthActionErrorTypes, ...UserProfileActionErrorTypes, ...WidgetCanvasActionErrorTypes, @@ -1336,7 +1338,7 @@ export const toastMessageErrorTypes = { ...GitActionErrorTypes, ...ImportExportActionErrorTypes, ...PlatformActionErrorTypes, - ...TenantActionErrorTypes, + ...OrganizationActionErrorTypes, ...UserAuthActionErrorTypes, ...UserProfileActionErrorTypes, ...WorkspaceActionErrorTypes, diff --git a/app/client/src/ce/constants/tenantConstants.ts b/app/client/src/ce/constants/organizationConstants.ts similarity index 88% rename from app/client/src/ce/constants/tenantConstants.ts rename to app/client/src/ce/constants/organizationConstants.ts index 8ab31888f464..0168039c00bd 100644 --- a/app/client/src/ce/constants/tenantConstants.ts +++ b/app/client/src/ce/constants/organizationConstants.ts @@ -1,4 +1,4 @@ -export const tenantConfigConnection: string[] = [ +export const organizationConfigConnection: string[] = [ "instanceName", "googleMapsKey", "emailVerificationEnabled", diff --git a/app/client/src/ce/pages/AdminSettings/config/authentication.tsx b/app/client/src/ce/pages/AdminSettings/config/authentication.tsx index 2d46cae39c18..8cb3b1544cde 100644 --- a/app/client/src/ce/pages/AdminSettings/config/authentication.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/authentication.tsx @@ -22,7 +22,7 @@ import { useSelector } from "react-redux"; import { getThirdPartyAuths, getIsFormLoginEnabled, -} from "ee/selectors/tenantSelectors"; +} from "ee/selectors/organizationSelectors"; import { FORM_LOGIN_DESC, GITHUB_AUTH_DESC, diff --git a/app/client/src/ce/pages/AdminSettings/config/general.tsx b/app/client/src/ce/pages/AdminSettings/config/general.tsx index ce70177f71f5..ae0ba589e46d 100644 --- a/app/client/src/ce/pages/AdminSettings/config/general.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/general.tsx @@ -110,7 +110,7 @@ export const APPSMITH_IS_ATOMIC_PUSH_ALLOWED: Setting = { category: SettingCategories.GENERAL, controlType: SettingTypes.CHECKBOX, label: "Allow atomic pushes", - text: "Git operations on this tenant should attempt to perform pushes atomically", + text: "Git operations on this organization should attempt to perform pushes atomically", }; export const APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING: Setting = { diff --git a/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx b/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx index 06940dc36fcc..b80fdc7c7bc2 100644 --- a/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx +++ b/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx @@ -15,8 +15,8 @@ jest.mock("selectors/gitModSelectors", () => ({ const defaultStoreState = { ...unitTestBaseMockStore, - tenant: { - tenantConfiguration: {}, + organization: { + organizationConfiguration: {}, }, entities: { ...unitTestBaseMockStore.entities, diff --git a/app/client/src/ce/pages/Applications/CreateNewAppsOption.tsx b/app/client/src/ce/pages/Applications/CreateNewAppsOption.tsx index 465c87898aca..c306a5396e31 100644 --- a/app/client/src/ce/pages/Applications/CreateNewAppsOption.tsx +++ b/app/client/src/ce/pages/Applications/CreateNewAppsOption.tsx @@ -27,7 +27,7 @@ import { fetchMockDatasources } from "actions/datasourceActions"; import DatasourceForm from "pages/Editor/SaaSEditor/DatasourceForm"; import type { Datasource } from "entities/Datasource"; import { fetchingEnvironmentConfigs } from "ee/actions/environmentAction"; -import { shouldShowLicenseBanner } from "ee/selectors/tenantSelectors"; +import { shouldShowLicenseBanner } from "ee/selectors/organizationSelectors"; import { isAirgapped } from "ee/utils/airgapHelpers"; const SectionWrapper = styled.div<{ isBannerVisible: boolean }>` diff --git a/app/client/src/ce/pages/Applications/index.tsx b/app/client/src/ce/pages/Applications/index.tsx index 393c3530e9bb..f04d3e39e388 100644 --- a/app/client/src/ce/pages/Applications/index.tsx +++ b/app/client/src/ce/pages/Applications/index.tsx @@ -97,9 +97,9 @@ import { getIsFetchingApplications, } from "ee/selectors/selectedWorkspaceSelectors"; import { - getTenantPermissions, + getOrganizationPermissions, shouldShowLicenseBanner, -} from "ee/selectors/tenantSelectors"; +} from "ee/selectors/organizationSelectors"; import { getWorkflowsList } from "ee/selectors/workflowSelectors"; import { getFetchedWorkspaces, @@ -301,12 +301,12 @@ export function LeftPaneSection(props: { }) { const dispatch = useDispatch(); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const fetchedWorkspaces = useSelector(getFetchedWorkspaces); const canCreateWorkspace = getHasCreateWorkspacePermission( isFeatureEnabled, - tenantPermissions, + organizationPermissions, ); const createNewWorkspace = async () => { diff --git a/app/client/src/ce/reducers/index.tsx b/app/client/src/ce/reducers/index.tsx index 522215056c91..e7537b9e557a 100644 --- a/app/client/src/ce/reducers/index.tsx +++ b/app/client/src/ce/reducers/index.tsx @@ -54,8 +54,8 @@ import SettingsReducer from "ee/reducers/settingsReducer"; import type { TriggerValuesEvaluationState } from "reducers/evaluationReducers/triggerReducer"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; import type { AppSettingsPaneReduxState } from "reducers/uiReducers/appSettingsPaneReducer"; -import type { TenantReduxState } from "ee/reducers/tenantReducer"; -import tenantReducer from "ee/reducers/tenantReducer"; +import type { OrganizationReduxState } from "ee/reducers/organizationReducer"; +import organizationReducer from "ee/reducers/organizationReducer"; import type { FocusHistoryState } from "reducers/uiReducers/focusHistoryReducer"; import type { EditorContextState } from "ee/reducers/uiReducers/editorContextReducer"; import type { LibraryState } from "reducers/uiReducers/libraryReducer"; @@ -90,7 +90,7 @@ export const reducerObject = { evaluations: evaluationsReducer, form: formReducer, settings: SettingsReducer, - tenant: tenantReducer, + organization: organizationReducer, linting: lintErrorReducer, git: gitReducer, }; @@ -183,7 +183,7 @@ export interface AppState { settings: SettingsReduxState; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - tenant: TenantReduxState; + organization: OrganizationReduxState; git: { global: GitGlobalReduxState; artifacts: GitArtifactRootReduxState; diff --git a/app/client/src/ce/reducers/tenantReducer.ts b/app/client/src/ce/reducers/organizationReducer.ts similarity index 68% rename from app/client/src/ce/reducers/tenantReducer.ts rename to app/client/src/ce/reducers/organizationReducer.ts index d0abcdaaa06b..c53179aec271 100644 --- a/app/client/src/ce/reducers/tenantReducer.ts +++ b/app/client/src/ce/reducers/organizationReducer.ts @@ -11,9 +11,9 @@ import { } from "utils/BrandingUtils"; import { createReducer } from "utils/ReducerUtils"; -export interface TenantReduxState { +export interface OrganizationReduxState { userPermissions: string[]; - tenantConfiguration: Record; + organizationConfiguration: Record; new: boolean; isLoading: boolean; instanceId: string; @@ -29,9 +29,9 @@ export const defaultBrandingConfig = { // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const initialState: TenantReduxState = { +export const initialState: OrganizationReduxState = { userPermissions: [], - tenantConfiguration: { + organizationConfiguration: { ...defaultBrandingConfig, }, new: false, @@ -40,65 +40,65 @@ export const initialState: TenantReduxState = { }; export const handlers = { - [ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG]: ( + [ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: TenantReduxState, + state: OrganizationReduxState, action: ReduxAction<{ isBackgroundRequest: boolean }>, ) => ({ ...state, isLoading: !action.payload.isBackgroundRequest, }), - [ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG_SUCCESS]: ( + [ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: TenantReduxState, + state: OrganizationReduxState, // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - action: ReduxAction>, + action: ReduxAction>, ) => ({ ...state, userPermissions: action.payload.userPermissions || [], - tenantConfiguration: { + organizationConfiguration: { ...defaultBrandingConfig, - ...state.tenantConfiguration, - ...action.payload.tenantConfiguration, + ...state.organizationConfiguration, + ...action.payload.organizationConfiguration, brandColors: { ...defaultBrandingConfig.brandColors, - ...action.payload.tenantConfiguration.brandColors, + ...action.payload.organizationConfiguration.brandColors, }, }, isLoading: false, instanceId: action.payload.instanceId, }), - [ReduxActionErrorTypes.FETCH_CURRENT_TENANT_CONFIG_ERROR]: ( + [ReduxActionErrorTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_ERROR]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: TenantReduxState, + state: OrganizationReduxState, ) => ({ ...state, isLoading: false, }), - [ReduxActionTypes.UPDATE_TENANT_CONFIG_SUCCESS]: ( + [ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG_SUCCESS]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: TenantReduxState, + state: OrganizationReduxState, // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - action: ReduxAction>, + action: ReduxAction>, ) => ({ ...state, ...action.payload, - tenantConfiguration: { - ...state.tenantConfiguration, - ...action.payload.tenantConfiguration, + organizationConfiguration: { + ...state.organizationConfiguration, + ...action.payload.organizationConfiguration, }, isLoading: false, }), - [ReduxActionErrorTypes.UPDATE_TENANT_CONFIG_ERROR]: ( + [ReduxActionErrorTypes.UPDATE_ORGANIZATION_CONFIG_ERROR]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: TenantReduxState, + state: OrganizationReduxState, ) => ({ ...state, isLoading: false, diff --git a/app/client/src/ce/reducers/settingsReducer.ts b/app/client/src/ce/reducers/settingsReducer.ts index b9354d99c8c5..db3164de752e 100644 --- a/app/client/src/ce/reducers/settingsReducer.ts +++ b/app/client/src/ce/reducers/settingsReducer.ts @@ -4,8 +4,8 @@ import { ReduxActionTypes, } from "ee/constants/ReduxActionConstants"; import { createReducer } from "utils/ReducerUtils"; -import type { TenantReduxState } from "ee/reducers/tenantReducer"; -import { tenantConfigConnection } from "ee/constants/tenantConstants"; +import type { OrganizationReduxState } from "ee/reducers/organizationReducer"; +import { organizationConfigConnection } from "ee/constants/organizationConstants"; export const initialState: SettingsReduxState = { isLoading: true, @@ -43,21 +43,21 @@ export const handlers = { ...action.payload, }, }), - [ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG_SUCCESS]: ( + [ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: SettingsReduxState & TenantReduxState, + state: SettingsReduxState & OrganizationReduxState, // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - action: ReduxAction>, + action: ReduxAction>, ) => { // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any const configs: any = {}; - tenantConfigConnection.forEach((key: string) => { - if (action.payload?.tenantConfiguration?.hasOwnProperty(key)) { - configs[key] = action.payload?.tenantConfiguration?.[key]; + organizationConfigConnection.forEach((key: string) => { + if (action.payload?.organizationConfiguration?.hasOwnProperty(key)) { + configs[key] = action.payload?.organizationConfiguration?.[key]; } }); @@ -70,21 +70,21 @@ export const handlers = { }, }; }, - [ReduxActionTypes.UPDATE_TENANT_CONFIG_SUCCESS]: ( + [ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG_SUCCESS]: ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - state: SettingsReduxState & TenantReduxState, + state: SettingsReduxState & OrganizationReduxState, // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any - action: ReduxAction>, + action: ReduxAction>, ) => { // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any const configs: any = {}; - tenantConfigConnection.forEach((key: string) => { - if (action.payload?.tenantConfiguration?.hasOwnProperty(key)) { - configs[key] = action.payload?.tenantConfiguration?.[key]; + organizationConfigConnection.forEach((key: string) => { + if (action.payload?.organizationConfiguration?.hasOwnProperty(key)) { + configs[key] = action.payload?.organizationConfiguration?.[key]; } }); diff --git a/app/client/src/ce/sagas/PageSagas.tsx b/app/client/src/ce/sagas/PageSagas.tsx index 2b6323759d82..53481cfcc892 100644 --- a/app/client/src/ce/sagas/PageSagas.tsx +++ b/app/client/src/ce/sagas/PageSagas.tsx @@ -129,7 +129,7 @@ import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { toast } from "@appsmith/ads"; import type { MainCanvasReduxState } from "reducers/uiReducers/mainCanvasReducer"; import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUtils"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import type { WidgetProps } from "widgets/BaseWidget"; import { nestDSL, flattenDSL, LATEST_DSL_VERSION } from "@shared/dsl"; diff --git a/app/client/src/ce/sagas/SuperUserSagas.tsx b/app/client/src/ce/sagas/SuperUserSagas.tsx index 9a9f444bd365..88131c767280 100644 --- a/app/client/src/ce/sagas/SuperUserSagas.tsx +++ b/app/client/src/ce/sagas/SuperUserSagas.tsx @@ -28,9 +28,9 @@ import { MIGRATION_STATUS, RESTART_POLL_INTERVAL, RESTART_POLL_TIMEOUT, -} from "ee/constants/tenantConstants"; -import type { FetchCurrentTenantConfigResponse } from "ee/api/TenantApi"; -import TenantApi from "ee/api/TenantApi"; +} from "ee/constants/organizationConstants"; +import type { FetchCurrentOrganizationConfigResponse } from "ee/api/OrganizationApi"; +import OrganizationApi from "ee/api/OrganizationApi"; export function* FetchAdminSettingsSaga() { const response: ApiResponse = yield call(UserApi.fetchAdminSettings); @@ -153,13 +153,13 @@ export function* RestryRestartServerPoll() { pollCount++; yield delay(RESTART_POLL_INTERVAL); try { - const response: FetchCurrentTenantConfigResponse = yield call( - TenantApi.fetchCurrentTenantConfig, + const response: FetchCurrentOrganizationConfigResponse = yield call( + OrganizationApi.fetchCurrentOrganizationConfig, ); if ( response.responseMeta.status === 200 && - response.data?.tenantConfiguration?.migrationStatus === + response.data?.organizationConfiguration?.migrationStatus === MIGRATION_STATUS.COMPLETED ) { window.location.reload(); diff --git a/app/client/src/ce/sagas/analyticsSaga.ts b/app/client/src/ce/sagas/analyticsSaga.ts index 355db4e04c0b..df5d0f4f4464 100644 --- a/app/client/src/ce/sagas/analyticsSaga.ts +++ b/app/client/src/ce/sagas/analyticsSaga.ts @@ -1,4 +1,4 @@ -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { call, select } from "redux-saga/effects"; import type { APP_MODE } from "entities/App"; import { getCurrentPageId } from "selectors/editorSelectors"; diff --git a/app/client/src/ce/sagas/index.tsx b/app/client/src/ce/sagas/index.tsx index e6bb5cf321aa..577711a4f01c 100644 --- a/app/client/src/ce/sagas/index.tsx +++ b/app/client/src/ce/sagas/index.tsx @@ -1,7 +1,7 @@ import { watchActionExecutionSagas } from "ee/sagas/ActionExecution/ActionExecutionSagas"; import NavigationSagas from "ee/sagas/NavigationSagas"; import SuperUserSagas from "ee/sagas/SuperUserSagas"; -import tenantSagas from "ee/sagas/tenantSagas"; +import organizationSagas from "ee/sagas/organizationSagas"; import userSagas from "ee/sagas/userSagas"; import workspaceSagas from "ee/sagas/WorkspaceSagas"; import { watchPluginActionExecutionSagas } from "sagas/ActionExecution/PluginActionSaga"; @@ -97,7 +97,7 @@ export const sagas = [ NavigationSagas, editorContextSagas, AutoHeightSagas, - tenantSagas, + organizationSagas, JSLibrarySaga, LintingSaga, autoLayoutUpdateSagas, diff --git a/app/client/src/ce/sagas/tenantSagas.tsx b/app/client/src/ce/sagas/organizationSagas.tsx similarity index 69% rename from app/client/src/ce/sagas/tenantSagas.tsx rename to app/client/src/ce/sagas/organizationSagas.tsx index b9a5c247a4c7..b1d5547bd18f 100644 --- a/app/client/src/ce/sagas/tenantSagas.tsx +++ b/app/client/src/ce/sagas/organizationSagas.tsx @@ -5,27 +5,27 @@ import { } from "ee/constants/ReduxActionConstants"; import { call, put } from "redux-saga/effects"; import type { APIResponseError, ApiResponse } from "api/ApiResponses"; -import type { UpdateTenantConfigRequest } from "ee/api/TenantApi"; -import { TenantApi } from "ee/api/TenantApi"; +import type { UpdateOrganizationConfigRequest } from "ee/api/OrganizationApi"; +import { OrganizationApi } from "ee/api/OrganizationApi"; import { validateResponse } from "sagas/ErrorSagas"; import { safeCrashAppRequest } from "actions/errorActions"; import { ERROR_CODES } from "ee/constants/ApiConstants"; -import { defaultBrandingConfig as CE_defaultBrandingConfig } from "ee/reducers/tenantReducer"; +import { defaultBrandingConfig as CE_defaultBrandingConfig } from "ee/reducers/organizationReducer"; import { toast } from "@appsmith/ads"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { getFromServerWhenNoPrefetchedResult } from "sagas/helper"; -// On CE we don't expose tenant config so this shouldn't make any API calls and should just return necessary permissions for the user -export function* fetchCurrentTenantConfigSaga(action?: { - payload?: { tenantConfig?: ApiResponse }; +// On CE we don't expose organization config so this shouldn't make any API calls and should just return necessary permissions for the user +export function* fetchCurrentOrganizationConfigSaga(action?: { + payload?: { organizationConfig?: ApiResponse }; }) { - const tenantConfig = action?.payload?.tenantConfig; + const organizationConfig = action?.payload?.organizationConfig; try { const response: ApiResponse = yield call( getFromServerWhenNoPrefetchedResult, - tenantConfig, - () => call(TenantApi.fetchCurrentTenantConfig), + organizationConfig, + () => call(OrganizationApi.fetchCurrentOrganizationConfig), ); const isValidResponse: boolean = yield validateResponse(response); @@ -36,29 +36,29 @@ export function* fetchCurrentTenantConfigSaga(action?: { const data: any = response.data; yield put({ - type: ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG_SUCCESS, + type: ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS, payload: data, }); AnalyticsUtil.initInstanceId(data.instanceId); } } catch (error) { yield put({ - type: ReduxActionErrorTypes.FETCH_CURRENT_TENANT_CONFIG_ERROR, + type: ReduxActionErrorTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_ERROR, payload: { error, }, }); - // tenant api is UI blocking call, we have to safe crash the app if it fails + // organization api is UI blocking call, we have to safe crash the app if it fails yield put(safeCrashAppRequest()); } } -export function* updateTenantConfigSaga( - action: ReduxAction, +export function* updateOrganizationConfigSaga( + action: ReduxAction, ) { try { - const settings = action.payload.tenantConfiguration; + const settings = action.payload.organizationConfiguration; const hasSingleSessionUserSetting = settings.hasOwnProperty( "singleSessionPerUserEnabled", ); @@ -70,7 +70,7 @@ export function* updateTenantConfigSaga( ); const response: ApiResponse = yield call( - TenantApi.updateTenantConfig, + OrganizationApi.updateOrganizationConfig, action.payload, ); const isValidResponse: boolean = yield validateResponse(response); @@ -100,19 +100,19 @@ export function* updateTenantConfigSaga( }); } - // If the tenant config is not present, we need to set the default config + // If the organization config is not present, we need to set the default config yield put({ - type: ReduxActionTypes.UPDATE_TENANT_CONFIG_SUCCESS, + type: ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG_SUCCESS, payload: { ...payload, - tenantConfiguration: { + organizationConfiguration: { ...CE_defaultBrandingConfig, - ...payload.tenantConfiguration, + ...payload.organizationConfiguration, }, }, }); - if (action.payload.isOnlyTenantSettings) { + if (action.payload.isOnlyOrganizationSettings) { toast.show("Successfully saved", { kind: "success", }); @@ -126,7 +126,7 @@ export function* updateTenantConfigSaga( const errorObj = error as APIResponseError; yield put({ - type: ReduxActionErrorTypes.UPDATE_TENANT_CONFIG_ERROR, + type: ReduxActionErrorTypes.UPDATE_ORGANIZATION_CONFIG_ERROR, payload: { errorObj, }, diff --git a/app/client/src/ce/sagas/userSagas.tsx b/app/client/src/ce/sagas/userSagas.tsx index da2459f5f8d6..65831655ff29 100644 --- a/app/client/src/ce/sagas/userSagas.tsx +++ b/app/client/src/ce/sagas/userSagas.tsx @@ -124,7 +124,7 @@ export function* getCurrentUserSaga(action?: { function* getSessionRecordingConfig() { const featureFlags: FeatureFlags = yield select(selectFeatureFlags); - // This is a tenant level flag to kill session recordings + // This is a organization level flag to kill session recordings // If this is true, we do not do any session recordings if (featureFlags.kill_session_recordings_enabled) { return { @@ -142,7 +142,7 @@ function* getSessionRecordingConfig() { }; } - // Now we know that both tenant and user level flags are not blocking session recordings + // Now we know that both organization and user level flags are not blocking session recordings return { enabled: true, // Check if we need to mask the session recordings from feature flags diff --git a/app/client/src/ce/selectors/tenantSelectors.tsx b/app/client/src/ce/selectors/organizationSelectors.tsx similarity index 52% rename from app/client/src/ce/selectors/tenantSelectors.tsx rename to app/client/src/ce/selectors/organizationSelectors.tsx index 2ab76f7e4cff..0011addfa39e 100644 --- a/app/client/src/ce/selectors/tenantSelectors.tsx +++ b/app/client/src/ce/selectors/organizationSelectors.tsx @@ -1,27 +1,27 @@ import type { AppState } from "ee/reducers"; /** - * selects the tenant permissions + * selects the organization permissions * * @param state * @returns */ -export const getTenantPermissions = (state: AppState) => { - return state.tenant?.userPermissions; +export const getOrganizationPermissions = (state: AppState) => { + return state.organization?.userPermissions; }; /** - * selects the tenant config + * selects the organization config * * @param state * @returns */ -export const getTenantConfig = (state: AppState) => { - return state.tenant?.tenantConfiguration; +export const getOrganizationConfig = (state: AppState) => { + return state.organization?.organizationConfiguration; }; /** - * selects the tenant brand colors + * selects the organization brand colors * * @returns */ @@ -33,27 +33,29 @@ export const isValidLicense = () => { return true; }; -export const isTenantLoading = (state: AppState) => { - return state.tenant?.isLoading; +export const isOrganizationLoading = (state: AppState) => { + return state.organization?.isLoading; }; export const getGoogleMapsApiKey = (state: AppState): string | undefined => - state.tenant?.tenantConfiguration?.googleMapsKey as string | undefined; + state.organization?.organizationConfiguration?.googleMapsKey as + | string + | undefined; export const getThirdPartyAuths = (state: AppState): string[] => - state.tenant?.tenantConfiguration?.thirdPartyAuths ?? []; + state.organization?.organizationConfiguration?.thirdPartyAuths ?? []; export const getIsFormLoginEnabled = (state: AppState): boolean => - state.tenant?.tenantConfiguration?.isFormLoginEnabled ?? true; + state.organization?.organizationConfiguration?.isFormLoginEnabled ?? true; export const getInstanceId = (state: AppState): string => - state.tenant?.instanceId; + state.organization?.instanceId; // eslint-disable-next-line @typescript-eslint/no-unused-vars export const shouldShowLicenseBanner = (state: AppState) => false; export const getHideWatermark = (state: AppState): boolean => - state.tenant?.tenantConfiguration?.hideWatermark; + state.organization?.organizationConfiguration?.hideWatermark; // eslint-disable-next-line @typescript-eslint/no-unused-vars export const isFreePlan = (state: AppState) => true; diff --git a/app/client/src/ce/selectors/rampSelectors.tsx b/app/client/src/ce/selectors/rampSelectors.tsx index 0d881df88581..06f755382c19 100644 --- a/app/client/src/ce/selectors/rampSelectors.tsx +++ b/app/client/src/ce/selectors/rampSelectors.tsx @@ -14,7 +14,7 @@ import { isPermitted, PERMISSION_TYPE } from "ee/utils/permissionHelpers"; const { cloudHosting, customerPortalUrl, pricingUrl } = getAppsmithConfigs(); -const tenantState = (state: AppState) => state.tenant; +const organizationState = (state: AppState) => state.organization; const uiState = (state: AppState) => state.ui; export const getRampLink = ({ @@ -26,8 +26,8 @@ export const getRampLink = ({ feature: string; isBusinessFeature?: boolean; }) => - createSelector(tenantState, (tenant) => { - const instanceId = tenant?.instanceId; + createSelector(organizationState, (organization) => { + const instanceId = organization?.instanceId; const source = cloudHosting ? "cloud" : "CE"; const RAMP_LINK_TO = isBusinessFeature ? CUSTOMER_PORTAL_URL_WITH_PARAMS( diff --git a/app/client/src/ce/utils/BusinessFeatures/adminSettingsHelpers.tsx b/app/client/src/ce/utils/BusinessFeatures/adminSettingsHelpers.tsx index f2667562545d..69df995cf5b5 100644 --- a/app/client/src/ce/utils/BusinessFeatures/adminSettingsHelpers.tsx +++ b/app/client/src/ce/utils/BusinessFeatures/adminSettingsHelpers.tsx @@ -20,11 +20,17 @@ export const getShowAdminSettings = ( export const getAdminSettingsPath = ( isEnabled: boolean, isSuperUser: boolean | undefined, - tenantPermissions: string[] = [], + organizationPermissions: string[] = [], ) => { if (isEnabled) { - return getDefaultAdminSettingsPath_EE({ isSuperUser, tenantPermissions }); + return getDefaultAdminSettingsPath_EE({ + isSuperUser, + organizationPermissions, + }); } else { - return getDefaultAdminSettingsPath_CE({ isSuperUser, tenantPermissions }); + return getDefaultAdminSettingsPath_CE({ + isSuperUser, + organizationPermissions, + }); } }; diff --git a/app/client/src/ce/utils/adminSettingsHelpers.ts b/app/client/src/ce/utils/adminSettingsHelpers.ts index 5628f50fe105..56ea44af04db 100644 --- a/app/client/src/ce/utils/adminSettingsHelpers.ts +++ b/app/client/src/ce/utils/adminSettingsHelpers.ts @@ -1,4 +1,4 @@ -import { tenantConfigConnection } from "ee/constants/tenantConstants"; +import { organizationConfigConnection } from "ee/constants/organizationConstants"; import type { AdminConfigType, Category, @@ -37,7 +37,7 @@ export const saveAllowed = ( export const getDefaultAdminSettingsPath = ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any - { isSuperUser, tenantPermissions: any = [] }: Record, + { isSuperUser, organizationPermissions: any = [] }: Record, ): string => { return ADMIN_SETTINGS_CATEGORY_DEFAULT_PATH; }; @@ -52,8 +52,8 @@ export const getLoginUrl = (method: string): string => { return urls[method]; }; -export const isTenantConfig = (name: string): boolean => { - const fields: string[] = tenantConfigConnection; +export const isOrganizationConfig = (name: string): boolean => { + const fields: string[] = organizationConfigConnection; return fields.includes(name); }; diff --git a/app/client/src/ce/utils/permissionHelpers.tsx b/app/client/src/ce/utils/permissionHelpers.tsx index da55328cf376..736e06ccb9f0 100644 --- a/app/client/src/ce/utils/permissionHelpers.tsx +++ b/app/client/src/ce/utils/permissionHelpers.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ export enum PERMISSION_TYPE { /* Workspace permissions */ - CREATE_WORKSPACE = "createWorkspaces:tenant", + CREATE_WORKSPACE = "createWorkspaces:organization", MANAGE_WORKSPACE = "manage:workspaces", READ_WORKSPACE = "read:workspaces", INVITE_USER_TO_WORKSPACE = "inviteUsers:workspace", diff --git a/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts b/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts index 6caa81392991..8d225b555af3 100644 --- a/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts +++ b/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts @@ -12684,7 +12684,7 @@ export const defaultAppState = { ], slug: "jacques-s-apps", isAutoGeneratedWorkspace: true, - tenantId: "653236225e9a6424e4c04b65", + organizationId: "653236225e9a6424e4c04b65", logoUrl: "/api/v1/assets/null", new: false, }, @@ -20651,9 +20651,9 @@ export const defaultAppState = { emailVerificationEnabled: false, }, }, - tenant: { + organization: { userPermissions: [], - tenantConfiguration: { + organizationConfiguration: { brandFaviconUrl: "https://assets.appsmith.com/appsmith-favicon-orange.ico", brandColors: { diff --git a/app/client/src/components/propertyControls/ColorPickerComponentV2.test.tsx b/app/client/src/components/propertyControls/ColorPickerComponentV2.test.tsx index 4810dbbd57ca..02c1e09ff49c 100644 --- a/app/client/src/components/propertyControls/ColorPickerComponentV2.test.tsx +++ b/app/client/src/components/propertyControls/ColorPickerComponentV2.test.tsx @@ -31,9 +31,9 @@ const store = mockStore({ }, }, }, - tenant: { + organization: { userPermissions: [], - tenantConfiguration: { + organizationConfiguration: { brandColors: {}, }, new: false, diff --git a/app/client/src/components/propertyControls/ColorPickerComponentV2.tsx b/app/client/src/components/propertyControls/ColorPickerComponentV2.tsx index c80ad0ee8ad6..a763add13ce5 100644 --- a/app/client/src/components/propertyControls/ColorPickerComponentV2.tsx +++ b/app/client/src/components/propertyControls/ColorPickerComponentV2.tsx @@ -29,7 +29,7 @@ import { import { TAILWIND_COLORS } from "constants/ThemeConstants"; import useDSEvent from "utils/hooks/useDSEvent"; import { DSEventTypes } from "utils/AppsmithUtils"; -import { getBrandColors } from "ee/selectors/tenantSelectors"; +import { getBrandColors } from "ee/selectors/organizationSelectors"; import FocusTrap from "focus-trap-react"; import { createMessage, FULL_COLOR_PICKER_LABEL } from "ee/constants/messages"; diff --git a/app/client/src/ee/actions/organizationActions.ts b/app/client/src/ee/actions/organizationActions.ts new file mode 100644 index 000000000000..02afdd761804 --- /dev/null +++ b/app/client/src/ee/actions/organizationActions.ts @@ -0,0 +1 @@ +export * from "ce/actions/organizationActions"; diff --git a/app/client/src/ee/actions/tenantActions.ts b/app/client/src/ee/actions/tenantActions.ts deleted file mode 100644 index e5fb6026b705..000000000000 --- a/app/client/src/ee/actions/tenantActions.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "ce/actions/tenantActions"; diff --git a/app/client/src/ee/api/OrganizationApi.ts b/app/client/src/ee/api/OrganizationApi.ts new file mode 100644 index 000000000000..432079bd435f --- /dev/null +++ b/app/client/src/ee/api/OrganizationApi.ts @@ -0,0 +1,6 @@ +export * from "ce/api/OrganizationApi"; +import { OrganizationApi as CE_OrganizationApi } from "ce/api/OrganizationApi"; + +class OrganizationApi extends CE_OrganizationApi {} + +export default OrganizationApi; diff --git a/app/client/src/ee/api/TenantApi.ts b/app/client/src/ee/api/TenantApi.ts deleted file mode 100644 index 5d2f188cd3de..000000000000 --- a/app/client/src/ee/api/TenantApi.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "ce/api/TenantApi"; -import { TenantApi as CE_TenantApi } from "ce/api/TenantApi"; - -class TenantApi extends CE_TenantApi {} - -export default TenantApi; diff --git a/app/client/src/ee/constants/organizationConstants.ts b/app/client/src/ee/constants/organizationConstants.ts new file mode 100644 index 000000000000..d2e66b215266 --- /dev/null +++ b/app/client/src/ee/constants/organizationConstants.ts @@ -0,0 +1 @@ +export * from "ce/constants/organizationConstants"; diff --git a/app/client/src/ee/constants/tenantConstants.ts b/app/client/src/ee/constants/tenantConstants.ts deleted file mode 100644 index 2866f0898e53..000000000000 --- a/app/client/src/ee/constants/tenantConstants.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "ce/constants/tenantConstants"; diff --git a/app/client/src/ee/reducers/organizationReducer.ts b/app/client/src/ee/reducers/organizationReducer.ts new file mode 100644 index 000000000000..c8c59c55c6ee --- /dev/null +++ b/app/client/src/ee/reducers/organizationReducer.ts @@ -0,0 +1,5 @@ +export * from "ce/reducers/organizationReducer"; +import { handlers, initialState } from "ce/reducers/organizationReducer"; +import { createReducer } from "utils/ReducerUtils"; + +export default createReducer(initialState, handlers); diff --git a/app/client/src/ee/reducers/tenantReducer.ts b/app/client/src/ee/reducers/tenantReducer.ts deleted file mode 100644 index a5ab731605a4..000000000000 --- a/app/client/src/ee/reducers/tenantReducer.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "ce/reducers/tenantReducer"; -import { handlers, initialState } from "ce/reducers/tenantReducer"; -import { createReducer } from "utils/ReducerUtils"; - -export default createReducer(initialState, handlers); diff --git a/app/client/src/ee/sagas/organizationSagas.tsx b/app/client/src/ee/sagas/organizationSagas.tsx new file mode 100644 index 000000000000..3d7e5e379a29 --- /dev/null +++ b/app/client/src/ee/sagas/organizationSagas.tsx @@ -0,0 +1,20 @@ +export * from "ce/sagas/organizationSagas"; +import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; +import { + fetchCurrentOrganizationConfigSaga, + updateOrganizationConfigSaga, +} from "ce/sagas/organizationSagas"; +import { all, takeLatest } from "redux-saga/effects"; + +export default function* organizationSagas() { + yield all([ + takeLatest( + ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG, + fetchCurrentOrganizationConfigSaga, + ), + takeLatest( + ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG, + updateOrganizationConfigSaga, + ), + ]); +} diff --git a/app/client/src/ee/sagas/tenantSagas.tsx b/app/client/src/ee/sagas/tenantSagas.tsx deleted file mode 100644 index 53ca8398e7e7..000000000000 --- a/app/client/src/ee/sagas/tenantSagas.tsx +++ /dev/null @@ -1,17 +0,0 @@ -export * from "ce/sagas/tenantSagas"; -import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; -import { - fetchCurrentTenantConfigSaga, - updateTenantConfigSaga, -} from "ce/sagas/tenantSagas"; -import { all, takeLatest } from "redux-saga/effects"; - -export default function* tenantSagas() { - yield all([ - takeLatest( - ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG, - fetchCurrentTenantConfigSaga, - ), - takeLatest(ReduxActionTypes.UPDATE_TENANT_CONFIG, updateTenantConfigSaga), - ]); -} diff --git a/app/client/src/ee/selectors/organizationSelectors.tsx b/app/client/src/ee/selectors/organizationSelectors.tsx new file mode 100644 index 000000000000..49474f8ce5e3 --- /dev/null +++ b/app/client/src/ee/selectors/organizationSelectors.tsx @@ -0,0 +1 @@ +export * from "ce/selectors/organizationSelectors"; diff --git a/app/client/src/ee/selectors/tenantSelectors.tsx b/app/client/src/ee/selectors/tenantSelectors.tsx deleted file mode 100644 index 22a80dbfc947..000000000000 --- a/app/client/src/ee/selectors/tenantSelectors.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from "ce/selectors/tenantSelectors"; diff --git a/app/client/src/git/hooks/useAppsmithEnterpriseUrl.ts b/app/client/src/git/hooks/useAppsmithEnterpriseUrl.ts index dfe46397247e..36d19eccd596 100644 --- a/app/client/src/git/hooks/useAppsmithEnterpriseUrl.ts +++ b/app/client/src/git/hooks/useAppsmithEnterpriseUrl.ts @@ -1,4 +1,4 @@ -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { useSelector } from "react-redux"; import { ENTERPRISE_PRICING_PAGE } from "constants/ThirdPartyConstants"; import { useMemo } from "react"; diff --git a/app/client/src/layoutSystems/common/dropTarget/unitTestUtils.ts b/app/client/src/layoutSystems/common/dropTarget/unitTestUtils.ts index 1f9ac44b17a8..d86a20c29947 100644 --- a/app/client/src/layoutSystems/common/dropTarget/unitTestUtils.ts +++ b/app/client/src/layoutSystems/common/dropTarget/unitTestUtils.ts @@ -247,7 +247,7 @@ export const unitTestBaseMockStore = { ], slug: "jacques-s-apps", isAutoGeneratedWorkspace: true, - tenantId: "653236225e9a6424e4c04b65", + organizationId: "653236225e9a6424e4c04b65", logoUrl: "/api/v1/assets/null", new: false, }, @@ -433,7 +433,7 @@ export const unitTestBaseMockStore = { ], slug: "jacques-s-apps", isAutoGeneratedWorkspace: true, - tenantId: "653236225e9a6424e4c04b65", + organizationId: "653236225e9a6424e4c04b65", logoUrl: "/api/v1/assets/null", new: false, }, diff --git a/app/client/src/pages/AdminSettings/Branding/BrandingPage.tsx b/app/client/src/pages/AdminSettings/Branding/BrandingPage.tsx index 834077106eb7..ed6feaf6415d 100644 --- a/app/client/src/pages/AdminSettings/Branding/BrandingPage.tsx +++ b/app/client/src/pages/AdminSettings/Branding/BrandingPage.tsx @@ -4,7 +4,7 @@ import { useForm } from "react-hook-form"; import Previews from "./previews"; import SettingsForm from "./SettingsForm"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { Wrapper } from "pages/AdminSettings/Authentication/AuthPage"; import { getAssetUrl } from "ee/utils/airgapHelpers"; @@ -31,11 +31,11 @@ interface BrandingPageProps { function BrandingPage(props: BrandingPageProps) { const { category } = props; const isBrandingEnabled = category?.isFeatureEnabled ?? false; - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const defaultValues = { - brandColors: tenantConfig.brandColors, - brandLogo: tenantConfig.brandLogoUrl, - brandFavicon: tenantConfig.brandFaviconUrl, + brandColors: organizationConfig.brandColors, + brandLogo: organizationConfig.brandLogoUrl, + brandFavicon: organizationConfig.brandFaviconUrl, }; const { control, @@ -53,15 +53,15 @@ function BrandingPage(props: BrandingPageProps) { const values = getValues(); /** - * reset the form when the tenant config changes + * reset the form when the organization config changes */ useEffect(() => { reset({ - brandColors: tenantConfig.brandColors, - brandLogo: tenantConfig.brandLogoUrl, - brandFavicon: tenantConfig.brandFaviconUrl, + brandColors: organizationConfig.brandColors, + brandLogo: organizationConfig.brandLogoUrl, + brandFavicon: organizationConfig.brandFaviconUrl, }); - }, [tenantConfig, reset]); + }, [organizationConfig, reset]); watch(); diff --git a/app/client/src/pages/AdminSettings/FormGroup/Checkbox.tsx b/app/client/src/pages/AdminSettings/FormGroup/Checkbox.tsx index 4a002cee0abc..7985d76657ea 100644 --- a/app/client/src/pages/AdminSettings/FormGroup/Checkbox.tsx +++ b/app/client/src/pages/AdminSettings/FormGroup/Checkbox.tsx @@ -7,7 +7,7 @@ import type { FormTextFieldProps } from "components/utils/ReduxFormTextField"; import { Checkbox } from "@appsmith/ads"; import { useSelector } from "react-redux"; import { SETTINGS_FORM_NAME } from "ee/constants/forms"; -import { isTenantConfig } from "ee/utils/adminSettingsHelpers"; +import { isOrganizationConfig } from "ee/utils/adminSettingsHelpers"; const CheckboxWrapper = styled.div` display: grid; @@ -98,7 +98,7 @@ export function CheckboxComponent({ setting }: SettingComponentProps) { isDisabled: setting.isDisabled && setting.isDisabled(settings), isFeatureEnabled: setting.isFeatureEnabled, labelSuffix: setting.textSuffix, - isPropertyDisabled: isTenantConfig(setting.id) + isPropertyDisabled: isOrganizationConfig(setting.id) ? false : !setting.name?.toLowerCase().includes("enable"), })} diff --git a/app/client/src/pages/AdminSettings/LeftPane.tsx b/app/client/src/pages/AdminSettings/LeftPane.tsx index 112fbe72e5ca..c410f3827b5c 100644 --- a/app/client/src/pages/AdminSettings/LeftPane.tsx +++ b/app/client/src/pages/AdminSettings/LeftPane.tsx @@ -14,7 +14,7 @@ import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { getCurrentUser } from "selectors/usersSelectors"; import BusinessTag from "components/BusinessTag"; import EnterpriseTag from "components/EnterpriseTag"; -import { getTenantPermissions } from "ee/selectors/tenantSelectors"; +import { getOrganizationPermissions } from "ee/selectors/organizationSelectors"; import { getFilteredAclCategories, getFilteredGeneralCategories, @@ -200,11 +200,11 @@ export default function LeftPane() { const { category, selected: subCategory } = useParams() as any; const user = useSelector(getCurrentUser); const isSuperUser = user?.isSuperUser; - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const isAuditLogsEnabled = getHasAuditLogsReadPermission( isFeatureEnabled, - tenantPermissions, + organizationPermissions, ); const filteredGeneralCategories = getFilteredGeneralCategories(categories); diff --git a/app/client/src/pages/AdminSettings/Main.tsx b/app/client/src/pages/AdminSettings/Main.tsx index 078459a3ad02..4702b6ab0356 100644 --- a/app/client/src/pages/AdminSettings/Main.tsx +++ b/app/client/src/pages/AdminSettings/Main.tsx @@ -6,7 +6,7 @@ import SettingsForm from "pages/AdminSettings/SettingsForm"; import { getWrapperCategory } from "ee/utils/adminSettingsHelpers"; import { useSelector } from "react-redux"; import { getCurrentUser } from "selectors/usersSelectors"; -import { getTenantPermissions } from "ee/selectors/tenantSelectors"; +import { getOrganizationPermissions } from "ee/selectors/organizationSelectors"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { getAdminSettingsPath } from "ee/utils/BusinessFeatures/adminSettingsHelpers"; @@ -17,7 +17,7 @@ const Main = () => { const params = useParams() as any; const { category, selected: subCategory } = params; const user = useSelector(getCurrentUser); - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const isSuperUser = user?.isSuperUser || false; const wrapperCategory = getWrapperCategory( AdminConfig.wrapperCategories, @@ -39,7 +39,7 @@ const Main = () => { to={getAdminSettingsPath( isFeatureEnabled, isSuperUser, - tenantPermissions, + organizationPermissions, )} /> ); diff --git a/app/client/src/pages/AdminSettings/SaveSettings.tsx b/app/client/src/pages/AdminSettings/SaveSettings.tsx index a3136feb9bfe..638bdb4ce086 100644 --- a/app/client/src/pages/AdminSettings/SaveSettings.tsx +++ b/app/client/src/pages/AdminSettings/SaveSettings.tsx @@ -31,25 +31,25 @@ const SettingsButtonWrapper = styled.div` `; interface SaveAdminSettingsProps { - isOnlyTenantConfig?: boolean; + isOnlyOrganizationConfig?: boolean; isSaving?: boolean; needsRefresh?: boolean; onSave?: () => void; onClear?: () => void; settings: Record; valid: boolean; - updatedTenantSettings?: string[]; + updatedOrganizationSettings?: string[]; } const saveAdminSettings = (props: SaveAdminSettingsProps) => { const { - isOnlyTenantConfig = false, + isOnlyOrganizationConfig = false, isSaving, needsRefresh = false, onClear, onSave, settings, - updatedTenantSettings, + updatedOrganizationSettings, valid, } = props; @@ -58,9 +58,9 @@ const saveAdminSettings = (props: SaveAdminSettingsProps) => { if (needsRefresh) { saveButtonText = SAVE_AND_REFRESH_BUTTON; } else if ( - isOnlyTenantConfig || - (updatedTenantSettings?.length === Object.keys(settings).length && - updatedTenantSettings?.length !== 0) + isOnlyOrganizationConfig || + (updatedOrganizationSettings?.length === Object.keys(settings).length && + updatedOrganizationSettings?.length !== 0) ) { saveButtonText = SAVE_BUTTON; } diff --git a/app/client/src/pages/AdminSettings/SettingsForm.tsx b/app/client/src/pages/AdminSettings/SettingsForm.tsx index 77a7a16c790c..0fc1d3c5dff4 100644 --- a/app/client/src/pages/AdminSettings/SettingsForm.tsx +++ b/app/client/src/pages/AdminSettings/SettingsForm.tsx @@ -29,7 +29,10 @@ import { DISCONNECT_SERVICE_WARNING, MANDATORY_FIELDS_ERROR, } from "ee/constants/messages"; -import { isTenantConfig, saveAllowed } from "ee/utils/adminSettingsHelpers"; +import { + isOrganizationConfig, + saveAllowed, +} from "ee/utils/adminSettingsHelpers"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { Wrapper, @@ -44,9 +47,9 @@ import { toast } from "@appsmith/ads"; import { getIsFormLoginEnabled, getThirdPartyAuths, -} from "ee/selectors/tenantSelectors"; -import { updateTenantConfig } from "ee/actions/tenantActions"; -import { tenantConfigConnection } from "ee/constants/tenantConstants"; +} from "ee/selectors/organizationSelectors"; +import { updateOrganizationConfig } from "ee/actions/organizationActions"; +import { organizationConfigConnection } from "ee/constants/organizationConstants"; interface FormProps { settings: Record; @@ -87,54 +90,54 @@ export function SettingsForm( const isFormLoginEnabled = useSelector(getIsFormLoginEnabled); const socialLoginList = useSelector(getThirdPartyAuths); - const updatedTenantSettings = useMemo( - () => Object.keys(props.settings).filter((s) => isTenantConfig(s)), + const updatedOrganizationSettings = useMemo( + () => Object.keys(props.settings).filter((s) => isOrganizationConfig(s)), [props.settings], ); - // Is there a non-tenant (env) config in this category of settings? - const isOnlyTenantConfig = !settingsDetails.find( + // Is there a non-organization (env) config in this category of settings? + const isOnlyOrganizationConfig = !settingsDetails.find( (s) => s.category === (subCategory || category) && s.controlType != SettingTypes.CALLOUT && - !isTenantConfig(s.id), + !isOrganizationConfig(s.id), ); const saveChangedSettings = () => { const settingsKeyLength = Object.keys(props.settings).length; const isOnlyEnvSettings = - updatedTenantSettings.length === 0 && settingsKeyLength !== 0; - const isEnvAndTenantSettings = - updatedTenantSettings.length !== 0 && - updatedTenantSettings.length !== settingsKeyLength; + updatedOrganizationSettings.length === 0 && settingsKeyLength !== 0; + const isEnvAndOrganizationSettings = + updatedOrganizationSettings.length !== 0 && + updatedOrganizationSettings.length !== settingsKeyLength; if (isOnlyEnvSettings) { // only env settings dispatch(saveSettings(props.settings)); } else { - // only tenant settings + // only organization settings // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any const config: any = {}; for (const each in props.settings) { - if (tenantConfigConnection.includes(each)) { + if (organizationConfigConnection.includes(each)) { config[each] = props.settings[each]; } } dispatch( - updateTenantConfig({ - tenantConfiguration: config, - isOnlyTenantSettings: !isEnvAndTenantSettings, + updateOrganizationConfig({ + organizationConfiguration: config, + isOnlyOrganizationSettings: !isEnvAndOrganizationSettings, needsRefresh: details?.needsRefresh, }), ); - // both env and tenant settings - if (isEnvAndTenantSettings) { + // both env and organization settings + if (isEnvAndOrganizationSettings) { const filteredSettings = Object.keys(props.settings) - .filter((key) => !isTenantConfig(key)) + .filter((key) => !isOrganizationConfig(key)) .reduce((obj, key) => { return Object.assign(obj, { [key]: props.settings[key], @@ -295,13 +298,13 @@ export function SettingsForm( /> {isSavable && ( )} diff --git a/app/client/src/pages/AppIDE/components/AppSettings/components/NavigationSettings/LogoInput.tsx b/app/client/src/pages/AppIDE/components/AppSettings/components/NavigationSettings/LogoInput.tsx index 502851e0d25f..bafdebf49823 100644 --- a/app/client/src/pages/AppIDE/components/AppSettings/components/NavigationSettings/LogoInput.tsx +++ b/app/client/src/pages/AppIDE/components/AppSettings/components/NavigationSettings/LogoInput.tsx @@ -12,7 +12,7 @@ import { getIsDeletingNavigationLogo, getIsUploadingNavigationLogo, } from "ee/selectors/applicationSelectors"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getAppsmithConfigs } from "ee/configs"; import { DeleteLogoButton } from "ee/pages/Editor/NavigationSettings/DeleteLogoButton"; @@ -28,7 +28,7 @@ const LogoInput = ({ navigationSetting }: ButtonGroupSettingProps) => { const applicationId = useSelector(getCurrentApplicationId); const isUploadingNavigationLogo = useSelector(getIsUploadingNavigationLogo); const isDeletingNavigationLogo = useSelector(getIsDeletingNavigationLogo); - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const { logoAssetId } = navigationSetting; const [logoUrl, setLogoUrl] = useState(null); @@ -41,8 +41,8 @@ const LogoInput = ({ navigationSetting }: ButtonGroupSettingProps) => { setLogoUrl(null); return; - } else if (!cloudHosting && tenantConfig?.brandLogoUrl) { - setLogoUrl(tenantConfig.brandLogoUrl); + } else if (!cloudHosting && organizationConfig?.brandLogoUrl) { + setLogoUrl(organizationConfig.brandLogoUrl); return; } @@ -50,7 +50,7 @@ const LogoInput = ({ navigationSetting }: ButtonGroupSettingProps) => { setLogoUrl(null); return; - }, [logoAssetId, tenantConfig, cloudHosting]); + }, [logoAssetId, organizationConfig, cloudHosting]); const handleChange = (file: File) => { dispatch({ diff --git a/app/client/src/pages/AppIDE/components/PageList/PagesSection.tsx b/app/client/src/pages/AppIDE/components/PageList/PagesSection.tsx index 56c9bf93b7d5..15f55b47e3d9 100644 --- a/app/client/src/pages/AppIDE/components/PageList/PagesSection.tsx +++ b/app/client/src/pages/AppIDE/components/PageList/PagesSection.tsx @@ -16,7 +16,7 @@ import { createNewPageFromEntities } from "actions/pageActions"; import AddPageContextMenu from "./AddPageContextMenu"; import { getNextEntityName } from "utils/AppsmithUtils"; import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { PageElement } from "./PageElement"; import { PAGE_ENTITY_NAME } from "ee/constants/messages"; diff --git a/app/client/src/pages/AppViewer/PageMenu.tsx b/app/client/src/pages/AppViewer/PageMenu.tsx index 85a915afc0ec..1625e261a250 100644 --- a/app/client/src/pages/AppViewer/PageMenu.tsx +++ b/app/client/src/pages/AppViewer/PageMenu.tsx @@ -21,7 +21,7 @@ import { PageMenuContainer, StyledNavLink } from "./PageMenu.styled"; import { StyledCtaContainer } from "./Navigation/Sidebar.styled"; import ShareButton from "./Navigation/components/ShareButton"; import BackToAppsButton from "./Navigation/components/BackToAppsButton"; -import { getHideWatermark } from "ee/selectors/tenantSelectors"; +import { getHideWatermark } from "ee/selectors/organizationSelectors"; interface NavigationProps { isOpen?: boolean; diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx index 7121f3ede048..e860847e5f7c 100644 --- a/app/client/src/pages/AppViewer/index.tsx +++ b/app/client/src/pages/AppViewer/index.tsx @@ -49,7 +49,7 @@ import { } from "@appsmith/wds-theming"; import { KBViewerFloatingButton } from "ee/pages/AppViewer/KnowledgeBase/KBViewerFloatingButton"; import urlBuilder from "ee/entities/URLRedirect/URLAssembly"; -import { getHideWatermark } from "ee/selectors/tenantSelectors"; +import { getHideWatermark } from "ee/selectors/organizationSelectors"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; const AppViewerBody = styled.section<{ diff --git a/app/client/src/pages/Editor/HelpButton.tsx b/app/client/src/pages/Editor/HelpButton.tsx index 186f2a8bb129..90b284b76e59 100644 --- a/app/client/src/pages/Editor/HelpButton.tsx +++ b/app/client/src/pages/Editor/HelpButton.tsx @@ -35,7 +35,7 @@ import { import SignpostingPopup from "pages/Editor/FirstTimeUserOnboarding/Modal"; import { showSignpostingModal } from "actions/onboardingActions"; import TooltipContent from "./FirstTimeUserOnboarding/TooltipContent"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { updateIntercomConsent, updateUserDetails } from "actions/userActions"; const { appVersion, cloudHosting, intercomAppID } = getAppsmithConfigs(); diff --git a/app/client/src/pages/Editor/IntegrationEditor/PremiumDatasources/ContactForm.tsx b/app/client/src/pages/Editor/IntegrationEditor/PremiumDatasources/ContactForm.tsx index 0a48ff808c9f..9d426751c171 100644 --- a/app/client/src/pages/Editor/IntegrationEditor/PremiumDatasources/ContactForm.tsx +++ b/app/client/src/pages/Editor/IntegrationEditor/PremiumDatasources/ContactForm.tsx @@ -17,7 +17,7 @@ import { isEmail } from "utils/formhelpers"; import ReduxFormTextField from "components/utils/ReduxFormTextField"; import { PRICING_PAGE_URL } from "constants/ThirdPartyConstants"; import { getAppsmithConfigs } from "ee/configs"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { pricingPageUrlSource } from "ee/utils/licenseHelpers"; import { RampFeature, RampSection } from "utils/ProductRamps/RampsControlList"; import { diff --git a/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabBranch/hooks.ts b/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabBranch/hooks.ts index 79adb77e8a1c..c8cb65a48e3d 100644 --- a/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabBranch/hooks.ts +++ b/app/client/src/pages/Editor/gitSync/GitSettingsModal/TabBranch/hooks.ts @@ -1,4 +1,4 @@ -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { useSelector } from "react-redux"; import { ENTERPRISE_PRICING_PAGE } from "constants/ThirdPartyConstants"; import { useMemo } from "react"; diff --git a/app/client/src/pages/UserAuth/Container.tsx b/app/client/src/pages/UserAuth/Container.tsx index ba731cd980e0..936e4b90ddb0 100644 --- a/app/client/src/pages/UserAuth/Container.tsx +++ b/app/client/src/pages/UserAuth/Container.tsx @@ -1,7 +1,7 @@ import React from "react"; import { useSelector } from "react-redux"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import LeftSideContent from "./LeftSideContent"; import { getAppsmithConfigs } from "ee/configs"; @@ -40,7 +40,7 @@ const BoxWrapper = styled.div<{ isMobileView: boolean }>` function Container(props: ContainerProps) { const { children, footer, subtitle, testId, title } = props; - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const { cloudHosting } = getAppsmithConfigs(); const isMobileDevice = useIsMobileDevice(); @@ -59,7 +59,7 @@ function Container(props: ContainerProps) { {!isMobileDevice && ( )}
diff --git a/app/client/src/pages/UserAuth/Login.tsx b/app/client/src/pages/UserAuth/Login.tsx index 76f59aa5a50e..fcac3e210b57 100644 --- a/app/client/src/pages/UserAuth/Login.tsx +++ b/app/client/src/pages/UserAuth/Login.tsx @@ -45,8 +45,8 @@ import Container from "pages/UserAuth/Container"; import { getThirdPartyAuths, getIsFormLoginEnabled, - getTenantConfig, -} from "ee/selectors/tenantSelectors"; + getOrganizationConfig, +} from "ee/selectors/organizationSelectors"; import Helmet from "react-helmet"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; @@ -97,8 +97,8 @@ export function Login(props: LoginFormProps) { const isBrandingEnabled = useFeatureFlag( FEATURE_FLAG.license_branding_enabled, ); - const tentantConfig = useSelector(getTenantConfig); - const { instanceName } = tentantConfig; + const organizationConfig = useSelector(getOrganizationConfig); + const { instanceName } = organizationConfig; const htmlPageTitle = getHTMLPageTitle(isBrandingEnabled, instanceName); const invalidCredsForgotPasswordLinkText = createMessage( LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK, diff --git a/app/client/src/pages/UserAuth/SignUp.tsx b/app/client/src/pages/UserAuth/SignUp.tsx index 0d5db6e3eec5..b0e3ebde1205 100644 --- a/app/client/src/pages/UserAuth/SignUp.tsx +++ b/app/client/src/pages/UserAuth/SignUp.tsx @@ -48,9 +48,9 @@ import { getIsSafeRedirectURL } from "utils/helpers"; import Container from "pages/UserAuth/Container"; import { getIsFormLoginEnabled, - getTenantConfig, + getOrganizationConfig, getThirdPartyAuths, -} from "ee/selectors/tenantSelectors"; +} from "ee/selectors/organizationSelectors"; import Helmet from "react-helmet"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; @@ -119,8 +119,8 @@ export function SignUp(props: SignUpFormProps) { const isBrandingEnabled = useFeatureFlag( FEATURE_FLAG.license_branding_enabled, ); - const tentantConfig = useSelector(getTenantConfig); - const { instanceName } = tentantConfig; + const organizationConfig = useSelector(getOrganizationConfig); + const { instanceName } = organizationConfig; const htmlPageTitle = getHTMLPageTitle(isBrandingEnabled, instanceName); const recaptchaStatus = useScript( diff --git a/app/client/src/pages/UserAuth/ThirdPartyAuth.tsx b/app/client/src/pages/UserAuth/ThirdPartyAuth.tsx index cb9077bcb631..496e61d413ac 100644 --- a/app/client/src/pages/UserAuth/ThirdPartyAuth.tsx +++ b/app/client/src/pages/UserAuth/ThirdPartyAuth.tsx @@ -6,9 +6,9 @@ import type { EventName } from "ee/utils/analyticsUtilTypes"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { useLocation } from "react-router-dom"; import { Button } from "@appsmith/ads"; -import { isTenantConfig } from "ee/utils/adminSettingsHelpers"; +import { isOrganizationConfig } from "ee/utils/adminSettingsHelpers"; import { useSelector } from "react-redux"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; const ThirdPartyAuthWrapper = styled.div` display: flex; @@ -36,7 +36,7 @@ function SocialLoginButton(props: { url: string; type: SignInType; }) { - const tenantConfiguration = useSelector(getTenantConfig); + const organizationConfiguration = useSelector(getOrganizationConfig); const location = useLocation(); const queryParams = new URLSearchParams(location.search); let url = props.url; @@ -48,8 +48,8 @@ function SocialLoginButton(props: { let buttonLabel = props.name; - if (props.name && isTenantConfig(props.name)) { - buttonLabel = tenantConfiguration[props.name]; + if (props.name && isOrganizationConfig(props.name)) { + buttonLabel = organizationConfiguration[props.name]; } return ( diff --git a/app/client/src/pages/UserAuth/index.tsx b/app/client/src/pages/UserAuth/index.tsx index 2ab6a60496a0..f7d948ef3a0b 100644 --- a/app/client/src/pages/UserAuth/index.tsx +++ b/app/client/src/pages/UserAuth/index.tsx @@ -17,7 +17,7 @@ import VerificationError from "./VerificationError"; import FooterLinks from "./FooterLinks"; import { useIsMobileDevice } from "utils/hooks/useDeviceDetect"; import { getAssetUrl } from "ee/utils/airgapHelpers"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getAppsmithConfigs } from "ee/configs"; const SentryRoute = Sentry.withSentryRouting(Route); @@ -29,7 +29,7 @@ export function UserAuth() { getThemeDetails(state, ThemeMode.LIGHT), ); const isMobileDevice = useIsMobileDevice(); - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const { cloudHosting } = getAppsmithConfigs(); return ( @@ -43,7 +43,7 @@ export function UserAuth() { {isMobileDevice && ( )} diff --git a/app/client/src/pages/UserProfile/General.tsx b/app/client/src/pages/UserProfile/General.tsx index 5ba9786e2f2e..b85ddd54a19d 100644 --- a/app/client/src/pages/UserProfile/General.tsx +++ b/app/client/src/pages/UserProfile/General.tsx @@ -18,7 +18,7 @@ import { ANONYMOUS_USERNAME } from "constants/userConstants"; import { ALL_LANGUAGE_CHARACTERS_REGEX } from "constants/Regex"; import { createMessage } from "@appsmith/ads-old"; import { notEmptyValidator } from "@appsmith/ads-old"; -import { getIsFormLoginEnabled } from "ee/selectors/tenantSelectors"; +import { getIsFormLoginEnabled } from "ee/selectors/organizationSelectors"; const nameValidator = ( value: string, diff --git a/app/client/src/pages/UserProfile/index.test.tsx b/app/client/src/pages/UserProfile/index.test.tsx index d938ffd0bd3c..9e1ec87d30a4 100644 --- a/app/client/src/pages/UserProfile/index.test.tsx +++ b/app/client/src/pages/UserProfile/index.test.tsx @@ -17,8 +17,8 @@ import Login from "pages/UserAuth/Login"; const defaultStoreState = { ...unitTestBaseMockStore, - tenant: { - tenantConfiguration: {}, + organization: { + organizationConfiguration: {}, }, entities: { ...unitTestBaseMockStore.entities, diff --git a/app/client/src/pages/common/ErrorPageHeader.tsx b/app/client/src/pages/common/ErrorPageHeader.tsx index 01ce8637a9b6..50666b9caade 100644 --- a/app/client/src/pages/common/ErrorPageHeader.tsx +++ b/app/client/src/pages/common/ErrorPageHeader.tsx @@ -13,7 +13,7 @@ import ProfileDropdown from "./ProfileDropdown"; import { flushErrorsAndRedirect, flushErrors } from "actions/errorActions"; import { getSafeCrash } from "selectors/errorSelectors"; import { Indices } from "constants/Layers"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; import { NAVIGATION_SETTINGS } from "constants/AppConstants"; import { get } from "lodash"; @@ -54,7 +54,7 @@ interface ErrorPageHeaderProps { export function ErrorPageHeader(props: ErrorPageHeaderProps) { const { flushErrors, flushErrorsAndRedirect, safeCrash, user } = props; const location = useLocation(); - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const queryParams = new URLSearchParams(location.search); let loginUrl = AUTH_LOGIN_URL; const redirectUrl = queryParams.get("redirectUrl"); @@ -77,7 +77,7 @@ export function ErrorPageHeader(props: ErrorPageHeaderProps) { return ( - {tenantConfig.brandLogoUrl && ( + {organizationConfig.brandLogoUrl && ( { @@ -88,7 +88,7 @@ export function ErrorPageHeader(props: ErrorPageHeaderProps) { Logo )} diff --git a/app/client/src/pages/common/ErrorPages/Page.tsx b/app/client/src/pages/common/ErrorPages/Page.tsx index 35b90d2b4339..0d4743305c0b 100644 --- a/app/client/src/pages/common/ErrorPages/Page.tsx +++ b/app/client/src/pages/common/ErrorPages/Page.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useSelector } from "react-redux"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getComplementaryGrayscaleColor } from "widgets/WidgetUtils"; import styled from "styled-components"; import type { PageErrorMessageProps } from "./Components/PageErrorMessage"; @@ -31,8 +31,8 @@ interface PageProps { function Page(props: PageProps) { const { cta, description, errorCode, errorIcon, title } = props; - const tenantConfig = useSelector(getTenantConfig); - const backgroundColor = tenantConfig.brandColors.background; + const organizationConfig = useSelector(getOrganizationConfig); + const backgroundColor = organizationConfig.brandColors.background; const textColor = getComplementaryGrayscaleColor(backgroundColor); return ( diff --git a/app/client/src/pages/common/MobileSidebar.tsx b/app/client/src/pages/common/MobileSidebar.tsx index 299d98717267..3d89938e2666 100644 --- a/app/client/src/pages/common/MobileSidebar.tsx +++ b/app/client/src/pages/common/MobileSidebar.tsx @@ -19,7 +19,7 @@ import { } from "ee/constants/messages"; import { getAppsmithConfigs } from "ee/configs"; import { howMuchTimeBeforeText } from "utils/helpers"; -import { getTenantPermissions } from "ee/selectors/tenantSelectors"; +import { getOrganizationPermissions } from "ee/selectors/organizationSelectors"; import { DISCORD_URL } from "constants/ThirdPartyConstants"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; @@ -85,7 +85,7 @@ const LeftPaneVersionData = styled.div` export default function MobileSideBar(props: MobileSideBarProps) { const user = useSelector(getCurrentUser); - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const { appVersion } = getAppsmithConfigs(); const howMuchTimeBefore = howMuchTimeBeforeText(appVersion.releaseDate); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); @@ -116,7 +116,7 @@ export default function MobileSideBar(props: MobileSideBarProps) { path: getAdminSettingsPath( isFeatureEnabled, user?.isSuperUser, - tenantPermissions, + organizationPermissions, ), }); }} diff --git a/app/client/src/pages/common/PageHeader.tsx b/app/client/src/pages/common/PageHeader.tsx index 80e2c01499d6..522eeddd4b29 100644 --- a/app/client/src/pages/common/PageHeader.tsx +++ b/app/client/src/pages/common/PageHeader.tsx @@ -8,7 +8,7 @@ import type { AppState } from "ee/reducers"; import type { User } from "constants/userConstants"; import { useIsMobileDevice } from "utils/hooks/useDeviceDetect"; import { getTemplateNotificationSeenAction } from "actions/templateActions"; -import { shouldShowLicenseBanner } from "ee/selectors/tenantSelectors"; +import { shouldShowLicenseBanner } from "ee/selectors/organizationSelectors"; import { Banner } from "ee/utils/licenseHelpers"; import bootIntercom from "utils/bootIntercom"; import EntitySearchBar from "pages/common/SearchBar/EntitySearchBar"; diff --git a/app/client/src/pages/common/PageWrapper.tsx b/app/client/src/pages/common/PageWrapper.tsx index b7a7ba755a47..4ce4f1bd4c6c 100644 --- a/app/client/src/pages/common/PageWrapper.tsx +++ b/app/client/src/pages/common/PageWrapper.tsx @@ -8,7 +8,7 @@ import { } from "ee/utils/BusinessFeatures/brandingPageHelpers"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { useSelector } from "react-redux"; export const Wrapper = styled.section<{ isFixed?: boolean }>` @@ -68,8 +68,8 @@ export function PageWrapper(props: PageWrapperProps) { const isBrandingEnabled = useFeatureFlag( FEATURE_FLAG?.license_branding_enabled, ); - const tentantConfig = useSelector(getTenantConfig); - const { instanceName } = tentantConfig; + const organizationConfig = useSelector(getOrganizationConfig); + const { instanceName } = organizationConfig; const titleSuffix = useMemo( () => getHTMLPageTitle(isBrandingEnabled, instanceName), diff --git a/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx b/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx index 71e2c00ce521..ada799f13174 100644 --- a/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx +++ b/app/client/src/pages/common/SearchBar/EntitySearchBar.tsx @@ -10,7 +10,7 @@ import EditorButton from "components/editorComponents/Button"; import history from "utils/history"; import ProductUpdatesModal from "pages/Applications/ProductUpdatesModal"; import { useDispatch, useSelector } from "react-redux"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { getCurrentApplication, getCurrentApplicationIdForCreateNewApp, @@ -68,7 +68,7 @@ function EntitySearchBar(props: any) { useState(false); const [searchedPackages, setSearchedPackages] = useState([]); - const tenantConfig = useSelector(getTenantConfig); + const organizationConfig = useSelector(getOrganizationConfig); const isCreateNewAppFlow = useSelector( getCurrentApplicationIdForCreateNewApp, ); @@ -243,12 +243,12 @@ function EntitySearchBar(props: any) { ))} - {tenantConfig.brandLogoUrl && ( + {organizationConfig.brandLogoUrl && ( Logo )} diff --git a/app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx b/app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx index 8d259e9d7ae6..50610c34a564 100644 --- a/app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx +++ b/app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx @@ -10,7 +10,7 @@ import { } from "ee/constants/messages"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { getCurrentApplicationIdForCreateNewApp } from "ee/selectors/applicationSelectors"; -import { getTenantPermissions } from "ee/selectors/tenantSelectors"; +import { getOrganizationPermissions } from "ee/selectors/organizationSelectors"; import { getAdminSettingsPath, getShowAdminSettings, @@ -61,7 +61,7 @@ const HomepageHeaderAction = ({ }) => { const dispatch = useDispatch(); const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); - const tenantPermissions = useSelector(getTenantPermissions); + const organizationPermissions = useSelector(getOrganizationPermissions); const isCreateNewAppFlow = useSelector( getCurrentApplicationIdForCreateNewApp, ); @@ -87,7 +87,7 @@ const HomepageHeaderAction = ({ path: getAdminSettingsPath( isFeatureEnabled, user?.isSuperUser, - tenantPermissions, + organizationPermissions, ), }); }} diff --git a/app/client/src/pages/setup/SignupSuccess.tsx b/app/client/src/pages/setup/SignupSuccess.tsx index 3289f58f0667..3efe3f6ff30f 100644 --- a/app/client/src/pages/setup/SignupSuccess.tsx +++ b/app/client/src/pages/setup/SignupSuccess.tsx @@ -8,7 +8,7 @@ import { getCurrentUser } from "selectors/usersSelectors"; import UserWelcomeScreen from "pages/setup/UserWelcomeScreen"; import { Center } from "pages/setup/common"; import { Spinner } from "@appsmith/ads"; -import { isValidLicense } from "ee/selectors/tenantSelectors"; +import { isValidLicense } from "ee/selectors/organizationSelectors"; import { redirectUserAfterSignup } from "ee/utils/signupHelpers"; import { setUserSignedUpFlag } from "utils/storage"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; diff --git a/app/client/src/pages/workspace/__tests__/settings.test.tsx b/app/client/src/pages/workspace/__tests__/settings.test.tsx index 464d800eb985..cdf9124e08ae 100644 --- a/app/client/src/pages/workspace/__tests__/settings.test.tsx +++ b/app/client/src/pages/workspace/__tests__/settings.test.tsx @@ -146,7 +146,7 @@ const mockWorkspaceData = { ], slug: "sangeeth-s-apps", isAutoGeneratedWorkspace: true, - tenantId: "62a57f3c30ad39335c4dbffe", + organizationId: "62a57f3c30ad39335c4dbffe", logoUrl: "/api/v1/assets/null", new: false, }; diff --git a/app/client/src/reducers/uiReducers/errorReducer.tsx b/app/client/src/reducers/uiReducers/errorReducer.tsx index f62b5930b172..bf3e542a1ae7 100644 --- a/app/client/src/reducers/uiReducers/errorReducer.tsx +++ b/app/client/src/reducers/uiReducers/errorReducer.tsx @@ -42,11 +42,12 @@ const errorReducer = createReducer(initialState, { [ReduxActionTypes.FLUSH_ERRORS]: () => { return initialState; }, - [ReduxActionTypes.FETCH_CURRENT_TENANT_CONFIG_SUCCESS]: ( + [ReduxActionTypes.FETCH_CURRENT_ORGANIZATION_CONFIG_SUCCESS]: ( state: ErrorReduxState, ) => { if ( - state?.currentError?.sourceAction === "FETCH_CURRENT_TENANT_CONFIG_ERROR" + state?.currentError?.sourceAction === + "FETCH_CURRENT_ORGANIZATION_CONFIG_ERROR" ) { return { ...state, @@ -56,8 +57,12 @@ const errorReducer = createReducer(initialState, { return state; }, - [ReduxActionTypes.UPDATE_TENANT_CONFIG_SUCCESS]: (state: ErrorReduxState) => { - if (state?.currentError?.sourceAction === "UPDATE_TENANT_CONFIG_ERROR") { + [ReduxActionTypes.UPDATE_ORGANIZATION_CONFIG_SUCCESS]: ( + state: ErrorReduxState, + ) => { + if ( + state?.currentError?.sourceAction === "UPDATE_ORGANIZATION_CONFIG_ERROR" + ) { return { ...state, ...initialState, diff --git a/app/client/src/sagas/EvaluationsSaga.test.ts b/app/client/src/sagas/EvaluationsSaga.test.ts index 9411d9a072ba..5aa1ca60bc70 100644 --- a/app/client/src/sagas/EvaluationsSaga.test.ts +++ b/app/client/src/sagas/EvaluationsSaga.test.ts @@ -24,7 +24,7 @@ import { } from "ee/constants/ReduxActionConstants"; import { fetchPluginFormConfigsSuccess } from "actions/pluginActions"; import { createJSCollectionSuccess } from "actions/jsActionActions"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { getApplicationLastDeployedAt, getCurrentApplicationId, diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index 302629efdfe0..8bbe2180b365 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -118,7 +118,7 @@ import { getCurrentApplicationId, getCurrentPageId, } from "selectors/editorSelectors"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import type { AffectedJSObjects, EvaluationReduxAction, diff --git a/app/client/src/sagas/InitSagas.ts b/app/client/src/sagas/InitSagas.ts index 8ad5f7ff6cc9..3b3f635ec929 100644 --- a/app/client/src/sagas/InitSagas.ts +++ b/app/client/src/sagas/InitSagas.ts @@ -66,7 +66,7 @@ import { getDebuggerErrors } from "selectors/debuggerSelectors"; import { deleteErrorLog } from "actions/debuggerActions"; import { getCurrentUser } from "actions/authActions"; -import { getCurrentTenant } from "ee/actions/tenantActions"; +import { getCurrentOrganization } from "ee/actions/organizationActions"; import { fetchFeatureFlagsInit, fetchProductAlertInit, @@ -106,7 +106,7 @@ export interface ReduxURLChangeAction { export interface DeployConsolidatedApi { productAlert: ApiResponse; - tenantConfig: ApiResponse; + organizationConfig: ApiResponse; featureFlags: ApiResponse; userProfile: ApiResponse; pages: FetchApplicationResponse; @@ -120,7 +120,7 @@ export interface DeployConsolidatedApi { export interface EditConsolidatedApi { productAlert: ApiResponse; - tenantConfig: ApiResponse; + organizationConfig: ApiResponse; featureFlags: ApiResponse; userProfile: ApiResponse; pages: FetchApplicationResponse; @@ -285,8 +285,13 @@ export function* getInitResponses({ throw new PageNotFoundError(`Cannot find page with base id: ${basePageId}`); } - const { featureFlags, productAlert, tenantConfig, userProfile, ...rest } = - response || {}; + const { + featureFlags, + organizationConfig, + productAlert, + userProfile, + ...rest + } = response || {}; //actions originating from INITIALIZE_CURRENT_PAGE should update user details //other actions are not necessary @@ -298,7 +303,7 @@ export function* getInitResponses({ yield put(fetchFeatureFlagsInit(featureFlags)); - yield put(getCurrentTenant(false, tenantConfig)); + yield put(getCurrentOrganization(false, organizationConfig)); yield put(fetchProductAlertInit(productAlert)); yield call( diff --git a/app/client/src/sagas/PostEvaluationSagas.ts b/app/client/src/sagas/PostEvaluationSagas.ts index 86811acf8915..9d705214da76 100644 --- a/app/client/src/sagas/PostEvaluationSagas.ts +++ b/app/client/src/sagas/PostEvaluationSagas.ts @@ -36,7 +36,7 @@ import type { ActionEntityConfig } from "ee/entities/DataTree/types"; import type { SuccessfulBindings } from "utils/SuccessfulBindingsMap"; import SuccessfulBindingMap from "utils/SuccessfulBindingsMap"; import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import type { EvalTreeResponseData } from "workers/Evaluation/types"; import { endSpan, startRootSpan } from "instrumentation/generateTraces"; import { getJSActionPathNameToDisplay } from "ee/utils/actionExecutionUtils"; diff --git a/app/client/src/selectors/propertyPaneSelectors.tsx b/app/client/src/selectors/propertyPaneSelectors.tsx index 18dde0b5a3f7..d0d341991092 100644 --- a/app/client/src/selectors/propertyPaneSelectors.tsx +++ b/app/client/src/selectors/propertyPaneSelectors.tsx @@ -16,7 +16,7 @@ import { isPathDynamicTrigger, } from "utils/DynamicBindingUtils"; import { generateClassName } from "utils/generators"; -import { getGoogleMapsApiKey } from "ee/selectors/tenantSelectors"; +import { getGoogleMapsApiKey } from "ee/selectors/organizationSelectors"; import type { WidgetProps } from "widgets/BaseWidget"; import { getCanvasWidgets } from "ee/selectors/entitiesSelector"; import { getLastSelectedWidget, getSelectedWidgets } from "./ui"; diff --git a/app/client/src/usagePulse/utils.ts b/app/client/src/usagePulse/utils.ts index 29ed44891a5a..c4270a80f12d 100644 --- a/app/client/src/usagePulse/utils.ts +++ b/app/client/src/usagePulse/utils.ts @@ -6,7 +6,7 @@ import { getAppMode } from "ee/selectors/entitiesSelector"; import store from "store"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { FALLBACK_KEY } from "ee/constants/UsagePulse"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; //TODO (Dipyaman): We should return a promise that will get resolved only on success or rejected after the retries export const fetchWithRetry = (config: { diff --git a/app/client/src/utils/BrandingUtils.ts b/app/client/src/utils/BrandingUtils.ts index d3756991ef52..5b3d2fac00a0 100644 --- a/app/client/src/utils/BrandingUtils.ts +++ b/app/client/src/utils/BrandingUtils.ts @@ -209,13 +209,13 @@ export const faivconImageValidator = ( // NOTE: the reason why the json parsing is out of selector is we don't // want to do the parsing everytime selector is called -let cachedTenantConfigParsed = {}; -const cachedTenantConfig = localStorage.getItem("tenantConfig"); +let cachedOrganizationConfigParsed = {}; +const cachedOrganizationConfig = localStorage.getItem("organizationConfig"); try { - if (cachedTenantConfig) { - cachedTenantConfigParsed = JSON.parse(cachedTenantConfig); + if (cachedOrganizationConfig) { + cachedOrganizationConfigParsed = JSON.parse(cachedOrganizationConfig); } } catch (e) {} -export { cachedTenantConfigParsed }; +export { cachedOrganizationConfigParsed }; diff --git a/app/client/src/utils/hooks/useBrandingTheme.ts b/app/client/src/utils/hooks/useBrandingTheme.ts index 12d6df6d84d3..df0a755cb904 100644 --- a/app/client/src/utils/hooks/useBrandingTheme.ts +++ b/app/client/src/utils/hooks/useBrandingTheme.ts @@ -1,13 +1,13 @@ import { useSelector } from "react-redux"; -import { getTenantConfig } from "ee/selectors/tenantSelectors"; +import { getOrganizationConfig } from "ee/selectors/organizationSelectors"; import { useLayoutEffect } from "react"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import { APPSMITH_BRAND_PRIMARY_COLOR } from "utils/BrandingUtils"; import { LightModeTheme } from "@appsmith/wds-theming"; const useBrandingTheme = () => { - const config = useSelector(getTenantConfig); + const config = useSelector(getOrganizationConfig); let activeColor: string | undefined = undefined; if ( diff --git a/app/client/src/utils/hooks/useOnUpgrade.ts b/app/client/src/utils/hooks/useOnUpgrade.ts index 29292d2b9c62..372c93932138 100644 --- a/app/client/src/utils/hooks/useOnUpgrade.ts +++ b/app/client/src/utils/hooks/useOnUpgrade.ts @@ -1,5 +1,5 @@ import { useSelector } from "react-redux"; -import { getInstanceId } from "ee/selectors/tenantSelectors"; +import { getInstanceId } from "ee/selectors/organizationSelectors"; import { CUSTOMER_PORTAL_URL_WITH_PARAMS, PRICING_PAGE_URL, diff --git a/app/client/src/widgets/withWidgetProps.tsx b/app/client/src/widgets/withWidgetProps.tsx index 5a0f13d6c19d..7781e3131907 100644 --- a/app/client/src/widgets/withWidgetProps.tsx +++ b/app/client/src/widgets/withWidgetProps.tsx @@ -37,7 +37,7 @@ import type { WidgetEntityConfig } from "ee/entities/DataTree/types"; import { Positioning } from "layoutSystems/common/utils/constants"; import { isAutoHeightEnabledForWidget } from "./WidgetUtils"; import { CANVAS_DEFAULT_MIN_HEIGHT_PX } from "constants/AppConstants"; -import { getGoogleMapsApiKey } from "ee/selectors/tenantSelectors"; +import { getGoogleMapsApiKey } from "ee/selectors/organizationSelectors"; import ConfigTreeActions from "utils/configTree"; import { getSelectedWidgetAncestry } from "../selectors/widgetSelectors"; import { getWidgetMinMaxDimensionsInPixel } from "layoutSystems/autolayout/utils/flexWidgetUtils"; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/OrganizationSpan.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/OrganizationSpan.java new file mode 100644 index 000000000000..a9c025d5794a --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/OrganizationSpan.java @@ -0,0 +1,5 @@ +package com.appsmith.external.constants.spans; + +import com.appsmith.external.constants.spans.ce.OrganizationSpanCE; + +public class OrganizationSpan extends OrganizationSpanCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/TenantSpan.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/TenantSpan.java deleted file mode 100644 index 488238e251ec..000000000000 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/TenantSpan.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.appsmith.external.constants.spans; - -import com.appsmith.external.constants.spans.ce.TenantSpanCE; - -public class TenantSpan extends TenantSpanCE {} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java index 9e2ac07b3ee8..6b8619565624 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/ConsolidatedApiSpanNamesCE.java @@ -15,7 +15,7 @@ public class ConsolidatedApiSpanNamesCE { public static final String CONSOLIDATED_API_ROOT_VIEW = CONSOLIDATED_API_PREFIX + VIEW + ROOT; public static final String USER_PROFILE_SPAN = "user_profile"; public static final String FEATURE_FLAG_SPAN = "feature_flag"; - public static final String TENANT_SPAN = "tenant"; + public static final String ORGANIZATION_SPAN = "tenant"; public static final String PRODUCT_ALERT_SPAN = "product_alert"; public static final String APPLICATION_ID_SPAN = "application_id"; public static final String PAGES_SPAN = "pages"; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/OrganizationSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/OrganizationSpanCE.java new file mode 100644 index 000000000000..1ce36010fd97 --- /dev/null +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/OrganizationSpanCE.java @@ -0,0 +1,11 @@ +package com.appsmith.external.constants.spans.ce; + +import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX; + +public class OrganizationSpanCE { + public static final String ORGANIZATION_SPAN = APPSMITH_SPAN_PREFIX + "tenant."; + public static final String FETCH_DEFAULT_ORGANIZATION_SPAN = ORGANIZATION_SPAN + "fetch_default_tenant"; + public static final String FETCH_ORGANIZATION_CACHE_POST_DESERIALIZATION_ERROR_SPAN = + ORGANIZATION_SPAN + "fetch_tenant_cache_post_deserialization_error"; + public static final String FETCH_ORGANIZATION_FROM_DB_SPAN = ORGANIZATION_SPAN + "fetch_tenant_from_db"; +} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/TenantSpanCE.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/TenantSpanCE.java deleted file mode 100644 index 104561730b0a..000000000000 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/constants/spans/ce/TenantSpanCE.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.appsmith.external.constants.spans.ce; - -import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX; - -public class TenantSpanCE { - public static final String TENANT_SPAN = APPSMITH_SPAN_PREFIX + "tenant."; - public static final String FETCH_DEFAULT_TENANT_SPAN = TENANT_SPAN + "fetch_default_tenant"; - public static final String FETCH_TENANT_CACHE_POST_DESERIALIZATION_ERROR_SPAN = - TENANT_SPAN + "fetch_tenant_cache_post_deserialization_error"; - public static final String FETCH_TENANT_FROM_DB_SPAN = TENANT_SPAN + "fetch_tenant_from_db"; -} diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java index 1704e0e1cf49..b524a3a2c8a6 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/dtos/ExecuteActionDTO.java @@ -20,7 +20,7 @@ public class ExecuteActionDTO { String datasourceId; String workspaceId; String instanceId; - String tenantId; + String organizationId; List params; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java index 0e47bb43b866..bde30a1ef674 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java @@ -6,7 +6,7 @@ public enum FeatureFlagEnum { TEST_FEATURE_1, TEST_FEATURE_2, TEST_FEATURE_3, - TENANT_TEST_FEATURE, + ORGANIZATION_TEST_FEATURE, // ------------------- End of features for testing -------------------------------------------------------------- // // ------------------- These are actual feature flags meant to be used across the product ----------------------- // diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/TriggerRequestDTO.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/TriggerRequestDTO.java index 6c1aae7faeba..01284535afe7 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/TriggerRequestDTO.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/TriggerRequestDTO.java @@ -37,7 +37,7 @@ public class TriggerRequestDTO { String datasourceId; String actionId; String instanceId; - String tenantId; + String organizationId; // this param is expected to be sent by the client if needed String workspaceId; diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java index 70acc28eeb9d..5f9cdb89d1b3 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java @@ -255,12 +255,10 @@ default Mono executeParameterizedWithMetrics( } // TODO: Following methods of executeParameterizedWithFlags, executeParameterizedWithMetricsAndFlags, - // triggerWithFlags are - // added - // to support feature flags in the plugin modules. Current implementation of featureFlagService is only available in - // server module - // and not available in any of the plugin modules due to dependencies on SessionUserService, TenantService etc. - // Hence, these methods are added to support feature flags in the plugin modules. + // triggerWithFlags are added to support feature flags in the plugin modules. Current implementation of + // featureFlagService is only available in server module and not available in any of the plugin modules due to + // dependencies on SessionUserService, OrganizationService etc. Hence, these methods are added to support feature + // flags in the plugin modules. // Ideal solution would be to move featureFlagService and its dependencies to the shared interface module // But this is a bigger change and will be done in future. Current change of passing flags was done to resolve // release blocker diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/constants/AppsmithAiConstants.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/constants/AppsmithAiConstants.java index 384d297f0624..e8b0e1570816 100644 --- a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/constants/AppsmithAiConstants.java +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/constants/AppsmithAiConstants.java @@ -32,7 +32,7 @@ public class AppsmithAiConstants { public static final String ACTION_ID = "actionId"; public static final String WORKSPACE_ID = "workspaceId"; public static final String INSTANCE_ID = "instanceId"; - public static final String TENANT_ID = "tenantId"; + public static final String ORGANIZATION_ID = "organizationId"; public static final String SOURCE_DETAILS = "sourceDetail"; public static final String PERIOD_DELIMITER = "."; diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/dtos/SourceDetails.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/dtos/SourceDetails.java index 34fdbc2dc6cb..75b554fa020c 100644 --- a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/dtos/SourceDetails.java +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/dtos/SourceDetails.java @@ -9,14 +9,14 @@ public class SourceDetails { String workspaceId; String datasourceId; String instanceId; - String tenantId; + String organizationId; public static SourceDetails createSourceDetails(ExecuteActionDTO executeActionDTO) { SourceDetails sourceDetails = new SourceDetails(); sourceDetails.setWorkspaceId(executeActionDTO.getWorkspaceId()); sourceDetails.setDatasourceId(executeActionDTO.getDatasourceId()); sourceDetails.setInstanceId(executeActionDTO.getInstanceId()); - sourceDetails.setTenantId(executeActionDTO.getTenantId()); + sourceDetails.setOrganizationId(executeActionDTO.getOrganizationId()); return sourceDetails; } @@ -25,7 +25,7 @@ public static SourceDetails createSourceDetails(TriggerRequestDTO triggerRequest sourceDetails.setWorkspaceId(triggerRequestDTO.getWorkspaceId()); sourceDetails.setDatasourceId(triggerRequestDTO.getDatasourceId()); sourceDetails.setInstanceId(triggerRequestDTO.getInstanceId()); - sourceDetails.setTenantId(triggerRequestDTO.getTenantId()); + sourceDetails.setOrganizationId(triggerRequestDTO.getOrganizationId()); return sourceDetails; } } diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/utils/HeadersUtil.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/utils/HeadersUtil.java index 9cc8562a0309..965e11a53fe2 100644 --- a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/utils/HeadersUtil.java +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/utils/HeadersUtil.java @@ -6,7 +6,7 @@ import static com.external.plugins.constants.AppsmithAiConstants.ACTION_ID; import static com.external.plugins.constants.AppsmithAiConstants.DATASOURCE_ID; import static com.external.plugins.constants.AppsmithAiConstants.INSTANCE_ID; -import static com.external.plugins.constants.AppsmithAiConstants.TENANT_ID; +import static com.external.plugins.constants.AppsmithAiConstants.ORGANIZATION_ID; import static com.external.plugins.constants.AppsmithAiConstants.WORKSPACE_ID; public class HeadersUtil { @@ -46,9 +46,9 @@ public static String createSourceDetailsHeader(SourceDetails sourceDetails) { + COLON + sourceDetails.getWorkspaceId() + SEMI_COLON - + TENANT_ID + + ORGANIZATION_ID + COLON - + sourceDetails.getTenantId() + + sourceDetails.getOrganizationId() + SEMI_COLON + INSTANCE_ID + COLON diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AclPermission.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AclPermission.java index 1d718b9f17f1..9ee3717cc9d0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AclPermission.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AclPermission.java @@ -7,8 +7,8 @@ import com.appsmith.server.domains.Config; import com.appsmith.server.domains.NewAction; import com.appsmith.server.domains.NewPage; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.PermissionGroup; -import com.appsmith.server.domains.Tenant; import com.appsmith.server.domains.Theme; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; @@ -120,8 +120,10 @@ public enum AclPermission { @Deprecated READ_PERMISSION_GROUPS("read:permissionGroups", PermissionGroup.class), - // Manage tenant permissions - MANAGE_TENANT("manage:tenants", Tenant.class), + // Manage organization permissions + MANAGE_ORGANIZATION("manage:organization", Organization.class), + @Deprecated(forRemoval = true, since = "v1.62") + MANAGE_TENANT("manage:tenant", Organization.class), CONNECT_TO_GIT("connectToGit:applications", Application.class), MANAGE_PROTECTED_BRANCHES("manageProtectedBranches:applications", Application.class), diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AppsmithRole.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AppsmithRole.java index 2f71537d7de4..85f0a91176be 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AppsmithRole.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/acl/AppsmithRole.java @@ -5,7 +5,7 @@ import java.util.Set; import static com.appsmith.server.acl.AclPermission.DELETE_WORKSPACES; -import static com.appsmith.server.acl.AclPermission.MANAGE_TENANT; +import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATION; import static com.appsmith.server.acl.AclPermission.MANAGE_WORKSPACES; import static com.appsmith.server.acl.AclPermission.READ_WORKSPACES; import static com.appsmith.server.acl.AclPermission.WORKSPACE_CREATE_APPLICATION; @@ -62,7 +62,7 @@ public enum AppsmithRole { WORKSPACE_READ_APPLICATIONS, WORKSPACE_INVITE_USERS, WORKSPACE_EXECUTE_DATASOURCES)), - TENANT_ADMIN("", "", Set.of(MANAGE_TENANT)), + TENANT_ADMIN("", "", Set.of(MANAGE_ORGANIZATION)), ; private Set permissions; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspect.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspect.java index 2216f66e8ce4..e0377b652b23 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspect.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspect.java @@ -65,7 +65,7 @@ private Object invokeMethod(ProceedingJoinPoint joinPoint, FeatureFlagged annota return featureFlagMono.flatMapMany(isSupported -> (Flux) invokeMethod(isSupported, joinPoint, method)); } // For non-reactive methods with feature flagging annotation we will be using the in memory feature flag cache - // which is getting updated whenever the tenant feature flags are updated. + // which is getting updated whenever the organization feature flags are updated. return invokeMethod(isFeatureFlagEnabled(flagName), joinPoint, method); } @@ -108,7 +108,7 @@ AppsmithException getInvalidAnnotationUsageException(Method method, String error } boolean isFeatureFlagEnabled(FeatureFlagEnum flagName) { - CachedFeatures cachedFeatures = featureFlagService.getCachedTenantFeatureFlags(); + CachedFeatures cachedFeatures = featureFlagService.getCachedOrganizationFeatureFlags(); return cachedFeatures != null && !CollectionUtils.isNullOrEmpty(cachedFeatures.getFeatures()) && Boolean.TRUE.equals(cachedFeatures.getFeatures().get(flagName.name())); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/AuthenticationSuccessHandler.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/AuthenticationSuccessHandler.java index 66467580e46a..4d538b6e552e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/AuthenticationSuccessHandler.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/AuthenticationSuccessHandler.java @@ -8,8 +8,8 @@ import com.appsmith.server.repositories.WorkspaceRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ApplicationPageService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.services.WorkspaceService; @@ -32,7 +32,7 @@ public AuthenticationSuccessHandler( ApplicationPageService applicationPageService, WorkspacePermission workspacePermission, RateLimitService rateLimitService, - TenantService tenantService, + OrganizationService organizationService, UserService userService, WorkspaceServiceHelper workspaceServiceHelper) { super( @@ -46,7 +46,7 @@ public AuthenticationSuccessHandler( applicationPageService, workspacePermission, rateLimitService, - tenantService, + organizationService, userService, workspaceServiceHelper); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java index 1b4054ddb248..c9a02b286a55 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java @@ -17,8 +17,8 @@ import com.appsmith.server.repositories.WorkspaceRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ApplicationPageService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.services.WorkspaceService; @@ -65,14 +65,14 @@ public class AuthenticationSuccessHandlerCE implements ServerAuthenticationSucce private final ApplicationPageService applicationPageService; private final WorkspacePermission workspacePermission; private final RateLimitService rateLimitService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final UserService userService; private final WorkspaceServiceHelper workspaceServiceHelper; private Mono isVerificationRequired(String userEmail, String method) { - Mono emailVerificationEnabledMono = tenantService - .getTenantConfiguration() - .map(tenant -> tenant.getTenantConfiguration().isEmailVerificationEnabled()) + Mono emailVerificationEnabledMono = organizationService + .getOrganizationConfiguration() + .map(organization -> organization.getOrganizationConfiguration().isEmailVerificationEnabled()) .cache(); Mono userMono = userRepository.findByEmail(userEmail).cache(); @@ -80,7 +80,7 @@ private Mono isVerificationRequired(String userEmail, String method) { if ("signup".equals(method)) { verificationRequiredMono = emailVerificationEnabledMono.flatMap(emailVerificationEnabled -> { - // email verification is not enabled at the tenant, so verification not required + // email verification is not enabled at the org, so verification not required if (!TRUE.equals(emailVerificationEnabled)) { return userMono.flatMap(user -> { user.setEmailVerificationRequired(FALSE); @@ -101,12 +101,12 @@ private Mono isVerificationRequired(String userEmail, String method) { return Mono.just(FALSE); } else { return emailVerificationEnabledMono.flatMap(emailVerificationEnabled -> { - // email verification not enabled at the tenant + // email verification not enabled at the org if (!TRUE.equals(emailVerificationEnabled)) { user.setEmailVerificationRequired(FALSE); return userRepository.save(user).then(Mono.just(FALSE)); } else { - // scenario when at the time of signup, the email verification was disabled at the tenant + // scenario when at the time of signup, the email verification was disabled at the org // but later on turned on, now when this user logs in, it will not be prompted to verify // as the configuration at time of signup is considered for any user. // for old users, the login works as expected, without the need to verify diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java index 879780c0bb71..261286df2b33 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/InstanceConfig.java @@ -61,17 +61,18 @@ public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { // Prefill the server cache with anonymous user permission group ids. .then(cacheableRepositoryHelper.preFillAnonymousUserPermissionGroupIdsCache()) // Add cold publisher as we have dependency on the instance registration - // TODO Update implementation to fetch license status for all the tenants once multi-tenancy is + // TODO Update implementation to fetch license status for all the organizations once multi-tenancy is // introduced .then(Mono.defer(instanceConfigHelper::isLicenseValid) - // Ensure that the tenant feature flags are refreshed with the latest values after completing + // Ensure that the organization feature flags are refreshed with the latest values after + // completing // the // license verification process. .flatMap(isValid -> { log.debug( "License verification completed with status: {}", TRUE.equals(isValid) ? "valid" : "invalid"); - return instanceConfigHelper.updateCacheForTenantFeatureFlags(); + return instanceConfigHelper.updateCacheForOrganizationFeatureFlags(); })); try { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/OrganizationConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/OrganizationConfig.java new file mode 100644 index 000000000000..49844825d2b5 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/OrganizationConfig.java @@ -0,0 +1,47 @@ +package com.appsmith.server.configurations; + +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.helpers.CollectionUtils; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.repositories.OrganizationRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Configuration; +import reactor.core.publisher.Mono; + +import static com.appsmith.external.models.BaseDomain.policySetToMap; + +@Configuration +@RequiredArgsConstructor +@Slf4j +public class OrganizationConfig implements ApplicationListener { + + private final OrganizationRepository organizationRepository; + private final CacheableRepositoryHelper cacheableRepositoryHelper; + + // Method to cleanup the cache and update the default organization policies if the policyMap is empty. This will + // make sure + // cache will be updated if we update the organization via startup DB migrations. + // As we have mocked the OrganizationService in the tests, we had to manually evict the cache and save the object to + // DB + private Mono cleanupAndUpdateRefreshDefaultOrganizationPolicies() { + log.debug("Cleaning up and updating default organization policies on server startup"); + return organizationRepository.findBySlug(FieldName.DEFAULT).flatMap(organization -> { + if (CollectionUtils.isNullOrEmpty(organization.getPolicyMap())) { + organization.setPolicyMap(policySetToMap(organization.getPolicies())); + return cacheableRepositoryHelper + .evictCachedOrganization(organization.getId()) + .then(organizationRepository.save(organization)); + } + return Mono.just(organization); + }); + } + + @Override + public void onApplicationEvent(ApplicationStartedEvent event) { + cleanupAndUpdateRefreshDefaultOrganizationPolicies().block(); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java index f44711f4c82a..ecf53ac70d16 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/SecurityConfig.java @@ -67,9 +67,9 @@ import static com.appsmith.server.constants.Url.APPLICATION_URL; import static com.appsmith.server.constants.Url.ASSET_URL; import static com.appsmith.server.constants.Url.CUSTOM_JS_LIB_URL; +import static com.appsmith.server.constants.Url.ORGANIZATION_URL; import static com.appsmith.server.constants.Url.PAGE_URL; import static com.appsmith.server.constants.Url.PRODUCT_ALERT; -import static com.appsmith.server.constants.Url.TENANT_URL; import static com.appsmith.server.constants.Url.THEME_URL; import static com.appsmith.server.constants.Url.USAGE_PULSE_URL; import static com.appsmith.server.constants.Url.USER_URL; @@ -213,7 +213,7 @@ public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, APPLICATION_URL + "/**"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, THEME_URL + "/**"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, ACTION_URL + "/execute"), - ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, TENANT_URL + "/current"), + ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, ORGANIZATION_URL + "/current"), ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, USAGE_PULSE_URL), ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, CUSTOM_JS_LIB_URL + "/*/view"), ServerWebExchangeMatchers.pathMatchers( diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java deleted file mode 100644 index 544430ca03ca..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/TenantConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.appsmith.server.configurations; - -import com.appsmith.server.constants.FieldName; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.helpers.CollectionUtils; -import com.appsmith.server.repositories.CacheableRepositoryHelper; -import com.appsmith.server.repositories.TenantRepository; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Configuration; -import reactor.core.publisher.Mono; - -import static com.appsmith.external.models.BaseDomain.policySetToMap; - -@Configuration -@RequiredArgsConstructor -@Slf4j -public class TenantConfig implements ApplicationListener { - - private final TenantRepository tenantRepository; - private final CacheableRepositoryHelper cachableRepositoryHelper; - - // Method to cleanup the cache and update the default tenant policies if the policyMap is empty. This will make sure - // cache will be updated if we update the tenant via startup DB migrations. - // As we have mocked the TenantService in the tests, we had to manually evict the cache and save the object to DB - private Mono cleanupAndUpdateRefreshDefaultTenantPolicies() { - log.debug("Cleaning up and updating default tenant policies on server startup"); - return tenantRepository.findBySlug(FieldName.DEFAULT).flatMap(tenant -> { - if (CollectionUtils.isNullOrEmpty(tenant.getPolicyMap())) { - tenant.setPolicyMap(policySetToMap(tenant.getPolicies())); - return cachableRepositoryHelper - .evictCachedTenant(tenant.getId()) - .then(tenantRepository.save(tenant)); - } - return Mono.just(tenant); - }); - } - - @Override - public void onApplicationEvent(ApplicationStartedEvent event) { - cleanupAndUpdateRefreshDefaultTenantPolicies().block(); - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java index 90fbc54eb4cc..1f78a25c43d6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCECompatibleImpl.java @@ -1,12 +1,12 @@ package com.appsmith.server.configurations.git; import com.appsmith.external.configurations.git.GitConfigCECompatible; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import org.springframework.stereotype.Component; @Component public class GitConfigCECompatibleImpl extends GitConfigCEImpl implements GitConfigCECompatible { - public GitConfigCECompatibleImpl(TenantService tenantService) { - super(tenantService); + public GitConfigCECompatibleImpl(OrganizationService organizationService) { + super(organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java index b75010ad32d0..441cc3a7dfcf 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigCEImpl.java @@ -1,7 +1,7 @@ package com.appsmith.server.configurations.git; import com.appsmith.external.configurations.git.GitConfigCE; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; @@ -10,13 +10,13 @@ @Component public class GitConfigCEImpl implements GitConfigCE { - private final TenantService tenantService; + private final OrganizationService organizationService; @Override public Mono getIsAtomicPushAllowed() { - return tenantService - .getTenantConfiguration() - .map(tenant -> tenant.getTenantConfiguration().getIsAtomicPushAllowed()) + return organizationService + .getOrganizationConfiguration() + .map(organization -> organization.getOrganizationConfiguration().getIsAtomicPushAllowed()) .switchIfEmpty(Mono.just(false)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java index 3cef3e9c08c4..1bf8d6d51525 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/git/GitConfigImpl.java @@ -1,12 +1,12 @@ package com.appsmith.server.configurations.git; import com.appsmith.external.configurations.git.GitConfig; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import org.springframework.stereotype.Component; @Component public class GitConfigImpl extends GitConfigCECompatibleImpl implements GitConfig { - public GitConfigImpl(TenantService tenantService) { - super(tenantService); + public GitConfigImpl(OrganizationService organizationService) { + super(organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java index aeab3822f0c4..2b53895370cc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java @@ -183,7 +183,7 @@ public class FieldNameCE { public static final String ENVIRONMENT = "environment"; public static final String UNUSED_ENVIRONMENT_ID = "unused_env"; - public static final String TENANT = "tenant"; + public static final String ORGANIZATION = "organization"; public static final String SUFFIX_USER_MANAGEMENT_ROLE = " User Management"; @@ -205,5 +205,6 @@ public class FieldNameCE { public static final String ARTIFACT_CONTEXT = "artifactContext"; public static final String ARTIFACT_ID = "artifactId"; public static final String BODY = "body"; + public static final String ORGANIZATION_ID = "organizationId"; public static final String NONE = "none"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/UrlCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/UrlCE.java index c070dbeabc2e..6e1780ba6f2f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/UrlCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/UrlCE.java @@ -27,7 +27,7 @@ public class UrlCE { public static final String THEME_URL = BASE_URL + VERSION + "/themes"; public static final String APP_TEMPLATE_URL = BASE_URL + VERSION + "/app-templates"; public static final String USAGE_PULSE_URL = BASE_URL + VERSION + "/usage-pulse"; - public static final String TENANT_URL = BASE_URL + VERSION + "/tenants"; + public static final String ORGANIZATION_URL = BASE_URL + VERSION + "/tenants"; public static final String CUSTOM_JS_LIB_URL = BASE_URL + VERSION + "/libraries"; public static final String PRODUCT_ALERT = BASE_URL + VERSION + "/product-alert"; public static final String SEARCH_ENTITY_URL = BASE_URL + VERSION + "/search-entities"; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/TenantController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java similarity index 50% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/TenantController.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java index 15a914eeac6f..45de4b18e74a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/TenantController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/OrganizationController.java @@ -1,18 +1,18 @@ package com.appsmith.server.controllers; import com.appsmith.server.constants.Url; -import com.appsmith.server.controllers.ce.TenantControllerCE; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.controllers.ce.OrganizationControllerCE; +import com.appsmith.server.services.OrganizationService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j -@RequestMapping(Url.TENANT_URL) -public class TenantController extends TenantControllerCE { +@RequestMapping(Url.ORGANIZATION_URL) +public class OrganizationController extends OrganizationControllerCE { - public TenantController(TenantService service) { + public OrganizationController(OrganizationService service) { super(service); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/TenantControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/OrganizationControllerCE.java similarity index 53% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/TenantControllerCE.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/OrganizationControllerCE.java index ba34d1029f44..2e2a8c01669b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/TenantControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/OrganizationControllerCE.java @@ -2,10 +2,10 @@ import com.appsmith.external.views.Views; import com.appsmith.server.constants.Url; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.dtos.ResponseDTO; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.fasterxml.jackson.annotation.JsonView; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -18,17 +18,17 @@ import java.util.Map; @Slf4j -@RequestMapping(Url.TENANT_URL) -public class TenantControllerCE { +@RequestMapping(Url.ORGANIZATION_URL) +public class OrganizationControllerCE { - private final TenantService service; + private final OrganizationService service; - public TenantControllerCE(TenantService service) { + public OrganizationControllerCE(OrganizationService service) { this.service = service; } /** - * This API returns the tenant configuration for any user (anonymous or logged in). The configurations are set + * This API returns the organization configuration for any user (anonymous or logged in). The configurations are set * in {@link com.appsmith.server.controllers.ce.InstanceAdminControllerCE#saveEnvChanges(Map)} *

* The update and retrieval are in different controllers because it would have been weird to fetch the configurations @@ -38,15 +38,16 @@ public TenantControllerCE(TenantService service) { */ @JsonView(Views.Public.class) @GetMapping("/current") - public Mono> getTenantConfig() { - log.debug("Attempting to retrieve tenant configuration ... "); - return service.getTenantConfiguration() + public Mono> getOrganizationConfig() { + log.debug("Attempting to retrieve organization configuration ... "); + return service.getOrganizationConfiguration() .map(resource -> new ResponseDTO<>(HttpStatus.OK.value(), resource, null)); } @PutMapping("") - public Mono> updateTenantConfiguration(@RequestBody TenantConfiguration tenantConfiguration) { - return service.updateDefaultTenantConfiguration(tenantConfiguration) - .map(tenant -> new ResponseDTO<>(HttpStatus.OK.value(), tenant, null)); + public Mono> updateOrganizationConfiguration( + @RequestBody OrganizationConfiguration organizationConfiguration) { + return service.updateDefaultOrganizationConfiguration(organizationConfiguration) + .map(organization -> new ResponseDTO<>(HttpStatus.OK.value(), organization, null)); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java index 3bd7a58a0cd1..df7decf15976 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceCEImpl.java @@ -31,9 +31,9 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SequenceService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.EnvironmentPermission; @@ -97,7 +97,7 @@ public class DatasourceServiceCEImpl implements DatasourceServiceCE { private final RateLimitService rateLimitService; private final FeatureFlagService featureFlagService; private final ObservationRegistry observationRegistry; - private final TenantService tenantService; + private final OrganizationService organizationService; private final ConfigService configService; // Defines blocking duration for test as well as connection created for query execution @@ -126,7 +126,7 @@ public DatasourceServiceCEImpl( RateLimitService rateLimitService, FeatureFlagService featureFlagService, ObservationRegistry observationRegistry, - TenantService tenantService, + OrganizationService organizationService, ConfigService configService) { this.workspaceService = workspaceService; @@ -146,7 +146,7 @@ public DatasourceServiceCEImpl( this.rateLimitService = rateLimitService; this.featureFlagService = featureFlagService; this.observationRegistry = observationRegistry; - this.tenantService = tenantService; + this.organizationService = organizationService; this.configService = configService; } @@ -264,12 +264,12 @@ private Mono createEx( } private Mono setAdditionalMetadataInDatasourceStorage(DatasourceStorage datasourceStorage) { - Mono tenantIdMono = tenantService.getDefaultTenantId(); + Mono organizationIdMono = organizationService.getDefaultOrganizationId(); Mono instanceIdMono = configService.getInstanceId(); Map metadata = new HashMap<>(); - return tenantIdMono.zipWith(instanceIdMono).map(tuple -> { + return organizationIdMono.zipWith(instanceIdMono).map(tuple -> { metadata.put(TENANT_ID, tuple.getT1()); metadata.put(INSTANCE_ID, tuple.getT2()); datasourceStorage.setMetadata(metadata); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceImpl.java index 67a8e8f3d94f..adb06b2f3b3e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/datasources/base/DatasourceServiceImpl.java @@ -11,9 +11,9 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SequenceService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.EnvironmentPermission; @@ -44,7 +44,7 @@ public DatasourceServiceImpl( RateLimitService rateLimitService, FeatureFlagService featureFlagService, ObservationRegistry observationRegistry, - TenantService tenantService, + OrganizationService organizationService, ConfigService configService) { super( @@ -65,7 +65,7 @@ public DatasourceServiceImpl( rateLimitService, featureFlagService, observationRegistry, - tenantService, + organizationService, configService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java new file mode 100644 index 000000000000..6740f279b216 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Organization.java @@ -0,0 +1,38 @@ +package com.appsmith.server.domains; + +import com.appsmith.external.models.BaseDomain; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.FieldNameConstants; +import org.checkerframework.common.aliasing.qual.Unique; +import org.springframework.data.annotation.Transient; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +@Getter +@Setter +@ToString +@NoArgsConstructor +@Document +@FieldNameConstants +public class Organization extends BaseDomain implements Serializable { + + @Unique String slug; + + String displayName; + + @Transient + String instanceId; + + @Transient + String adminEmailDomainHash; + + PricingPlan pricingPlan; + + OrganizationConfiguration organizationConfiguration; + + // TODO add SSO and other configurations here after migrating from environment variables to database configuration +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/OrganizationConfiguration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/OrganizationConfiguration.java new file mode 100644 index 000000000000..5be0df072461 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/OrganizationConfiguration.java @@ -0,0 +1,9 @@ +package com.appsmith.server.domains; + +import com.appsmith.server.domains.ce.OrganizationConfigurationCE; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OrganizationConfiguration extends OrganizationConfigurationCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PermissionGroup.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PermissionGroup.java index fcb44cdc2e4f..52729bd50e55 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PermissionGroup.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PermissionGroup.java @@ -21,8 +21,12 @@ public class PermissionGroup extends BaseDomain { @NotNull String name; + @Deprecated + // TODO: Remove this field once we have migrated the data to use organizationId instead of tenantId String tenantId; + String organizationId; + String description; // TODO: refactor this to defaultDocumentId, as we can use this to store associated document id for diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PricingPlan.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PricingPlan.java index b216f0c78faf..3fc13de97019 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PricingPlan.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/PricingPlan.java @@ -1,7 +1,7 @@ package com.appsmith.server.domains; /** - * Deprecated since we use plans based on the license and this information is stored inside license tenant pricingPlan is no longer used + * Deprecated since we use plans based on the license and this information is stored inside license organization pricingPlan is no longer used */ @Deprecated public enum PricingPlan { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Tenant.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Tenant.java index f4a005bbff76..53f97fae68b6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Tenant.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Tenant.java @@ -12,6 +12,8 @@ import java.io.Serializable; +@Deprecated +// This class has been deprecated. Please use Organization instead. @Getter @Setter @ToString diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/TenantConfiguration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/TenantConfiguration.java index e4b293b814a7..ccae88485bd5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/TenantConfiguration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/TenantConfiguration.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; +@Deprecated @Data @EqualsAndHashCode(callSuper = true) public class TenantConfiguration extends TenantConfigurationCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/UsagePulse.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/UsagePulse.java index 36ed0e074d83..03637199c319 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/UsagePulse.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/UsagePulse.java @@ -15,7 +15,11 @@ public class UsagePulse extends BaseDomain { // Hashed user email private String user; private String instanceId; - private String tenantId; + private String organizationId; private Boolean viewMode; private Boolean isAnonymousUser; + + @Deprecated + // TODO: Remove this field once we have migrated the data to use organizationId instead of tenantId + private String tenantId; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java index a2444c5ac74e..87b211f2cd03 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/User.java @@ -76,9 +76,14 @@ public class User extends BaseDomain implements UserDetails, OidcUser { @JsonView(Views.Public.class) Boolean isAnonymous = false; + @Deprecated + // TODO: Remove this field once we have migrated the data to use organizationId instead of tenantId @JsonView(Views.Public.class) private String tenantId; + @JsonView(Views.Public.class) + private String organizationId; + // Field to indicate if the user is system generated or not. Expected to be `true` for system generated users, null // otherwise. // e.g. AnonymousUser is created by the system migration during the first time startup. diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Workspace.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Workspace.java index 8e72b4b98d9c..49f8fc3afa82 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Workspace.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Workspace.java @@ -47,9 +47,14 @@ public class Workspace extends BaseDomain { @JsonView(Views.Internal.class) private String logoAssetId; + @Deprecated + // TODO: Remove this field once we have migrated the data to use organizationId instead of tenantId @JsonView(Views.Public.class) private String tenantId; + @JsonView(Views.Public.class) + private String organizationId; + @JsonView(Views.Internal.class) private Boolean hasEnvironments; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/OrganizationConfigurationCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/OrganizationConfigurationCE.java new file mode 100644 index 000000000000..a8cd697d5594 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/OrganizationConfigurationCE.java @@ -0,0 +1,91 @@ +package com.appsmith.server.domains.ce; + +import com.appsmith.external.enums.FeatureFlagEnum; +import com.appsmith.server.constants.FeatureMigrationType; +import com.appsmith.server.constants.LicensePlan; +import com.appsmith.server.constants.MigrationStatus; +import com.appsmith.server.domains.License; +import com.appsmith.server.domains.OrganizationConfiguration; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Data +public class OrganizationConfigurationCE implements Serializable { + + private String googleMapsKey; + + private Boolean isFormLoginEnabled; + + private String instanceName; + + protected License license; + + // organization admin can toggle this field to enable/disable email verification + private Boolean emailVerificationEnabled; + + // We add `JsonInclude` here, so that this field is included in the JSON response, even if it is `null`. Reason is, + // if this field is not present, then the existing value in client's state doesn't get updated. It's just the way + // the splat (`...`) operator works in the client. Evidently, we'll want this for all fields in this class. + // In that sense, this class is special, because organization configuration is cached in `localStorage`, and so it's + // state + // is preserved across browser refreshes. + @JsonInclude + private List thirdPartyAuths; + + // Field to be used to track the status of migrations during upgrade and downgrade workflows. Downgrade migrations + // are gated by user consent whereas upgrade can be triggered immediately and depending upon the status client + // blocks the user access to the instance + MigrationStatus migrationStatus = MigrationStatus.COMPLETED; + + // Field to store the list of features for which the migrations are pending. This will be used to store the diffs of + // the feature flags. This can happen for 2 reasons: + // 1. The license plan changes + // 2. Because of grandfathering via cron where organization level feature flags are fetched + Map featuresWithPendingMigration; + + // This variable is used to indicate if the server needs to be restarted after the migration based on feature flags + // is complete. + Boolean isRestartRequired; + + Boolean isStrongPasswordPolicyEnabled; + + private Boolean isAtomicPushAllowed = false; + + public void addThirdPartyAuth(String auth) { + if (thirdPartyAuths == null) { + thirdPartyAuths = new ArrayList<>(); + } + thirdPartyAuths.add(auth); + } + + public void copyNonSensitiveValues(OrganizationConfiguration organizationConfiguration) { + license = new License(); + license.setPlan(LicensePlan.FREE); + + if (organizationConfiguration == null) { + return; + } + + googleMapsKey = ObjectUtils.defaultIfNull(organizationConfiguration.getGoogleMapsKey(), googleMapsKey); + isFormLoginEnabled = + ObjectUtils.defaultIfNull(organizationConfiguration.getIsFormLoginEnabled(), isFormLoginEnabled); + instanceName = ObjectUtils.defaultIfNull(organizationConfiguration.getInstanceName(), instanceName); + emailVerificationEnabled = ObjectUtils.defaultIfNull( + organizationConfiguration.isEmailVerificationEnabled(), emailVerificationEnabled); + + featuresWithPendingMigration = organizationConfiguration.getFeaturesWithPendingMigration(); + migrationStatus = organizationConfiguration.getMigrationStatus(); + isStrongPasswordPolicyEnabled = organizationConfiguration.getIsStrongPasswordPolicyEnabled(); + isAtomicPushAllowed = organizationConfiguration.getIsAtomicPushAllowed(); + } + + public Boolean isEmailVerificationEnabled() { + return Boolean.TRUE.equals(this.emailVerificationEnabled); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java index 74a62527e47c..29f5e4e84bb3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/TenantConfigurationCE.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; +@Deprecated @Data public class TenantConfigurationCE implements Serializable { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/FeaturesRequestDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/FeaturesRequestDTO.java index f18672b49a58..d1f61bd79f39 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/FeaturesRequestDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/FeaturesRequestDTO.java @@ -7,7 +7,7 @@ @Setter public class FeaturesRequestDTO { private String instanceId; - private String tenantId; + private String organizationId; private String appsmithVersion; private Boolean isCloudHosting; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java index 92b6adab46e8..9767c1ae6232 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/UserSessionDTO.java @@ -45,7 +45,7 @@ public class UserSessionDTO { private Set workspaceIds; - private String tenantId; + private String organizationId; private Object credentials; @@ -85,7 +85,7 @@ public static UserSessionDTO fromToken(Authentication authentication) { session.state = user.getState(); session.isEnabled = user.isEnabled(); session.workspaceIds = user.getWorkspaceIds(); - session.tenantId = user.getTenantId(); + session.organizationId = user.getOrganizationId(); session.emailVerified = Boolean.TRUE.equals(user.getEmailVerified()); session.emailVerificationRequired = Boolean.TRUE.equals(user.getEmailVerificationRequired()); @@ -126,7 +126,7 @@ public Authentication makeToken() { user.setState(state); user.setIsEnabled(isEnabled); user.setWorkspaceIds(workspaceIds); - user.setTenantId(tenantId); + user.setOrganizationId(organizationId); user.setEmailVerified(Boolean.TRUE.equals(emailVerified)); user.setEmailVerificationRequired(Boolean.TRUE.equals(emailVerificationRequired)); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ConsolidatedAPIResponseCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ConsolidatedAPIResponseCE_DTO.java index d51d75e23b2c..a9eb001f8a63 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ConsolidatedAPIResponseCE_DTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/ConsolidatedAPIResponseCE_DTO.java @@ -3,8 +3,8 @@ import com.appsmith.external.models.ActionDTO; import com.appsmith.external.models.Datasource; import com.appsmith.server.domains.CustomJSLib; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.Plugin; -import com.appsmith.server.domains.Tenant; import com.appsmith.server.domains.Theme; import com.appsmith.server.dtos.ActionCollectionDTO; import com.appsmith.server.dtos.ActionCollectionViewDTO; @@ -36,7 +36,7 @@ public class ConsolidatedAPIResponseCE_DTO { ResponseDTO> featureFlags; /* v1/tenants/current */ - ResponseDTO tenantConfig; + ResponseDTO organizationConfig; /* v1/product-alert/alert */ ResponseDTO productAlert; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java index 1a9e705fb383..49df751a001e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java @@ -912,9 +912,9 @@ public enum AppsmithError { ErrorType.INTERNAL_ERROR, null), - TENANT_EMAIL_VERIFICATION_NOT_ENABLED( + ORGANIZATION_EMAIL_VERIFICATION_NOT_ENABLED( 400, - AppsmithErrorCode.TENANT_EMAIL_VERIFICATION_NOT_ENABLED.getCode(), + AppsmithErrorCode.ORGANIZATION_EMAIL_VERIFICATION_NOT_ENABLED.getCode(), "Email verification is not enabled. Please contact your admin", AppsmithErrorAction.DEFAULT, "Email verification not enabled", diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithErrorCode.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithErrorCode.java index 4824f9815e22..44b154674c90 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithErrorCode.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithErrorCode.java @@ -123,7 +123,7 @@ public enum AppsmithErrorCode { USER_EMAIL_ALREADY_VERIFIED("AE-EMV-4095", "User email already verified"), EMAIL_VERIFICATION_TOKEN_EXPIRED("AE-EMV-4096", "Email Verification Token expired"), - TENANT_EMAIL_VERIFICATION_NOT_ENABLED("AE-EMV-4097", "Email Verification not enabled"), + ORGANIZATION_EMAIL_VERIFICATION_NOT_ENABLED("AE-EMV-4097", "Email Verification not enabled"), INVALID_EMAIL_VERIFICATION("AE-EMV-4098", "Invalid email verification request"), diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/FeatureFlagIdentityTraits.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/FeatureFlagIdentityTraits.java index 204c93c8bb94..f87209b01652 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/FeatureFlagIdentityTraits.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/featureflags/FeatureFlagIdentityTraits.java @@ -18,7 +18,7 @@ @AllArgsConstructor public class FeatureFlagIdentityTraits { String instanceId; - String tenantId; + String organizationId; Set userIdentifiers; Map traits; String appsmithVersion; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/EmailServiceHelperImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/EmailServiceHelperImpl.java index afa9819ce76d..57fda98d43da 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/EmailServiceHelperImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/EmailServiceHelperImpl.java @@ -1,12 +1,12 @@ package com.appsmith.server.helpers; import com.appsmith.server.helpers.ce.EmailServiceHelperCEImpl; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import org.springframework.stereotype.Component; @Component public class EmailServiceHelperImpl extends EmailServiceHelperCEImpl implements EmailServiceHelper { - public EmailServiceHelperImpl(TenantService tenantService) { - super(tenantService); + public EmailServiceHelperImpl(OrganizationService organizationService) { + super(organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/InMemoryCacheableRepositoryHelper.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/InMemoryCacheableRepositoryHelper.java index cbf2e123c357..b409e60b3436 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/InMemoryCacheableRepositoryHelper.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/InMemoryCacheableRepositoryHelper.java @@ -8,7 +8,7 @@ public class InMemoryCacheableRepositoryHelper { private Set anonymousUserPermissionGroupIds = null; - private String defaultTenantId = null; + private String defaultOrganizationId = null; private String instanceAdminPermissionGroupId = null; @@ -20,12 +20,12 @@ public void setAnonymousUserPermissionGroupIds(Set anonymousUserPermissi this.anonymousUserPermissionGroupIds = anonymousUserPermissionGroupIds; } - public String getDefaultTenantId() { - return defaultTenantId; + public String getDefaultOrganizationId() { + return defaultOrganizationId; } - public void setDefaultTenantId(String defaultTenantId) { - this.defaultTenantId = defaultTenantId; + public void setDefaultOrganizationId(String defaultOrganizationId) { + this.defaultOrganizationId = defaultOrganizationId; } public void setInstanceAdminPermissionGroupId(String instanceAdminPermissionGroupId) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/EmailServiceHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/EmailServiceHelperCEImpl.java index 2dca84c12c4f..239be2322bc7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/EmailServiceHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/EmailServiceHelperCEImpl.java @@ -1,7 +1,7 @@ package com.appsmith.server.helpers.ce; -import com.appsmith.server.domains.TenantConfiguration; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.domains.OrganizationConfiguration; +import com.appsmith.server.services.OrganizationService; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -23,13 +23,14 @@ @AllArgsConstructor public class EmailServiceHelperCEImpl implements EmailServiceHelperCE { - private final TenantService tenantService; + private final OrganizationService organizationService; @Override public Mono> enrichWithBrandParams(Map params, String origin) { - return tenantService.getTenantConfiguration().map(tenant -> { - final TenantConfiguration tenantConfiguration = tenant.getTenantConfiguration(); - params.put(INSTANCE_NAME, StringUtils.defaultIfEmpty(tenantConfiguration.getInstanceName(), "Appsmith")); + return organizationService.getOrganizationConfiguration().map(organization -> { + final OrganizationConfiguration organizationConfiguration = organization.getOrganizationConfiguration(); + params.put( + INSTANCE_NAME, StringUtils.defaultIfEmpty(organizationConfiguration.getInstanceName(), "Appsmith")); return params; }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCE.java index 0a89a9c81fca..3df6f2d0577c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCE.java @@ -2,19 +2,20 @@ import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.server.constants.FeatureMigrationType; -import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.Organization; import reactor.core.publisher.Mono; import java.util.Map; public interface FeatureFlagMigrationHelperCE { - Mono> getUpdatedFlagsWithPendingMigration(Tenant defaultTenant); + Mono> getUpdatedFlagsWithPendingMigration( + Organization defaultOrganization); Mono> getUpdatedFlagsWithPendingMigration( - Tenant tenant, boolean forceUpdate); + Organization organization, boolean forceUpdate); - Mono checkAndExecuteMigrationsForFeatureFlag(Tenant tenant, FeatureFlagEnum featureFlagEnum); + Mono checkAndExecuteMigrationsForFeatureFlag(Organization organization, FeatureFlagEnum featureFlagEnum); - Mono executeMigrationsBasedOnFeatureFlag(Tenant tenant, FeatureFlagEnum featureFlagEnum); + Mono executeMigrationsBasedOnFeatureFlag(Organization organization, FeatureFlagEnum featureFlagEnum); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCEImpl.java index 566d2865adf8..df4756817626 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/FeatureFlagMigrationHelperCEImpl.java @@ -2,8 +2,8 @@ import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.server.constants.FeatureMigrationType; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.services.CacheableFeatureFlagHelper; @@ -32,74 +32,76 @@ public class FeatureFlagMigrationHelperCEImpl implements FeatureFlagMigrationHel /** * To avoid race condition keep the refresh rate lower than cron execution interval {@link ScheduledTaskCEImpl} - * to update the tenant level feature flags + * to update the org level feature flags */ - private static final long TENANT_FEATURES_CACHE_TIME_MIN = 115; + private static final long ORGANIZATION_FEATURES_CACHE_TIME_MIN = 115; @Override - public Mono> getUpdatedFlagsWithPendingMigration(Tenant defaultTenant) { - return getUpdatedFlagsWithPendingMigration(defaultTenant, FALSE); + public Mono> getUpdatedFlagsWithPendingMigration( + Organization defaultOrganization) { + return getUpdatedFlagsWithPendingMigration(defaultOrganization, FALSE); } /** * Method to get the updated feature flags with pending migrations. This method finds and registers the flags for * migration by comparing the diffs between the feature flags stored in cache and the latest one pulled from CS - * @param tenant Tenant for which the feature flags need to be updated - * @param forceUpdate Flag to force update the tenant level feature flags + * @param organization Organization for which the feature flags need to be updated + * @param forceUpdate Flag to force update the organization level feature flags * @return Map of feature flags with pending migrations */ @Override public Mono> getUpdatedFlagsWithPendingMigration( - Tenant tenant, boolean forceUpdate) { + Organization organization, boolean forceUpdate) { /* * 1. Fetch current/saved feature flags from cache - * 2. Force update the tenant flags keeping existing flags as fallback in case the API call to fetch the flags fails for some reason + * 2. Force update the organization flags keeping existing flags as fallback in case the API call to fetch the flags fails for some reason * 3. Get the diff and update the flags with pending migrations to be used to run migrations selectively */ return cacheableFeatureFlagHelper - .fetchCachedTenantFeatures(tenant.getId()) + .fetchCachedOrganizationFeatures(organization.getId()) .zipWhen(existingCachedFlags -> { if (existingCachedFlags.getRefreshedAt().until(Instant.now(), ChronoUnit.MINUTES) - < TENANT_FEATURES_CACHE_TIME_MIN + < ORGANIZATION_FEATURES_CACHE_TIME_MIN && !forceUpdate) { return Mono.just(existingCachedFlags); } - return this.refreshTenantFeatures(tenant, existingCachedFlags); + return this.refreshOrganizationFeatures(organization, existingCachedFlags); }) .map(tuple2 -> { CachedFeatures existingCachedFlags = tuple2.getT1(); CachedFeatures latestFlags = tuple2.getT2(); - return this.getUpdatedFlagsWithPendingMigration(tenant, latestFlags, existingCachedFlags); + return this.getUpdatedFlagsWithPendingMigration(organization, latestFlags, existingCachedFlags); }); } /** - * Method to force update the tenant level feature flags. This will be utilised in scenarios where we don't want + * Method to force update the organization level feature flags. This will be utilised in scenarios where we don't want * to wait for the flags to get updated for cron scheduled time * - * @param tenant tenant for which the feature flags need to be updated + * @param organization organization for which the feature flags need to be updated * @return Cached features */ - private Mono refreshTenantFeatures(Tenant tenant, CachedFeatures existingCachedFeatures) { + private Mono refreshOrganizationFeatures( + Organization organization, CachedFeatures existingCachedFeatures) { /* 1. Force update the flag a. Evict the cache b. Fetch and save latest flags from CS - 2. In case the tenant is unable to fetch the latest flags save the existing flags from step 1 to cache (fallback) + 2. In case the organization is unable to fetch the latest flags save the existing flags from step 1 to cache (fallback) */ - String tenantId = tenant.getId(); + String organizationId = organization.getId(); return cacheableFeatureFlagHelper - .evictCachedTenantFeatures(tenantId) - .then(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(tenantId)) + .evictCachedOrganizationFeatures(organizationId) + .then(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(organizationId)) .flatMap(features -> { if (CollectionUtils.isNullOrEmpty(features.getFeatures())) { // In case the retrieval of the latest flags from CS encounters an error, the previous flags // will serve as a fallback value. return cacheableFeatureFlagHelper - .evictCachedTenantFeatures(tenantId) - .then(cacheableFeatureFlagHelper.updateCachedTenantFeatures( - tenantId, existingCachedFeatures)); + .evictCachedOrganizationFeatures(organizationId) + .then(cacheableFeatureFlagHelper.updateCachedOrganizationFeatures( + organizationId, existingCachedFeatures)); } return Mono.just(features); }); @@ -121,16 +123,16 @@ private Mono refreshTenantFeatures(Tenant tenant, CachedFeatures * Step 4: User adds the valid key or renews the subscription again which results in enabling the feature and * ends up in nullifying the effect for step 2 * - * @param tenant Tenant for which the feature flag migrations stats needs to be stored + * @param organization Organization for which the feature flag migrations stats needs to be stored * @param latestFlags Latest flags pulled in from CS * @param existingCachedFlags Flags which are already stored in cache - * @return updated tenant with the required flags with pending migrations + * @return updated organization with the required flags with pending migrations */ private Map getUpdatedFlagsWithPendingMigration( - Tenant tenant, CachedFeatures latestFlags, CachedFeatures existingCachedFlags) { + Organization organization, CachedFeatures latestFlags, CachedFeatures existingCachedFlags) { // 1. Check if there are any diffs for the feature flags - // 2. Update the flags for pending migration within provided tenant object + // 2. Update the flags for pending migration within provided organization object Map featureDiffsWithMigrationType = new HashMap<>(); Map existingFeatureMap = existingCachedFlags.getFeatures(); latestFlags.getFeatures().forEach((key, value) -> { @@ -147,16 +149,17 @@ private Map getUpdatedFlagsWithPendingMig } } }); - return getUpdatedFlagsWithPendingMigration(featureDiffsWithMigrationType, tenant); + return getUpdatedFlagsWithPendingMigration(featureDiffsWithMigrationType, organization); } private Map getUpdatedFlagsWithPendingMigration( - Map latestFeatureDiffsWithMigrationType, Tenant dbTenant) { + Map latestFeatureDiffsWithMigrationType, + Organization dbOrganization) { Map featuresWithPendingMigrationDB = - dbTenant.getTenantConfiguration().getFeaturesWithPendingMigration() == null + dbOrganization.getOrganizationConfiguration().getFeaturesWithPendingMigration() == null ? new HashMap<>() - : dbTenant.getTenantConfiguration().getFeaturesWithPendingMigration(); + : dbOrganization.getOrganizationConfiguration().getFeaturesWithPendingMigration(); Map updatedFlagsForMigrations = new HashMap<>(featuresWithPendingMigrationDB); @@ -197,25 +200,26 @@ with disable type (This will happen via cron to check the license status) /** * Method to check and execute if the migrations are required for the provided feature flag. - * @param tenant Tenant for which the migrations need to be executed + * @param organization Organization for which the migrations need to be executed * @param featureFlagEnum Feature flag for which the migrations need to be executed * @return Boolean indicating if the migrations is successfully executed or not */ - public Mono checkAndExecuteMigrationsForFeatureFlag(Tenant tenant, FeatureFlagEnum featureFlagEnum) { + public Mono checkAndExecuteMigrationsForFeatureFlag( + Organization organization, FeatureFlagEnum featureFlagEnum) { - TenantConfiguration tenantConfiguration = tenant.getTenantConfiguration(); + OrganizationConfiguration organizationConfiguration = organization.getOrganizationConfiguration(); if (featureFlagEnum == null - || tenantConfiguration == null - || CollectionUtils.isNullOrEmpty(tenantConfiguration.getFeaturesWithPendingMigration())) { + || organizationConfiguration == null + || CollectionUtils.isNullOrEmpty(organizationConfiguration.getFeaturesWithPendingMigration())) { return Mono.just(TRUE); } - return isMigrationRequired(tenant, featureFlagEnum).flatMap(isMigrationRequired -> { + return isMigrationRequired(organization, featureFlagEnum).flatMap(isMigrationRequired -> { if (FALSE.equals(isMigrationRequired)) { return Mono.just(TRUE); } Map featuresWithPendingMigration = - tenantConfiguration.getFeaturesWithPendingMigration(); + organizationConfiguration.getFeaturesWithPendingMigration(); if (CollectionUtils.isNullOrEmpty(featuresWithPendingMigration) || !featuresWithPendingMigration.containsKey(featureFlagEnum)) { return Mono.just(TRUE); @@ -224,24 +228,24 @@ public Mono checkAndExecuteMigrationsForFeatureFlag(Tenant tenant, Feat "Running the migration for flag {} with migration type {}", featureFlagEnum.name(), featuresWithPendingMigration.get(featureFlagEnum)); - return this.executeMigrationsBasedOnFeatureFlag(tenant, featureFlagEnum); + return this.executeMigrationsBasedOnFeatureFlag(organization, featureFlagEnum); }); } /** * Method to check if the migrations are required for the provided feature flag. - * @param tenant Tenant for which the migrations need to be executed + * @param organization Organization for which the migrations need to be executed * @param featureFlagEnum Feature flag for which the migrations need to be executed * @return Boolean indicating if the migrations is required or not */ - private Mono isMigrationRequired(Tenant tenant, FeatureFlagEnum featureFlagEnum) { + private Mono isMigrationRequired(Organization organization, FeatureFlagEnum featureFlagEnum) { Map featureMigrationTypeMap = - tenant.getTenantConfiguration().getFeaturesWithPendingMigration(); + organization.getOrganizationConfiguration().getFeaturesWithPendingMigration(); if (CollectionUtils.isNullOrEmpty(featureMigrationTypeMap)) { return Mono.just(FALSE); } return cacheableFeatureFlagHelper - .fetchCachedTenantFeatures(tenant.getId()) + .fetchCachedOrganizationFeatures(organization.getId()) .map(cachedFeatures -> { Map featureFlags = cachedFeatures.getFeatures(); if (featureFlags.containsKey(featureFlagEnum.name())) { @@ -258,12 +262,13 @@ private Mono isMigrationRequired(Tenant tenant, FeatureFlagEnum feature /** * Method to execute the migrations for the given feature flag. - * @param tenant Tenant for which the migrations need to be executed + * @param organization Organization for which the migrations need to be executed * @param featureFlagEnum Feature flag for which the migrations need to be executed * @return Boolean indicating if the migrations is successfully executed or not */ @Override - public Mono executeMigrationsBasedOnFeatureFlag(Tenant tenant, FeatureFlagEnum featureFlagEnum) { + public Mono executeMigrationsBasedOnFeatureFlag( + Organization organization, FeatureFlagEnum featureFlagEnum) { return Mono.just(TRUE); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCE.java index 9d97843468bb..18d5b550246b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCE.java @@ -17,5 +17,5 @@ public interface InstanceConfigHelperCE { Mono checkMongoDBVersion(); - Mono updateCacheForTenantFeatureFlags(); + Mono updateCacheForOrganizationFeatureFlags(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java index 68126fa0c7da..1d26b253898b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/InstanceConfigHelperCEImpl.java @@ -226,7 +226,7 @@ public Mono checkMongoDBVersion() { } @Override - public Mono updateCacheForTenantFeatureFlags() { - return featureFlagService.getTenantFeatures().then(); + public Mono updateCacheForOrganizationFeatureFlags() { + return featureFlagService.getOrganizationFeatures().then(); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/UserUtilsCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/UserUtilsCE.java index eea297afe722..b927e4f6d7ad 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/UserUtilsCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/UserUtilsCE.java @@ -91,7 +91,7 @@ public Mono makeSuperUser(List users) { .then(Mono.just(users)) .flatMapMany(Flux::fromIterable) .flatMap(user -> permissionGroupRepository.evictAllPermissionGroupCachesForUser( - user.getEmail(), user.getTenantId())) + user.getEmail(), user.getOrganizationId())) .then(Mono.just(Boolean.TRUE)); } @@ -110,7 +110,7 @@ public Mono removeSuperUser(List users) { .then(Mono.just(users)) .flatMapMany(Flux::fromIterable) .flatMap(user -> permissionGroupRepository.evictAllPermissionGroupCachesForUser( - user.getEmail(), user.getTenantId())) + user.getEmail(), user.getOrganizationId())) .then(Mono.just(Boolean.TRUE)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java index ba30d97b5614..bfd58c438d5b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java @@ -25,7 +25,6 @@ import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; import com.appsmith.server.dtos.Permission; -import com.appsmith.server.helpers.TextUtils; import com.appsmith.server.migrations.solutions.UpdateSuperUserMigrationHelper; import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.solutions.PolicySolution; @@ -62,15 +61,12 @@ import static com.appsmith.server.acl.AclPermission.READ_PERMISSION_GROUP_MEMBERS; import static com.appsmith.server.acl.AclPermission.READ_THEMES; import static com.appsmith.server.acl.AppsmithRole.TENANT_ADMIN; -import static com.appsmith.server.constants.EnvVariables.APPSMITH_ADMIN_EMAILS; import static com.appsmith.server.constants.FieldName.DEFAULT_PERMISSION_GROUP; import static com.appsmith.server.constants.FieldName.PERMISSION_GROUP_ID; -import static com.appsmith.server.helpers.CollectionUtils.findSymmetricDiff; import static com.appsmith.server.migrations.DatabaseChangelog1.dropIndexIfExists; import static com.appsmith.server.migrations.DatabaseChangelog1.ensureIndexes; import static com.appsmith.server.migrations.DatabaseChangelog1.installPluginToAllWorkspaces; import static com.appsmith.server.migrations.DatabaseChangelog1.makeIndex; -import static com.appsmith.server.migrations.MigrationHelperMethods.evictPermissionCacheForUsers; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; import static org.springframework.data.mongodb.core.query.Update.update; @@ -443,65 +439,6 @@ public static void doAddPermissionGroupIndex(MongoTemplate mongoTemplate) { ensureIndexes(mongoTemplate, PermissionGroup.class, assignedToUserIds_deleted_compound_index); } - /** - * Changing the order of this function to 10000 so that it always gets executed at the end. - * This ensures that any permission changes for super users happen once all other migrations are completed - */ - @ChangeSet(order = "10000", id = "update-super-users", author = "", runAlways = true) - public void updateSuperUsers( - MongoTemplate mongoTemplate, - CacheableRepositoryHelper cacheableRepositoryHelper, - PolicySolution policySolution, - PolicyGenerator policyGenerator) { - // Read the admin emails from the environment and update the super users accordingly - String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS)); - - Set adminEmails = TextUtils.csvToSet(adminEmailsStr); - - Query instanceConfigurationQuery = new Query(); - instanceConfigurationQuery.addCriteria(where(Config.Fields.name).is(FieldName.INSTANCE_CONFIG)); - Config instanceAdminConfiguration = mongoTemplate.findOne(instanceConfigurationQuery, Config.class); - - String instanceAdminPermissionGroupId = - (String) instanceAdminConfiguration.getConfig().get(DEFAULT_PERMISSION_GROUP); - - Query permissionGroupQuery = new Query(); - permissionGroupQuery - .addCriteria(where(PermissionGroup.Fields.id).is(instanceAdminPermissionGroupId)) - .fields() - .include(PermissionGroup.Fields.assignedToUserIds); - PermissionGroup instanceAdminPG = mongoTemplate.findOne(permissionGroupQuery, PermissionGroup.class); - - Query tenantQuery = new Query(); - tenantQuery.addCriteria(where(Tenant.Fields.slug).is("default")); - Tenant tenant = mongoTemplate.findOne(tenantQuery, Tenant.class); - - Set userIds = adminEmails.stream() - .map(email -> email.trim()) - .map(String::toLowerCase) - .map(email -> { - Query userQuery = new Query(); - userQuery.addCriteria(where(User.Fields.email).is(email)); - User user = mongoTemplate.findOne(userQuery, User.class); - - if (user == null) { - log.info("Creating super user with username {}", email); - user = updateSuperUserMigrationHelper.createNewUser( - email, tenant, instanceAdminPG, mongoTemplate, policySolution, policyGenerator); - } - - return user.getId(); - }) - .collect(Collectors.toSet()); - - Set oldSuperUsers = instanceAdminPG.getAssignedToUserIds(); - Set updatedUserIds = findSymmetricDiff(oldSuperUsers, userIds); - evictPermissionCacheForUsers(updatedUserIds, mongoTemplate, cacheableRepositoryHelper); - - Update update = new Update().set(PermissionGroup.Fields.assignedToUserIds, userIds); - mongoTemplate.updateFirst(permissionGroupQuery, update, PermissionGroup.class); - } - @ChangeSet(order = "034", id = "update-bad-theme-state", author = "") public void updateBadThemeState( MongoTemplate mongoTemplate, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java index 277a3ac5768e..c361a99812cd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java @@ -224,7 +224,7 @@ public static void evictPermissionCacheForUsers( if (user != null) { // blocking call for cache eviction to ensure its subscribed immediately before proceeding further. cacheableRepositoryHelper - .evictPermissionGroupsUser(user.getEmail(), user.getTenantId()) + .evictPermissionGroupsUser(user.getEmail(), user.getOrganizationId()) .block(); } }); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration059PolicySetToPolicyMap.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration059PolicySetToPolicyMap.java index 76c3f6d00ac5..501414f0d527 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration059PolicySetToPolicyMap.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration059PolicySetToPolicyMap.java @@ -91,7 +91,13 @@ public void execute() { tenantQuery.addCriteria(where(Tenant.Fields.slug).is(DEFAULT)); Tenant defaultTenant = mongoTemplate.findOne(tenantQuery, Tenant.class).block(); assert defaultTenant != null : "Default tenant not found"; - cacheableRepositoryHelper.evictCachedTenant(defaultTenant.getId()).block(); + + // The following code line has been commented as part of Tenant to Organization migration. The function does not + // exist + // anymore and no need to evict the cached tenant anymore because Migration 065 would migrate the tenant to + // organization + // and a new cache line would be set for the organization. + // cacheableRepositoryHelper.evictCachedTenant(defaultTenant.getId()).block(); } private static Mono executeForCollection(ReactiveMongoTemplate mongoTemplate, String collectionName) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration061TenantPolicySetToPolicyMap.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration061TenantPolicySetToPolicyMap.java index cb966fd6b810..592f39090790 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration061TenantPolicySetToPolicyMap.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration061TenantPolicySetToPolicyMap.java @@ -49,7 +49,13 @@ public void executeMigration() { defaultTenant.getPolicies().forEach(policy -> policyMap.put(policy.getPermission(), policy)); defaultTenant.setPolicyMap(policyMap); mongoTemplate.save(defaultTenant); - cacheableRepositoryHelper.evictCachedTenant(defaultTenant.getId()).block(); + + // The following code line has been commented as part of Tenant to Organization migration. The function does + // not exist + // anymore and no need to evict the cached tenant anymore because Migration 065 would migrate the tenant to + // organization + // and a new cache line would be set for the organization. + // cacheableRepositoryHelper.evictCachedTenant(defaultTenant.getId()).block(); } else { log.info( "Tenant already has policyMap set. Skipping migration to update policy set to map in tenant Migration061TenantPolicySetToPolicyMap."); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration065_CopyTenantIdToOrganizationId.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration065_CopyTenantIdToOrganizationId.java new file mode 100644 index 000000000000..7cf8d0945f00 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration065_CopyTenantIdToOrganizationId.java @@ -0,0 +1,242 @@ +package com.appsmith.server.migrations.db.ce; + +import com.appsmith.external.models.Policy; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.PermissionGroup; +import com.appsmith.server.domains.UsagePulse; +import com.appsmith.server.domains.User; +import com.appsmith.server.domains.Workspace; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.mongodb.DuplicateKeyException; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import lombok.extern.slf4j.Slf4j; +import org.bson.Document; +import org.bson.types.ObjectId; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.redis.core.ReactiveRedisOperations; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.springframework.data.mongodb.core.query.Criteria.where; + +@Slf4j +@ChangeUnit(id = "copy-tenant-id-to-organization-id", order = "065") +public class Migration065_CopyTenantIdToOrganizationId { + + private final ReactiveRedisOperations reactiveRedisOperations; + private final ObjectMapper objectMapper; + private final MongoTemplate mongoTemplate; + + private final List> DOMAIN_CLASSES = + Arrays.asList(User.class, Workspace.class, PermissionGroup.class, UsagePulse.class); + + public Migration065_CopyTenantIdToOrganizationId( + @Qualifier("reactiveRedisOperations") ReactiveRedisOperations reactiveRedisOperations, + ObjectMapper objectMapper, + MongoTemplate mongoTemplate) { + this.reactiveRedisOperations = reactiveRedisOperations; + this.objectMapper = objectMapper; + this.mongoTemplate = mongoTemplate; + } + + @RollbackExecution + public void rollbackExecution() {} + + @Execution + public void execute() { + migrateTenantCollection(); + migrateMongoCollections(); + migrateRedisData(); + } + + private void migrateTenantCollection() { + try { + // Get the single tenant document + Document tenant = mongoTemplate.findOne(new Query(), Document.class, "tenant"); + + if (tenant == null) { + log.info("No tenant found to migrate"); + return; + } + + try { + // Create new organization document + Document organizationDocument = new Document(); + + // Copy all fields from tenant to organization + organizationDocument.putAll(tenant); + + // Ensure the _id is preserved + String tenantId = tenant.getObjectId("_id").toString(); + organizationDocument.put("_id", new ObjectId(tenantId)); + + // Handle configuration key rename + if (tenant.containsKey("tenantConfiguration")) { + organizationDocument.put("organizationConfiguration", tenant.get("tenantConfiguration")); + organizationDocument.remove("tenantConfiguration"); + } + + Organization organization = mongoTemplate.getConverter().read(Organization.class, organizationDocument); + + Map existingPolicyMap = organization.getPolicyMap(); + if (existingPolicyMap == null || existingPolicyMap.isEmpty()) { + return; + } + + Map updatedPolicyMap = new HashMap<>(existingPolicyMap); // Copy existing policies + Set updatedPolicies = + new HashSet<>(organization.getPolicies()); // Copy existing deprecated policies + + // Process each policy + for (Map.Entry entry : existingPolicyMap.entrySet()) { + Policy existingPolicy = entry.getValue(); + String permission = existingPolicy.getPermission(); + + // Only process policies that contain 'tenant' + if (permission.toLowerCase().contains("tenant")) { + // Create new policy with 'organization' instead of 'tenant' + String newPermission = permission.replaceAll("(?i)tenant", "organization"); + + // Skip if the new permission already exists + if (!updatedPolicyMap.containsKey(newPermission)) { + // Create a new policy object with the same permissions but new name + Policy newPolicy = + new Policy(newPermission, new HashSet<>(existingPolicy.getPermissionGroups())); + + updatedPolicyMap.put(newPermission, newPolicy); + updatedPolicies.add(newPolicy); + } + } + } + + organization.setPolicyMap(updatedPolicyMap); + organization.setPolicies(updatedPolicies); + + // Insert into organization collection + try { + mongoTemplate.save(organization); + log.info("Successfully migrated tenant to organization with id: {}", tenantId); + } catch (DuplicateKeyException e) { + log.warn("Organization already exists for tenant: {}", tenantId); + } + + } catch (Exception e) { + log.error("Error migrating tenant: {}", tenant.get("_id"), e); + } + + } catch (Exception e) { + log.error("Error during tenant to organization migration", e); + } + } + + private void migrateMongoCollections() { + for (Class domainClass : DOMAIN_CLASSES) { + try { + migrateCollection(domainClass); + } catch (Exception e) { + log.error("Error while migrating collection for {}: ", domainClass.getSimpleName(), e); + } + } + } + + private void migrateCollection(Class domainClass) { + Query query = + new Query(where("tenantId").exists(true).and("organizationId").exists(false)); + + // Create an update pipeline that copies the value + List pipeline = Arrays.asList(new Document("$set", new Document("organizationId", "$tenantId"))); + + try { + long updatedCount = mongoTemplate + .getCollection(mongoTemplate.getCollectionName(domainClass)) + .updateMany(query.getQueryObject(), pipeline) + .getModifiedCount(); + + log.info( + "Successfully copied tenantId to organizationId for {} documents in collection: {}", + updatedCount, + domainClass.getSimpleName()); + } catch (Exception e) { + log.error( + "Error while copying tenantId to organizationId for collection {}: ", + domainClass.getSimpleName(), + e); + throw e; + } + } + + private void migrateRedisData() { + try { + // Get all session keys + List sessionKeys = reactiveRedisOperations + .keys("spring:session:sessions:*") + .collectList() + .block(); + + if (sessionKeys == null || sessionKeys.isEmpty()) { + log.info("No session keys found in Redis"); + return; + } + + int updatedCount = 0; + for (String sessionKey : sessionKeys) { + Map sessionData = reactiveRedisOperations + .opsForHash() + .entries(sessionKey) + .collectMap(entry -> entry.getKey(), entry -> entry.getValue()) + .block(); + + if (sessionData != null && sessionData.containsKey("sessionAttr:SPRING_SECURITY_CONTEXT")) { + try { + String sessionStr = sessionData + .get("sessionAttr:SPRING_SECURITY_CONTEXT") + .toString(); + // Extract the appsmith-session JSON string + if (sessionStr.contains("appsmith-session:")) { + String jsonStr = + sessionStr.substring(sessionStr.indexOf('{'), sessionStr.lastIndexOf('}') + 1); + JsonNode jsonNode = objectMapper.readTree(jsonStr); + ObjectNode objectNode = (ObjectNode) jsonNode; + + if (objectNode.has("tenantId") && !objectNode.has("organizationId")) { + // Copy tenantId value to organizationId + objectNode.put( + "organizationId", + objectNode.get("tenantId").asText()); + // Remove tenantId + objectNode.remove("tenantId"); + + // Reconstruct the session string with updated JSON + String updatedJson = objectMapper.writeValueAsString(objectNode); + String updatedSessionStr = "appsmith-session:" + updatedJson; + + // Convert to byte array if needed + reactiveRedisOperations + .opsForHash() + .put(sessionKey, "sessionAttr:SPRING_SECURITY_CONTEXT", updatedSessionStr) + .block(); + updatedCount++; + } + } + } catch (Exception e) { + log.error("Error processing Redis session key {}: ", sessionKey, e); + } + } + } + log.info("Successfully migrated {} Redis sessions", updatedCount); + } catch (Exception e) { + log.error("Error while migrating Redis session data: ", e); + } + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration10000_UpdateSuperUser.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration10000_UpdateSuperUser.java new file mode 100644 index 000000000000..03cd7e111787 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration10000_UpdateSuperUser.java @@ -0,0 +1,113 @@ +package com.appsmith.server.migrations.db.ce; + +import com.appsmith.server.acl.PolicyGenerator; +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Config; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.PermissionGroup; +import com.appsmith.server.domains.User; +import com.appsmith.server.helpers.TextUtils; +import com.appsmith.server.migrations.solutions.UpdateSuperUserMigrationHelper; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.solutions.PolicySolution; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; + +import java.util.Set; +import java.util.stream.Collectors; + +import static com.appsmith.server.constants.EnvVariables.APPSMITH_ADMIN_EMAILS; +import static com.appsmith.server.constants.ce.FieldNameCE.DEFAULT_PERMISSION_GROUP; +import static com.appsmith.server.helpers.CollectionUtils.findSymmetricDiff; +import static com.appsmith.server.migrations.MigrationHelperMethods.evictPermissionCacheForUsers; +import static org.springframework.data.mongodb.core.query.Criteria.where; + +/** + * The order of this migration is set to 10000 so that it always gets executed at the end. + * This ensures that any permission changes for super users happen once all other migrations are completed. + */ +@Slf4j +@ChangeUnit(order = "10000", id = "update-super-users", author = "", runAlways = true) +public class Migration10000_UpdateSuperUser { + + private final MongoTemplate mongoTemplate; + private final CacheableRepositoryHelper cacheableRepositoryHelper; + private final PolicySolution policySolution; + private final PolicyGenerator policyGenerator; + private final UpdateSuperUserMigrationHelper updateSuperUserMigrationHelper; + + public Migration10000_UpdateSuperUser( + MongoTemplate mongoTemplate, + CacheableRepositoryHelper cacheableRepositoryHelper, + PolicySolution policySolution, + PolicyGenerator policyGenerator) { + this.mongoTemplate = mongoTemplate; + this.cacheableRepositoryHelper = cacheableRepositoryHelper; + this.policySolution = policySolution; + this.policyGenerator = policyGenerator; + this.updateSuperUserMigrationHelper = new UpdateSuperUserMigrationHelper(); + } + + @RollbackExecution + public void rollbackExecution() {} + + @Execution + public void executeMigration() { + // Read the admin emails from the environment and update the super users accordingly + String adminEmailsStr = System.getenv(String.valueOf(APPSMITH_ADMIN_EMAILS)); + + Set adminEmails = TextUtils.csvToSet(adminEmailsStr); + + Query instanceConfigurationQuery = new Query(); + instanceConfigurationQuery.addCriteria(where(Config.Fields.name).is(FieldName.INSTANCE_CONFIG)); + Config instanceAdminConfiguration = mongoTemplate.findOne(instanceConfigurationQuery, Config.class); + + String instanceAdminPermissionGroupId = + (String) instanceAdminConfiguration.getConfig().get(DEFAULT_PERMISSION_GROUP); + + Query permissionGroupQuery = new Query(); + permissionGroupQuery + .addCriteria(where(PermissionGroup.Fields.id).is(instanceAdminPermissionGroupId)) + .fields() + .include(PermissionGroup.Fields.assignedToUserIds); + PermissionGroup instanceAdminPG = mongoTemplate.findOne(permissionGroupQuery, PermissionGroup.class); + + Query organizationQuery = new Query(); + organizationQuery.addCriteria(where(Organization.Fields.slug).is("default")); + Organization organization = mongoTemplate.findOne(organizationQuery, Organization.class); + + Set userIds = adminEmails.stream() + .map(email -> email.trim()) + .map(String::toLowerCase) + .map(email -> { + Query userQuery = new Query(); + userQuery.addCriteria(where(User.Fields.email).is(email)); + User user = mongoTemplate.findOne(userQuery, User.class); + + if (user == null) { + log.info("Creating super user with username {}", email); + user = updateSuperUserMigrationHelper.createNewUser( + email, organization, instanceAdminPG, mongoTemplate, policySolution, policyGenerator); + } + + return user.getId(); + }) + .collect(Collectors.toSet()); + + Set oldSuperUsers = instanceAdminPG.getAssignedToUserIds(); + Set updatedUserIds = findSymmetricDiff(oldSuperUsers, userIds); + evictPermissionCacheForUsers(updatedUserIds, mongoTemplate, cacheableRepositoryHelper); + + Update update = new Update().set(PermissionGroup.Fields.assignedToUserIds, userIds); + mongoTemplate.updateFirst(permissionGroupQuery, update, PermissionGroup.class); + + // Assign all super users to the default role + updateSuperUserMigrationHelper.assignAllSuperUsersToDefaultRole( + userIds, mongoTemplate, cacheableRepositoryHelper); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java index 0c9836a18c2e..8c45a7c4d0fc 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/solutions/ce/UpdateSuperUserMigrationHelperCE.java @@ -3,10 +3,11 @@ import com.appsmith.external.models.Policy; import com.appsmith.server.acl.PolicyGenerator; import com.appsmith.server.constants.FieldName; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.PermissionGroup; -import com.appsmith.server.domains.Tenant; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.Permission; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.solutions.PolicySolution; import org.jetbrains.annotations.NotNull; import org.springframework.data.mongodb.core.MongoTemplate; @@ -24,7 +25,7 @@ protected Set generateUserPolicy( User user, PermissionGroup userManagementRole, PermissionGroup instanceAdminRole, - Tenant tenant, + Organization organization, PolicySolution policySolution, PolicyGenerator policyGenerator) { Policy readUserPolicy = Policy.builder() @@ -45,7 +46,7 @@ protected Set generateUserPolicy( public User createNewUser( String email, - Tenant tenant, + Organization organization, PermissionGroup instanceAdminRole, MongoTemplate mongoTemplate, PolicySolution policySolution, @@ -53,14 +54,14 @@ public User createNewUser( User user = new User(); user.setEmail(email); user.setIsEnabled(false); - user.setTenantId(tenant.getId()); + user.setOrganizationId(organization.getId()); user.setCreatedAt(Instant.now()); user = mongoTemplate.save(user); PermissionGroup userManagementPermissionGroup = createUserManagementPermissionGroup(mongoTemplate, user); Set userPolicies = this.generateUserPolicy( - user, userManagementPermissionGroup, instanceAdminRole, tenant, policySolution, policyGenerator); + user, userManagementPermissionGroup, instanceAdminRole, organization, policySolution, policyGenerator); user.setPolicies(userPolicies); @@ -79,4 +80,9 @@ public User createNewUser( PermissionGroup savedPermissionGroup = mongoTemplate.save(userManagementPermissionGroup); return savedPermissionGroup; } + + public void assignAllSuperUsersToDefaultRole( + Set userIds, MongoTemplate mongoTemplate, CacheableRepositoryHelper cacheableRepositoryHelper) { + // Empty function in CE to override in EE + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java index a983e279d1eb..bfa29a1b8b75 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java @@ -10,7 +10,7 @@ import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; @@ -28,7 +28,7 @@ public class PluginTriggerSolutionCEImpl implements PluginTriggerSolutionCE { private final PluginExecutorHelper pluginExecutorHelper; private final PluginRepository pluginRepository; private final ConfigService configService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final FeatureFlagService featureFlagService; public PluginTriggerSolutionCEImpl( @@ -36,13 +36,13 @@ public PluginTriggerSolutionCEImpl( PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService, + OrganizationService organizationService, FeatureFlagService featureFlagService) { this.datasourceTriggerSolution = datasourceTriggerSolution; this.pluginExecutorHelper = pluginExecutorHelper; this.pluginRepository = pluginRepository; this.configService = configService; - this.tenantService = tenantService; + this.organizationService = organizationService; this.featureFlagService = featureFlagService; } @@ -81,7 +81,7 @@ public Mono trigger( // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag // Once thoroughly tested, this flag can be removed Map featureFlagMap = - featureFlagService.getCachedTenantFeatureFlags().getFeatures(); + featureFlagService.getCachedOrganizationFeatureFlags().getFeatures(); /* * Since there is no datasource provided, we are passing the Datasource Context connection and datasourceConfiguration as null. @@ -91,7 +91,7 @@ public Mono trigger( Plugin plugin = pair.getT1(); PluginExecutor pluginExecutor = pair.getT2(); setHeadersToTriggerRequest(plugin, httpHeaders, triggerRequestDTO); - return setTenantAndInstanceId(triggerRequestDTO) + return setOrganizationAndInstanceId(triggerRequestDTO) .flatMap(updatedTriggerRequestDTO -> ((PluginExecutor) pluginExecutor) .triggerWithFlags(null, null, updatedTriggerRequestDTO, featureFlagMap)); }); @@ -115,12 +115,12 @@ public Mono trigger( }); } - private Mono setTenantAndInstanceId(TriggerRequestDTO triggerRequestDTO) { - return tenantService - .getDefaultTenantId() + private Mono setOrganizationAndInstanceId(TriggerRequestDTO triggerRequestDTO) { + return organizationService + .getDefaultOrganizationId() .zipWith(configService.getInstanceId()) .map(tuple -> { - triggerRequestDTO.setTenantId(tuple.getT1()); + triggerRequestDTO.setOrganizationId(tuple.getT1()); triggerRequestDTO.setInstanceId(tuple.getT2()); return triggerRequestDTO; }); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java index 373235b5e09d..afc84986419b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java @@ -4,7 +4,7 @@ import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.springframework.stereotype.Component; @@ -15,14 +15,14 @@ public PluginTriggerSolutionImpl( PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService, + OrganizationService organizationService, FeatureFlagService featureFlagService) { super( datasourceTriggerSolution, pluginExecutorHelper, pluginRepository, configService, - tenantService, + organizationService, featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java new file mode 100644 index 000000000000..aac5045ce90e --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepository.java @@ -0,0 +1,5 @@ +package com.appsmith.server.repositories; + +import com.appsmith.server.repositories.ce.CustomOrganizationRepositoryCE; + +public interface CustomOrganizationRepository extends CustomOrganizationRepositoryCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java new file mode 100644 index 000000000000..0f1a49fe8319 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomOrganizationRepositoryImpl.java @@ -0,0 +1,6 @@ +package com.appsmith.server.repositories; + +import com.appsmith.server.repositories.ce.CustomOrganizationRepositoryCEImpl; + +public class CustomOrganizationRepositoryImpl extends CustomOrganizationRepositoryCEImpl + implements CustomOrganizationRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepository.java deleted file mode 100644 index 19002ae711a8..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepository.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.appsmith.server.repositories; - -import com.appsmith.server.repositories.ce.CustomTenantRepositoryCE; - -public interface CustomTenantRepository extends CustomTenantRepositoryCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepositoryImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepositoryImpl.java deleted file mode 100644 index b56a9559f6e4..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/CustomTenantRepositoryImpl.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.appsmith.server.repositories; - -import com.appsmith.server.repositories.ce.CustomTenantRepositoryCEImpl; - -public class CustomTenantRepositoryImpl extends CustomTenantRepositoryCEImpl implements CustomTenantRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/OrganizationRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/OrganizationRepository.java new file mode 100644 index 000000000000..4a9c8f4ecbab --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/OrganizationRepository.java @@ -0,0 +1,7 @@ +package com.appsmith.server.repositories; + +import com.appsmith.server.repositories.ce.OrganizationRepositoryCE; +import org.springframework.stereotype.Repository; + +@Repository +public interface OrganizationRepository extends OrganizationRepositoryCE, CustomOrganizationRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/TenantRepository.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/TenantRepository.java deleted file mode 100644 index 3c138f24e290..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/TenantRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.appsmith.server.repositories; - -import com.appsmith.server.repositories.ce.TenantRepositoryCE; -import org.springframework.stereotype.Repository; - -@Repository -public interface TenantRepository extends TenantRepositoryCE, CustomTenantRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java index 8a297df4bf0e..cb3179a2dcb8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/BaseAppsmithRepositoryCEImpl.java @@ -446,15 +446,15 @@ public Mono setUserPermissionsInObject(T obj, Set permissionGroups) { protected Mono> getAllPermissionGroupsForUser(User user) { Mono userMono = Mono.just(user); - if (user.getTenantId() == null) { - userMono = cacheableRepositoryHelper.getDefaultTenantId().map(tenantId -> { - user.setTenantId(tenantId); + if (user.getOrganizationId() == null) { + userMono = cacheableRepositoryHelper.getDefaultOrganizationId().map(organizationId -> { + user.setOrganizationId(organizationId); return user; }); } - return userMono.flatMap(userWithTenant -> Mono.zip( - cacheableRepositoryHelper.getPermissionGroupsOfUser(userWithTenant), + return userMono.flatMap(userWithOrganization -> Mono.zip( + cacheableRepositoryHelper.getPermissionGroupsOfUser(userWithOrganization), getAnonymousUserPermissionGroups())) .map(tuple -> { Set permissionGroups = new HashSet<>(tuple.getT1()); @@ -477,9 +477,9 @@ protected Mono> getAllPermissionGroupsForUser(User user) { protected Mono> getStrictPermissionGroupsForUser(User user) { Mono userMono = Mono.just(user); - if (user.getTenantId() == null) { - userMono = cacheableRepositoryHelper.getDefaultTenantId().map(tenantId -> { - user.setTenantId(tenantId); + if (user.getOrganizationId() == null) { + userMono = cacheableRepositoryHelper.getDefaultOrganizationId().map(organizationId -> { + user.setOrganizationId(organizationId); return user; }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java index fc66e5e2eeec..7c6e7e3e007f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCE.java @@ -1,6 +1,6 @@ package com.appsmith.server.repositories.ce; -import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.User; import reactor.core.publisher.Mono; @@ -15,15 +15,15 @@ public interface CacheableRepositoryHelperCE { Mono> getPermissionGroupsOfAnonymousUser(); - Mono evictPermissionGroupsUser(String email, String tenantId); + Mono evictPermissionGroupsUser(String email, String organizationId); - Mono getDefaultTenantId(); + Mono getDefaultOrganizationId(); Mono getInstanceAdminPermissionGroupId(); - Mono fetchDefaultTenant(String tenantId); + Mono fetchDefaultOrganization(String organizationId); - Mono evictCachedTenant(String tenantId); + Mono evictCachedOrganization(String organizationId); /** * Retrieves the base application ID from the cache based on the provided base page ID. diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java index 3cdcc4e8b087..d0d67118af77 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CacheableRepositoryHelperCEImpl.java @@ -4,9 +4,9 @@ import com.appsmith.caching.annotations.CacheEvict; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Config; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.PermissionGroup; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; import com.appsmith.server.exceptions.AppsmithError; @@ -29,7 +29,7 @@ import java.util.Set; import java.util.stream.Collectors; -import static com.appsmith.external.constants.spans.TenantSpan.FETCH_TENANT_FROM_DB_SPAN; +import static com.appsmith.external.constants.spans.OrganizationSpan.FETCH_ORGANIZATION_FROM_DB_SPAN; import static com.appsmith.server.constants.FieldName.PERMISSION_GROUP_ID; import static com.appsmith.server.constants.ce.FieldNameCE.ANONYMOUS_USER; import static com.appsmith.server.constants.ce.FieldNameCE.DEFAULT_PERMISSION_GROUP; @@ -45,7 +45,7 @@ public class CacheableRepositoryHelperCEImpl implements CacheableRepositoryHelpe private final ObservationRegistry observationRegistry; private static final String CACHE_DEFAULT_PAGE_ID_TO_DEFAULT_APPLICATION_ID = "pageIdToAppId"; - @Cache(cacheName = "permissionGroupsForUser", key = "{#user.email + #user.tenantId}") + @Cache(cacheName = "permissionGroupsForUser", key = "{#user.email + #user.organizationId}") @Override public Mono> getPermissionGroupsOfUser(User user) { @@ -127,27 +127,28 @@ public Mono> getPermissionGroupsOfAnonymousUser() { return Mono.error(new AppsmithException(AppsmithError.SERVER_NOT_READY)); } - @CacheEvict(cacheName = "permissionGroupsForUser", key = "{#email + #tenantId}") + @CacheEvict(cacheName = "permissionGroupsForUser", key = "{#email + #organizationId}") @Override - public Mono evictPermissionGroupsUser(String email, String tenantId) { + public Mono evictPermissionGroupsUser(String email, String organizationId) { return Mono.empty(); } @Override - public Mono getDefaultTenantId() { - String defaultTenantId = inMemoryCacheableRepositoryHelper.getDefaultTenantId(); - if (defaultTenantId != null && !defaultTenantId.isEmpty()) { - return Mono.just(defaultTenantId); + public Mono getDefaultOrganizationId() { + String defaultOrganizationId = inMemoryCacheableRepositoryHelper.getDefaultOrganizationId(); + if (defaultOrganizationId != null && !defaultOrganizationId.isEmpty()) { + return Mono.just(defaultOrganizationId); } - BridgeQuery defaultTenantCriteria = Bridge.equal(Tenant.Fields.slug, FieldName.DEFAULT); + BridgeQuery defaultOrganizationCriteria = + Bridge.equal(Organization.Fields.slug, FieldName.DEFAULT); Query query = new Query(); - query.addCriteria(defaultTenantCriteria); + query.addCriteria(defaultOrganizationCriteria); - return mongoOperations.findOne(query, Tenant.class).map(defaultTenant -> { - String newDefaultTenantId = defaultTenant.getId(); - inMemoryCacheableRepositoryHelper.setDefaultTenantId(newDefaultTenantId); - return newDefaultTenantId; + return mongoOperations.findOne(query, Organization.class).map(defaultOrganization -> { + String newDefaultOrganizationId = defaultOrganization.getId(); + inMemoryCacheableRepositoryHelper.setDefaultOrganizationId(newDefaultOrganizationId); + return newDefaultOrganizationId; }); } @@ -171,35 +172,36 @@ public Mono getInstanceAdminPermissionGroupId() { } /** - * Returns the default tenant from the cache if present. - * If not present in cache, then it fetches the default tenant from the database and adds to redis. - * @param tenantId + * Returns the default organization from the cache if present. + * If not present in cache, then it fetches the default organization from the database and adds to redis. + * @param organizationId * @return */ - @Cache(cacheName = "tenant", key = "{#tenantId}") + @Cache(cacheName = "organization", key = "{#organizationId}") @Override - public Mono fetchDefaultTenant(String tenantId) { - BridgeQuery defaultTenantCriteria = Bridge.equal(Tenant.Fields.slug, FieldName.DEFAULT); - BridgeQuery notDeletedCriteria = notDeleted(); - BridgeQuery andCriteria = Bridge.and(defaultTenantCriteria, notDeletedCriteria); + public Mono fetchDefaultOrganization(String organizationId) { + BridgeQuery defaultOrganizationCriteria = + Bridge.equal(Organization.Fields.slug, FieldName.DEFAULT); + BridgeQuery notDeletedCriteria = notDeleted(); + BridgeQuery andCriteria = Bridge.and(defaultOrganizationCriteria, notDeletedCriteria); Query query = new Query(); query.addCriteria(andCriteria); - log.info("Fetching tenant from database as it couldn't be found in the cache!"); + log.info("Fetching organization from database as it couldn't be found in the cache!"); return mongoOperations - .findOne(query, Tenant.class) - .map(tenant -> { - if (tenant.getTenantConfiguration() == null) { - tenant.setTenantConfiguration(new TenantConfiguration()); + .findOne(query, Organization.class) + .map(organization -> { + if (organization.getOrganizationConfiguration() == null) { + organization.setOrganizationConfiguration(new OrganizationConfiguration()); } - return tenant; + return organization; }) - .name(FETCH_TENANT_FROM_DB_SPAN) + .name(FETCH_ORGANIZATION_FROM_DB_SPAN) .tap(Micrometer.observation(observationRegistry)); } - @CacheEvict(cacheName = "tenant", key = "{#tenantId}") + @CacheEvict(cacheName = "organization", key = "{#organizationId}") @Override - public Mono evictCachedTenant(String tenantId) { + public Mono evictCachedOrganization(String organizationId) { return Mono.empty().then(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCE.java new file mode 100644 index 000000000000..1f3b9139fb47 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCE.java @@ -0,0 +1,6 @@ +package com.appsmith.server.repositories.ce; + +import com.appsmith.server.domains.Organization; +import com.appsmith.server.repositories.AppsmithRepository; + +public interface CustomOrganizationRepositoryCE extends AppsmithRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCEImpl.java new file mode 100644 index 000000000000..7b21660b8509 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomOrganizationRepositoryCEImpl.java @@ -0,0 +1,9 @@ +package com.appsmith.server.repositories.ce; + +import com.appsmith.server.domains.Organization; +import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CustomOrganizationRepositoryCEImpl extends BaseAppsmithRepositoryImpl + implements CustomOrganizationRepositoryCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCE.java index 0dc34109dd43..250c6110ed26 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCE.java @@ -23,9 +23,9 @@ Flux findAllByAssignedToUserIdAndDefaultWorkspaceId( Flux findByDefaultWorkspaceIds(Set workspaceIds, AclPermission permission); - Mono evictPermissionGroupsUser(String email, String tenantId); + Mono evictPermissionGroupsUser(String email, String organizationId); - Mono evictAllPermissionGroupCachesForUser(String email, String tenantId); + Mono evictAllPermissionGroupCachesForUser(String email, String organizationId); Flux findAllByAssignedToUserIn( Set userIds, Optional> includeFields, Optional permission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCEImpl.java index 19d41817d5fb..95c95c7f92cb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomPermissionGroupRepositoryCEImpl.java @@ -62,13 +62,13 @@ public Flux findByDefaultWorkspaceIds(Set workspaceIds, } @Override - public Mono evictPermissionGroupsUser(String email, String tenantId) { - return cacheableRepositoryHelper.evictPermissionGroupsUser(email, tenantId); + public Mono evictPermissionGroupsUser(String email, String organizationId) { + return cacheableRepositoryHelper.evictPermissionGroupsUser(email, organizationId); } @Override - public Mono evictAllPermissionGroupCachesForUser(String email, String tenantId) { - return this.evictPermissionGroupsUser(email, tenantId); + public Mono evictAllPermissionGroupCachesForUser(String email, String organizationId) { + return this.evictPermissionGroupsUser(email, organizationId); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCE.java deleted file mode 100644 index e9cc3b92c097..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCE.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.appsmith.server.repositories.ce; - -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.repositories.AppsmithRepository; - -public interface CustomTenantRepositoryCE extends AppsmithRepository {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCEImpl.java deleted file mode 100644 index 2b56879bdef8..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomTenantRepositoryCEImpl.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.appsmith.server.repositories.ce; - -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class CustomTenantRepositoryCEImpl extends BaseAppsmithRepositoryImpl - implements CustomTenantRepositoryCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java index 10c66781ecf4..856f1c54e152 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java @@ -12,7 +12,7 @@ public interface CustomUserRepositoryCE extends AppsmithRepository { Mono findByEmail(String email, AclPermission aclPermission); - Mono findByEmailAndTenantId(String email, String tenantId); + Mono findByEmailAndOrganizationId(String email, String organizationId); Mono isUsersEmpty(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java index 17db68683223..96e6650ee5b2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java @@ -26,9 +26,9 @@ public Mono findByEmail(String email, AclPermission aclPermission) { } @Override - public Mono findByEmailAndTenantId(String email, String tenantId) { + public Mono findByEmailAndOrganizationId(String email, String organizationId) { return queryBuilder() - .criteria(Bridge.equal(User.Fields.email, email).equal(User.Fields.tenantId, tenantId)) + .criteria(Bridge.equal(User.Fields.email, email).equal(User.Fields.organizationId, organizationId)) .one(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCE.java index facee3f521de..7216b7443a50 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCE.java @@ -13,7 +13,8 @@ public interface CustomWorkspaceRepositoryCE extends AppsmithRepository findByName(String name, AclPermission aclPermission); - Flux findByIdsIn(Set workspaceIds, String tenantId, AclPermission aclPermission, Sort sort); + Flux findByIdsIn( + Set workspaceIds, String organizationId, AclPermission aclPermission, Sort sort); Flux findAll(AclPermission permission); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCEImpl.java index df76a0a10742..4aa572372e29 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomWorkspaceRepositoryCEImpl.java @@ -30,10 +30,10 @@ public Mono findByName(String name, AclPermission aclPermission) { @Override public Flux findByIdsIn( - Set workspaceIds, String tenantId, AclPermission aclPermission, Sort sort) { + Set workspaceIds, String organizationId, AclPermission aclPermission, Sort sort) { return queryBuilder() .criteria(Bridge.in(Workspace.Fields.id, workspaceIds) - .equal(Workspace.Fields.tenantId, tenantId)) + .equal(Workspace.Fields.organizationId, organizationId)) .permission(aclPermission) .sort(sort) .all(); @@ -42,7 +42,7 @@ public Flux findByIdsIn( @Override public Flux findAll(AclPermission permission) { return sessionUserService.getCurrentUser().flatMapMany(user -> queryBuilder() - .criteria(Bridge.equal(Workspace.Fields.tenantId, user.getTenantId())) + .criteria(Bridge.equal(Workspace.Fields.organizationId, user.getOrganizationId())) .permission(permission) .all()); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/OrganizationRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/OrganizationRepositoryCE.java new file mode 100644 index 000000000000..de74acb700ff --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/OrganizationRepositoryCE.java @@ -0,0 +1,11 @@ +package com.appsmith.server.repositories.ce; + +import com.appsmith.server.domains.Organization; +import com.appsmith.server.repositories.BaseRepository; +import reactor.core.publisher.Mono; + +public interface OrganizationRepositoryCE extends BaseRepository, CustomOrganizationRepositoryCE { + // Use organizationService.getDefaultOrganization() instead of this method as it is cached to redis. + @Deprecated(forRemoval = true) + Mono findBySlug(String slug); +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/TenantRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/TenantRepositoryCE.java deleted file mode 100644 index 7cad8f0f12a4..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/TenantRepositoryCE.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.appsmith.server.repositories.ce; - -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.repositories.BaseRepository; -import reactor.core.publisher.Mono; - -public interface TenantRepositoryCE extends BaseRepository, CustomTenantRepositoryCE { - // Use tenantService.getDefaultTenant() instead of this method as it is cached to redis. - @Deprecated(forRemoval = true) - Mono findBySlug(String slug); -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java index ac0b365f3210..17895ce93f08 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/UserRepositoryCE.java @@ -29,5 +29,5 @@ public interface UserRepositoryCE extends BaseRepository, CustomUs Mono countByDeletedAtIsNullAndLastActiveAtGreaterThanAndIsSystemGeneratedIsNot( Instant lastActiveAt, Boolean excludeSystemGenerated); - Mono findByEmailAndTenantId(String email, String tenantId); + Mono findByEmailAndOrganizationId(String email, String organizationId); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java index abd2394cdf69..54b06ec8c2b8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/CacheableFeatureFlagHelperImpl.java @@ -2,7 +2,7 @@ import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.configurations.CommonConfig; -import com.appsmith.server.repositories.TenantRepository; +import com.appsmith.server.repositories.OrganizationRepository; import com.appsmith.server.services.ce.CacheableFeatureFlagHelperCEImpl; import com.appsmith.server.solutions.ReleaseNotesService; import lombok.extern.slf4j.Slf4j; @@ -13,14 +13,14 @@ public class CacheableFeatureFlagHelperImpl extends CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHelper { public CacheableFeatureFlagHelperImpl( - TenantRepository tenantRepository, + OrganizationRepository organizationRepository, ConfigService configService, CloudServicesConfig cloudServicesConfig, CommonConfig commonConfig, UserIdentifierService userIdentifierService, ReleaseNotesService releaseNotesService) { super( - tenantRepository, + organizationRepository, configService, cloudServicesConfig, commonConfig, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java index 649619990d7e..cbf20d6813c2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ConsolidatedAPIServiceImpl.java @@ -23,7 +23,7 @@ public ConsolidatedAPIServiceImpl( SessionUserService sessionUserService, UserService userService, UserDataService userDataService, - TenantService tenantService, + OrganizationService organizationService, ProductAlertService productAlertService, NewPageService newPageService, NewActionService newActionService, @@ -42,7 +42,7 @@ public ConsolidatedAPIServiceImpl( sessionUserService, userService, userDataService, - tenantService, + organizationService, productAlertService, newPageService, newActionService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/FeatureFlagServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/FeatureFlagServiceImpl.java index 103a3fd5df97..9423abc9f671 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/FeatureFlagServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/FeatureFlagServiceImpl.java @@ -8,13 +8,13 @@ public class FeatureFlagServiceImpl extends FeatureFlagServiceCEImpl implements FeatureFlagService { public FeatureFlagServiceImpl( SessionUserService sessionUserService, - TenantService tenantService, + OrganizationService organizationService, UserIdentifierService userIdentifierService, CacheableFeatureFlagHelper cacheableFeatureFlagHelper, FeatureFlagMigrationHelper featureFlagMigrationHelper) { super( sessionUserService, - tenantService, + organizationService, userIdentifierService, cacheableFeatureFlagHelper, featureFlagMigrationHelper); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java new file mode 100644 index 000000000000..2e5f7af07a85 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationService.java @@ -0,0 +1,5 @@ +package com.appsmith.server.services; + +import com.appsmith.server.services.ce.OrganizationServiceCE; + +public interface OrganizationService extends OrganizationServiceCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java similarity index 78% rename from app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantServiceImpl.java rename to app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java index 53fdf6b1be7f..f8c1b46cf21c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/OrganizationServiceImpl.java @@ -3,8 +3,8 @@ import com.appsmith.server.configurations.CommonConfig; import com.appsmith.server.helpers.FeatureFlagMigrationHelper; import com.appsmith.server.repositories.CacheableRepositoryHelper; -import com.appsmith.server.repositories.TenantRepository; -import com.appsmith.server.services.ce.TenantServiceCEImpl; +import com.appsmith.server.repositories.OrganizationRepository; +import com.appsmith.server.services.ce.OrganizationServiceCEImpl; import com.appsmith.server.solutions.EnvManager; import io.micrometer.observation.ObservationRegistry; import jakarta.validation.Validator; @@ -12,11 +12,11 @@ import org.springframework.stereotype.Service; @Service -public class TenantServiceImpl extends TenantServiceCEImpl implements TenantService { +public class OrganizationServiceImpl extends OrganizationServiceCEImpl implements OrganizationService { - public TenantServiceImpl( + public OrganizationServiceImpl( Validator validator, - TenantRepository repository, + OrganizationRepository repository, AnalyticsService analyticsService, ConfigService configService, @Lazy EnvManager envManager, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PermissionGroupServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PermissionGroupServiceImpl.java index 56d0694f5a9f..0df6d95080a4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PermissionGroupServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PermissionGroupServiceImpl.java @@ -18,7 +18,7 @@ public PermissionGroupServiceImpl( PermissionGroupRepository repository, AnalyticsService analyticsService, SessionUserService sessionUserService, - TenantService tenantService, + OrganizationService organizationService, UserRepository userRepository, PolicySolution policySolution, ConfigRepository configRepository, @@ -29,7 +29,7 @@ public PermissionGroupServiceImpl( repository, analyticsService, sessionUserService, - tenantService, + organizationService, userRepository, policySolution, configRepository, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantService.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantService.java deleted file mode 100644 index 30b371afa49e..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/TenantService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.appsmith.server.services; - -import com.appsmith.server.services.ce.TenantServiceCE; - -public interface TenantService extends TenantServiceCE {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UsagePulseServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UsagePulseServiceImpl.java index f20294f9a1ba..3ac0ad266642 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UsagePulseServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UsagePulseServiceImpl.java @@ -12,9 +12,9 @@ public UsagePulseServiceImpl( UsagePulseRepository repository, SessionUserService sessionUserService, UserService userService, - TenantService tenantService, + OrganizationService organizationService, ConfigService configService, CommonConfig commonConfig) { - super(repository, sessionUserService, userService, tenantService, configService, commonConfig); + super(repository, sessionUserService, userService, organizationService, configService, commonConfig); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserDataServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserDataServiceImpl.java index 1b1d5fb61967..030c6cc69f29 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserDataServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserDataServiceImpl.java @@ -21,7 +21,7 @@ public UserDataServiceImpl( ReleaseNotesService releaseNotesService, FeatureFlagService featureFlagService, ApplicationRepository applicationRepository, - TenantService tenantService) { + OrganizationService organizationService) { super( validator, @@ -33,6 +33,6 @@ public UserDataServiceImpl( releaseNotesService, featureFlagService, applicationRepository, - tenantService); + organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java index bed86dbc475f..0f0b98bde6c2 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserServiceImpl.java @@ -35,7 +35,7 @@ public UserServiceImpl( CommonConfig commonConfig, EmailConfig emailConfig, UserDataService userDataService, - TenantService tenantService, + OrganizationService organizationService, PermissionGroupService permissionGroupService, UserUtils userUtils, EmailVerificationTokenRepository emailVerificationTokenRepository, @@ -53,7 +53,7 @@ public UserServiceImpl( passwordEncoder, commonConfig, userDataService, - tenantService, + organizationService, userUtils, emailVerificationTokenRepository, emailService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserWorkspaceServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserWorkspaceServiceImpl.java index 487a58508e67..f3ed33931c6f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserWorkspaceServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/UserWorkspaceServiceImpl.java @@ -17,7 +17,7 @@ public UserWorkspaceServiceImpl( UserRepository userRepository, UserDataService userDataService, PermissionGroupService permissionGroupService, - TenantService tenantService, + OrganizationService organizationService, WorkspacePermission workspacePermission, PermissionGroupPermission permissionGroupPermission) { @@ -27,7 +27,7 @@ public UserWorkspaceServiceImpl( userRepository, userDataService, permissionGroupService, - tenantService, + organizationService, workspacePermission, permissionGroupPermission); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java index ab1f5c756ac7..e6c1c04c33b1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCE.java @@ -16,25 +16,25 @@ public interface CacheableFeatureFlagHelperCE { Mono evictUserCachedFlags(String userIdentifier); /** - * To fetch the tenant new features via cache - * @param tenantId Id of the tenant + * To fetch the org new features via cache + * @param organizationId Id of the organization * @return Mono of CachedFeatures */ - Mono fetchCachedTenantFeatures(String tenantId); + Mono fetchCachedOrganizationFeatures(String organizationId); - Mono updateCachedTenantFeatures(String tenantId, CachedFeatures cachedFeatures); + Mono updateCachedOrganizationFeatures(String organizationId, CachedFeatures cachedFeatures); /** - * To evict the tenant new features cache - * @param tenantId Id of the tenant + * To evict the org new features cache + * @param organizationId Id of the organization * @return Mono of Void */ - Mono evictCachedTenantFeatures(String tenantId); + Mono evictCachedOrganizationFeatures(String organizationId); /** - * To get all tenant features from Cloud Services + * To get all organization features from Cloud Services * @param featuresRequestDTO FeaturesRequestDTO * @return Mono of Map */ - Mono getRemoteFeaturesForTenant(FeaturesRequestDTO featuresRequestDTO); + Mono getRemoteFeaturesForOrganization(FeaturesRequestDTO featuresRequestDTO); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java index 12cc4cafcc0e..07088910c5b3 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/CacheableFeatureFlagHelperCEImpl.java @@ -4,7 +4,7 @@ import com.appsmith.caching.annotations.CacheEvict; import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.configurations.CommonConfig; -import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.FeaturesRequestDTO; import com.appsmith.server.dtos.FeaturesResponseDTO; @@ -16,7 +16,7 @@ import com.appsmith.server.featureflags.FeatureFlagIdentityTraits; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.helpers.SignatureVerifier; -import com.appsmith.server.repositories.TenantRepository; +import com.appsmith.server.repositories.OrganizationRepository; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.UserIdentifierService; import com.appsmith.server.solutions.ReleaseNotesService; @@ -44,7 +44,7 @@ @Slf4j @RequiredArgsConstructor public class CacheableFeatureFlagHelperCEImpl implements CacheableFeatureFlagHelperCE { - private final TenantRepository tenantRepository; + private final OrganizationRepository organizationRepository; private final ConfigService configService; private final CloudServicesConfig cloudServicesConfig; private final CommonConfig commonConfig; @@ -88,7 +88,7 @@ private Mono> getUserDefaultTraits(User user) { } userTraits.put("email", emailTrait); userTraits.put("instanceId", instanceId); - userTraits.put("tenantId", user.getTenantId()); + userTraits.put("organizationId", user.getOrganizationId()); userTraits.put("emailDomain", emailDomain); userTraits.put("isTelemetryOn", !commonConfig.isTelemetryDisabled()); // for anonymous user, user.getCreatedAt() is null @@ -109,14 +109,14 @@ public Mono evictUserCachedFlags(String userIdentifier) { private Mono> forceAllRemoteFeatureFlagsForUser(String userIdentifier, User user) { Mono instanceIdMono = configService.getInstanceId(); - // TODO: Convert to current tenant when the feature is enabled - Mono defaultTenantMono = tenantRepository.findBySlug(DEFAULT); - return Mono.zip(instanceIdMono, defaultTenantMono, getUserDefaultTraits(user)) + // TODO: Convert to current organization when the feature is enabled + Mono organizationMono = organizationRepository.findBySlug(DEFAULT); + return Mono.zip(instanceIdMono, organizationMono, getUserDefaultTraits(user)) .flatMap(objects -> { - String tenantId = objects.getT2().getId(); + String organizationId = objects.getT2().getId(); String appsmithVersion = releaseNotesService.getRunningVersion(); FeatureFlagIdentityTraits featureFlagIdentityTraits = new FeatureFlagIdentityTraits( - objects.getT1(), tenantId, Set.of(userIdentifier), objects.getT3(), appsmithVersion); + objects.getT1(), organizationId, Set.of(userIdentifier), objects.getT3(), appsmithVersion); return this.getRemoteFeatureFlagsByIdentity(featureFlagIdentityTraits); }) .map(newValue -> ObjectUtils.defaultIfNull(newValue.get(userIdentifier), Map.of())); @@ -162,14 +162,14 @@ private Mono>> getRemoteFeatureFlagsByIdentity( } /** - * To fetch the tenant new features via cache - * @param tenantId Id of the tenant + * To fetch the organization new features via cache + * @param organizationId Id of the organization * @return Mono of CachedFeatures */ - @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @Cache(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono fetchCachedTenantFeatures(String tenantId) { - return this.forceAllRemoteFeaturesForTenant(tenantId).flatMap(flags -> { + public Mono fetchCachedOrganizationFeatures(String organizationId) { + return this.forceAllRemoteFeaturesForOrganization(organizationId).flatMap(flags -> { CachedFeatures cachedFeatures = new CachedFeatures(); cachedFeatures.setFeatures(flags); // If CS is down we expect the empty flags, from upstream method. Hence, setting the refreshed at to past @@ -183,54 +183,54 @@ public Mono fetchCachedTenantFeatures(String tenantId) { }); } - @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @Cache(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono updateCachedTenantFeatures(String tenantId, CachedFeatures cachedFeatures) { - log.debug("Updating cached tenant features for tenant: {}", tenantId); + public Mono updateCachedOrganizationFeatures(String organizationId, CachedFeatures cachedFeatures) { + log.debug("Updating cached organization features for organization: {}", organizationId); return Mono.just(cachedFeatures); } /** - * To evict the tenant new features cache - * @param tenantId Id of the tenant + * To evict the organization new features cache + * @param organizationId Id of the organization * @return Mono of Void */ - @CacheEvict(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @CacheEvict(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono evictCachedTenantFeatures(String tenantId) { + public Mono evictCachedOrganizationFeatures(String organizationId) { return Mono.empty(); } /** - * To force fetch all tenant features from Cloud Services - * @param tenantId Id of the tenant + * To force fetch all organization features from Cloud Services + * @param organizationId Id of the organization * @return Mono of Map */ - private Mono> forceAllRemoteFeaturesForTenant(String tenantId) { + private Mono> forceAllRemoteFeaturesForOrganization(String organizationId) { Mono instanceIdMono = configService.getInstanceId(); String appsmithVersion = releaseNotesService.getRunningVersion(); return instanceIdMono .map(instanceId -> { FeaturesRequestDTO featuresRequestDTO = new FeaturesRequestDTO(); - featuresRequestDTO.setTenantId(tenantId); + featuresRequestDTO.setOrganizationId(organizationId); featuresRequestDTO.setInstanceId(instanceId); featuresRequestDTO.setAppsmithVersion(appsmithVersion); featuresRequestDTO.setIsCloudHosting(commonConfig.isCloudHosting()); return featuresRequestDTO; }) - .flatMap(this::getRemoteFeaturesForTenant) + .flatMap(this::getRemoteFeaturesForOrganization) .map(responseDTO -> CollectionUtils.isNullOrEmpty(responseDTO.getFeatures()) ? new HashMap<>() : responseDTO.getFeatures()); } /** - * To get all tenant features from Cloud Services. + * To get all organization features from Cloud Services. * @param featuresRequestDTO FeaturesRequestDTO * @return Mono of Map */ @Override - public Mono getRemoteFeaturesForTenant(FeaturesRequestDTO featuresRequestDTO) { + public Mono getRemoteFeaturesForOrganization(FeaturesRequestDTO featuresRequestDTO) { Mono>> responseEntityMono = WebClientUtils.create( cloudServicesConfig.getBaseUrlWithSignatureVerification()) .post() diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java index 97588fb631cb..a4702cfef355 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceCEImpl.java @@ -27,9 +27,9 @@ import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.MockDataService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.ProductAlertService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.themes.base.ThemeService; @@ -79,11 +79,11 @@ import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.FEATURE_FLAG_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.FORM_CONFIG_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.MOCK_DATASOURCES_SPAN; +import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.ORGANIZATION_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.PAGES_DSL_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.PAGES_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.PLUGINS_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.PRODUCT_ALERT_SPAN; -import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.TENANT_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.THEMES_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.USER_PROFILE_SPAN; import static com.appsmith.external.constants.spans.ConsolidatedApiSpanNames.WORKSPACE_SPAN; @@ -104,7 +104,7 @@ public class ConsolidatedAPIServiceCEImpl implements ConsolidatedAPIServiceCE { private final SessionUserService sessionUserService; private final UserService userService; private final UserDataService userDataService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final ProductAlertService productAlertService; private final NewPageService newPageService; private final NewActionService newActionService; @@ -198,13 +198,13 @@ protected List> getAllFetchableMonos( .cache(); fetches.add(featureFlagsForCurrentUserResponseDTOMonoCache); - /* Get tenant config data */ - fetches.add(tenantService - .getTenantConfiguration() + /* Get organization config data */ + fetches.add(organizationService + .getOrganizationConfiguration() .as(this::toResponseDTO) - .doOnError(e -> log.error("Error fetching tenant config", e)) - .doOnSuccess(consolidatedAPIResponseDTO::setTenantConfig) - .name(getQualifiedSpanName(TENANT_SPAN, mode)) + .doOnError(e -> log.error("Error fetching organization config", e)) + .doOnSuccess(consolidatedAPIResponseDTO::setOrganizationConfig) + .name(getQualifiedSpanName(ORGANIZATION_SPAN, mode)) .tap(Micrometer.observation(observationRegistry))); /* Get any product alert info */ @@ -687,7 +687,7 @@ private boolean isPossibleToCreateQueryWithoutDatasource(Plugin plugin) { Map consolidateAPISignature = Map.of( "userProfile", consolidatedAPIResponseDTO.getUserProfile(), "featureFlags", consolidatedAPIResponseDTO.getFeatureFlags(), - "tenantConfig", consolidatedAPIResponseDTO.getTenantConfig(), + "organizationConfig", consolidatedAPIResponseDTO.getOrganizationConfig(), "productAlert", consolidatedAPIResponseDTO.getProductAlert(), "currentTheme", currentTheme, "themes", themes, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java index c10ba8c38352..3613e452b664 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCE.java @@ -1,7 +1,7 @@ package com.appsmith.server.services.ce; import com.appsmith.external.enums.FeatureFlagEnum; -import com.appsmith.server.domains.Tenant; +import com.appsmith.server.domains.Organization; import com.appsmith.server.featureflags.CachedFeatures; import reactor.core.publisher.Mono; @@ -26,18 +26,18 @@ public interface FeatureFlagServiceCE { Mono> getAllFeatureFlagsForUser(); /** - * To get all features of the tenant from Cloud Services and store them locally + * To get all features of the organization from Cloud Services and store them locally * @return Mono of Void */ - Mono getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations(); + Mono getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations(); /** - * To get all features of the current tenant. + * To get all features of the current organization. * @return Mono of Map */ - Mono> getTenantFeatures(); + Mono> getOrganizationFeatures(); - Mono checkAndExecuteMigrationsForTenantFeatureFlags(Tenant tenant); + Mono checkAndExecuteMigrationsForOrganizationFeatureFlags(Organization organization); - CachedFeatures getCachedTenantFeatureFlags(); + CachedFeatures getCachedOrganizationFeatureFlags(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java index fda8d2da3764..7f3a8f4a52d0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/FeatureFlagServiceCEImpl.java @@ -2,16 +2,16 @@ import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.server.constants.MigrationStatus; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.featureflags.CachedFlags; import com.appsmith.server.helpers.CollectionUtils; import com.appsmith.server.helpers.FeatureFlagMigrationHelper; import com.appsmith.server.services.CacheableFeatureFlagHelper; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserIdentifierService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -29,7 +29,7 @@ public class FeatureFlagServiceCEImpl implements FeatureFlagServiceCE { private final SessionUserService sessionUserService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final UserIdentifierService userIdentifierService; @@ -38,11 +38,11 @@ public class FeatureFlagServiceCEImpl implements FeatureFlagServiceCE { private final FeatureFlagMigrationHelper featureFlagMigrationHelper; private static final long FEATURE_FLAG_CACHE_TIME_MIN = 120; - private CachedFeatures cachedTenantFeatureFlags; + private CachedFeatures cachedOrganizationFeatureFlags; /** * This function checks if the feature is enabled for the current user. In case the user object is not present, - * i.e. when the method is getting called internally via cron or other mechanism check for tenant level flag and + * i.e. when the method is getting called internally via cron or other mechanism check for organization level flag and * provide a fallback as falsy value i.e. not supported * * @param featureEnum feature flag to be checked @@ -59,20 +59,20 @@ public Mono check(FeatureFlagEnum featureEnum) { /** * Retrieves a map of feature flags along with their corresponding boolean values for the current user. - * This takes into account for both user-level and tenant-level feature flags + * This takes into account for both user-level and organization-level feature flags * * @return A Mono emitting a Map where keys are feature names and values are corresponding boolean flags. */ @Override public Mono> getAllFeatureFlagsForUser() { - // Combine local flags, remote flags, and tenant features, and merge them into a single map - return Mono.zip(this.getAllRemoteFeatureFlagsForUser(), this.getTenantFeatures()) - .map(remoteAndTenantFlags -> { + // Combine local flags, remote flags, and organization features, and merge them into a single map + return Mono.zip(this.getAllRemoteFeatureFlagsForUser(), this.getOrganizationFeatures()) + .map(remoteAndOrganizationFlags -> { Map combinedFlags = new HashMap<>(); - combinedFlags.putAll(remoteAndTenantFlags.getT1()); - // Always add the tenant level flags after the user flags to make sure tenant flags gets the - // precedence - combinedFlags.putAll(remoteAndTenantFlags.getT2()); + combinedFlags.putAll(remoteAndOrganizationFlags.getT1()); + // Always add the organization level flags after the user flags to make sure organization flags gets + // the precedence + combinedFlags.putAll(remoteAndOrganizationFlags.getT2()); return combinedFlags; }); } @@ -115,52 +115,55 @@ private Mono> getAllRemoteFeatureFlagsForUser() { } /** - * To get all features of the tenant from Cloud Services and store them locally + * To get all features of the organization from Cloud Services and store them locally * @return Mono of Void */ - public Mono getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations() { - return tenantService - .getDefaultTenant() - .flatMap(defaultTenant -> + public Mono getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations() { + return organizationService + .getDefaultOrganization() + .flatMap(defaultOrganization -> // 1. Fetch current/saved feature flags from cache - // 2. Force update the tenant flags keeping existing flags as fallback in case the API + // 2. Force update the org flags keeping existing flags as fallback in case the API // call to fetch the flags fails for some reason // 3. Get the diff and update the flags with pending migrations to be used to run // migrations selectively featureFlagMigrationHelper - .getUpdatedFlagsWithPendingMigration(defaultTenant) + .getUpdatedFlagsWithPendingMigration(defaultOrganization) .flatMap(featureFlagWithPendingMigrations -> { - TenantConfiguration tenantConfig = defaultTenant.getTenantConfiguration() == null - ? new TenantConfiguration() - : defaultTenant.getTenantConfiguration(); + OrganizationConfiguration organizationConfiguration = + defaultOrganization.getOrganizationConfiguration() == null + ? new OrganizationConfiguration() + : defaultOrganization.getOrganizationConfiguration(); // We expect the featureFlagWithPendingMigrations to be empty hence // verifying only for null if (featureFlagWithPendingMigrations != null && !featureFlagWithPendingMigrations.equals( - tenantConfig.getFeaturesWithPendingMigration())) { - tenantConfig.setFeaturesWithPendingMigration(featureFlagWithPendingMigrations); + organizationConfiguration.getFeaturesWithPendingMigration())) { + organizationConfiguration.setFeaturesWithPendingMigration( + featureFlagWithPendingMigrations); if (!featureFlagWithPendingMigrations.isEmpty()) { - tenantConfig.setMigrationStatus(MigrationStatus.PENDING); + organizationConfiguration.setMigrationStatus(MigrationStatus.PENDING); } else { - tenantConfig.setMigrationStatus(MigrationStatus.COMPLETED); + organizationConfiguration.setMigrationStatus(MigrationStatus.COMPLETED); } - return tenantService.update(defaultTenant.getId(), defaultTenant); + return organizationService.update( + defaultOrganization.getId(), defaultOrganization); } - return Mono.just(defaultTenant); + return Mono.just(defaultOrganization); })) .then(); } /** - * To get all features of the current tenant. + * To get all features of the current organization. * @return Mono of Map */ - public Mono> getTenantFeatures() { - return tenantService - .getDefaultTenantId() - .flatMap(cacheableFeatureFlagHelper::fetchCachedTenantFeatures) + public Mono> getOrganizationFeatures() { + return organizationService + .getDefaultOrganizationId() + .flatMap(cacheableFeatureFlagHelper::fetchCachedOrganizationFeatures) .map(cachedFeatures -> { - cachedTenantFeatureFlags = cachedFeatures; + cachedOrganizationFeatureFlags = cachedFeatures; return cachedFeatures.getFeatures(); }) .switchIfEmpty(Mono.just(new HashMap<>())); @@ -168,16 +171,15 @@ public Mono> getTenantFeatures() { /** * This function checks if there are any pending migrations for a feature flag and executes them. - * @param tenant tenant for which the migrations need to be executed - * @return tenant with migrations executed + * @param organization organization for which the migrations need to be executed + * @return organization with migrations executed */ @Override - public Mono checkAndExecuteMigrationsForTenantFeatureFlags(Tenant tenant) { - return tenantService.checkAndExecuteMigrationsForTenantFeatureFlags(tenant); + public Mono checkAndExecuteMigrationsForOrganizationFeatureFlags(Organization organization) { + return organizationService.checkAndExecuteMigrationsForOrganizationFeatureFlags(organization); } - @Override - public CachedFeatures getCachedTenantFeatureFlags() { - return this.cachedTenantFeatureFlags; + public CachedFeatures getCachedOrganizationFeatureFlags() { + return this.cachedOrganizationFeatureFlags; } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCE.java new file mode 100644 index 000000000000..d2ecea72254a --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCE.java @@ -0,0 +1,33 @@ +package com.appsmith.server.services.ce; + +import com.appsmith.server.acl.AclPermission; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; +import com.appsmith.server.services.CrudService; +import reactor.core.publisher.Mono; + +public interface OrganizationServiceCE extends CrudService { + + Mono getDefaultOrganizationId(); + + Mono updateOrganizationConfiguration( + String organizationId, OrganizationConfiguration organizationConfiguration); + + Mono findById(String organizationId, AclPermission permission); + + Mono getOrganizationConfiguration(Mono dbOrganizationMono); + + Mono getOrganizationConfiguration(); + + Mono getDefaultOrganization(); + + Mono updateDefaultOrganizationConfiguration(OrganizationConfiguration organizationConfiguration); + + Mono save(Organization organization); + + Mono checkAndExecuteMigrationsForOrganizationFeatureFlags(Organization organization); + + Mono retrieveById(String id); + + Mono restartOrganization(); +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCEImpl.java new file mode 100644 index 000000000000..997be981e3e1 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/OrganizationServiceCEImpl.java @@ -0,0 +1,359 @@ +package com.appsmith.server.services.ce; + +import com.appsmith.external.enums.FeatureFlagEnum; +import com.appsmith.external.helpers.AppsmithBeanUtils; +import com.appsmith.server.acl.AclPermission; +import com.appsmith.server.configurations.CommonConfig; +import com.appsmith.server.constants.FeatureMigrationType; +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.constants.MigrationStatus; +import com.appsmith.server.constants.ce.FieldNameCE; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; +import com.appsmith.server.exceptions.AppsmithError; +import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.helpers.CollectionUtils; +import com.appsmith.server.helpers.FeatureFlagMigrationHelper; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.repositories.OrganizationRepository; +import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.BaseService; +import com.appsmith.server.services.ConfigService; +import com.appsmith.server.solutions.EnvManager; +import io.micrometer.observation.ObservationRegistry; +import jakarta.validation.Validator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.StringUtils; +import reactor.core.observability.micrometer.Micrometer; +import reactor.core.publisher.Mono; + +import java.util.Map; + +import static com.appsmith.external.constants.spans.OrganizationSpan.FETCH_DEFAULT_ORGANIZATION_SPAN; +import static com.appsmith.external.constants.spans.OrganizationSpan.FETCH_ORGANIZATION_CACHE_POST_DESERIALIZATION_ERROR_SPAN; +import static com.appsmith.server.acl.AclPermission.MANAGE_ORGANIZATION; +import static java.lang.Boolean.TRUE; + +@Slf4j +public class OrganizationServiceCEImpl extends BaseService + implements OrganizationServiceCE { + + private String organizationId = null; + + private final ConfigService configService; + + private final EnvManager envManager; + + private final FeatureFlagMigrationHelper featureFlagMigrationHelper; + + private final CacheableRepositoryHelper cacheableRepositoryHelper; + + private final CommonConfig commonConfig; + private final ObservationRegistry observationRegistry; + + public OrganizationServiceCEImpl( + Validator validator, + OrganizationRepository repository, + AnalyticsService analyticsService, + ConfigService configService, + @Lazy EnvManager envManager, + FeatureFlagMigrationHelper featureFlagMigrationHelper, + CacheableRepositoryHelper cacheableRepositoryHelper, + CommonConfig commonConfig, + ObservationRegistry observationRegistry) { + super(validator, repository, analyticsService); + this.configService = configService; + this.envManager = envManager; + this.featureFlagMigrationHelper = featureFlagMigrationHelper; + this.cacheableRepositoryHelper = cacheableRepositoryHelper; + this.commonConfig = commonConfig; + this.observationRegistry = observationRegistry; + } + + @Override + public Mono getDefaultOrganizationId() { + + // If the value exists in cache, return it as is + if (StringUtils.hasLength(organizationId)) { + return Mono.just(organizationId); + } + return repository.findBySlug(FieldName.DEFAULT).map(Organization::getId).map(organizationId -> { + // Set the cache value before returning. + this.organizationId = organizationId; + return organizationId; + }); + } + + @Override + public Mono updateOrganizationConfiguration( + String organizationId, OrganizationConfiguration organizationConfiguration) { + Mono evictOrganizationCache = cacheableRepositoryHelper.evictCachedOrganization(organizationId); + return repository + .findById(organizationId, MANAGE_ORGANIZATION) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.ORGANIZATION, organizationId))) + .flatMap(organization -> { + OrganizationConfiguration oldOrganizationConfiguration = + organization.getOrganizationConfiguration(); + if (oldOrganizationConfiguration == null) { + oldOrganizationConfiguration = new OrganizationConfiguration(); + } + Mono> envMono = Mono.empty(); + // instance admin is setting the email verification to true but the SMTP settings are not configured + if (organizationConfiguration.isEmailVerificationEnabled() == Boolean.TRUE) { + envMono = envManager.getAllNonEmpty().flatMap(properties -> { + String mailHost = properties.get("APPSMITH_MAIL_HOST"); + if (mailHost == null || mailHost == "") { + return Mono.error(new AppsmithException(AppsmithError.INVALID_SMTP_CONFIGURATION)); + } + return Mono.empty(); + }); + } + + return envMono.then(Mono.zip(Mono.just(oldOrganizationConfiguration), Mono.just(organization))); + }) + .flatMap(tuple2 -> { + Organization organization = tuple2.getT2(); + OrganizationConfiguration oldConfig = tuple2.getT1(); + AppsmithBeanUtils.copyNestedNonNullProperties(organizationConfiguration, oldConfig); + organization.setOrganizationConfiguration(oldConfig); + Mono updatedOrganizationMono = repository + .updateById(organizationId, organization, MANAGE_ORGANIZATION) + .cache(); + // Firstly updating the Organization object in the database and then evicting the cache. + // returning the updatedOrganization, notice the updatedOrganizationMono is cached using .cache() + // hence it will not be evaluated again + return updatedOrganizationMono + .then(Mono.defer(() -> evictOrganizationCache)) + .then(updatedOrganizationMono); + }); + } + + @Override + public Mono findById(String organizationId, AclPermission permission) { + return repository + .findById(organizationId, permission) + .switchIfEmpty(Mono.error(new AppsmithException( + AppsmithError.NO_RESOURCE_FOUND, FieldNameCE.ORGANIZATION_ID, organizationId))); + } + + @Override + public Mono getOrganizationConfiguration(Mono dbOrganizationMono) { + String adminEmailDomainHash = commonConfig.getAdminEmailDomainHash(); + Mono clientOrganizationMono = configService + .getInstanceId() + .map(instanceId -> { + final Organization organization = new Organization(); + organization.setInstanceId(instanceId); + organization.setAdminEmailDomainHash(adminEmailDomainHash); + + final OrganizationConfiguration config = new OrganizationConfiguration(); + organization.setOrganizationConfiguration(config); + + config.setGoogleMapsKey(System.getenv("APPSMITH_GOOGLE_MAPS_API_KEY")); + + if (StringUtils.hasText(System.getenv("APPSMITH_OAUTH2_GOOGLE_CLIENT_ID"))) { + config.addThirdPartyAuth("google"); + } + + if (StringUtils.hasText(System.getenv("APPSMITH_OAUTH2_GITHUB_CLIENT_ID"))) { + config.addThirdPartyAuth("github"); + } + + config.setIsFormLoginEnabled(!"true".equals(System.getenv("APPSMITH_FORM_LOGIN_DISABLED"))); + + return organization; + }); + + return Mono.zip(dbOrganizationMono, clientOrganizationMono).flatMap(tuple -> { + Organization dbOrganization = tuple.getT1(); + Organization clientOrganization = tuple.getT2(); + return getClientPertinentOrganization(dbOrganization, clientOrganization); + }); + } + + /* + * For now, returning just the instance-id, with an empty organizationConfiguration object in this class. Will enhance + * this function once we start saving other pertinent environment variables in the organization collection. + */ + @Override + public Mono getOrganizationConfiguration() { + Mono dbOrganizationMono = getDefaultOrganization(); + return getOrganizationConfiguration(dbOrganizationMono); + } + + @Override + public Mono getDefaultOrganization() { + // Fetching Organization from redis cache + return getDefaultOrganizationId() + .flatMap(organizationId -> cacheableRepositoryHelper.fetchDefaultOrganization(organizationId)) + .name(FETCH_DEFAULT_ORGANIZATION_SPAN) + .tap(Micrometer.observation(observationRegistry)) + .flatMap(organization -> + repository.setUserPermissionsInObject(organization).switchIfEmpty(Mono.just(organization))) + .onErrorResume(e -> { + e.printStackTrace(); + log.error("Error fetching default organization from redis : {}", e.getMessage()); + // If there is an error fetching the organization from the cache, then evict the cache and fetching + // from the db. This handles the case for deserialization errors. This prevents the entire instance + // to + // go down if organization cache is corrupted. + // More info - https://github.com/appsmithorg/appsmith/issues/33504 + log.info("Evicting the default organization from cache and fetching from the database!"); + return cacheableRepositoryHelper + .evictCachedOrganization(organizationId) + .then(cacheableRepositoryHelper + .fetchDefaultOrganization(organizationId) + .map(organization -> { + if (organization.getOrganizationConfiguration() == null) { + organization.setOrganizationConfiguration(new OrganizationConfiguration()); + } + return organization; + })) + .name(FETCH_ORGANIZATION_CACHE_POST_DESERIALIZATION_ERROR_SPAN) + .tap(Micrometer.observation(observationRegistry)) + .flatMap(organization -> repository + .setUserPermissionsInObject(organization) + .switchIfEmpty(Mono.just(organization))); + }); + } + + @Override + public Mono updateDefaultOrganizationConfiguration( + OrganizationConfiguration organizationConfiguration) { + return getDefaultOrganizationId() + .flatMap(organizationId -> updateOrganizationConfiguration(organizationId, organizationConfiguration)) + .flatMap(updatedOrganization -> getOrganizationConfiguration()); + } + + /** + * To get the Organization with values that are pertinent to the client + * @param dbOrganization Original organization from the database + * @param clientOrganization Organization object that is sent to the client, can be null + * @return Mono + */ + protected Mono getClientPertinentOrganization( + Organization dbOrganization, Organization clientOrganization) { + if (clientOrganization == null) { + clientOrganization = new Organization(); + clientOrganization.setOrganizationConfiguration(new OrganizationConfiguration()); + } + + final OrganizationConfiguration organizationConfiguration = clientOrganization.getOrganizationConfiguration(); + + // Only copy the values that are pertinent to the client + organizationConfiguration.copyNonSensitiveValues(dbOrganization.getOrganizationConfiguration()); + clientOrganization.setUserPermissions(dbOrganization.getUserPermissions()); + + return Mono.just(clientOrganization); + } + + // This function is used to save the organization object in the database and evict the cache + @Override + public Mono save(Organization organization) { + Mono evictCachedOrganization = cacheableRepositoryHelper.evictCachedOrganization(organizationId); + Mono savedOrganizationMono = repository.save(organization).cache(); + return savedOrganizationMono + .then(Mono.defer(() -> evictCachedOrganization)) + .then(savedOrganizationMono); + } + + /** + * This function checks if there are any pending migrations for feature flags and execute them. + * @param organization organization for which the migrations need to be executed + * @return organization with migrations executed + */ + @Override + public Mono checkAndExecuteMigrationsForOrganizationFeatureFlags(Organization organization) { + if (!isMigrationRequired(organization)) { + return Mono.just(organization); + } + Map featureMigrationTypeMap = + organization.getOrganizationConfiguration().getFeaturesWithPendingMigration(); + + FeatureFlagEnum featureFlagEnum = + featureMigrationTypeMap.keySet().stream().findFirst().orElse(null); + return featureFlagMigrationHelper + .checkAndExecuteMigrationsForFeatureFlag(organization, featureFlagEnum) + .flatMap(isSuccessful -> { + if (TRUE.equals(isSuccessful)) { + featureMigrationTypeMap.remove(featureFlagEnum); + if (CollectionUtils.isNullOrEmpty(featureMigrationTypeMap)) { + organization.getOrganizationConfiguration().setMigrationStatus(MigrationStatus.COMPLETED); + } else { + organization.getOrganizationConfiguration().setMigrationStatus(MigrationStatus.IN_PROGRESS); + } + return this.save(organization) + // Fetch the organization again from DB to make sure the downstream chain is consuming + // the + // latest + // DB object and not the modified one because of the client pertinent changes + .then(repository.findById(organization.getId())) + .flatMap(this::checkAndExecuteMigrationsForOrganizationFeatureFlags); + } + return Mono.error( + new AppsmithException(AppsmithError.FeatureFlagMigrationFailure, featureFlagEnum, "")); + }); + } + + @Override + public Mono retrieveById(String id) { + if (!StringUtils.hasLength(id)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); + } + return repository.findById(id); + } + + /** + * This function updates the organization object in the database and evicts the cache + * @param organizationId + * @param organization + * @return + */ + @Override + public Mono update(String organizationId, Organization organization) { + Mono evictCachedOrganization = cacheableRepositoryHelper.evictCachedOrganization(organizationId); + Mono updatedOrganizationMono = + super.update(organizationId, organization).cache(); + return updatedOrganizationMono + .then(Mono.defer(() -> evictCachedOrganization)) + .then(updatedOrganizationMono); + } + + /** + * This function checks if the organization needs to be restarted and restarts after the feature flag migrations are + * executed. + * + * @return + */ + @Override + public Mono restartOrganization() { + // Avoid dependency on user context as this method will be called internally by the server + Mono defaultOrganizationMono = + this.getDefaultOrganizationId().flatMap(this::retrieveById); + return defaultOrganizationMono.flatMap(updatedOrganization -> { + if (TRUE.equals(updatedOrganization.getOrganizationConfiguration().getIsRestartRequired())) { + log.debug("Triggering organization restart after the feature flag migrations are executed"); + OrganizationConfiguration organizationConfiguration = + updatedOrganization.getOrganizationConfiguration(); + organizationConfiguration.setIsRestartRequired(false); + return this.update(updatedOrganization.getId(), updatedOrganization) + .then(envManager.restartWithoutAclCheck()); + } + return Mono.empty(); + }); + } + + private boolean isMigrationRequired(Organization organization) { + return organization.getOrganizationConfiguration() != null + && (!CollectionUtils.isNullOrEmpty( + organization.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + || (CollectionUtils.isNullOrEmpty(organization + .getOrganizationConfiguration() + .getFeaturesWithPendingMigration()) + && !MigrationStatus.COMPLETED.equals(organization + .getOrganizationConfiguration() + .getMigrationStatus()))); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java index 22e516476ef5..57e0fef46b4e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/PermissionGroupServiceCEImpl.java @@ -18,8 +18,8 @@ import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.BaseService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.PermissionGroupPermission; import com.appsmith.server.solutions.PolicySolution; import jakarta.validation.Validator; @@ -45,7 +45,7 @@ public class PermissionGroupServiceCEImpl extends BaseService cleanPermissionGroupCacheForUsers(List userIds) { Mono> userMapMono = userRepository.findAllById(userIds).collectMap(user -> user.getId(), user -> user.getEmail()); - return tenantService - .getDefaultTenantId() + return organizationService + .getDefaultOrganizationId() .zipWith(userMapMono) .flatMapMany(tuple -> { - String defaultTenantId = tuple.getT1(); + String defaultOrganizationId = tuple.getT1(); Map userMap = tuple.getT2(); return Flux.fromIterable(userIds).flatMap(userId -> { String email = userMap.get(userId); return repository - .evictAllPermissionGroupCachesForUser(email, defaultTenantId) + .evictAllPermissionGroupCachesForUser(email, defaultOrganizationId) .thenReturn(TRUE); }); }) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCE.java deleted file mode 100644 index b8fb796bc630..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCE.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.appsmith.server.services.ce; - -import com.appsmith.server.acl.AclPermission; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; -import com.appsmith.server.services.CrudService; -import reactor.core.publisher.Mono; - -public interface TenantServiceCE extends CrudService { - - Mono getDefaultTenantId(); - - Mono updateTenantConfiguration(String tenantId, TenantConfiguration tenantConfiguration); - - Mono findById(String tenantId, AclPermission permission); - - Mono getTenantConfiguration(Mono dbTenantMono); - - Mono getTenantConfiguration(); - - Mono getDefaultTenant(); - - Mono updateDefaultTenantConfiguration(TenantConfiguration tenantConfiguration); - - Mono save(Tenant tenant); - - Mono checkAndExecuteMigrationsForTenantFeatureFlags(Tenant tenant); - - Mono retrieveById(String id); - - Mono restartTenant(); -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java deleted file mode 100644 index 2592b08a00fe..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/TenantServiceCEImpl.java +++ /dev/null @@ -1,338 +0,0 @@ -package com.appsmith.server.services.ce; - -import com.appsmith.external.enums.FeatureFlagEnum; -import com.appsmith.external.helpers.AppsmithBeanUtils; -import com.appsmith.server.acl.AclPermission; -import com.appsmith.server.configurations.CommonConfig; -import com.appsmith.server.constants.FeatureMigrationType; -import com.appsmith.server.constants.FieldName; -import com.appsmith.server.constants.MigrationStatus; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; -import com.appsmith.server.exceptions.AppsmithError; -import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.CollectionUtils; -import com.appsmith.server.helpers.FeatureFlagMigrationHelper; -import com.appsmith.server.repositories.CacheableRepositoryHelper; -import com.appsmith.server.repositories.TenantRepository; -import com.appsmith.server.services.AnalyticsService; -import com.appsmith.server.services.BaseService; -import com.appsmith.server.services.ConfigService; -import com.appsmith.server.solutions.EnvManager; -import io.micrometer.observation.ObservationRegistry; -import jakarta.validation.Validator; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.util.StringUtils; -import reactor.core.observability.micrometer.Micrometer; -import reactor.core.publisher.Mono; - -import java.util.Map; - -import static com.appsmith.external.constants.spans.TenantSpan.FETCH_DEFAULT_TENANT_SPAN; -import static com.appsmith.external.constants.spans.TenantSpan.FETCH_TENANT_CACHE_POST_DESERIALIZATION_ERROR_SPAN; -import static com.appsmith.server.acl.AclPermission.MANAGE_TENANT; -import static java.lang.Boolean.TRUE; - -@Slf4j -public class TenantServiceCEImpl extends BaseService implements TenantServiceCE { - - private String tenantId = null; - - private final ConfigService configService; - - private final EnvManager envManager; - - private final FeatureFlagMigrationHelper featureFlagMigrationHelper; - - private final CacheableRepositoryHelper cacheableRepositoryHelper; - - private final CommonConfig commonConfig; - private final ObservationRegistry observationRegistry; - - public TenantServiceCEImpl( - Validator validator, - TenantRepository repository, - AnalyticsService analyticsService, - ConfigService configService, - @Lazy EnvManager envManager, - FeatureFlagMigrationHelper featureFlagMigrationHelper, - CacheableRepositoryHelper cacheableRepositoryHelper, - CommonConfig commonConfig, - ObservationRegistry observationRegistry) { - super(validator, repository, analyticsService); - this.configService = configService; - this.envManager = envManager; - this.featureFlagMigrationHelper = featureFlagMigrationHelper; - this.cacheableRepositoryHelper = cacheableRepositoryHelper; - this.commonConfig = commonConfig; - this.observationRegistry = observationRegistry; - } - - @Override - public Mono getDefaultTenantId() { - - // If the value exists in cache, return it as is - if (StringUtils.hasLength(tenantId)) { - return Mono.just(tenantId); - } - return repository.findBySlug(FieldName.DEFAULT).map(Tenant::getId).map(tenantId -> { - // Set the cache value before returning. - this.tenantId = tenantId; - return tenantId; - }); - } - - @Override - public Mono updateTenantConfiguration(String tenantId, TenantConfiguration tenantConfiguration) { - Mono evictTenantCache = cacheableRepositoryHelper.evictCachedTenant(tenantId); - return repository - .findById(tenantId, MANAGE_TENANT) - .switchIfEmpty(Mono.error( - new AppsmithException(AppsmithError.ACL_NO_RESOURCE_FOUND, FieldName.TENANT, tenantId))) - .flatMap(tenant -> { - TenantConfiguration oldtenantConfiguration = tenant.getTenantConfiguration(); - if (oldtenantConfiguration == null) { - oldtenantConfiguration = new TenantConfiguration(); - } - Mono> envMono = Mono.empty(); - // instance admin is setting the email verification to true but the SMTP settings are not configured - if (tenantConfiguration.isEmailVerificationEnabled() == Boolean.TRUE) { - envMono = envManager.getAllNonEmpty().flatMap(properties -> { - String mailHost = properties.get("APPSMITH_MAIL_HOST"); - if (mailHost == null || mailHost == "") { - return Mono.error(new AppsmithException(AppsmithError.INVALID_SMTP_CONFIGURATION)); - } - return Mono.empty(); - }); - } - - return envMono.then(Mono.zip(Mono.just(oldtenantConfiguration), Mono.just(tenant))); - }) - .flatMap(tuple2 -> { - Tenant tenant = tuple2.getT2(); - TenantConfiguration oldConfig = tuple2.getT1(); - AppsmithBeanUtils.copyNestedNonNullProperties(tenantConfiguration, oldConfig); - tenant.setTenantConfiguration(oldConfig); - Mono updatedTenantMono = repository - .updateById(tenantId, tenant, MANAGE_TENANT) - .cache(); - // Firstly updating the Tenant object in the database and then evicting the cache. - // returning the updatedTenant, notice the updatedTenantMono is cached using .cache() - // hence it will not be evaluated again - return updatedTenantMono - .then(Mono.defer(() -> evictTenantCache)) - .then(updatedTenantMono); - }); - } - - @Override - public Mono findById(String tenantId, AclPermission permission) { - return repository - .findById(tenantId, permission) - .switchIfEmpty( - Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "tenantId", tenantId))); - } - - @Override - public Mono getTenantConfiguration(Mono dbTenantMono) { - String adminEmailDomainHash = commonConfig.getAdminEmailDomainHash(); - Mono clientTenantMono = configService.getInstanceId().map(instanceId -> { - final Tenant tenant = new Tenant(); - tenant.setInstanceId(instanceId); - tenant.setAdminEmailDomainHash(adminEmailDomainHash); - - final TenantConfiguration config = new TenantConfiguration(); - tenant.setTenantConfiguration(config); - - config.setGoogleMapsKey(System.getenv("APPSMITH_GOOGLE_MAPS_API_KEY")); - - if (StringUtils.hasText(System.getenv("APPSMITH_OAUTH2_GOOGLE_CLIENT_ID"))) { - config.addThirdPartyAuth("google"); - } - - if (StringUtils.hasText(System.getenv("APPSMITH_OAUTH2_GITHUB_CLIENT_ID"))) { - config.addThirdPartyAuth("github"); - } - - config.setIsFormLoginEnabled(!"true".equals(System.getenv("APPSMITH_FORM_LOGIN_DISABLED"))); - - return tenant; - }); - - return Mono.zip(dbTenantMono, clientTenantMono).flatMap(tuple -> { - Tenant dbTenant = tuple.getT1(); - Tenant clientTenant = tuple.getT2(); - return getClientPertinentTenant(dbTenant, clientTenant); - }); - } - - /* - * For now, returning just the instance-id, with an empty tenantConfiguration object in this class. Will enhance - * this function once we start saving other pertinent environment variables in the tenant collection. - */ - @Override - public Mono getTenantConfiguration() { - Mono dbTenantMono = getDefaultTenant(); - return getTenantConfiguration(dbTenantMono); - } - - @Override - public Mono getDefaultTenant() { - // Fetching Tenant from redis cache - return getDefaultTenantId() - .flatMap(tenantId -> cacheableRepositoryHelper.fetchDefaultTenant(tenantId)) - .name(FETCH_DEFAULT_TENANT_SPAN) - .tap(Micrometer.observation(observationRegistry)) - .flatMap(tenant -> repository.setUserPermissionsInObject(tenant).switchIfEmpty(Mono.just(tenant))) - .onErrorResume(e -> { - e.printStackTrace(); - log.error("Error fetching default tenant from redis : {}", e.getMessage()); - // If there is an error fetching the tenant from the cache, then evict the cache and fetching from - // the db. This handles the case for deserialization errors. This prevents the entire instance to - // go down if tenant cache is corrupted. - // More info - https://github.com/appsmithorg/appsmith/issues/33504 - log.info("Evicting the default tenant from cache and fetching from the database!"); - return cacheableRepositoryHelper - .evictCachedTenant(tenantId) - .then(cacheableRepositoryHelper - .fetchDefaultTenant(tenantId) - .map(tenant -> { - if (tenant.getTenantConfiguration() == null) { - tenant.setTenantConfiguration(new TenantConfiguration()); - } - return tenant; - })) - .name(FETCH_TENANT_CACHE_POST_DESERIALIZATION_ERROR_SPAN) - .tap(Micrometer.observation(observationRegistry)) - .flatMap(tenant -> repository - .setUserPermissionsInObject(tenant) - .switchIfEmpty(Mono.just(tenant))); - }); - } - - @Override - public Mono updateDefaultTenantConfiguration(TenantConfiguration tenantConfiguration) { - return getDefaultTenantId() - .flatMap(tenantId -> updateTenantConfiguration(tenantId, tenantConfiguration)) - .flatMap(updatedTenant -> getTenantConfiguration()); - } - - /** - * To get the Tenant with values that are pertinent to the client - * @param dbTenant Original tenant from the database - * @param clientTenant Tenant object that is sent to the client, can be null - * @return Mono - */ - protected Mono getClientPertinentTenant(Tenant dbTenant, Tenant clientTenant) { - if (clientTenant == null) { - clientTenant = new Tenant(); - clientTenant.setTenantConfiguration(new TenantConfiguration()); - } - - final TenantConfiguration tenantConfiguration = clientTenant.getTenantConfiguration(); - - // Only copy the values that are pertinent to the client - tenantConfiguration.copyNonSensitiveValues(dbTenant.getTenantConfiguration()); - clientTenant.setUserPermissions(dbTenant.getUserPermissions()); - - return Mono.just(clientTenant); - } - - // This function is used to save the tenant object in the database and evict the cache - @Override - public Mono save(Tenant tenant) { - Mono evictTenantCache = cacheableRepositoryHelper.evictCachedTenant(tenantId); - Mono savedTenantMono = repository.save(tenant).cache(); - return savedTenantMono.then(Mono.defer(() -> evictTenantCache)).then(savedTenantMono); - } - - /** - * This function checks if there are any pending migrations for feature flags and execute them. - * @param tenant tenant for which the migrations need to be executed - * @return tenant with migrations executed - */ - @Override - public Mono checkAndExecuteMigrationsForTenantFeatureFlags(Tenant tenant) { - if (!isMigrationRequired(tenant)) { - return Mono.just(tenant); - } - Map featureMigrationTypeMap = - tenant.getTenantConfiguration().getFeaturesWithPendingMigration(); - - FeatureFlagEnum featureFlagEnum = - featureMigrationTypeMap.keySet().stream().findFirst().orElse(null); - return featureFlagMigrationHelper - .checkAndExecuteMigrationsForFeatureFlag(tenant, featureFlagEnum) - .flatMap(isSuccessful -> { - if (TRUE.equals(isSuccessful)) { - featureMigrationTypeMap.remove(featureFlagEnum); - if (CollectionUtils.isNullOrEmpty(featureMigrationTypeMap)) { - tenant.getTenantConfiguration().setMigrationStatus(MigrationStatus.COMPLETED); - } else { - tenant.getTenantConfiguration().setMigrationStatus(MigrationStatus.IN_PROGRESS); - } - return this.save(tenant) - // Fetch the tenant again from DB to make sure the downstream chain is consuming the - // latest - // DB object and not the modified one because of the client pertinent changes - .then(repository.findById(tenant.getId())) - .flatMap(this::checkAndExecuteMigrationsForTenantFeatureFlags); - } - return Mono.error( - new AppsmithException(AppsmithError.FeatureFlagMigrationFailure, featureFlagEnum, "")); - }); - } - - @Override - public Mono retrieveById(String id) { - if (!StringUtils.hasLength(id)) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); - } - return repository.findById(id); - } - - /** - * This function updates the tenant object in the database and evicts the cache - * @param tenantId - * @param tenant - * @return - */ - @Override - public Mono update(String tenantId, Tenant tenant) { - Mono evictTenantCache = cacheableRepositoryHelper.evictCachedTenant(tenantId); - Mono updatedTenantMono = super.update(tenantId, tenant).cache(); - return updatedTenantMono.then(Mono.defer(() -> evictTenantCache)).then(updatedTenantMono); - } - - /** - * This function checks if the tenant needs to be restarted and restarts after the feature flag migrations are - * executed. - * - * @return - */ - @Override - public Mono restartTenant() { - // Avoid dependency on user context as this method will be called internally by the server - Mono defaultTenantMono = this.getDefaultTenantId().flatMap(this::retrieveById); - return defaultTenantMono.flatMap(updatedTenant -> { - if (TRUE.equals(updatedTenant.getTenantConfiguration().getIsRestartRequired())) { - log.debug("Triggering tenant restart after the feature flag migrations are executed"); - TenantConfiguration tenantConfiguration = updatedTenant.getTenantConfiguration(); - tenantConfiguration.setIsRestartRequired(false); - return this.update(updatedTenant.getId(), updatedTenant).then(envManager.restartWithoutAclCheck()); - } - return Mono.empty(); - }); - } - - private boolean isMigrationRequired(Tenant tenant) { - return tenant.getTenantConfiguration() != null - && (!CollectionUtils.isNullOrEmpty( - tenant.getTenantConfiguration().getFeaturesWithPendingMigration()) - || (CollectionUtils.isNullOrEmpty( - tenant.getTenantConfiguration().getFeaturesWithPendingMigration()) - && !MigrationStatus.COMPLETED.equals( - tenant.getTenantConfiguration().getMigrationStatus()))); - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java index 55027b06933b..4a041fa0c323 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java @@ -11,8 +11,8 @@ import com.appsmith.server.helpers.ce.bridge.BridgeUpdate; import com.appsmith.server.repositories.UsagePulseRepository; import com.appsmith.server.services.ConfigService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserService; import lombok.RequiredArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; @@ -33,7 +33,7 @@ public class UsagePulseServiceCEImpl implements UsagePulseServiceCE { private final UserService userService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final ConfigService configService; @@ -64,43 +64,43 @@ public Mono createPulse(UsagePulseDTO usagePulseDTO) { usagePulse.setViewMode(usagePulseDTO.getViewMode()); Mono currentUserMono = sessionUserService.getCurrentUser(); - // TODO: Change to getCurrentTenantId once multi-tenancy in introduced - Mono tenantIdMono = tenantService.getDefaultTenantId(); + Mono defaultOrganizationIdMono = organizationService.getDefaultOrganizationId(); Mono instanceIdMono = configService.getInstanceId(); - return Mono.zip(currentUserMono, tenantIdMono, instanceIdMono).flatMap(tuple -> { - User user = tuple.getT1(); - String tenantId = tuple.getT2(); - String instanceId = tuple.getT3(); - usagePulse.setTenantId(tenantId); - usagePulse.setInstanceId(instanceId); - - if (user.isAnonymous()) { - if (null == usagePulseDTO.getAnonymousUserId()) { - return Mono.error( - new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ANONYMOUS_USER_ID)); - } - usagePulse.setIsAnonymousUser(true); - usagePulse.setUser(usagePulseDTO.getAnonymousUserId()); - return save(usagePulse); - } - usagePulse.setIsAnonymousUser(false); - BridgeUpdate updateUserObj = Bridge.update(); - - String hashedEmail = user.getHashedEmail(); - if (StringUtils.isEmpty(hashedEmail)) { - hashedEmail = DigestUtils.sha256Hex(user.getEmail()); - // Hashed user email is stored to user for future mapping of user and pulses - updateUserObj.set(User.Fields.hashedEmail, hashedEmail); - } - usagePulse.setUser(hashedEmail); - - updateUserObj.set(User.Fields.lastActiveAt, Instant.now()); - - return userService - .updateWithoutPermission(user.getId(), updateUserObj) - .then(save(usagePulse)); - }); + return Mono.zip(currentUserMono, defaultOrganizationIdMono, instanceIdMono) + .flatMap(tuple -> { + User user = tuple.getT1(); + String organizationId = tuple.getT2(); + String instanceId = tuple.getT3(); + usagePulse.setOrganizationId(organizationId); + usagePulse.setInstanceId(instanceId); + + if (user.isAnonymous()) { + if (null == usagePulseDTO.getAnonymousUserId()) { + return Mono.error(new AppsmithException( + AppsmithError.INVALID_PARAMETER, FieldName.ANONYMOUS_USER_ID)); + } + usagePulse.setIsAnonymousUser(true); + usagePulse.setUser(usagePulseDTO.getAnonymousUserId()); + return save(usagePulse); + } + usagePulse.setIsAnonymousUser(false); + BridgeUpdate updateUserObj = Bridge.update(); + + String hashedEmail = user.getHashedEmail(); + if (StringUtils.isEmpty(hashedEmail)) { + hashedEmail = DigestUtils.sha256Hex(user.getEmail()); + // Hashed user email is stored to user for future mapping of user and pulses + updateUserObj.set(User.Fields.hashedEmail, hashedEmail); + } + usagePulse.setUser(hashedEmail); + + updateUserObj.set(User.Fields.lastActiveAt, Instant.now()); + + return userService + .updateWithoutPermission(user.getId(), updateUserObj) + .then(save(usagePulse)); + }); } /** diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java index 0f2180207caf..eac40e84e845 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserDataServiceCEImpl.java @@ -20,8 +20,8 @@ import com.appsmith.server.services.AssetService; import com.appsmith.server.services.BaseService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ReleaseNotesService; import jakarta.validation.Validator; import org.apache.commons.lang3.ObjectUtils; @@ -54,7 +54,7 @@ public class UserDataServiceCEImpl extends BaseService getForCurrentUser() { @Override public Mono getForUserEmail(String email) { - return tenantService - .getDefaultTenantId() - .flatMap(tenantId -> userRepository.findByEmailAndTenantId(email, tenantId)) + return organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> userRepository.findByEmailAndOrganizationId(email, organizationId)) .flatMap(this::getForUser); } @@ -124,9 +124,10 @@ public Mono> getProfilePhotoAssetIdsForUserIds(Collection updateForCurrentUser(UserData updates) { return sessionUserService .getCurrentUser() - .flatMap(user -> tenantService - .getDefaultTenantId() - .flatMap(tenantId -> userRepository.findByEmailAndTenantId(user.getEmail(), tenantId))) + .flatMap(user -> organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> + userRepository.findByEmailAndOrganizationId(user.getEmail(), organizationId))) .flatMap(user -> updateForUser(user, updates)); } @@ -170,9 +171,10 @@ public Mono setViewedCurrentVersionReleaseNotes(User user, String version) } return Mono.justOrEmpty(user.getId()) - .switchIfEmpty(tenantService - .getDefaultTenantId() - .flatMap(tenantId -> userRepository.findByEmailAndTenantId(user.getEmail(), tenantId)) + .switchIfEmpty(organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> + userRepository.findByEmailAndOrganizationId(user.getEmail(), organizationId)) .flatMap(user1 -> Mono.justOrEmpty(user1.getId()))) .flatMap(userId -> repository .saveReleaseNotesViewedVersion(userId, version) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java index 24dfffcbc0a9..108138c5078a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java @@ -19,7 +19,7 @@ public interface UserServiceCE extends CrudService { Mono findByEmail(String email); - Mono findByEmailAndTenantId(String email, String tenantId); + Mono findByEmailAndOrganizationId(String email, String organizationId); Mono forgotPasswordTokenGenerate(ResetUserPasswordDTO resetUserPasswordDTO); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java index 4f5d7a690c3f..c6ced67e84f9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java @@ -7,9 +7,9 @@ import com.appsmith.server.constants.RateLimitConstants; import com.appsmith.server.domains.EmailVerificationToken; import com.appsmith.server.domains.LoginSource; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.PasswordResetToken; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserData; import com.appsmith.server.domains.Workspace; @@ -31,9 +31,9 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.BaseService; import com.appsmith.server.services.EmailService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PACConfigurationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.WorkspaceService; import jakarta.validation.Validator; @@ -77,7 +77,7 @@ import static com.appsmith.server.acl.AclPermission.MANAGE_USERS; import static com.appsmith.server.constants.FieldName.DEFAULT; -import static com.appsmith.server.constants.FieldName.TENANT; +import static com.appsmith.server.constants.FieldName.ORGANIZATION; import static com.appsmith.server.helpers.RedirectHelper.DEFAULT_REDIRECT_URL; import static com.appsmith.server.helpers.ValidationUtils.LOGIN_PASSWORD_MAX_LENGTH; import static com.appsmith.server.helpers.ValidationUtils.LOGIN_PASSWORD_MIN_LENGTH; @@ -97,7 +97,7 @@ public class UserServiceCEImpl extends BaseService private final CommonConfig commonConfig; private final UserDataService userDataService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final UserUtils userUtils; private final EmailService emailService; private final RateLimitService rateLimitService; @@ -128,7 +128,7 @@ public UserServiceCEImpl( PasswordEncoder passwordEncoder, CommonConfig commonConfig, UserDataService userDataService, - TenantService tenantService, + OrganizationService organizationService, UserUtils userUtils, EmailVerificationTokenRepository emailVerificationTokenRepository, EmailService emailService, @@ -143,7 +143,7 @@ public UserServiceCEImpl( this.passwordEncoder = passwordEncoder; this.commonConfig = commonConfig; this.userDataService = userDataService; - this.tenantService = tenantService; + this.organizationService = organizationService; this.userUtils = userUtils; this.rateLimitService = rateLimitService; this.emailVerificationTokenRepository = emailVerificationTokenRepository; @@ -154,12 +154,14 @@ public UserServiceCEImpl( @Override public Mono findByEmail(String email) { - return tenantService.getDefaultTenantId().flatMap(tenantId -> findByEmailAndTenantId(email, tenantId)); + return organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> findByEmailAndOrganizationId(email, organizationId)); } @Override - public Mono findByEmailAndTenantId(String email, String tenantId) { - return repository.findByEmailAndTenantId(email, tenantId); + public Mono findByEmailAndOrganizationId(String email, String organizationId) { + return repository.findByEmailAndOrganizationId(email, organizationId); } /** @@ -305,9 +307,10 @@ public Mono resetPasswordAfterForgotPassword(String encryptedToken, Use return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.TOKEN)); } - Mono tenantMono = tenantService - .getDefaultTenant() - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, DEFAULT, TENANT))); + Mono organizationMono = organizationService + .getDefaultOrganization() + .switchIfEmpty( + Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, DEFAULT, ORGANIZATION))); return passwordResetTokenRepository .findByEmail(emailTokenDTO.getEmail()) @@ -325,13 +328,14 @@ public Mono resetPasswordAfterForgotPassword(String encryptedToken, Use .findByEmail(emailAddress) .switchIfEmpty(Mono.error( new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.USER, emailAddress))) - .zipWith(tenantMono) + .zipWith(organizationMono) .flatMap(tuple -> { User userFromDb = tuple.getT1(); - TenantConfiguration tenantConfiguration = - tuple.getT2().getTenantConfiguration(); - boolean isStrongPasswordPolicyEnabled = tenantConfiguration != null - && Boolean.TRUE.equals(tenantConfiguration.getIsStrongPasswordPolicyEnabled()); + OrganizationConfiguration organizationConfiguration = + tuple.getT2().getOrganizationConfiguration(); + boolean isStrongPasswordPolicyEnabled = organizationConfiguration != null + && Boolean.TRUE.equals( + organizationConfiguration.getIsStrongPasswordPolicyEnabled()); if (!validateUserPassword(user.getPassword(), isStrongPasswordPolicyEnabled)) { return isStrongPasswordPolicyEnabled @@ -395,19 +399,19 @@ public Mono userCreate(User user, boolean isAdminUser) { // convert the user email to lowercase user.setEmail(user.getEmail().toLowerCase()); - Mono userWithTenantMono = Mono.just(user).flatMap(userBeforeSave -> { - if (userBeforeSave.getTenantId() == null) { - return tenantService.getDefaultTenantId().map(tenantId -> { - userBeforeSave.setTenantId(tenantId); + Mono userWithOrgMono = Mono.just(user).flatMap(userBeforeSave -> { + if (userBeforeSave.getOrganizationId() == null) { + return organizationService.getDefaultOrganizationId().map(organizationId -> { + userBeforeSave.setOrganizationId(organizationId); return userBeforeSave; }); } - // The tenant has been set already. No need to set the default tenant id. + // The org has been set already. No need to set the default org id. return Mono.just(userBeforeSave); }); // Save the new user - return userWithTenantMono + return userWithOrgMono .flatMap(this::validateObject) .flatMap(repository::save) .flatMap(this::addUserPoliciesAndSaveToRepo) @@ -674,7 +678,8 @@ public Mono buildUserProfileDTO(User user) { Mono userFromDbMono = findByEmail(user.getEmail()).cache(); - Mono isSuperUserMono = userFromDbMono.flatMap(userUtils::isSuperUser); + Mono isSuperUserMono = + userFromDbMono.flatMap(userUtils::isSuperUser).defaultIfEmpty(false); return Mono.zip( isUsersEmpty(), @@ -754,13 +759,13 @@ public Mono resendEmailVerification( if (TRUE.equals(user.getEmailVerified())) { return Mono.error(new AppsmithException(AppsmithError.USER_ALREADY_VERIFIED)); } - return tenantService.getTenantConfiguration().flatMap(tenant -> { + return organizationService.getOrganizationConfiguration().flatMap(organization -> { Boolean emailVerificationEnabled = - tenant.getTenantConfiguration().isEmailVerificationEnabled(); - // Email verification not enabled at tenant + organization.getOrganizationConfiguration().isEmailVerificationEnabled(); + // Email verification not enabled at organization level if (!TRUE.equals(emailVerificationEnabled)) { return Mono.error( - new AppsmithException(AppsmithError.TENANT_EMAIL_VERIFICATION_NOT_ENABLED)); + new AppsmithException(AppsmithError.ORGANIZATION_EMAIL_VERIFICATION_NOT_ENABLED)); } return emailVerificationTokenRepository .findByEmail(user.getEmail()) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserWorkspaceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserWorkspaceServiceCEImpl.java index 3430bb83b993..239aae4c7da8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserWorkspaceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserWorkspaceServiceCEImpl.java @@ -13,9 +13,9 @@ import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.AppsmithComparators; import com.appsmith.server.repositories.UserRepository; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PermissionGroupService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.solutions.PermissionGroupPermission; @@ -50,7 +50,7 @@ public class UserWorkspaceServiceCEImpl implements UserWorkspaceServiceCE { private final UserRepository userRepository; private final UserDataService userDataService; private final PermissionGroupService permissionGroupService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final WorkspacePermission workspacePermission; private final PermissionGroupPermission permissionGroupPermission; @@ -61,7 +61,7 @@ public UserWorkspaceServiceCEImpl( UserRepository userRepository, UserDataService userDataService, PermissionGroupService permissionGroupService, - TenantService tenantService, + OrganizationService organizationService, WorkspacePermission workspacePermission, PermissionGroupPermission permissionGroupPermission) { this.sessionUserService = sessionUserService; @@ -69,7 +69,7 @@ public UserWorkspaceServiceCEImpl( this.userRepository = userRepository; this.userDataService = userDataService; this.permissionGroupService = permissionGroupService; - this.tenantService = tenantService; + this.organizationService = organizationService; this.workspacePermission = workspacePermission; this.permissionGroupPermission = permissionGroupPermission; } @@ -147,9 +147,10 @@ public Mono updatePermissionGroupForMember( .cache(); // Get the user - Mono userMono = tenantService - .getDefaultTenantId() - .flatMap(tenantId -> userRepository.findByEmailAndTenantId(changeUserGroupDTO.getUsername(), tenantId)) + Mono userMono = organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> + userRepository.findByEmailAndOrganizationId(changeUserGroupDTO.getUsername(), organizationId)) .switchIfEmpty(Mono.error(new AppsmithException( AppsmithError.NO_RESOURCE_FOUND, FieldName.USER, changeUserGroupDTO.getUsername()))) .cache(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCE.java index 40ce39ce0298..071001f4d981 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCE.java @@ -28,7 +28,7 @@ public interface WorkspaceServiceCE extends CrudService { Mono findByIdAndPluginsPluginId(String workspaceId, String pluginId); - Flux findByIdsIn(Set ids, String tenantId, AclPermission permission); + Flux findByIdsIn(Set ids, String organizationId, AclPermission permission); Flux getAll(AclPermission permission); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCEImpl.java index 7758ee3f0c58..cdcd6187a86f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/WorkspaceServiceCEImpl.java @@ -193,7 +193,7 @@ protected void prepareWorkspaceToCreate(Workspace workspace, User user) { } workspace.setSlug(TextUtils.makeSlug(workspace.getName())); - workspace.setTenantId(user.getTenantId()); + workspace.setOrganizationId(user.getOrganizationId()); } protected Mono createWorkspaceDependents(Workspace createdWorkspace) { @@ -240,7 +240,7 @@ private Mono> generateDefaultPermissionGroupsWithoutPermiss adminPermissionGroup.setName(generateDefaultRoleNameForResource(ADMINISTRATOR, workspaceName)); adminPermissionGroup.setDefaultDomainId(workspaceId); adminPermissionGroup.setDefaultDomainType(Workspace.class.getSimpleName()); - adminPermissionGroup.setTenantId(workspace.getTenantId()); + adminPermissionGroup.setOrganizationId(workspace.getOrganizationId()); adminPermissionGroup.setDescription(WORKSPACE_ADMINISTRATOR_DESCRIPTION); adminPermissionGroup.setPermissions(Set.of()); @@ -249,7 +249,7 @@ private Mono> generateDefaultPermissionGroupsWithoutPermiss developerPermissionGroup.setName(generateDefaultRoleNameForResource(DEVELOPER, workspaceName)); developerPermissionGroup.setDefaultDomainId(workspaceId); developerPermissionGroup.setDefaultDomainType(Workspace.class.getSimpleName()); - developerPermissionGroup.setTenantId(workspace.getTenantId()); + developerPermissionGroup.setOrganizationId(workspace.getOrganizationId()); developerPermissionGroup.setDescription(WORKSPACE_DEVELOPER_DESCRIPTION); developerPermissionGroup.setPermissions(Set.of()); @@ -258,7 +258,7 @@ private Mono> generateDefaultPermissionGroupsWithoutPermiss viewerPermissionGroup.setName(generateDefaultRoleNameForResource(VIEWER, workspaceName)); viewerPermissionGroup.setDefaultDomainId(workspaceId); viewerPermissionGroup.setDefaultDomainType(Workspace.class.getSimpleName()); - viewerPermissionGroup.setTenantId(workspace.getTenantId()); + viewerPermissionGroup.setOrganizationId(workspace.getOrganizationId()); viewerPermissionGroup.setDescription(WORKSPACE_VIEWER_DESCRIPTION); viewerPermissionGroup.setPermissions(Set.of()); @@ -456,10 +456,10 @@ public Mono findByIdAndPluginsPluginId(String workspaceId, String plu } @Override - public Flux findByIdsIn(Set ids, String tenantId, AclPermission permission) { + public Flux findByIdsIn(Set ids, String organizationId, AclPermission permission) { Sort sort = Sort.by(FieldName.NAME); - return repository.findByIdsIn(ids, tenantId, permission, sort); + return repository.findByIdsIn(ids, organizationId, permission, sort); } @Override diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java index c6f94b2cf303..5baec349b02a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/ConsolidatedAPIServiceCECompatibleImpl.java @@ -11,9 +11,9 @@ import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.MockDataService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.ProductAlertService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.services.ce.ConsolidatedAPIServiceCEImpl; @@ -26,7 +26,7 @@ public ConsolidatedAPIServiceCECompatibleImpl( SessionUserService sessionUserService, UserService userService, UserDataService userDataService, - TenantService tenantService, + OrganizationService organizationService, ProductAlertService productAlertService, NewPageService newPageService, NewActionService newActionService, @@ -45,7 +45,7 @@ public ConsolidatedAPIServiceCECompatibleImpl( sessionUserService, userService, userDataService, - tenantService, + organizationService, productAlertService, newPageService, newActionService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/PermissionGroupServiceCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/PermissionGroupServiceCECompatibleImpl.java index be6024011cb8..3d9c82438b9f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/PermissionGroupServiceCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/PermissionGroupServiceCECompatibleImpl.java @@ -4,8 +4,8 @@ import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.ce.PermissionGroupServiceCEImpl; import com.appsmith.server.solutions.PermissionGroupPermission; import com.appsmith.server.solutions.PolicySolution; @@ -20,7 +20,7 @@ public PermissionGroupServiceCECompatibleImpl( PermissionGroupRepository repository, AnalyticsService analyticsService, SessionUserService sessionUserService, - TenantService tenantService, + OrganizationService organizationService, UserRepository userRepository, PolicySolution policySolution, ConfigRepository configRepository, @@ -30,7 +30,7 @@ public PermissionGroupServiceCECompatibleImpl( repository, analyticsService, sessionUserService, - tenantService, + organizationService, userRepository, policySolution, configRepository, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/UserServiceCECompatibleImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/UserServiceCECompatibleImpl.java index 7589ceac4a88..a3d91e7c9a44 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/UserServiceCECompatibleImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce_compatible/UserServiceCECompatibleImpl.java @@ -9,9 +9,9 @@ import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.EmailService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PACConfigurationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.WorkspaceService; import com.appsmith.server.services.ce.UserServiceCEImpl; @@ -31,7 +31,7 @@ public UserServiceCECompatibleImpl( PasswordEncoder passwordEncoder, CommonConfig commonConfig, UserDataService userDataService, - TenantService tenantService, + OrganizationService organizationService, UserUtils userUtils, EmailVerificationTokenRepository emailVerificationTokenRepository, EmailService emailService, @@ -48,7 +48,7 @@ public UserServiceCECompatibleImpl( passwordEncoder, commonConfig, userDataService, - tenantService, + organizationService, userUtils, emailVerificationTokenRepository, emailService, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java index 6f3413f55d94..47ec8c2b321d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java @@ -14,8 +14,8 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ce.ActionExecutionSolutionCEImpl; import com.fasterxml.jackson.databind.ObjectMapper; import io.micrometer.observation.ObservationRegistry; @@ -41,7 +41,7 @@ public ActionExecutionSolutionImpl( DatasourceStorageService datasourceStorageService, EnvironmentPermission environmentPermission, ConfigService configService, - TenantService tenantService, + OrganizationService organizationService, CommonConfig commonConfig, ActionExecutionSolutionHelper actionExecutionSolutionHelper, FeatureFlagService featureFlagService) { @@ -63,7 +63,7 @@ public ActionExecutionSolutionImpl( datasourceStorageService, environmentPermission, configService, - tenantService, + organizationService, commonConfig, actionExecutionSolutionHelper, featureFlagService); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java index a892502e7ffb..71c7c1e9f8bb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java @@ -8,7 +8,7 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.solutions.ce.DatasourceTriggerSolutionCEImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -29,7 +29,7 @@ public DatasourceTriggerSolutionImpl( DatasourcePermission datasourcePermission, EnvironmentPermission environmentPermission, ConfigService configService, - TenantService tenantService, + OrganizationService organizationService, FeatureFlagService featureFlagService) { super( datasourceService, @@ -42,7 +42,7 @@ public DatasourceTriggerSolutionImpl( datasourcePermission, environmentPermission, configService, - tenantService, + organizationService, featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java index 865c9bf2dd82..974b359c4e86 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/EnvManagerImpl.java @@ -10,9 +10,9 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PermissionGroupService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserService; import com.appsmith.server.solutions.ce.EnvManagerCEImpl; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,7 +38,7 @@ public EnvManagerImpl( PermissionGroupService permissionGroupService, ConfigService configService, UserUtils userUtils, - TenantService tenantService, + OrganizationService organizationService, ObjectMapper objectMapper, EmailService emailService) { @@ -56,7 +56,7 @@ public EnvManagerImpl( permissionGroupService, configService, userUtils, - tenantService, + organizationService, objectMapper, emailService); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java index 7b16eae7de6f..4ea28396a8b4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ScheduledTaskImpl.java @@ -1,11 +1,11 @@ package com.appsmith.server.solutions; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.solutions.ce.ScheduledTaskCEImpl; public class ScheduledTaskImpl extends ScheduledTaskCEImpl implements ScheduledTask { - public ScheduledTaskImpl(FeatureFlagService featureFlagService, TenantService tenantService) { - super(featureFlagService, tenantService); + public ScheduledTaskImpl(FeatureFlagService featureFlagService, OrganizationService organizationService) { + super(featureFlagService, organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/UserSignupImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/UserSignupImpl.java index 29b03db32ad7..2cca8735001b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/UserSignupImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/UserSignupImpl.java @@ -7,7 +7,7 @@ import com.appsmith.server.services.CaptchaService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.solutions.ce.UserSignupCEImpl; @@ -29,7 +29,7 @@ public UserSignupImpl( UserUtils userUtils, NetworkUtils networkUtils, EmailService emailService, - TenantService tenantService) { + OrganizationService organizationService) { super( userService, @@ -42,6 +42,6 @@ public UserSignupImpl( userUtils, networkUtils, emailService, - tenantService); + organizationService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 78737b83b78a..3c717e069713 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -46,8 +46,8 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.EnvironmentPermission; @@ -121,7 +121,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE private final DatasourceStorageService datasourceStorageService; private final EnvironmentPermission environmentPermission; private final ConfigService configService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final ActionExecutionSolutionHelper actionExecutionSolutionHelper; private final CommonConfig commonConfig; private final FeatureFlagService featureFlagService; @@ -151,7 +151,7 @@ public ActionExecutionSolutionCEImpl( DatasourceStorageService datasourceStorageService, EnvironmentPermission environmentPermission, ConfigService configService, - TenantService tenantService, + OrganizationService organizationService, CommonConfig commonConfig, ActionExecutionSolutionHelper actionExecutionSolutionHelper, FeatureFlagService featureFlagService) { @@ -172,7 +172,7 @@ public ActionExecutionSolutionCEImpl( this.datasourceStorageService = datasourceStorageService; this.environmentPermission = environmentPermission; this.configService = configService; - this.tenantService = tenantService; + this.organizationService = organizationService; this.commonConfig = commonConfig; this.actionExecutionSolutionHelper = actionExecutionSolutionHelper; this.featureFlagService = featureFlagService; @@ -252,16 +252,16 @@ private Mono getTrueEnvironmentId( */ private Mono populateExecuteActionDTO(ExecuteActionDTO executeActionDTO, NewAction newAction) { Mono instanceIdMono = configService.getInstanceId(); - Mono defaultTenantIdMono = tenantService.getDefaultTenantId(); + Mono defaultOrganizationIdMono = organizationService.getDefaultOrganizationId(); Mono systemInfoPopulatedExecuteActionDTOMono = actionExecutionSolutionHelper.populateExecuteActionDTOWithSystemInfo(executeActionDTO); return systemInfoPopulatedExecuteActionDTOMono.flatMap(populatedExecuteActionDTO -> Mono.zip( - instanceIdMono, defaultTenantIdMono) + instanceIdMono, defaultOrganizationIdMono) .map(tuple -> { String instanceId = tuple.getT1(); - String tenantId = tuple.getT2(); + String organizationId = tuple.getT2(); populatedExecuteActionDTO.setActionId(newAction.getId()); populatedExecuteActionDTO.setWorkspaceId(newAction.getWorkspaceId()); if (TRUE.equals(executeActionDTO.getViewMode())) { @@ -272,7 +272,7 @@ private Mono populateExecuteActionDTO(ExecuteActionDTO execute newAction.getUnpublishedAction().getDatasource().getId()); } populatedExecuteActionDTO.setInstanceId(instanceId); - populatedExecuteActionDTO.setTenantId(tenantId); + populatedExecuteActionDTO.setOrganizationId(organizationId); return populatedExecuteActionDTO; })); } @@ -731,8 +731,10 @@ protected Mono verifyDatasourceAndMakeRequest( // Now that we have the context (connection details), execute the action. Instant requestedAt = Instant.now(); - Map features = featureFlagService.getCachedTenantFeatureFlags() != null - ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + Map features = featureFlagService.getCachedOrganizationFeatureFlags() != null + ? featureFlagService + .getCachedOrganizationFeatureFlags() + .getFeatures() : Collections.emptyMap(); // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java index b73dc33a26de..b934b4d0841b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java @@ -18,7 +18,7 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.DatasourceStructureSolution; import com.appsmith.server.solutions.EnvironmentPermission; @@ -54,7 +54,7 @@ public class DatasourceTriggerSolutionCEImpl implements DatasourceTriggerSolutio private final DatasourcePermission datasourcePermission; private final EnvironmentPermission environmentPermission; private final ConfigService configService; - private final TenantService tenantService; + private final OrganizationService organizationService; private final FeatureFlagService featureFlagService; public Mono trigger( @@ -110,8 +110,10 @@ public Mono trigger( // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag // Once thoroughly tested, this flag can be removed - Map featureFlagMap = featureFlagService.getCachedTenantFeatureFlags() != null - ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + Map featureFlagMap = featureFlagService.getCachedOrganizationFeatureFlags() != null + ? featureFlagService + .getCachedOrganizationFeatureFlags() + .getFeatures() : Collections.emptyMap(); return datasourceContextService @@ -164,11 +166,11 @@ public Mono trigger( private Mono populateTriggerRequestDto( TriggerRequestDTO triggerRequestDTO, Datasource datasource) { - return tenantService - .getDefaultTenantId() + return organizationService + .getDefaultOrganizationId() .zipWith(configService.getInstanceId()) .map(tuple -> { - triggerRequestDTO.setTenantId(tuple.getT1()); + triggerRequestDTO.setOrganizationId(tuple.getT1()); triggerRequestDTO.setInstanceId(tuple.getT2()); triggerRequestDTO.setWorkspaceId(datasource.getWorkspaceId()); return triggerRequestDTO; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java index af74b26950ed..72528b88a9b8 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/EnvManagerCEImpl.java @@ -7,8 +7,8 @@ import com.appsmith.server.configurations.GoogleRecaptchaConfig; import com.appsmith.server.constants.EnvVariables; import com.appsmith.server.constants.FieldName; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.dtos.TestEmailConfigRequestDTO; import com.appsmith.server.exceptions.AppsmithError; @@ -24,9 +24,9 @@ import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PermissionGroupService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserService; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; @@ -108,7 +108,7 @@ public class EnvManagerCEImpl implements EnvManagerCE { private final UserUtils userUtils; - private final TenantService tenantService; + private final OrganizationService organizationService; private final ObjectMapper objectMapper; @@ -138,7 +138,7 @@ public EnvManagerCEImpl( PermissionGroupService permissionGroupService, ConfigService configService, UserUtils userUtils, - TenantService tenantService, + OrganizationService organizationService, ObjectMapper objectMapper, EmailService emailService) { @@ -155,7 +155,7 @@ public EnvManagerCEImpl( this.permissionGroupService = permissionGroupService; this.configService = configService; this.userUtils = userUtils; - this.tenantService = tenantService; + this.organizationService = organizationService; this.objectMapper = objectMapper; this.emailService = emailService; } @@ -172,12 +172,13 @@ public EnvManagerCEImpl( @Override public List transformEnvContent(String envContent, Map changes) { final Set variablesNotInWhitelist = new HashSet<>(changes.keySet()); - final Set tenantConfigWhitelist = allowedTenantConfiguration(); + final Set organizationConfigWhitelist = allowedOrganizationConfiguration(); - // We remove all the variables that aren't defined in our env variable whitelist or in the TenantConfiguration - // class. This is because the configuration can be saved either in the .env file or the tenant collection + // We remove all the variables that aren't defined in our env variable whitelist or in the + // OrganizationConfiguration + // class. This is because the configuration can be saved either in the .env file or the organization collection variablesNotInWhitelist.removeAll(VARIABLE_WHITELIST); - variablesNotInWhitelist.removeAll(tenantConfigWhitelist); + variablesNotInWhitelist.removeAll(organizationConfigWhitelist); if (!variablesNotInWhitelist.isEmpty()) { throw new AppsmithException(AppsmithError.GENERIC_BAD_REQUEST); @@ -263,7 +264,7 @@ private String unescapeFromShell(String input) { return valueBuilder.toString(); } - // Expect user object to be null when this method is getting called to run the tenant specific migrations without + // Expect user object to be null when this method is getting called to run the org specific migrations without // user context private Mono validateChanges(User user, Map changes) { if (changes.containsKey(APPSMITH_ADMIN_EMAILS.name())) { @@ -284,12 +285,12 @@ private Mono validateChanges(User user, Map changes) { } /** - * This function returns a set of String based on the JsonProperty annotations in the TenantConfiguration class + * This function returns a set of String based on the JsonProperty annotations in the OrganizationConfiguration class * * @return */ - private Set allowedTenantConfiguration() { - return AppsmithBeanUtils.getAllFields(TenantConfiguration.class) + private Set allowedOrganizationConfiguration() { + return AppsmithBeanUtils.getAllFields(OrganizationConfiguration.class) .map(field -> { JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class); return jsonProperty == null ? field.getName() : jsonProperty.value(); @@ -298,57 +299,61 @@ private Set allowedTenantConfiguration() { } /** - * This function sets the value in the TenantConfiguration object based on the JsonProperty annotation of the field + * This function sets the value in the OrganizationConfiguration object based on the JsonProperty annotation of the field * The key must be exactly equal to the json annotation * - * @param tenantConfiguration + * @param organizationConfiguration * @param key * @param value */ - private void setConfigurationByKey(TenantConfiguration tenantConfiguration, String key, String value) { - Stream fieldStream = AppsmithBeanUtils.getAllFields(TenantConfiguration.class); + private void setConfigurationByKey(OrganizationConfiguration organizationConfiguration, String key, String value) { + Stream fieldStream = AppsmithBeanUtils.getAllFields(OrganizationConfiguration.class); fieldStream.forEach(field -> { JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class); if (jsonProperty != null && jsonProperty.value().equals(key)) { try { field.setAccessible(true); Object typedValue = ConvertUtils.convert(value, field.getType()); - field.set(tenantConfiguration, typedValue); + field.set(organizationConfiguration, typedValue); } catch (IllegalAccessException e) { // Catch the error, log it and then do nothing. log.error( - "Got error while parsing the JSON annotations from TenantConfiguration class. Cause: ", e); + "Got error while parsing the JSON annotations from OrganizationConfiguration class. Cause: ", + e); } } else if (field.getName().equals(key)) { try { field.setAccessible(true); Object typedValue = ConvertUtils.convert(value, field.getType()); - field.set(tenantConfiguration, typedValue); + field.set(organizationConfiguration, typedValue); } catch (IllegalAccessException e) { // Catch the error, log it and then do nothing. - log.error("Got error while attempting to save property to TenantConfiguration class. Cause: ", e); + log.error( + "Got error while attempting to save property to OrganizationConfiguration class. Cause: ", + e); } } }); } - private Mono updateTenantConfiguration(String tenantId, Map changes) { - TenantConfiguration tenantConfiguration = new TenantConfiguration(); - // Write the changes to the tenant collection in configuration field + private Mono updateOrganizationConfiguration(String organizationId, Map changes) { + OrganizationConfiguration organizationConfiguration = new OrganizationConfiguration(); + // Write the changes to the organization collection in configuration field return Flux.fromIterable(changes.entrySet()) .map(map -> { String key = map.getKey(); String value = map.getValue(); - setConfigurationByKey(tenantConfiguration, key, value); + setConfigurationByKey(organizationConfiguration, key, value); return map; }) - .then(Mono.just(tenantConfiguration)) - .flatMap(updatedTenantConfig -> tenantService.updateTenantConfiguration(tenantId, tenantConfiguration)); + .then(Mono.just(organizationConfiguration)) + .flatMap(updatedOrganizationConfig -> + organizationService.updateOrganizationConfiguration(organizationId, organizationConfiguration)); } @Override public Mono applyChanges(Map changes, String originHeader) { - // This flow is pertinent for any variables that need to change in the .env file or be saved in the tenant + // This flow is pertinent for any variables that need to change in the .env file or be saved in the organization // configuration return verifyCurrentUserIsSuper() .flatMap(user -> validateChanges(user, changes).thenReturn(user)) @@ -356,8 +361,8 @@ public Mono applyChanges(Map changes, String originHeader) // For configuration variables, save the variables to the config collection instead of .env file // We ideally want to migrate all variables from .env file to the config collection for better // scalability - // Write the changes to the tenant collection in configuration field - .flatMap(originalVariables -> updateTenantConfiguration(user.getTenantId(), changes) + // Write the changes to the organization collection in configuration field + .flatMap(originalVariables -> updateOrganizationConfiguration(user.getOrganizationId(), changes) .then(sendAnalyticsEvent(user, originalVariables, changes)) .thenReturn(originalVariables))) .flatMap(originalValues -> { @@ -453,9 +458,9 @@ public Mono> applyChangesToEnvFileWithoutAclCheck(Map originalVariables = parseToMap(originalContent); final Map envFileChanges = new HashMap<>(changes); - final Set tenantConfigurationKeys = allowedTenantConfiguration(); + final Set organizationConfigurationKeys = allowedOrganizationConfiguration(); for (final String key : changes.keySet()) { - if (tenantConfigurationKeys.contains(key)) { + if (organizationConfigurationKeys.contains(key)) { envFileChanges.remove(key); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java index 9d385f2655fb..d34cd294fb4e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ScheduledTaskCEImpl.java @@ -2,7 +2,7 @@ import com.appsmith.server.helpers.LoadShifter; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import io.micrometer.observation.annotation.Observed; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -16,19 +16,19 @@ public class ScheduledTaskCEImpl implements ScheduledTaskCE { private final FeatureFlagService featureFlagService; - private final TenantService tenantService; + private final OrganizationService organizationService; @Scheduled(initialDelay = 10 * 1000 /* ten seconds */, fixedRate = 30 * 60 * 1000 /* thirty minutes */) @Observed(name = "fetchFeatures") public void fetchFeatures() { - log.info("Fetching features for default tenant"); + log.info("Fetching features for default organization"); featureFlagService - .getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations() - .then(tenantService - .getDefaultTenant() - .flatMap(featureFlagService::checkAndExecuteMigrationsForTenantFeatureFlags) - .then(tenantService.restartTenant())) - .doOnError(error -> log.error("Error while fetching tenant feature flags", error)) + .getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations() + .then(organizationService + .getDefaultOrganization() + .flatMap(featureFlagService::checkAndExecuteMigrationsForOrganizationFeatureFlags) + .then(organizationService.restartOrganization())) + .doOnError(error -> log.error("Error while fetching organization feature flags", error)) .subscribeOn(LoadShifter.elasticScheduler) .subscribe(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/UserSignupCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/UserSignupCEImpl.java index b60a7faae798..80cc7ae6827d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/UserSignupCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/UserSignupCEImpl.java @@ -4,8 +4,8 @@ import com.appsmith.server.authentication.handlers.AuthenticationSuccessHandler; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.LoginSource; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserData; import com.appsmith.server.domains.UserState; @@ -20,7 +20,7 @@ import com.appsmith.server.services.CaptchaService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.solutions.EnvManager; @@ -59,9 +59,9 @@ import static com.appsmith.server.constants.ce.FieldNameCE.DEFAULT; import static com.appsmith.server.constants.ce.FieldNameCE.EMAIL; import static com.appsmith.server.constants.ce.FieldNameCE.NAME; +import static com.appsmith.server.constants.ce.FieldNameCE.ORGANIZATION; import static com.appsmith.server.constants.ce.FieldNameCE.PROFICIENCY; import static com.appsmith.server.constants.ce.FieldNameCE.ROLE; -import static com.appsmith.server.constants.ce.FieldNameCE.TENANT; import static com.appsmith.server.helpers.RedirectHelper.REDIRECT_URL_QUERY_PARAM; import static com.appsmith.server.helpers.ValidationUtils.LOGIN_PASSWORD_MAX_LENGTH; import static com.appsmith.server.helpers.ValidationUtils.LOGIN_PASSWORD_MIN_LENGTH; @@ -82,7 +82,7 @@ public class UserSignupCEImpl implements UserSignupCE { private final UserUtils userUtils; private final NetworkUtils networkUtils; private final EmailService emailService; - private final TenantService tenantService; + private final OrganizationService organizationService; private static final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy(); @@ -99,7 +99,7 @@ public UserSignupCEImpl( UserUtils userUtils, NetworkUtils networkUtils, EmailService emailService, - TenantService tenantService) { + OrganizationService organizationService) { this.userService = userService; this.userDataService = userDataService; @@ -111,7 +111,7 @@ public UserSignupCEImpl( this.userUtils = userUtils; this.networkUtils = networkUtils; this.emailService = emailService; - this.tenantService = tenantService; + this.organizationService = organizationService; } /** @@ -130,16 +130,17 @@ public Mono signupAndLogin(User user, ServerWebExchange exchange) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, EMAIL)); } - Mono tenantMono = tenantService - .getDefaultTenant() - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, DEFAULT, TENANT))); + Mono organizationMono = organizationService + .getDefaultOrganization() + .switchIfEmpty( + Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, DEFAULT, ORGANIZATION))); - // - Only creating user if the password strength is acceptable as per the tenant policy + // - Only creating user if the password strength is acceptable as per the organization policy // - Welcome email will be sent post user email verification - Mono createUserMono = tenantMono.flatMap(tenant -> { - TenantConfiguration tenantConfiguration = tenant.getTenantConfiguration(); - boolean isStrongPasswordPolicyEnabled = tenantConfiguration != null - && Boolean.TRUE.equals(tenantConfiguration.getIsStrongPasswordPolicyEnabled()); + Mono createUserMono = organizationMono.flatMap(organization -> { + OrganizationConfiguration organizationConfiguration = organization.getOrganizationConfiguration(); + boolean isStrongPasswordPolicyEnabled = organizationConfiguration != null + && Boolean.TRUE.equals(organizationConfiguration.getIsStrongPasswordPolicyEnabled()); if (!validateUserPassword(user.getPassword(), isStrongPasswordPolicyEnabled)) { return isStrongPasswordPolicyEnabled diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspectTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspectTest.java index 2158670c2b2d..49c8607bc577 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspectTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/FeatureFlaggedMethodInvokerAspectTest.java @@ -37,12 +37,12 @@ class FeatureFlaggedMethodInvokerAspectTest { @BeforeEach void setUp() { - Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.TENANT_TEST_FEATURE))) + Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE))) .thenReturn(Mono.just(false)); CachedFeatures cachedFeatures = new CachedFeatures(); - cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.TENANT_TEST_FEATURE.name(), Boolean.FALSE)); - Mockito.when(featureFlagService.getCachedTenantFeatureFlags()).thenReturn(cachedFeatures); + cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE.name(), Boolean.FALSE)); + Mockito.when(featureFlagService.getCachedOrganizationFeatureFlags()).thenReturn(cachedFeatures); } @Test @@ -53,7 +53,7 @@ void testEEOnlyMethod() { @Test void eeCeCompatibleDiffMethod_eeImplTest() { - Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.TENANT_TEST_FEATURE))) + Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE))) .thenReturn(Mono.just(true)); Mono resultMono = testComponent.eeCeCompatibleDiffMethod(); StepVerifier.create(resultMono).expectNext(EE_RESPONSE).verifyComplete(); @@ -86,7 +86,7 @@ void ceEeDiffMethod_ceImplTest() { @Test void ceEeDiffMethod_eeImplTest() { - Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.TENANT_TEST_FEATURE))) + Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE))) .thenReturn(Mono.just(true)); Mono resultMono = testComponent.ceEeDiffMethod(); StepVerifier.create(resultMono).expectNext(EE_RESPONSE).verifyComplete(); @@ -94,7 +94,7 @@ void ceEeDiffMethod_eeImplTest() { @Test void ceEeDiffMethodReturnsFlux_eeImplTest() { - Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.TENANT_TEST_FEATURE))) + Mockito.when(featureFlagService.check(eq(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE))) .thenReturn(Mono.just(true)); Flux resultFlux = testComponent.ceEeDiffMethodReturnsFlux(); StepVerifier.create(resultFlux).expectNext("ee", "impl", "method").verifyComplete(); @@ -109,8 +109,8 @@ void ceEeDiffMethodReturnsFlux_ceImplTest() { @Test void ceEeSyncMethod_eeImplTest() { CachedFeatures cachedFeatures = new CachedFeatures(); - cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.TENANT_TEST_FEATURE.name(), Boolean.TRUE)); - Mockito.when(featureFlagService.getCachedTenantFeatureFlags()).thenReturn(cachedFeatures); + cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE.name(), Boolean.TRUE)); + Mockito.when(featureFlagService.getCachedOrganizationFeatureFlags()).thenReturn(cachedFeatures); String result = testComponent.ceEeSyncMethod("arg_"); assertEquals("arg_ee_impl_method", result); } @@ -124,8 +124,8 @@ void ceEeSyncMethod_ceImplTest() { @Test void ceEeThrowAppsmithException_eeImplTest() { CachedFeatures cachedFeatures = new CachedFeatures(); - cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.TENANT_TEST_FEATURE.name(), Boolean.TRUE)); - Mockito.when(featureFlagService.getCachedTenantFeatureFlags()).thenReturn(cachedFeatures); + cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE.name(), Boolean.TRUE)); + Mockito.when(featureFlagService.getCachedOrganizationFeatureFlags()).thenReturn(cachedFeatures); assertThrows( AppsmithException.class, () -> testComponent.ceEeThrowAppsmithException("arg_"), @@ -135,8 +135,8 @@ void ceEeThrowAppsmithException_eeImplTest() { @Test void ceEeThrowNonAppsmithException_eeImplTest_throwExceptionFromAspect() { CachedFeatures cachedFeatures = new CachedFeatures(); - cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.TENANT_TEST_FEATURE.name(), Boolean.TRUE)); - Mockito.when(featureFlagService.getCachedTenantFeatureFlags()).thenReturn(cachedFeatures); + cachedFeatures.setFeatures(Map.of(FeatureFlagEnum.ORGANIZATION_TEST_FEATURE.name(), Boolean.TRUE)); + Mockito.when(featureFlagService.getCachedOrganizationFeatureFlags()).thenReturn(cachedFeatures); assertThrows( AppsmithException.class, () -> testComponent.ceEeThrowNonAppsmithException("arg_"), diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/component/TestComponentImpl.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/component/TestComponentImpl.java index 3da1b574d1c0..373e0eabf195 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/component/TestComponentImpl.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/aspect/component/TestComponentImpl.java @@ -19,19 +19,19 @@ public Mono eeOnlyMethod() { return Mono.just("ee_impl_method"); } - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) @Override public Mono ceEeDiffMethod() { return Mono.just("ee_impl_method"); } - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) @Override public Mono eeCeCompatibleDiffMethod() { return Mono.just("ee_impl_method"); } - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) @Override public Flux ceEeDiffMethodReturnsFlux() { List result = List.of("ee", "impl", "method"); @@ -39,19 +39,19 @@ public Flux ceEeDiffMethodReturnsFlux() { } @Override - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) public String ceEeSyncMethod(String arg) { return arg + "ee_impl_method"; } @Override - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) public void ceEeThrowAppsmithException(String arg) { throw new AppsmithException(AppsmithError.GENERIC_BAD_REQUEST, "This is a test exception"); } @Override - @FeatureFlagged(featureFlagName = FeatureFlagEnum.TENANT_TEST_FEATURE) + @FeatureFlagged(featureFlagName = FeatureFlagEnum.ORGANIZATION_TEST_FEATURE) public void ceEeThrowNonAppsmithException(String arg) { throw new RuntimeException("This is a test exception"); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java index 98b1dbd01151..8fec8a1f87ba 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/configurations/SeedMongoData.java @@ -2,16 +2,16 @@ import com.appsmith.external.models.PluginType; import com.appsmith.external.models.Policy; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.PermissionGroup; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.PricingPlan; -import com.appsmith.server.domains.Tenant; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserState; import com.appsmith.server.dtos.Permission; +import com.appsmith.server.repositories.OrganizationRepository; import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.repositories.PluginRepository; -import com.appsmith.server.repositories.TenantRepository; import com.appsmith.server.repositories.UserRepository; import com.appsmith.server.repositories.WorkspaceRepository; import com.appsmith.server.solutions.PolicySolution; @@ -40,7 +40,7 @@ ApplicationRunner init( UserRepository userRepository, WorkspaceRepository workspaceRepository, PluginRepository pluginRepository, - TenantRepository tenantRepository, + OrganizationRepository organizationRepository, PermissionGroupRepository permissionGroupRepository, PolicySolution policySolution) { @@ -117,29 +117,29 @@ ApplicationRunner init( }) .flatMap(pluginRepository::save); - Tenant defaultTenant = new Tenant(); - defaultTenant.setDisplayName("Default"); - defaultTenant.setSlug("default"); - defaultTenant.setPricingPlan(PricingPlan.FREE); + Organization defaultOrganization = new Organization(); + defaultOrganization.setDisplayName("Default"); + defaultOrganization.setSlug("default"); + defaultOrganization.setPricingPlan(PricingPlan.FREE); - Mono defaultTenantId = tenantRepository + Mono defaultOrganizationId = organizationRepository .findBySlug("default") - .switchIfEmpty(tenantRepository.save(defaultTenant)) - .map(Tenant::getId) + .switchIfEmpty(organizationRepository.save(defaultOrganization)) + .map(Organization::getId) .cache(); Flux userFlux = Flux.just(userData) - .zipWith(defaultTenantId.repeat()) + .zipWith(defaultOrganizationId.repeat()) .flatMap(tuple -> { Object[] array = tuple.getT1(); - String tenantId = tuple.getT2(); + String organizationId = tuple.getT2(); log.debug("Going to create bare users"); User user = new User(); user.setName((String) array[0]); user.setEmail((String) array[1]); user.setState((UserState) array[2]); user.setPolicies((Set) array[3]); - user.setTenantId(tenantId); + user.setOrganizationId(organizationId); return userRepository.save(user); }) .flatMap(user -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/domains/EqualityTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/domains/EqualityTest.java index ff0476e4cbed..9068612b2659 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/domains/EqualityTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/domains/EqualityTest.java @@ -19,6 +19,7 @@ public class EqualityTest { private final Set> TESTED_CLASSES = Set.of( // Note: Adding a class here means that we have a test for its equality in this file. ApplicationDetail.class, + OrganizationConfiguration.class, TenantConfiguration.class, Application.AppLayout.class, Application.EmbedSetting.class, @@ -50,12 +51,12 @@ void testAffirmation() { } @Test - void testTenantConfiguration() { - TenantConfiguration c1 = new TenantConfiguration(); + void testOrganizationConfiguration() { + OrganizationConfiguration c1 = new OrganizationConfiguration(); c1.setEmailVerificationEnabled(true); - TenantConfiguration c2 = new TenantConfiguration(); + OrganizationConfiguration c2 = new OrganizationConfiguration(); c2.setEmailVerificationEnabled(true); - TenantConfiguration c3 = new TenantConfiguration(); + OrganizationConfiguration c3 = new OrganizationConfiguration(); c3.setEmailVerificationEnabled(false); assertThat(c1).isEqualTo(c2).isNotEqualTo(c3); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/FeatureFlagMigrationHelperTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/FeatureFlagMigrationHelperTest.java index f9553860e6d0..b55cfc9b9b53 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/FeatureFlagMigrationHelperTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/FeatureFlagMigrationHelperTest.java @@ -2,8 +2,8 @@ import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.server.constants.FeatureMigrationType; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.featureflags.CachedFeatures; import com.appsmith.server.services.CacheableFeatureFlagHelper; import org.junit.jupiter.api.BeforeEach; @@ -21,7 +21,7 @@ import java.util.Map; import java.util.UUID; -import static com.appsmith.external.enums.FeatureFlagEnum.TENANT_TEST_FEATURE; +import static com.appsmith.external.enums.FeatureFlagEnum.ORGANIZATION_TEST_FEATURE; import static com.appsmith.server.constants.FeatureMigrationType.DISABLE; import static com.appsmith.server.constants.FeatureMigrationType.ENABLE; import static com.appsmith.server.constants.MigrationStatus.PENDING; @@ -42,37 +42,37 @@ void setUp() {} @Test void getUpdatedFlagsWithPendingMigration_diffForExistingAndLatestFlag_pendingMigrationReportedWithDisableStatus() { - Tenant defaultTenant = new Tenant(); - defaultTenant.setId(UUID.randomUUID().toString()); - defaultTenant.setTenantConfiguration(new TenantConfiguration()); + Organization defaultOrganization = new Organization(); + defaultOrganization.setId(UUID.randomUUID().toString()); + defaultOrganization.setOrganizationConfiguration(new OrganizationConfiguration()); CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), true); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.DAYS)); CachedFeatures latestCachedFeatures = new CachedFeatures(); Map latestFeatureMap = new HashMap<>(); - latestFeatureMap.put(TENANT_TEST_FEATURE.name(), false); + latestFeatureMap.put(ORGANIZATION_TEST_FEATURE.name(), false); latestCachedFeatures.setFeatures(latestFeatureMap); latestCachedFeatures.setRefreshedAt(Instant.now()); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)) .thenReturn(Mono.just(latestCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.evictCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(any())) .thenReturn(Mono.empty()); Mono> getUpdatedFlagsWithPendingMigration = - featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultTenant); + featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultOrganization); StepVerifier.create(getUpdatedFlagsWithPendingMigration) .assertNext(featureFlagEnumFeatureMigrationTypeMap -> { assertThat(featureFlagEnumFeatureMigrationTypeMap).isNotEmpty(); assertThat(featureFlagEnumFeatureMigrationTypeMap).hasSize(1); - assertThat(featureFlagEnumFeatureMigrationTypeMap.get(TENANT_TEST_FEATURE)) + assertThat(featureFlagEnumFeatureMigrationTypeMap.get(ORGANIZATION_TEST_FEATURE)) .isEqualTo(DISABLE); }) .verifyComplete(); @@ -80,37 +80,37 @@ void getUpdatedFlagsWithPendingMigration_diffForExistingAndLatestFlag_pendingMig @Test void getUpdatedFlagsWithPendingMigration_diffForExistingAndLatestFlag_pendingMigrationReportedWithEnableStatus() { - Tenant defaultTenant = new Tenant(); - defaultTenant.setId(UUID.randomUUID().toString()); - defaultTenant.setTenantConfiguration(new TenantConfiguration()); + Organization defaultOrganization = new Organization(); + defaultOrganization.setId(UUID.randomUUID().toString()); + defaultOrganization.setOrganizationConfiguration(new OrganizationConfiguration()); CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), false); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), false); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.DAYS)); CachedFeatures latestCachedFeatures = new CachedFeatures(); Map latestFeatureMap = new HashMap<>(); - latestFeatureMap.put(TENANT_TEST_FEATURE.name(), true); + latestFeatureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); latestCachedFeatures.setFeatures(latestFeatureMap); latestCachedFeatures.setRefreshedAt(Instant.now()); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)) .thenReturn(Mono.just(latestCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.evictCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(any())) .thenReturn(Mono.empty()); Mono> getUpdatedFlagsWithPendingMigration = - featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultTenant); + featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultOrganization); StepVerifier.create(getUpdatedFlagsWithPendingMigration) .assertNext(featureFlagEnumFeatureMigrationTypeMap -> { assertThat(featureFlagEnumFeatureMigrationTypeMap).isNotEmpty(); assertThat(featureFlagEnumFeatureMigrationTypeMap).hasSize(1); - assertThat(featureFlagEnumFeatureMigrationTypeMap.get(TENANT_TEST_FEATURE)) + assertThat(featureFlagEnumFeatureMigrationTypeMap.get(ORGANIZATION_TEST_FEATURE)) .isEqualTo(ENABLE); }) .verifyComplete(); @@ -118,24 +118,24 @@ void getUpdatedFlagsWithPendingMigration_diffForExistingAndLatestFlag_pendingMig @Test void getUpdatedFlagsWithPendingMigration_noDiffForExistingAndLatestFlag_noPendingMigrations() { - Tenant defaultTenant = new Tenant(); - defaultTenant.setId(UUID.randomUUID().toString()); - defaultTenant.setTenantConfiguration(new TenantConfiguration()); + Organization defaultOrganization = new Organization(); + defaultOrganization.setId(UUID.randomUUID().toString()); + defaultOrganization.setOrganizationConfiguration(new OrganizationConfiguration()); CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), true); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.HOURS)); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.evictCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(any())) .thenReturn(Mono.empty()); Mono> getUpdatedFlagsWithPendingMigration = - featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultTenant); + featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultOrganization); StepVerifier.create(getUpdatedFlagsWithPendingMigration) .assertNext(featureFlagEnumFeatureMigrationTypeMap -> { @@ -147,14 +147,14 @@ void getUpdatedFlagsWithPendingMigration_noDiffForExistingAndLatestFlag_noPendin } @Test - void getUpdatedFlagsWithPendingMigration_fetchTenantFlagsFailedFromCS_pendingMigrationReported() { - Tenant defaultTenant = new Tenant(); - defaultTenant.setId(UUID.randomUUID().toString()); - defaultTenant.setTenantConfiguration(new TenantConfiguration()); + void getUpdatedFlagsWithPendingMigration_fetchOrganizationFlagsFailedFromCS_pendingMigrationReported() { + Organization defaultOrganization = new Organization(); + defaultOrganization.setId(UUID.randomUUID().toString()); + defaultOrganization.setOrganizationConfiguration(new OrganizationConfiguration()); CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), true); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.HOURS)); @@ -162,18 +162,18 @@ void getUpdatedFlagsWithPendingMigration_fetchTenantFlagsFailedFromCS_pendingMig existingCachedFeatures.setFeatures(new HashMap<>()); existingCachedFeatures.setRefreshedAt(Instant.now()); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)) .thenReturn(Mono.just(latestCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.updateCachedTenantFeatures(any(), any())) + Mockito.when(cacheableFeatureFlagHelper.updateCachedOrganizationFeatures(any(), any())) .thenReturn(Mono.just(existingCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.evictCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(any())) .thenReturn(Mono.empty()); Mono> getUpdatedFlagsWithPendingMigration = - featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultTenant); + featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultOrganization); StepVerifier.create(getUpdatedFlagsWithPendingMigration) .assertNext(featureFlagEnumFeatureMigrationTypeMap -> { @@ -186,9 +186,9 @@ void getUpdatedFlagsWithPendingMigration_fetchTenantFlagsFailedFromCS_pendingMig @Test void checkAndExecuteMigrationsForFeatureFlag_nullFeatureFlag_success() { - Tenant defaultTenant = new Tenant(); + Organization defaultOrganization = new Organization(); Mono resultMono = - featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(defaultTenant, null); + featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(defaultOrganization, null); StepVerifier.create(resultMono) .assertNext(result -> assertThat(result).isTrue()) .verifyComplete(); @@ -196,28 +196,28 @@ void checkAndExecuteMigrationsForFeatureFlag_nullFeatureFlag_success() { @Test void checkAndExecuteMigrationsForFeatureFlag_validFeatureFlag_success() { - Tenant defaultTenant = new Tenant(); - TenantConfiguration tenantConfiguration = new TenantConfiguration(); - tenantConfiguration.setFeaturesWithPendingMigration(Map.of(TENANT_TEST_FEATURE, ENABLE)); - tenantConfiguration.setMigrationStatus(PENDING); - defaultTenant.setTenantConfiguration(tenantConfiguration); + Organization defaultOrganization = new Organization(); + OrganizationConfiguration organizationConfiguration = new OrganizationConfiguration(); + organizationConfiguration.setFeaturesWithPendingMigration(Map.of(ORGANIZATION_TEST_FEATURE, ENABLE)); + organizationConfiguration.setMigrationStatus(PENDING); + defaultOrganization.setOrganizationConfiguration(organizationConfiguration); CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), true); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.HOURS)); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)); - Mono resultMono = - featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(defaultTenant, TENANT_TEST_FEATURE); + Mono resultMono = featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag( + defaultOrganization, ORGANIZATION_TEST_FEATURE); StepVerifier.create(resultMono) .assertNext(result -> { assertThat(result).isTrue(); - assertThat(tenantConfiguration.getFeaturesWithPendingMigration()) + assertThat(organizationConfiguration.getFeaturesWithPendingMigration()) .hasSize(1); - assertThat(tenantConfiguration.getMigrationStatus()).isEqualTo(PENDING); + assertThat(organizationConfiguration.getMigrationStatus()).isEqualTo(PENDING); }) .verifyComplete(); } @@ -228,36 +228,36 @@ void checkAndExecuteMigrationsForFeatureFlag_validFeatureFlag_success() { // Mock DB state to have the feature flag in pending migration list with DISABLE status which means the feature // flag flipped from true to false - Tenant defaultTenant = new Tenant(); - defaultTenant.setId(UUID.randomUUID().toString()); - TenantConfiguration tenantConfiguration = new TenantConfiguration(); - tenantConfiguration.setFeaturesWithPendingMigration(Map.of(TENANT_TEST_FEATURE, DISABLE)); - defaultTenant.setTenantConfiguration(tenantConfiguration); + Organization defaultOrganization = new Organization(); + defaultOrganization.setId(UUID.randomUUID().toString()); + OrganizationConfiguration organizationConfiguration = new OrganizationConfiguration(); + organizationConfiguration.setFeaturesWithPendingMigration(Map.of(ORGANIZATION_TEST_FEATURE, DISABLE)); + defaultOrganization.setOrganizationConfiguration(organizationConfiguration); // Mock CS calls to fetch the feature flags to have the feature flag in pending migration list with ENABLE // status // This means the feature flag flipped from false to true again with latest check CachedFeatures existingCachedFeatures = new CachedFeatures(); Map featureMap = new HashMap<>(); - featureMap.put(TENANT_TEST_FEATURE.name(), false); + featureMap.put(ORGANIZATION_TEST_FEATURE.name(), false); existingCachedFeatures.setFeatures(featureMap); existingCachedFeatures.setRefreshedAt(Instant.now().minus(1, ChronoUnit.DAYS)); CachedFeatures latestCachedFeatures = new CachedFeatures(); Map latestFeatureMap = new HashMap<>(); - latestFeatureMap.put(TENANT_TEST_FEATURE.name(), true); + latestFeatureMap.put(ORGANIZATION_TEST_FEATURE.name(), true); latestCachedFeatures.setFeatures(latestFeatureMap); latestCachedFeatures.setRefreshedAt(Instant.now()); - Mockito.when(cacheableFeatureFlagHelper.fetchCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(any())) .thenReturn(Mono.just(existingCachedFeatures)) .thenReturn(Mono.just(latestCachedFeatures)); - Mockito.when(cacheableFeatureFlagHelper.evictCachedTenantFeatures(any())) + Mockito.when(cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(any())) .thenReturn(Mono.empty()); Mono> getUpdatedFlagsWithPendingMigration = - featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultTenant); + featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(defaultOrganization); StepVerifier.create(getUpdatedFlagsWithPendingMigration) .assertNext(featureFlagEnumFeatureMigrationTypeMap -> { diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/MockCacheableFeatureFlagHelper.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/MockCacheableFeatureFlagHelper.java index 8e4199ba0bc5..689257da3700 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/MockCacheableFeatureFlagHelper.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/MockCacheableFeatureFlagHelper.java @@ -17,7 +17,7 @@ import java.util.HashMap; import java.util.Map; -import static com.appsmith.external.enums.FeatureFlagEnum.TENANT_TEST_FEATURE; +import static com.appsmith.external.enums.FeatureFlagEnum.ORGANIZATION_TEST_FEATURE; import static com.appsmith.external.enums.FeatureFlagEnum.TEST_FEATURE_1; import static com.appsmith.external.enums.FeatureFlagEnum.TEST_FEATURE_2; @@ -50,10 +50,10 @@ public Mono evictUserCachedFlags(String userIdentifier) { return Mono.empty(); } - @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @Cache(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono fetchCachedTenantFeatures(String tenantId) { - return getRemoteFeaturesForTenant(new FeaturesRequestDTO()).map(responseDTO -> { + public Mono fetchCachedOrganizationFeatures(String organizationId) { + return getRemoteFeaturesForOrganization(new FeaturesRequestDTO()).map(responseDTO -> { CachedFeatures cachedFeatures = new CachedFeatures(); cachedFeatures.setRefreshedAt(Instant.now()); cachedFeatures.setFeatures(responseDTO.getFeatures()); @@ -61,23 +61,23 @@ public Mono fetchCachedTenantFeatures(String tenantId) { }); } - @Cache(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @Cache(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono updateCachedTenantFeatures(String tenantId, CachedFeatures cachedFeatures) { + public Mono updateCachedOrganizationFeatures(String organizationId, CachedFeatures cachedFeatures) { return Mono.just(cachedFeatures); } - @CacheEvict(cacheName = "tenantNewFeatures", key = "{#tenantId}") + @CacheEvict(cacheName = "organizationNewFeatures", key = "{#organizationId}") @Override - public Mono evictCachedTenantFeatures(String tenantId) { + public Mono evictCachedOrganizationFeatures(String organizationId) { return Mono.empty(); } @Override - public Mono getRemoteFeaturesForTenant(FeaturesRequestDTO featuresRequestDTO) { + public Mono getRemoteFeaturesForOrganization(FeaturesRequestDTO featuresRequestDTO) { FeaturesResponseDTO responseDTO = new FeaturesResponseDTO(); Map features = new HashMap<>(); - features.put(TENANT_TEST_FEATURE.name(), true); + features.put(ORGANIZATION_TEST_FEATURE.name(), true); responseDTO.setFeatures(features); return Mono.just(responseDTO); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/EmailServiceHelperCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/EmailServiceHelperCETest.java index b4d3e67c91c7..e10befb4c39a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/EmailServiceHelperCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/helpers/ce/EmailServiceHelperCETest.java @@ -1,7 +1,7 @@ package com.appsmith.server.helpers.ce; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.services.OrganizationService; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -19,7 +19,6 @@ import static com.appsmith.server.constants.ce.EmailConstantsCE.INVITE_WORKSPACE_TEMPLATE_EXISTING_USER_CE; import static com.appsmith.server.constants.ce.EmailConstantsCE.INVITE_WORKSPACE_TEMPLATE_NEW_USER_CE; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; @SpringBootTest class EmailServiceHelperCETest { @@ -28,14 +27,15 @@ class EmailServiceHelperCETest { @Qualifier("emailServiceHelperCEImpl") private EmailServiceHelperCE emailServiceHelperCE; @Autowired - TenantService tenantService; + OrganizationService organizationService; @Test @WithUserDetails(value = "api_user") public void testEnrichWithBrandParams() { - Tenant defautTenant = tenantService.getTenantConfiguration().block(); - String instanceName = - StringUtils.defaultIfEmpty(defautTenant.getTenantConfiguration().getInstanceName(), "Appsmith"); + Organization defautOrganization = + organizationService.getOrganizationConfiguration().block(); + String instanceName = StringUtils.defaultIfEmpty( + defautOrganization.getOrganizationConfiguration().getInstanceName(), "Appsmith"); StepVerifier.create(emailServiceHelperCE.enrichWithBrandParams(new HashMap<>(), "www.test.com")) .assertNext(map -> { assertThat(map.containsKey(INSTANCE_NAME)).isTrue(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UsagePulseServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UsagePulseServiceTest.java index 517b3ceeadb2..4a502d82bba9 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UsagePulseServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UsagePulseServiceTest.java @@ -57,7 +57,7 @@ public void test_AnonymousUserPulse_Success() { assertThat(usagePulse.getUser()).isEqualTo(anonymousUserId); assertThat(usagePulse.getIsAnonymousUser()).isTrue(); assertThat(usagePulse.getInstanceId()).isNotNull(); - assertThat(usagePulse.getTenantId()).isNotNull(); + assertThat(usagePulse.getOrganizationId()).isNotNull(); assertThat(usagePulse.getViewMode()).isTrue(); }) .verifyComplete(); @@ -94,7 +94,7 @@ public void test_loggedInUserPulse_Success() { assertThat(usagePulse.getUser()).isEqualTo(hashedUserEmail); assertThat(usagePulse.getIsAnonymousUser()).isFalse(); assertThat(usagePulse.getInstanceId()).isNotNull(); - assertThat(usagePulse.getTenantId()).isNotNull(); + assertThat(usagePulse.getOrganizationId()).isNotNull(); assertThat(usagePulse.getViewMode()).isTrue(); }) .verifyComplete(); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java index 7edad2e12835..3f9aad56b434 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserServiceTest.java @@ -7,10 +7,10 @@ import com.appsmith.server.configurations.WithMockAppsmithUser; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.LoginSource; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.PasswordResetToken; import com.appsmith.server.domains.PermissionGroup; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserData; import com.appsmith.server.domains.UserState; @@ -103,7 +103,7 @@ public class UserServiceTest { EmailVerificationTokenRepository emailVerificationTokenRepository; @Autowired - TenantService tenantService; + OrganizationService organizationService; Mono userMono; @@ -187,7 +187,7 @@ public void createNewUserValid() { assertThat(user.getId()).isNotNull(); assertThat(user.getEmail()).isEqualTo("new-user-email@email.com"); assertThat(user.getName()).isNullOrEmpty(); - assertThat(user.getTenantId()).isNotNull(); + assertThat(user.getOrganizationId()).isNotNull(); Set userPolicies = user.getPolicies(); Optional optionalManageUserPolicy = userPolicies.stream() @@ -667,21 +667,23 @@ public void emailVerificationTokenGenerate_WhenInstanceEmailVerificationIsNotEna newUser.setEmail(testEmail); Mono userMono = userRepository.save(newUser); - // Setting tenant Config emailVerificationEnabled to FALSE - Mono tenantMono = tenantService.getDefaultTenant().flatMap(tenant1 -> { - TenantConfiguration tenantConfiguration = tenant1.getTenantConfiguration(); - tenantConfiguration.setEmailVerificationEnabled(Boolean.FALSE); - tenant1.setTenantConfiguration(tenantConfiguration); - return tenantService.update(tenant1.getId(), tenant1); - }); + // Setting Organization Config emailVerificationEnabled to FALSE + Mono organizationMono = organizationService + .getDefaultOrganization() + .flatMap(organization -> { + OrganizationConfiguration organizationConfiguration = organization.getOrganizationConfiguration(); + organizationConfiguration.setEmailVerificationEnabled(Boolean.FALSE); + organization.setOrganizationConfiguration(organizationConfiguration); + return organizationService.update(organization.getId(), organization); + }); Mono emailVerificationMono = userService.resendEmailVerification(getResendEmailVerificationDTO(testEmail), null); - Mono resultMono = userMono.then(tenantMono).then(emailVerificationMono); + Mono resultMono = userMono.then(organizationMono).then(emailVerificationMono); StepVerifier.create(resultMono) - .expectErrorMessage(AppsmithError.TENANT_EMAIL_VERIFICATION_NOT_ENABLED.getMessage()) + .expectErrorMessage(AppsmithError.ORGANIZATION_EMAIL_VERIFICATION_NOT_ENABLED.getMessage()) .verify(); } @@ -695,18 +697,20 @@ public void emailVerificationTokenGenerate_WhenUserEmailAlreadyVerified_ThrowsEx newUser.setEmailVerified(Boolean.TRUE); Mono userMono = userRepository.save(newUser); - // Setting tenant Config emailVerificationEnabled to TRUE - Mono tenantMono = tenantService.getDefaultTenant().flatMap(tenant1 -> { - TenantConfiguration tenantConfiguration = tenant1.getTenantConfiguration(); - tenantConfiguration.setEmailVerificationEnabled(Boolean.TRUE); - tenant1.setTenantConfiguration(tenantConfiguration); - return tenantService.update(tenant1.getId(), tenant1); - }); + // Setting Organization Config emailVerificationEnabled to TRUE + Mono organizationMono = organizationService + .getDefaultOrganization() + .flatMap(organization -> { + OrganizationConfiguration organizationConfiguration = organization.getOrganizationConfiguration(); + organizationConfiguration.setEmailVerificationEnabled(Boolean.TRUE); + organization.setOrganizationConfiguration(organizationConfiguration); + return organizationService.update(organization.getId(), organization); + }); Mono emailVerificationMono = userService.resendEmailVerification(getResendEmailVerificationDTO(testEmail), null); - Mono resultMono = userMono.then(tenantMono).then(emailVerificationMono); + Mono resultMono = userMono.then(organizationMono).then(emailVerificationMono); StepVerifier.create(resultMono) .expectErrorMessage(AppsmithError.USER_ALREADY_VERIFIED.getMessage()) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceUnitTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceUnitTest.java index 22b53e0cce3b..f7ca9468321a 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceUnitTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/UserWorkspaceServiceUnitTest.java @@ -252,7 +252,7 @@ public void getUserWorkspacesByRecentlyUsedOrder_noRecentWorkspaces_allEntriesAr assertThat(workspaces).hasSize(4); workspaces.forEach(workspace -> { assertThat(workspaceIds.contains(workspace.getId())).isTrue(); - assertThat(workspace.getTenantId()).isNotEmpty(); + assertThat(workspace.getOrganizationId()).isNotEmpty(); }); }) .verifyComplete(); @@ -281,7 +281,7 @@ public void getUserWorkspacesByRecentlyUsedOrder_withRecentlyUsedWorkspaces_allE workspaces.forEach(workspace -> { fetchedWorkspaceIds.add(workspace.getId()); assertThat(workspaceIds.contains(workspace.getId())).isTrue(); - assertThat(workspace.getTenantId()).isNotEmpty(); + assertThat(workspace.getOrganizationId()).isNotEmpty(); }); assertThat(fetchedWorkspaceIds).isEqualTo(workspaceIds); }) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/WorkspaceServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/WorkspaceServiceTest.java index 3af09f039fcf..8ae96af4c516 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/WorkspaceServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/WorkspaceServiceTest.java @@ -180,7 +180,7 @@ public void createDefaultWorkspace() { assertThat(workspace1.getSlug()).isNotNull(); assertThat(workspace1.getEmail()).isEqualTo("api_user"); assertThat(workspace1.getIsAutoGeneratedWorkspace()).isTrue(); - assertThat(workspace1.getTenantId()).isEqualTo(user.getTenantId()); + assertThat(workspace1.getOrganizationId()).isEqualTo(user.getOrganizationId()); assertThat(workspace1.getDefaultPermissionGroups()).hasSize(3); PermissionGroup adminPermissionGroup = permissionGroups.stream() @@ -338,7 +338,7 @@ public void validCreateWorkspaceTest() { assertThat(workspace1.getSlug()).isEqualTo(TextUtils.makeSlug(workspace.getName())); assertThat(workspace1.getEmail()).isEqualTo("api_user"); assertThat(workspace1.getIsAutoGeneratedWorkspace()).isNull(); - assertThat(workspace1.getTenantId()).isEqualTo(user.getTenantId()); + assertThat(workspace1.getOrganizationId()).isEqualTo(user.getOrganizationId()); // Assert admin permission group policies adminPermissionGroup.getPolicies().stream() diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java index bdeea2812344..16f6198daa64 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ConsolidatedAPIServiceImplTest.java @@ -13,8 +13,8 @@ import com.appsmith.server.domains.CustomJSLib; import com.appsmith.server.domains.GitArtifactMetadata; import com.appsmith.server.domains.NewPage; +import com.appsmith.server.domains.Organization; import com.appsmith.server.domains.Plugin; -import com.appsmith.server.domains.Tenant; import com.appsmith.server.domains.Theme; import com.appsmith.server.domains.User; import com.appsmith.server.domains.UserData; @@ -42,9 +42,9 @@ import com.appsmith.server.services.ApplicationPageService; import com.appsmith.server.services.ConsolidatedAPIService; import com.appsmith.server.services.MockDataService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.ProductAlertService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import com.appsmith.server.themes.base.ThemeService; @@ -96,7 +96,7 @@ public class ConsolidatedAPIServiceImplTest { UserDataService mockUserDataService; @MockBean - TenantService mockTenantService; + OrganizationService mockOrganizationService; @MockBean ProductAlertService mockProductAlertService; @@ -163,9 +163,9 @@ public void testPageLoadResponseWhenPageIdAndApplicationIdMissing() { sampleFeatureFlagMap.put("sampleFeatureFlag", true); when(mockUserDataService.getFeatureFlagsForCurrentUser()).thenReturn(Mono.just(sampleFeatureFlagMap)); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -185,11 +185,11 @@ public void testPageLoadResponseWhenPageIdAndApplicationIdMissing() { .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -223,9 +223,9 @@ public void testPageLoadResponseForViewMode() { sampleFeatureFlagMap.put("sampleFeatureFlag", true); when(mockUserDataService.getFeatureFlagsForCurrentUser()).thenReturn(Mono.just(sampleFeatureFlagMap)); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -312,11 +312,11 @@ public void testPageLoadResponseForViewMode() { .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -412,9 +412,9 @@ public void testPageLoadResponseForEditMode() { sampleFeatureFlagMap.put("sampleFeatureFlag", true); when(mockUserDataService.getFeatureFlagsForCurrentUser()).thenReturn(Mono.just(sampleFeatureFlagMap)); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -538,11 +538,11 @@ public void testPageLoadResponseForEditMode() { .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -731,9 +731,9 @@ public void testErrorResponseWhenAnonymousUserAccessPrivateApp() { sampleFeatureFlagMap.put("sampleFeatureFlag", true); when(mockUserDataService.getFeatureFlagsForCurrentUser()).thenReturn(Mono.just(sampleFeatureFlagMap)); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -760,11 +760,11 @@ public void testErrorResponseWhenAnonymousUserAccessPrivateApp() { .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -903,9 +903,9 @@ public void testPageLoadResponseForViewMode_whenBranchNameIsPresentInNonGitApp() sampleFeatureFlagMap.put("sampleFeatureFlag", true); when(mockUserDataService.getFeatureFlagsForCurrentUser()).thenReturn(Mono.just(sampleFeatureFlagMap)); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -992,11 +992,11 @@ public void testPageLoadResponseForViewMode_whenBranchNameIsPresentInNonGitApp() .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -1095,9 +1095,9 @@ public void testPageLoadResponseForEditModeWhenDefaultBranchIsDifferentFromDefau when(mockUserDataService.updateLastUsedResourceAndWorkspaceList(any(), any(), any())) .thenReturn(Mono.just(new UserData())); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); @@ -1250,11 +1250,11 @@ public void testPageLoadResponseForEditModeWhenDefaultBranchIsDifferentFromDefau .getData() .getName()); - assertNotNull(consolidatedAPIResponseDTO.getTenantConfig()); + assertNotNull(consolidatedAPIResponseDTO.getOrganizationConfig()); assertEquals( - "sampleTenant", + "sampleOrganization", consolidatedAPIResponseDTO - .getTenantConfig() + .getOrganizationConfig() .getData() .getDisplayName()); @@ -1441,9 +1441,9 @@ public void testPageLoadWhenPageFromFeatureBranchAndCacheableRepositoryReturnsBa when(mockUserDataService.updateLastUsedResourceAndWorkspaceList(any(), any(), any())) .thenReturn(Mono.just(new UserData())); - Tenant sampleTenant = new Tenant(); - sampleTenant.setDisplayName("sampleTenant"); - when(mockTenantService.getTenantConfiguration()).thenReturn(Mono.just(sampleTenant)); + Organization sampleOrganization = new Organization(); + sampleOrganization.setDisplayName("sampleOrganization"); + when(mockOrganizationService.getOrganizationConfiguration()).thenReturn(Mono.just(sampleOrganization)); ProductAlertResponseDTO sampleProductAlertResponseDTO = new ProductAlertResponseDTO(); sampleProductAlertResponseDTO.setTitle("sampleProductAlert"); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/EmailServiceCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/EmailServiceCEImplTest.java index 4ad36c2a26fe..84900e41745f 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/EmailServiceCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/EmailServiceCEImplTest.java @@ -5,7 +5,6 @@ import com.appsmith.server.domains.User; import com.appsmith.server.domains.Workspace; import com.appsmith.server.notifications.EmailSender; -import com.appsmith.server.services.TenantService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -39,9 +38,6 @@ @SpringBootTest class EmailServiceCEImplTest { - @Autowired - TenantService tenantService; - @SpyBean EmailSender mockEmailSender; diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/FeatureFlagServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/FeatureFlagServiceCETest.java index e4b875e2672f..89129e40c09d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/FeatureFlagServiceCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/FeatureFlagServiceCETest.java @@ -9,7 +9,7 @@ import com.appsmith.server.helpers.FeatureFlagMigrationHelper; import com.appsmith.server.services.CacheableFeatureFlagHelper; import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -31,7 +31,7 @@ import java.util.Map; import java.util.UUID; -import static com.appsmith.external.enums.FeatureFlagEnum.TENANT_TEST_FEATURE; +import static com.appsmith.external.enums.FeatureFlagEnum.ORGANIZATION_TEST_FEATURE; import static com.appsmith.server.constants.FeatureMigrationType.DISABLE; import static com.appsmith.server.constants.FeatureMigrationType.ENABLE; import static com.appsmith.server.constants.MigrationStatus.COMPLETED; @@ -65,7 +65,7 @@ public class FeatureFlagServiceCETest { FeatureFlagMigrationHelper featureFlagMigrationHelper; @Autowired - TenantService tenantService; + OrganizationService organizationService; @BeforeEach void setup() { @@ -78,7 +78,7 @@ void setup() { @AfterEach void tearDown() { cacheManager.evictAll("featureFlag").block(); - cacheManager.evictAll("tenantNewFeatures").block(); + cacheManager.evictAll("organizationNewFeatures").block(); } @Test @@ -102,26 +102,26 @@ public void testGetFeaturesForUser() { @Test @WithUserDetails(value = "api_user") - public void testGetFeaturesForUser_overrideWithTenantFeature() { + public void testGetFeaturesForUser_overrideWithOrganizationFeature() { - // Assert feature flag is false before the tenant level flag overrides the existing flag + // Assert feature flag is false before the org level flag overrides the existing flag StepVerifier.create(featureFlagService.getAllFeatureFlagsForUser()) .assertNext(result -> { assertNotNull(result); - assertTrue(result.get(TENANT_TEST_FEATURE.toString())); + assertTrue(result.get(ORGANIZATION_TEST_FEATURE.toString())); }) .verifyComplete(); - Map tenantFeatures = new HashMap<>(); - tenantFeatures.put(TENANT_TEST_FEATURE.toString(), false); + Map organizationFeatures = new HashMap<>(); + organizationFeatures.put(ORGANIZATION_TEST_FEATURE.toString(), false); FeaturesResponseDTO responseDTO = new FeaturesResponseDTO(); - responseDTO.setFeatures(tenantFeatures); - doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForTenant(any()); - // Assert true for same feature flag after tenant level flag overrides the existing flag + responseDTO.setFeatures(organizationFeatures); + doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForOrganization(any()); + // Assert true for same feature flag after org level flag overrides the existing flag StepVerifier.create(featureFlagService.getAllFeatureFlagsForUser()) .assertNext(result -> { assertNotNull(result); - assertFalse(result.get(TENANT_TEST_FEATURE.toString())); + assertFalse(result.get(ORGANIZATION_TEST_FEATURE.toString())); }) .verifyComplete(); } @@ -148,7 +148,7 @@ public void evictFeatureFlags_withUserIdentifier_redisKeyDoesNotExist() { } @Test - public void getFeatures_withTenantIdentifier_redisKeyExists() { + public void getFeatures_withOrganizationIdentifier_redisKeyExists() { Map flags = new HashMap<>(); flags.put(UUID.randomUUID().toString(), true); flags.put(UUID.randomUUID().toString(), false); @@ -157,20 +157,20 @@ public void getFeatures_withTenantIdentifier_redisKeyExists() { doReturn(Mono.just(featuresResponseDTO)) .when(cacheableFeatureFlagHelper) - .getRemoteFeaturesForTenant(any()); + .getRemoteFeaturesForOrganization(any()); - String tenantIdentifier = UUID.randomUUID().toString(); + String organizationIdentifier = UUID.randomUUID().toString(); Mono cachedFeaturesMono = - cacheableFeatureFlagHelper.fetchCachedTenantFeatures(tenantIdentifier); - Mono hasKeyMono = reactiveRedisTemplate.hasKey("tenantNewFeatures:" + tenantIdentifier); + cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(organizationIdentifier); + Mono hasKeyMono = reactiveRedisTemplate.hasKey("organizationNewFeatures:" + organizationIdentifier); StepVerifier.create(cachedFeaturesMono.then(hasKeyMono)) .assertNext(Assertions::assertTrue) .verifyComplete(); } @Test - public void evictFeatures_withTenantIdentifier_redisKeyDoesNotExist() { - // Insert dummy value for tenant flags + public void evictFeatures_withOrganizationIdentifier_redisKeyDoesNotExist() { + // Insert dummy value for org flags Map flags = new HashMap<>(); flags.put(UUID.randomUUID().toString(), true); flags.put(UUID.randomUUID().toString(), false); @@ -179,19 +179,19 @@ public void evictFeatures_withTenantIdentifier_redisKeyDoesNotExist() { doReturn(Mono.just(featuresResponseDTO)) .when(cacheableFeatureFlagHelper) - .getRemoteFeaturesForTenant(any()); + .getRemoteFeaturesForOrganization(any()); - String tenantIdentifier = UUID.randomUUID().toString(); + String organizationIdentifier = UUID.randomUUID().toString(); Mono cachedFeaturesMono = - cacheableFeatureFlagHelper.fetchCachedTenantFeatures(tenantIdentifier); - Mono hasKeyMono = reactiveRedisTemplate.hasKey("tenantNewFeatures:" + tenantIdentifier); + cacheableFeatureFlagHelper.fetchCachedOrganizationFeatures(organizationIdentifier); + Mono hasKeyMono = reactiveRedisTemplate.hasKey("organizationNewFeatures:" + organizationIdentifier); // Assert key is inserted in cache StepVerifier.create(cachedFeaturesMono.then(hasKeyMono)) .assertNext(Assertions::assertTrue) .verifyComplete(); - Mono evictCache = cacheableFeatureFlagHelper.evictCachedTenantFeatures(tenantIdentifier); - hasKeyMono = reactiveRedisTemplate.hasKey("tenantNewFeatures:" + tenantIdentifier); + Mono evictCache = cacheableFeatureFlagHelper.evictCachedOrganizationFeatures(organizationIdentifier); + hasKeyMono = reactiveRedisTemplate.hasKey("organizationNewFeatures:" + organizationIdentifier); // Assert key is evicted from cache StepVerifier.create(evictCache.then(hasKeyMono)) .assertNext(Assertions::assertFalse) @@ -200,19 +200,19 @@ public void evictFeatures_withTenantIdentifier_redisKeyDoesNotExist() { @Test public void - getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations_emptyMapForPendingMigration_statesUpdate() { + getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations_emptyMapForPendingMigration_statesUpdate() { Mockito.when(featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(any())) .thenReturn(Mono.just(new HashMap<>())); featureFlagService - .getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations() + .getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations() .block(); - StepVerifier.create(tenantService.getDefaultTenant()) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration().getFeaturesWithPendingMigration()) + StepVerifier.create(organizationService.getDefaultOrganization()) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration().getFeaturesWithPendingMigration()) .isEqualTo(new HashMap<>()); - assertThat(tenant.getTenantConfiguration().getMigrationStatus()) + assertThat(organization.getOrganizationConfiguration().getMigrationStatus()) .isEqualTo(COMPLETED); }) .verifyComplete(); @@ -220,80 +220,82 @@ public void evictFeatures_withTenantIdentifier_redisKeyDoesNotExist() { @Test public void - getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations_disableMigration_statesUpdate() { + getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations_disableMigration_statesUpdate() { Mockito.when(featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(any())) - .thenReturn(Mono.just(Map.of(TENANT_TEST_FEATURE, DISABLE))); + .thenReturn(Mono.just(Map.of(ORGANIZATION_TEST_FEATURE, DISABLE))); featureFlagService - .getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations() + .getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations() .block(); - StepVerifier.create(tenantService.getDefaultTenant()) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration().getFeaturesWithPendingMigration()) - .isEqualTo(Map.of(TENANT_TEST_FEATURE, DISABLE)); - assertThat(tenant.getTenantConfiguration().getMigrationStatus()) + StepVerifier.create(organizationService.getDefaultOrganization()) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + .isEqualTo(Map.of(ORGANIZATION_TEST_FEATURE, DISABLE)); + assertThat(organization.getOrganizationConfiguration().getMigrationStatus()) .isEqualTo(PENDING); }) .verifyComplete(); } @Test - public void getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations_enableMigration_statesUpdate() { + public void + getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations_enableMigration_statesUpdate() { Mockito.when(featureFlagMigrationHelper.getUpdatedFlagsWithPendingMigration(any())) - .thenReturn(Mono.just(Map.of(TENANT_TEST_FEATURE, ENABLE))); + .thenReturn(Mono.just(Map.of(ORGANIZATION_TEST_FEATURE, ENABLE))); featureFlagService - .getAllRemoteFeaturesForTenantAndUpdateFeatureFlagsWithPendingMigrations() + .getAllRemoteFeaturesForOrganizationAndUpdateFeatureFlagsWithPendingMigrations() .block(); - StepVerifier.create(tenantService.getDefaultTenant()) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration().getFeaturesWithPendingMigration()) - .isEqualTo(Map.of(TENANT_TEST_FEATURE, ENABLE)); - assertThat(tenant.getTenantConfiguration().getMigrationStatus()) + StepVerifier.create(organizationService.getDefaultOrganization()) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + .isEqualTo(Map.of(ORGANIZATION_TEST_FEATURE, ENABLE)); + assertThat(organization.getOrganizationConfiguration().getMigrationStatus()) .isEqualTo(PENDING); }) .verifyComplete(); } @Test - public void getTenantFeatureFlags_withDefaultTenant_fetchLatestFlags() { + public void getOrganizationFeatureFlags_withDefaultOrganization_fetchLatestFlags() { - Map tenantFeatures = new HashMap<>(); - tenantFeatures.put(TENANT_TEST_FEATURE.name(), true); + Map organizationFeatures = new HashMap<>(); + organizationFeatures.put(ORGANIZATION_TEST_FEATURE.name(), true); FeaturesResponseDTO responseDTO = new FeaturesResponseDTO(); - responseDTO.setFeatures(tenantFeatures); - doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForTenant(any()); - StepVerifier.create(featureFlagService.getTenantFeatures()) + responseDTO.setFeatures(organizationFeatures); + doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForOrganization(any()); + StepVerifier.create(featureFlagService.getOrganizationFeatures()) .assertNext(result -> { assertNotNull(result); - assertTrue(result.get(TENANT_TEST_FEATURE.name())); + assertTrue(result.get(ORGANIZATION_TEST_FEATURE.name())); }) .verifyComplete(); } @Test - public void getCachedTenantFeatureFlags_withDefaultTenant_tenantFeatureFlagsAreCached() { + public void getCachedOrganizationFeatureFlags_withDefaultOrganization_organizationFeatureFlagsAreCached() { // Assert that the cached feature flags are empty before the remote fetch - CachedFeatures cachedFeaturesBeforeRemoteCall = featureFlagService.getCachedTenantFeatureFlags(); + CachedFeatures cachedFeaturesBeforeRemoteCall = featureFlagService.getCachedOrganizationFeatureFlags(); assertThat(cachedFeaturesBeforeRemoteCall.getFeatures()).hasSize(1); - assertTrue(cachedFeaturesBeforeRemoteCall.getFeatures().get(TENANT_TEST_FEATURE.name())); + assertTrue(cachedFeaturesBeforeRemoteCall.getFeatures().get(ORGANIZATION_TEST_FEATURE.name())); - Map tenantFeatures = new HashMap<>(); - tenantFeatures.put(TENANT_TEST_FEATURE.name(), false); + Map organizationFeatures = new HashMap<>(); + organizationFeatures.put(ORGANIZATION_TEST_FEATURE.name(), false); FeaturesResponseDTO responseDTO = new FeaturesResponseDTO(); - responseDTO.setFeatures(tenantFeatures); - doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForTenant(any()); - StepVerifier.create(featureFlagService.getTenantFeatures()) + responseDTO.setFeatures(organizationFeatures); + doReturn(Mono.just(responseDTO)).when(cacheableFeatureFlagHelper).getRemoteFeaturesForOrganization(any()); + StepVerifier.create(featureFlagService.getOrganizationFeatures()) .assertNext(result -> { assertNotNull(result); - assertFalse(result.get(TENANT_TEST_FEATURE.name())); + assertFalse(result.get(ORGANIZATION_TEST_FEATURE.name())); // Check if the cached feature flags are updated after the remote fetch - CachedFeatures cachedFeaturesAfterRemoteCall = featureFlagService.getCachedTenantFeatureFlags(); - assertFalse(cachedFeaturesAfterRemoteCall.getFeatures().get(TENANT_TEST_FEATURE.name())); + CachedFeatures cachedFeaturesAfterRemoteCall = + featureFlagService.getCachedOrganizationFeatureFlags(); + assertFalse(cachedFeaturesAfterRemoteCall.getFeatures().get(ORGANIZATION_TEST_FEATURE.name())); }) .verifyComplete(); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/OrganizationServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/OrganizationServiceCETest.java new file mode 100644 index 000000000000..a9b1dd8c8211 --- /dev/null +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/OrganizationServiceCETest.java @@ -0,0 +1,414 @@ +package com.appsmith.server.services.ce; + +import com.appsmith.caching.components.CacheManager; +import com.appsmith.external.enums.FeatureFlagEnum; +import com.appsmith.server.constants.FeatureMigrationType; +import com.appsmith.server.constants.LicensePlan; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; +import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.helpers.FeatureFlagMigrationHelper; +import com.appsmith.server.helpers.UserUtils; +import com.appsmith.server.helpers.ce.bridge.Bridge; +import com.appsmith.server.repositories.CacheableRepositoryHelper; +import com.appsmith.server.repositories.OrganizationRepository; +import com.appsmith.server.repositories.UserRepository; +import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; +import com.appsmith.server.solutions.EnvManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.security.test.context.support.WithUserDetails; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static com.appsmith.external.enums.FeatureFlagEnum.ORGANIZATION_TEST_FEATURE; +import static com.appsmith.external.enums.FeatureFlagEnum.TEST_FEATURE_2; +import static com.appsmith.server.constants.MigrationStatus.COMPLETED; +import static com.appsmith.server.constants.MigrationStatus.IN_PROGRESS; +import static com.appsmith.server.exceptions.AppsmithErrorCode.FEATURE_FLAG_MIGRATION_FAILURE; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; + +@SpringBootTest +class OrganizationServiceCETest { + + @Autowired + OrganizationService organizationService; + + @MockBean + EnvManager envManager; + + @Autowired + UserRepository userRepository; + + @Autowired + OrganizationRepository organizationRepository; + + @Autowired + UserUtils userUtils; + + @SpyBean + FeatureFlagService featureFlagService; + + @Autowired + ReactiveRedisTemplate reactiveRedisTemplate; + + @SpyBean + CacheManager cacheManager; + + @SpyBean + CacheableRepositoryHelper cacheableRepositoryHelper; + + @MockBean + FeatureFlagMigrationHelper featureFlagMigrationHelper; + + OrganizationConfiguration originalOrganizationConfiguration; + + @BeforeEach + public void setup() throws IOException { + final Organization organization = + organizationService.getDefaultOrganization().block(); + assert organization != null; + originalOrganizationConfiguration = organization.getOrganizationConfiguration(); + + organizationRepository + .updateAndReturn( + organization.getId(), + Bridge.update().set(Organization.Fields.organizationConfiguration, null), + null) + .block(); + + // Make api_user super-user to test organization admin functionality + // Todo change this to organization admin once we introduce multitenancy + userRepository + .findByEmail("api_user") + .flatMap(user -> userUtils.makeSuperUser(List.of(user))) + .block(); + doReturn(Mono.empty()).when(cacheManager).get(anyString(), anyString()); + } + + @AfterEach + public void cleanup() { + Organization updatedOrganization = new Organization(); + updatedOrganization.setOrganizationConfiguration(originalOrganizationConfiguration); + organizationService + .getDefaultOrganizationId() + .flatMap(organizationId -> organizationService.update(organizationId, updatedOrganization)) + .doOnError(error -> { + System.err.println("Error during cleanup: " + error.getMessage()); + }) + .block(); + } + + @Test + void ensureMapsKey() { + StepVerifier.create(organizationService.getOrganizationConfiguration()) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration().getGoogleMapsKey()) + .isNull(); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails("api_user") + void setMapsKeyAndGetItBack() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setGoogleMapsKey("test-key"); + + final Mono resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .assertNext(organizationConfiguration -> { + assertThat(organizationConfiguration.getGoogleMapsKey()).isEqualTo("test-key"); + }) + .verifyComplete(); + } + + @Test + void setMapsKeyWithoutAuthentication() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setGoogleMapsKey("test-key"); + + final Mono resultMono = organizationService.updateDefaultOrganizationConfiguration(changes); + + StepVerifier.create(resultMono) + .expectErrorMatches(error -> { + assertThat(error.getMessage()).startsWith("Unable to find organization "); + return true; + }) + .verify(); + } + + @Test + @WithUserDetails("usertest@usertest.com") + void setMapsKeyWithoutAuthorization() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setGoogleMapsKey("test-key"); + + final Mono resultMono = organizationService.updateDefaultOrganizationConfiguration(changes); + + StepVerifier.create(resultMono) + .expectErrorMatches(error -> { + assertThat(error.getMessage()).startsWith("Unable to find organization "); + return true; + }) + .verify(); + } + + @Test + @WithUserDetails("anonymousUser") + void getOrganizationConfig_Valid_AnonymousUser() { + StepVerifier.create(organizationService.getOrganizationConfiguration()) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration()).isNotNull(); + assertThat(organization.getOrganizationConfiguration().getLicense()) + .isNotNull(); + assertThat(organization + .getOrganizationConfiguration() + .getLicense() + .getPlan()) + .isEqualTo(LicensePlan.FREE); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails("api_user") + void setEmailVerificationEnabled_WithInvalidSMTPHost_ReturnsError() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setEmailVerificationEnabled(TRUE); + + Map envVars = new HashMap<>(); + // adding invalid mail host + envVars.put("APPSMITH_MAIL_HOST", ""); + + // mocking env vars file + Mockito.when(envManager.getAllNonEmpty()).thenReturn(Mono.just(envVars)); + + final Mono resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .then(organizationService.getOrganizationConfiguration()) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .expectErrorMatches(error -> { + assertThat(error.getMessage()).startsWith("Your SMTP configuration is invalid"); + return true; + }) + .verify(); + } + + @Test + @WithUserDetails("api_user") + void setEmailVerificationEnabled_WithValidSMTPHost_Success() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setEmailVerificationEnabled(TRUE); + + Map envVars = new HashMap<>(); + // adding valid mail host + envVars.put("APPSMITH_MAIL_HOST", "smtp.sendgrid.net"); + + // mocking env vars file + Mockito.when(envManager.getAllNonEmpty()).thenReturn(Mono.just(envVars)); + + final Mono resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .then(organizationService.getOrganizationConfiguration()) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .assertNext(organizationConfiguration -> { + assertThat(organizationConfiguration.isEmailVerificationEnabled()) + .isTrue(); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails("api_user") + void setEmailVerificationEnabledFalseAndGetItBack() { + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setEmailVerificationEnabled(Boolean.FALSE); + + final Mono resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .then(organizationService.getOrganizationConfiguration()) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .assertNext(organizationConfiguration -> { + assertThat(organizationConfiguration.isEmailVerificationEnabled()) + .isFalse(); + }) + .verifyComplete(); + } + + @Test + void checkAndExecuteMigrationsForOrganizationFeatureFlags_emptyMigrationMap_revertSameOrganization() { + Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) + .thenReturn(Mono.just(TRUE)); + + Organization organization = new Organization(); + organization.setId(UUID.randomUUID().toString()); + OrganizationConfiguration config = new OrganizationConfiguration(); + config.setFeaturesWithPendingMigration(new HashMap<>()); + organization.setOrganizationConfiguration(config); + final Mono resultMono = + organizationService.checkAndExecuteMigrationsForOrganizationFeatureFlags(organization); + StepVerifier.create(resultMono) + .assertNext(organization1 -> { + assertThat(organization1).isEqualTo(organization); + assertThat(organization1.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + .isEmpty(); + assertThat(organization1.getOrganizationConfiguration().getMigrationStatus()) + .isEqualTo(COMPLETED); + }) + .verifyComplete(); + } + + @Test + void checkAndExecuteMigrationsForOrganizationFeatureFlags_withPendingMigration_getUpdatedOrganization() { + Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) + .thenReturn(Mono.just(TRUE)); + + Organization organization = new Organization(); + organization.setId(UUID.randomUUID().toString()); + OrganizationConfiguration config = new OrganizationConfiguration(); + Map featureMigrationTypeMap = new HashMap<>(); + config.setFeaturesWithPendingMigration(featureMigrationTypeMap); + featureMigrationTypeMap.put(ORGANIZATION_TEST_FEATURE, FeatureMigrationType.ENABLE); + featureMigrationTypeMap.put(TEST_FEATURE_2, FeatureMigrationType.DISABLE); + organization.setOrganizationConfiguration(config); + final Mono resultMono = + organizationService.checkAndExecuteMigrationsForOrganizationFeatureFlags(organization); + StepVerifier.create(resultMono) + .assertNext(organization1 -> { + assertThat(organization1.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + .isEmpty(); + assertThat(organization1.getOrganizationConfiguration().getMigrationStatus()) + .isEqualTo(COMPLETED); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails("api_user") + void + checkAndExecuteMigrationsForOrganizationFeatureFlags_withPendingMigration_exceptionWhileRunningMigration_getUpdatedOrganization() { + Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) + .thenReturn(Mono.just(TRUE)) + .thenReturn(Mono.just(FALSE)); + + Organization organization = new Organization(); + organization.setId(UUID.randomUUID().toString()); + OrganizationConfiguration config = new OrganizationConfiguration(); + Map featureMigrationTypeMap = new HashMap<>(); + config.setFeaturesWithPendingMigration(featureMigrationTypeMap); + featureMigrationTypeMap.put(ORGANIZATION_TEST_FEATURE, FeatureMigrationType.DISABLE); + featureMigrationTypeMap.put(TEST_FEATURE_2, FeatureMigrationType.ENABLE); + organization.setOrganizationConfiguration(config); + final Mono resultMono = + organizationService.checkAndExecuteMigrationsForOrganizationFeatureFlags(organization); + + // Verify that the feature flag migration failure is thrown + StepVerifier.create(resultMono) + .expectErrorSatisfies(throwable -> { + assertThat(throwable instanceof AppsmithException).isTrue(); + assertThat(((AppsmithException) throwable).getAppErrorCode()) + .isEqualTo(FEATURE_FLAG_MIGRATION_FAILURE.getCode()); + }) + .verify(); + + // Verify that the organization is updated for the feature flag migration failure + StepVerifier.create(organizationService.getByIdWithoutPermissionCheck(organization.getId())) + .assertNext(organization1 -> { + assertThat(organization1.getOrganizationConfiguration().getFeaturesWithPendingMigration()) + .hasSize(1); + assertThat(organization1.getOrganizationConfiguration().getMigrationStatus()) + .isEqualTo(IN_PROGRESS); + }) + .verifyComplete(); + } + + @Test + @WithUserDetails("api_user") + void updateOrganizationConfiguration_updateStrongPasswordPolicy_success() { + + // Ensure that the default organization does not have strong password policy setup + Mono organizationMono = organizationService.getDefaultOrganization(); + StepVerifier.create(organizationMono) + .assertNext(organization -> { + assertThat(organization.getOrganizationConfiguration().getIsStrongPasswordPolicyEnabled()) + .isNull(); + }) + .verifyComplete(); + + // Ensure that the strong password policy is enabled after the update + final OrganizationConfiguration changes = new OrganizationConfiguration(); + changes.setIsStrongPasswordPolicyEnabled(TRUE); + Mono resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .then(organizationService.getOrganizationConfiguration()) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .assertNext(organizationConfiguration -> { + assertThat(organizationConfiguration.getIsStrongPasswordPolicyEnabled()) + .isTrue(); + }) + .verifyComplete(); + + // Ensure that the strong password policy is disabled after the update + changes.setIsStrongPasswordPolicyEnabled(FALSE); + resultMono = organizationService + .updateDefaultOrganizationConfiguration(changes) + .then(organizationService.getOrganizationConfiguration()) + .map(Organization::getOrganizationConfiguration); + + StepVerifier.create(resultMono) + .assertNext(organizationConfiguration -> { + assertThat(organizationConfiguration.getIsStrongPasswordPolicyEnabled()) + .isFalse(); + }) + .verifyComplete(); + } + + /** + * This test checks that the organization cache is created and data is fetched without any deserialization errors + * This will ensure if any new nested user-defined classes are created in the organization object in the future, and + * implements serializable is missed for that class, the deserialization will fail leads this test to fail. + */ + @Test + @WithUserDetails(value = "api_user") + public void testDeserializationErrors() { + String organizationId = organizationService.getDefaultOrganizationId().block(); + Mono evictCachedOrganization = cacheableRepositoryHelper.evictCachedOrganization(organizationId); + Mono hasKeyMono = reactiveRedisTemplate.hasKey("organization:" + organizationId); + Mono organizationMono = organizationService.getDefaultOrganization(); + StepVerifier.create(evictCachedOrganization.then(organizationMono).then(hasKeyMono)) + .assertNext(Assertions::assertTrue) + .verifyComplete(); + } +} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java deleted file mode 100644 index f82b882de984..000000000000 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/TenantServiceCETest.java +++ /dev/null @@ -1,400 +0,0 @@ -package com.appsmith.server.services.ce; - -import com.appsmith.caching.components.CacheManager; -import com.appsmith.external.enums.FeatureFlagEnum; -import com.appsmith.server.constants.FeatureMigrationType; -import com.appsmith.server.constants.LicensePlan; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; -import com.appsmith.server.exceptions.AppsmithException; -import com.appsmith.server.helpers.FeatureFlagMigrationHelper; -import com.appsmith.server.helpers.UserUtils; -import com.appsmith.server.helpers.ce.bridge.Bridge; -import com.appsmith.server.repositories.CacheableRepositoryHelper; -import com.appsmith.server.repositories.TenantRepository; -import com.appsmith.server.repositories.UserRepository; -import com.appsmith.server.services.FeatureFlagService; -import com.appsmith.server.services.TenantService; -import com.appsmith.server.solutions.EnvManager; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.security.test.context.support.WithUserDetails; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import static com.appsmith.external.enums.FeatureFlagEnum.TENANT_TEST_FEATURE; -import static com.appsmith.external.enums.FeatureFlagEnum.TEST_FEATURE_2; -import static com.appsmith.server.constants.MigrationStatus.COMPLETED; -import static com.appsmith.server.constants.MigrationStatus.IN_PROGRESS; -import static com.appsmith.server.exceptions.AppsmithErrorCode.FEATURE_FLAG_MIGRATION_FAILURE; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; - -@SpringBootTest -class TenantServiceCETest { - - @Autowired - TenantService tenantService; - - @MockBean - EnvManager envManager; - - @Autowired - UserRepository userRepository; - - @Autowired - TenantRepository tenantRepository; - - @Autowired - UserUtils userUtils; - - @SpyBean - FeatureFlagService featureFlagService; - - @Autowired - ReactiveRedisTemplate reactiveRedisTemplate; - - @SpyBean - CacheManager cacheManager; - - @SpyBean - CacheableRepositoryHelper cacheableRepositoryHelper; - - @MockBean - FeatureFlagMigrationHelper featureFlagMigrationHelper; - - TenantConfiguration originalTenantConfiguration; - - @BeforeEach - public void setup() throws IOException { - final Tenant tenant = tenantService.getDefaultTenant().block(); - assert tenant != null; - originalTenantConfiguration = tenant.getTenantConfiguration(); - - tenantRepository - .updateAndReturn(tenant.getId(), Bridge.update().set(Tenant.Fields.tenantConfiguration, null), null) - .block(); - - // Make api_user super-user to test tenant admin functionality - // Todo change this to tenant admin once we introduce multitenancy - userRepository - .findByEmail("api_user") - .flatMap(user -> userUtils.makeSuperUser(List.of(user))) - .block(); - doReturn(Mono.empty()).when(cacheManager).get(anyString(), anyString()); - } - - @AfterEach - public void cleanup() { - Tenant updatedTenant = new Tenant(); - updatedTenant.setTenantConfiguration(originalTenantConfiguration); - tenantService - .getDefaultTenantId() - .flatMap(tenantId -> tenantService.update(tenantId, updatedTenant)) - .doOnError(error -> { - System.err.println("Error during cleanup: " + error.getMessage()); - }) - .block(); - } - - @Test - void ensureMapsKey() { - StepVerifier.create(tenantService.getTenantConfiguration()) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration().getGoogleMapsKey()) - .isNull(); - }) - .verifyComplete(); - } - - @Test - @WithUserDetails("api_user") - void setMapsKeyAndGetItBack() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setGoogleMapsKey("test-key"); - - final Mono resultMono = - tenantService.updateDefaultTenantConfiguration(changes).map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .assertNext(tenantConfiguration -> { - assertThat(tenantConfiguration.getGoogleMapsKey()).isEqualTo("test-key"); - }) - .verifyComplete(); - } - - @Test - void setMapsKeyWithoutAuthentication() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setGoogleMapsKey("test-key"); - - final Mono resultMono = tenantService.updateDefaultTenantConfiguration(changes); - - StepVerifier.create(resultMono) - .expectErrorMatches(error -> { - assertThat(error.getMessage()).startsWith("Unable to find tenant "); - return true; - }) - .verify(); - } - - @Test - @WithUserDetails("usertest@usertest.com") - void setMapsKeyWithoutAuthorization() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setGoogleMapsKey("test-key"); - - final Mono resultMono = tenantService.updateDefaultTenantConfiguration(changes); - - StepVerifier.create(resultMono) - .expectErrorMatches(error -> { - assertThat(error.getMessage()).startsWith("Unable to find tenant "); - return true; - }) - .verify(); - } - - @Test - @WithUserDetails("anonymousUser") - void getTenantConfig_Valid_AnonymousUser() { - StepVerifier.create(tenantService.getTenantConfiguration()) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration()).isNotNull(); - assertThat(tenant.getTenantConfiguration().getLicense()).isNotNull(); - assertThat(tenant.getTenantConfiguration().getLicense().getPlan()) - .isEqualTo(LicensePlan.FREE); - }) - .verifyComplete(); - } - - @Test - @WithUserDetails("api_user") - void setEmailVerificationEnabled_WithInvalidSMTPHost_ReturnsError() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setEmailVerificationEnabled(TRUE); - - Map envVars = new HashMap<>(); - // adding invalid mail host - envVars.put("APPSMITH_MAIL_HOST", ""); - - // mocking env vars file - Mockito.when(envManager.getAllNonEmpty()).thenReturn(Mono.just(envVars)); - - final Mono resultMono = tenantService - .updateDefaultTenantConfiguration(changes) - .then(tenantService.getTenantConfiguration()) - .map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .expectErrorMatches(error -> { - assertThat(error.getMessage()).startsWith("Your SMTP configuration is invalid"); - return true; - }) - .verify(); - } - - @Test - @WithUserDetails("api_user") - void setEmailVerificationEnabled_WithValidSMTPHost_Success() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setEmailVerificationEnabled(TRUE); - - Map envVars = new HashMap<>(); - // adding valid mail host - envVars.put("APPSMITH_MAIL_HOST", "smtp.sendgrid.net"); - - // mocking env vars file - Mockito.when(envManager.getAllNonEmpty()).thenReturn(Mono.just(envVars)); - - final Mono resultMono = tenantService - .updateDefaultTenantConfiguration(changes) - .then(tenantService.getTenantConfiguration()) - .map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .assertNext(tenantConfiguration -> { - assertThat(tenantConfiguration.isEmailVerificationEnabled()).isTrue(); - }) - .verifyComplete(); - } - - @Test - @WithUserDetails("api_user") - void setEmailVerificationEnabledFalseAndGetItBack() { - final TenantConfiguration changes = new TenantConfiguration(); - changes.setEmailVerificationEnabled(Boolean.FALSE); - - final Mono resultMono = tenantService - .updateDefaultTenantConfiguration(changes) - .then(tenantService.getTenantConfiguration()) - .map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .assertNext(tenantConfiguration -> { - assertThat(tenantConfiguration.isEmailVerificationEnabled()).isFalse(); - }) - .verifyComplete(); - } - - @Test - void checkAndExecuteMigrationsForTenantFeatureFlags_emptyMigrationMap_revertSameTenant() { - Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) - .thenReturn(Mono.just(TRUE)); - - Tenant tenant = new Tenant(); - tenant.setId(UUID.randomUUID().toString()); - TenantConfiguration config = new TenantConfiguration(); - config.setFeaturesWithPendingMigration(new HashMap<>()); - tenant.setTenantConfiguration(config); - final Mono resultMono = tenantService.checkAndExecuteMigrationsForTenantFeatureFlags(tenant); - StepVerifier.create(resultMono) - .assertNext(tenant1 -> { - assertThat(tenant1).isEqualTo(tenant); - assertThat(tenant1.getTenantConfiguration().getFeaturesWithPendingMigration()) - .isEmpty(); - assertThat(tenant1.getTenantConfiguration().getMigrationStatus()) - .isEqualTo(COMPLETED); - }) - .verifyComplete(); - } - - @Test - void checkAndExecuteMigrationsForTenantFeatureFlags_withPendingMigration_getUpdatedTenant() { - Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) - .thenReturn(Mono.just(TRUE)); - - Tenant tenant = new Tenant(); - tenant.setId(UUID.randomUUID().toString()); - TenantConfiguration config = new TenantConfiguration(); - Map featureMigrationTypeMap = new HashMap<>(); - config.setFeaturesWithPendingMigration(featureMigrationTypeMap); - featureMigrationTypeMap.put(TENANT_TEST_FEATURE, FeatureMigrationType.ENABLE); - featureMigrationTypeMap.put(TEST_FEATURE_2, FeatureMigrationType.DISABLE); - tenant.setTenantConfiguration(config); - final Mono resultMono = tenantService.checkAndExecuteMigrationsForTenantFeatureFlags(tenant); - StepVerifier.create(resultMono) - .assertNext(tenant1 -> { - assertThat(tenant1.getTenantConfiguration().getFeaturesWithPendingMigration()) - .isEmpty(); - assertThat(tenant1.getTenantConfiguration().getMigrationStatus()) - .isEqualTo(COMPLETED); - }) - .verifyComplete(); - } - - @Test - @WithUserDetails("api_user") - void - checkAndExecuteMigrationsForTenantFeatureFlags_withPendingMigration_exceptionWhileRunningMigration_getUpdatedTenant() { - Mockito.when(featureFlagMigrationHelper.checkAndExecuteMigrationsForFeatureFlag(any(), any())) - .thenReturn(Mono.just(TRUE)) - .thenReturn(Mono.just(FALSE)); - - Tenant tenant = new Tenant(); - tenant.setId(UUID.randomUUID().toString()); - TenantConfiguration config = new TenantConfiguration(); - Map featureMigrationTypeMap = new HashMap<>(); - config.setFeaturesWithPendingMigration(featureMigrationTypeMap); - featureMigrationTypeMap.put(TENANT_TEST_FEATURE, FeatureMigrationType.DISABLE); - featureMigrationTypeMap.put(TEST_FEATURE_2, FeatureMigrationType.ENABLE); - tenant.setTenantConfiguration(config); - final Mono resultMono = tenantService.checkAndExecuteMigrationsForTenantFeatureFlags(tenant); - - // Verify that the feature flag migration failure is thrown - StepVerifier.create(resultMono) - .expectErrorSatisfies(throwable -> { - assertThat(throwable instanceof AppsmithException).isTrue(); - assertThat(((AppsmithException) throwable).getAppErrorCode()) - .isEqualTo(FEATURE_FLAG_MIGRATION_FAILURE.getCode()); - }) - .verify(); - - // Verify that the tenant is updated for the feature flag migration failure - StepVerifier.create(tenantService.getByIdWithoutPermissionCheck(tenant.getId())) - .assertNext(updatedTenant -> { - assertThat(updatedTenant.getTenantConfiguration().getFeaturesWithPendingMigration()) - .hasSize(1); - assertThat(updatedTenant.getTenantConfiguration().getMigrationStatus()) - .isEqualTo(IN_PROGRESS); - }) - .verifyComplete(); - } - - @Test - @WithUserDetails("api_user") - void updateTenantConfiguration_updateStrongPasswordPolicy_success() { - - // Ensure that the default tenant does not have strong password policy setup - Mono tenantMono = tenantService.getDefaultTenant(); - StepVerifier.create(tenantMono) - .assertNext(tenant -> { - assertThat(tenant.getTenantConfiguration().getIsStrongPasswordPolicyEnabled()) - .isNull(); - }) - .verifyComplete(); - - // Ensure that the strong password policy is enabled after the update - final TenantConfiguration changes = new TenantConfiguration(); - changes.setIsStrongPasswordPolicyEnabled(TRUE); - Mono resultMono = tenantService - .updateDefaultTenantConfiguration(changes) - .then(tenantService.getTenantConfiguration()) - .map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .assertNext(tenantConfiguration -> { - assertThat(tenantConfiguration.getIsStrongPasswordPolicyEnabled()) - .isTrue(); - }) - .verifyComplete(); - - // Ensure that the strong password policy is disabled after the update - changes.setIsStrongPasswordPolicyEnabled(FALSE); - resultMono = tenantService - .updateDefaultTenantConfiguration(changes) - .then(tenantService.getTenantConfiguration()) - .map(Tenant::getTenantConfiguration); - - StepVerifier.create(resultMono) - .assertNext(tenantConfiguration -> { - assertThat(tenantConfiguration.getIsStrongPasswordPolicyEnabled()) - .isFalse(); - }) - .verifyComplete(); - } - - /** - * This test checks that the tenant cache is created and data is fetched without any deserialization errors - * This will ensure if any new nested user-defined classes are created in the tenant object in the future, and - * implements serializable is missed for that class, the deserialization will fail leads this test to fail. - */ - @Test - @WithUserDetails(value = "api_user") - public void testDeserializationErrors() { - String tenantId = tenantService.getDefaultTenantId().block(); - Mono evictTenantCache = cacheableRepositoryHelper.evictCachedTenant(tenantId); - Mono hasKeyMono = reactiveRedisTemplate.hasKey("tenant:" + tenantId); - Mono cachedTenant = tenantService.getDefaultTenant(); - StepVerifier.create(evictTenantCache.then(cachedTenant).then(hasKeyMono)) - .assertNext(Assertions::assertTrue) - .verifyComplete(); - } -} diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java index 05d302d4d203..5bcb12f37009 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/EnvManagerTest.java @@ -14,9 +14,9 @@ import com.appsmith.server.services.AssetService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.PermissionGroupService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.services.UserService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; @@ -81,7 +81,7 @@ public class EnvManagerTest { private UserUtils userUtils; @MockBean - private TenantService tenantService; + private OrganizationService organizationService; @MockBean private ObjectMapper objectMapper; @@ -108,7 +108,7 @@ public void setup() { permissionGroupService, configService, userUtils, - tenantService, + organizationService, objectMapper, emailService); } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/UserSignupTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/UserSignupTest.java index b00c0e0bd6c9..f47afc744b59 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/UserSignupTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/UserSignupTest.java @@ -1,8 +1,8 @@ package com.appsmith.server.solutions; import com.appsmith.server.authentication.handlers.AuthenticationSuccessHandler; -import com.appsmith.server.domains.Tenant; -import com.appsmith.server.domains.TenantConfiguration; +import com.appsmith.server.domains.Organization; +import com.appsmith.server.domains.OrganizationConfiguration; import com.appsmith.server.domains.User; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; @@ -12,7 +12,7 @@ import com.appsmith.server.services.CaptchaService; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.EmailService; -import com.appsmith.server.services.TenantService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.UserDataService; import com.appsmith.server.services.UserService; import org.junit.jupiter.api.BeforeEach; @@ -64,11 +64,11 @@ public class UserSignupTest { private EmailService emailService; @MockBean - private TenantService tenantService; + private OrganizationService organizationService; private UserSignup userSignup; - private static Tenant tenant; + private static Organization organization; private static ServerWebExchange exchange; @@ -85,15 +85,15 @@ public void setup() { userUtils, networkUtils, emailService, - tenantService); + organizationService); exchange = Mockito.mock(ServerWebExchange.class); Mockito.when(exchange.getSession()).thenReturn(Mono.just(new MockWebSession())); - tenant = new Tenant(); - TenantConfiguration configuration = new TenantConfiguration(); - tenant.setTenantConfiguration(configuration); - Mockito.when(tenantService.getDefaultTenant()).thenReturn(Mono.just(tenant)); + organization = new Organization(); + OrganizationConfiguration configuration = new OrganizationConfiguration(); + organization.setOrganizationConfiguration(configuration); + Mockito.when(organizationService.getDefaultOrganization()).thenReturn(Mono.just(organization)); } private String createRandomString(int length) { @@ -141,8 +141,8 @@ public void signupAndLogin_whenStrongPasswordRequirementEnabled_whenPasswordIsWe user.setEmail("testemail@test123.com"); user.setPassword(createRandomString(LOGIN_PASSWORD_MAX_LENGTH - 1)); - tenant.getTenantConfiguration().setIsStrongPasswordPolicyEnabled(true); - Mockito.when(tenantService.getDefaultTenant()).thenReturn(Mono.just(tenant)); + organization.getOrganizationConfiguration().setIsStrongPasswordPolicyEnabled(true); + Mockito.when(organizationService.getDefaultOrganization()).thenReturn(Mono.just(organization)); Mono userMono = userSignup.signupAndLogin(user, exchange); StepVerifier.create(userMono) .expectErrorSatisfies(throwable -> { @@ -154,6 +154,6 @@ public void signupAndLogin_whenStrongPasswordRequirementEnabled_whenPasswordIsWe }) .verify(); - tenant.getTenantConfiguration().setIsStrongPasswordPolicyEnabled(false); + organization.getOrganizationConfiguration().setIsStrongPasswordPolicyEnabled(false); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java index 0fc84add17f8..d1c1bfe57dd3 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java @@ -25,8 +25,8 @@ import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; import com.appsmith.server.services.FeatureFlagService; +import com.appsmith.server.services.OrganizationService; import com.appsmith.server.services.SessionUserService; -import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.EnvironmentPermission; @@ -129,7 +129,7 @@ class ActionExecutionSolutionCEImplTest { ConfigService configService; @SpyBean - TenantService tenantService; + OrganizationService organizationService; @SpyBean CommonConfig commonConfig; @@ -169,7 +169,7 @@ public void beforeEach() { datasourceStorageService, environmentPermission, configService, - tenantService, + organizationService, commonConfig, actionExecutionSolutionHelper, featureFlagService); diff --git a/update-tenant-client.sh b/update-tenant-client.sh new file mode 100755 index 000000000000..f0c0e1cb59d7 --- /dev/null +++ b/update-tenant-client.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Navigate to the client src directory +cd app/client/src || { echo "Failed to navigate to app/client/src directory"; exit 1; } + +# First, find and rename files containing 'tenant' or 'tentant' in their names +find . -type f \ + \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) \ + ! -path "*/cypress/fixtures/*" \ + ! -path "*/assets/*" \ + ! -name "*.pdf" \ + ! -name "*.png" \ + ! -name "*.jpg" \ + ! -name "*.jpeg" \ + ! -name "*.gif" \ + ! -name "*.mp4" \ + ! -name "*.webm" \ + ! -name "*.svg" | while read -r file; do + + # Check if filename contains 'tenant' or 'tentant' (case-insensitive) + filename=$(basename "$file") + dirname=$(dirname "$file") + + # Create new filename replacing both spellings + newfilename=$(echo "$filename" | sed -e 's/tentant/organization/g' -e 's/Tentant/Organization/g' -e 's/tenant/organization/g' -e 's/Tenant/Organization/g') + + # If filename changed, rename the file + if [ "$filename" != "$newfilename" ]; then + mv "$file" "$dirname/$newfilename" + echo "Renamed: $file → $dirname/$newfilename" + # Update file variable to point to new location + file="$dirname/$newfilename" + fi + + # Create backup + cp "$file" "$file.bak" + + # Perform content replacements + sed -i.tmp \ + -e 's/tentantConfiguration/organizationConfiguration/g' \ + -e 's/TentantConfiguration/OrganizationConfiguration/g' \ + -e 's/TENTANT_CONFIGURATION/ORGANIZATION_CONFIGURATION/g' \ + -e 's/tenantConfiguration/organizationConfiguration/g' \ + -e 's/TenantConfiguration/OrganizationConfiguration/g' \ + -e 's/TENANT_CONFIGURATION/ORGANIZATION_CONFIGURATION/g' \ + -e 's/\([^a-zA-Z0-9]\)tentant\([^a-zA-Z0-9]\)/\1organization\2/g' \ + -e 's/\([^a-zA-Z0-9]\)Tentant\([^a-zA-Z0-9]\)/\1Organization\2/g' \ + -e 's/\([^a-zA-Z0-9]\)TENTANT\([^a-zA-Z0-9]\)/\1ORGANIZATION\2/g' \ + -e 's/\([^a-zA-Z0-9]\)tenant\([^a-zA-Z0-9]\)/\1organization\2/g' \ + -e 's/\([^a-zA-Z0-9]\)Tenant\([^a-zA-Z0-9]\)/\1Organization\2/g' \ + -e 's/\([^a-zA-Z0-9]\)TENANT\([^a-zA-Z0-9]\)/\1ORGANIZATION\2/g' \ + -e 's/Tentant\([A-Z]\)/Organization\1/g' \ + -e 's/tentant\([A-Z]\)/organization\1/g' \ + -e 's/Tenant\([A-Z]\)/Organization\1/g' \ + -e 's/tenant\([A-Z]\)/organization\1/g' \ + -e 's/\([a-z]\)Tentant/\1Organization/g' \ + -e 's/\([a-z]\)tentant/\1organization/g' \ + -e 's/\([a-z]\)Tenant/\1Organization/g' \ + -e 's/\([a-z]\)tenant/\1organization/g' \ + "$file" + + # Compare files to see if content was modified + if ! cmp -s "$file" "$file.bak"; then + echo "Updated content: $file" + fi + + # Clean up temporary files + rm "$file.bak" + rm "$file.tmp" +done + +echo "Replacement complete!" \ No newline at end of file