Prepare databases

This commit is contained in:
Kevin Kandlbinder 2023-10-20 16:08:37 +00:00
parent 3beb6eef8a
commit 3ca5db4649
14 changed files with 330 additions and 40 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
/config.yaml
### VisualStudioCode ### ### VisualStudioCode ###
.vscode/* .vscode/*
!.vscode/settings.json !.vscode/settings.json

View file

@ -2,10 +2,16 @@ package cmd
import ( import (
"os" "os"
"time"
"git.1in9.net/raider/wroofauth/internal/logger"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/zap"
) )
var cfgFile string
// rootCmd represents the base command when called without any subcommands // rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "wroofauth", Use: "wroofauth",
@ -31,13 +37,89 @@ func Execute() {
} }
func init() { func init() {
// Here you will define your flags and configuration settings. rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./config.yaml)")
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.wroofauth.yaml)") viper.SetDefault("development", false)
// Cobra also supports local flags, which will only run viper.BindEnv("development", "DEV")
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") logger.StartLogger()
viper.SetDefault("mongo.uri", "mongodb://localhost:27017")
viper.SetDefault("mongo.database", "wroofauth")
viper.SetDefault("mongo.collection.users", "users")
viper.SetDefault("mongo.collection.clients", "clients")
viper.SetDefault("mongo.collection.groups", "groups")
viper.BindEnv("mongo.uri", "MONGO_URI", "MONGODB_URI")
viper.BindEnv("mongo.database", "MONGO_DATABASE", "MONGODB_DATABASE")
viper.SetDefault("redis.addr", "localhost:6379")
viper.SetDefault("redis.username", "")
viper.SetDefault("redis.password", "")
viper.SetDefault("redis.db", 0)
viper.BindEnv("redis.addr", "REDIS_ADDRESS", "REDIS_ADDR")
viper.BindEnv("redis.password", "REDIS_PASSWORD", "REDIS_PASS")
viper.BindEnv("redis.db", "REDIS_DB")
/*viper.SetDefault("http.wyrd_url", "http://localhost:3001")
viper.SetDefault("http.frontend_url", "http://localhost:3000")
viper.BindEnv("http.wyrd_url", "WYRD_URL")
viper.BindEnv("http.frontend_url", "WYRD_FRONTEND_URL")*/
/*viper.SetDefault("crypto.keys", jwk.NewSet())
viper.SetDefault("crypto.keyfile", nil)
viper.SetDefault("crypto.use_key", "")
viper.BindEnv("crypto.keyfile", "WYRD_KEYFILE")*/
viper.SetDefault("totp.issuer", "WroofAuth") // Used for 2fa issuer value
cobra.OnInitialize(loadConfig)
}
func loadConfig() {
if etcdUrl, found := os.LookupEnv("ETCD_URL"); found {
etcdPath, found := os.LookupEnv("ETCD_WROOF_CONFIG")
if !found {
etcdPath = "/config/wroofauth.json"
}
viper.SetConfigType("json")
viper.AddRemoteProvider("etcd3", etcdUrl, etcdPath)
err := viper.ReadRemoteConfig()
if err != nil {
logger.Sugar.Fatal(err)
}
go func() {
for {
time.Sleep(time.Second * 5)
err := viper.WatchRemoteConfig()
if err != nil {
logger.Sugar.Fatal("unable to read remote config: %v", err)
continue
}
}
}()
}
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath(".")
viper.SetConfigName("config")
}
err := viper.ReadInConfig()
if err != nil {
logger.Logger.Fatal("failed to load config", zap.Error(err))
}
logger.StartLogger() // Restart Logger, as we may have changed our loglevel
logger.Sugar.Info("Using config file:", viper.ConfigFileUsed())
} }

View file

@ -1,6 +1,10 @@
package cmd package cmd
import ( import (
"context"
"git.1in9.net/raider/wroofauth/internal/database"
"git.1in9.net/raider/wroofauth/internal/entities"
"git.1in9.net/raider/wroofauth/internal/server" "git.1in9.net/raider/wroofauth/internal/server"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -16,7 +20,17 @@ Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files This application is a tool to generate the needed files
to quickly create a Cobra application.`, to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
ctx := context.Background()
database.MongoConnect(ctx)
database.RedisConnect(ctx)
entities.SetupEntityDatabases()
server.Serve() server.Serve()
database.MongoDisconnect(ctx)
database.RedisDisconnect()
}, },
} }

7
go.mod
View file

@ -4,8 +4,11 @@ go 1.18
require ( require (
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bsm/redislock v0.9.4 // indirect
github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.3 // indirect github.com/golang/snappy v0.0.3 // indirect
@ -19,6 +22,7 @@ require (
github.com/pelletier/go-toml v1.9.4 // indirect github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pquerna/otp v1.4.0 // indirect github.com/pquerna/otp v1.4.0 // indirect
github.com/redis/go-redis/v9 v9.2.1 // indirect
github.com/rs/cors v1.7.0 // indirect github.com/rs/cors v1.7.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@ -37,7 +41,8 @@ require (
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.mongodb.org/mongo-driver v1.12.1 // indirect go.mongodb.org/mongo-driver v1.12.1 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.15.0 // indirect golang.org/x/net v0.15.0 // indirect

13
go.sum
View file

@ -81,6 +81,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= 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/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw=
github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@ -88,9 +90,12 @@ github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1P
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -124,6 +129,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
@ -469,6 +476,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -591,10 +600,14 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

View file

@ -0,0 +1,16 @@
package database
import (
"time"
"github.com/bsm/redislock"
)
var (
Locker *redislock.Client
LockBackoff = redislock.LimitRetry(redislock.LinearBackoff(100*time.Millisecond), 5)
)
func setupLocker() {
Locker = redislock.New(Redis)
}

View file

@ -3,48 +3,53 @@ package database
import ( import (
"context" "context"
"git.1in9.net/raider/wroofauth/internal/logger"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/event"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref" "go.mongodb.org/mongo-driver/mongo/readpref"
"go.uber.org/zap"
) )
var dbClient *mongo.Client var dbClient *mongo.Client
var MongoDatabase *mongo.Database var Mongo *mongo.Database
func MongoConnect(ctx context.Context) {
logger.Logger.Info("establishing connection to mongoDB...")
func Connect() {
cmdMonitor := &event.CommandMonitor{ cmdMonitor := &event.CommandMonitor{
Started: func(_ context.Context, evt *event.CommandStartedEvent) { Started: func(_ context.Context, evt *event.CommandStartedEvent) {
// TODO: Log logger.Logger.Debug("mongoDB command running", zap.String("command", evt.Command.String()))
}, },
} }
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(viper.GetString("mongo.uri")).SetMonitor(cmdMonitor)) client, err := mongo.Connect(ctx, options.Client().ApplyURI(viper.GetString("mongo.uri")).SetMonitor(cmdMonitor))
if err != nil { if err != nil {
// TODO: Log logger.Logger.Fatal("unable to connect to MongoDB", zap.Error(err))
panic(err)
} }
err = client.Ping(context.TODO(), readpref.Nearest()) err = client.Ping(ctx, readpref.Nearest())
if err != nil { if err != nil {
// TODO: Log logger.Logger.Fatal("unable to ping to MongoDB", zap.Error(err))
panic(err)
} }
logger.Logger.Info("mongoDB connection established")
dbClient = client dbClient = client
MongoDatabase = client.Database(viper.GetString("mongo.database")) Mongo = client.Database(viper.GetString("mongo.database"))
//UserCollection = Database.Collection(viper.GetString("mongo.collection.users")) //UserCollection = Database.Collection(viper.GetString("mongo.collection.users"))
//ClientCollection = Database.Collection(viper.GetString("mongo.collection.clients")) //ClientCollection = Database.Collection(viper.GetString("mongo.collection.clients"))
//GroupCollection = Database.Collection(viper.GetString("mongo.collection.groups")) //GroupCollection = Database.Collection(viper.GetString("mongo.collection.groups"))
} }
func Disconnect() { func MongoDisconnect(ctx context.Context) {
err := dbClient.Disconnect(context.TODO()) err := dbClient.Disconnect(ctx)
if err != nil { if err != nil {
// TODO: Log logger.Logger.Warn("failed to gracefully disconnect MongoDB", zap.Error(err))
panic(err)
} }
logger.Logger.Info("mongoDB gracefully disconnected")
} }

View file

@ -0,0 +1,40 @@
package database
import (
"context"
"git.1in9.net/raider/wroofauth/internal/logger"
"github.com/redis/go-redis/v9"
"github.com/spf13/viper"
"go.uber.org/zap"
)
var Redis *redis.Client
func RedisConnect(ctx context.Context) {
logger.Logger.Info("establishing connection to redis...")
Redis = redis.NewClient(&redis.Options{
Addr: viper.GetString("redis.addr"),
Username: viper.GetString("redis.username"),
Password: viper.GetString("redis.password"),
DB: viper.GetInt("redis.db"),
})
err := Redis.Ping(ctx).Err()
if err != nil {
logger.Logger.Fatal("unable to ping to redis", zap.Error(err))
}
setupLocker()
logger.Logger.Info("redis connection established")
}
func RedisDisconnect() {
err := Redis.Close()
if err != nil {
logger.Logger.Warn("failed to gracefully disconnect redis", zap.Error(err))
}
logger.Logger.Info("redis gracefully disconnected")
}

View file

@ -1,8 +1,15 @@
package entities package entities
import "go.mongodb.org/mongo-driver/bson/primitive" import (
"git.1in9.net/raider/wroofauth/internal/entities/user"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Entity interface { type Entity interface {
GetType() string GetType() string
GetID() primitive.ObjectID GetID() primitive.ObjectID
} }
func SetupEntityDatabases() {
user.SetupCollection()
}

View file

@ -1,5 +1,77 @@
package user package user
func GetByIdentification(identification string) (*User, error) { import (
return nil, nil "context"
}
"git.1in9.net/raider/wroofauth/internal/database"
"git.1in9.net/raider/wroofauth/internal/logger"
"github.com/spf13/viper"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var collection *mongo.Collection
func SetupCollection() {
collection = database.Mongo.Collection(viper.GetString("mongo.collection.users"))
}
func (u *User) Persist(ctx context.Context) error {
return Persist(ctx, u)
}
func Persist(ctx context.Context, user *User) error {
if user == nil {
logger.Logger.Panic("trying to persist null-pointer")
}
// TODO: Validate?
upsert := true
_, err := collection.ReplaceOne(ctx, bson.M{"_id": user.ID}, user, &options.ReplaceOptions{Upsert: &upsert})
if err != nil {
return err
}
return nil
}
func GetById(ctx context.Context, id primitive.ObjectID) (*User, error) {
res := collection.FindOne(ctx, bson.M{"_id": id})
if res.Err() != nil {
return nil, res.Err()
}
var user User
err := res.Decode(&user)
if err != nil {
return nil, err
}
return &user, nil
}
func GetByIdentification(ctx context.Context, identification string) (*User, error) {
res := collection.FindOne(ctx, bson.D{
{Key: "$or",
Value: bson.A{
bson.D{{Key: "username", Value: identification}},
bson.D{{Key: "email", Value: identification}},
},
},
})
if res.Err() != nil {
return nil, res.Err()
}
var user User
err := res.Decode(&user)
if err != nil {
return nil, err
}
return &user, nil
}

View file

@ -1,6 +1,7 @@
package user package user
import ( import (
"context"
"crypto/subtle" "crypto/subtle"
"encoding/base64" "encoding/base64"
"errors" "errors"
@ -8,10 +9,12 @@ import (
"strings" "strings"
"time" "time"
"github.com/bsm/redislock"
"github.com/pquerna/otp/totp" "github.com/pquerna/otp/totp"
"github.com/spf13/viper" "github.com/spf13/viper"
"golang.org/x/crypto/argon2" "golang.org/x/crypto/argon2"
"git.1in9.net/raider/wroofauth/internal/database"
"git.1in9.net/raider/wroofauth/internal/parameters" "git.1in9.net/raider/wroofauth/internal/parameters"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
) )
@ -50,6 +53,12 @@ func (u *User) GetID() primitive.ObjectID {
return u.ID return u.ID
} }
func (u *User) Lock(ctx context.Context) (*redislock.Lock, error) {
return database.Locker.Obtain(ctx, u.ID.Hex(), 100*time.Millisecond, &redislock.Options{
RetryStrategy: database.LockBackoff,
})
}
func (u *User) GetFriendlyIdentifier() string { func (u *User) GetFriendlyIdentifier() string {
if u.Username != nil { if u.Username != nil {
return *u.Username return *u.Username

21
internal/logger/logger.go Normal file
View file

@ -0,0 +1,21 @@
package logger
import (
"github.com/spf13/viper"
"go.uber.org/zap"
)
var (
Logger *zap.Logger
Sugar *zap.SugaredLogger
)
func StartLogger() {
Logger, _ = zap.NewProduction()
if viper.GetBool("development") {
Logger, _ = zap.NewDevelopment()
}
Sugar = Logger.Sugar()
}

View file

@ -1,6 +1,7 @@
package machines package machines
import ( import (
"context"
"errors" "errors"
"strings" "strings"
@ -49,7 +50,7 @@ type Session struct {
User *user.User User *user.User
} }
func NewSession() *Session { func NewSession(ctx context.Context) *Session {
return &Session{ return &Session{
State: SessionState_EMPTY, State: SessionState_EMPTY,
AuthenticationMethod: AuthenticationMethod_NONE, AuthenticationMethod: AuthenticationMethod_NONE,
@ -58,7 +59,7 @@ func NewSession() *Session {
} }
// s.Validate checks if the session is in a valid state // s.Validate checks if the session is in a valid state
func (s *Session) Validate() error { func (s *Session) Validate(ctx context.Context) error {
if s.IsAnyAuthenticated() { if s.IsAnyAuthenticated() {
if s.User == nil { if s.User == nil {
// We can only be here if a user is set // We can only be here if a user is set
@ -84,7 +85,7 @@ func (s *Session) IsAnyAuthenticated() bool {
return strings.HasPrefix(string(s.State), "AUTHENTICATED_") return strings.HasPrefix(string(s.State), "AUTHENTICATED_")
} }
func (s *Session) performPreflight() error { func (s *Session) performPreflight(ctx context.Context) error {
// TODO: Do Preflight Checks. // TODO: Do Preflight Checks.
// TODO: Do PASSWORD_EXPIRED check // TODO: Do PASSWORD_EXPIRED check
@ -103,12 +104,12 @@ func (s *Session) performPreflight() error {
return nil return nil
} }
func (s *Session) HandleIdentification(identification string) error { func (s *Session) HandleIdentification(ctx context.Context, identification string) error {
if s.State != SessionState_EMPTY { if s.State != SessionState_EMPTY {
return ErrIllegalStateAction // This step may only run on EMPTY sessions return ErrIllegalStateAction // This step may only run on EMPTY sessions
} }
user, err := user.GetByIdentification(identification) user, err := user.GetByIdentification(ctx, identification)
if err != nil { if err != nil {
return err return err
} }
@ -118,15 +119,15 @@ func (s *Session) HandleIdentification(identification string) error {
} }
s.User = user s.User = user
//TODO: Check for SAML //TODO: Check for SAML
s.State = SessionState_UNAUTHENTICATED s.State = SessionState_UNAUTHENTICATED
return nil return nil
} }
func (s *Session) HandlePassword(password string) error { func (s *Session) HandlePassword(ctx context.Context, password string) error {
if s.State != SessionState_UNAUTHENTICATED { if s.State != SessionState_UNAUTHENTICATED {
return ErrIllegalStateAction // This step may only run on UNAUTHENTICATED sessions return ErrIllegalStateAction // This step may only run on UNAUTHENTICATED sessions
} }
@ -142,7 +143,7 @@ func (s *Session) HandlePassword(password string) error {
if !s.User.Needs2FA() { if !s.User.Needs2FA() {
// No 2fa, jump to AUTHENTICATED_PENDING for preflight // No 2fa, jump to AUTHENTICATED_PENDING for preflight
s.State = SessionState_AUTHENTICATED_PENDING s.State = SessionState_AUTHENTICATED_PENDING
return s.performPreflight() return s.performPreflight(ctx)
} }
s.State = SessionState_AWAITING_FACTOR s.State = SessionState_AWAITING_FACTOR
@ -151,7 +152,7 @@ func (s *Session) HandlePassword(password string) error {
// TODO: Passkey action // TODO: Passkey action
func (s *Session) HandleTOTP(otp string) error { func (s *Session) HandleTOTP(ctx context.Context, otp string) error {
if s.State != SessionState_AWAITING_FACTOR { if s.State != SessionState_AWAITING_FACTOR {
return ErrIllegalStateAction return ErrIllegalStateAction
} }
@ -166,10 +167,10 @@ func (s *Session) HandleTOTP(otp string) error {
// Good to go for preflight. // Good to go for preflight.
s.State = SessionState_AUTHENTICATED_PENDING s.State = SessionState_AUTHENTICATED_PENDING
return s.performPreflight() return s.performPreflight(ctx)
} }
func (s *Session) HandleLock() error { func (s *Session) HandleLock(ctx context.Context) error {
if !s.IsAnyAuthenticated() { if !s.IsAnyAuthenticated() {
return ErrIllegalStateAction return ErrIllegalStateAction
} }
@ -177,7 +178,7 @@ func (s *Session) HandleLock() error {
return nil return nil
} }
func (s *Session) HandleLogout() error { func (s *Session) HandleLogout(ctx context.Context) error {
if !s.IsAnyAuthenticated() { if !s.IsAnyAuthenticated() {
return ErrIllegalStateAction return ErrIllegalStateAction
} }
@ -185,7 +186,7 @@ func (s *Session) HandleLogout() error {
return nil return nil
} }
func (s *Session) Destroy() error { func (s *Session) Destroy(ctx context.Context) error {
// TODO: Destroy Session // TODO: Destroy Session
return nil return nil
} }

View file

@ -1,4 +1,7 @@
package server package server
import "log"
func Serve() { func Serve() {
log.Println("hello")
} }