mirror of
https://github.com/joohoi/acme-dns.git
synced 2025-07-13 09:17:47 +07:00
More API tests and removal of dead code
This commit is contained in:
21
api.go
21
api.go
@ -24,6 +24,9 @@ func (a authMiddleware) Serve(ctx *iris.Context) {
|
|||||||
ctx.Next()
|
ctx.Next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ctx.JSON(iris.StatusBadRequest, iris.Map{"error": "bad data"})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// To protect against timed side channel (never gonna give you up)
|
// To protect against timed side channel (never gonna give you up)
|
||||||
@ -39,7 +42,7 @@ func webRegisterPost(ctx *iris.Context) {
|
|||||||
var regStatus int
|
var regStatus int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errstr := fmt.Sprintf("%v", err)
|
errstr := fmt.Sprintf("%v", err)
|
||||||
regJSON = iris.Map{"username": "", "password": "", "domain": "", "error": errstr}
|
regJSON = iris.Map{"error": errstr}
|
||||||
regStatus = iris.StatusInternalServerError
|
regStatus = iris.StatusInternalServerError
|
||||||
log.Debugf("Error in registration, [%v]", err)
|
log.Debugf("Error in registration, [%v]", err)
|
||||||
} else {
|
} else {
|
||||||
@ -60,18 +63,10 @@ func webUpdatePost(ctx *iris.Context) {
|
|||||||
// User auth done in middleware
|
// User auth done in middleware
|
||||||
a := ACMETxt{}
|
a := ACMETxt{}
|
||||||
userStr := ctx.RequestHeader("X-API-User")
|
userStr := ctx.RequestHeader("X-API-User")
|
||||||
username, err := getValidUsername(userStr)
|
// Already checked in auth middlware
|
||||||
if err != nil {
|
username, _ := getValidUsername(userStr)
|
||||||
log.Warningf("Error while getting username [%s]. This should never happen because of auth middlware.", userStr)
|
// Already checked in auth middleware
|
||||||
webUpdatePostError(ctx, err, iris.StatusUnauthorized)
|
_ = ctx.ReadJSON(&a)
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := ctx.ReadJSON(&a); err != nil {
|
|
||||||
// Handle bad post data
|
|
||||||
log.Warningf("Could not unmarshal: [%v]", err)
|
|
||||||
webUpdatePostError(ctx, err, iris.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a.Username = username
|
a.Username = username
|
||||||
// Do update
|
// Do update
|
||||||
if validSubdomain(a.Subdomain) && validTXT(a.Value) {
|
if validSubdomain(a.Subdomain) && validTXT(a.Value) {
|
||||||
|
61
api_test.go
61
api_test.go
@ -1,14 +1,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/gavv/httpexpect"
|
"github.com/gavv/httpexpect"
|
||||||
"github.com/kataras/iris"
|
"github.com/kataras/iris"
|
||||||
"github.com/kataras/iris/httptest"
|
"github.com/kataras/iris/httptest"
|
||||||
"github.com/op/go-logging"
|
"github.com/op/go-logging"
|
||||||
|
"gopkg.in/DATA-DOG/go-sqlmock.v1"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupIris(t *testing.T, debug bool) *httpexpect.Expect {
|
func SetupIris(t *testing.T, debug bool, noauth bool) *httpexpect.Expect {
|
||||||
iris.ResetDefault()
|
iris.ResetDefault()
|
||||||
var dbcfg = dbsettings{
|
var dbcfg = dbsettings{
|
||||||
Engine: "sqlite3",
|
Engine: "sqlite3",
|
||||||
@ -33,14 +35,18 @@ func SetupIris(t *testing.T, debug bool) *httpexpect.Expect {
|
|||||||
var ForceAuth = authMiddleware{}
|
var ForceAuth = authMiddleware{}
|
||||||
iris.Get("/register", webRegisterGet)
|
iris.Get("/register", webRegisterGet)
|
||||||
iris.Post("/register", webRegisterPost)
|
iris.Post("/register", webRegisterPost)
|
||||||
iris.Post("/update", ForceAuth.Serve, webUpdatePost)
|
if noauth {
|
||||||
|
iris.Post("/update", webUpdatePost)
|
||||||
|
} else {
|
||||||
|
iris.Post("/update", ForceAuth.Serve, webUpdatePost)
|
||||||
|
}
|
||||||
httptestcfg := httptest.DefaultConfiguration()
|
httptestcfg := httptest.DefaultConfiguration()
|
||||||
httptestcfg.Debug = debug
|
httptestcfg.Debug = debug
|
||||||
return httptest.New(iris.Default, t, httptestcfg)
|
return httptest.New(iris.Default, t, httptestcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApiRegister(t *testing.T) {
|
func TestApiRegister(t *testing.T) {
|
||||||
e := SetupIris(t, false)
|
e := SetupIris(t, false, false)
|
||||||
defer DB.DB.Close()
|
defer DB.DB.Close()
|
||||||
e.GET("/register").Expect().
|
e.GET("/register").Expect().
|
||||||
Status(iris.StatusCreated).
|
Status(iris.StatusCreated).
|
||||||
@ -60,8 +66,22 @@ func TestApiRegister(t *testing.T) {
|
|||||||
NotContainsKey("error")
|
NotContainsKey("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApiRegisterWithMockDB(t *testing.T) {
|
||||||
|
e := SetupIris(t, false, false)
|
||||||
|
DB.DB.Close()
|
||||||
|
db, mock, _ := sqlmock.New()
|
||||||
|
DB.DB = db
|
||||||
|
defer DB.DB.Close()
|
||||||
|
mock.ExpectBegin()
|
||||||
|
mock.ExpectPrepare("INSERT INTO records").WillReturnError(errors.New("error"))
|
||||||
|
e.GET("/register").Expect().
|
||||||
|
Status(iris.StatusInternalServerError).
|
||||||
|
JSON().Object().
|
||||||
|
ContainsKey("error")
|
||||||
|
}
|
||||||
|
|
||||||
func TestApiUpdateWithoutCredentials(t *testing.T) {
|
func TestApiUpdateWithoutCredentials(t *testing.T) {
|
||||||
e := SetupIris(t, false)
|
e := SetupIris(t, false, false)
|
||||||
defer DB.DB.Close()
|
defer DB.DB.Close()
|
||||||
e.POST("/update").Expect().
|
e.POST("/update").Expect().
|
||||||
Status(iris.StatusUnauthorized).
|
Status(iris.StatusUnauthorized).
|
||||||
@ -77,7 +97,7 @@ func TestApiUpdateWithCredentials(t *testing.T) {
|
|||||||
"subdomain": "",
|
"subdomain": "",
|
||||||
"txt": ""}
|
"txt": ""}
|
||||||
|
|
||||||
e := SetupIris(t, false)
|
e := SetupIris(t, false, false)
|
||||||
defer DB.DB.Close()
|
defer DB.DB.Close()
|
||||||
newUser, err := DB.Register()
|
newUser, err := DB.Register()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -97,19 +117,43 @@ func TestApiUpdateWithCredentials(t *testing.T) {
|
|||||||
ContainsKey("txt").
|
ContainsKey("txt").
|
||||||
NotContainsKey("error").
|
NotContainsKey("error").
|
||||||
ValueEqual("txt", validTxtData)
|
ValueEqual("txt", validTxtData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApiUpdateWithCredentialsMockDB(t *testing.T) {
|
||||||
|
validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
updateJSON := map[string]interface{}{
|
||||||
|
"subdomain": "",
|
||||||
|
"txt": ""}
|
||||||
|
|
||||||
|
// Valid data
|
||||||
|
updateJSON["subdomain"] = "a097455b-52cc-4569-90c8-7a4b97c6eba8"
|
||||||
|
updateJSON["txt"] = validTxtData
|
||||||
|
|
||||||
|
e := SetupIris(t, false, true)
|
||||||
|
DB.DB.Close()
|
||||||
|
db, mock, _ := sqlmock.New()
|
||||||
|
DB.DB = db
|
||||||
|
defer DB.DB.Close()
|
||||||
|
mock.ExpectBegin()
|
||||||
|
mock.ExpectPrepare("UPDATE records").WillReturnError(errors.New("error"))
|
||||||
|
e.POST("/update").
|
||||||
|
WithJSON(updateJSON).
|
||||||
|
Expect().
|
||||||
|
Status(iris.StatusInternalServerError).
|
||||||
|
JSON().Object().
|
||||||
|
ContainsKey("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApiManyUpdateWithCredentials(t *testing.T) {
|
func TestApiManyUpdateWithCredentials(t *testing.T) {
|
||||||
// TODO: transfer to using httpexpect builder
|
// TODO: transfer to using httpexpect builder
|
||||||
// If test fails and more debuf info is needed, use SetupIris(t, true)
|
// If test fails and more debuf info is needed, use SetupIris(t, true, false)
|
||||||
validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
|
||||||
updateJSON := map[string]interface{}{
|
updateJSON := map[string]interface{}{
|
||||||
"subdomain": "",
|
"subdomain": "",
|
||||||
"txt": ""}
|
"txt": ""}
|
||||||
|
|
||||||
e := SetupIris(t, false)
|
e := SetupIris(t, true, false)
|
||||||
defer DB.DB.Close()
|
defer DB.DB.Close()
|
||||||
newUser, err := DB.Register()
|
newUser, err := DB.Register()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,7 +163,7 @@ func TestApiManyUpdateWithCredentials(t *testing.T) {
|
|||||||
user string
|
user string
|
||||||
pass string
|
pass string
|
||||||
subdomain string
|
subdomain string
|
||||||
txt string
|
txt interface{}
|
||||||
status int
|
status int
|
||||||
}{
|
}{
|
||||||
{"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 401},
|
{"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 401},
|
||||||
@ -127,6 +171,7 @@ func TestApiManyUpdateWithCredentials(t *testing.T) {
|
|||||||
{"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401},
|
{"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401},
|
||||||
{newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401},
|
{newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401},
|
||||||
{newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400},
|
{newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400},
|
||||||
|
{newUser.Username.String(), newUser.Password, newUser.Subdomain, 1234567890, 400},
|
||||||
{newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200},
|
{newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200},
|
||||||
} {
|
} {
|
||||||
updateJSON = map[string]interface{}{
|
updateJSON = map[string]interface{}{
|
||||||
|
2
db.go
2
db.go
@ -68,7 +68,7 @@ func (d *database) Register() (ACMETxt, error) {
|
|||||||
}
|
}
|
||||||
sm, err := d.DB.Prepare(regSQL)
|
sm, err := d.DB.Prepare(regSQL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return a, err
|
return a, errors.New("SQL error")
|
||||||
}
|
}
|
||||||
defer sm.Close()
|
defer sm.Close()
|
||||||
_, err = sm.Exec(a.Username.String(), passwordHash, a.Subdomain, timenow)
|
_, err = sm.Exec(a.Username.String(), passwordHash, a.Subdomain, timenow)
|
||||||
|
Reference in New Issue
Block a user