diff --git a/conf/app.conf b/conf/app.conf
index ae58699a9..5223d5ef5 100644
--- a/conf/app.conf
+++ b/conf/app.conf
@@ -1,12 +1,21 @@
 appname = github.com/deluan/gosonic
-httpport = 8080
-runmode = dev
-autorender = false
-copyrequestbody = true
+httpPort = 8080
+runMode = dev
+autoRender = false
+copyRequestBody = true
 
-apiversion = 1.0.0
-musicfolder=.
+apiVersion = 1.0.0
+musicFolder=.
+user=deluan
+password=wordpass
 
 [dev]
-enableadmin = true
-indexpath = ./gosonic.index
\ No newline at end of file
+disableValidation = true
+enableAdmin = true
+indexPath = ./gosonic.index
+
+[test]
+disableValidation = false
+enableAdmin = false
+user=deluan
+password=wordpass
diff --git a/controllers/get_license.go b/controllers/get_license.go
index 142212f7f..a998dad41 100644
--- a/controllers/get_license.go
+++ b/controllers/get_license.go
@@ -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)
 }
diff --git a/controllers/get_music_folders.go b/controllers/get_music_folders.go
index 2d3293679..3863b0d90 100644
--- a/controllers/get_music_folders.go
+++ b/controllers/get_music_folders.go
@@ -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)
+}
+
+
+
diff --git a/controllers/ping.go b/controllers/ping.go
index df2098ce4..a80b1b945 100644
--- a/controllers/ping.go
+++ b/controllers/ping.go
@@ -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)))
diff --git a/controllers/responses/error.go b/controllers/responses/error.go
new file mode 100644
index 000000000..b1b872331
--- /dev/null
+++ b/controllers/responses/error.go
@@ -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))
+}
\ No newline at end of file
diff --git a/controllers/responses/subsonic.go b/controllers/responses/subsonic.go
index 4ea5a2c04..f0c98c05c 100644
--- a/controllers/responses/subsonic.go
+++ b/controllers/responses/subsonic.go
@@ -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 {
diff --git a/controllers/validation.go b/controllers/validation.go
new file mode 100644
index 000000000..a04e6b2c9
--- /dev/null
+++ b/controllers/validation.go
@@ -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)))
+}
\ No newline at end of file
diff --git a/repositories/media_file_repository.go b/repositories/media_file_repository.go
index 54a331956..df5e8c351 100644
--- a/repositories/media_file_repository.go
+++ b/repositories/media_file_repository.go
@@ -1,6 +1,6 @@
 package repositories
 
-import "github.com/deluan/gosonic/models"
+//import "github.com/deluan/gosonic/models"
 //
 //func AddMediaFile(m models.MediaFile) string {
 //	m.ID = "user_" + strconv.FormatInt(time.Now().UnixNano(), 10)
diff --git a/repositories/media_folders_repository.go b/repositories/media_folders_repository.go
new file mode 100644
index 000000000..c7a835b14
--- /dev/null
+++ b/repositories/media_folders_repository.go
@@ -0,0 +1,3 @@
+package repositories
+
+
diff --git a/routers/router.go b/routers/router.go
index eff9faae1..cc1c000a9 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -17,5 +17,6 @@ func init() {
 	beego.Include(
 		&controllers.PingController{},
 		&controllers.GetLicenseController{},
+		&controllers.GetMusicFoldersController{},
 	)
 }
