150 lines
3.3 KiB
Go
150 lines
3.3 KiB
Go
package backends
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/iegomez/mosquitto-go-auth/backends/js"
|
|
"github.com/pkg/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type Javascript struct {
|
|
stackDepthLimit int
|
|
msMaxDuration int64
|
|
|
|
userScript string
|
|
superuserScript string
|
|
aclScript string
|
|
|
|
runner *js.Runner
|
|
}
|
|
|
|
func NewJavascript(authOpts map[string]string, logLevel log.Level) (*Javascript, error) {
|
|
|
|
log.SetLevel(logLevel)
|
|
|
|
javascript := &Javascript{
|
|
stackDepthLimit: js.DefaultStackDepthLimit,
|
|
msMaxDuration: js.DefaultMsMaxDuration,
|
|
}
|
|
|
|
jsOk := true
|
|
missingOptions := ""
|
|
|
|
if stackLimit, ok := authOpts["js_stack_depth_limit"]; ok {
|
|
limit, err := strconv.ParseInt(stackLimit, 10, 64)
|
|
if err != nil {
|
|
log.Errorf("invalid stack depth limit %s, defaulting to %d", stackLimit, js.DefaultStackDepthLimit)
|
|
} else {
|
|
javascript.stackDepthLimit = int(limit)
|
|
}
|
|
}
|
|
|
|
if maxDuration, ok := authOpts["js_ms_max_duration"]; ok {
|
|
duration, err := strconv.ParseInt(maxDuration, 10, 64)
|
|
if err != nil {
|
|
log.Errorf("invalid stack depth limit %s, defaulting to %d", maxDuration, js.DefaultMsMaxDuration)
|
|
} else {
|
|
javascript.msMaxDuration = duration
|
|
}
|
|
}
|
|
|
|
if userScriptPath, ok := authOpts["js_user_script_path"]; ok {
|
|
script, err := js.LoadScript(userScriptPath)
|
|
if err != nil {
|
|
return javascript, err
|
|
}
|
|
|
|
javascript.userScript = script
|
|
} else {
|
|
jsOk = false
|
|
missingOptions += " js_user_script_path"
|
|
}
|
|
|
|
if superuserScriptPath, ok := authOpts["js_superuser_script_path"]; ok {
|
|
script, err := js.LoadScript(superuserScriptPath)
|
|
if err != nil {
|
|
return javascript, err
|
|
}
|
|
|
|
javascript.superuserScript = script
|
|
} else {
|
|
jsOk = false
|
|
missingOptions += " js_superuser_script_path"
|
|
}
|
|
|
|
if aclScriptPath, ok := authOpts["js_acl_script_path"]; ok {
|
|
script, err := js.LoadScript(aclScriptPath)
|
|
if err != nil {
|
|
return javascript, err
|
|
}
|
|
|
|
javascript.aclScript = script
|
|
} else {
|
|
jsOk = false
|
|
missingOptions += " js_acl_script_path"
|
|
}
|
|
|
|
//Exit if any mandatory option is missing.
|
|
if !jsOk {
|
|
return nil, errors.Errorf("Javascript backend error: missing options: %s", missingOptions)
|
|
}
|
|
|
|
javascript.runner = js.NewRunner(javascript.stackDepthLimit, javascript.msMaxDuration)
|
|
|
|
return javascript, nil
|
|
}
|
|
|
|
func (o *Javascript) GetUser(username, password, clientid string) (bool, error) {
|
|
params := map[string]interface{}{
|
|
"username": username,
|
|
"password": password,
|
|
"clientid": clientid,
|
|
}
|
|
|
|
granted, err := o.runner.RunScript(o.userScript, params)
|
|
if err != nil {
|
|
log.Errorf("js error: %s", err)
|
|
}
|
|
|
|
return granted, err
|
|
}
|
|
|
|
func (o *Javascript) GetSuperuser(username string) (bool, error) {
|
|
params := map[string]interface{}{
|
|
"username": username,
|
|
}
|
|
|
|
granted, err := o.runner.RunScript(o.superuserScript, params)
|
|
if err != nil {
|
|
log.Errorf("js error: %s", err)
|
|
}
|
|
|
|
return granted, err
|
|
}
|
|
|
|
func (o *Javascript) CheckAcl(username, topic, clientid string, acc int32) (bool, error) {
|
|
params := map[string]interface{}{
|
|
"username": username,
|
|
"topic": topic,
|
|
"clientid": clientid,
|
|
"acc": acc,
|
|
}
|
|
|
|
granted, err := o.runner.RunScript(o.aclScript, params)
|
|
if err != nil {
|
|
log.Errorf("js error: %s", err)
|
|
}
|
|
|
|
return granted, err
|
|
}
|
|
|
|
//GetName returns the backend's name
|
|
func (o *Javascript) GetName() string {
|
|
return "Javascript"
|
|
}
|
|
|
|
func (o *Javascript) Halt() {
|
|
// NO-OP
|
|
}
|