fix: [one-click-binding] gsheets connection mode issue (#27613)
## Description Updated the permission check on the Google sheet to look in the following path `atasourceConfiguration.authentication.scopeString` #### PR fixes following issue(s) Fixes https://github.com/appsmithorg/appsmith/issues/27102 > if no issue exists, please create an issue and ask the maintainers about this first > > #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (fix or feature that would cause existing functionality to not work as expected) - Chore (housekeeping or task changes that don't impact user perception) - This change requires a documentation update > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed
This commit is contained in:
parent
fb12f6ad87
commit
c2cc455fb6
|
|
@ -1 +1,9 @@
|
||||||
export class BaseQueryGenerator {}
|
import type { DatasourceStorage } from "entities/Datasource";
|
||||||
|
|
||||||
|
export class BaseQueryGenerator {
|
||||||
|
static getConnectionMode(
|
||||||
|
datasourceConfiguration: DatasourceStorage["datasourceConfiguration"],
|
||||||
|
) {
|
||||||
|
return datasourceConfiguration?.connection?.mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import type {
|
||||||
} from "WidgetQueryGenerators/types";
|
} from "WidgetQueryGenerators/types";
|
||||||
import { removeSpecialChars } from "utils/helpers";
|
import { removeSpecialChars } from "utils/helpers";
|
||||||
import { DatasourceConnectionMode } from "entities/Datasource";
|
import { DatasourceConnectionMode } from "entities/Datasource";
|
||||||
|
import type { DatasourceStorage } from "entities/Datasource";
|
||||||
|
|
||||||
enum COMMAND_TYPES {
|
enum COMMAND_TYPES {
|
||||||
"FIND" = "FETCH_MANY",
|
"FIND" = "FETCH_MANY",
|
||||||
|
|
@ -47,6 +48,7 @@ export default abstract class GSheets extends BaseQueryGenerator {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static buildFind(
|
private static buildFind(
|
||||||
widgetConfig: WidgetQueryGenerationConfig,
|
widgetConfig: WidgetQueryGenerationConfig,
|
||||||
formConfig: WidgetQueryGenerationFormConfig,
|
formConfig: WidgetQueryGenerationFormConfig,
|
||||||
|
|
@ -306,6 +308,16 @@ export default abstract class GSheets extends BaseQueryGenerator {
|
||||||
return configs.filter((val) => !!val);
|
return configs.filter((val) => !!val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getConnectionMode(
|
||||||
|
datasourceConfiguration: DatasourceStorage["datasourceConfiguration"],
|
||||||
|
) {
|
||||||
|
return datasourceConfiguration?.authentication?.scopeString?.includes(
|
||||||
|
"spreadsheets.readonly",
|
||||||
|
)
|
||||||
|
? DatasourceConnectionMode.READ_ONLY
|
||||||
|
: DatasourceConnectionMode.READ_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
static getTotalRecordExpression(binding: string) {
|
static getTotalRecordExpression(binding: string) {
|
||||||
return `${binding}.length`;
|
return `${binding}.length`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import { getCurrentWorkspaceId } from "@appsmith/selectors/workspaceSelectors";
|
||||||
import type { WidgetProps } from "widgets/BaseWidget";
|
import type { WidgetProps } from "widgets/BaseWidget";
|
||||||
import { WidgetQueryGeneratorFormContext } from "components/editorComponents/WidgetQueryGeneratorForm/index";
|
import { WidgetQueryGeneratorFormContext } from "components/editorComponents/WidgetQueryGeneratorForm/index";
|
||||||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||||
|
import { getDatasourceConnectionMode } from "components/editorComponents/WidgetQueryGeneratorForm/utils";
|
||||||
|
|
||||||
interface DatasourceOptionsProps {
|
interface DatasourceOptionsProps {
|
||||||
widget: WidgetProps;
|
widget: WidgetProps;
|
||||||
|
|
@ -83,10 +84,10 @@ function useDatasourceOptions(props: DatasourceOptionsProps) {
|
||||||
isValid: isEnvironmentValid(datasource, currentEnvironment),
|
isValid: isEnvironmentValid(datasource, currentEnvironment),
|
||||||
pluginPackageName: pluginsPackageNamesMap[datasource.pluginId],
|
pluginPackageName: pluginsPackageNamesMap[datasource.pluginId],
|
||||||
isSample: false,
|
isSample: false,
|
||||||
connectionMode: getEnvironmentConfiguration(
|
connectionMode: getDatasourceConnectionMode(
|
||||||
datasource,
|
pluginsPackageNamesMap[datasource.pluginId],
|
||||||
currentEnvironment,
|
getEnvironmentConfiguration(datasource, currentEnvironment),
|
||||||
)?.connection?.mode,
|
),
|
||||||
},
|
},
|
||||||
icon: (
|
icon: (
|
||||||
<ImageWrapper>
|
<ImageWrapper>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import WidgetQueryGeneratorRegistry from "utils/WidgetQueryGeneratorRegistry";
|
||||||
|
import { getDatasourceConnectionMode } from "./utils";
|
||||||
|
import type { DatasourceStorage } from "entities/Datasource";
|
||||||
|
import { PluginPackageName } from "entities/Action";
|
||||||
|
import PostgreSQL from "WidgetQueryGenerators/PostgreSQL";
|
||||||
|
import GSheets from "WidgetQueryGenerators/GSheets";
|
||||||
|
|
||||||
|
describe("getDatasourceConnectionMode", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
WidgetQueryGeneratorRegistry.register(
|
||||||
|
PluginPackageName.POSTGRES,
|
||||||
|
PostgreSQL,
|
||||||
|
);
|
||||||
|
WidgetQueryGeneratorRegistry.register(
|
||||||
|
PluginPackageName.GOOGLE_SHEETS,
|
||||||
|
GSheets,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the connection mode from the query generator", () => {
|
||||||
|
expect(
|
||||||
|
getDatasourceConnectionMode(PluginPackageName.POSTGRES, {
|
||||||
|
connection: {
|
||||||
|
mode: "READ_ONLY",
|
||||||
|
},
|
||||||
|
} as DatasourceStorage["datasourceConfiguration"]),
|
||||||
|
).toEqual("READ_ONLY");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getDatasourceConnectionMode(PluginPackageName.GOOGLE_SHEETS, {
|
||||||
|
authentication: {
|
||||||
|
scopeString: "spreadsheets.readonly",
|
||||||
|
},
|
||||||
|
} as DatasourceStorage["datasourceConfiguration"]),
|
||||||
|
).toEqual("READ_ONLY");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getDatasourceConnectionMode(PluginPackageName.GOOGLE_SHEETS, {
|
||||||
|
authentication: {
|
||||||
|
scopeString: "spreadsheets",
|
||||||
|
},
|
||||||
|
} as DatasourceStorage["datasourceConfiguration"]),
|
||||||
|
).toEqual("READ_WRITE");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return null if the query generator is not found", () => {
|
||||||
|
const result = getDatasourceConnectionMode(
|
||||||
|
"non-existent-plugin-package-name",
|
||||||
|
{
|
||||||
|
connection: {
|
||||||
|
mode: "READ_ONLY",
|
||||||
|
},
|
||||||
|
} as DatasourceStorage["datasourceConfiguration"],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toBe(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { isNumber } from "lodash";
|
import { isNumber } from "lodash";
|
||||||
|
import WidgetQueryGeneratorRegistry from "utils/WidgetQueryGeneratorRegistry";
|
||||||
|
import type { DatasourceStorage } from "entities/Datasource";
|
||||||
|
|
||||||
export const getSheetUrl = (sheetId: string): string =>
|
export const getSheetUrl = (sheetId: string): string =>
|
||||||
`https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
|
`https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
|
||||||
|
|
@ -9,3 +11,12 @@ export const isValidGsheetConfig = (config: Record<string, any>) =>
|
||||||
isNumber(Number(config.tableHeaderIndex)) &&
|
isNumber(Number(config.tableHeaderIndex)) &&
|
||||||
!isNaN(Number(config.tableHeaderIndex)) &&
|
!isNaN(Number(config.tableHeaderIndex)) &&
|
||||||
config.tableHeaderIndex > 0;
|
config.tableHeaderIndex > 0;
|
||||||
|
|
||||||
|
export const getDatasourceConnectionMode = (
|
||||||
|
pluginPackageName: string,
|
||||||
|
datasourceConfiguration?: DatasourceStorage["datasourceConfiguration"],
|
||||||
|
) => {
|
||||||
|
const queryGenerator = WidgetQueryGeneratorRegistry.get(pluginPackageName);
|
||||||
|
|
||||||
|
return queryGenerator?.getConnectionMode(datasourceConfiguration);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ export interface DatasourceAuthentication {
|
||||||
authenticationType?: string;
|
authenticationType?: string;
|
||||||
secretExists?: Record<string, boolean>;
|
secretExists?: Record<string, boolean>;
|
||||||
isAuthorized?: boolean;
|
isAuthorized?: boolean;
|
||||||
|
scopeString?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatasourceColumns {
|
export interface DatasourceColumns {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user