diff --git a/.gitignore b/.gitignore index cf1d1e01d5..1f002f8b84 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .vscode/* app/client/cypress.env.json +stacks # to ignore the node_modeules folder node_modules diff --git a/app/client/cypress/fixtures/githubSource.json b/app/client/cypress/fixtures/githubSource.json new file mode 100644 index 0000000000..2b7975ebcc --- /dev/null +++ b/app/client/cypress/fixtures/githubSource.json @@ -0,0 +1,4 @@ +{ + "githubClientId": "", + "githubClientSecret": "" +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/googleSource.json b/app/client/cypress/fixtures/googleSource.json new file mode 100644 index 0000000000..70fa5bb342 --- /dev/null +++ b/app/client/cypress/fixtures/googleSource.json @@ -0,0 +1,5 @@ +{ + "googleClientId": "", + "googleClientSecret": "", + "googleAllowedDomains": "appsmith.com" +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/EnterpriseTests/AdminSettings/Admin_settings_spec.js b/app/client/cypress/integration/Smoke_TestSuite/EnterpriseTests/AdminSettings/Admin_settings_spec.js index 13c13a76ea..55d28c01ca 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/EnterpriseTests/AdminSettings/Admin_settings_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/EnterpriseTests/AdminSettings/Admin_settings_spec.js @@ -23,9 +23,11 @@ describe("Admin settings page", function() { cy.visit("/settings/general"); cy.get(adminsSettings.authenticationTab).click(); cy.url().should("contain", "/settings/authentication"); - cy.get(EnterpriseAdminSettingsLocators.upgradeButton).each(($el) => { - cy.wrap($el).should("be.visible"); - cy.wrap($el).should("contain", "UPGRADE"); - }); + cy.get(EnterpriseAdminSettingsLocators.upgradeOidcButton) + .should("be.visible") + .should("contain", "UPGRADE"); + cy.get(EnterpriseAdminSettingsLocators.upgradeSamlButton) + .should("be.visible") + .should("contain", "UPGRADE"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Github/EnableGithub_spec.js b/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Github/EnableGithub_spec.js new file mode 100644 index 0000000000..6a732c6816 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Github/EnableGithub_spec.js @@ -0,0 +1,103 @@ +const adminSettings = require("../../../../locators/AdminsSettings"); +const commonlocators = require("../../../../locators/commonlocators.json"); +import homePage from "../../../../locators/HomePage"; + +describe("SSO with Github test functionality", function() { + it("1. Go to admin settings and enable Github with not all mandatory fields filled", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.githubButton) + .should("be.visible") + .should("contain", "ENABLE"); + cy.get(adminSettings.githubButton).click(); + cy.wait(2000); + // fill github form + cy.fillGithubFormPartly(); + cy.get(commonlocators.toastBody).should("be.visible"); + cy.get(commonlocators.toastBody).should( + "contain", + "Mandatory fields cannot be empty", + ); + }); + + it("2. Go to admin settings and enable Github", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.githubButton) + .should("be.visible") + .should("contain", "ENABLE"); + cy.get(adminSettings.githubButton).click(); + cy.wait(2000); + // fill github form + cy.fillGithubForm(); + cy.wait(2000); + // assert server is restarting + cy.get(adminSettings.restartNotice).should("be.visible"); + // adding wait for server to restart + cy.wait(120000); + cy.waitUntil(() => cy.get(homePage.profileMenu).should("be.visible")); + cy.get(homePage.profileMenu).click(); + cy.get(homePage.signOutIcon).click(); + cy.wait(500); + // validating sso with github is enabled + cy.get(adminSettings.loginWithGithub).should( + "have.text", + "continue with Github", + ); + }); + + it("3. Go to admin settings and disable Github", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.githubButton) + .should("be.visible") + .should("contain", "EDIT"); + cy.get(adminSettings.githubButton).click(); + cy.wait(2000); + cy.get(adminSettings.disconnectBtn) + .should("be.visible") + .should("contain", "Disconnect"); + cy.get(adminSettings.disconnectBtn) + .click() + .should("contain", "Are you sure?"); + cy.get(adminSettings.disconnectBtn).click(); + + // assert server is restarting + cy.get(adminSettings.restartNotice).should("be.visible"); + // adding wait for server to restart + cy.wait(120000); + cy.waitUntil(() => cy.get(homePage.profileMenu).should("be.visible")); + cy.get(homePage.profileMenu).click(); + cy.get(homePage.signOutIcon).click(); + cy.wait(500); + // validating sso with github is disabled + cy.get(adminSettings.loginWithGithub).should("not.exist"); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Google/EnableGoogle_spec.js b/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Google/EnableGoogle_spec.js new file mode 100644 index 0000000000..a9ed62b651 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite_Fat/ClientSideTests/Google/EnableGoogle_spec.js @@ -0,0 +1,103 @@ +const adminSettings = require("../../../../locators/AdminsSettings"); +const commonlocators = require("../../../../locators/commonlocators.json"); +import homePage from "../../../../locators/HomePage"; + +describe("SSO with Google test functionality", function() { + it("1. Go to admin settings and enable Google with not all mandatory fields filled", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.googleButton) + .should("be.visible") + .should("contain", "ENABLE"); + cy.get(adminSettings.googleButton).click(); + cy.wait(2000); + // fill google form + cy.fillGoogleFormPartly(); + cy.get(commonlocators.toastBody).should("be.visible"); + cy.get(commonlocators.toastBody).should( + "contain", + "Mandatory fields cannot be empty", + ); + }); + + it("2. Go to admin settings and enable Google", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.googleButton) + .should("be.visible") + .should("contain", "ENABLE"); + cy.get(adminSettings.googleButton).click(); + cy.wait(2000); + // fill google form + cy.fillGoogleForm(); + cy.wait(2000); + // assert server is restarting + cy.get(adminSettings.restartNotice).should("be.visible"); + // adding wait for server to restart + cy.wait(120000); + cy.waitUntil(() => cy.get(homePage.profileMenu).should("be.visible")); + cy.get(homePage.profileMenu).click(); + cy.get(homePage.signOutIcon).click(); + cy.wait(500); + // validating sso with google is enabled + cy.get(adminSettings.loginWithGoogle).should( + "have.text", + "continue with Google", + ); + }); + + it("3. Go to admin settings and disable Google", function() { + cy.LogOut(); + cy.LoginFromAPI(Cypress.env("USERNAME"), Cypress.env("PASSWORD")); + cy.visit("/applications"); + cy.get(".t--profile-menu-icon").should("be.visible"); + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--admin-settings-menu").should("be.visible"); + cy.get(".t--admin-settings-menu").click(); + cy.url().should("contain", "/settings/general"); + // click authentication tab + cy.get(adminSettings.authenticationTab).click(); + cy.url().should("contain", "/settings/authentication"); + cy.get(adminSettings.googleButton) + .should("be.visible") + .should("contain", "EDIT"); + cy.get(adminSettings.googleButton).click(); + cy.wait(2000); + cy.get(adminSettings.disconnectBtn) + .should("be.visible") + .should("contain", "Disconnect"); + cy.get(adminSettings.disconnectBtn) + .click() + .should("contain", "Are you sure?"); + cy.get(adminSettings.disconnectBtn).click(); + + // assert server is restarting + cy.get(adminSettings.restartNotice).should("be.visible"); + // adding wait for server to restart + cy.wait(120000); + cy.waitUntil(() => cy.get(homePage.profileMenu).should("be.visible")); + cy.get(homePage.profileMenu).click(); + cy.get(homePage.signOutIcon).click(); + cy.wait(500); + // validating sso with google is disabled + cy.get(adminSettings.loginWithGoogle).should("not.exist"); + }); +}); diff --git a/app/client/cypress/locators/AdminsSettings.js b/app/client/cypress/locators/AdminsSettings.js index 63275ea0ca..23f2acf0ae 100644 --- a/app/client/cypress/locators/AdminsSettings.js +++ b/app/client/cypress/locators/AdminsSettings.js @@ -20,4 +20,7 @@ export default { restartNotice: ".t--admin-settings-restart-notice", appsmithLogo: ".t--appsmith-logo", appsmithHeader: "[data-testid='t--appsmith-page-header']", + loginWithGoogle: "[data-testid='login-with-Google']", + loginWithGithub: "[data-testid='login-with-Github']", + disconnectBtn: "[data-testid='disconnect-service-button']", }; diff --git a/app/client/cypress/locators/EnterpriseAdminSettingsLocators.json b/app/client/cypress/locators/EnterpriseAdminSettingsLocators.json index 18478b2e93..eebcadee62 100644 --- a/app/client/cypress/locators/EnterpriseAdminSettingsLocators.json +++ b/app/client/cypress/locators/EnterpriseAdminSettingsLocators.json @@ -1,3 +1,4 @@ { - "upgradeButton": ".t--settings-sub-category-upgrade" + "upgradeSamlButton": ".t--settings-sub-category-upgrade-saml", + "upgradeOidcButton": ".t--settings-sub-category-upgrade-oidc" } \ No newline at end of file diff --git a/app/client/cypress/locators/GithubForm.json b/app/client/cypress/locators/GithubForm.json new file mode 100644 index 0000000000..d1d9e6c986 --- /dev/null +++ b/app/client/cypress/locators/GithubForm.json @@ -0,0 +1,5 @@ +{ + "githubClientId": "[name='APPSMITH_OAUTH2_GITHUB_CLIENT_ID']", + "githubClientSecret": "[name='APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET']", + "saveBtn": ".t--admin-settings-save-button" +} \ No newline at end of file diff --git a/app/client/cypress/locators/GoogleForm.json b/app/client/cypress/locators/GoogleForm.json new file mode 100644 index 0000000000..4a002882c6 --- /dev/null +++ b/app/client/cypress/locators/GoogleForm.json @@ -0,0 +1,6 @@ +{ + "googleClientId": "[name='APPSMITH_OAUTH2_GOOGLE_CLIENT_ID']", + "googleClientSecret": "[name='APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET']", + "googleAllowedDomains": "[name='APPSMITH_SIGNUP_ALLOWED_DOMAINS']", + "saveBtn": ".t--admin-settings-save-button" +} \ No newline at end of file diff --git a/app/client/cypress/support/AdminSettingsCommands.js b/app/client/cypress/support/AdminSettingsCommands.js new file mode 100644 index 0000000000..908dd5dff9 --- /dev/null +++ b/app/client/cypress/support/AdminSettingsCommands.js @@ -0,0 +1,46 @@ +/* eslint-disable cypress/no-unnecessary-waiting */ +/* eslint-disable cypress/no-assigning-return-values */ + +require("cy-verify-downloads").addCustomCommand(); +require("cypress-file-upload"); + +const googleForm = require("../locators/GoogleForm.json"); +const googleData = require("../fixtures/googleSource.json"); +const githubForm = require("../locators/GithubForm.json"); +const githubData = require("../fixtures/githubSource.json"); + +Cypress.Commands.add("fillGoogleFormPartly", () => { + cy.get(googleForm.googleClientId).type( + Cypress.env("APPSMITH_OAUTH2_GOOGLE_CLIENT_ID"), + ); + cy.get(googleForm.googleAllowedDomains).type(googleData.googleAllowedDomains); + cy.get(googleForm.saveBtn).click({ force: true }); +}); + +Cypress.Commands.add("fillGoogleForm", () => { + cy.get(googleForm.googleClientId).type( + Cypress.env("APPSMITH_OAUTH2_GOOGLE_CLIENT_ID"), + ); + cy.get(googleForm.googleClientSecret).type( + Cypress.env("APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET"), + ); + cy.get(googleForm.googleAllowedDomains).type(googleData.googleAllowedDomains); + cy.get(googleForm.saveBtn).click({ force: true }); +}); + +Cypress.Commands.add("fillGithubFormPartly", () => { + cy.get(githubForm.githubClientId).type( + Cypress.env("APPSMITH_OAUTH2_GITHUB_CLIENT_ID"), + ); + cy.get(githubForm.saveBtn).click({ force: true }); +}); + +Cypress.Commands.add("fillGithubForm", () => { + cy.get(githubForm.githubClientId).type( + Cypress.env("APPSMITH_OAUTH2_GITHUB_CLIENT_ID"), + ); + cy.get(githubForm.githubClientSecret).type( + Cypress.env("APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET"), + ); + cy.get(githubForm.saveBtn).click({ force: true }); +}); diff --git a/app/client/cypress/support/index.js b/app/client/cypress/support/index.js index ab6f7004fc..e8f0024268 100644 --- a/app/client/cypress/support/index.js +++ b/app/client/cypress/support/index.js @@ -28,6 +28,7 @@ import { initLocalstorageRegistry } from "./Objects/Registry"; import "./OrgCommands"; import "./queryCommands"; import "./widgetCommands"; +import "./AdminSettingsCommands"; /// Cypress.on("uncaught:exception", () => { diff --git a/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx b/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx index c0fa1e9b27..13667db915 100644 --- a/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx @@ -184,7 +184,11 @@ export function AuthPage({ authMethods }: { authMethods: AuthMethodType[] }) { openOnTargetFocus={false} position={Position.RIGHT} > - + )} @@ -202,7 +206,9 @@ export function AuthPage({ authMethods }: { authMethods: AuthMethodType[] }) { method.isConnected ? Category.primary : Category.tertiary } className={`t--settings-sub-category-${ - method.needsUpgrade ? "upgrade" : method.category + method.needsUpgrade + ? `upgrade-${method.category}` + : method.category }`} data-cy="btn-auth-account" onClick={() => diff --git a/app/client/src/ce/pages/AdminSettings/config/authentication/index.tsx b/app/client/src/ce/pages/AdminSettings/config/authentication/index.tsx index 8ad6f8530c..ff83d4392a 100644 --- a/app/client/src/ce/pages/AdminSettings/config/authentication/index.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/authentication/index.tsx @@ -181,6 +181,7 @@ export const Github_Auth_Callout: AuthMethodType = { export const Saml_Auth_Callout: AuthMethodType = { id: "APPSMITH_SAML_AUTH", + category: "saml", label: "SAML 2.0", subText: `Enable your organization to sign in with your preferred SAML2 compliant provider.`, image: SamlSso, @@ -190,6 +191,7 @@ export const Saml_Auth_Callout: AuthMethodType = { export const Oidc_Auth_Callout: AuthMethodType = { id: "APPSMITH_OIDC_AUTH", + category: "oidc", label: "OIDC", subText: `Enable your organization to sign in with Open ID Connect.`, image: OIDC, diff --git a/app/client/src/ce/pages/UserAuth/ThirdPartyAuth.tsx b/app/client/src/ce/pages/UserAuth/ThirdPartyAuth.tsx index 4033f584f0..ecb7fa9bd9 100644 --- a/app/client/src/ce/pages/UserAuth/ThirdPartyAuth.tsx +++ b/app/client/src/ce/pages/UserAuth/ThirdPartyAuth.tsx @@ -86,7 +86,7 @@ function SocialLoginButton(props: { }} > -
+
{props.label ?? `continue with ${props.name}`}