summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/README.md
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-18 20:34:13 +0200
committerGitHub <noreply@github.com>2021-05-18 20:34:13 +0200
commit56bd2ef6b0583fee1dd2da5dceaf57feb07649c9 (patch)
tree6d4cfbc44c97cd3ec1e30aa977cd08f404b41b0d /opendc-web/opendc-web-ui/README.md
parent02776c958a3254735b2be7d9fb1627f75e7f80cd (diff)
parentce95cfdf803043e66e2279d0f76c6bfc64e7864e (diff)
Migrate to Auth0 as Identity Provider
This pull request removes the hard dependency on Google for authenticating users and migrates to Auth0 as Identity Provider for OpenDC. This has as benefit that we can authenticate users without having to manage user data ourselves and do not have a dependency on Google accounts anymore. - Frontend cleanup: - Use CSS modules everywhere to encapsulate the styling of React components. - Perform all communication in the frontend via the REST API (as opposed to WebSockets). The original approach was aimed at collaborative editing, but made normal operations harder to implement and debug. If we want to implement collaborative editing in the future, we can expose only a small WebSocket API specifically for collaborative editing. - Move to FontAwesome 5 (using the official React libraries) - Use Reactstrap where possible. Previously, we mixed raw Bootstrap classes with Reactstrap, which is confusing. - Reduce the scope of the Redux state. Some state in the frontend application can be kept locally and does not need to be managed by Redux. - Migrate from Create React App (CRA) to Next.js since it allows us to pre-render multiple pages as well as opt-in to Server Side Rendering. - Remove the Google login and use Auth0 for authentication now. - Use Node 16 - Backend cleanup: - Remove Socket.IO endpoint from backend, since it is not needed by the frontend anymore. Removing it reduces the attack surface of OpenDC as well as the maintenance efforts. - Use Auth0 JWT token for authorizing API accesses - Refactor API endpoints to use Flask Restful as opposed to our custom in-house routing logic. Previously, this was needed to support the Socket.IO endpoint, but increases maintenance effort. - Expose Swagger UI from API - Use Python 3.9 and uwsgi to host Flask application - Actualize OpenAPI schema and update to version 3.0. **Breaking API Changes** * This pull request removes the users collection from the database table. Instead, we now use the user identifier passed by Auth0 to identify the data that belongs to a user.
Diffstat (limited to 'opendc-web/opendc-web-ui/README.md')
-rw-r--r--opendc-web/opendc-web-ui/README.md73
1 files changed, 51 insertions, 22 deletions
diff --git a/opendc-web/opendc-web-ui/README.md b/opendc-web/opendc-web-ui/README.md
index f3a58e7a..d562f2a4 100644
--- a/opendc-web/opendc-web-ui/README.md
+++ b/opendc-web/opendc-web-ui/README.md
@@ -7,16 +7,19 @@
Collaborative Datacenter Simulation and Exploration for Everybody
</p>
-The user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual) datacenters. Built in *React.js* and *Redux*, with the help of `create-react-app`.
-
+The user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual)
+datacenters. Built in *React.js* and *Redux*, with the help of [Next.js](https://nextjs.org/).
## Get Up and Running
-Looking for the full OpenDC stack? Check out [the main OpenDC repo](https://github.com/atlarge-research/opendc) for instructions on how to set up a Docker container with all of OpenDC, without the hassle of running each of the components manually.
+Looking for the full OpenDC stack? Check out the [deployment guide](../../docs/deploy.md) for instructions on
+how to set up a Docker container with all of OpenDC, without the hassle of running each of the components manually.
### Installation
-To get started, you'll need the [Node.js environment](https://nodejs.org) and the [Yarn package manager](https://yarnpkg.com). Once you have those installed, run the following command from the root directory of this repo:
+To get started, you'll need the [Node.js environment](https://nodejs.org) and
+the [Yarn package manager](https://yarnpkg.com). Once you have those installed, run the following command from the root
+directory of this repo:
```bash
yarn
@@ -24,17 +27,22 @@ yarn
### Running the development server
-First, you need to have a Google OAuth client ID set up. Check the [documentation of the main OpenDC repo](https://github.com/atlarge-research/opendc) if you're not sure how to do this. Once you have such an ID, you need to set it as environment variable `REACT_APP_OAUTH_CLIENT_ID`. One way of doing this is to create an `.env` file with content `REACT_APP_OAUTH_CLIENT_ID=YOUR_ID` (`YOUR_ID` without quotes), in the root directory of this repo.
+First, you need to set up an [Auth0](https://auth0.com) application. Check
+the [documentation in the deployment guide](../../docs/deploy.md) if you're not sure how to do this. Once you have such
+an ID, you need to set it as environment variable `NEXT_PUBLIC_AUTH0_CLIENT_ID` and `NEXT_PUBLIC_AUTH0_DOMAIN`
+One way of doing this is to create an `.env.local` file with content `NEXT_PUBLIC_AUTH0_CLIENT_ID=YOUR_ID` and
+`NEXT_PUBLIC_AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN` in the root directory of this repo.
Once you've set this variable, start the OpenDC `docker-compose` setup. See the root README for instructions on this.
-
+
Now, you're ready to start the development server:
```bash
-yarn start
+yarn dev
```
-This will start a development server running on [`localhost:3000`](http://localhost:3000), watching for changes you make to the code and rebuilding automatically when you save changes.
+This will start a development server running on [`localhost:3000`](http://localhost:3000), watching for changes you make
+to the code and rebuilding automatically when you save changes.
To compile everything for camera-ready deployment, use the following command:
@@ -42,47 +50,68 @@ To compile everything for camera-ready deployment, use the following command:
yarn build
```
+You can run the production server using Next.js as follows:
+
+```bash
+yarn start
+```
## Architecture
-The codebase follows a standard React.js structure, with static assets being contained in the `public` folder, while dynamic components and their styles are contained in `src`. The app uses client-side routing (with `react-router`), meaning that the only HTML file needing to be served is a `index.html` file.
+The codebase follows a standard React.js structure, with static assets being contained in the `public` folder, while
+dynamic components and their styles are contained in `src`.
### Pages
-All pages are represented by a component in the `src/pages` directory. There are components for the following pages:
+All pages are represented by a component in the `src/pages` directory, following
+the [Next.js conventions](https://nextjs.org/docs/routing/introduction) for routing. There are components for the
+following pages:
-**Home.js** - Entry page (`/`)
+**index.js** - Entry page (`/`)
-**Projects.js** - Overview of projects of the user (`/projects`)
+**projects/index.js** - Overview of projects of the user (`/projects`)
-**App.js** - Main application, with datacenter construction and simulation UI (`/projects/:projectId` and `/projects/:projectId/portfolios/:portfolioId`)
+**projects/[project]/index.js** - Main application, with datacenter construction and simulation UI (`/projects/:projectId`
+and `/projects/:projectId/portfolios/:portfolioId`)
-**Profile.js** - Profile of the current user (`/profile`)
+**profile.js** - Profile of the current user (`/profile`)
-**NotFound.js** - 404 page to appear when the route is invalid (`/*`)
+**404.js** - 404 page to appear when the route is invalid (`/*`)
### Components & Containers
-The building blocks of the UI are divided into so-called *components* and *containers* ([as encouraged](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) by the author of Redux). *Components* are considered 'pure', rendered as a function of input properties. *Containers*, on the other hand, are wrappers around *components*, injecting state through the properties of the components they wrap.
+The building blocks of the UI are divided into so-called *components* and *
+containers* ([as encouraged](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) by the author of
+Redux). *Components* are considered 'pure', rendered as a function of input properties. *Containers*, on the other hand,
+are wrappers around *components*, injecting state through the properties of the components they wrap.
-Even the canvas (the main component of the app) is built using React components, with the help of the `react-konva` module. To illustrate: A rectangular object on the canvas is defined in a way that is not very different from how we define a standard `div` element on the splashpage.
+Even the canvas (the main component of the app) is built using React components, with the help of the `react-konva`
+module. To illustrate: A rectangular object on the canvas is defined in a way that is not very different from how we
+define a standard `div` element on the splashpage.
### State Management
-Almost all state is kept in a central Redux store. State is kept there in an immutable form, only to be modified through actions being dispatched. These actions are contained in the `src/actions` folder, and the reducers (managing how state is updated according to dispatched actions) are located in `src/reducers`. If you're not familiar with the Redux approach to state management, have a look at their [official documentation](https://redux.js.org/).
+Almost all state is kept in a central Redux store. State is kept there in an immutable form, only to be modified through
+actions being dispatched. These actions are contained in the `src/actions` folder, and the reducers (managing how state
+is updated according to dispatched actions) are located in `src/reducers`. If you're not familiar with the Redux
+approach to state management, have a look at their [official documentation](https://redux.js.org/).
### API Interaction
-The web-app needs to pull data in from the API of a backend running on a server. The functions that call routes are located in `src/api`. The actual logic responsible for calling these functions is contained in `src/sagas`. These API fetch procedures are written with the help of `redux-saga`. The [official documentation](https://redux-saga.js.org/) of `redux-saga` can be a helpful aid in understanding that part of the codebase.
-
+The web-app needs to pull data in from the API of a backend running on a server. The functions that call routes are
+located in `src/api`. The actual logic responsible for calling these functions is contained in `src/sagas`. These API
+fetch procedures are written with the help of `redux-saga`. The [official documentation](https://redux-saga.js.org/)
+of `redux-saga` can be a helpful aid in understanding that part of the codebase.
## Tests
-Files containing tests can be recognized by the `.test.js` suffix. They are usually located right next to the source code they are testing, to make discovery easier.
+Files containing tests can be recognized by the `.test.js` suffix. They are usually located right next to the source
+code they are testing, to make discovery easier.
### Running all tests
-The following command runs all tests in the codebase. On top of this, it also watches the code for changes and reruns the tests whenever any file is saved.
+The following command runs all tests in the codebase. On top of this, it also watches the code for changes and reruns
+the tests whenever any file is saved.
```bash
yarn test