From 5a2b549419623b3f0805fdd6b9ba4f6e57d687eb Mon Sep 17 00:00:00 2001 From: Aniketh Jain Date: Tue, 30 Aug 2022 23:17:34 +0530 Subject: [PATCH 1/5] Integration test for SAML Authentication flow Signed-off-by: Aniketh Jain --- DEVELOPER_GUIDE.md | 73 ++-- idp-private-key.pem | 28 ++ idp-public-cert.pem | 20 ++ package.json | 1 + public/apps/account/account-nav-button.tsx | 10 +- .../account-nav-button.test.tsx.snap | 7 +- server/auth/types/saml/routes.ts | 35 +- server/auth/types/saml/saml_auth.ts | 4 +- test/helper/cookie.ts | 2 +- test/jest_integration/runIdpServer.js | 22 ++ test/jest_integration/saml_auth.test.ts | 336 ++++++++++++++++++ 11 files changed, 478 insertions(+), 60 deletions(-) create mode 100644 idp-private-key.pem create mode 100644 idp-public-cert.pem create mode 100644 test/jest_integration/runIdpServer.js create mode 100644 test/jest_integration/saml_auth.test.ts diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index e78086018..92327be59 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -1,4 +1,5 @@ # Developer Guide + So you want to contribute code to this project? Excellent! We're glad you're here. Here's what you need to do. - [Prerequisites](#prerequisites) @@ -9,28 +10,27 @@ So you want to contribute code to this project? Excellent! We're glad you're her This project is a plugin of [OpenSearch-Dashboards](**https://github.com/opensearch-project/OpenSearch-Dashboards). It requires an [OpenSearch](https://github.com/opensearch-project/OpenSearch) server running with the [Security](https://github.com/opensearch-project/security) plugin installed. At the time of this writing there is a strict version check between these components, so we recommend running all of them from their respective branches with matching versions (this will also ensure they work well together before we cut a new release.) -As a prerequisite, please follow [the developer guide of the Security Plugin](https://github.com/opensearch-project/security/blob/main/DEVELOPER_GUIDE.md). This will get a OpenSearch server running with security plugin enabled. - +As a prerequisite, please follow [the developer guide of the Security Plugin](https://github.com/opensearch-project/security/blob/main/DEVELOPER_GUIDE.md). This will get a OpenSearch server running with security plugin enabled. > NOTE: If you are following this guide by the dot, please make sure that source code that you compile for OpenSearch project using `./gradlew localDistro` is done from [1.x branch](https://github.com/opensearch-project/OpenSearch/tree/1.x). - At present there are following branches available to choose from for the setup: ### **Back-end** -| OpenSearch
branch | Security Plugin
branch | OpenSearch
version | -|-------- |--- |--- | +| OpenSearch
branch | Security Plugin
branch | OpenSearch
version | +| ---------------------------------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [1.x](https://github.com/opensearch-project/OpenSearch/tree/1.x) | [main](https://github.com/opensearch-project/security/) | [v1.3.0](https://github.com/opensearch-project/OpenSearch/blob/6eda740be744846f7aa0b2674820b5ed9b6be17e/buildSrc/version.properties#L1) | -| [main](https://github.com/opensearch-project/OpenSearch) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch/blob/1e5d98329eaa76d1aea19306242e6fa74b840b75/buildSrc/version.properties#L1) | +| [main](https://github.com/opensearch-project/OpenSearch) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch/blob/1e5d98329eaa76d1aea19306242e6fa74b840b75/buildSrc/version.properties#L1) |
### **Front-end** -| OpenSearch Dashboards
branch | Security Dashboards Plugin
branch | OpenSearch Dashboards
version | -| --- | --- | --- | + +| OpenSearch Dashboards
branch | Security Dashboards Plugin
branch | OpenSearch Dashboards
version | +| --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | [1.x](https://github.com/opensearch-project/OpenSearch-Dashboards/tree/1.x) | [main](https://github.com/opensearch-project/security-dashboards-plugin/) | [v1.3.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/b82f214babf7ef8db4a9705b7b51a912f779184c/package.json#L14) | -| [main](https://github.com/opensearch-project/OpenSearch-Dashboards) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/0c3f901c569838b2708a079d058c7d09970b944c/package.json#L14) | +| [main](https://github.com/opensearch-project/OpenSearch-Dashboards) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/0c3f901c569838b2708a079d058c7d09970b944c/package.json#L14) | \ For the sake of this guide, let's assume that the latest versions (`1.3.0-SNAPSHOT` for OpenSearch and OpenSearch Dashboards, and `1.3.0.0-SNAPSHOT` for the backend and the frontend of this Security plugin). @@ -53,39 +53,51 @@ plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem plugins.security.allow_unsafe_democertificates: true plugins.security.allow_default_init_securityindex: true plugins.security.authcz.admin_dn: -- CN=kirk,OU=client,O=client,L=test, C=de + - CN=kirk,OU=client,O=client,L=test, C=de +plugins.security.unsupported.restapi.allow_securityconfig_modification: true plugins.security.audit.type: internal_opensearch plugins.security.enable_snapshot_restore_privilege: true plugins.security.check_snapshot_restore_write_privileges: true -plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"] +plugins.security.restapi.roles_enabled: ['all_access', 'security_rest_api_access'] plugins.security.system_indices.enabled: true -plugins.security.system_indices.indices: [".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opendistro-notifications-*", ".opendistro-notebooks", ".opensearch-observability", ".opendistro-asynchronous-search-response*", ".replication-metadata-store"] +plugins.security.system_indices.indices: + [ + '.opendistro-alerting-config', + '.opendistro-alerting-alert*', + '.opendistro-anomaly-results*', + '.opendistro-anomaly-detector*', + '.opendistro-anomaly-checkpoints', + '.opendistro-anomaly-detection-state', + '.opendistro-reports-*', + '.opendistro-notifications-*', + '.opendistro-notebooks', + '.opensearch-observability', + '.opendistro-asynchronous-search-response*', + '.replication-metadata-store', + ] node.max_local_storage_nodes: 3 - ######## End OpenSearch Security Demo Configuration ######## ``` +**Please Note** : This project runs on node `10.24.1` at the time of writing this guide (refer to the `.nvmrc` or `.node-version` file in the base directory for correct version) and so when installing node please ensure that you install this version. You can do so by running -**Please Note** : This project runs on node `10.24.1` at the time of writing this guide (refer to the `.nvmrc` or `.node-version` file in the base directory for correct version) and so when installing node please ensure that you install this version. You can do so by running -```script +```script nvm use --install ``` - Next, checkout the [1.x branch](https://github.com/opensearch-project/OpenSearch-Dashboards/tree/1.x) from OpenSearch-Dashboards repo. Follow the [developer guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/1.x/DEVELOPER_GUIDE.md) and replace the version of `opensearch-dashboards.yml` there with this: - ```yaml -server.host: "0" -opensearch.hosts: ["https://localhost:9200"] +server.host: '0' +opensearch.hosts: ['https://localhost:9200'] opensearch.ssl.verificationMode: none -opensearch.username: "kibanaserver" -opensearch.password: "kibanaserver" -opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] +opensearch.username: 'kibanaserver' +opensearch.password: 'kibanaserver' +opensearch.requestHeadersWhitelist: [authorization, securitytenant] opensearch_security.multitenancy.enabled: true -opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] -opensearch_security.readonly_mode.roles: ["kibana_read_only"] +opensearch_security.multitenancy.tenants.preferred: ['Private', 'Global'] +opensearch_security.readonly_mode.roles: ['kibana_read_only'] # Use this setting if you are running opensearch-dashboards without https opensearch_security.cookie.secure: false @@ -94,10 +106,10 @@ opensearch_security.cookie.secure: false \ Note that at this point `yarn start` will fail, as we still don't have the security plugin installed in the Dashboards. We are ready to install it now. - ## Building Change to the `plugins` directory of the locally cloned Opensearch Dashboards directory. + ``` cd /OpenSearch-Dashboards cd plugins @@ -114,7 +126,6 @@ yarn build Next, go to the base directory and run `yarn osd bootstrap` to install any additional packages introduced by the security plugin. (If you do not run this, `yarn start` might fail with an error like `Cannot find module xxxxx`) - Now, from the base directory and run `yarn start`. This should start dashboard UI successfully. `Cmd+click` the url in the console output (It should look something like `http://0:5601/omf`). Once the page loads, you should be able to log in with user `admin` and password `admin`. ## Submitting Changes @@ -123,8 +134,8 @@ See [CONTRIBUTING](CONTRIBUTING.md). ## Backports -The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the -original PR with an appropriate label `backport ` is merged to main with the backport workflow -run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label -`backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is -merged to main, the workflow will create a backport PR to the `1.x` branch. \ No newline at end of file +The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the +original PR with an appropriate label `backport ` is merged to main with the backport workflow +run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label +`backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is +merged to main, the workflow will create a backport PR to the `1.x` branch. diff --git a/idp-private-key.pem b/idp-private-key.pem new file mode 100644 index 000000000..7e5f47b7a --- /dev/null +++ b/idp-private-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+eflDQihJ4zoZ +urwXuY3Nk9jRA3ms5Ge6jYuvId9mPjJ9ezndOdiVWnTgdqfmYUFMRsQ53iJJmprp +GHctBIPWpaz5Ao4oeco0D87CcySLA94tp8SG5ja2vasVYiNsaN9er1oWVo8uQP82 +iLGF5jXOBDaN3iPub8W2w78oSfgV2Kw5fgmcEIxUGyf/Jr1a8X5TdbX1rS8cZ08D +crZ8DAQZ9ndLl6wJ6RKnp7dqtEys1BT2LXQVvGkFp7zrN74AnNl8+FUE269Wct3t +sPVkIKgGxURGj+ky6oHT9MbVp7vvE9+7dcwfQMDqbd5elOIFZsWad0wd4LgIFUGa +ATnaSyXrAgMBAAECggEAGiwOWPSFLqnfONvUrnnbhyzSdN3CYUQ9EIAUemrwFE9l +hqJg8AnbvaHhP1pudZRVcZKjscPY+D4bHP40meXt65d2Lfzw5ZTeeMrXQRarJcLR +S3qq4VJOoEttb5G9hk7eqlbzzO/12ogpySd9JQXdzMH9cP7d9ww6oYNCB9oqEW4o +QVjwF5RHuq9dB6FmhsNux9VbbP6gGVTXA7IpmNwFddW8JoDM2mj952POYjAwEy00 +VQb0dzVrfuEw8DmpWZAOfyDt5QYO+7SC+L4eHbhrZrxeCzXr2hEhiCa1Nn3ieAHD +fF5FaguRMJcfGI3UEQZAw0++0SYeWPnjnwM1wE/nyQKBgQDyZA+6D1f3H/0fg4tT +ZrpGydnRPqqvMF+GBCtfa7Gjf6NdFQ+j0NzUXGzbIGy+0pJKEfEk4hE/2xFjCzru +LYJ5hSz/GXZH6qn4H39f0byl9oT6DYKDmrcXt1jRM4ioCU4Q1c58e2MqsvttVCnw +dVDQuTMb1xm6okHqcm3Fn8rUBwKBgQDJK7wbgrQcWriFxKDITdLvAivDcYAQ/p/e +XDw+nVdwq0p9Kpe+N5Lt6kvlTVyrS1aWfa9ucLVKMSKCbkjJBhesJsZU3nZgLa65 +XT5+sP4640/gBoHWvauYBBjOy0iHHzhrIx+Kw0BXWzrYE0ol0aIWYZt1/I1LQtoB +E0+ojQLN/QKBgQDCtZhgiNTLwhmOSBgSffHizWC4klN/+SayvASvWQ5QXUa4jiOL +H0tVF42mFIzmWLaE45bHXwYmOm7kFfBXxZ0Kyu0TWrvGF35Dv+GM8ilNVBML3vBZ +kV3EolapbnE3MopQQb/mBSPq9+26rCIoc8TgdfTVR1v2rUKv9w2w86R13wKBgGh5 +GQikeUscZiW6NtGvcPMFCptGb37j7Tx6ZCMUbVuq6VVVcFat39VEz0N3SMAAsSgY +f6n4SH4ORGC+S3hyfIq/3FIo8gsCznGflhwPaQhGEq5CUt2lxN5+ii+i7LiXoyIo +rHHQ8rIrQ8UBR4mac/XxnN3KWcqTHkpesAjVqnY1AoGAXoc9kr4v3WP0AG6lUhjB +P77AIrpCokbvnXfsAj9coPBJjK16XY534jjmnem4lwvxad/+PDWfU2i3wlP64YCi +BJkN8s9vJyJqHDFJjQ18zl6rdlFt+43x+YCt/zHsqazdcm47XN9kbXrunDYpVh2E +PZWa3aHt74aNhNMshynDIXI= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/idp-public-cert.pem b/idp-public-cert.pem new file mode 100644 index 000000000..0e5f8db49 --- /dev/null +++ b/idp-public-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVjCCAj4CCQCgL9L+gaw8+jANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQGEwJV +UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEQ +MA4GA1UECgwHSmFua3lDbzEfMB0GA1UEAwwWVGVzdCBJZGVudGl0eSBQcm92aWRl +cjAeFw0yMjA3MTUxNjU1MjRaFw00MjA3MTAxNjU1MjRaMG0xCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAw +DgYDVQQKDAdKYW5reUNvMR8wHQYDVQQDDBZUZXN0IElkZW50aXR5IFByb3ZpZGVy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvnn5Q0IoSeM6Gbq8F7mN +zZPY0QN5rORnuo2LryHfZj4yfXs53TnYlVp04Han5mFBTEbEOd4iSZqa6Rh3LQSD +1qWs+QKOKHnKNA/OwnMkiwPeLafEhuY2tr2rFWIjbGjfXq9aFlaPLkD/NoixheY1 +zgQ2jd4j7m/FtsO/KEn4FdisOX4JnBCMVBsn/ya9WvF+U3W19a0vHGdPA3K2fAwE +GfZ3S5esCekSp6e3arRMrNQU9i10FbxpBae86ze+AJzZfPhVBNuvVnLd7bD1ZCCo +BsVERo/pMuqB0/TG1ae77xPfu3XMH0DA6m3eXpTiBWbFmndMHeC4CBVBmgE52ksl +6wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQADzGujWOBelV81BoxkS5vB+VGmEDAx +I67cZCZ7734vJsrf5c6QV45zz+NiOqyLkY2JEsHMh89Ns8n+1MsbIPn01tfjXFgL +arJLhLBRxFhqZr0H81E8DAzHwjAtx8Qmr/IQXcLPhJ0SMubIGC7EhCkYrphteTyd +2Rr5C9lCwF4Lb3xgoT2RsEO/IWDKb/CthcisQdDTw1XWLeAc+pJa76kOgDSkP93i +hHoZJMswOFU8KnLiXMaSxUZOXHLOYY7k4+xyh7dGqEkwKRYyY3TJ3mAULcJr5Ngz +UJvwmjmuEVCIgVNWqW45UsXJqkvdGFtUKj3UGfgyuvSV33daqXjkAims +-----END CERTIFICATE----- \ No newline at end of file diff --git a/package.json b/package.json index 41e345fbc..f4aa8866a 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "lint:es": "node ../../scripts/eslint", "lint:style": "node ../../scripts/stylelint", "lint": "yarn run lint:es && yarn run lint:style", + "pretest:jest_server": "node ./test/jest_integration/runIdpServer.js &", "test:jest_server": "node ./test/run_jest_tests.js --config ./test/jest.config.server.js", "test:jest_ui": "node ./test/run_jest_tests.js --config ./test/jest.config.ui.js" }, diff --git a/public/apps/account/account-nav-button.tsx b/public/apps/account/account-nav-button.tsx index 1100e9f31..fd85ff8fc 100644 --- a/public/apps/account/account-nav-button.tsx +++ b/public/apps/account/account-nav-button.tsx @@ -93,7 +93,11 @@ export function AccountNavButton(props: { {resolveTenantName(props.tenant || '', username)}} + label={ + + {resolveTenantName(props.tenant || '', username)} + + } /> @@ -140,7 +144,7 @@ export function AccountNavButton(props: { ); return ( - + ); -} +} \ No newline at end of file diff --git a/public/apps/account/test/__snapshots__/account-nav-button.test.tsx.snap b/public/apps/account/test/__snapshots__/account-nav-button.test.tsx.snap index c45a38eee..3b174c45f 100644 --- a/public/apps/account/test/__snapshots__/account-nav-button.test.tsx.snap +++ b/public/apps/account/test/__snapshots__/account-nav-button.test.tsx.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Account navigation button renders 1`] = ` - + tenant1 @@ -114,4 +117,4 @@ exports[`Account navigation button renders 1`] = ` -`; +`; \ No newline at end of file diff --git a/server/auth/types/saml/routes.ts b/server/auth/types/saml/routes.ts index 79454272c..eafa05ab3 100644 --- a/server/auth/types/saml/routes.ts +++ b/server/auth/types/saml/routes.ts @@ -14,21 +14,18 @@ */ import { schema } from '@osd/config-schema'; -import { - IRouter, - SessionStorageFactory, - OpenSearchDashboardsRequest, -} from '../../../../../../src/core/server'; +import { IRouter, SessionStorageFactory } from '../../../../../../src/core/server'; import { SecuritySessionCookie } from '../../../session/security_cookie'; import { SecurityPluginConfigType } from '../../..'; import { SecurityClient } from '../../../backend/opensearch_security_client'; +import { API_AUTH_LOGOUT } from '../../../../common'; import { CoreSetup } from '../../../../../../src/core/server'; import { validateNextUrl } from '../../../utils/next_url'; +import { AuthType } from '../../../../common/index'; export class SamlAuthRoutes { constructor( private readonly router: IRouter, - // @ts-ignore: unused variable private readonly config: SecurityPluginConfigType, private readonly sessionStorageFactory: SessionStorageFactory, private readonly securityClient: SecurityClient, @@ -38,7 +35,7 @@ export class SamlAuthRoutes { public setupRoutes() { this.router.get( { - path: `/auth/saml/login`, + path: '/auth/saml/login', validate: { query: schema.object({ nextUrl: schema.maybe( @@ -86,7 +83,8 @@ export class SamlAuthRoutes { this.router.post( { - path: `/_opendistro/_security/saml/acs`, + // need to change to /_opendistro to execute the tests. + path: '/_opendistro/_security/saml/acs', validate: { body: schema.any(), }, @@ -143,11 +141,12 @@ export class SamlAuthRoutes { credentials: { authHeaderValue: credentials.authorization, }, - authType: 'saml', // TODO: create constant + authType: AuthType.SAML, expiryTime, }; this.sessionStorageFactory.asScoped(request).set(cookie); if (redirectHash) { + console.log('The server base path is : ' + this.coreSetup.http.basePath.serverBasePath); return response.redirected({ headers: { location: `${ @@ -174,7 +173,7 @@ export class SamlAuthRoutes { this.router.post( { - path: `/_opendistro/_security/saml/acs/idpinitiated`, + path: '/_plugins/_security/saml/acs/idpinitiated', validate: { body: schema.any(), }, @@ -183,7 +182,7 @@ export class SamlAuthRoutes { }, }, async (context, request, response) => { - const acsEndpoint = `${this.coreSetup.http.basePath.serverBasePath}/_opendistro/_security/saml/acs/idpinitiated`; + const acsEndpoint = `${this.coreSetup.http.basePath.serverBasePath}/_plugins/_security/saml/acs/idpinitiated`; try { const credentials = await this.securityClient.authToken( undefined, @@ -211,7 +210,7 @@ export class SamlAuthRoutes { credentials: { authHeaderValue: credentials.authorization, }, - authType: 'saml', // TODO: create constant + authType: AuthType.SAML, expiryTime, }; this.sessionStorageFactory.asScoped(request).set(cookie); @@ -229,8 +228,6 @@ export class SamlAuthRoutes { } ); - // captureUrlFragment is the first route that will be invoked in the SP initiated login. - // This route will execute the captureUrlFragment.js script. this.coreSetup.http.resources.register( { path: '/auth/saml/captureUrlFragment', @@ -261,7 +258,6 @@ export class SamlAuthRoutes { } ); - // This script will store the URL Hash in browser's local storage. this.coreSetup.http.resources.register( { path: '/auth/saml/captureUrlFragment.js', @@ -291,9 +287,6 @@ export class SamlAuthRoutes { } ); - // Once the User is authenticated via the '_opendistro/_security/saml/acs' route, - // the browser will be redirected to '/auth/saml/redirectUrlFragment' route, - // which will execute the redirectUrlFragment.js. this.coreSetup.http.resources.register( { path: '/auth/saml/redirectUrlFragment', @@ -319,8 +312,6 @@ export class SamlAuthRoutes { } ); - // This script will pop the Hash from local storage if it exists. - // And forward the browser to the next url. this.coreSetup.http.resources.register( { path: '/auth/saml/redirectUrlFragment.js', @@ -344,7 +335,7 @@ export class SamlAuthRoutes { this.router.get( { - path: `/auth/logout`, + path: API_AUTH_LOGOUT, validate: false, }, async (context, request, response) => { @@ -366,4 +357,4 @@ export class SamlAuthRoutes { } ); } -} +} \ No newline at end of file diff --git a/server/auth/types/saml/saml_auth.ts b/server/auth/types/saml/saml_auth.ts index 201e76c43..336ff3d36 100644 --- a/server/auth/types/saml/saml_auth.ts +++ b/server/auth/types/saml/saml_auth.ts @@ -58,6 +58,7 @@ export class SamlAuthentication extends AuthenticationType { return escape(path); } + // Check if we can get the previous tenant information from the expired cookie. private redirectSAMlCapture = (request: OpenSearchDashboardsRequest, toolkit: AuthToolkit) => { const nextUrl = this.generateNextUrl(request); const clearOldVersionCookie = clearOldVersionCookieValue(this.config); @@ -97,6 +98,7 @@ export class SamlAuthentication extends AuthenticationType { }; } + // Can be improved to check if the token is expiring. async isValidCookie(cookie: SecuritySessionCookie): Promise { return ( cookie.authType === this.type && @@ -123,4 +125,4 @@ export class SamlAuthentication extends AuthenticationType { headers[SamlAuthentication.AUTH_HEADER_NAME] = cookie.credentials?.authHeaderValue; return headers; } -} +} \ No newline at end of file diff --git a/test/helper/cookie.ts b/test/helper/cookie.ts index 381891f9a..dcbea1489 100644 --- a/test/helper/cookie.ts +++ b/test/helper/cookie.ts @@ -20,7 +20,7 @@ import { AUTHORIZATION_HEADER_NAME } from '../constant'; export function extractAuthCookie(response: Response) { const setCookieHeaders = response.header['set-cookie'] as string[]; - let securityAuthCookie: string; + let securityAuthCookie: string | null = null; for (const setCookie of setCookieHeaders) { if (setCookie.startsWith('security_authentication=')) { securityAuthCookie = setCookie.split(';')[0]; diff --git a/test/jest_integration/runIdpServer.js b/test/jest_integration/runIdpServer.js new file mode 100644 index 000000000..c3da01390 --- /dev/null +++ b/test/jest_integration/runIdpServer.js @@ -0,0 +1,22 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +const { runServer } = require('saml-idp'); + +// Create certificate pair on the fly and pass it to runServer +runServer({ + acsUrl: 'http://localhost:5601/_opendistro/_security/saml/acs', + audience: 'https://localhost:9200', +}); \ No newline at end of file diff --git a/test/jest_integration/saml_auth.test.ts b/test/jest_integration/saml_auth.test.ts new file mode 100644 index 000000000..293f36c80 --- /dev/null +++ b/test/jest_integration/saml_auth.test.ts @@ -0,0 +1,336 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import * as osdTestServer from '../../../../src/core/test_helpers/osd_server'; +import { Root } from '../../../../src/core/server/root'; +import { resolve } from 'path'; +import { describe, expect, it, beforeAll, afterAll, afterEach, test } from '@jest/globals'; +import { + ADMIN_CREDENTIALS, + OPENSEARCH_DASHBOARDS_SERVER_USER, + OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, +} from '../constant'; +import wreck from '@hapi/wreck'; +import { Builder, By, until, ThenableWebDriver } from 'selenium-webdriver'; +import { Options } from 'selenium-webdriver/firefox'; + +describe('start OpenSearch Dashboards server', () => { + let root: Root; + let config; + + // XPath Constants + const userIconBtnXPath = '//button[@id="user-icon-btn"]'; + const signInBtnXPath = '//*[@id="btn-sign-in"]'; + const skipWelcomeBtnXPath = '//button[@data-test-subj="skipWelcomeScreen"]'; + const tenantNameLabelXPath = '//*[@id="tenantName"]'; + const pageTitleXPath = '//*[@id="osdOverviewPageHeader__title"]'; + + beforeAll(async () => { + root = osdTestServer.createRootWithSettings( + { + plugins: { + scanDirs: [resolve(__dirname, '../..')], + }, + server: { + host: 'localhost', + port: 5601, + xsrf: { + whitelist: [ + '/_opendistro/_security/saml/acs/idpinitiated', + '/_opendistro/_security/saml/acs', + '/_opendistro/_security/saml/logout', + ], + }, + }, + opensearch: { + hosts: ['https://localhost:9200'], + ignoreVersionMismatch: true, + ssl: { verificationMode: 'none' }, + username: OPENSEARCH_DASHBOARDS_SERVER_USER, + password: OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, + requestHeadersWhitelist: ['authorization', 'securitytenant'], + }, + opensearch_security: { + auth: { + anonymous_auth_enabled: false, + type: 'saml', + }, + multitenancy: { + enabled: true, + tenants: { + enable_global: true, + enable_private: true, + preferred: ['Private', 'Global'], + }, + }, + }, + }, + { + // to make ignoreVersionMismatch setting work + // can be removed when we have corresponding ES version + dev: true, + } + ); + + console.log('Starting OpenSearchDashboards server..'); + await root.setup(); + await root.start(); + + console.log('Starting the Selenium Web Driver'); + await wreck.patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { + payload: [ + { + op: 'add', + path: '/users', + value: ['saml.jackson@example.com'], + }, + ], + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + }, + }); + console.log('Starting to Download Flights Sample Data'); + await wreck.post('http://localhost:5601/api/sample_data/flights', { + payload: {}, + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + security_tenant: 'global', + }, + }); + console.log('Downloaded Sample Data'); + const getConfigResponse = await wreck.get( + 'https://localhost:9200/_plugins/_security/api/securityconfig', + { + rejectUnauthorized: false, + headers: { + authorization: ADMIN_CREDENTIALS, + }, + } + ); + const responseBody = (getConfigResponse.payload as Buffer).toString(); + config = JSON.parse(responseBody).config; + const samlConfig = { + http_enabled: true, + transport_enabled: false, + order: 5, + http_authenticator: { + challenge: true, + type: 'saml', + config: { + idp: { + metadata_url: 'http://localhost:7000/metadata', + entity_id: 'urn:example:idp', + }, + sp: { + entity_id: 'https://localhost:9200', + }, + kibana_url: 'http://localhost:5601', + exchange_key: '6aff3042-1327-4f3d-82f0-40a157ac4464', + }, + }, + authentication_backend: { + type: 'noop', + config: {}, + }, + }; + try { + config.dynamic!.authc!.saml_auth_domain = samlConfig; + config.dynamic!.authc!.basic_internal_auth_domain.http_authenticator.challenge = false; + config.dynamic!.http!.anonymous_auth_enabled = false; + await wreck.put('https://localhost:9200/_plugins/_security/api/securityconfig/config', { + payload: config, + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + }, + }); + } catch (error) { + console.log('Got an error!!', error.stack); + } + console.log('The Config Response is : ' + JSON.stringify(config)); + }); + + afterAll(async () => { + console.log('Remove the Sample Data'); + await wreck + .delete('http://localhost:5601/api/sample_data/flights', { + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + }, + }) + .then((value) => { + Promise.resolve(value); + }) + .catch((value) => { + Promise.resolve(value); + }); + console.log('Remove the Role Mapping'); + await wreck + .patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { + payload: [ + { + op: 'remove', + path: '/users', + users: ['saml.jackson@example.com'], + }, + ], + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + }, + }) + .then((value) => { + Promise.resolve(value); + }) + .catch((value) => { + Promise.resolve(value); + }); + console.log('Remove the Security Config'); + await wreck + .patch('https://localhost:9200/_plugins/_security/api/securityconfig', { + payload: [ + { + op: 'remove', + path: '/config/dynamic/authc/saml_auth_domain', + }, + ], + rejectUnauthorized: false, + headers: { + 'Content-Type': 'application/json', + authorization: ADMIN_CREDENTIALS, + }, + }) + .then((value) => { + Promise.resolve(value); + }) + .catch((value) => { + Promise.resolve(value); + }); + // shutdown OpenSearchDashboards server + await root.shutdown(); + }); + + it('Login to app/opensearch_dashboards_overview#/ when SAML is enabled', async () => { + const driver = getDriver().build(); + await driver.get('http://localhost:5601/app/opensearch_dashboards_overview#/'); + await driver.findElement(By.id('btn-sign-in')).click(); + await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); + + const cookie = await driver.manage().getCookies(); + expect(cookie.length).toEqual(2); + await driver.manage().deleteAllCookies(); + await driver.quit(); + }); + + it('Login to app/dev_tools#/console when SAML is enabled', async () => { + const driver = getDriver().build(); + await driver.get('http://localhost:5601/app/dev_tools#/console'); + await driver.findElement(By.id('btn-sign-in')).click(); + + await driver.wait( + until.elementsLocated( + By.xpath('/html/body/div[1]/div/div/div/div[2]/div/main/div[1]/span/button/span') + ), + 10000 + ); + + const cookie = await driver.manage().getCookies(); + expect(cookie.length).toEqual(2); + await driver.manage().deleteAllCookies(); + await driver.quit(); + }); + + it('Login to Dashboard with Hash', async () => { + const urlWithHash = `http://localhost:5601/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=(filters:!(),refreshInterval:(pause:!f,value:900000),time:(from:now-24h,to:now))&_a=(description:'Analyze%20mock%20flight%20data%20for%20OpenSearch-Air,%20Logstash%20Airways,%20OpenSearch%20Dashboards%20Airlines%20and%20BeatsWest',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!t,title:'%5BFlights%5D%20Global%20Flight%20Dashboard',viewMode:view)`; + const driver = getDriver().build(); + await driver.manage().deleteAllCookies(); + await driver.get(urlWithHash); + await driver.wait(until.elementsLocated(By.xpath('/html/body/nav/div/div[1]/a/i/span')), 60000); + await driver.findElement(By.xpath(signInBtnXPath)).click(); + await driver.wait( + until.elementsLocated(By.xpath('/html/body/div[1]/div/header/div/div[2]')), + 20000 + ); + const windowHash = await driver.getCurrentUrl(); + expect(windowHash).toEqual(urlWithHash); + const cookie = await driver.manage().getCookies(); + expect(cookie.length).toEqual(2); + await driver.manage().deleteAllCookies(); + await driver.quit(); + }); + + it('Testing Tenancy IT', async () => { + const driver = getDriver().build(); + + await driver.get('http://localhost:5601/app/opensearch_dashboards_overview#/'); + + await driver.findElement(By.xpath(signInBtnXPath)).click(); + + await driver.wait(until.elementsLocated(By.xpath(pageTitleXPath)), 10000); + + await driver.wait( + until.elementsLocated(By.xpath('//button[@aria-label="Closes this modal window"]')), + 10000 + ); + + // Select Global Tenant Radio Button + const radio = await driver.findElement(By.xpath('//input[@id="global"]')); + await driver.executeScript('arguments[0].scrollIntoView(true);', radio); + await driver.executeScript('arguments[0].click();', radio); + + await driver.findElement(By.xpath('//button[@data-test-subj="confirm"]')).click(); + + await driver.wait(until.elementsLocated(By.xpath(userIconBtnXPath)), 10000); + + await driver.findElement(By.xpath(userIconBtnXPath)).click(); + + await driver.findElement(By.xpath('//*[@data-test-subj="log-out-1"]')).click(); + + // RELOGIN AND CHECK TENANT + + await driver.wait(until.elementsLocated(By.xpath(signInBtnXPath)), 10000); + + await driver.findElement(By.xpath(signInBtnXPath)).click(); + + await driver.wait(until.elementsLocated(By.xpath(skipWelcomeBtnXPath)), 10000); + + await driver.findElement(By.xpath(skipWelcomeBtnXPath)).click(); + + await driver.findElement(By.xpath(userIconBtnXPath)).click(); + + await driver.wait(until.elementsLocated(By.xpath(tenantNameLabelXPath)), 10000); + + const tenantName = await driver.findElement(By.xpath(tenantNameLabelXPath)).getText(); + + console.log('Tenant after login is %s', tenantName); + + expect(tenantName).toEqual('Global'); + + await driver.manage().deleteAllCookies(); + await driver.quit(); + }); +}); + +function getDriver() { + return new Builder().forBrowser('firefox').setFirefoxOptions(new Options().headless()); +} \ No newline at end of file From d852393754857927f0ba750825e29395cda698ad Mon Sep 17 00:00:00 2001 From: Aniketh Jain Date: Tue, 30 Aug 2022 23:23:28 +0530 Subject: [PATCH 2/5] Dev Guide Formatting changes Signed-off-by: Aniketh Jain --- DEVELOPER_GUIDE.md | 72 ++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 92327be59..c81d25e04 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -1,5 +1,4 @@ # Developer Guide - So you want to contribute code to this project? Excellent! We're glad you're here. Here's what you need to do. - [Prerequisites](#prerequisites) @@ -10,27 +9,28 @@ So you want to contribute code to this project? Excellent! We're glad you're her This project is a plugin of [OpenSearch-Dashboards](**https://github.com/opensearch-project/OpenSearch-Dashboards). It requires an [OpenSearch](https://github.com/opensearch-project/OpenSearch) server running with the [Security](https://github.com/opensearch-project/security) plugin installed. At the time of this writing there is a strict version check between these components, so we recommend running all of them from their respective branches with matching versions (this will also ensure they work well together before we cut a new release.) -As a prerequisite, please follow [the developer guide of the Security Plugin](https://github.com/opensearch-project/security/blob/main/DEVELOPER_GUIDE.md). This will get a OpenSearch server running with security plugin enabled. +As a prerequisite, please follow [the developer guide of the Security Plugin](https://github.com/opensearch-project/security/blob/main/DEVELOPER_GUIDE.md). This will get a OpenSearch server running with security plugin enabled. + > NOTE: If you are following this guide by the dot, please make sure that source code that you compile for OpenSearch project using `./gradlew localDistro` is done from [1.x branch](https://github.com/opensearch-project/OpenSearch/tree/1.x). + At present there are following branches available to choose from for the setup: ### **Back-end** -| OpenSearch
branch | Security Plugin
branch | OpenSearch
version | -| ---------------------------------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| OpenSearch
branch | Security Plugin
branch | OpenSearch
version | +|-------- |--- |--- | | [1.x](https://github.com/opensearch-project/OpenSearch/tree/1.x) | [main](https://github.com/opensearch-project/security/) | [v1.3.0](https://github.com/opensearch-project/OpenSearch/blob/6eda740be744846f7aa0b2674820b5ed9b6be17e/buildSrc/version.properties#L1) | -| [main](https://github.com/opensearch-project/OpenSearch) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch/blob/1e5d98329eaa76d1aea19306242e6fa74b840b75/buildSrc/version.properties#L1) | +| [main](https://github.com/opensearch-project/OpenSearch) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch/blob/1e5d98329eaa76d1aea19306242e6fa74b840b75/buildSrc/version.properties#L1) |
### **Front-end** - -| OpenSearch Dashboards
branch | Security Dashboards Plugin
branch | OpenSearch Dashboards
version | -| --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| OpenSearch Dashboards
branch | Security Dashboards Plugin
branch | OpenSearch Dashboards
version | +| --- | --- | --- | | [1.x](https://github.com/opensearch-project/OpenSearch-Dashboards/tree/1.x) | [main](https://github.com/opensearch-project/security-dashboards-plugin/) | [v1.3.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/b82f214babf7ef8db4a9705b7b51a912f779184c/package.json#L14) | -| [main](https://github.com/opensearch-project/OpenSearch-Dashboards) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/0c3f901c569838b2708a079d058c7d09970b944c/package.json#L14) | +| [main](https://github.com/opensearch-project/OpenSearch-Dashboards) | (under development) | [v2.0.0](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/0c3f901c569838b2708a079d058c7d09970b944c/package.json#L14) | \ For the sake of this guide, let's assume that the latest versions (`1.3.0-SNAPSHOT` for OpenSearch and OpenSearch Dashboards, and `1.3.0.0-SNAPSHOT` for the backend and the frontend of this Security plugin). @@ -53,51 +53,40 @@ plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem plugins.security.allow_unsafe_democertificates: true plugins.security.allow_default_init_securityindex: true plugins.security.authcz.admin_dn: - - CN=kirk,OU=client,O=client,L=test, C=de +- CN=kirk,OU=client,O=client,L=test, C=de plugins.security.unsupported.restapi.allow_securityconfig_modification: true plugins.security.audit.type: internal_opensearch plugins.security.enable_snapshot_restore_privilege: true plugins.security.check_snapshot_restore_write_privileges: true -plugins.security.restapi.roles_enabled: ['all_access', 'security_rest_api_access'] +plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"] plugins.security.system_indices.enabled: true -plugins.security.system_indices.indices: - [ - '.opendistro-alerting-config', - '.opendistro-alerting-alert*', - '.opendistro-anomaly-results*', - '.opendistro-anomaly-detector*', - '.opendistro-anomaly-checkpoints', - '.opendistro-anomaly-detection-state', - '.opendistro-reports-*', - '.opendistro-notifications-*', - '.opendistro-notebooks', - '.opensearch-observability', - '.opendistro-asynchronous-search-response*', - '.replication-metadata-store', - ] +plugins.security.system_indices.indices: [".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opendistro-notifications-*", ".opendistro-notebooks", ".opensearch-observability", ".opendistro-asynchronous-search-response*", ".replication-metadata-store"] node.max_local_storage_nodes: 3 + ######## End OpenSearch Security Demo Configuration ######## ``` -**Please Note** : This project runs on node `10.24.1` at the time of writing this guide (refer to the `.nvmrc` or `.node-version` file in the base directory for correct version) and so when installing node please ensure that you install this version. You can do so by running -```script +**Please Note** : This project runs on node `10.24.1` at the time of writing this guide (refer to the `.nvmrc` or `.node-version` file in the base directory for correct version) and so when installing node please ensure that you install this version. You can do so by running +```script nvm use --install ``` + Next, checkout the [1.x branch](https://github.com/opensearch-project/OpenSearch-Dashboards/tree/1.x) from OpenSearch-Dashboards repo. Follow the [developer guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/1.x/DEVELOPER_GUIDE.md) and replace the version of `opensearch-dashboards.yml` there with this: + ```yaml -server.host: '0' -opensearch.hosts: ['https://localhost:9200'] +server.host: "0" +opensearch.hosts: ["https://localhost:9200"] opensearch.ssl.verificationMode: none -opensearch.username: 'kibanaserver' -opensearch.password: 'kibanaserver' -opensearch.requestHeadersWhitelist: [authorization, securitytenant] +opensearch.username: "kibanaserver" +opensearch.password: "kibanaserver" +opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] opensearch_security.multitenancy.enabled: true -opensearch_security.multitenancy.tenants.preferred: ['Private', 'Global'] -opensearch_security.readonly_mode.roles: ['kibana_read_only'] +opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] +opensearch_security.readonly_mode.roles: ["kibana_read_only"] # Use this setting if you are running opensearch-dashboards without https opensearch_security.cookie.secure: false @@ -106,10 +95,10 @@ opensearch_security.cookie.secure: false \ Note that at this point `yarn start` will fail, as we still don't have the security plugin installed in the Dashboards. We are ready to install it now. + ## Building Change to the `plugins` directory of the locally cloned Opensearch Dashboards directory. - ``` cd /OpenSearch-Dashboards cd plugins @@ -126,6 +115,7 @@ yarn build Next, go to the base directory and run `yarn osd bootstrap` to install any additional packages introduced by the security plugin. (If you do not run this, `yarn start` might fail with an error like `Cannot find module xxxxx`) + Now, from the base directory and run `yarn start`. This should start dashboard UI successfully. `Cmd+click` the url in the console output (It should look something like `http://0:5601/omf`). Once the page loads, you should be able to log in with user `admin` and password `admin`. ## Submitting Changes @@ -134,8 +124,8 @@ See [CONTRIBUTING](CONTRIBUTING.md). ## Backports -The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the -original PR with an appropriate label `backport ` is merged to main with the backport workflow -run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label -`backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is -merged to main, the workflow will create a backport PR to the `1.x` branch. +The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the +original PR with an appropriate label `backport ` is merged to main with the backport workflow +run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label +`backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is +merged to main, the workflow will create a backport PR to the `1.x` branch. \ No newline at end of file From 3e2cfefe3ddc4d18b53abd241cf84944771d93f1 Mon Sep 17 00:00:00 2001 From: Aniketh Jain Date: Wed, 31 Aug 2022 01:59:19 +0530 Subject: [PATCH 3/5] Lint formatting changes Signed-off-by: Aniketh Jain --- public/apps/account/account-nav-button.tsx | 2 +- server/auth/types/saml/routes.ts | 2 +- server/auth/types/saml/saml_auth.ts | 2 +- test/jest_integration/runIdpServer.js | 2 +- test/jest_integration/saml_auth.test.ts | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/apps/account/account-nav-button.tsx b/public/apps/account/account-nav-button.tsx index fd85ff8fc..7bd0e578b 100644 --- a/public/apps/account/account-nav-button.tsx +++ b/public/apps/account/account-nav-button.tsx @@ -163,4 +163,4 @@ export function AccountNavButton(props: { {modal}
); -} \ No newline at end of file +} diff --git a/server/auth/types/saml/routes.ts b/server/auth/types/saml/routes.ts index eafa05ab3..4d2bb8c27 100644 --- a/server/auth/types/saml/routes.ts +++ b/server/auth/types/saml/routes.ts @@ -357,4 +357,4 @@ export class SamlAuthRoutes { } ); } -} \ No newline at end of file +} diff --git a/server/auth/types/saml/saml_auth.ts b/server/auth/types/saml/saml_auth.ts index 336ff3d36..ee8762406 100644 --- a/server/auth/types/saml/saml_auth.ts +++ b/server/auth/types/saml/saml_auth.ts @@ -125,4 +125,4 @@ export class SamlAuthentication extends AuthenticationType { headers[SamlAuthentication.AUTH_HEADER_NAME] = cookie.credentials?.authHeaderValue; return headers; } -} \ No newline at end of file +} diff --git a/test/jest_integration/runIdpServer.js b/test/jest_integration/runIdpServer.js index c3da01390..ad29cccd5 100644 --- a/test/jest_integration/runIdpServer.js +++ b/test/jest_integration/runIdpServer.js @@ -19,4 +19,4 @@ const { runServer } = require('saml-idp'); runServer({ acsUrl: 'http://localhost:5601/_opendistro/_security/saml/acs', audience: 'https://localhost:9200', -}); \ No newline at end of file +}); diff --git a/test/jest_integration/saml_auth.test.ts b/test/jest_integration/saml_auth.test.ts index 293f36c80..636d3ea23 100644 --- a/test/jest_integration/saml_auth.test.ts +++ b/test/jest_integration/saml_auth.test.ts @@ -16,14 +16,14 @@ import * as osdTestServer from '../../../../src/core/test_helpers/osd_server'; import { Root } from '../../../../src/core/server/root'; import { resolve } from 'path'; -import { describe, expect, it, beforeAll, afterAll, afterEach, test } from '@jest/globals'; +import { describe, expect, it, beforeAll, afterAll } from '@jest/globals'; import { ADMIN_CREDENTIALS, OPENSEARCH_DASHBOARDS_SERVER_USER, OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, } from '../constant'; import wreck from '@hapi/wreck'; -import { Builder, By, until, ThenableWebDriver } from 'selenium-webdriver'; +import { Builder, By, until } from 'selenium-webdriver'; import { Options } from 'selenium-webdriver/firefox'; describe('start OpenSearch Dashboards server', () => { @@ -279,7 +279,7 @@ describe('start OpenSearch Dashboards server', () => { await driver.quit(); }); - it('Testing Tenancy IT', async () => { + it('Tenant information retained after logout', async () => { const driver = getDriver().build(); await driver.get('http://localhost:5601/app/opensearch_dashboards_overview#/'); @@ -333,4 +333,4 @@ describe('start OpenSearch Dashboards server', () => { function getDriver() { return new Builder().forBrowser('firefox').setFirefoxOptions(new Options().headless()); -} \ No newline at end of file +} From 7dc423633d8d412363021b68e8941369c5580985 Mon Sep 17 00:00:00 2001 From: Aniketh Jain Date: Wed, 31 Aug 2022 02:21:13 +0530 Subject: [PATCH 4/5] Added saml-idp module as a dev dependency Signed-off-by: Aniketh Jain --- package.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f4aa8866a..d49cdf583 100644 --- a/package.json +++ b/package.json @@ -23,14 +23,15 @@ }, "devDependencies": { "@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards", - "typescript": "4.0.2", - "gulp-rename": "2.0.0", "@testing-library/react-hooks": "^7.0.2", - "@types/hapi__wreck": "^15.0.1" + "@types/hapi__wreck": "^15.0.1", + "gulp-rename": "2.0.0", + "typescript": "4.0.2" }, "dependencies": { - "@hapi/wreck": "^17.1.0", "@hapi/cryptiles": "5.0.0", - "html-entities": "1.3.1" + "@hapi/wreck": "^17.1.0", + "html-entities": "1.3.1", + "saml-idp": "^1.2.1" } } From 556519334b3fd7d63c8956fb28772632a3f3de78 Mon Sep 17 00:00:00 2001 From: Aniketh Jain Date: Wed, 31 Aug 2022 02:29:21 +0530 Subject: [PATCH 5/5] Added saml-idp module as a dev dependency Signed-off-by: Aniketh Jain --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d49cdf583..692778a1b 100644 --- a/package.json +++ b/package.json @@ -25,13 +25,12 @@ "@elastic/eslint-import-resolver-kibana": "link:../../packages/osd-eslint-import-resolver-opensearch-dashboards", "@testing-library/react-hooks": "^7.0.2", "@types/hapi__wreck": "^15.0.1", - "gulp-rename": "2.0.0", - "typescript": "4.0.2" + "selenium-webdriver": "^4.0.0-alpha.7", + "saml-idp": "^1.2.1" }, "dependencies": { "@hapi/cryptiles": "5.0.0", "@hapi/wreck": "^17.1.0", - "html-entities": "1.3.1", - "saml-idp": "^1.2.1" + "html-entities": "1.3.1" } }