diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-16 23:18:02 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-18 15:46:42 +0200 |
| commit | a6865b86cc8d710374fc0b6cfcbd2b863f1942a9 (patch) | |
| tree | 121fdb26827c5509a12a4427e8f9d881dbdefe82 /opendc-web/opendc-web-ui/src/redux/sagas | |
| parent | 6412610f38117e1ea0635a56fa023183723fa67a (diff) | |
ui: Migrate to Auth0 as Identity Provider
This change updates the frontend codebase to move away from the Google
login and instead use Auth0 as generic Identity Provider. This allows
users to login with other accounts as well.
Since Auth0 has a free tier, users can experiment themselves with OpenDC
locally without having to pay for the login functionality. The code has
been written so that we should be able to migrate away from Auth0 once
it is not a suitable Identity Provider for OpenDC anymore.
Diffstat (limited to 'opendc-web/opendc-web-ui/src/redux/sagas')
9 files changed, 67 insertions, 108 deletions
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/index.js b/opendc-web/opendc-web-ui/src/redux/sagas/index.js index 6332b2fb..a8f44843 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/index.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/index.js @@ -1,7 +1,6 @@ import { takeEvery } from 'redux-saga/effects' -import { LOG_IN } from '../actions/auth' import { ADD_PORTFOLIO, DELETE_PORTFOLIO, OPEN_PORTFOLIO_SUCCEEDED, UPDATE_PORTFOLIO } from '../actions/portfolios' -import { ADD_PROJECT, DELETE_PROJECT, OPEN_PROJECT_SUCCEEDED } from '../actions/projects' +import { ADD_PROJECT, DELETE_PROJECT, FETCH_PROJECTS, OPEN_PROJECT_SUCCEEDED } from '../actions/projects' import { ADD_TILE, CANCEL_NEW_ROOM_CONSTRUCTION, @@ -11,10 +10,8 @@ import { import { ADD_UNIT, DELETE_MACHINE, DELETE_UNIT } from '../actions/topology/machine' import { ADD_MACHINE, DELETE_RACK, EDIT_RACK_NAME } from '../actions/topology/rack' import { ADD_RACK_TO_TILE, DELETE_ROOM, EDIT_ROOM_NAME } from '../actions/topology/room' -import { DELETE_CURRENT_USER, FETCH_AUTHORIZATIONS_OF_CURRENT_USER } from '../actions/users' import { onAddPortfolio, onDeletePortfolio, onOpenPortfolioSucceeded, onUpdatePortfolio } from './portfolios' -import { onDeleteCurrentUser } from './profile' -import { onOpenProjectSucceeded, onProjectAdd, onProjectDelete } from './projects' +import { onFetchProjects, onOpenProjectSucceeded, onProjectAdd, onProjectDelete } from './projects' import { onAddMachine, onAddRackToTile, @@ -32,7 +29,6 @@ import { onEditRoomName, onStartNewRoomConstruction, } from './topology' -import { onFetchAuthorizationsOfCurrentUser, onFetchLoggedInUser } from './users' import { ADD_TOPOLOGY, DELETE_TOPOLOGY } from '../actions/topologies' import { ADD_SCENARIO, DELETE_SCENARIO, OPEN_SCENARIO_SUCCEEDED, UPDATE_SCENARIO } from '../actions/scenarios' import { onAddScenario, onDeleteScenario, onOpenScenarioSucceeded, onUpdateScenario } from './scenarios' @@ -40,14 +36,10 @@ import { onAddPrefab } from './prefabs' import { ADD_PREFAB } from '../actions/prefabs' export default function* rootSaga() { - yield takeEvery(LOG_IN, onFetchLoggedInUser) - - yield takeEvery(FETCH_AUTHORIZATIONS_OF_CURRENT_USER, onFetchAuthorizationsOfCurrentUser) + yield takeEvery(FETCH_PROJECTS, onFetchProjects) yield takeEvery(ADD_PROJECT, onProjectAdd) yield takeEvery(DELETE_PROJECT, onProjectDelete) - yield takeEvery(DELETE_CURRENT_USER, onDeleteCurrentUser) - yield takeEvery(OPEN_PROJECT_SUCCEEDED, onOpenProjectSucceeded) yield takeEvery(OPEN_PORTFOLIO_SUCCEEDED, onOpenPortfolioSucceeded) yield takeEvery(OPEN_SCENARIO_SUCCEEDED, onOpenScenarioSucceeded) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js b/opendc-web/opendc-web-ui/src/redux/sagas/objects.js index 82dbb935..e5fd092d 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/objects.js @@ -1,9 +1,8 @@ -import { call, put, select } from 'redux-saga/effects' +import { call, put, select, getContext } from 'redux-saga/effects' import { addToStore } from '../actions/objects' import { getAllSchedulers } from '../../api/schedulers' import { getProject } from '../../api/projects' import { getAllTraces } from '../../api/traces' -import { getUser } from '../../api/users' import { getTopology, updateTopology } from '../../api/topologies' import { uuid } from 'uuidv4' @@ -42,9 +41,10 @@ function* fetchAndStoreObjects(objectType, apiCall) { return objects } -export const fetchAndStoreProject = (id) => fetchAndStoreObject('project', id, call(getProject, id)) - -export const fetchAndStoreUser = (id) => fetchAndStoreObject('user', id, call(getUser, id)) +export const fetchAndStoreProject = function* (id) { + const auth = yield getContext('auth') + return yield fetchAndStoreObject('project', id, call(getProject, auth, id)) +} export const fetchAndStoreTopology = function* (id) { const topologyStore = yield select(OBJECT_SELECTORS['topology']) @@ -52,10 +52,11 @@ export const fetchAndStoreTopology = function* (id) { const tileStore = yield select(OBJECT_SELECTORS['tile']) const rackStore = yield select(OBJECT_SELECTORS['rack']) const machineStore = yield select(OBJECT_SELECTORS['machine']) + const auth = yield getContext('auth') let topology = topologyStore[id] if (!topology) { - const fullTopology = yield call(getTopology, id) + const fullTopology = yield call(getTopology, auth, id) for (let roomIdx in fullTopology.rooms) { const fullRoom = fullTopology.rooms[roomIdx] @@ -142,8 +143,8 @@ const generateIdIfNotPresent = (obj) => { export const updateTopologyOnServer = function* (id) { const topology = yield getTopologyAsObject(id, true) - - yield call(updateTopology, topology) + const auth = yield getContext('auth') + yield call(updateTopology, auth, topology) } export const getTopologyAsObject = function* (id, keepIds) { @@ -217,10 +218,14 @@ export const getRackById = function* (id, keepIds) { } } -export const fetchAndStoreAllTraces = () => fetchAndStoreObjects('trace', call(getAllTraces)) +export const fetchAndStoreAllTraces = function* () { + const auth = yield getContext('auth') + return yield fetchAndStoreObjects('trace', call(getAllTraces, auth)) +} export const fetchAndStoreAllSchedulers = function* () { - const objects = yield call(getAllSchedulers) + const auth = yield getContext('auth') + const objects = yield call(getAllSchedulers, auth) for (let object of objects) { object._id = object.name yield put(addToStore('scheduler', object)) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js b/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js index 8ddf888d..340cb490 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js @@ -1,4 +1,4 @@ -import { call, put, select, delay } from 'redux-saga/effects' +import { call, put, select, delay, getContext } from 'redux-saga/effects' import { addPropToStoreObject, addToStore } from '../actions/objects' import { addPortfolio, deletePortfolio, getPortfolio, updatePortfolio } from '../../api/portfolios' import { getProject } from '../../api/projects' @@ -8,7 +8,8 @@ import { getScenario } from '../../api/scenarios' export function* onOpenPortfolioSucceeded(action) { try { - const project = yield call(getProject, action.projectId) + const auth = yield getContext('auth') + const project = yield call(getProject, auth, action.projectId) yield put(addToStore('project', project)) yield fetchAndStoreAllTopologiesOfProject(project._id) yield fetchPortfoliosOfProject() @@ -66,11 +67,12 @@ export function* fetchPortfoliosOfProject() { export function* fetchPortfolioWithScenarios(portfolioId) { try { - const portfolio = yield call(getPortfolio, portfolioId) + const auth = yield getContext('auth') + const portfolio = yield call(getPortfolio, auth, portfolioId) yield put(addToStore('portfolio', portfolio)) for (let i in portfolio.scenarioIds) { - const scenario = yield call(getScenario, portfolio.scenarioIds[i]) + const scenario = yield call(getScenario, auth, portfolio.scenarioIds[i]) yield put(addToStore('scenario', scenario)) } return portfolio @@ -82,9 +84,10 @@ export function* fetchPortfolioWithScenarios(portfolioId) { export function* onAddPortfolio(action) { try { const currentProjectId = yield select((state) => state.currentProjectId) - + const auth = yield getContext('auth') const portfolio = yield call( addPortfolio, + auth, currentProjectId, Object.assign({}, action.portfolio, { projectId: currentProjectId, @@ -106,7 +109,8 @@ export function* onAddPortfolio(action) { export function* onUpdatePortfolio(action) { try { - const portfolio = yield call(updatePortfolio, action.portfolio._id, action.portfolio) + const auth = yield getContext('auth') + const portfolio = yield call(updatePortfolio, auth, action.portfolio._id, action.portfolio) yield put(addToStore('portfolio', portfolio)) } catch (error) { console.error(error) @@ -115,7 +119,8 @@ export function* onUpdatePortfolio(action) { export function* onDeletePortfolio(action) { try { - yield call(deletePortfolio, action.id) + const auth = yield getContext('auth') + yield call(deletePortfolio, auth, action.id) const currentProjectId = yield select((state) => state.currentProjectId) const portfolioIds = yield select((state) => state.objects.project[currentProjectId].portfolioIds) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js b/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js index 3158a219..ec679391 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/prefabs.js @@ -1,4 +1,4 @@ -import { call, put, select } from 'redux-saga/effects' +import { call, put, select, getContext } from 'redux-saga/effects' import { addToStore } from '../actions/objects' import { addPrefab } from '../../api/prefabs' import { getRackById } from './objects' @@ -7,7 +7,8 @@ export function* onAddPrefab(action) { try { const currentRackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rackId) const currentRackJson = yield getRackById(currentRackId, false) - const prefab = yield call(addPrefab, { name: action.name, rack: currentRackJson }) + const auth = yield getContext('auth') + const prefab = yield call(addPrefab, auth, { name: action.name, rack: currentRackJson }) yield put(addToStore('prefab', prefab)) } catch (error) { console.error(error) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/profile.js b/opendc-web/opendc-web-ui/src/redux/sagas/profile.js deleted file mode 100644 index e187b765..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/profile.js +++ /dev/null @@ -1,12 +0,0 @@ -import { call, put } from 'redux-saga/effects' -import { deleteCurrentUserSucceeded } from '../actions/users' -import { deleteUser } from '../../api/users' - -export function* onDeleteCurrentUser(action) { - try { - yield call(deleteUser, action.userId) - yield put(deleteCurrentUserSucceeded()) - } catch (error) { - console.error(error) - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js b/opendc-web/opendc-web-ui/src/redux/sagas/projects.js index ecd9a7c9..506df6ed 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/projects.js @@ -1,14 +1,15 @@ -import { call, put } from 'redux-saga/effects' +import { call, put, getContext } from 'redux-saga/effects' import { addToStore } from '../actions/objects' -import { addProjectSucceeded, deleteProjectSucceeded } from '../actions/projects' -import { addProject, deleteProject, getProject } from '../../api/projects' +import { addProjectSucceeded, deleteProjectSucceeded, fetchProjectsSucceeded } from '../actions/projects' +import { addProject, deleteProject, getProject, getProjects } from '../../api/projects' import { fetchAndStoreAllTopologiesOfProject } from './topology' import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' import { fetchPortfoliosOfProject } from './portfolios' export function* onOpenProjectSucceeded(action) { try { - const project = yield call(getProject, action.id) + const auth = yield getContext('auth') + const project = yield call(getProject, auth, action.id) yield put(addToStore('project', project)) yield fetchAndStoreAllTopologiesOfProject(action.id, true) @@ -22,17 +23,10 @@ export function* onOpenProjectSucceeded(action) { export function* onProjectAdd(action) { try { - const project = yield call(addProject, { name: action.name }) + const auth = yield getContext('auth') + const project = yield call(addProject, auth, { name: action.name }) yield put(addToStore('project', project)) - - const authorization = { - projectId: project._id, - userId: action.userId, - authorizationLevel: 'OWN', - project, - } - yield put(addToStore('authorization', authorization)) - yield put(addProjectSucceeded([authorization.userId, authorization.projectId])) + yield put(addProjectSucceeded(project)) } catch (error) { console.error(error) } @@ -40,9 +34,20 @@ export function* onProjectAdd(action) { export function* onProjectDelete(action) { try { - yield call(deleteProject, action.id) + const auth = yield getContext('auth') + yield call(deleteProject, auth, action.id) yield put(deleteProjectSucceeded(action.id)) } catch (error) { console.error(error) } } + +export function* onFetchProjects(action) { + try { + const auth = yield getContext('auth') + const projects = yield call(getProjects, auth) + yield put(fetchProjectsSucceeded(projects)) + } catch (error) { + console.error(error) + } +} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js b/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js index a5463fa6..bdb7c45d 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js @@ -1,4 +1,4 @@ -import { call, put, select } from 'redux-saga/effects' +import { call, put, select, getContext } from 'redux-saga/effects' import { addPropToStoreObject, addToStore } from '../actions/objects' import { getProject } from '../../api/projects' import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' @@ -8,7 +8,8 @@ import { fetchPortfolioWithScenarios, watchForPortfolioResults } from './portfol export function* onOpenScenarioSucceeded(action) { try { - const project = yield call(getProject, action.projectId) + const auth = yield getContext('auth') + const project = yield call(getProject, auth, action.projectId) yield put(addToStore('project', project)) yield fetchAndStoreAllTopologiesOfProject(project._id) yield fetchAndStoreAllSchedulers() @@ -23,7 +24,8 @@ export function* onOpenScenarioSucceeded(action) { export function* onAddScenario(action) { try { - const scenario = yield call(addScenario, action.scenario.portfolioId, action.scenario) + const auth = yield getContext('auth') + const scenario = yield call(addScenario, auth, action.scenario.portfolioId, action.scenario) yield put(addToStore('scenario', scenario)) const scenarioIds = yield select((state) => state.objects.portfolio[action.scenario.portfolioId].scenarioIds) @@ -40,7 +42,8 @@ export function* onAddScenario(action) { export function* onUpdateScenario(action) { try { - const scenario = yield call(updateScenario, action.scenario._id, action.scenario) + const auth = yield getContext('auth') + const scenario = yield call(updateScenario, auth, action.scenario._id, action.scenario) yield put(addToStore('scenario', scenario)) } catch (error) { console.error(error) @@ -49,7 +52,8 @@ export function* onUpdateScenario(action) { export function* onDeleteScenario(action) { try { - yield call(deleteScenario, action.id) + const auth = yield getContext('auth') + yield call(deleteScenario, auth, action.id) const currentPortfolioId = yield select((state) => state.currentPortfolioId) const scenarioIds = yield select((state) => state.objects.portfolio[currentPortfolioId].scenarioIds) diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js index 65f97cc9..e5fd3d39 100644 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js @@ -1,4 +1,4 @@ -import { call, put, select } from 'redux-saga/effects' +import { call, put, select, getContext } from 'redux-saga/effects' import { goDownOneInteractionLevel } from '../actions/interaction-level' import { addIdToStoreObjectListProp, @@ -50,8 +50,10 @@ export function* onAddTopology(action) { topologyToBeCreated = { name: action.name, rooms: [] } } + const auth = yield getContext('auth') const topology = yield call( addTopology, + auth, Object.assign({}, topologyToBeCreated, { projectId: currentProjectId, }) @@ -79,7 +81,8 @@ export function* onDeleteTopology(action) { yield put(setCurrentTopology(topologyIds.filter((t) => t !== action.id)[0])) } - yield call(deleteTopology, action.id) + const auth = yield getContext('auth') + yield call(deleteTopology, auth, action.id) yield put( addPropToStoreObject('project', currentProjectId, { diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/users.js b/opendc-web/opendc-web-ui/src/redux/sagas/users.js deleted file mode 100644 index 88c424b5..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/users.js +++ /dev/null @@ -1,44 +0,0 @@ -import { call, put } from 'redux-saga/effects' -import { logInSucceeded } from '../actions/auth' -import { addToStore } from '../actions/objects' -import { fetchAuthorizationsOfCurrentUserSucceeded } from '../actions/users' -import { performTokenSignIn } from '../../api/token-signin' -import { addUser } from '../../api/users' -import { saveAuthLocalStorage } from '../../auth' -import { fetchAndStoreProject, fetchAndStoreUser } from './objects' - -export function* onFetchLoggedInUser(action) { - try { - const tokenResponse = yield call(performTokenSignIn, action.payload.authToken) - - let userId = tokenResponse.userId - - if (tokenResponse.isNewUser) { - saveAuthLocalStorage({ authToken: action.payload.authToken }) - const newUser = yield call(addUser, action.payload) - userId = newUser._id - } - - yield put(logInSucceeded(Object.assign({ userId }, action.payload))) - } catch (error) { - console.error(error) - } -} - -export function* onFetchAuthorizationsOfCurrentUser(action) { - try { - const user = yield call(fetchAndStoreUser, action.userId) - - for (const authorization of user.authorizations) { - authorization.userId = action.userId - yield put(addToStore('authorization', authorization)) - yield fetchAndStoreProject(authorization.projectId) - } - - const authorizationIds = user.authorizations.map((authorization) => [action.userId, authorization.projectId]) - - yield put(fetchAuthorizationsOfCurrentUserSucceeded(authorizationIds)) - } catch (error) { - console.error(error) - } -} |