diff --git a/tests/controllers/get_license_test.go b/tests/controllers/get_license_test.go
index c2cd35c54..0568e69fd 100644
--- a/tests/controllers/get_license_test.go
+++ b/tests/controllers/get_license_test.go
@@ -12,6 +12,7 @@ import (
 	. "github.com/smartystreets/goconvey/convey"
 	"encoding/xml"
 	"fmt"
+	"github.com/deluan/gosonic/tests"
 )
 
 func init() {
@@ -22,7 +23,7 @@ func init() {
 
 // TestGet is a sample to run an endpoint test
 func TestGetLicense(t *testing.T) {
-	r, _ := http.NewRequest("GET", "/rest/getLicense.view", nil)
+	r, _ := http.NewRequest("GET", test.AddParams("/rest/getLicense.view"), nil)
 	w := httptest.NewRecorder()
 	beego.BeeApp.Handlers.ServeHTTP(w, r)
 
diff --git a/tests/controllers/ping_test.go b/tests/controllers/ping_test.go
index d8ff0c8ec..0ca26ca5a 100644
--- a/tests/controllers/ping_test.go
+++ b/tests/controllers/ping_test.go
@@ -12,6 +12,7 @@ import (
 	. "github.com/smartystreets/goconvey/convey"
 	"fmt"
 	"github.com/deluan/gosonic/controllers/responses"
+	"github.com/deluan/gosonic/tests"
 )
 
 func init() {
@@ -20,13 +21,12 @@ func init() {
 	beego.TestBeegoInit(appPath)
 }
 
-// TestGet is a sample to run an endpoint test
 func TestPing(t *testing.T) {
-	r, _ := http.NewRequest("GET", "/rest/ping.view", nil)
+	r, _ := http.NewRequest("GET", test.AddParams("/rest/ping.view"), nil)
 	w := httptest.NewRecorder()
 	beego.BeeApp.Handlers.ServeHTTP(w, r)
 
-	beego.Trace("testing", "TestPing", fmt.Sprintf("Code[%d]\n%s", w.Code, w.Body.String()))
+	beego.Trace("testing", "TestPing", fmt.Sprintf("\nUrl: %s\n\nCode[%d]\n%s", r.URL, w.Code, w.Body.String()))
 
 	Convey("Subject: Ping Endpoint\n", t, func() {
 		Convey("Status code should be 200", func() {
diff --git a/tests/controllers/validation_test.go b/tests/controllers/validation_test.go
new file mode 100644
index 000000000..76f3ce40b
--- /dev/null
+++ b/tests/controllers/validation_test.go
@@ -0,0 +1,67 @@
+package test
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+	"runtime"
+	"encoding/xml"
+	"path/filepath"
+	_ "github.com/deluan/gosonic/routers"
+	"github.com/astaxie/beego"
+	. "github.com/smartystreets/goconvey/convey"
+	"fmt"
+	"github.com/deluan/gosonic/controllers/responses"
+)
+
+func init() {
+	_, file, _, _ := runtime.Caller(1)
+	appPath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, "../.." + string(filepath.Separator))))
+	beego.TestBeegoInit(appPath)
+}
+
+func TestCheckParams(t *testing.T) {
+	r, _ := http.NewRequest("GET", "/rest/ping.view", nil)
+	w := httptest.NewRecorder()
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
+
+	beego.Trace("testing", "TestCheckParams", fmt.Sprintf("\nUrl: %s\n\nCode[%d]\n%s", r.URL, w.Code, w.Body.String()))
+
+	Convey("Subject: Validation\n", t, func() {
+		Convey("Status code should be 200", func() {
+			So(w.Code, ShouldEqual, 200)
+		})
+		Convey("The errorCode should be 10", func() {
+			So(w.Body.String(), ShouldContainSubstring, `error code="10" message=`)
+		})
+		Convey("The status should be 'fail'", func() {
+			v := responses.Subsonic{}
+			xml.Unmarshal(w.Body.Bytes(), &v)
+			So(v.Status, ShouldEqual, "fail")
+		})
+	})
+}
+
+func TestAuthentication(t *testing.T) {
+	r, _ := http.NewRequest("GET", "/rest/ping.view?u=INVALID&p=INVALID&c=test&v=1.0.0", nil)
+	w := httptest.NewRecorder()
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
+
+	beego.Trace("testing", "TestCheckParams", fmt.Sprintf("\nUrl: %s\n\nCode[%d]\n%s", r.URL, w.Code, w.Body.String()))
+
+	Convey("Subject: Validation\n", t, func() {
+		Convey("Status code should be 200", func() {
+			So(w.Code, ShouldEqual, 200)
+		})
+		Convey("The errorCode should be 10", func() {
+			So(w.Body.String(), ShouldContainSubstring, `error code="40" message=`)
+		})
+		Convey("The status should be 'fail'", func() {
+			v := responses.Subsonic{}
+			xml.Unmarshal(w.Body.Bytes(), &v)
+			So(v.Status, ShouldEqual, "fail")
+		})
+	})
+}
+
+
diff --git a/tests/test_helper.go b/tests/test_helper.go
new file mode 100644
index 000000000..0c2c3dfe0
--- /dev/null
+++ b/tests/test_helper.go
@@ -0,0 +1,16 @@
+package test
+
+import "fmt"
+
+const (
+	testUser = "deluan"
+	testPassword = "wordpass"
+	testClient = "test"
+	testVersion = "1.0.0"
+)
+
+func AddParams(url string) string {
+	return fmt.Sprintf("%s?u=%s&p=%s&c=%s&v=%s", url, testUser, testPassword, testClient, testVersion)
+}
+
+