Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Support authentication and server-side user state #19

Closed
JeanMertz opened this issue Jun 15, 2019 · 5 comments
Closed

Support authentication and server-side user state #19

JeanMertz opened this issue Jun 15, 2019 · 5 comments
Labels
help wanted Extra attention is needed
Milestone

Comments

@JeanMertz
Copy link
Contributor

JeanMertz commented Jun 15, 2019

There are quite a few features (#9, #10, #11) that require some kind of state. In those feature descriptions, its mentioned to use client-side storage for the time being. This feature request is to track storing that information server-side and adding authentication support.

The goal right now is to keep it as simple as possible, while also providing enough flexibility for the current and near-term needs.

If you have any thoughts on this, or a better proposal, please speak up!

Here's the gist of it:

Automaat Server

  • Add a users table to the database, containing the following columns:
    • api_token – a personal token used to authenticate
    • preferences – a JSON-based column to store preferences
  • Add a CLI argument (e.g. --enable-authentication) to require API requests to contain a header with a user token.
  • Add a new GraphQL query to get the preferences of a user.
  • Add a new GraphQL mutation to allow resetting the API token, and also changing the stored preferences.

Automaat Web Client

  • When receiving a 401 response, show a full-screen dialogue asking the visitor to provide a valid user token (which they would get by asking a server admin to provide them one).
  • Store this token in a secure cookie for future use.
  • Add this token to all requests.
  • On startup, fetch user preferences from server using the server API

Notably missing from this proposal is creating user accounts. This will have to be done manually by server admins by adding a record to the database using a raw SQL insert statement. This keeps things simple, and allows us in the future to add an optional --allow-user-registration server flag to start exposing this functionality (if there is ever a need).


This implementation is not the meant for public access security. Given that Automaat is a powerful tool if exposed in your organisations infrastructure, I think we should explicitly mention that this tool is meant to run inside your internal network (or exposed over a VPN), the authentication added here is merely meant to:

  • Allow a specific set of people within your organisation to access its functionality.
  • Persist user preferences across clients/devices.
  • Provide future-proofing for when we add role-based access models to further segregate who gets to do what.
@JeanMertz
Copy link
Contributor Author

JeanMertz commented Jul 6, 2019

Another thing we can/should do once this lands:

Add weak references between jobs and users, so that you can view a history of the tasks you ran in the past, and re-view their output.

If we're doing this, we might later add some kind of way to "archive" jobs, so that they are no longer visible in the history, and perhaps automate this for older jobs, for security/privacy related purposes.

@JeanMertz
Copy link
Contributor Author

An excellent point by @jewilmeer:

The reference between jobs and users could not only serve as a way to view your job history, but also (more importantly) as an auditing trail to see who ran what task.

JeanMertz added a commit that referenced this issue Jul 21, 2019
With this change, the GraphQL endpoint is put behind an authentication
middleware. You are required to supply the `authorization` header with
the correct authentication token.

Tokens are stored as plain-text UUIDv4 in the database (for now), as
this authentication mechanism is not meant to secure the server from the
outside world, but rather to limit internal company-wide access.

In the future, the new `sessions` table will also be used to store
session-related configuration properties.

To facilitate this change, a new `RequestState` object is introduced
that is created for each incoming request. It contains a database
connection handle to perform the necessary queries, and the `Session`
object that will contain the preferences of the current active session
in the future.

There is also a new `createSession` endpoint, that will generate a new
session key that can be distributed within your organisation. Again, in
the future this will be extended to update session preferences.

There is no default session, so you'll have to create your first session
manually using a query such as `INSERT INTO sessions DEFAULT VALUES;`
(the table is configured to auto-generate UUIDv4 values for tokens).

Client-side support has yet to be implemented.

This is part of an ongoing effort described in
#19.
@JeanMertz
Copy link
Contributor Author

JeanMertz commented Jul 21, 2019

Initial server-side support has been implemented in 411e8e2. This does not (yet) cover the full spectrum of described features in this issue, and client-side support is still pending.

What's implemented in this commit:

  • put GraphQL API behind an authentication layer
  • table to store session-related details (only session token for now)
  • mutation endpoint to generate new session keys
  • mechanism to pass along session-details during request handling

JeanMertz added a commit that referenced this issue Jul 22, 2019
With this change, the web client now supports authentication as
implemented by the server in 411e8e2.

The GraphqlService now redirects the client to the newly added `Login`
page if the server indicates authentication is required. On this page,
a session token can be provided. Once provided and verified, the page
redirects to the home page of Automaat.

The session token is stored in a secure cookie. Visiting the login page
removes the cookie, acting as both a login and logout page.

It's still a bit rough around the edges, and could use another refactor
or two, but the concept works fine as is.

This is another step towards solving
#19.

Now that there is a way to fetch and store session data, the path is
clear to introduce persistent state to be able to store favorite tasks,
and implement other functionality that requires state to be stored.
@JeanMertz
Copy link
Contributor Author

JeanMertz commented Jul 22, 2019

Another step towards solving this issue has been implemented in 5552179.

With this change, the client<>server authentication loop is implemented. The next step is to use the new fundamentals to start storing persistent session state on the server.

Here's a screenshot of the new login page:

Screenshot 2019-07-22 at 20 15 19

JeanMertz added a commit that referenced this issue Jul 22, 2019
With this change, the web client now supports authentication as
implemented by the server in 411e8e2.

The GraphqlService now redirects the client to the newly added `Login`
page if the server indicates authentication is required. On this page,
a session token can be provided. Once provided and verified, the page
redirects to the home page of Automaat.

The session token is stored in a secure cookie. Visiting the login page
removes the cookie, acting as both a login and logout page.

It's still a bit rough around the edges, and could use another refactor
or two, but the concept works fine as is.

This is another step towards solving
#19.

Now that there is a way to fetch and store session data, the path is
clear to introduce persistent state to be able to store favorite tasks,
and implement other functionality that requires state to be stored.
@JeanMertz
Copy link
Contributor Author

JeanMertz commented Jul 23, 2019

This has been implemented in bf9ffe4.

Kapture 2019-07-24 at 0 06 13

Storing more/other server-side state will be tackled in the relevant issues, such as #9 and #10.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant