Prepare databases
This commit is contained in:
parent
3beb6eef8a
commit
3ca5db4649
14 changed files with 330 additions and 40 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
|
/config.yaml
|
||||||
|
|
||||||
### VisualStudioCode ###
|
### VisualStudioCode ###
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
|
|
96
cmd/root.go
96
cmd/root.go
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
14
cmd/serve.go
14
cmd/serve.go
|
@ -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
7
go.mod
|
@ -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
13
go.sum
|
@ -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=
|
||||||
|
|
16
internal/database/locker.go
Normal file
16
internal/database/locker.go
Normal 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)
|
||||||
|
}
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
40
internal/database/redis.go
Normal file
40
internal/database/redis.go
Normal 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")
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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
21
internal/logger/logger.go
Normal 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()
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -126,7 +127,7 @@ func (s *Session) HandleIdentification(identification string) error {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
func Serve() {
|
func Serve() {
|
||||||
|
log.Println("hello")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue