Skip to content

Commit

Permalink
fix: an admin should not be able to update or see itself
Browse files Browse the repository at this point in the history
  • Loading branch information
simonwep committed Oct 28, 2023
1 parent 95d6a5b commit e4b7182
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GENESIS_JWT_TOKEN_EXPIRATION=120960
GENESIS_GIN_MODE=test
GENESIS_LOG_MODE=development
GENESIS_PORT=8080
GENESIS_CREATE_USERS=foo:hgEiPCZP,bar!:EczUR8dn
GENESIS_CREATE_USERS=foo:hgEiPCZP,baz:8d7f6g5h,bar!:EczUR8dn
GENESIS_USERNAME_PATTERN=^[\w]{0,32}$
GENESIS_KEY_PATTERN=^[\w]{0,32}$
GENESIS_DATA_MAX_SIZE=1
Expand Down
17 changes: 13 additions & 4 deletions core/db.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"bytes"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -147,19 +148,27 @@ func GetUser(name string) (*User, error) {
})
}

func GetUsers() ([]*PublicUser, error) {
func GetUsers(skip string) ([]*PublicUser, error) {
txn := database.NewTransaction(true)
defer txn.Discard()

it := txn.NewIterator(badger.DefaultIteratorOptions)
defer it.Close()

skipKey := buildUserKey(skip)
users := make([]*PublicUser, 0)
prefix := buildUserKey("")

for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
item := it.Item()

// Skip the user we want to skip
if bytes.Equal(skipKey, item.Key()) {
continue
}

var user PublicUser
err := it.Item().Value(func(val []byte) error {
err := item.Value(func(val []byte) error {
return json.Unmarshal(val, &user)
})

Expand Down Expand Up @@ -373,12 +382,12 @@ func buildUserDataKey(name, key string) []byte {
}

func hashPassword(pwd string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
hashed, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)

if err != nil {
return "", err
} else {
return string(bytes), err
return string(hashed), err
}
}

Expand Down
11 changes: 8 additions & 3 deletions routes/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ func CreateUser(c *gin.Context) {
}

func UpdateUser(c *gin.Context) {
user := authenticateUser(c)
validate := validator.New()
name := c.Param("name")
var body core.PartialUser

if !isAsAdminAuthenticated(c) {
if user == nil || !user.Admin {
c.Status(http.StatusForbidden)
} else if name == user.Name {
c.Status(http.StatusForbidden)
} else if err := c.ShouldBindJSON(&body); err != nil {
c.Status(http.StatusBadRequest)
Expand Down Expand Up @@ -70,9 +73,11 @@ func DeleteUser(c *gin.Context) {
}

func GetUser(c *gin.Context) {
if !isAsAdminAuthenticated(c) {
user := authenticateUser(c)

if user == nil || !user.Admin {
c.Status(http.StatusForbidden)
} else if list, err := core.GetUsers(); err != nil {
} else if list, err := core.GetUsers(user.Name); err != nil {
c.Status(http.StatusInternalServerError)
core.Logger.Error("failed to retrieve users", zap.Error(err))
} else {
Expand Down
16 changes: 14 additions & 2 deletions routes/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ func TestRetrieveUsers(t *testing.T) {
tryAuthorizedGet("/user", AuthorizedConfig{
Token: token,
Handler: func(response *httptest.ResponseRecorder) {
bar := "{\"name\":\"bar\",\"admin\":true}"
baz := "{\"name\":\"baz\",\"admin\":false}"
foo := "{\"name\":\"foo\",\"admin\":false}"
assert.Equal(t, "["+bar+","+foo+"]", response.Body.String())
assert.Equal(t, "["+baz+","+foo+"]", response.Body.String())
},
})
}
Expand Down Expand Up @@ -156,6 +156,18 @@ func TestUpdateUser(t *testing.T) {
})
}

func TestUpdateItself(t *testing.T) {
token := loginAdmin(t)

tryAuthorizedPost("/user/bar", AuthorizedBodyConfig{
Token: token,
Body: "{\"password\":\"wK8iVkRO\",\"admin\":true}",
Handler: func(response *httptest.ResponseRecorder) {
assert.Equal(t, http.StatusForbidden, response.Code)
},
})
}

func TestPartialUpdate(t *testing.T) {
token := loginAdmin(t)

Expand Down

0 comments on commit e4b7182

Please sign in to comment.