mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Replace typescript version of authelia-scripts by Go version.
This commit is contained in:
parent
2dccd10a27
commit
9d7224b7ad
20
.travis.yml
20
.travis.yml
|
@ -14,22 +14,18 @@ addons:
|
|||
packages:
|
||||
- libgif-dev
|
||||
- google-chrome-stable
|
||||
|
||||
before_script:
|
||||
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
|
||||
- nvm install v9 && nvm use v9 && npm i
|
||||
- nvm install v11 && nvm use v11 && npm i
|
||||
script:
|
||||
- "./scripts/authelia-scripts travis"
|
||||
- "source bootstrap.sh"
|
||||
- "authelia-scripts ci"
|
||||
after_success:
|
||||
- "./scripts/authelia-scripts docker publish"
|
||||
deploy:
|
||||
provider: npm
|
||||
email: clement.michaud34@gmail.com
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
secure: HpaWykYM6zaTXrDRGvyRvsIhn1BLT5gxdU1VXB6PMlr+FpTUoOXsYqLf+S1ipmR8rfjCGXIM1dRPfp/UmEgeWBSJ8PDjipcjYLEWkJSsW8IAO6GVR+pNPO6TgBQmR5RljZRwBd/uIh43nW9tG1YeoERVxdF4OvqwIeu0+jFrVnMdQngfAhXOiEMDSwH328q8QZIkQUmEhWn+IksHG34rLyo29hQQtJ1OnPkJwB9ZSJ71EEp0VH5UtJBCy5eDxKo9NQgvZpf+t6b2jfmHzp1uHlc8h7frpsCIJ0mborzWgc7P0VT/eaNbiFEC0oYkm+0lYVa0kgwbpxB02b/N/VGNXp8Tg8cWQmDly9NomR2BXeCgoQr4hvwpbXNw/I1FunVHVM66o0lMJmFJllFhqSWYLtqHrJb1qNIIFJGCqkTb6pnj35pTC50HjITAK9hQqvhwQ8v142qEpxu9rIvQ+ao90sY9IPxTedhGRs6gjF32JEeXjzysysecZ16jnae4bxmGVT21VF4zcDabCz6IMPje/aGg4flGxGJ5rwYb9p9vWXcgO2FXQzmNg3USTqCQWL+4oN0aiv9IknStkZ9bHLSK+tQ/SGjSlIpn5ou2CfQgkBSkj1vmmG+M+eJN0x/BzRYwURrQRm2t4BBPpcj+PkLVDoNuw6I8ETfsLf9b/B1mi2E=
|
||||
on:
|
||||
tags: true
|
||||
repo: clems4ever/authelia
|
||||
- "authelia-scripts docker publish"
|
||||
|
||||
# TODO(c.michaud): publish built artifact on Github.
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
|
|
|
@ -82,7 +82,7 @@ func RandomString(n int) string {
|
|||
func HashPassword(password string, salt *string) string {
|
||||
var generatedSalt string
|
||||
if salt == nil {
|
||||
generatedSalt = fmt.Sprintf("$6$rounds=5000$%s$", RandomString(16))
|
||||
generatedSalt = fmt.Sprintf("$6$rounds=50000$%s$", RandomString(16))
|
||||
} else {
|
||||
generatedSalt = *salt
|
||||
}
|
||||
|
|
32
bootstrap.sh
32
bootstrap.sh
|
@ -1,33 +1,19 @@
|
|||
|
||||
export PATH=$(pwd)/scripts:/tmp:$PATH
|
||||
set -e
|
||||
|
||||
export PATH=./cmd/authelia-scripts/:/tmp:$PATH
|
||||
|
||||
if [ -z "$OLD_PS1" ]; then
|
||||
OLD_PS1="$PS1"
|
||||
export PS1="(authelia) $PS1"
|
||||
fi
|
||||
|
||||
npm i
|
||||
|
||||
pushd client
|
||||
npm i
|
||||
popd
|
||||
|
||||
echo "[BOOTSTRAP] Checking if Docker is installed..."
|
||||
if [ ! -x "$(command -v docker)" ];
|
||||
echo "[BOOTSTRAP] Checking if Go is installed..."
|
||||
if [ ! -x "$(command -v go)" ];
|
||||
then
|
||||
echo "[ERROR] You must install docker on your machine.";
|
||||
echo "[ERROR] You must install Go on your machine.";
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[BOOTSTRAP] Checking if docker-compose is installed..."
|
||||
if [ ! -x "$(command -v docker-compose)" ];
|
||||
then
|
||||
echo "[ERROR] You must install docker-compose on your machine.";
|
||||
return;
|
||||
fi
|
||||
|
||||
echo "[BOOTSTRAP] Running additional bootstrap steps..."
|
||||
authelia-scripts bootstrap
|
||||
|
||||
# Create temporary directory that will contain the databases used in tests.
|
||||
mkdir -p /tmp/authelia
|
||||
|
||||
echo "[BOOTSTRAP] Run 'authelia-scripts suites start dockerhub' to start Authelia and visit https://home.example.com:8080."
|
||||
echo "[BOOTSTRAP] More details at https://github.com/clems4ever/authelia/blob/master/docs/getting-started.md"
|
||||
|
|
3
cmd/authelia-scripts/authelia-scripts
Executable file
3
cmd/authelia-scripts/authelia-scripts
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
go run cmd/authelia-scripts/*.go $*
|
225
cmd/authelia-scripts/cmd_bootstrap.go
Normal file
225
cmd/authelia-scripts/cmd_bootstrap.go
Normal file
|
@ -0,0 +1,225 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// HostEntry represents an entry in /etc/hosts
|
||||
type HostEntry struct {
|
||||
Domain string
|
||||
IP string
|
||||
}
|
||||
|
||||
var hostEntries = []HostEntry{
|
||||
// For common tests
|
||||
HostEntry{Domain: "login.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "admin.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "singlefactor.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "dev.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "home.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "mx1.mail.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "mx2.mail.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "public.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "secure.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "mail.example.com", IP: "192.168.240.100"},
|
||||
HostEntry{Domain: "duo.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For Traefik suite
|
||||
HostEntry{Domain: "traefik.example.com", IP: "192.168.240.100"},
|
||||
|
||||
// For testing network ACLs
|
||||
HostEntry{Domain: "proxy-client1.example.com", IP: "192.168.240.201"},
|
||||
HostEntry{Domain: "proxy-client2.example.com", IP: "192.168.240.202"},
|
||||
HostEntry{Domain: "proxy-client3.example.com", IP: "192.168.240.203"},
|
||||
}
|
||||
|
||||
func runCommand(cmd string, args ...string) {
|
||||
command := CommandWithStdout(cmd, args...)
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func installNpmPackages() {
|
||||
runCommand("npm", "ci")
|
||||
}
|
||||
|
||||
func checkCommandExist(cmd string) {
|
||||
fmt.Print("Checking if '" + cmd + "' command is installed...")
|
||||
command := exec.Command("bash", "-c", "command -v "+cmd)
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("[ERROR] You must install " + cmd + " on your machine.")
|
||||
}
|
||||
|
||||
fmt.Println(" OK")
|
||||
}
|
||||
|
||||
func installClientNpmPackages() {
|
||||
command := CommandWithStdout("npm", "ci")
|
||||
command.Dir = "client"
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createTemporaryDirectory() {
|
||||
err := os.MkdirAll("/tmp/authelia", 0755)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func bootstrapPrintln(args ...interface{}) {
|
||||
a := make([]interface{}, 0)
|
||||
a = append(a, "[BOOTSTRAP]")
|
||||
a = append(a, args...)
|
||||
fmt.Println(a...)
|
||||
}
|
||||
|
||||
func shell(cmd string) {
|
||||
runCommand("bash", "-c", cmd)
|
||||
}
|
||||
|
||||
func buildDockerImages() {
|
||||
shell("docker build -t authelia-example-backend example/compose/nginx/backend")
|
||||
shell("docker build -t authelia-duo-api example/compose/duo-api")
|
||||
}
|
||||
|
||||
func installKubernetesDependencies() {
|
||||
if exist, err := FileExists("/tmp/kind"); err == nil && !exist {
|
||||
shell("wget -nv https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-linux-amd64 -O /tmp/kind && chmod +x /tmp/kind")
|
||||
} else {
|
||||
bootstrapPrintln("Skip installing Kind since it's already installed")
|
||||
}
|
||||
|
||||
if exist, err := FileExists("/tmp/kubectl"); err == nil && !exist {
|
||||
shell("wget -nv https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl -O /tmp/kubectl && chmod +x /tmp/kubectl")
|
||||
} else {
|
||||
bootstrapPrintln("Skip installing Kubectl since it's already installed")
|
||||
}
|
||||
}
|
||||
|
||||
func prepareHostsFile() {
|
||||
contentBytes, err := readHostsFile()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := strings.Split(string(contentBytes), "\n")
|
||||
toBeAddedLine := make([]string, 0)
|
||||
modified := false
|
||||
|
||||
for _, entry := range hostEntries {
|
||||
domainInHostFile := false
|
||||
for i, line := range lines {
|
||||
domainFound := strings.Contains(line, entry.Domain)
|
||||
ipFound := strings.Contains(line, entry.IP)
|
||||
|
||||
if domainFound {
|
||||
domainInHostFile = true
|
||||
|
||||
// The IP is not up to date.
|
||||
if ipFound {
|
||||
break
|
||||
} else {
|
||||
lines[i] = entry.IP + " " + entry.Domain
|
||||
modified = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !domainInHostFile {
|
||||
toBeAddedLine = append(toBeAddedLine, entry.IP+" "+entry.Domain)
|
||||
}
|
||||
}
|
||||
|
||||
if len(toBeAddedLine) > 0 {
|
||||
lines = append(lines, toBeAddedLine...)
|
||||
modified = true
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile("/tmp/authelia/hosts", []byte(strings.Join(lines, "\n")), 0644)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if modified {
|
||||
bootstrapPrintln("/etc/hosts needs to be updated")
|
||||
shell("/usr/bin/sudo mv /tmp/authelia/hosts /etc/hosts")
|
||||
}
|
||||
}
|
||||
|
||||
// ReadHostsFile reads the hosts file.
|
||||
func readHostsFile() ([]byte, error) {
|
||||
bs, err := ioutil.ReadFile("/etc/hosts")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
func readVersion(cmd string, args ...string) {
|
||||
command := exec.Command(cmd, args...)
|
||||
b, err := command.Output()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Print(cmd + " => " + string(b))
|
||||
}
|
||||
|
||||
func readVersions() {
|
||||
readVersion("go", "version")
|
||||
readVersion("node", "--version")
|
||||
readVersion("docker", "--version")
|
||||
readVersion("docker-compose", "--version")
|
||||
}
|
||||
|
||||
// Bootstrap bootstrap authelia dev environment
|
||||
func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
||||
bootstrapPrintln("Checking command installation...")
|
||||
checkCommandExist("node")
|
||||
checkCommandExist("docker")
|
||||
checkCommandExist("docker-compose")
|
||||
|
||||
bootstrapPrintln("Getting versions of tools")
|
||||
readVersions()
|
||||
|
||||
bootstrapPrintln("Installing NPM packages for development...")
|
||||
installNpmPackages()
|
||||
|
||||
bootstrapPrintln("Install NPM packages for frontend...")
|
||||
installClientNpmPackages()
|
||||
|
||||
bootstrapPrintln("Building development Docker images...")
|
||||
buildDockerImages()
|
||||
|
||||
bootstrapPrintln("Installing Kubernetes dependencies for testing in /tmp... (no junk installed on host)")
|
||||
installKubernetesDependencies()
|
||||
|
||||
createTemporaryDirectory()
|
||||
|
||||
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
||||
prepareHostsFile()
|
||||
|
||||
bootstrapPrintln("Run 'authelia-scripts suites start basic' 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")
|
||||
}
|
54
cmd/authelia-scripts/cmd_build.go
Normal file
54
cmd/authelia-scripts/cmd_build.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func buildAutheliaBinary() {
|
||||
cmd := CommandWithStdout("go", "build", "-o", OutputDir+"/authelia")
|
||||
cmd.Env = append(os.Environ(),
|
||||
"GOOS=linux", "GOARCH=amd64", "CGO_ENABLED=1")
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func buildFrontend() {
|
||||
cmd := CommandWithStdout("npm", "run", "build")
|
||||
cmd.Dir = "client"
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Rename("client/build", OutputDir+"/public_html")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Build build Authelia
|
||||
func Build(cobraCmd *cobra.Command, args []string) {
|
||||
Clean(cobraCmd, args)
|
||||
|
||||
fmt.Println("Creating `" + OutputDir + "` directory")
|
||||
err := os.MkdirAll(OutputDir, os.ModePerm)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Building Authelia Go binary...")
|
||||
buildAutheliaBinary()
|
||||
|
||||
fmt.Println("Building Authelia frontend...")
|
||||
buildFrontend()
|
||||
}
|
59
cmd/authelia-scripts/cmd_ci.go
Normal file
59
cmd/authelia-scripts/cmd_ci.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const dockerPullCommandLine = "docker-compose -f docker-compose.yml " +
|
||||
"-f example/compose/mongo/docker-compose.yml " +
|
||||
"-f example/compose/redis/docker-compose.yml " +
|
||||
"-f example/compose/nginx/portal/docker-compose.yml " +
|
||||
"-f example/compose/smtp/docker-compose.yml " +
|
||||
"-f example/compose/httpbin/docker-compose.yml " +
|
||||
"-f example/compose/ldap/docker-compose.admin.yml " +
|
||||
"-f example/compose/ldap/docker-compose.yml " +
|
||||
"pull"
|
||||
|
||||
// RunCI run the CI scripts
|
||||
func RunCI(cmd *cobra.Command, args []string) {
|
||||
command := CommandWithStdout("bash", "-c", dockerPullCommandLine)
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("===== Build stage =====")
|
||||
command = CommandWithStdout("authelia-scripts", "build")
|
||||
err = command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("===== Unit testing stage =====")
|
||||
command = CommandWithStdout("authelia-scripts", "unittest")
|
||||
err = command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("===== Docker image build stage =====")
|
||||
command = CommandWithStdout("authelia-scripts", "docker", "build")
|
||||
err = command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("===== End-to-end testing stage =====")
|
||||
command = CommandWithStdout("authelia-scripts", "suites", "test", "--headless", "--only-forbidden")
|
||||
err = command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
18
cmd/authelia-scripts/cmd_clean.go
Normal file
18
cmd/authelia-scripts/cmd_clean.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// Clean artifacts built and installed by authelia-scripts
|
||||
func Clean(cobraCmd *cobra.Command, args []string) {
|
||||
fmt.Println("Removing `" + OutputDir + "` directory")
|
||||
err := os.RemoveAll(OutputDir)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
96
cmd/authelia-scripts/cmd_docker.go
Normal file
96
cmd/authelia-scripts/cmd_docker.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// DockerBuildCmd Command for building docker image of Authelia.
|
||||
var DockerBuildCmd = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: "Build the docker image of Authelia",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
docker := &Docker{}
|
||||
err := docker.Build(IntermediateDockerImageName, ".")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// DockerPushCmd Command for pushing Authelia docker image to Dockerhub
|
||||
var DockerPushCmd = &cobra.Command{
|
||||
Use: "publish",
|
||||
Short: "Publish Authelia docker image to Dockerhub",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
publishDockerImage()
|
||||
},
|
||||
}
|
||||
|
||||
func login(docker *Docker) {
|
||||
username := os.Getenv("DOCKER_USERNAME")
|
||||
password := os.Getenv("DOCKER_PASSWORD")
|
||||
|
||||
if username == "" {
|
||||
panic(errors.New("DOCKER_USERNAME is empty"))
|
||||
}
|
||||
|
||||
if password == "" {
|
||||
panic(errors.New("DOCKER_PASSWORD is empty"))
|
||||
}
|
||||
|
||||
fmt.Println("Login to dockerhub as " + username)
|
||||
err := docker.Login(username, password)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Login to dockerhub failed")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func deploy(docker *Docker, tag string) {
|
||||
imageWithTag := DockerImageName + ":" + tag
|
||||
fmt.Println("===================================================")
|
||||
fmt.Println("Docker image " + imageWithTag + " will be deployed on Dockerhub.")
|
||||
fmt.Println("===================================================")
|
||||
|
||||
err := docker.Tag(DockerImageName, imageWithTag)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
docker.Push(imageWithTag)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func publishDockerImage() {
|
||||
docker := &Docker{}
|
||||
|
||||
travisBranch := os.Getenv("TRAVIS_BRANCH")
|
||||
travisPullRequest := os.Getenv("TRAVIS_PULL_REQUEST")
|
||||
travisTag := os.Getenv("TRAVIS_TAG")
|
||||
|
||||
if travisBranch == "master" && travisPullRequest == "false" {
|
||||
login(docker)
|
||||
deploy(docker, "master")
|
||||
} else if travisTag != "" {
|
||||
login(docker)
|
||||
deploy(docker, travisTag)
|
||||
deploy(docker, "latest")
|
||||
} else {
|
||||
fmt.Println("Docker image will not be built")
|
||||
}
|
||||
}
|
13
cmd/authelia-scripts/cmd_hash_password.go
Normal file
13
cmd/authelia-scripts/cmd_hash_password.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/clems4ever/authelia/authentication"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// HashPassword hash the provided password with crypt sha256 hash function
|
||||
func HashPassword(cobraCmd *cobra.Command, args []string) {
|
||||
fmt.Println(authentication.HashPassword(args[0], nil))
|
||||
}
|
14
cmd/authelia-scripts/cmd_serve.go
Normal file
14
cmd/authelia-scripts/cmd_serve.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// ServeCmd serve authelia with the provided configuration
|
||||
func ServeCmd(cobraCmd *cobra.Command, args []string) {
|
||||
cmd := CommandWithStdout(OutputDir+"/authelia", "-config", args[0])
|
||||
cmd.Env = append(os.Environ(), "PUBLIC_DIR=dist/public_html")
|
||||
RunCommandUntilCtrlC(cmd)
|
||||
}
|
234
cmd/authelia-scripts/cmd_suites.go
Normal file
234
cmd/authelia-scripts/cmd_suites.go
Normal file
|
@ -0,0 +1,234 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func listDirectories(path string) ([]string, error) {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dirs := make([]string, 0)
|
||||
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
dirs = append(dirs, f.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
func listSuites() ([]string, error) {
|
||||
return listDirectories("./test/suites/")
|
||||
}
|
||||
|
||||
func suiteAvailable(suite string, suites []string) (bool, error) {
|
||||
suites, err := listSuites()
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, s := range suites {
|
||||
if s == suite {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// SuitesListCmd Command for listing the available suites
|
||||
var SuitesListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List available suites.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
suites, err := listSuites()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(strings.Join(suites, "\n"))
|
||||
},
|
||||
Args: cobra.ExactArgs(0),
|
||||
}
|
||||
|
||||
// SuitesCleanCmd Command for cleaning suite environments
|
||||
var SuitesCleanCmd = &cobra.Command{
|
||||
Use: "clean",
|
||||
Short: "Clean suite environments.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
command := CommandWithStdout("bash", "-c",
|
||||
"./node_modules/.bin/ts-node -P test/tsconfig.json -- ./scripts/clean-environment.ts")
|
||||
err := command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
},
|
||||
Args: cobra.ExactArgs(0),
|
||||
}
|
||||
|
||||
// SuitesStartCmd Command for starting a suite
|
||||
var SuitesStartCmd = &cobra.Command{
|
||||
Use: "start [suite]",
|
||||
Short: "Start a suite. Suites can be listed using the list command.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
suites, err := listSuites()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
selectedSuite := args[0]
|
||||
|
||||
available, err := suiteAvailable(selectedSuite, suites)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !available {
|
||||
panic(errors.New("Suite named " + selectedSuite + " does not exist"))
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(RunningSuiteFile, []byte(selectedSuite), 0644)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
signalChannel := make(chan os.Signal)
|
||||
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
cmdline := "./node_modules/.bin/ts-node -P test/tsconfig.json -- ./scripts/run-environment.ts " + selectedSuite
|
||||
command := CommandWithStdout("bash", "-c", cmdline)
|
||||
command.Env = append(os.Environ(), "ENVIRONMENT=dev")
|
||||
|
||||
err = command.Run()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Remove(RunningSuiteFile)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
},
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
|
||||
// SuitesTestCmd Command for testing a suite
|
||||
var SuitesTestCmd = &cobra.Command{
|
||||
Use: "test [suite]",
|
||||
Short: "Test a suite. Suites can be listed using the list command.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
runningSuite, err := getRunningSuite()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(args) == 1 {
|
||||
suite := args[0]
|
||||
|
||||
if runningSuite != "" && suite != runningSuite {
|
||||
panic(errors.New("Running suite (" + runningSuite + ") is different than suite to be tested (" + suite + "). Shutdown running suite and retry"))
|
||||
}
|
||||
|
||||
runSuiteTests(suite, runningSuite == "")
|
||||
} else {
|
||||
if runningSuite != "" {
|
||||
panic(errors.New("Cannot run all tests while a suite is currently running. Shutdown running suite and retry"))
|
||||
}
|
||||
fmt.Println("No suite provided therefore all suites will be tested")
|
||||
runAllSuites()
|
||||
}
|
||||
},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
func getRunningSuite() (string, error) {
|
||||
exist, err := FileExists(RunningSuiteFile)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(RunningSuiteFile)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
func runSuiteTests(suite string, withEnv bool) {
|
||||
mochaArgs := []string{"--exit", "--colors", "--require", "ts-node/register", "test/suites/" + suite + "/test.ts"}
|
||||
if onlyForbidden {
|
||||
mochaArgs = append(mochaArgs, "--forbid-only", "--forbid-pending")
|
||||
}
|
||||
mochaCmdLine := "./node_modules/.bin/mocha " + strings.Join(mochaArgs, " ")
|
||||
|
||||
fmt.Println(mochaCmdLine)
|
||||
|
||||
headlessValue := "n"
|
||||
if headless {
|
||||
headlessValue = "y"
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
|
||||
if withEnv {
|
||||
fmt.Println("No running suite detected, setting up an environment for running the tests")
|
||||
cmd = CommandWithStdout("bash", "-c",
|
||||
"./node_modules/.bin/ts-node ./scripts/run-environment.ts "+suite+" '"+mochaCmdLine+"'")
|
||||
} else {
|
||||
fmt.Println("Running suite detected. Running tests...")
|
||||
cmd = CommandWithStdout("bash", "-c", mochaCmdLine)
|
||||
}
|
||||
|
||||
cmd.Env = append(os.Environ(),
|
||||
"TS_NODE_PROJECT=test/tsconfig.json",
|
||||
"HEADLESS="+headlessValue,
|
||||
"ENVIRONMENT=dev")
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func runAllSuites() {
|
||||
suites, err := listSuites()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, s := range suites {
|
||||
runSuiteTests(s, true)
|
||||
}
|
||||
}
|
||||
|
||||
var headless bool
|
||||
var onlyForbidden bool
|
||||
|
||||
func init() {
|
||||
SuitesTestCmd.Flags().BoolVar(&headless, "headless", false, "Run tests in headless mode")
|
||||
SuitesTestCmd.Flags().BoolVar(&onlyForbidden, "only-forbidden", false, "Mocha 'only' filters are forbidden")
|
||||
}
|
11
cmd/authelia-scripts/cmd_unittest.go
Normal file
11
cmd/authelia-scripts/cmd_unittest.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package main
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
// RunUnitTest run the unit tests
|
||||
func RunUnitTest(cobraCmd *cobra.Command, args []string) {
|
||||
err := CommandWithStdout("go", "test", "./...").Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
13
cmd/authelia-scripts/constants.go
Normal file
13
cmd/authelia-scripts/constants.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
// OutputDir the output directory where the built version of Authelia is located
|
||||
var OutputDir = "dist"
|
||||
|
||||
// DockerImageName the official name of authelia docker image
|
||||
var DockerImageName = "clems4ever/authelia"
|
||||
|
||||
// IntermediateDockerImageName local name of the docker image
|
||||
var IntermediateDockerImageName = "authelia:dist"
|
||||
|
||||
// RunningSuiteFile name of the file containing the currently running suite
|
||||
var RunningSuiteFile = ".suite"
|
24
cmd/authelia-scripts/docker.go
Normal file
24
cmd/authelia-scripts/docker.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
// Docker a docker object
|
||||
type Docker struct{}
|
||||
|
||||
// Build build a docker image
|
||||
func (d *Docker) Build(tag string, target string) error {
|
||||
return CommandWithStdout("docker", "build", "-t", tag, target).Run()
|
||||
}
|
||||
|
||||
// Tag tag a docker image.
|
||||
func (d *Docker) Tag(image, tag string) error {
|
||||
return CommandWithStdout("docker", "tag", image, tag).Run()
|
||||
}
|
||||
|
||||
// Login login to the dockerhub registry.
|
||||
func (d *Docker) Login(username, password string) error {
|
||||
return CommandWithStdout("docker", "login", "-u", username, "-p", password).Run()
|
||||
}
|
||||
|
||||
// Push push a docker image to dockerhub.
|
||||
func (d *Docker) Push(tag string) error {
|
||||
return CommandWithStdout("docker", "push", tag).Run()
|
||||
}
|
52
cmd/authelia-scripts/exec.go
Normal file
52
cmd/authelia-scripts/exec.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// CommandWithStdout execute the command and forward stdout and stderr to the OS streams
|
||||
func CommandWithStdout(name string, args ...string) *exec.Cmd {
|
||||
cmd := exec.Command(name, args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd
|
||||
}
|
||||
|
||||
// RunCommandUntilCtrlC run a command until ctrl-c is hit
|
||||
func RunCommandUntilCtrlC(cmd *exec.Cmd) {
|
||||
mutex := sync.Mutex{}
|
||||
cond := sync.NewCond(&mutex)
|
||||
signalChannel := make(chan os.Signal)
|
||||
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
mutex.Lock()
|
||||
|
||||
go func() {
|
||||
mutex.Lock()
|
||||
f := bufio.NewWriter(os.Stdout)
|
||||
defer f.Flush()
|
||||
|
||||
fmt.Println("Hit Ctrl+C to shutdown...")
|
||||
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
cond.Broadcast()
|
||||
mutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
<-signalChannel
|
||||
cond.Broadcast()
|
||||
mutex.Unlock()
|
||||
}()
|
||||
|
||||
cond.Wait()
|
||||
}
|
15
cmd/authelia-scripts/files.go
Normal file
15
cmd/authelia-scripts/files.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package main
|
||||
|
||||
import "os"
|
||||
|
||||
// FileExists returns whether the given file or directory exists
|
||||
func FileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return true, err
|
||||
}
|
121
cmd/authelia-scripts/main.go
Executable file
121
cmd/authelia-scripts/main.go
Executable file
|
@ -0,0 +1,121 @@
|
|||
//usr/bin/env go run "$0" "$@"; exit
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// AutheliaCommandDefinition is the definition of one authelia-scripts command.
|
||||
type AutheliaCommandDefinition struct {
|
||||
Name string
|
||||
Short string
|
||||
Long string
|
||||
CommandLine string
|
||||
Args cobra.PositionalArgs
|
||||
Func func(cmd *cobra.Command, args []string)
|
||||
SubCommands []*cobra.Command
|
||||
}
|
||||
|
||||
// CobraCommands list of cobra commands
|
||||
type CobraCommands = []*cobra.Command
|
||||
|
||||
// Commands is the list of commands of authelia-scripts
|
||||
var Commands = []AutheliaCommandDefinition{
|
||||
AutheliaCommandDefinition{
|
||||
Name: "bootstrap",
|
||||
Short: "Prepare environment for development and testing.",
|
||||
Long: `Prepare environment for development and testing. This command prepares docker
|
||||
images and download tools like Kind for Kubernetes testing.`,
|
||||
Func: Bootstrap,
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "build",
|
||||
Short: "Build Authelia binary and static assets",
|
||||
Func: Build,
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "clean",
|
||||
Short: "Clean build artifacts",
|
||||
Func: Clean,
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "docker",
|
||||
Short: "Commands related to building and publishing docker image",
|
||||
SubCommands: CobraCommands{DockerBuildCmd, DockerPushCmd},
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "hash-password [password]",
|
||||
Short: "Compute hash of a password for creating a file-based users database",
|
||||
Func: HashPassword,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "serve [config]",
|
||||
Short: "Serve compiled version of Authelia",
|
||||
Func: ServeCmd,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "suites",
|
||||
Short: "Compute hash of a password for creating a file-based users database",
|
||||
SubCommands: CobraCommands{SuitesCleanCmd, SuitesListCmd, SuitesStartCmd, SuitesTestCmd},
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "ci",
|
||||
Short: "Run continuous integration script",
|
||||
Func: RunCI,
|
||||
},
|
||||
AutheliaCommandDefinition{
|
||||
Name: "unittest",
|
||||
Short: "Run unit tests",
|
||||
Func: RunUnitTest,
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
var rootCmd = &cobra.Command{Use: "authelia-scripts"}
|
||||
cobraCommands := make([]*cobra.Command, 0)
|
||||
|
||||
for _, autheliaCommand := range Commands {
|
||||
var fn func(cobraCmd *cobra.Command, args []string)
|
||||
|
||||
if autheliaCommand.CommandLine != "" {
|
||||
cmdline := autheliaCommand.CommandLine
|
||||
fn = func(cobraCmd *cobra.Command, args []string) {
|
||||
cmd := CommandWithStdout(cmdline, args...)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
} else if autheliaCommand.Func != nil {
|
||||
fn = autheliaCommand.Func
|
||||
}
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: autheliaCommand.Name,
|
||||
Short: autheliaCommand.Short,
|
||||
}
|
||||
|
||||
if autheliaCommand.Long != "" {
|
||||
command.Long = autheliaCommand.Long
|
||||
}
|
||||
|
||||
if fn != nil {
|
||||
command.Run = fn
|
||||
}
|
||||
|
||||
if autheliaCommand.Args != nil {
|
||||
command.Args = autheliaCommand.Args
|
||||
}
|
||||
|
||||
if autheliaCommand.SubCommands != nil {
|
||||
command.AddCommand(autheliaCommand.SubCommands...)
|
||||
}
|
||||
|
||||
cobraCommands = append(cobraCommands, command)
|
||||
}
|
||||
rootCmd.AddCommand(cobraCommands...)
|
||||
rootCmd.Execute()
|
||||
}
|
|
@ -2,7 +2,6 @@ package validator
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/clems4ever/authelia/configuration/schema"
|
||||
|
@ -37,7 +36,6 @@ func validateLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationB
|
|||
} else {
|
||||
configuration.URL = validateLdapURL(configuration.URL, validator)
|
||||
}
|
||||
fmt.Println(configuration.URL)
|
||||
|
||||
if configuration.User == "" {
|
||||
validator.Push(errors.New("Please provide a user name to connect to the LDAP server"))
|
||||
|
|
1
go.mod
1
go.mod
|
@ -15,6 +15,7 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.11.0
|
||||
github.com/pquerna/otp v1.2.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tstranex/u2f v1.0.0
|
||||
github.com/valyala/fasthttp v1.6.0
|
||||
|
|
26
go.sum
26
go.sum
|
@ -1,10 +1,16 @@
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo=
|
||||
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -16,6 +22,7 @@ github.com/fasthttp/router v0.5.2 h1:xdmx8uYc9IFDtlbG2/FhE1Gyowv7/sqMgMonRjoW0Yo
|
|||
github.com/fasthttp/router v0.5.2/go.mod h1:Y5JAeRTSPwSLoUgH4x75UnT1j1IcAgVshMDMMrnNmKQ=
|
||||
github.com/fasthttp/session v1.1.3 h1:2qjxNltI7iv0yh7frsIdhbsGmSoRnTajU8xtpC6Hd80=
|
||||
github.com/fasthttp/session v1.1.3/go.mod h1:DRxVb1PWFtAUTE4U+GgggsVkUaQyacoL8TN+3o4/yLw=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
|
@ -25,6 +32,8 @@ github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
|||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
|
@ -32,21 +41,34 @@ github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
|
||||
github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/savsgio/dictpool v0.0.0-20191028211042-a886cee3358a h1:HHo8bk/5tOTL+UJ2VBkzGWhurfjyrLMRnvdRBnXYlfs=
|
||||
github.com/savsgio/dictpool v0.0.0-20191028211042-a886cee3358a/go.mod h1:hnGRFeigcU3gTEMTWW8OjfoSYztn2GPcriOY9iIzCrA=
|
||||
github.com/savsgio/gotils v0.0.0-20190925070755-524bc4f47500 h1:9Pi10H7E8E79/x2HSe1FmMGd7BJ1WAqDKzwjpv+ojFg=
|
||||
github.com/savsgio/gotils v0.0.0-20190925070755-524bc4f47500/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
|
@ -57,6 +79,7 @@ github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
|
|||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY=
|
||||
|
@ -66,14 +89,17 @@ github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV
|
|||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -42,28 +42,21 @@
|
|||
"@types/request": "^2.0.5",
|
||||
"@types/request-promise": "^4.1.38",
|
||||
"@types/selenium-webdriver": "^3.0.16",
|
||||
"@types/sinon": "^4.3.0",
|
||||
"@types/speakeasy": "^2.0.2",
|
||||
"@types/tmp": "0.0.33",
|
||||
"chokidar": "^2.0.4",
|
||||
"chromedriver": "^77.0.0",
|
||||
"commander": "^2.19.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"ejs": "^2.6.2",
|
||||
"mocha": "^6.1.4",
|
||||
"mockdate": "^2.0.1",
|
||||
"node-fetch": "^2.3.0",
|
||||
"nodemon": "^1.18.9",
|
||||
"query-string": "^6.0.0",
|
||||
"readable-stream": "^2.3.3",
|
||||
"redis": "^2.8.0",
|
||||
"request": "^2.88.0",
|
||||
"request-promise": "^4.2.2",
|
||||
"selenium-webdriver": "^4.0.0-alpha.4",
|
||||
"should": "^13.2.1",
|
||||
"sinon": "^5.0.7",
|
||||
"speakeasy": "^2.0.0",
|
||||
"tmp": "0.0.33",
|
||||
"tree-kill": "^1.2.1",
|
||||
"ts-node": "^6.0.1",
|
||||
"tslint": "^5.2.0",
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
|
||||
.command('bootstrap', 'Prepare some containers for development.')
|
||||
.command('suites', 'Run Authelia in specific environments.')
|
||||
.command('serve', 'Run Authelia with a customized configuration.')
|
||||
.command('build', 'Build production version of Authelia from source.')
|
||||
.command('clean', 'Clean the production version of Authelia.')
|
||||
.command('unittest', 'Run Authelia integration tests.')
|
||||
|
||||
.command('travis', 'Build and test Authelia on Travis.')
|
||||
.command('hash-password <password>', 'Hash a password with SSHA512.')
|
||||
.command('docker', 'Docker related commands.')
|
||||
.parse(process.argv);
|
|
@ -1,86 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var { exec } = require('./utils/exec');
|
||||
var fs = require('fs');
|
||||
|
||||
async function buildDockerImages() {
|
||||
console.log("[BOOTSTRAP] Building required Docker images...");
|
||||
|
||||
console.log('Build authelia-example-backend docker image.')
|
||||
await exec('docker build -t authelia-example-backend example/compose/nginx/backend');
|
||||
|
||||
console.log('Build authelia-duo-api docker image.')
|
||||
await exec('docker build -t authelia-duo-api example/compose/duo-api');
|
||||
}
|
||||
|
||||
async function checkHostsFile() {
|
||||
async function checkAndFixEntry(entries, domain, ip) {
|
||||
const foundEntry = entries.filter(l => l[1] == domain);
|
||||
if (foundEntry.length > 0) {
|
||||
if (foundEntry[0][0] == ip) {
|
||||
// The entry exists and is correct.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// We need to remove the entry and replace it.
|
||||
console.log(`Update entry for ${domain}.`);
|
||||
await exec(`cat /etc/hosts | grep -v "${domain}" | /usr/bin/sudo tee /etc/hosts > /dev/null`);
|
||||
await exec(`echo "${ip} ${domain}" | /usr/bin/sudo tee -a /etc/hosts > /dev/null`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need to add the new entry.
|
||||
console.log(`Add entry for ${domain}.`);
|
||||
await exec(`echo "${ip} ${domain}" | /usr/bin/sudo tee -a /etc/hosts > /dev/null`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[BOOTSTRAP] Checking if example.com domain is forwarded to your machine...");
|
||||
const actualEntries = fs.readFileSync("/etc/hosts").toString("utf-8")
|
||||
.split("\n").filter(l => l !== '').map(l => l.split(" ").filter(w => w !== ''));
|
||||
|
||||
await checkAndFixEntry(actualEntries, 'login.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'admin.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'singlefactor.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'dev.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'home.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mx1.mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mx2.mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'public.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'secure.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'duo.example.com', '192.168.240.100');
|
||||
|
||||
// For Traefik suite.
|
||||
await checkAndFixEntry(actualEntries, 'traefik.example.com', '192.168.240.100');
|
||||
|
||||
// For testing network ACLs.
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client1.example.com', '192.168.240.201');
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client2.example.com', '192.168.240.202');
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client3.example.com', '192.168.240.203');
|
||||
}
|
||||
|
||||
async function checkKubernetesDependencies() {
|
||||
console.log("[BOOTSTRAP] Checking Kubernetes tools in /tmp to allow testing a Kube cluster... (no junk installed on host)");
|
||||
|
||||
if (!fs.existsSync('/tmp/kind')) {
|
||||
console.log('Install Kind for spawning a Kubernetes cluster.');
|
||||
await exec('wget -nv https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-linux-amd64 -O /tmp/kind && chmod +x /tmp/kind');
|
||||
}
|
||||
|
||||
if (!fs.existsSync('/tmp/kubectl')) {
|
||||
console.log('Install Kubectl for interacting with Kubernetes.');
|
||||
await exec('wget -nv https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl -O /tmp/kubectl && chmod +x /tmp/kubectl');
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await checkHostsFile();
|
||||
await buildDockerImages();
|
||||
await checkKubernetesDependencies();
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
})
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
DIST_DIR=dist
|
||||
|
||||
rm -rf $DIST_DIR
|
||||
mkdir -p $DIST_DIR
|
||||
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o $DIST_DIR/authelia
|
||||
|
||||
# Build the client
|
||||
pushd client
|
||||
npm run build
|
||||
popd
|
||||
|
||||
mv client/build $DIST_DIR/public_html
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -rf dist
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.command('build', 'Build docker image clems4ever/authelia.')
|
||||
.command('publish', 'Publish image clems4ever/authelia to Dockerhub.')
|
||||
.parse(process.argv);
|
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var { exec } = require('./utils/exec');
|
||||
var { IMAGE_NAME, DOCKERHUB_IMAGE_NAME } = require('./utils/docker');
|
||||
|
||||
async function main() {
|
||||
await exec(`docker build -t ${IMAGE_NAME}:dist .`);
|
||||
await exec(`docker tag ${IMAGE_NAME}:dist ${DOCKERHUB_IMAGE_NAME}`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
})
|
|
@ -1,42 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Parameters:
|
||||
# TAG - The name of the tag to use for publishing in Dockerhub
|
||||
|
||||
function login_to_dockerhub {
|
||||
echo "Logging in to Dockerhub as $DOCKER_USERNAME."
|
||||
docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
|
||||
if [ "$?" -ne "0" ];
|
||||
then
|
||||
echo "Logging in to Dockerhub failed.";
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function deploy_on_dockerhub {
|
||||
TAG=$1
|
||||
IMAGE_NAME=authelia:dist
|
||||
DOCKERHUB_IMAGE_NAME=clems4ever/authelia
|
||||
IMAGE_WITH_TAG=$DOCKERHUB_IMAGE_NAME:$TAG
|
||||
|
||||
echo "==========================================================="
|
||||
echo "Docker image $IMAGE_WITH_TAG will be deployed on Dockerhub."
|
||||
echo "==========================================================="
|
||||
docker tag $IMAGE_NAME $IMAGE_WITH_TAG;
|
||||
docker push $IMAGE_WITH_TAG;
|
||||
echo "Docker image deployed successfully."
|
||||
}
|
||||
|
||||
|
||||
if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
echo "Building on master branch"
|
||||
login_to_dockerhub
|
||||
deploy_on_dockerhub master
|
||||
elif [ ! -z "$TRAVIS_TAG" ]; then
|
||||
login_to_dockerhub
|
||||
deploy_on_dockerhub $TRAVIS_TAG
|
||||
deploy_on_dockerhub latest
|
||||
else
|
||||
echo "Docker image will not be deployed on Dockerhub."
|
||||
fi
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var RandomString = require("randomstring");
|
||||
var Util = require("util");
|
||||
var crypt = require("crypt3");
|
||||
|
||||
function ssha512(password, saltSize, rounds) {
|
||||
// $6 means SHA512
|
||||
const _salt = Util.format("$6$rounds=%d$%s", rounds,
|
||||
RandomString.generate(saltSize));
|
||||
|
||||
const hash = crypt(password, _salt);
|
||||
return Util.format("{CRYPT}%s", hash);
|
||||
}
|
||||
|
||||
let password;
|
||||
|
||||
program
|
||||
.option('-s, --salt <size>', 'The size of the salt to generate.')
|
||||
.option('-r, --rounds <rounds>', 'The number of rounds.')
|
||||
.arguments('<password>')
|
||||
.action(function (_password) {
|
||||
password = _password;
|
||||
})
|
||||
.parse(process.argv);
|
||||
|
||||
if (!password) {
|
||||
program.help();
|
||||
}
|
||||
|
||||
console.log(ssha512(password, program.salt || 16, program.rounds || 500000));
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
let config;
|
||||
|
||||
program
|
||||
.description('Run Authelia server with a custom configuration file. This is an alternative to suites in the case the environment is already set up.')
|
||||
.arguments('[config_file]', 'Configuration file to run Authelia with.')
|
||||
.action((configArg) => config = configArg)
|
||||
.parse(process.argv);
|
||||
|
||||
|
||||
if (!config) {
|
||||
config = 'config.yml'; // set default config file.;
|
||||
}
|
||||
|
||||
const server = spawn(__dirname + '/../dist/authelia', ['-config', config], {
|
||||
env: {
|
||||
...process.env,
|
||||
PUBLIC_DIR: __dirname + "/../dist/public_html"
|
||||
}
|
||||
});
|
||||
|
||||
server.stdout.pipe(process.stdout);
|
||||
server.stderr.pipe(process.stderr);
|
||||
|
||||
server.on('exit', function(statusCode) {
|
||||
process.exit(statusCode);
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.command('start', 'Start a suite.')
|
||||
.command('list', 'List the available suites')
|
||||
.command('test', 'Test a suite.')
|
||||
.command('clean', 'Clean remaining environment artifacts (like docker-compose env).')
|
||||
.parse(process.argv);
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
program
|
||||
.description(`Clean environment artifacts from previous suites.`)
|
||||
.parse(process.argv)
|
||||
|
||||
runEnvProcess = spawn('./node_modules/.bin/ts-node -P test/tsconfig.json -- ./scripts/clean-environment.ts', {
|
||||
shell: true
|
||||
});
|
||||
runEnvProcess.stdout.pipe(process.stdout);
|
||||
runEnvProcess.stderr.pipe(process.stderr);
|
||||
|
||||
runEnvProcess.on('exit', function(statusCode) {
|
||||
process.exit(statusCode);
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var ListSuites = require('./utils/ListSuites');
|
||||
|
||||
program
|
||||
.description(`List the available suites.`)
|
||||
.parse(process.argv)
|
||||
|
||||
console.log(ListSuites().join("\n"));
|
|
@ -1,64 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var spawn = require('child_process').spawn;
|
||||
var fs = require('fs');
|
||||
var ListSuites = require('./utils/ListSuites');
|
||||
|
||||
let suite;
|
||||
|
||||
program
|
||||
.description(`Start the suite provided as argument. You can list the suites with the 'list' command.`)
|
||||
.arguments('<suite>')
|
||||
.action((suiteArg) => suite = suiteArg)
|
||||
.parse(process.argv)
|
||||
|
||||
if (!suite) {
|
||||
program.help();
|
||||
}
|
||||
|
||||
if (ListSuites().indexOf(suite) == -1) {
|
||||
console.log("[WARNING] This suite does not exist. Use 'list' command to check the existing suites.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const ENVIRONMENT_FILENAME = '.suite';
|
||||
|
||||
let runEnvProcess;
|
||||
|
||||
// Sometime SIGINT is received twice, we make sure with this variable that we cleanup
|
||||
// only once.
|
||||
var alreadyCleaningUp = false;
|
||||
|
||||
// Properly cleanup server and client if ctrl-c is hit
|
||||
process.on('SIGINT', function() {
|
||||
if (alreadyCleaningUp) return;
|
||||
alreadyCleaningUp = true;
|
||||
console.log('Cleanup procedure is running...');
|
||||
});
|
||||
|
||||
async function main() {
|
||||
fs.writeFileSync(ENVIRONMENT_FILENAME, suite);
|
||||
|
||||
// Start the environment from ts-node process.
|
||||
runEnvProcess = spawn('./node_modules/.bin/ts-node -P test/tsconfig.json -- ./scripts/run-environment.ts ' + suite, {
|
||||
shell: true,
|
||||
env: {
|
||||
...process.env,
|
||||
ENVIRONMENT: 'dev',
|
||||
}
|
||||
});
|
||||
runEnvProcess.stdout.pipe(process.stdout);
|
||||
runEnvProcess.stderr.pipe(process.stderr);
|
||||
|
||||
runEnvProcess.on('exit', function(statusCode) {
|
||||
fs.unlinkSync(ENVIRONMENT_FILENAME);
|
||||
process.exit(statusCode);
|
||||
});
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1)
|
||||
});
|
|
@ -1,120 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var spawn = require('child_process').spawn;
|
||||
var fs = require('fs');
|
||||
var ListSuites = require('./utils/ListSuites');
|
||||
|
||||
let suite;
|
||||
|
||||
program
|
||||
.description('Run the tests for the current suite or the provided one.')
|
||||
.arguments('[suite]')
|
||||
.option('--headless', 'Run in headless mode.')
|
||||
.option('--forbid-only', 'Forbid only and pending filters.')
|
||||
.action((suiteArg) => suite = suiteArg)
|
||||
.parse(process.argv);
|
||||
|
||||
async function runTests(suite, withEnv) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let mochaArgs = ['--exit', '--colors', '--require', 'ts-node/register', 'test/suites/' + suite + '/test.ts']
|
||||
if (program.forbidOnly) {
|
||||
mochaArgs = ['--forbid-only', '--forbid-pending'].concat(mochaArgs);
|
||||
}
|
||||
|
||||
const mochaCommand = './node_modules/.bin/mocha ' + mochaArgs.join(' ');
|
||||
let testProcess;
|
||||
if (!withEnv) {
|
||||
testProcess = spawn(mochaCommand, {
|
||||
shell: true,
|
||||
env: {
|
||||
...process.env,
|
||||
TS_NODE_PROJECT: 'test/tsconfig.json',
|
||||
HEADLESS: (program.headless) ? 'y' : 'n',
|
||||
ENVIRONMENT: 'dev',
|
||||
}
|
||||
});
|
||||
} else {
|
||||
testProcess = spawn('./node_modules/.bin/ts-node',
|
||||
['-P', 'test/tsconfig.json', '--', './scripts/run-environment.ts', suite, mochaCommand], {
|
||||
env: {
|
||||
...process.env,
|
||||
TS_NODE_PROJECT: 'test/tsconfig.json',
|
||||
HEADLESS: (program.headless) ? 'y' : 'n',
|
||||
ENVIRONMENT: 'dev',
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
testProcess.stdout.pipe(process.stdout);
|
||||
testProcess.stderr.pipe(process.stderr);
|
||||
|
||||
testProcess.on('exit', function(statusCode) {
|
||||
if (statusCode == 0) resolve();
|
||||
reject(new Error('Tests exited with status ' + statusCode));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function runAllTests() {
|
||||
const suites = ListSuites();
|
||||
let failure = false;
|
||||
for(var s in suites) {
|
||||
try {
|
||||
console.log('Running suite %s', suites[s]);
|
||||
await runTests(suites[s], true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
if (failure) {
|
||||
throw new Error('Some tests failed.');
|
||||
}
|
||||
}
|
||||
|
||||
const ENVIRONMENT_FILENAME = '.suite'; // This file is created by the start command.
|
||||
const suiteFileExists = fs.existsSync(ENVIRONMENT_FILENAME);
|
||||
|
||||
if (suite) {
|
||||
if (suiteFileExists && suite != fs.readFileSync(ENVIRONMENT_FILENAME)) {
|
||||
console.error('You cannot test a suite while another one is running. If you want to test the current suite, ' +
|
||||
'do not provide the suite argument. Otherwise, stop the current suite and run the command again.');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Suite %s provided. Running test related to this suite against built version of Authelia.', suite);
|
||||
runTests(suite, !suiteFileExists)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
else if (suiteFileExists) {
|
||||
suite = fs.readFileSync(ENVIRONMENT_FILENAME);
|
||||
console.log('Suite %s detected from dev env. Running test related to this suite.', suite);
|
||||
runTests(suite, false)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.log('No suite provided therefore all suites will be tested.');
|
||||
runAllTests(suite)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
// Sometime SIGINT is received twice, we make sure with this variable that we cleanup
|
||||
// only once.
|
||||
var alreadyCleaningUp = false;
|
||||
|
||||
// Properly cleanup server and client if ctrl-c is hit
|
||||
process.on('SIGINT', function() {
|
||||
if (alreadyCleaningUp) return;
|
||||
alreadyCleaningUp = true;
|
||||
console.log('Cleanup procedure is running...');
|
||||
});
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
source bootstrap.sh
|
||||
|
||||
docker --version
|
||||
docker-compose --version
|
||||
|
||||
authelia-scripts bootstrap
|
||||
|
||||
docker-compose -f docker-compose.yml \
|
||||
-f example/compose/mongo/docker-compose.yml \
|
||||
-f example/compose/redis/docker-compose.yml \
|
||||
-f example/compose/nginx/portal/docker-compose.yml \
|
||||
-f example/compose/smtp/docker-compose.yml \
|
||||
-f example/compose/httpbin/docker-compose.yml \
|
||||
-f example/compose/ldap/docker-compose.admin.yml \
|
||||
-f example/compose/ldap/docker-compose.yml \
|
||||
pull
|
||||
|
||||
# Build
|
||||
echo "===> Build stage"
|
||||
authelia-scripts build
|
||||
|
||||
# Run unit tests
|
||||
echo "===> Unit tests stage"
|
||||
authelia-scripts unittest
|
||||
|
||||
# Build the docker image
|
||||
echo "===> Docker image build stage"
|
||||
authelia-scripts docker build
|
||||
|
||||
# Run integration tests
|
||||
echo "===> e2e stage"
|
||||
authelia-scripts suites test --headless --forbid-only
|
||||
|
||||
# Test npm deployment before actual deployment
|
||||
# ./scripts/npm-deployment-test.sh
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
go test ./...
|
|
@ -1,43 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
NPM_UNPACK_DIR=/tmp/npm-unpack
|
||||
|
||||
echo "--- Packing npm package into a tarball"
|
||||
npm pack
|
||||
|
||||
AUTHELIA_PACKAGE=`ls | grep "authelia-\([0-9]\+.\)\{2\}[0-9]\+.tgz"`
|
||||
echo "--- Authelia package is ${AUTHELIA_PACKAGE}"
|
||||
|
||||
tar -tzvf ${AUTHELIA_PACKAGE}
|
||||
|
||||
echo "--- Copy package into "${NPM_UNPACK_DIR}" to test unpacking"
|
||||
mkdir -p ${NPM_UNPACK_DIR}
|
||||
cp ${AUTHELIA_PACKAGE} ${NPM_UNPACK_DIR}
|
||||
|
||||
pushd ${NPM_UNPACK_DIR}
|
||||
|
||||
echo "--- Test unpacking..."
|
||||
npm install ${AUTHELIA_PACKAGE}
|
||||
|
||||
RET_CODE_INSTALL=$?
|
||||
# echo ${RET_CODE}
|
||||
|
||||
# The binary must start and display the help menu
|
||||
./node_modules/.bin/authelia | grep "No config file has been provided."
|
||||
RET_CODE_RUN=$?
|
||||
|
||||
popd
|
||||
|
||||
if [ "$RET_CODE_INSTALL" != "0" ] || [ "$RET_CODE_RUN" != "0" ]
|
||||
then
|
||||
echo "--- Unpacking failed..."
|
||||
exit 1
|
||||
else
|
||||
echo "+++ Unpacking succeeded"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -39,8 +39,9 @@ async function stop() {
|
|||
console.error('Teardown timed out...');
|
||||
process.exit(1);
|
||||
}, teardown_timeout);
|
||||
console.log('>>> Tearing down environment <<<');
|
||||
|
||||
try {
|
||||
console.log('>>> Tearing down environment <<<');
|
||||
await teardown();
|
||||
clearTimeout(timer);
|
||||
} catch(err) {
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
|
||||
module.exports = {
|
||||
IMAGE_NAME: 'authelia',
|
||||
DOCKERHUB_IMAGE_NAME: 'clems4ever/authelia'
|
||||
}
|
|
@ -14,8 +14,8 @@ class AutheliaServerFromDist implements AutheliaServerInterface {
|
|||
}
|
||||
|
||||
async start() {
|
||||
console.log("Spawn authelia server from dist.");
|
||||
this.serverProcess = ChildProcess.spawn('./scripts/authelia-scripts serve ' + this.configPath, {
|
||||
console.log("Spawn authelia server from dist using config " + this.configPath);
|
||||
this.serverProcess = ChildProcess.spawn('./cmd/authelia-scripts/authelia-scripts serve ' + this.configPath, {
|
||||
shell: true,
|
||||
env: process.env,
|
||||
} as any);
|
||||
|
|
|
@ -30,7 +30,7 @@ export default function(timeout: number = 5000) {
|
|||
await VisitPage(this.driver, "https://admin.example.com:8080/secret.html");
|
||||
|
||||
// the url should be the one from the portal.
|
||||
await VerifyUrlContains(this.driver, "https://login.example.com:8080/#/?rd=https://admin.example.com:8080", timeout);
|
||||
await VerifyUrlContains(this.driver, "https://login.example.com:8080/#/?rd=https://admin.example.com:8080/secret.html", timeout);
|
||||
|
||||
// And the user should end up on the second factor page.
|
||||
await VerifyIsSecondFactorStage(this.driver, timeout);
|
||||
|
|
Loading…
Reference in New Issue
Block a user