Create suite for testing the docker image.
Running this suite is the first advice given by the bootstrap script to help the user move forward. This commit also updates the documentation to reflect changes introduced by the Go rewrite.pull/429/head
parent
c6e6551ebc
commit
b9fea361c9
|
@ -211,6 +211,7 @@ func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
bootstrapPrintln("Building development Docker images...")
|
bootstrapPrintln("Building development Docker images...")
|
||||||
buildDockerImages()
|
buildDockerImages()
|
||||||
|
DockerBuildOfficialImage()
|
||||||
|
|
||||||
bootstrapPrintln("Installing Kubernetes dependencies for testing in /tmp... (no junk installed on host)")
|
bootstrapPrintln("Installing Kubernetes dependencies for testing in /tmp... (no junk installed on host)")
|
||||||
installKubernetesDependencies()
|
installKubernetesDependencies()
|
||||||
|
@ -220,6 +221,6 @@ func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
||||||
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
||||||
prepareHostsFile()
|
prepareHostsFile()
|
||||||
|
|
||||||
bootstrapPrintln("Run 'authelia-scripts suites start basic' to start Authelia and visit https://home.example.com:8080.")
|
bootstrapPrintln("Run 'authelia-scripts suites start docker-image' to start Authelia and visit https://home.example.com:8080.")
|
||||||
bootstrapPrintln("More details at https://github.com/clems4ever/authelia/blob/master/docs/getting-started.md")
|
bootstrapPrintln("More details at https://github.com/clems4ever/authelia/blob/master/docs/getting-started.md")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,29 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func DockerBuildOfficialImage() error {
|
||||||
|
docker := &Docker{}
|
||||||
|
return docker.Build(IntermediateDockerImageName, ".")
|
||||||
|
}
|
||||||
|
|
||||||
// DockerBuildCmd Command for building docker image of Authelia.
|
// DockerBuildCmd Command for building docker image of Authelia.
|
||||||
var DockerBuildCmd = &cobra.Command{
|
var DockerBuildCmd = &cobra.Command{
|
||||||
Use: "build",
|
Use: "build",
|
||||||
Short: "Build the docker image of Authelia",
|
Short: "Build the docker image of Authelia",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
docker := &Docker{}
|
err := DockerBuildOfficialImage()
|
||||||
err := docker.Build(IntermediateDockerImageName, ".")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
docker := &Docker{}
|
||||||
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,8 +16,8 @@ For instance, you can build Authelia with:
|
||||||
|
|
||||||
authelia-scripts build
|
authelia-scripts build
|
||||||
|
|
||||||
Or start the *basic* suite with:
|
Or start the *docker-image* suite with:
|
||||||
|
|
||||||
authelia-scripts suites start basic
|
authelia-scripts suites start docker-image
|
||||||
|
|
||||||
You will find more information in the scripts usage helpers.
|
You will find more information in the scripts usage helpers.
|
|
@ -1,23 +1,24 @@
|
||||||
# Build and dev
|
# Build and dev
|
||||||
|
|
||||||
**Authelia** is written in Typescript and built with [Authelia scripts](./authelia-scripts.md).
|
**Authelia** is written in Go and comes with a dedicated CLI called [authelia-scripts](./authelia-scripts.md)
|
||||||
|
which is provided after running `source bootstrap.sh`. This CLI provides many useful tools to help you during
|
||||||
|
development.
|
||||||
|
|
||||||
In order to build and contribute to **Authelia**, you need to make sure Node with version >= 8 and < 10
|
In order to build and contribute to **Authelia**, you need to make sure Node with version >= 8 and < 12,
|
||||||
and NPM is installed on your machine.
|
Go v1.13 and Docker is installed on your machine.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
**Authelia** is made of two parts: the frontend and the backend.
|
**Authelia** is made of two parts: the frontend and the backend.
|
||||||
|
|
||||||
The frontend is a [React](https://reactjs.org/) application written in Typescript and
|
The frontend is a [React](https://reactjs.org/) application written in Typescript and
|
||||||
the backend is an express application also written in Typescript.
|
the backend is Go application.
|
||||||
|
|
||||||
|
|
||||||
The following command builds **Authelia** under dist/:
|
The following command builds **Authelia** under dist/:
|
||||||
|
|
||||||
authelia-scripts build
|
authelia-scripts build
|
||||||
|
|
||||||
And then you can also build the Docker image with:
|
Or you can also build the Alpine-based official Docker image with:
|
||||||
|
|
||||||
authelia-scripts docker build
|
authelia-scripts docker build
|
||||||
|
|
||||||
|
@ -25,8 +26,8 @@ And then you can also build the Docker image with:
|
||||||
|
|
||||||
In order to ease development, Authelia uses the concept of [suites]. This is
|
In order to ease development, Authelia uses the concept of [suites]. This is
|
||||||
a kind of virutal environment for **Authelia**, it allows you to run **Authelia** in a complete
|
a kind of virutal environment for **Authelia**, it allows you to run **Authelia** in a complete
|
||||||
environment, develop and test your patches. A hot-reload feature has been implemented so that
|
ecosystem, develop and test your patches. A hot-reload feature has been implemented so that
|
||||||
you can test your changes in realtime.
|
you can test your changes right after the file has been saved.
|
||||||
|
|
||||||
The next command will start the suite called [basic](../test/suites/basic/README.md):
|
The next command will start the suite called [basic](../test/suites/basic/README.md):
|
||||||
|
|
||||||
|
@ -36,13 +37,13 @@ Then, edit the code and observe how **Authelia** is automatically updated.
|
||||||
|
|
||||||
### Unit tests
|
### Unit tests
|
||||||
|
|
||||||
To run the unit tests written in Mocha, run:
|
To run the unit tests written, run:
|
||||||
|
|
||||||
authelia-scripts unittest
|
authelia-scripts unittest
|
||||||
|
|
||||||
### Integration tests
|
### Integration tests
|
||||||
|
|
||||||
Integration tests also run with Mocha and are based on Selenium. They generally
|
Integration tests run with Mocha and are based on Selenium. They generally
|
||||||
require a complete environment made of several components like redis, mongo and a LDAP
|
require a complete environment made of several components like redis, mongo and a LDAP
|
||||||
to run. That's why [suites] have been created. At this point, the *basic* suite should
|
to run. That's why [suites] have been created. At this point, the *basic* suite should
|
||||||
already be running and you can run the tests related to this suite with the following
|
already be running and you can run the tests related to this suite with the following
|
||||||
|
@ -50,5 +51,13 @@ command:
|
||||||
|
|
||||||
authelia-scripts suites test
|
authelia-scripts suites test
|
||||||
|
|
||||||
|
You don't need to start the suite before testing it. Given your environment is not running
|
||||||
|
any suite, just use the following command to test the basic suite.
|
||||||
|
|
||||||
|
authelia-scripts suites test basic
|
||||||
|
|
||||||
|
The suite will be spawned, tests will be run and then the suite will be teared down
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
|
||||||
[suites]: ./suites.md
|
[suites]: ./suites.md
|
||||||
|
|
|
@ -18,17 +18,17 @@ non resilient to failures.*
|
||||||
|
|
||||||
In some cases, like protecting personal websites, it can be fine to use
|
In some cases, like protecting personal websites, it can be fine to use
|
||||||
**Authelia** in a non highly-available setup. We can
|
**Authelia** in a non highly-available setup. We can
|
||||||
achieve that in order to reduce the number of components to only two: Authelia
|
achieve that in order to reduce the number of components to only two: a
|
||||||
and nginx.
|
reverse proxy such as nginx or Traefik and Authelia as a companion of the
|
||||||
|
proxy.
|
||||||
|
|
||||||
As for a regular deployment in production, you need to install **Authelia**
|
As for a regular deployment in production, you need to install **Authelia**
|
||||||
either by pulling the Docker image or installing the npm package and run
|
either by pulling the Docker image or building distributable version.
|
||||||
it with a configuration file passed as argument.
|
|
||||||
|
|
||||||
## Deploy with npm
|
## Build and deploy the distributable version
|
||||||
|
|
||||||
npm install -g authelia
|
authelia-scripts build
|
||||||
authelia /path/to/your/config.yml
|
PUBLIC_DIR=./dist/public_html ./dist/authelia -config /path/to/your/config.yml
|
||||||
|
|
||||||
## Deploy with Docker
|
## Deploy with Docker
|
||||||
|
|
||||||
|
@ -40,21 +40,27 @@ it with a configuration file passed as argument.
|
||||||
You also need to install nginx and take [example/compose/nginx/minimal/nginx.conf](./example/compose/nginx/minimal/nginx.conf)
|
You also need to install nginx and take [example/compose/nginx/minimal/nginx.conf](./example/compose/nginx/minimal/nginx.conf)
|
||||||
as an example for your configuration.
|
as an example for your configuration.
|
||||||
|
|
||||||
|
## Deploy Traefik
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
## Discard components
|
## Discard components
|
||||||
|
|
||||||
### Discard MongoDB
|
### Discard MongoDB
|
||||||
|
|
||||||
There is an option in the configuration file to discard MongoDB and use
|
There is an option in the configuration file to discard MongoDB and use
|
||||||
your local filesystem to store the database data. This option will therefore
|
your local filesystem to store data in a sqlite3 database. This option will
|
||||||
prevent you from running multiple instances of **Authelia** in parallel.
|
therefore prevent you from running multiple instances of **Authelia** in
|
||||||
Consequently, this option is not meant to be used in production.
|
parallel.
|
||||||
|
Consequently, this option is not meant to be used in production or at least
|
||||||
|
not one that should scale out.
|
||||||
|
|
||||||
Here is the configuration block you should use:
|
Here is the configuration block you should use:
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
# The directory where the DB files will be saved
|
# The directory where the sqlite3 file will be saved
|
||||||
local:
|
local:
|
||||||
path: /var/lib/authelia/store
|
path: /var/lib/authelia/db.sqlite3
|
||||||
|
|
||||||
### Discard Redis
|
### Discard Redis
|
||||||
|
|
||||||
|
@ -62,8 +68,8 @@ There is an option in the configuration file to discard Redis and use the
|
||||||
memory of the server to store the KV data. This option will therefore
|
memory of the server to store the KV data. This option will therefore
|
||||||
prevent you from running multiple instances of **Authelia** in parallel and
|
prevent you from running multiple instances of **Authelia** in parallel and
|
||||||
will make you lose user sessions if the application restarts. This
|
will make you lose user sessions if the application restarts. This
|
||||||
concretely means that all your users will need to authenticate again in
|
concretely means that all your users will need to authenticate again after
|
||||||
that case. Hence, this option is not meant to be used in production.
|
a restart of Authelia. Hence, this option is not meant to be used in production.
|
||||||
|
|
||||||
To use memory instead of a Redis backend, just comment out the Redis
|
To use memory instead of a Redis backend, just comment out the Redis
|
||||||
connection details in the following block:
|
connection details in the following block:
|
||||||
|
@ -98,19 +104,22 @@ The content of this file is as follows:
|
||||||
- admins
|
- admins
|
||||||
- dev
|
- dev
|
||||||
|
|
||||||
The password is hashed and salted as it is in LDAP servers with salted SHA-512. Here is a one-liner to generate such hashed password:
|
The password is hashed and salted as it is in LDAP servers with salted SHA-512
|
||||||
|
(more hash algorithms such as Argon2 will be provided in the future).
|
||||||
|
Here is a one-liner to generate such hashed password:
|
||||||
|
|
||||||
$ npm run hash-password mypassword
|
$ authelia-scripts hash-password mypassword
|
||||||
$6$rounds=50000$BpLnfgDsc2WD8F2q$PumMwig8O0uIe9SgneL8Cm1FvUniOzpqBrH.uQE3aZR4K1dHsQldu5gEjJZsXcO./v3itfz6CXTDTJgeh5e8t.
|
$6$rounds=50000$BpLnfgDsc2WD8F2q$PumMwig8O0uIe9SgneL8Cm1FvUniOzpqBrH.uQE3aZR4K1dHsQldu5gEjJZsXcO./v3itfz6CXTDTJgeh5e8t.
|
||||||
|
|
||||||
Copy this newly hashed password into your `users_database.yml` file, prefixed with `{CRYPT}` as shown in the example file above.
|
Copy this newly hashed password into your `users_database.yml` file, prefixed with
|
||||||
|
`{CRYPT}` as shown in the example file above.
|
||||||
|
|
||||||
Once the file is created, edit the configuration file with the following
|
Once the file is created, edit the configuration file with the following
|
||||||
block (as used in [config.yml](../test/suites/basic/config.yml)):
|
block (as used in [config.yml](../test/suites/basic/config.yml)):
|
||||||
|
|
||||||
authentication_backend:
|
authentication_backend:
|
||||||
file:
|
file:
|
||||||
path: /etc/authelia/users_database.yml
|
path: /path/to/the/users_database.yml
|
||||||
|
|
||||||
instead of (used in [config.template.yml](../config.template.yml)):
|
instead of (used in [config.template.yml](../config.template.yml)):
|
||||||
|
|
||||||
|
@ -152,6 +161,6 @@ a production environment. That being said, in some cases it is just fine and
|
||||||
writing an Ansible playbook to automate all this process is ok.
|
writing an Ansible playbook to automate all this process is ok.
|
||||||
We would really be more than happy to review such a PR.
|
We would really be more than happy to review such a PR.
|
||||||
In the meantime, you can check the *basic* [suite](./suites.md) to see all this
|
In the meantime, you can check the *basic* [suite](./suites.md) to see all this
|
||||||
in real example.
|
in a real example.
|
||||||
|
|
||||||
[Getting Started]: ./getting-started.md
|
[Getting Started]: ./getting-started.md
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# Deployment for Production
|
# Deployment for Production
|
||||||
|
|
||||||
**Authelia** can be deployed on bare metal or on Kubernetes with two
|
**Authelia** can be deployed on bare metal or on Kubernetes with two
|
||||||
different kind of artifacts: an npm package or a Docker image.
|
different kind of artifacts: the distributable version (binary and public_html)
|
||||||
|
or a Docker image.
|
||||||
|
|
||||||
**NOTE:** If not done already, we highly recommend you first follow the
|
**NOTE:** If not done already, we highly recommend you first follow the
|
||||||
[Getting Started] documentation.
|
[Getting Started] documentation.
|
||||||
|
@ -11,21 +12,28 @@ different kind of artifacts: an npm package or a Docker image.
|
||||||
**Authelia** has been designed to be a proxy companion handling the
|
**Authelia** has been designed to be a proxy companion handling the
|
||||||
authentication and authorization requests for your entire infrastructure.
|
authentication and authorization requests for your entire infrastructure.
|
||||||
|
|
||||||
As **Authelia** will be key in your architecture, it requires several
|
As **Authelia** will be key to your architecture, it requires several
|
||||||
components to make it highly-available. Deploying it in production means having an LDAP server for storing the information about the users, a Redis cache to store the user sessions in a distributed manner, a
|
components to make it highly-available. Deploying it in production means having
|
||||||
MongoDB to persist user configurations and one or more nginx reverse proxies configured to be used with Authelia. With such a setup **Authelia** can easily be scaled to multiple instances to evenly handle the traffic.
|
an LDAP server for storing the information about the users, a Redis cache to
|
||||||
|
store the user sessions in a distributed manner, a MongoDB to persist user
|
||||||
|
configurations and one or more nginx reverse proxies configured to be used with
|
||||||
|
Authelia. With such a setup **Authelia** can easily be scaled to multiple instances
|
||||||
|
to evenly handle the traffic.
|
||||||
|
|
||||||
**NOTE:** If you don't have all those components, don't worry, there is a way to deploy **Authelia** with only nginx. This is described in [Deployment for Devs].
|
**NOTE:** If you don't have all those components, don't worry, there is a way to
|
||||||
|
deploy **Authelia** with only nginx. This is described in [Deployment for Devs].
|
||||||
|
|
||||||
Here are the available steps to deploy **Authelia** given
|
Here are the available steps to deploy **Authelia** given
|
||||||
the configuration file is **/path/to/your/config.yml**. Note that you can
|
the configuration file is **/path/to/your/config.yml**. Note that you can
|
||||||
create your own configuration file from [config.template.yml] located at
|
create your own configuration file from [config.template.yml] located at
|
||||||
the root of the repo.
|
the root of the repo.
|
||||||
|
|
||||||
### Deploy With NPM
|
### Deploy with the distributable version
|
||||||
|
|
||||||
npm install -g authelia
|
# Build it if not done already
|
||||||
authelia /path/to/your/config.yml
|
authelia-scripts build
|
||||||
|
|
||||||
|
PUBLIC_DIR=./dist/public_html authelia -config /path/to/your/config.yml
|
||||||
|
|
||||||
### Deploy With Docker
|
### Deploy With Docker
|
||||||
|
|
||||||
|
@ -49,7 +57,7 @@ for more information.
|
||||||
Ansible would be a very good candidate to automate the installation of such
|
Ansible would be a very good candidate to automate the installation of such
|
||||||
an infrastructure on bare metal. We would be more than happy to review any PR on that matter.
|
an infrastructure on bare metal. We would be more than happy to review any PR on that matter.
|
||||||
|
|
||||||
Regarding Kubernetes, the right way to go would be to write a helm recipe.
|
Regarding Kubernetes, the right way to go would be to write a Helm recipe.
|
||||||
Again, we would be glad to review any PR implementing this.
|
Again, we would be glad to review any PR implementing this.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
# Getting Started
|
# Getting Started
|
||||||
|
|
||||||
**Authelia** can be tested in a matter of seconds with docker-compose based
|
**Authelia** can be tested in a matter of seconds with Docker and docker-compose.
|
||||||
on the latest image available on [Dockerhub].
|
|
||||||
|
|
||||||
In order to deploy the latest release locally, run the following command and
|
In order to deploy the current version of Authelia locally, run the following
|
||||||
follow the instructions of bootstrap.sh:
|
command and follow the instructions of bootstrap.sh:
|
||||||
|
|
||||||
source bootstrap.sh
|
source bootstrap.sh
|
||||||
|
|
||||||
Then, start the *dockerhub* [suite].
|
Then, start the *docker-image* [suite].
|
||||||
|
|
||||||
authelia-scripts suites start dockerhub
|
authelia-scripts suites start docker-image
|
||||||
|
|
||||||
A [suite] is kind of a virtual environment for running Authelia.
|
A [suite] is kind of a virtual environment for running Authelia in a complete ecosystem.
|
||||||
If you want more details please read the related [documentation](./suites.md).
|
If you want more details please read the related [documentation](./suites.md).
|
||||||
|
|
||||||
## Test it!
|
## Test it!
|
||||||
|
@ -43,7 +42,7 @@ Since we're running a test environment, we provide a fake webmail called
|
||||||
*MailCatcher* from which you can checkout the email and confirm
|
*MailCatcher* from which you can checkout the email and confirm
|
||||||
your identity.
|
your identity.
|
||||||
The webmail is accessible from
|
The webmail is accessible from
|
||||||
[http://mail.example.com:8080](http://mail.example.com:8085).
|
[http://mail.example.com:8080](http://mail.example.com:8080).
|
||||||
|
|
||||||
Enjoy!
|
Enjoy!
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ post nginx has written on [HSTS].
|
||||||
|
|
||||||
## Content-Security-Policy
|
## Content-Security-Policy
|
||||||
|
|
||||||
Authelia's portal is protected against XSS using the content
|
Authelia's portal is protected against some XSS using the content
|
||||||
security policy mechanism that is documented
|
security policy mechanism that is documented
|
||||||
[here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). This protection
|
[here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). This protection
|
||||||
will reject untrusted payloads threatening your users during the authentication
|
will reject untrusted payloads threatening your users during the authentication
|
||||||
|
@ -51,10 +51,6 @@ add_header X-Frame-Options "SAMEORIGIN";
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
```
|
```
|
||||||
|
|
||||||
## Helmet
|
|
||||||
|
|
||||||
To improve even more the security, [Helmet] has been added to **Authelia**.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
If you find possible vulnerabilities or threats, do not hesitate to contribute
|
If you find possible vulnerabilities or threats, do not hesitate to contribute
|
||||||
|
@ -62,4 +58,3 @@ either by writing a test case demonstrating the possible attack and if
|
||||||
possible some solutions to prevent it or submit a PR.
|
possible some solutions to prevent it or submit a PR.
|
||||||
|
|
||||||
[HSTS]: https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
|
[HSTS]: https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
|
||||||
[Helmet]: https://helmetjs.github.io/
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ suite which is a kind of virtual environment for Authelia, it allows to create a
|
||||||
components such as nginx, redis or mongo in which Authelia can run and be tested.
|
components such as nginx, redis or mongo in which Authelia can run and be tested.
|
||||||
|
|
||||||
This abstraction allows to prepare an environment for manual testing during development and also to
|
This abstraction allows to prepare an environment for manual testing during development and also to
|
||||||
craft and run integration tests.
|
craft and run integration tests efficiently.
|
||||||
|
|
||||||
## Start a suite.
|
## Start a suite.
|
||||||
|
|
||||||
|
@ -28,16 +28,19 @@ and this will run the tests related to the running suite.
|
||||||
|
|
||||||
### Run tests of non-running suite
|
### Run tests of non-running suite
|
||||||
|
|
||||||
However, if no suite is running and you still want to test a particular suite like *complete*.
|
However, if no suite is running and you still want to test a particular suite like *high-availability*.
|
||||||
You can do so with the next command:
|
You can do so with the next command:
|
||||||
|
|
||||||
authelia-scripts suites test complete
|
authelia-scripts suites test high-availability
|
||||||
|
|
||||||
This command will run the tests for the *complete* suite using the built version of Authelia that
|
This command will run the tests for the *high-availability* suite. Beware that running tests of a
|
||||||
should be located in *dist*.
|
non-running suite implies the tests run against the distributable version of Authelia instead of
|
||||||
|
the current development version. If you made some patches, you must build the distributable version
|
||||||
|
before running the test command:
|
||||||
|
|
||||||
WARNING: Authelia must be built with `authelia-scripts build` and possibly
|
# Build authelia before running the tests against the suite.
|
||||||
`authelia-scripts docker build` before running this command.
|
authelia-scripts build
|
||||||
|
authelia-scripts docker build
|
||||||
|
|
||||||
### Run all tests of all suites
|
### Run all tests of all suites
|
||||||
|
|
||||||
|
@ -45,10 +48,17 @@ Running all tests is easy. Make sure that no suite is already running and run:
|
||||||
|
|
||||||
authelia-scripts suites test
|
authelia-scripts suites test
|
||||||
|
|
||||||
|
Beware that the distributable version of Authelia is tested in that case. Don't
|
||||||
|
forget to build Authelia including your patches before running the command.
|
||||||
|
|
||||||
|
|
||||||
|
# Build authelia before running the tests against the suite.
|
||||||
|
authelia-scripts build
|
||||||
|
authelia-scripts docker build
|
||||||
|
|
||||||
### Run tests in headless mode
|
### Run tests in headless mode
|
||||||
|
|
||||||
In order to run the tests without seeing the windows creating and vanishing, one
|
In order to run the tests in headless mode, use the following command:
|
||||||
can run the tests in headless mode with:
|
|
||||||
|
|
||||||
authelia-scripts suites test --headless
|
authelia-scripts suites test --headless
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
version: '2'
|
version: '2'
|
||||||
services:
|
services:
|
||||||
authelia:
|
authelia:
|
||||||
image: clems4ever/authelia:latest
|
image: authelia:dist
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- ./test/suites/dockerhub/config.yml:/etc/authelia/config.yml:ro
|
- ./test/suites/docker-image/config.yml:/etc/authelia/config.yml:ro
|
||||||
environment:
|
environment:
|
||||||
- NODE_TLS_REJECT_UNAUTHORIZED=0
|
- NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||||
depends_on:
|
depends_on:
|
|
@ -77,56 +77,54 @@
|
||||||
<p></p>These rules are extracted from the configuration file
|
<p></p>These rules are extracted from the configuration file
|
||||||
<a href="https://github.com/clems4ever/authelia/blob/master/config.template.yml">config.template.yml</a>.</p>
|
<a href="https://github.com/clems4ever/authelia/blob/master/config.template.yml">config.template.yml</a>.</p>
|
||||||
<pre id="rules" style="border: 1px grey solid; padding: 20px; display: inline-block;">
|
<pre id="rules" style="border: 1px grey solid; padding: 20px; display: inline-block;">
|
||||||
default_policy: deny
|
default_policy: deny
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
# Rules applied to everyone
|
# Rules applied to everyone
|
||||||
- domain: public.example.com
|
- domain: public.example.com
|
||||||
policy: bypass
|
policy: two_factor
|
||||||
- domain: secure.example.com
|
- domain: singlefactor.example.com
|
||||||
policy: two_factor
|
policy: one_factor
|
||||||
- domain: singlefactor.example.com
|
|
||||||
policy: one_factor
|
# Rules applied to 'admin' group
|
||||||
|
- domain: 'mx2.mail.example.com'
|
||||||
# Rules applied to 'admin' group
|
subject: 'group:admin'
|
||||||
- domain: 'mx2.mail.example.com'
|
policy: deny
|
||||||
subject: 'group:admin'
|
- domain: '*.example.com'
|
||||||
policy: deny
|
subject: 'group:admin'
|
||||||
- domain: '*.example.com'
|
policy: two_factor
|
||||||
subject: 'group:admin'
|
|
||||||
policy: two_factor
|
# Rules applied to 'dev' group
|
||||||
|
- domain: dev.example.com
|
||||||
# Rules applied to 'dev' group
|
resources:
|
||||||
- domain: dev.example.com
|
- '^/groups/dev/.*$'
|
||||||
resources:
|
subject: 'group:dev'
|
||||||
- '^/groups/dev/.*$'
|
policy: two_factor
|
||||||
subject: 'group:dev'
|
|
||||||
policy: two_factor
|
# Rules applied to user 'john'
|
||||||
|
- domain: dev.example.com
|
||||||
# Rules applied to user 'john'
|
resources:
|
||||||
- domain: dev.example.com
|
- '^/users/john/.*$'
|
||||||
resources:
|
subject: 'user:john'
|
||||||
- '^/users/john/.*$'
|
policy: two_factor
|
||||||
subject: 'user:john'
|
|
||||||
policy: two_factor
|
|
||||||
|
# Rules applied to user 'harry'
|
||||||
|
- domain: dev.example.com
|
||||||
# Rules applied to user 'harry'
|
resources:
|
||||||
- domain: dev.example.com
|
- '^/users/harry/.*$'
|
||||||
resources:
|
subject: 'user:harry'
|
||||||
- '^/users/harry/.*$'
|
policy: two_factor
|
||||||
subject: 'user:harry'
|
|
||||||
policy: two_factor
|
# Rules applied to user 'bob'
|
||||||
|
- domain: '*.mail.example.com'
|
||||||
# Rules applied to user 'bob'
|
subject: 'user:bob'
|
||||||
- domain: '*.mail.example.com'
|
policy: two_factor
|
||||||
subject: 'user:bob'
|
- domain: 'dev.example.com'
|
||||||
policy: two_factor
|
resources:
|
||||||
- domain: 'dev.example.com'
|
- '^/users/bob/.*$'
|
||||||
resources:
|
subject: 'user:bob'
|
||||||
- '^/users/bob/.*$'
|
policy: two_factor
|
||||||
subject: 'user:bob'
|
|
||||||
policy: two_factor
|
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ import Fs = require("fs");
|
||||||
import Request = require("request-promise");
|
import Request = require("request-promise");
|
||||||
|
|
||||||
export async function GetLinkFromFile() {
|
export async function GetLinkFromFile() {
|
||||||
const data = await Bluebird.promisify(Fs.readFile)("/tmp/authelia/notification.txt")
|
const data = await Bluebird.promisify(Fs.readFile)(
|
||||||
|
"/tmp/authelia/notification.txt")
|
||||||
const regexp = new RegExp(/Link: (.+)/);
|
const regexp = new RegExp(/Link: (.+)/);
|
||||||
const match = regexp.exec(data.toLocaleString());
|
const match = regexp.exec(data.toLocaleString());
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
|
@ -19,12 +20,14 @@ export async function GetLinkFromEmail() {
|
||||||
json: true,
|
json: true,
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const messageId = data[data.length - 1].id;
|
const messageId = data[data.length - 1].id;
|
||||||
const data2 = await Request({
|
const data2 = await Request({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
uri: `https://mail.example.com:8080/messages/${messageId}.html`
|
uri: `https://mail.example.com:8080/messages/${messageId}.html`,
|
||||||
});
|
});
|
||||||
|
|
||||||
const regexp = new RegExp(/<a href="(.+)" class="button">.*<\/a>/);
|
const regexp = new RegExp(/<a href="(.+)" class="button">.*<\/a>/);
|
||||||
const match = regexp.exec(data2);
|
const match = regexp.exec(data2);
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
|
|
|
@ -8,7 +8,11 @@ export default function (timeout: number = 5000) {
|
||||||
describe('The user is redirected to target url upon successful authentication', function() {
|
describe('The user is redirected to target url upon successful authentication', function() {
|
||||||
before(async function() {
|
before(async function() {
|
||||||
this.driver = await StartDriver();
|
this.driver = await StartDriver();
|
||||||
await RegisterAndLoginTwoFactor(this.driver, 'john', "password", true, 'https://admin.example.com:8080/secret.html', timeout);
|
await RegisterAndLoginTwoFactor(
|
||||||
|
this.driver,
|
||||||
|
'john', "password", true,
|
||||||
|
'https://admin.example.com:8080/secret.html',
|
||||||
|
timeout);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(async function() {
|
after(async function() {
|
||||||
|
@ -17,7 +21,10 @@ export default function (timeout: number = 5000) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should redirect the user', async function() {
|
it('should redirect the user', async function() {
|
||||||
await VerifyUrlIs(this.driver, 'https://admin.example.com:8080/secret.html', timeout);
|
await VerifyUrlIs(
|
||||||
|
this.driver,
|
||||||
|
'https://admin.example.com:8080/secret.html',
|
||||||
|
timeout);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Dockerhub suite
|
||||||
|
|
||||||
|
This suite is made to quickly test that the Docker image of Authelia runs properly when spawned.
|
||||||
|
It can also be used for you to test Authelia without building it since the latest image will be
|
||||||
|
pulled from Dockerhub.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
This suite will spawn an highly-available setup with nginx, mongo, redis, OpenLDAP, etc...
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
Check if the image runs and does not crash unexpectedly and do a simple authentication with 2FA.
|
|
@ -0,0 +1,261 @@
|
||||||
|
###############################################################
|
||||||
|
# Authelia configuration #
|
||||||
|
###############################################################
|
||||||
|
|
||||||
|
# The port to listen on
|
||||||
|
port: 9091
|
||||||
|
|
||||||
|
# Log level
|
||||||
|
#
|
||||||
|
# Level of verbosity for logs
|
||||||
|
logs_level: debug
|
||||||
|
|
||||||
|
jwt_secret: unsecure_secret
|
||||||
|
|
||||||
|
# Default redirection URL
|
||||||
|
#
|
||||||
|
# If user tries to authenticate without any referer, Authelia
|
||||||
|
# does not know where to redirect the user to at the end of the
|
||||||
|
# authentication process.
|
||||||
|
# This parameter allows you to specify the default redirection
|
||||||
|
# URL Authelia will use in such a case.
|
||||||
|
#
|
||||||
|
# Note: this parameter is optional. If not provided, user won't
|
||||||
|
# be redirected upon successful authentication.
|
||||||
|
default_redirection_url: https://home.example.com:8080/
|
||||||
|
|
||||||
|
# TOTP Issuer Name
|
||||||
|
#
|
||||||
|
# This will be the issuer name displayed in Google Authenticator
|
||||||
|
# See: https://github.com/google/google-authenticator/wiki/Key-Uri-Format for more info on issuer names
|
||||||
|
totp:
|
||||||
|
issuer: authelia.com
|
||||||
|
|
||||||
|
# The authentication backend to use for verifying user passwords
|
||||||
|
# and retrieve information such as email address and groups
|
||||||
|
# users belong to.
|
||||||
|
#
|
||||||
|
# There are two supported backends: `ldap` and `file`.
|
||||||
|
authentication_backend:
|
||||||
|
# LDAP backend configuration.
|
||||||
|
#
|
||||||
|
# This backend allows Authelia to be scaled to more
|
||||||
|
# than one instance and therefore is recommended for
|
||||||
|
# production.
|
||||||
|
ldap:
|
||||||
|
# The url of the ldap server
|
||||||
|
url: ldap://openldap
|
||||||
|
|
||||||
|
# The base dn for every entries
|
||||||
|
base_dn: dc=example,dc=com
|
||||||
|
|
||||||
|
# An additional dn to define the scope to all users
|
||||||
|
additional_users_dn: ou=users
|
||||||
|
|
||||||
|
# The users filter used to find the user DN
|
||||||
|
# {0} is a matcher replaced by username.
|
||||||
|
# 'cn={0}' by default.
|
||||||
|
users_filter: (cn={0})
|
||||||
|
|
||||||
|
# An additional dn to define the scope of groups
|
||||||
|
additional_groups_dn: ou=groups
|
||||||
|
|
||||||
|
# The groups filter used for retrieving groups of a given user.
|
||||||
|
# {0} is a matcher replaced by username.
|
||||||
|
# {dn} is a matcher replaced by user DN.
|
||||||
|
# 'member={dn}' by default.
|
||||||
|
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||||
|
|
||||||
|
# The attribute holding the name of the group
|
||||||
|
group_name_attribute: cn
|
||||||
|
|
||||||
|
# The attribute holding the mail address of the user
|
||||||
|
mail_attribute: mail
|
||||||
|
|
||||||
|
# The username and password of the admin user.
|
||||||
|
user: cn=admin,dc=example,dc=com
|
||||||
|
password: password
|
||||||
|
|
||||||
|
# File backend configuration.
|
||||||
|
#
|
||||||
|
# With this backend, the users database is stored in a file
|
||||||
|
# which is updated when users reset their passwords.
|
||||||
|
# Therefore, this backend is meant to be used in a dev environment
|
||||||
|
# and not in production since it prevents Authelia to be scaled to
|
||||||
|
# more than one instance.
|
||||||
|
#
|
||||||
|
## file:
|
||||||
|
## path: ./users_database.yml
|
||||||
|
|
||||||
|
|
||||||
|
# Access Control
|
||||||
|
#
|
||||||
|
# Access control is a list of rules defining the authorizations applied for one
|
||||||
|
# resource to users or group of users.
|
||||||
|
#
|
||||||
|
# If 'access_control' is not defined, ACL rules are disabled and the `bypass`
|
||||||
|
# rule is applied, i.e., access is allowed to anyone. Otherwise restrictions follow
|
||||||
|
# the rules defined.
|
||||||
|
#
|
||||||
|
# Note: One can use the wildcard * to match any subdomain.
|
||||||
|
# It must stand at the beginning of the pattern. (example: *.mydomain.com)
|
||||||
|
#
|
||||||
|
# Note: You must put patterns containing wildcards between simple quotes for the YAML
|
||||||
|
# to be syntaxically correct.
|
||||||
|
#
|
||||||
|
# Definition: A `rule` is an object with the following keys: `domain`, `subject`,
|
||||||
|
# `policy` and `resources`.
|
||||||
|
#
|
||||||
|
# - `domain` defines which domain or set of domains the rule applies to.
|
||||||
|
#
|
||||||
|
# - `subject` defines the subject to apply authorizations to. This parameter is
|
||||||
|
# optional and matching any user if not provided. If provided, the parameter
|
||||||
|
# represents either a user or a group. It should be of the form 'user:<username>'
|
||||||
|
# or 'group:<groupname>'.
|
||||||
|
#
|
||||||
|
# - `policy` is the policy to apply to resources. It must be either `bypass`,
|
||||||
|
# `one_factor`, `two_factor` or `deny`.
|
||||||
|
#
|
||||||
|
# - `resources` is a list of regular expressions that matches a set of resources to
|
||||||
|
# apply the policy to. This parameter is optional and matches any resource if not
|
||||||
|
# provided.
|
||||||
|
#
|
||||||
|
# Note: the order of the rules is important. The first policy matching
|
||||||
|
# (domain, resource, subject) applies.
|
||||||
|
access_control:
|
||||||
|
# Default policy can either be `bypass`, `one_factor`, `two_factor` or `deny`.
|
||||||
|
# It is the policy applied to any resource if there is no policy to be applied
|
||||||
|
# to the user.
|
||||||
|
default_policy: deny
|
||||||
|
|
||||||
|
rules:
|
||||||
|
# Rules applied to everyone
|
||||||
|
- domain: public.example.com
|
||||||
|
policy: two_factor
|
||||||
|
- domain: singlefactor.example.com
|
||||||
|
policy: one_factor
|
||||||
|
|
||||||
|
# Rules applied to 'admin' group
|
||||||
|
- domain: 'mx2.mail.example.com'
|
||||||
|
subject: 'group:admin'
|
||||||
|
policy: deny
|
||||||
|
- domain: '*.example.com'
|
||||||
|
subject: 'group:admin'
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
# Rules applied to 'dev' group
|
||||||
|
- domain: dev.example.com
|
||||||
|
resources:
|
||||||
|
- '^/groups/dev/.*$'
|
||||||
|
subject: 'group:dev'
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
# Rules applied to user 'john'
|
||||||
|
- domain: dev.example.com
|
||||||
|
resources:
|
||||||
|
- '^/users/john/.*$'
|
||||||
|
subject: 'user:john'
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
|
||||||
|
# Rules applied to user 'harry'
|
||||||
|
- domain: dev.example.com
|
||||||
|
resources:
|
||||||
|
- '^/users/harry/.*$'
|
||||||
|
subject: 'user:harry'
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
# Rules applied to user 'bob'
|
||||||
|
- domain: '*.mail.example.com'
|
||||||
|
subject: 'user:bob'
|
||||||
|
policy: two_factor
|
||||||
|
- domain: 'dev.example.com'
|
||||||
|
resources:
|
||||||
|
- '^/users/bob/.*$'
|
||||||
|
subject: 'user:bob'
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
|
||||||
|
# Configuration of session cookies
|
||||||
|
#
|
||||||
|
# The session cookies identify the user once logged in.
|
||||||
|
session:
|
||||||
|
# The name of the session cookie. (default: authelia_session).
|
||||||
|
name: authelia_session
|
||||||
|
|
||||||
|
# The secret to encrypt the session cookie.
|
||||||
|
secret: unsecure_session_secret
|
||||||
|
|
||||||
|
# The time in ms before the cookie expires and session is reset.
|
||||||
|
expiration: 3600 # 1 hour
|
||||||
|
|
||||||
|
# The inactivity time in ms before the session is reset.
|
||||||
|
inactivity: 300 # 5 minutes
|
||||||
|
|
||||||
|
# The domain to protect.
|
||||||
|
# Note: the authenticator must also be in that domain. If empty, the cookie
|
||||||
|
# is restricted to the subdomain of the issuer.
|
||||||
|
domain: example.com
|
||||||
|
|
||||||
|
# The redis connection details
|
||||||
|
redis:
|
||||||
|
host: redis
|
||||||
|
port: 6379
|
||||||
|
password: authelia
|
||||||
|
|
||||||
|
# Configuration of the authentication regulation mechanism.
|
||||||
|
#
|
||||||
|
# This mechanism prevents attackers from brute forcing the first factor.
|
||||||
|
# It bans the user if too many attempts are done in a short period of
|
||||||
|
# time.
|
||||||
|
regulation:
|
||||||
|
# The number of failed login attempts before user is banned.
|
||||||
|
# Set it to 0 to disable regulation.
|
||||||
|
max_retries: 3
|
||||||
|
|
||||||
|
# The time range during which the user can attempt login before being banned.
|
||||||
|
# The user is banned if the authenticaction failed `max_retries` times in a `find_time` seconds window.
|
||||||
|
find_time: 15
|
||||||
|
|
||||||
|
# The length of time before a banned user can login again.
|
||||||
|
ban_time: 20
|
||||||
|
|
||||||
|
# Configuration of the storage backend used to store data and secrets.
|
||||||
|
#
|
||||||
|
# You must use only an available configuration: local, mongo
|
||||||
|
storage:
|
||||||
|
# The directory where the DB files will be saved
|
||||||
|
## local:
|
||||||
|
## path: /var/lib/authelia/store
|
||||||
|
|
||||||
|
# Settings to connect to mongo server
|
||||||
|
mongo:
|
||||||
|
url: mongodb://mongo
|
||||||
|
database: authelia
|
||||||
|
auth:
|
||||||
|
username: authelia
|
||||||
|
password: authelia
|
||||||
|
|
||||||
|
# Configuration of the notification system.
|
||||||
|
#
|
||||||
|
# Notifications are sent to users when they require a password reset, a u2f
|
||||||
|
# registration or a TOTP registration.
|
||||||
|
# Use only an available configuration: filesystem, gmail
|
||||||
|
notifier:
|
||||||
|
# For testing purpose, notifications can be sent in a file
|
||||||
|
## filesystem:
|
||||||
|
## filename: /tmp/authelia/notification.txt
|
||||||
|
|
||||||
|
# Use your email account to send the notifications. You can use an app password.
|
||||||
|
# List of valid services can be found here: https://nodemailer.com/smtp/well-known/
|
||||||
|
## email:
|
||||||
|
## username: user@example.com
|
||||||
|
## password: yourpassword
|
||||||
|
## sender: admin@example.com
|
||||||
|
## service: gmail
|
||||||
|
|
||||||
|
# Use a SMTP server for sending notifications
|
||||||
|
smtp:
|
||||||
|
host: smtp
|
||||||
|
port: 1025
|
||||||
|
sender: admin@example.com
|
|
@ -0,0 +1,37 @@
|
||||||
|
import DockerEnvironment from "../../helpers/context/DockerEnvironment";
|
||||||
|
import { exec } from "../../helpers/utils/exec";
|
||||||
|
|
||||||
|
const composeFiles = [
|
||||||
|
'docker-compose.yml',
|
||||||
|
'example/compose/authelia/docker-compose.yml',
|
||||||
|
'example/compose/mongo/docker-compose.yml',
|
||||||
|
'example/compose/redis/docker-compose.yml',
|
||||||
|
'example/compose/nginx/backend/docker-compose.yml',
|
||||||
|
'example/compose/nginx/portal/docker-compose.yml',
|
||||||
|
'example/compose/smtp/docker-compose.yml',
|
||||||
|
'example/compose/httpbin/docker-compose.yml',
|
||||||
|
'example/compose/ldap/docker-compose.admin.yml', // This is just used for administration, not for testing.
|
||||||
|
'example/compose/ldap/docker-compose.yml'
|
||||||
|
]
|
||||||
|
|
||||||
|
const dockerEnv = new DockerEnvironment(composeFiles);
|
||||||
|
|
||||||
|
async function setup() {
|
||||||
|
await exec('./example/compose/nginx/portal/render.js --production http://authelia:9091');
|
||||||
|
await dockerEnv.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function teardown() {
|
||||||
|
await dockerEnv.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
const setup_timeout = 30000;
|
||||||
|
const teardown_timeout = 30000;
|
||||||
|
|
||||||
|
export {
|
||||||
|
setup,
|
||||||
|
setup_timeout,
|
||||||
|
teardown,
|
||||||
|
teardown_timeout,
|
||||||
|
composeFiles
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
import AutheliaSuite from '../../helpers/context/AutheliaSuite';
|
||||||
|
import DockerCompose from '../../helpers/context/DockerCompose';
|
||||||
|
import { composeFiles } from './environment';
|
||||||
|
import Assert from 'assert';
|
||||||
|
import SingleFactorAuthentication from '../../helpers/scenarii/SingleFactorAuthentication';
|
||||||
|
import TwoFactorAuthentication from '../../helpers/scenarii/TwoFactorAuthentication';
|
||||||
|
|
||||||
|
AutheliaSuite(__dirname, function() {
|
||||||
|
this.timeout(15000);
|
||||||
|
const dockerCompose = new DockerCompose(composeFiles);
|
||||||
|
|
||||||
|
describe('Check the container', function() {
|
||||||
|
it('should be running', async function() {
|
||||||
|
const stdout = await dockerCompose.ps();
|
||||||
|
const lines = stdout.split("\n");
|
||||||
|
const autheliaLine = lines.filter(l => l.indexOf('authelia_1') > -1);
|
||||||
|
if (autheliaLine.length != 1) {
|
||||||
|
throw new Error('Authelia container not found...');
|
||||||
|
}
|
||||||
|
// check if the container is up.
|
||||||
|
Assert(autheliaLine[0].indexOf(' Up ') > -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Single-factor authentication', SingleFactorAuthentication())
|
||||||
|
describe('Two-factor authentication', TwoFactorAuthentication());
|
||||||
|
});
|
Loading…
Reference in New Issue