quintodrome/api/validation.go

93 lines
2.3 KiB
Go
Raw Normal View History

package api
import (
"context"
2016-03-24 15:00:28 -08:00
"crypto/md5"
2016-03-09 17:05:23 -09:00
"encoding/hex"
2016-03-15 13:06:23 -08:00
"fmt"
2016-03-24 15:00:28 -08:00
"strings"
2016-03-15 13:06:23 -08:00
"github.com/astaxie/beego"
2017-04-01 05:47:14 -08:00
"github.com/cloudsonic/sonic-server/api/responses"
"github.com/cloudsonic/sonic-server/conf"
)
type ControllerInterface interface {
GetString(key string, def ...string) string
CustomAbort(status int, body string)
SendError(errorCode int, message ...interface{})
}
2016-03-15 13:06:23 -08:00
func Validate(controller BaseAPIController) {
addNewContext(controller)
2017-04-01 05:47:14 -08:00
if !conf.Sonic.DisableValidation {
checkParameters(controller)
authenticate(controller)
2016-02-24 15:16:42 -09:00
// TODO Validate version
}
}
func addNewContext(c BaseAPIController) {
ctx := context.Background()
id := c.Ctx.Input.GetData("requestId")
ctx = context.WithValue(ctx, "requestId", id)
c.Ctx.Input.SetData("context", ctx)
}
2016-03-15 13:06:23 -08:00
func checkParameters(c BaseAPIController) {
2016-03-24 15:00:28 -08:00
requiredParameters := []string{"u", "v", "c"}
2016-02-25 14:52:07 -09:00
for _, p := range requiredParameters {
if c.GetString(p) == "" {
2016-03-15 13:06:23 -08:00
logWarn(c, fmt.Sprintf(`Missing required parameter "%s"`, p))
2016-03-23 08:35:10 -08:00
abortRequest(c, responses.ErrorMissingParameter)
}
}
2016-03-24 15:00:28 -08:00
if c.GetString("p") == "" && (c.GetString("s") == "" || c.GetString("t") == "") {
logWarn(c, "Missing authentication information")
}
ctx := c.Ctx.Input.GetData("context").(context.Context)
ctx = context.WithValue(ctx, "user", c.GetString("u"))
ctx = context.WithValue(ctx, "client", c.GetString("c"))
ctx = context.WithValue(ctx, "version", c.GetString("v"))
c.Ctx.Input.SetData("context", ctx)
}
2016-03-15 13:06:23 -08:00
func authenticate(c BaseAPIController) {
2017-04-01 05:47:14 -08:00
password := conf.Sonic.Password
user := c.GetString("u")
2016-03-09 17:05:23 -09:00
pass := c.GetString("p")
2016-03-24 15:00:28 -08:00
salt := c.GetString("s")
token := c.GetString("t")
valid := false
switch {
case pass != "":
if strings.HasPrefix(pass, "enc:") {
e := strings.TrimPrefix(pass, "enc:")
if dec, err := hex.DecodeString(e); err == nil {
pass = string(dec)
}
2016-03-09 17:05:23 -09:00
}
valid = pass == password
2016-03-24 15:00:28 -08:00
case token != "":
t := fmt.Sprintf("%x", md5.Sum([]byte(password+salt)))
valid = t == token
2016-03-09 17:05:23 -09:00
}
2016-03-24 15:00:28 -08:00
2017-04-01 05:47:14 -08:00
if user != conf.Sonic.User || !valid {
2016-03-15 13:06:23 -08:00
logWarn(c, fmt.Sprintf(`Invalid login for user "%s"`, user))
2016-03-23 08:35:10 -08:00
abortRequest(c, responses.ErrorAuthenticationFail)
}
}
2016-03-15 13:06:23 -08:00
func abortRequest(c BaseAPIController, code int) {
c.SendError(code)
2016-02-25 14:52:07 -09:00
}
2016-03-15 13:06:23 -08:00
func logWarn(c BaseAPIController, msg string) {
beego.Warn(fmt.Sprintf("%s?%s: %s", c.Ctx.Request.URL.Path, c.Ctx.Request.URL.RawQuery, msg))
}