224 lines
6.7 KiB
Go
224 lines
6.7 KiB
Go
|
package common
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"database/sql"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"runtime"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"git.lehouerou.net/laurent/sorare"
|
||
|
"git.lehouerou.net/laurent/sorare/graphql"
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/rs/zerolog"
|
||
|
"github.com/rs/zerolog/log"
|
||
|
"github.com/spf13/cobra"
|
||
|
"github.com/spf13/viper"
|
||
|
"github.com/uptrace/bun"
|
||
|
"github.com/uptrace/bun/dialect/pgdialect"
|
||
|
"github.com/uptrace/bun/driver/pgdriver"
|
||
|
"github.com/uptrace/bun/extra/bundebug"
|
||
|
)
|
||
|
|
||
|
func InitParams(cmd *cobra.Command) {
|
||
|
cobra.OnInitialize(InitConfig)
|
||
|
|
||
|
viper.AutomaticEnv()
|
||
|
viper.SetEnvPrefix("sorare")
|
||
|
|
||
|
cmd.PersistentFlags().BoolP("verbose", "v", false, "Verbose output")
|
||
|
_ = viper.BindPFlag("verbose", cmd.PersistentFlags().Lookup("verbose"))
|
||
|
viper.SetDefault("verbose", false)
|
||
|
|
||
|
cmd.PersistentFlags().String("jwttoken", "", "Sorare JWT Token")
|
||
|
_ = viper.BindPFlag("jwttoken", cmd.PersistentFlags().Lookup("jwttoken"))
|
||
|
viper.SetDefault("jwttoken", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("jwtaudience", "", "Sorare JWT Audience")
|
||
|
_ = viper.BindPFlag("jwtaudience", cmd.PersistentFlags().Lookup("jwtaudience"))
|
||
|
viper.SetDefault("jwtaudience", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("email", "", "Sorare Email")
|
||
|
_ = viper.BindPFlag("email", cmd.PersistentFlags().Lookup("email"))
|
||
|
viper.SetDefault("email", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("password", "", "Sorare Password")
|
||
|
_ = viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password"))
|
||
|
viper.SetDefault("password", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("otp", "", "Sorare OTP")
|
||
|
_ = viper.BindPFlag("otp", cmd.PersistentFlags().Lookup("otp"))
|
||
|
viper.SetDefault("otp", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("dbhost", "", "Database Host")
|
||
|
_ = viper.BindPFlag("dbhost", cmd.PersistentFlags().Lookup("dbhost"))
|
||
|
viper.SetDefault("dbhost", "192.168.1.250")
|
||
|
|
||
|
cmd.PersistentFlags().String("dbport", "", "Database Port")
|
||
|
_ = viper.BindPFlag("dbport", cmd.PersistentFlags().Lookup("dbport"))
|
||
|
viper.SetDefault("dbport", "5436")
|
||
|
|
||
|
cmd.PersistentFlags().String("dbuser", "", "Database User")
|
||
|
_ = viper.BindPFlag("dbuser", cmd.PersistentFlags().Lookup("dbuser"))
|
||
|
viper.SetDefault("dbuser", "sorare")
|
||
|
|
||
|
cmd.PersistentFlags().String("dbpass", "", "Database Password")
|
||
|
_ = viper.BindPFlag("dbpass", cmd.PersistentFlags().Lookup("dbpass"))
|
||
|
viper.SetDefault("dbpass", "sorare")
|
||
|
|
||
|
cmd.PersistentFlags().String("dbname", "", "Database Name")
|
||
|
_ = viper.BindPFlag("dbname", cmd.PersistentFlags().Lookup("dbname"))
|
||
|
viper.SetDefault("dbname", "sorare")
|
||
|
|
||
|
cmd.PersistentFlags().String("privatekey", "", "Sorare Private Key")
|
||
|
_ = viper.BindPFlag("privatekey", cmd.PersistentFlags().Lookup("privatekey"))
|
||
|
viper.SetDefault("privatekey", "")
|
||
|
|
||
|
cmd.PersistentFlags().Bool("tracedb", false, "Trace Database Queries")
|
||
|
_ = viper.BindPFlag("tracedb", cmd.PersistentFlags().Lookup("tracedb"))
|
||
|
viper.SetDefault("tracedb", false)
|
||
|
|
||
|
cmd.PersistentFlags().Bool("tracesorare", false, "Trace Sorare API Calls")
|
||
|
_ = viper.BindPFlag("tracesorare", cmd.PersistentFlags().Lookup("tracesorare"))
|
||
|
viper.SetDefault("tracesorare", false)
|
||
|
|
||
|
cmd.PersistentFlags().String("cryptkey", "", "Crypt Key")
|
||
|
_ = viper.BindPFlag("cryptkey", cmd.PersistentFlags().Lookup("cryptkey"))
|
||
|
viper.SetDefault("cryptkey", "")
|
||
|
|
||
|
cmd.PersistentFlags().String("jwtkey", "", "JWT Key")
|
||
|
_ = viper.BindPFlag("jwtkey", cmd.PersistentFlags().Lookup("jwtkey"))
|
||
|
viper.SetDefault("jwtkey", "")
|
||
|
}
|
||
|
|
||
|
func InitConfig() {
|
||
|
log.Logger = zerolog.New(zerolog.ConsoleWriter{
|
||
|
Out: os.Stdout,
|
||
|
|
||
|
TimeFormat: "2006-01-02 | 15:04:05.000",
|
||
|
FormatLevel: func(i interface{}) string {
|
||
|
return strings.ToUpper(fmt.Sprintf("| %-6s|", i))
|
||
|
},
|
||
|
FormatFieldName: func(i interface{}) string {
|
||
|
return fmt.Sprintf("%s:", i)
|
||
|
},
|
||
|
FormatFieldValue: func(i interface{}) string {
|
||
|
return strings.ToUpper(fmt.Sprintf("%s", i))
|
||
|
},
|
||
|
}).With().Timestamp().Logger()
|
||
|
zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMicro
|
||
|
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||
|
|
||
|
verbose := viper.GetBool("verbose")
|
||
|
if verbose {
|
||
|
log.Info().Msg("Verbose output enabled")
|
||
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func InitSorare(ctx context.Context) (*sorare.Sorare, error) {
|
||
|
audience := viper.GetString("jwtaudience")
|
||
|
if audience == "" {
|
||
|
return nil, errors.New("jwtaudience is required")
|
||
|
}
|
||
|
|
||
|
jwttoken := viper.GetString("jwttoken")
|
||
|
s := sorare.New()
|
||
|
tracesorare := viper.GetBool("tracesorare")
|
||
|
if tracesorare {
|
||
|
s.Debug()
|
||
|
}
|
||
|
if jwttoken != "" {
|
||
|
s.SetJWTToken(graphql.JwtToken{
|
||
|
Token: jwttoken,
|
||
|
ExpiredAt: time.Time{},
|
||
|
}, audience)
|
||
|
} else {
|
||
|
email := viper.GetString("email")
|
||
|
password := viper.GetString("password")
|
||
|
otp := viper.GetString("otp")
|
||
|
err := s.Authenticate(ctx, email, password, audience, otp)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "authenticating to sorare")
|
||
|
}
|
||
|
log.Info().Msgf("authentication to sorare successful. new token: %s", s.GetCurrentToken().Token)
|
||
|
}
|
||
|
cu, err := s.Users.CurrentUser.Get(ctx, graphql.EmptyParams{})
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "getting current user")
|
||
|
}
|
||
|
log.Info().Msgf("authenticated on Sorare as %s (%s)", cu.Nickname, cu.Profile.ClubName)
|
||
|
return s, nil
|
||
|
}
|
||
|
|
||
|
func InitDb() (*bun.DB, error) {
|
||
|
host := viper.GetString("dbhost")
|
||
|
if host == "" {
|
||
|
return nil, errors.New("dbhost is required")
|
||
|
}
|
||
|
port := viper.GetString("dbport")
|
||
|
if port == "" {
|
||
|
return nil, errors.New("dbport is required")
|
||
|
}
|
||
|
user := viper.GetString("dbuser")
|
||
|
if user == "" {
|
||
|
return nil, errors.New("dbuser is required")
|
||
|
}
|
||
|
password := viper.GetString("dbpass")
|
||
|
if password == "" {
|
||
|
return nil, errors.New("dbpass is required")
|
||
|
}
|
||
|
dbname := viper.GetString("dbname")
|
||
|
if dbname == "" {
|
||
|
return nil, errors.New("dbname is required")
|
||
|
}
|
||
|
|
||
|
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(fmt.Sprintf(
|
||
|
"postgres://%s:%s@%s:%s/%s?sslmode=disable",
|
||
|
user,
|
||
|
password,
|
||
|
host,
|
||
|
port,
|
||
|
dbname,
|
||
|
))))
|
||
|
maxOpenConns := 4 * runtime.GOMAXPROCS(0)
|
||
|
sqldb.SetMaxOpenConns(maxOpenConns)
|
||
|
sqldb.SetMaxIdleConns(maxOpenConns)
|
||
|
db := bun.NewDB(sqldb, pgdialect.New())
|
||
|
|
||
|
tracedb := viper.GetBool("tracedb")
|
||
|
if tracedb {
|
||
|
log.Debug().Msgf("Enabling database query tracing")
|
||
|
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
|
||
|
}
|
||
|
|
||
|
// Test the connection
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
|
defer cancel()
|
||
|
if err := db.DB.PingContext(ctx); err != nil {
|
||
|
return nil, errors.Wrap(err, "pinging database")
|
||
|
}
|
||
|
|
||
|
log.Info().Msgf("connected to database %s@%s:%s/%s", user, host, port, dbname)
|
||
|
|
||
|
return db, nil
|
||
|
}
|
||
|
|
||
|
func CmdPreRunE(cmd *cobra.Command, _ []string) error {
|
||
|
s, err := InitSorare(cmd.Context())
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "initializing sorare client")
|
||
|
}
|
||
|
cmd.SetContext(context.WithValue(cmd.Context(), "sorare", s))
|
||
|
|
||
|
db, err := InitDb()
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "initializing database")
|
||
|
}
|
||
|
cmd.SetContext(context.WithValue(cmd.Context(), "db", db))
|
||
|
|
||
|
return nil
|
||
|
}
|