Skip to content

Commit

Permalink
SAML Integration Tests (opensearch-project#1088)
Browse files Browse the repository at this point in the history
* Refactor + add support to run saml based integ tests via selenium web driver

Signed-off-by: Deepak Devarakonda <[email protected]>

* Add plugins.security.unsupported.restapi.allow_securityconfig_modification in developer guide

Signed-off-by: Deepak Devarakonda <[email protected]>

* Add one more test

Signed-off-by: Deepak Devarakonda <[email protected]>

* Added tests for checking tenancy retention after logout in SAML

Signed-off-by: Aniketh Jain <[email protected]>

* Lint formatting fixes

Signed-off-by: Aniketh Jain <[email protected]>

* Removed unused imports

Signed-off-by: Aniketh Jain <[email protected]>

* Add plugins.security.unsupported.restapi.allow_securityconfig_modification in developer guide

Signed-off-by: Deepak Devarakonda <[email protected]>

* Added License header

Signed-off-by: Aniketh Jain <[email protected]>

* Added building the plugin bundles while running ITs

Signed-off-by: Aniketh Jain <[email protected]>

* Signed off the commit

Removed a comment no longer required

Signed-off-by: Aniketh Jain <[email protected]>

* Added debug loggers for checking IT failures

Signed-off-by: Aniketh Jain <[email protected]>

* Added debug loggers for checking IT failures

Signed-off-by: Aniketh Jain <[email protected]>

* Added debug loggers for checking IT failures

Signed-off-by: Aniketh Jain <[email protected]>

* Added debug loggers for checking IT failures

Signed-off-by: Aniketh Jain <[email protected]>

* Added a new stage for debug loggers before cleanup

Signed-off-by: Aniketh Jain <[email protected]>

* Added a new stage for debug loggers before cleanup

Signed-off-by: Aniketh Jain <[email protected]>

* Added logger to print error recieved from auth info during saml login

Signed-off-by: Aniketh Jain <[email protected]>

* Added Docker host N/W Config to allow connection to SAML IDP

Signed-off-by: Aniketh Jain <[email protected]>

* Added discovery type config to be single node for passing bootstrap checks

Signed-off-by: Aniketh Jain <[email protected]>

* Debug loggers

Signed-off-by: Aniketh Jain <[email protected]>

* Debug loggers

Signed-off-by: Aniketh Jain <[email protected]>

* Debug loggers

Signed-off-by: Aniketh Jain <[email protected]>

* Reverted run command to see change in error

Signed-off-by: Aniketh Jain <[email protected]>

* Trying with full docker image of OS

Signed-off-by: Aniketh Jain <[email protected]>

* Refactored the integration test yaml to use OS Full Docker image

Signed-off-by: Aniketh Jain <[email protected]>

* Removed all debug loggers

Signed-off-by: Aniketh Jain <[email protected]>

* Added selfSigned package for generating certs and integrated with saml-idp

Signed-off-by: Aniketh Jain <[email protected]>

* Deleted checked-in key and cert for saml-idp server

Signed-off-by: Aniketh Jain <[email protected]>

* Reverted use of docker image and testing again with manual build

Signed-off-by: Aniketh Jain <[email protected]>

* Reverted use of docker image and testing again with manual build

Signed-off-by: Aniketh Jain <[email protected]>

* Upgraded version from 2.3 to 2.4

Signed-off-by: Aniketh Jain <[email protected]>

* Removed debug pointers

Signed-off-by: Aniketh Jain <[email protected]>

* Commented out failing IT temporarily

Signed-off-by: Aniketh Jain <[email protected]>

* Lint formatting fix

Signed-off-by: Aniketh Jain <[email protected]>

* Added the commented failing test back again

Signed-off-by: Aniketh Jain <[email protected]>

* Removed assertion from test again to make it pass

Signed-off-by: Aniketh Jain <[email protected]>

* Used a better XPath and improved error logging in tests

Signed-off-by: Aniketh Jain <[email protected]>

* Removed an unused XPath

Signed-off-by: Aniketh Jain <[email protected]>

* Added back the assertion for failing IT

Signed-off-by: Aniketh Jain <[email protected]>

* Added steps to run Selenium based Integ Tests

Signed-off-by: Aniketh Jain <[email protected]>

* Commented out the test, will re-enable it again in the fix PR

Signed-off-by: Aniketh Jain <[email protected]>

* Parameterized the getDriver function

Signed-off-by: Aniketh Jain <[email protected]>

Signed-off-by: Deepak Devarakonda <[email protected]>
Signed-off-by: Aniketh Jain <[email protected]>
Co-authored-by: Deepak Devarakonda <[email protected]>
  • Loading branch information
expani and devardee authored Sep 19, 2022
1 parent 5d018b0 commit a4fa35d
Show file tree
Hide file tree
Showing 10 changed files with 398 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
WORKDIR /opensearch/
ENTRYPOINT /docker-host/os-ep.sh
EOF
docker run -d -p 9200:9200 -p 9600:9600 -i opensearch-test:latest
docker run -d --network=host -i opensearch-test:latest
- name: Checkout OpenSearch Dashboard
uses: actions/checkout@v2
Expand Down Expand Up @@ -103,6 +103,7 @@ jobs:
run: |
cd ./OpenSearch-Dashboards
yarn osd bootstrap
node scripts/build_opensearch_dashboards_platform_plugins.js
- name: Run integration tests
run: |
Expand Down
3 changes: 3 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
- 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
Expand Down Expand Up @@ -117,6 +118,8 @@ Next, go to the base directory and run `yarn osd bootstrap` to install any addit
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`.
To run selenium based integration tests, download and export the firefox web-driver to your PATH. Also, run `node scripts/build_opensearch_dashboards_platform_plugins.js` or `yarn start` before running the tests. This is essential to generate the bundles.
## Submitting Changes
See [CONTRIBUTING](CONTRIBUTING.md).
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@
"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"
},
"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",
"saml-idp": "^1.2.1",
"selenium-webdriver": "^4.0.0-alpha.7",
"selfsigned": "^2.0.1",
"typescript": "4.0.2"
},
"dependencies": {
"@hapi/wreck": "^17.1.0",
"@hapi/cryptiles": "5.0.0",
"@hapi/wreck": "^17.1.0",
"html-entities": "1.3.1"
}
}
8 changes: 6 additions & 2 deletions public/apps/account/account-nav-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ export function AccountNavButton(props: {
<EuiListGroupItem
color="subdued"
key="tenant"
label={<EuiText size="xs">{resolveTenantName(props.tenant || '', username)}</EuiText>}
label={
<EuiText size="xs" id="tenantName">
{resolveTenantName(props.tenant || '', username)}
</EuiText>
}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down Expand Up @@ -140,7 +144,7 @@ export function AccountNavButton(props: {
</div>
);
return (
<EuiHeaderSectionItemButton>
<EuiHeaderSectionItemButton id="user-icon-btn">
<EuiPopover
data-test-subj="account-popover"
id="actionsMenu"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Account navigation button renders 1`] = `
<EuiHeaderSectionItemButton>
<EuiHeaderSectionItemButton
id="user-icon-btn"
>
<EuiPopover
anchorPosition="downCenter"
button={
Expand Down Expand Up @@ -63,6 +65,7 @@ exports[`Account navigation button renders 1`] = `
key="tenant"
label={
<EuiText
id="tenantName"
size="xs"
>
tenant1
Expand Down
2 changes: 2 additions & 0 deletions server/auth/types/saml/saml_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -97,6 +98,7 @@ export class SamlAuthentication extends AuthenticationType {
};
}

// Can be improved to check if the token is expiring.
async isValidCookie(cookie: SecuritySessionCookie): Promise<boolean> {
return (
cookie.authType === this.type &&
Expand Down
1 change: 1 addition & 0 deletions server/backend/opensearch_security_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export class SecurityClient {
// location="https://<your-auth-domain.com>/api/saml2/v1/sso?SAMLRequest=<some-encoded-string>"
// requestId="<request_id>"
// '

if (!error.wwwAuthenticateDirective) {
throw error;
}
Expand Down
2 changes: 1 addition & 1 deletion test/helper/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
32 changes: 32 additions & 0 deletions test/jest_integration/runIdpServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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');

const { generate } = require('selfsigned');

const pems = generate(null, {
keySize: 2048,
clientCertificateCN: '/C=US/ST=California/L=San Francisco/O=JankyCo/CN=Test Identity Provider',
days: 7300,
});

// Create certificate pair on the fly and pass it to runServer
runServer({
acsUrl: 'http://localhost:5601/_opendistro/_security/saml/acs',
audience: 'https://localhost:9200',
cert: pems.cert,
key: pems.private.toString().replace(/\r\n/, '\n'),
});
Loading

0 comments on commit a4fa35d

Please sign in to comment.