Handling request validation/authentication

This commit is contained in:
Deluan
2016-02-24 18:06:49 -05:00
parent 9a55fa1c64
commit 975327a6cb
14 changed files with 220 additions and 14 deletions
+1
View File
@@ -9,6 +9,7 @@ type GetLicenseController struct{ beego.Controller }
// @router /rest/getLicense.view [get]
func (this *GetLicenseController) Get() {
validate(this)
response := responses.NewXML(&responses.License{Valid: true})
this.Ctx.Output.Body(response)
}
+17
View File
@@ -1 +1,18 @@
package controllers
import (
"github.com/astaxie/beego"
"github.com/deluan/gosonic/controllers/responses"
)
type GetMusicFoldersController struct{ beego.Controller }
// @router /rest/getMusicFolders.view [get]
func (this *GetMusicFoldersController) Get() {
validate(this)
response := responses.NewError(responses.ERROR_GENERIC)
this.Ctx.Output.Body(response)
}
+1
View File
@@ -10,6 +10,7 @@ type PingController struct{ beego.Controller }
// @router /rest/ping.view [get]
func (this *PingController) Get() {
validate(this)
response := responses.NewEmpty()
xmlBody, _ := xml.Marshal(response)
this.Ctx.Output.Body([]byte(xml.Header + string(xmlBody)))
+50
View File
@@ -0,0 +1,50 @@
package responses
import (
"encoding/xml"
)
const (
ERROR_GENERIC = iota * 10
ERROR_MISSING_PARAMETER
ERROR_CLIENT_TOO_OLD
ERROR_SERVER_TOO_OLD
ERROR_AUTHENTICATION_FAIL
ERROR_AUTHORIZATION_FAIL
ERROR_TRIAL_EXPIRED
ERROR_DATA_NOT_FOUND
)
var (
errors map[int]string
)
func init() {
errors = make(map[int]string)
errors[ERROR_GENERIC] = "A generic error"
errors[ERROR_MISSING_PARAMETER] = "Required parameter is missing"
errors[ERROR_CLIENT_TOO_OLD] = "Incompatible Subsonic REST protocol version. Client must upgrade"
errors[ERROR_SERVER_TOO_OLD] = "Incompatible Subsonic REST protocol version. Server must upgrade"
errors[ERROR_AUTHENTICATION_FAIL] = "Wrong username or password"
errors[ERROR_AUTHORIZATION_FAIL] = "User is not authorized for the given operation"
errors[ERROR_TRIAL_EXPIRED] = "The trial period for the Subsonic server is over. Please upgrade to Subsonic Premium. Visit subsonic.org for details"
errors[ERROR_DATA_NOT_FOUND] = "The requested data was not found"
}
type error struct {
XMLName xml.Name`xml:"error"`
Code int `xml:"code,attr"`
Message string `xml:"message,attr"`
}
func NewError(errorCode int) []byte {
response := NewEmpty()
response.Status = "fail"
if errors[errorCode] == "" {
errorCode = ERROR_GENERIC
}
xmlBody, _ := xml.Marshal(&error{Code: errorCode, Message: errors[errorCode]})
response.Body = xmlBody
xmlResponse, _ := xml.Marshal(response)
return []byte(xml.Header + string(xmlResponse))
}
+1 -1
View File
@@ -13,7 +13,7 @@ type Subsonic struct {
}
func NewEmpty() Subsonic {
return Subsonic{Status: "ok", Version: beego.AppConfig.String("apiversion")}
return Subsonic{Status: "ok", Version: beego.AppConfig.String("apiVersion")}
}
func NewXML(body interface{}) []byte {
+40
View File
@@ -0,0 +1,40 @@
package controllers
import (
"github.com/astaxie/beego"
"github.com/deluan/gosonic/controllers/responses"
)
type ControllerInterface interface {
GetString(key string, def ...string) string
CustomAbort(status int, body string)
}
func validate(controller ControllerInterface) {
if beego.AppConfig.String("disableValidation") != "true" {
checkParameters(controller)
authenticate(controller)
}
}
func checkParameters(c ControllerInterface) {
requiredParameters := []string {"u", "p", "v", "c",}
for _,p := range requiredParameters {
if c.GetString(p) == "" {
cancel(c, responses.ERROR_MISSING_PARAMETER)
}
}
}
func authenticate(c ControllerInterface) {
user := c.GetString("u")
pass := c.GetString("p")
if (user != beego.AppConfig.String("user") || pass != beego.AppConfig.String("password")) {
cancel(c, responses.ERROR_AUTHENTICATION_FAIL)
}
}
func cancel(c ControllerInterface, code int) {
c.CustomAbort(200, string(responses.NewError(code)))
}