Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ server=3.2|3.3|3.4|3.5 (default 3.4)
browser-password=<your-pw> (default 'newpassword')
include-import-tests=true|false (default false)
bolt-url=<bolt url excluding the protocol> (default localhost:7687)
E2E_TEST_ENV=local|null (if the initial set of pw should run or not) (default undefined)
BROWSER_URL=<url to reach the browser to test> (default http://localhost:8080)
```

Test environment options (cannot be set using the `--env` flag as the ones above).
These needs to be set before the test command is run.

```
CYPRESS_E2E_TEST_ENV=local|null (if the initial set of pw should run or not) (default undefined)
CYPRESS_BASE_URL=<url to reach the browser to test> (default http://localhost:8080)
```

Example: `CYPRESS_E2E_TEST_ENV="local" CYPRESS_BASE_URL=http://localhost:8081 cypress open --env server=3.4`

## Devtools

Download these two chrome extensions:
Expand Down
2 changes: 1 addition & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"animationDistanceThreshold": 5,
"baseUrl": null,
"baseUrl": "http://localhost:8080",
"chromeWebSecurity": true,
"defaultCommandTimeout": 4000,
"environmentVariables": {},
Expand Down
2 changes: 1 addition & 1 deletion e2e_tests/support/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Cypress.config.serverVersion = parseFloat(Cypress.env('server')) || 3.4
Cypress.config.includeImportTests = Cypress.env('include-import-tests') || false
Cypress.config.url = Cypress.env('BROWSER_URL') || 'http://localhost:8080'
Cypress.config.url = '/'
Cypress.config.password = Cypress.env('browser-password') || 'newpassword'
Cypress.config.boltHost = Cypress.env('bolt-url')
? Cypress.env('bolt-url').split(':')[0]
Expand Down
15 changes: 12 additions & 3 deletions src/shared/modules/commands/commandsDuck.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import {
extractWhitelistFromConfigString,
addProtocolsToUrlList,
firstSuccessPromise,
serialExecution
serialExecution,
resolveWhitelistWildcard
} from 'services/utils'
import helper from 'services/commandInterpreterHelper'
import { addHistory } from '../history/historyDuck'
Expand All @@ -45,7 +46,8 @@ import {
UPDATE_SETTINGS,
getAvailableSettings,
fetchMetaData,
getRemoteContentHostnameWhitelist
getRemoteContentHostnameWhitelist,
getDefaultRemoteContentHostnameWhitelist
} from '../dbMeta/dbMetaDuck'
import { APP_START, USER_CLEAR } from 'shared/modules/app/appDuck'
import { add as addFrame } from 'shared/modules/stream/streamDuck'
Expand Down Expand Up @@ -256,7 +258,14 @@ export const fetchGuideFromWhitelistEpic = (some$, store) =>
}
const whitelistStr = getRemoteContentHostnameWhitelist(store.getState())
const whitelist = extractWhitelistFromConfigString(whitelistStr)
const urlWhitelist = addProtocolsToUrlList(whitelist)
const defaultWhitelist = extractWhitelistFromConfigString(
getDefaultRemoteContentHostnameWhitelist(store.getState())
)
const resolvedWildcardWhitelist = resolveWhitelistWildcard(
whitelist,
defaultWhitelist
)
const urlWhitelist = addProtocolsToUrlList(resolvedWildcardWhitelist)
const guidesUrls = urlWhitelist.map(url => url + '/' + action.url)
return firstSuccessPromise(guidesUrls, url => {
// Get first successful fetch
Expand Down
128 changes: 128 additions & 0 deletions src/shared/modules/commands/remoteGuides.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2002-2018 "Neo4j, Inc"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/* global jest, describe, afterEach, test, expect */
import { createEpicMiddleware } from 'redux-observable'
import { createBus } from 'suber'
import {
fetchGuideFromWhitelistAction,
fetchGuideFromWhitelistEpic
} from './commandsDuck'

jest.mock('services/remote', () => {
const orig = require.requireActual('services/remote')
return {
...orig,
get: jest.fn()
}
})
const remote = require.requireMock('services/remote')

jest.mock('shared/modules/dbMeta/dbMetaDuck', () => {
const orig = require.requireActual('shared/modules/dbMeta/dbMetaDuck')
return {
...orig,
getRemoteContentHostnameWhitelist: jest.fn(),
getDefaultRemoteContentHostnameWhitelist: jest.fn()
}
})
const dbMeta = require.requireMock('shared/modules/dbMeta/dbMetaDuck')

describe('fetchGuideFromWhitelistEpic', () => {
afterEach(() => {
remote.get.mockReset()
dbMeta.getRemoteContentHostnameWhitelist.mockReset()
dbMeta.getDefaultRemoteContentHostnameWhitelist.mockReset()
})

it('resolves * to default whitelist when looking for a guide', done => {
// Given
const bus = createBus()
bus.applyReduxMiddleware(createEpicMiddleware(fetchGuideFromWhitelistEpic))
remote.get.mockImplementation(() => Promise.reject(new Error('test')))
dbMeta.getRemoteContentHostnameWhitelist.mockImplementation(() => '*')
dbMeta.getDefaultRemoteContentHostnameWhitelist.mockImplementation(
() => 'testurl1.test, testurl2.test'
)
const $$responseChannel = 'test-channel'
const action = fetchGuideFromWhitelistAction('reco')
action.$$responseChannel = $$responseChannel
bus.one($$responseChannel, res => {
// Then
expect(dbMeta.getRemoteContentHostnameWhitelist).toHaveBeenCalledTimes(1)
expect(
dbMeta.getDefaultRemoteContentHostnameWhitelist
).toHaveBeenCalledTimes(1)
expect(remote.get).toHaveBeenCalledTimes(4) // 2 times per hostname
expect(remote.get).toHaveBeenCalledWith('http://testurl1.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
expect(remote.get).toHaveBeenCalledWith('https://testurl1.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
expect(remote.get).toHaveBeenCalledWith('http://testurl2.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
expect(remote.get).toHaveBeenCalledWith('https://testurl2.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
done()
})
bus.send(action.type, action)
})
it('does not change behavior when * isnt involved', done => {
// Given
const bus = createBus()
bus.applyReduxMiddleware(createEpicMiddleware(fetchGuideFromWhitelistEpic))
remote.get.mockImplementation(() => Promise.reject(new Error('test')))
dbMeta.getRemoteContentHostnameWhitelist.mockImplementation(
() => 'configurl1.test'
)

dbMeta.getDefaultRemoteContentHostnameWhitelist.mockImplementation(
() => 'test1.test, test2.test'
)
const $$responseChannel = 'test-channel'
const action = fetchGuideFromWhitelistAction('reco')
action.$$responseChannel = $$responseChannel
bus.one($$responseChannel, res => {
// Then
expect(dbMeta.getRemoteContentHostnameWhitelist).toHaveBeenCalledTimes(1)
expect(
dbMeta.getDefaultRemoteContentHostnameWhitelist
).toHaveBeenCalledTimes(1)
expect(remote.get).toHaveBeenCalledTimes(2)
expect(remote.get).toHaveBeenCalledWith('http://configurl1.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
expect(remote.get).toHaveBeenCalledWith('https://configurl1.test/reco', {
'cache-control': 'no-cache',
pragma: 'no-cache'
})
done()
})
bus.send(action.type, action)
})
})
2 changes: 2 additions & 0 deletions src/shared/modules/dbMeta/dbMetaDuck.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ export const credentialsTimeout = state =>
export const getRemoteContentHostnameWhitelist = state =>
getAvailableSettings(state)['browser.remote_content_hostname_whitelist'] ||
initialState.settings['browser.remote_content_hostname_whitelist']
export const getDefaultRemoteContentHostnameWhitelist = () =>
initialState.settings['browser.remote_content_hostname_whitelist']
export const shouldRetainConnectionCredentials = state => {
const settings = getAvailableSettings(state)
const conf = settings['browser.retain_connection_credentials']
Expand Down
9 changes: 9 additions & 0 deletions src/shared/services/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ export const addProtocolsToUrlList = list => {
}, [])
}

export const resolveWhitelistWildcard = (list, resolveTo = []) => {
return list.reduce((all, entry) => {
if (entry && entry.trim() === '*') {
entry = resolveTo
}
return all.concat(entry)
}, [])
}

export const getUrlInfo = url => {
let protocolMissing = false

Expand Down
37 changes: 37 additions & 0 deletions src/shared/services/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,43 @@ describe('utils', () => {
])
})
})
describe('resolveWhitelistWildcard', () => {
test('Resolves * to given urls', () => {
// Given
const input = ['*']
const resolveTo = ['guides.neo4j.com', 'localhost']

// When
const res = utils.resolveWhitelistWildcard(input, resolveTo)

// Then
expect(res).toEqual(['guides.neo4j.com', 'localhost'])
})
test('Resolves * to given urls when in a list', () => {
// Given
const input = [
'http://test.com',
'oskarhane.com',
'*',
null,
'https://mysite.com/guides'
]
const resolveTo = ['guides.neo4j.com', 'localhost']

// When
const res = utils.resolveWhitelistWildcard(input, resolveTo)

// Then
expect(res).toEqual([
'http://test.com',
'oskarhane.com',
'guides.neo4j.com',
'localhost',
null,
'https://mysite.com/guides'
])
})
})
describe('hostIsAllowed', () => {
test('should respect host whitelist', () => {
// Given
Expand Down