# Stackspin Dashboard

This repo hosts the Stackspin Dashboard, both frontend and backend code.

## Project structure

### Frontend

The frontend code lives in the `frontend` directory.

### Backend

The backend code lives in the `backend` directory. Apart from the dashboard
backend itself, it also contains a flask application that functions as the
identity provider, login, consent and logout endpoints for the OpenID Connect
(OIDC) process.

The application relies on the following components:

 - **Hydra**: Hydra is an open source OIDC server.
   It means applications can connect to Hydra to start a session with a user.
   Hydra provides the application with the username
   and other roles/claims for the application.
   Hydra is developed by Ory and has security as one of their top priorities.

 - **Kratos**: This is Identity Manager
   and contains all the user profiles and secrets (passwords).
   Kratos is designed to work mostly between UI (browser) and kratos directly,
   over a public API endpoint.
   Authentication, form-validation, etc. are all handled by Kratos.
   Kratos only provides an API and not UI itself.
   Kratos provides an admin API as well,
   which is only used from the server-side flask app to create/delete users.

 - **MariaDB**: The login application, as well as Hydra and Kratos, need to store data.
   This is done in a MariaDB database server.
   There is one instance with three databases.
   As all databases are very small we do not foresee resource limitation problems.

If Hydra hits a new session/user, it has to know if this user has access.
To do so, the user has to login through a login application.
This application is developed by the Stackspin team (Greenhost)
and is part of this repository.
It is a Python Flask application
The application follows flows defined in Kratos,
and as such a lot of the interaction is done in the web-browser,
rather then server-side.
As a result,
the login application has a UI component which relies heavily on JavaScript.
As this is a relatively small application,
it is based on traditional Bootstrap + JQuery.

## Development environment

After this process is finished, the following will run in local docker containers:

- the dashboard frontend
- the dashboard backend

The following will be available through proxies running in local docker containers and port-forwards:

- Hydra admin API
- Kratos admin API and public API
- The MariaDB database

These need to be available locally, because Kratos wants to run on the same
domain as the front-end that serves the login interface.

### Setup

Please read through all subsections to set up your environment before
attempting to run the dashboard locally.

#### 1. Stackspin cluster

To develop the Dashboard, you need a Stackspin cluster that is set up as a
development environment. Follow the instructions [in the
dashboard-dev-overrides
repository](https://open.greenhost.net/stackspin/dashboard-dev-overrides#dashboard-dev-overrides)
in order to set up a development-capable cluster. The Dashboard, as well as
Kratos and Hydra, will be configured to point their endpoints to
`http://stackspin_proxy:8081` in that cluster. As a result, you can run
components using the `docker-compose.yml` file in this repository, and still log
into Stackspin applications that run on the cluster.

#### 2. Environment for frontend

The frontend needs to know where the backend API and hydra can be reached. To
configure it, create a `local.env` file in the `frontend` directory:

    cp local.env.example local.env

and adjust the `REACT_APP_HYDRA_PUBLIC_URL` to the SSO URL of your cluster.

#### 3. Setup hosts file

The application will run on `http://stackspin_proxy`. Add the following line to
`/etc/hosts` to be able to access that from your browser:

```
127.0.0.1	stackspin_proxy
```

#### 4. Kubernetes access

The script needs you to have access to the Kubernetes cluster that runs
Stackspin. Point the `KUBECONFIG` environment variable to a kubectl config. Attention points:

* The kubeconfig will be mounted inside docker containers, so also make sure
  your Docker user can read it.
* The bind-mount done by docker might not work if the file pointed to is
  part of a filesystem such as sshfs. In that case, copy the file to a local
  drive first.

### Build and run

After you've finished all setup steps, you can run everything using

    ./run_app.sh

This sets a few environment variables based on what is in your cluster
secrets, and run `docker compose up` to build and run all necessary components,
including a reverse proxy and the backend flask application.