Compare commits
5 Commits
d019677fb0
...
d0253e9850
Author | SHA1 | Date |
---|---|---|
Justin Dalrymple | d0253e9850 | |
Ignacio Gómez | 59681181c0 | |
dependabot[bot] | 4668815a2c | |
Justin Dalrymple | 84ac164557 | |
Justin Dalrymple | e90423f7fd |
|
@ -3,7 +3,8 @@ package backends
|
|||
import (
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
|
||||
"github.com/iegomez/mosquitto-go-auth/hashing"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -13,6 +14,7 @@ type localJWTChecker struct {
|
|||
db string
|
||||
postgres Postgres
|
||||
mysql Mysql
|
||||
mongo Mongo
|
||||
userQuery string
|
||||
hasher hashing.HashComparer
|
||||
options tokenOptions
|
||||
|
@ -21,10 +23,11 @@ type localJWTChecker struct {
|
|||
const (
|
||||
mysqlDB = "mysql"
|
||||
postgresDB = "postgres"
|
||||
mongoDB = "mongo"
|
||||
)
|
||||
|
||||
// NewLocalJWTChecker initializes a checker with a local DB.
|
||||
func NewLocalJWTChecker(authOpts map[string]string, logLevel log.Level, hasher hashing.HashComparer, options tokenOptions) (jwtChecker, error) {
|
||||
func NewLocalJWTChecker(authOpts map[string]string, logLevel log.Level, hasher hashing.HashComparer, options tokenOptions) (JWTChecker, error) {
|
||||
checker := &localJWTChecker{
|
||||
hasher: hasher,
|
||||
db: postgresDB,
|
||||
|
@ -35,7 +38,7 @@ func NewLocalJWTChecker(authOpts map[string]string, logLevel log.Level, hasher h
|
|||
localOk := true
|
||||
|
||||
if options.secret == "" {
|
||||
return nil, errors.New("JWT backend error: missing jwt secret")
|
||||
return nil, errors.New("JWT backend error: missing JWT secret")
|
||||
}
|
||||
|
||||
if db, ok := authOpts["jwt_db"]; ok {
|
||||
|
@ -59,21 +62,28 @@ func NewLocalJWTChecker(authOpts map[string]string, logLevel log.Level, hasher h
|
|||
if checker.db == mysqlDB {
|
||||
mysql, err := NewMysql(dbAuthOpts, logLevel, hasher)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("JWT backend error: couldn't create mysql connector for local jwt: %s", err)
|
||||
return nil, errors.Errorf("JWT backend error: couldn't create mysql connector for local JWT: %s", err)
|
||||
}
|
||||
|
||||
checker.mysql = mysql
|
||||
} else if checker.db == mongoDB {
|
||||
mongodb, err := NewMongo(dbAuthOpts, logLevel, hasher)
|
||||
|
||||
return checker, nil
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("JWT backend error: couldn't create mysql connector for local JWT: %s", err)
|
||||
}
|
||||
|
||||
checker.mongo = mongodb
|
||||
} else {
|
||||
postgres, err := NewPostgres(dbAuthOpts, logLevel, hasher)
|
||||
|
||||
checker.postgres = postgres
|
||||
}
|
||||
|
||||
postgres, err := NewPostgres(dbAuthOpts, logLevel, hasher)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("JWT backend error: couldn't create postgres connector for local jwt: %s", err)
|
||||
return nil, errors.Errorf("JWT backend error: couldn't create postgres connector for local JWT: %s", err)
|
||||
}
|
||||
|
||||
checker.postgres = postgres
|
||||
|
||||
return checker, nil
|
||||
}
|
||||
|
||||
|
@ -81,7 +91,7 @@ func (o *localJWTChecker) GetUser(token string) (bool, error) {
|
|||
username, err := getUsernameForToken(o.options, token, o.options.skipUserExpiration)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("jwt local get user error: %s", err)
|
||||
log.Printf("JWT local get user error: %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
@ -92,43 +102,47 @@ func (o *localJWTChecker) GetSuperuser(token string) (bool, error) {
|
|||
username, err := getUsernameForToken(o.options, token, o.options.skipUserExpiration)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("jwt local get superuser error: %s", err)
|
||||
log.Printf("JWT local get superuser error: %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if o.db == mysqlDB {
|
||||
return o.mysql.GetSuperuser(username)
|
||||
} else if o.db == mongoDB {
|
||||
return o.mongo.GetSuperuser(username)
|
||||
} else {
|
||||
return o.postgres.GetSuperuser(username)
|
||||
}
|
||||
|
||||
return o.postgres.GetSuperuser(username)
|
||||
}
|
||||
|
||||
func (o *localJWTChecker) CheckAcl(token, topic, clientid string, acc int32) (bool, error) {
|
||||
username, err := getUsernameForToken(o.options, token, o.options.skipACLExpiration)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("jwt local check acl error: %s", err)
|
||||
log.Printf("JWT local check acl error: %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if o.db == mysqlDB {
|
||||
return o.mysql.CheckAcl(username, topic, clientid, acc)
|
||||
} else if o.db == mongoDB {
|
||||
return o.mongo.CheckAcl(username)
|
||||
} else {
|
||||
return o.postgres.CheckAcl(username)
|
||||
}
|
||||
|
||||
return o.postgres.CheckAcl(username, topic, clientid, acc)
|
||||
}
|
||||
|
||||
func (o *localJWTChecker) Halt() {
|
||||
if o.postgres != (Postgres{}) && o.postgres.DB != nil {
|
||||
err := o.postgres.DB.Close()
|
||||
if err != nil {
|
||||
log.Errorf("JWT cleanup error: %s", err)
|
||||
}
|
||||
} else if o.mysql != (Mysql{}) && o.mysql.DB != nil {
|
||||
err := o.mysql.DB.Close()
|
||||
if err != nil {
|
||||
log.Errorf("JWT cleanup error: %s", err)
|
||||
}
|
||||
} else if o.mongo != (Mongo{}) && o.mongo.Conn != nil {
|
||||
err := o.mongo.Conn.Disconnect(context.TODO())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("JWT cleanup error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,25 +151,36 @@ func (o *localJWTChecker) getLocalUser(username string) (bool, error) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
var count sql.NullInt64
|
||||
var err error
|
||||
var sqlCount sql.NullInt64
|
||||
var count Int64
|
||||
var valid boolean
|
||||
|
||||
if o.db == mysqlDB {
|
||||
err = o.mysql.DB.Get(&count, o.userQuery, username)
|
||||
valid = sqlCount.Valid
|
||||
count = sqlCount.Int64
|
||||
} else if o.db == mongoDB {
|
||||
var uc := o.mongo.Conn.Database(o.mongo.DBName).Collection(o.mongo.UsersCollection)
|
||||
|
||||
count, err := uc.CountDocuments(context.TODO(), bson.M{"username": username})
|
||||
} else {
|
||||
err = o.postgres.DB.Get(&count, o.userQuery, username)
|
||||
}
|
||||
valid = sqlCount.Valid
|
||||
count = sqlCount.Int64
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("local JWT get user error: %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !count.Valid {
|
||||
if !valid {
|
||||
log.Debugf("local JWT get user error: user %s not found", username)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if count.Int64 > 0 {
|
||||
if count > 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -165,9 +190,12 @@ func (o *localJWTChecker) getLocalUser(username string) (bool, error) {
|
|||
func extractOpts(authOpts map[string]string, db string) map[string]string {
|
||||
dbAuthOpts := make(map[string]string)
|
||||
|
||||
dbPrefix := "pg"
|
||||
if db == mysqlDB {
|
||||
dbPrefix = mysqlDB
|
||||
} else if db == mongoDB {
|
||||
dbPrefix = mongoDB
|
||||
} else {
|
||||
dbPrefix := "pg"
|
||||
}
|
||||
|
||||
prefix := "jwt_" + dbPrefix
|
||||
|
|
2
go.mod
2
go.mod
|
@ -42,7 +42,7 @@ require (
|
|||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -222,8 +222,8 @@ google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
|
|||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
|
Loading…
Reference in New Issue