Commit ca533f7d authored by Sonja Happ's avatar Sonja Happ
Browse files

Merge branch 'jwt-config' into 'master'

Make JWT configurable

See merge request !24
parents 71e69688 ebe9d230
......@@ -30,57 +30,61 @@ import (
)
// Global configuration
var GolbalConfig *config.Config = nil
var GlobalConfig *config.Config = nil
func InitConfig() error {
if GolbalConfig != nil {
if GlobalConfig != nil {
return nil
}
var (
dbHost = flag.String("db-host", "/var/run/postgresql", "Host of the PostgreSQL database (default is /var/run/postgresql for localhost DB on Ubuntu systems)")
dbName = flag.String("db-name", "villasdb", "Name of the database to use (default is villasdb)")
dbUser = flag.String("db-user", "", "Username of database connection (default is <empty>)")
dbPass = flag.String("db-pass", "", "Password of database connection (default is <empty>)")
dbSSLMode = flag.String("db-ssl-mode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production
amqpHost = flag.String("amqp-host", "", "If set, use this as host for AMQP broker (default is disabled)")
amqpUser = flag.String("amqp-user", "", "Username for AMQP broker")
amqpPass = flag.String("amqp-pass", "", "Password for AMQP broker")
configFile = flag.String("config", "", "Path to YAML configuration file")
mode = flag.String("mode", "release", "Select debug/release/test mode (default is release)")
port = flag.String("port", "4000", "Port of the backend (default is 4000)")
baseHost = flag.String("base-host", "localhost:4000", "The host at which the backend is hosted (default: localhost)")
basePath = flag.String("base-path", "/api/v2", "The path at which the API routes are located (default /api/v2)")
adminUser = flag.String("admin-user", "", "Initial admin username")
adminPass = flag.String("admin-pass", "", "Initial admin password")
adminMail = flag.String("admin-mail", "", "Initial admin mail address")
s3Bucket = flag.String("s3-bucket", "", "S3 Bucket for uploading files")
s3Endpoint = flag.String("s3-endpoint", "", "Endpoint of S3 API for file uploads")
s3Region = flag.String("s3-region", "default", "S3 Region for file uploads")
s3NoSSL = flag.Bool("s3-nossl", false, "Use encrypted connections to the S3 API")
s3PathStyle = flag.Bool("s3-pathstyle", false, "Use path-style S3 API")
dbHost = flag.String("db-host", "/var/run/postgresql", "Host of the PostgreSQL database (default is /var/run/postgresql for localhost DB on Ubuntu systems)")
dbName = flag.String("db-name", "villasdb", "Name of the database to use (default is villasdb)")
dbUser = flag.String("db-user", "", "Username of database connection (default is <empty>)")
dbPass = flag.String("db-pass", "", "Password of database connection (default is <empty>)")
dbSSLMode = flag.String("db-ssl-mode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production
amqpHost = flag.String("amqp-host", "", "If set, use this as host for AMQP broker (default is disabled)")
amqpUser = flag.String("amqp-user", "", "Username for AMQP broker")
amqpPass = flag.String("amqp-pass", "", "Password for AMQP broker")
configFile = flag.String("config", "", "Path to YAML configuration file")
mode = flag.String("mode", "release", "Select debug/release/test mode (default is release)")
port = flag.String("port", "4000", "Port of the backend (default is 4000)")
baseHost = flag.String("base-host", "localhost:4000", "The host at which the backend is hosted (default: localhost)")
basePath = flag.String("base-path", "/api/v2", "The path at which the API routes are located (default /api/v2)")
adminUser = flag.String("admin-user", "", "Initial admin username")
adminPass = flag.String("admin-pass", "", "Initial admin password")
adminMail = flag.String("admin-mail", "", "Initial admin mail address")
s3Bucket = flag.String("s3-bucket", "", "S3 Bucket for uploading files")
s3Endpoint = flag.String("s3-endpoint", "", "Endpoint of S3 API for file uploads")
s3Region = flag.String("s3-region", "default", "S3 Region for file uploads")
s3NoSSL = flag.Bool("s3-nossl", false, "Use encrypted connections to the S3 API")
s3PathStyle = flag.Bool("s3-pathstyle", false, "Use path-style S3 API")
jwtSecret = flag.String("jwt-secret", "This should NOT be here!!@33$8&", "The JSON Web Token secret")
jwtExpiresAfter = flag.String("jwt-expires-after", "168h" /* 1 week */, "The time after which the JSON Web Token expires")
)
flag.Parse()
static := map[string]string{
"db.host": *dbHost,
"db.name": *dbName,
"db.user": *dbUser,
"db.pass": *dbPass,
"db.ssl": *dbSSLMode,
"amqp.host": *amqpHost,
"amqp.user": *amqpUser,
"amqp.pass": *amqpPass,
"mode": *mode,
"port": *port,
"base.host": *baseHost,
"base.path": *basePath,
"admin.user": *adminUser,
"admin.pass": *adminPass,
"admin.mail": *adminMail,
"s3.bucket": *s3Bucket,
"s3.endpoint": *s3Endpoint,
"s3.region": *s3Region,
"db.host": *dbHost,
"db.name": *dbName,
"db.user": *dbUser,
"db.pass": *dbPass,
"db.ssl": *dbSSLMode,
"amqp.host": *amqpHost,
"amqp.user": *amqpUser,
"amqp.pass": *amqpPass,
"mode": *mode,
"port": *port,
"base.host": *baseHost,
"base.path": *basePath,
"admin.user": *adminUser,
"admin.pass": *adminPass,
"admin.mail": *adminMail,
"s3.bucket": *s3Bucket,
"s3.endpoint": *s3Endpoint,
"s3.region": *s3Region,
"jwt.secret": *jwtSecret,
"jwt.expires-after": *jwtExpiresAfter,
}
if *s3NoSSL == true {
......@@ -96,51 +100,53 @@ func InitConfig() error {
}
mappings := map[string]string{
"DB_HOST": "db.host",
"DB_NAME": "db.name",
"DB_USER": "db.user",
"DB_PASS": "db.pass",
"DB_SSLMODE": "db.ssl",
"AMQP_HOST": "amqp.host",
"AMQP_USER": "amqp.user",
"AMQP_PASS": "amqp.pass",
"BASE_HOST": "base.host",
"BASE_PATH": "base.path",
"MODE": "mode",
"PORT": "port",
"ADMIN_USER": "admin.user",
"ADMIN_PASS": "admin.pass",
"ADMIN_MAIL": "admin.mail",
"S3_BUCKET": "s3.bucket",
"S3_ENDPOINT": "s3.endpoint",
"S3_REGION": "s3.region",
"S3_NOSSL": "s3.nossl",
"S3_PATHSTYLE": "s3.pathstyle",
"DB_HOST": "db.host",
"DB_NAME": "db.name",
"DB_USER": "db.user",
"DB_PASS": "db.pass",
"DB_SSLMODE": "db.ssl",
"AMQP_HOST": "amqp.host",
"AMQP_USER": "amqp.user",
"AMQP_PASS": "amqp.pass",
"BASE_HOST": "base.host",
"BASE_PATH": "base.path",
"MODE": "mode",
"PORT": "port",
"ADMIN_USER": "admin.user",
"ADMIN_PASS": "admin.pass",
"ADMIN_MAIL": "admin.mail",
"S3_BUCKET": "s3.bucket",
"S3_ENDPOINT": "s3.endpoint",
"S3_REGION": "s3.region",
"S3_NOSSL": "s3.nossl",
"S3_PATHSTYLE": "s3.pathstyle",
"JWT_SECRET": "jwt.secret",
"JWT_EXPIRES_AFTER": "jwt.expires-after",
}
defaults := config.NewStatic(static)
env := config.NewEnvironment(mappings)
if _, err := os.Stat(*configFile); os.IsNotExist(err) {
GolbalConfig = config.NewConfig([]config.Provider{defaults, env})
GlobalConfig = config.NewConfig([]config.Provider{defaults, env})
} else {
yamlFile := config.NewYAMLFile(*configFile)
GolbalConfig = config.NewConfig([]config.Provider{defaults, yamlFile, env})
GlobalConfig = config.NewConfig([]config.Provider{defaults, yamlFile, env})
}
err := GolbalConfig.Load()
err := GlobalConfig.Load()
if err != nil {
log.Fatal("failed to parse config")
return err
}
m, err := GolbalConfig.String("mode")
m, err := GlobalConfig.String("mode")
if err != nil {
return err
}
if m != "test" {
settings, _ := GolbalConfig.Settings()
settings, _ := GlobalConfig.Settings()
log.Print("All settings:")
for key, val := range settings {
// TODO password settings should be excluded!
......@@ -159,31 +165,31 @@ func ConfigureBackend() (string, string, string, string, string, string, string,
return "", "", "", "", "", "", "", err
}
mode, err := GolbalConfig.String("mode")
mode, err := GlobalConfig.String("mode")
if err != nil {
log.Printf("Error reading mode from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
baseHost, err := GolbalConfig.String("base.host")
baseHost, err := GlobalConfig.String("base.host")
if err != nil {
log.Printf("Error reading base.host from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
basePath, err := GolbalConfig.String("base.path")
basePath, err := GlobalConfig.String("base.path")
if err != nil {
log.Printf("Error reading base.path from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
port, err := GolbalConfig.String("port")
port, err := GlobalConfig.String("port")
if err != nil {
log.Printf("Error reading port from global configuration: %v, aborting.", err.Error())
return "", "", "", "", "", "", "", err
}
AMQPhost, _ := GolbalConfig.String("amqp.host")
AMQPuser, _ := GolbalConfig.String("amqp.user")
AMQPpass, _ := GolbalConfig.String("amqp.pass")
AMQPhost, _ := GlobalConfig.String("amqp.host")
AMQPuser, _ := GlobalConfig.String("amqp.user")
AMQPpass, _ := GlobalConfig.String("amqp.pass")
return mode, baseHost, basePath, port, AMQPhost, AMQPuser, AMQPpass, nil
}
......@@ -23,10 +23,11 @@ package database
import (
"fmt"
"github.com/zpatrick/go-config"
"os"
"testing"
"github.com/zpatrick/go-config"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"github.com/stretchr/testify/assert"
)
......@@ -52,33 +53,33 @@ func TestInitDB(t *testing.T) {
err = InitDB(ownconfig)
assert.Error(t, err)
dbname, err := configuration.GolbalConfig.String("db.name")
dbname, err := configuration.GlobalConfig.String("db.name")
assert.NoError(t, err)
static["db.name"] = dbname
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbhost, err := configuration.GolbalConfig.String("db.host")
dbhost, err := configuration.GlobalConfig.String("db.host")
assert.NoError(t, err)
static["db.host"] = dbhost
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbuser, err := configuration.GolbalConfig.String("db.user")
dbuser, err := configuration.GlobalConfig.String("db.user")
static["db.user"] = dbuser
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbpass, err := configuration.GolbalConfig.String("db.pass")
dbpass, err := configuration.GlobalConfig.String("db.pass")
static["db.pass"] = dbpass
ownconfig = config.NewConfig([]config.Provider{defaults, env})
err = InitDB(ownconfig)
assert.Error(t, err)
dbssl, err := configuration.GolbalConfig.String("db.ssl")
dbssl, err := configuration.GlobalConfig.String("db.ssl")
assert.NoError(t, err)
static["db.ssl"] = dbssl
ownconfig = config.NewConfig([]config.Provider{defaults, env})
......
......@@ -23,9 +23,10 @@ package helper
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"net/http"
)
func DBError(c *gin.Context, err error) bool {
......@@ -70,7 +71,7 @@ func UnauthorizedError(c *gin.Context, err string) {
func UnauthorizedAbort(c *gin.Context, err string) {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
"succes": false,
"success": false,
"message": fmt.Sprintf("%v", err),
})
}
......
......@@ -23,17 +23,18 @@ package component_configuration
import (
"fmt"
"os"
"testing"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
var router *gin.Engine
......@@ -146,7 +147,7 @@ func TestMain(m *testing.M) {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
if err != nil {
panic(m)
}
......
......@@ -23,6 +23,10 @@ package dashboard
import (
"fmt"
"log"
"os"
"testing"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
......@@ -31,9 +35,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/stretchr/testify/assert"
"log"
"os"
"testing"
)
var router *gin.Engine
......@@ -80,7 +81,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
if err != nil {
panic(m)
}
......
......@@ -98,7 +98,7 @@ func (f *File) Register(fileHeader *multipart.FileHeader, scenarioID uint) error
}
defer fileContent.Close()
bucket, err := configuration.GolbalConfig.String("s3.bucket")
bucket, err := configuration.GlobalConfig.String("s3.bucket")
if bucket == "" {
f.FileData, err = ioutil.ReadAll(fileContent)
f.Key = ""
......@@ -157,7 +157,7 @@ func (f *File) update(fileHeader *multipart.FileHeader) error {
}
defer fileContent.Close()
bucket, err := configuration.GolbalConfig.String("s3.bucket")
bucket, err := configuration.GlobalConfig.String("s3.bucket")
if bucket == "" {
f.FileData, err = ioutil.ReadAll(fileContent)
f.Key = ""
......
......@@ -40,7 +40,7 @@ var s3Session *session.Session = nil
func getS3Session() (*session.Session, string, error) {
bucket, err := configuration.GolbalConfig.String("s3.bucket")
bucket, err := configuration.GlobalConfig.String("s3.bucket")
if err != nil || bucket == "" {
return nil, "", fmt.Errorf("no S3 bucket configured: %s", err)
}
......@@ -57,10 +57,10 @@ func getS3Session() (*session.Session, string, error) {
}
func createS3Session() (*session.Session, error) {
endpoint, err := configuration.GolbalConfig.String("s3.endpoint")
region, err := configuration.GolbalConfig.String("s3.region")
pathStyle, err := configuration.GolbalConfig.Bool("s3.pathstyle")
nossl, err := configuration.GolbalConfig.Bool("s3.nossl")
endpoint, err := configuration.GlobalConfig.String("s3.endpoint")
region, err := configuration.GlobalConfig.String("s3.region")
pathStyle, err := configuration.GlobalConfig.Bool("s3.pathstyle")
nossl, err := configuration.GlobalConfig.Bool("s3.nossl")
sess, err := session.NewSession(
&aws.Config{
......
......@@ -24,6 +24,14 @@ package file
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"testing"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
......@@ -32,13 +40,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/stretchr/testify/assert"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"testing"
)
var router *gin.Engine
......@@ -83,7 +84,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
if err != nil {
panic(m)
}
......
......@@ -22,14 +22,15 @@
package healthz
import (
"log"
"net/http"
"strings"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
"github.com/gin-gonic/gin"
"log"
"net/http"
"strings"
)
func RegisterHealthzEndpoint(r *gin.RouterGroup) {
......@@ -55,7 +56,7 @@ func getHealth(c *gin.Context) {
}
// check if connection to AMQP broker is alive if backend was started with AMQP client
url, err := configuration.GolbalConfig.String("amqp.host")
url, err := configuration.GlobalConfig.String("amqp.host")
if err != nil && strings.Contains(err.Error(), "Required setting 'amqp.host' not set") {
c.JSON(http.StatusOK, gin.H{})
return
......
......@@ -22,15 +22,16 @@
package healthz
import (
"log"
"net/http"
"testing"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
infrastructure_component "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"log"
"net/http"
"testing"
)
var router *gin.Engine
......@@ -40,7 +41,7 @@ func TestHealthz(t *testing.T) {
assert.NoError(t, err)
// connect DB
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
assert.NoError(t, err)
defer database.DBpool.Close()
......@@ -58,7 +59,7 @@ func TestHealthz(t *testing.T) {
assert.Equalf(t, 500, code, "Response body: \n%v\n", resp)
// reconnect DB
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
assert.NoError(t, err)
defer database.DBpool.Close()
......@@ -68,11 +69,11 @@ func TestHealthz(t *testing.T) {
assert.Equalf(t, 500, code, "Response body: \n%v\n", resp)
// connect AMQP client (make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set via command line parameters)
host, err := configuration.GolbalConfig.String("amqp.host")
host, err := configuration.GlobalConfig.String("amqp.host")
assert.NoError(t, err)
user, err := configuration.GolbalConfig.String("amqp.user")
user, err := configuration.GlobalConfig.String("amqp.user")
assert.NoError(t, err)
pass, err := configuration.GolbalConfig.String("amqp.pass")
pass, err := configuration.GlobalConfig.String("amqp.pass")
assert.NoError(t, err)
amqpURI := "amqp://" + user + ":" + pass + "@" + host
......
......@@ -24,15 +24,16 @@ package infrastructure_component
import (
"encoding/json"
"fmt"
"os"
"testing"
"time"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
component_configuration "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
"github.com/jinzhu/gorm/dialects/postgres"
"github.com/streadway/amqp"
"github.com/stretchr/testify/assert"
"os"
"testing"
"time"
"github.com/gin-gonic/gin"
......@@ -94,7 +95,7 @@ func TestMain(m *testing.M) {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
if err != nil {
panic(m)
}
......@@ -126,9 +127,9 @@ func TestAddICAsAdmin(t *testing.T) {
// connect AMQP client
// Make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set
host, err := configuration.GolbalConfig.String("amqp.host")
user, err := configuration.GolbalConfig.String("amqp.user")
pass, err := configuration.GolbalConfig.String("amqp.pass")
host, err := configuration.GlobalConfig.String("amqp.host")
user, err := configuration.GlobalConfig.String("amqp.user")
pass, err := configuration.GlobalConfig.String("amqp.pass")
amqpURI := "amqp://" + user + ":" + pass + "@" + host
// AMQP Connection startup is tested here
......
......@@ -42,7 +42,7 @@ func TestMain(m *testing.M) {
panic(m)
}
err = database.InitDB(configuration.GolbalConfig)
err = database.InitDB(configuration.GlobalConfig)
if err != nil {
panic(m)
}
......@@ -51,9 +51,9 @@ func TestMain(m *testing.M) {
router = gin.Default()
// connect AMQP client (make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set via command line parameters)
host, err := configuration.GolbalConfig.String("amqp.host")
user, err := configuration.GolbalConfig.String("amqp.user")
pass, err := configuration.GolbalConfig.String("amqp.pass")
host, err := configuration.GlobalConfig.String("amqp.host")
user, err := configuration.GlobalConfig.String("amqp.user")
pass, err := configuration.GlobalConfig.String("amqp.pass")
amqpURI := "amqp://" + user + ":" + pass + "@" + host
......@@ -76,6 +76,6 @@ func TestAddTestData(t *testing.T) {
panic(t)
}
resp, err := AddTestData(configuration.GolbalConfig, router)
resp, err := AddTestData(configuration.GlobalConfig, router)
assert.NoError(t, err, "Response body: %v", resp)
}
......@@ -26,6 +26,14 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"testing"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
......@@ -35,13 +43,6 @@ import (
"github.com/gin-gonic/gin"