Removed register GET request in favor of POST, and did required HTTP api changes

This commit is contained in:
Joona Hoikkala 2016-12-02 15:42:10 +02:00
parent c3ac7a211c
commit 5f68d84ca5
No known key found for this signature in database
GPG Key ID: C14AAE0F5ADCB854
4 changed files with 75 additions and 27 deletions

View File

@ -41,6 +41,22 @@ func (c *cidrslice) ValidEntries() []string {
return valid
}
// Check if IP belongs to an allowed net
func (a ACMETxt) allowedFrom(ip string) bool {
remoteIP := net.ParseIP(ip)
// Range not limited
if len(a.AllowFrom.ValidEntries()) == 0 {
return true
}
for _, v := range a.AllowFrom.ValidEntries() {
_, vnet, _ := net.ParseCIDR(v)
if vnet.Contains(remoteIP) {
return true
}
}
return false
}
func newACMETxt() ACMETxt {
var a = ACMETxt{}
password := generatePassword(40)

31
api.go
View File

@ -23,16 +23,18 @@ func (a authMiddleware) Serve(ctx *iris.Context) {
} else {
if correctPassword(password, au.Password) {
// Password ok
if err := ctx.ReadJSON(&postData); err == nil {
// Check that the subdomain belongs to the user
if au.Subdomain == postData.Subdomain {
ctx.Next()
if au.allowedFrom(ctx.RequestIP()) {
// Update is allowed from remote addr
if err := ctx.ReadJSON(&postData); err == nil {
if au.Subdomain == postData.Subdomain {
ctx.Next()
return
}
} else {
// JSON error
ctx.JSON(iris.StatusBadRequest, iris.Map{"error": "bad data"})
return
}
} else {
// JSON error
ctx.JSON(iris.StatusBadRequest, iris.Map{"error": "bad data"})
return
}
} else {
// Wrong password
@ -44,17 +46,19 @@ func (a authMiddleware) Serve(ctx *iris.Context) {
}
func webRegisterPost(ctx *iris.Context) {
// Create new user
nu, err := DB.Register(cidrslice{})
var regJSON iris.Map
var regStatus int
cslice := cidrslice{}
_ = ctx.ReadJSON(&cslice)
// Create new user
nu, err := DB.Register(cslice)
if err != nil {
errstr := fmt.Sprintf("%v", err)
regJSON = iris.Map{"error": errstr}
regStatus = iris.StatusInternalServerError
log.WithFields(log.Fields{"error": err.Error()}).Debug("Error in registration")
} else {
regJSON = iris.Map{"username": nu.Username, "password": nu.Password, "fulldomain": nu.Subdomain + "." + DNSConf.General.Domain, "subdomain": nu.Subdomain}
regJSON = iris.Map{"username": nu.Username, "password": nu.Password, "fulldomain": nu.Subdomain + "." + DNSConf.General.Domain, "subdomain": nu.Subdomain, "allowfrom": nu.AllowFrom.JSON()}
regStatus = iris.StatusCreated
log.WithFields(log.Fields{"user": nu.Username.String()}).Debug("Created new user")
@ -62,11 +66,6 @@ func webRegisterPost(ctx *iris.Context) {
ctx.JSON(regStatus, regJSON)
}
func webRegisterGet(ctx *iris.Context) {
// This is placeholder for now
webRegisterPost(ctx)
}
func webUpdatePost(ctx *iris.Context) {
// User auth done in middleware
a := ACMETxt{}

View File

@ -26,7 +26,6 @@ func setupIris(t *testing.T, debug bool, noauth bool) *httpexpect.Expect {
}
DNSConf = dnscfg
var ForceAuth = authMiddleware{}
iris.Get("/register", webRegisterGet)
iris.Post("/register", webRegisterPost)
if noauth {
iris.Post("/update", webUpdatePost)
@ -40,14 +39,6 @@ func setupIris(t *testing.T, debug bool, noauth bool) *httpexpect.Expect {
func TestApiRegister(t *testing.T) {
e := setupIris(t, false, false)
e.GET("/register").Expect().
Status(iris.StatusCreated).
JSON().Object().
ContainsKey("fulldomain").
ContainsKey("subdomain").
ContainsKey("username").
ContainsKey("password").
NotContainsKey("error")
e.POST("/register").Expect().
Status(iris.StatusCreated).
JSON().Object().
@ -56,6 +47,27 @@ func TestApiRegister(t *testing.T) {
ContainsKey("username").
ContainsKey("password").
NotContainsKey("error")
allowfrom := []interface{}{
"123.123.123.123/32",
"1010.10.10.10/24",
"invalid",
}
response := e.POST("/register").
WithJSON(allowfrom).
Expect().
Status(iris.StatusCreated).
JSON().Object().
ContainsKey("fulldomain").
ContainsKey("subdomain").
ContainsKey("username").
ContainsKey("password").
ContainsKey("allowfrom").
NotContainsKey("error")
response.Value("allowfrom").String().Equal("[\"123.123.123.123/32\"]")
}
func TestApiRegisterWithMockDB(t *testing.T) {
@ -66,7 +78,7 @@ func TestApiRegisterWithMockDB(t *testing.T) {
defer db.Close()
mock.ExpectBegin()
mock.ExpectPrepare("INSERT INTO records").WillReturnError(errors.New("error"))
e.GET("/register").Expect().
e.POST("/register").Expect().
Status(iris.StatusInternalServerError).
JSON().Object().
ContainsKey("error")
@ -146,10 +158,30 @@ func TestApiManyUpdateWithCredentials(t *testing.T) {
"txt": ""}
e := setupIris(t, false, false)
// User without defined CIDR masks
newUser, err := DB.Register(cidrslice{})
if err != nil {
t.Errorf("Could not create new user, got error [%v]", err)
}
// User with defined allow from - CIDR masks, all invalid
// (httpexpect doesn't provide a way to mock remote ip)
newUserWithCIDR, err := DB.Register(cidrslice{"192.168.1.1/32", "invalid"})
if err != nil {
t.Errorf("Could not create new user with CIDR, got error [%v]", err)
}
// Another user with valid CIDR mask to match the httpexpect default
newUserWithValidCIDR, err := DB.Register(cidrslice{"0.0.0.0/32", "invalid"})
if err != nil {
t.Errorf("Could not create new user with a valid CIDR, got error [%v]", err)
}
/* newUserWithValidCIDR, err := DB.Register(cidrslice{"192.168.1.1/32", "invalid"})
if err != nil {
t.Errorf("Could not create new user with CIDR, got error [%v]", err)
}
*/
for _, test := range []struct {
user string
pass string
@ -164,6 +196,8 @@ func TestApiManyUpdateWithCredentials(t *testing.T) {
{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},
{newUserWithCIDR.Username.String(), newUserWithCIDR.Password, newUserWithCIDR.Subdomain, validTxtData, 401},
{newUserWithValidCIDR.Username.String(), newUserWithValidCIDR.Password, newUserWithValidCIDR.Subdomain, validTxtData, 200},
{newUser.Username.String(), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", newUser.Subdomain, validTxtData, 401},
} {
updateJSON = map[string]interface{}{

View File

@ -49,7 +49,6 @@ func startHTTPAPI() {
})
api.Use(crs)
var ForceAuth = authMiddleware{}
api.Get("/register", webRegisterGet)
api.Post("/register", webRegisterPost)
api.Post("/update", ForceAuth.Serve, webUpdatePost)
switch DNSConf.API.TLS {