test(authz): refine authz tests
This commit is contained in:
parent
731e4029c9
commit
0967ca53dc
6 changed files with 241 additions and 229 deletions
|
@ -31,7 +31,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrReachedLimit = errors.New("reached space limit")
|
||||
ErrReachedLimit = errors.New("reached space limit")
|
||||
ErrNotFound = errors.New("not found")
|
||||
|
||||
DefaultPreferences = Preferences{
|
||||
Bg: &sitestore.BgConfig{
|
||||
Url: "",
|
||||
|
@ -262,11 +264,11 @@ func (us *KVUserStore) GetUserByName(name string) (*User, error) {
|
|||
|
||||
userID, ok := us.store.GetStringIn(IDsNs, name)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user id (%s) not found", name)
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
infoStr, ok := us.store.GetStringIn(UsersNs, userID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user name (%s) not found", userID)
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
user := &User{}
|
||||
|
|
|
@ -829,13 +829,20 @@ func (h *FileHandlers) DelUploading(c *gin.Context) {
|
|||
}
|
||||
|
||||
userID := c.MustGet(q.UserIDParam).(string)
|
||||
role := c.MustGet(q.RoleParam).(string)
|
||||
userName := c.MustGet(q.UserParam).(string)
|
||||
// op is empty, because users must be admin, or the path belongs to this user
|
||||
if !h.canAccess(userName, role, "", filePath) {
|
||||
c.JSON(q.ErrResp(c, 403, errors.New("forbidden")))
|
||||
return
|
||||
}
|
||||
|
||||
userIDInt, err := strconv.ParseUint(userID, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
return
|
||||
}
|
||||
|
||||
userName := c.MustGet(q.UserParam).(string)
|
||||
tmpFilePath := q.UploadPath(userName, filePath)
|
||||
locker := h.NewAutoLocker(c, lockName(tmpFilePath))
|
||||
locker.Exec(func() {
|
||||
|
|
|
@ -82,7 +82,6 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
|
|||
apiRuleCname(userstore.UserRole, "POST", "/v1/users/logout"): true,
|
||||
apiRuleCname(userstore.UserRole, "GET", "/v1/users/isauthed"): true,
|
||||
apiRuleCname(userstore.UserRole, "PATCH", "/v1/users/pwd"): true,
|
||||
apiRuleCname(userstore.UserRole, "PATCH", "/v1/users/"): true,
|
||||
apiRuleCname(userstore.UserRole, "GET", "/v1/users/self"): true,
|
||||
apiRuleCname(userstore.UserRole, "PATCH", "/v1/users/preferences"): true,
|
||||
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/files"): true,
|
||||
|
@ -114,13 +113,11 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
|
|||
apiRuleCname(userstore.VisitorRole, "GET", "/"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", publicPath): true,
|
||||
apiRuleCname(userstore.VisitorRole, "POST", "/v1/users/login"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/users/isauthed"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/users/self"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/files"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/dirs"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/settings/client"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "POST", "/v1/settings/errors"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true,
|
||||
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true,
|
||||
|
@ -220,7 +217,7 @@ type LoginReq struct {
|
|||
func (h *MultiUsersSvc) Login(c *gin.Context) {
|
||||
req := &LoginReq{}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
c.JSON(q.ErrResp(c, 400, err))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -235,13 +232,17 @@ func (h *MultiUsersSvc) Login(c *gin.Context) {
|
|||
|
||||
user, err := h.deps.Users().GetUserByName(req.User)
|
||||
if err != nil {
|
||||
if errors.Is(err, userstore.ErrNotFound) {
|
||||
c.JSON(q.ErrResp(c, 403, err))
|
||||
return
|
||||
}
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.Pwd), []byte(req.Pwd))
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
c.JSON(q.ErrResp(c, 403, err))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -276,11 +277,6 @@ func (h *MultiUsersSvc) Logout(c *gin.Context) {
|
|||
|
||||
func (h *MultiUsersSvc) IsAuthed(c *gin.Context) {
|
||||
// token alreay verified in the authn middleware
|
||||
role := c.MustGet(q.RoleParam).(string)
|
||||
if role == userstore.VisitorRole {
|
||||
c.JSON(q.ErrResp(c, 403, q.ErrUnauthorized))
|
||||
return
|
||||
}
|
||||
c.JSON(q.Resp(200))
|
||||
}
|
||||
|
||||
|
@ -350,15 +346,6 @@ func (h *MultiUsersSvc) ForceSetPwd(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
claims, err := h.getUserInfo(c)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 403, err))
|
||||
return
|
||||
}
|
||||
if claims[q.RoleParam] != userstore.AdminRole {
|
||||
c.JSON(q.ErrResp(c, 403, errors.New("operation denied")))
|
||||
return
|
||||
}
|
||||
targetUID, err := strconv.ParseUint(req.ID, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
|
@ -681,12 +668,6 @@ func (h *MultiUsersSvc) SetUser(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
role := c.MustGet(q.RoleParam).(string)
|
||||
if role != userstore.AdminRole {
|
||||
c.JSON(q.ErrResp(c, 403, errors.New("Forbidden")))
|
||||
return
|
||||
}
|
||||
|
||||
err := h.deps.Users().SetInfo(req.ID, &userstore.User{
|
||||
Role: req.Role,
|
||||
Quota: req.Quota,
|
||||
|
@ -710,21 +691,7 @@ func (h *MultiUsersSvc) SetPreferences(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
claims, err := h.getUserInfo(c)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 401, err))
|
||||
return
|
||||
}
|
||||
if claims[q.RoleParam] == userstore.VisitorRole {
|
||||
c.JSON(q.ErrResp(c, 403, errors.New("operation denied")))
|
||||
return
|
||||
}
|
||||
|
||||
uidStr, ok := claims[q.UserIDParam]
|
||||
if !ok {
|
||||
c.JSON(q.ErrResp(c, 500, errors.New("user id not found")))
|
||||
return
|
||||
}
|
||||
uidStr := c.MustGet(q.UserIDParam).(string)
|
||||
uid, err := strconv.ParseUint(uidStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db/userstore"
|
||||
q "github.com/ihexxa/quickshare/src/handlers"
|
||||
)
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/ihexxa/gocfg"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/db/sitestore"
|
||||
"github.com/ihexxa/quickshare/src/db/userstore"
|
||||
"github.com/ihexxa/quickshare/src/depidx"
|
||||
q "github.com/ihexxa/quickshare/src/handlers"
|
||||
)
|
||||
|
@ -71,12 +70,6 @@ func (h *SettingsSvc) SetClientCfg(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
role := c.MustGet(q.RoleParam).(string)
|
||||
if role != userstore.AdminRole {
|
||||
c.JSON(q.ErrResp(c, 403, q.ErrUnauthorized))
|
||||
return
|
||||
}
|
||||
|
||||
err = h.deps.SiteStore().SetClientCfg(clientCfg)
|
||||
if err != nil {
|
||||
c.JSON(q.ErrResp(c, 500, err))
|
||||
|
@ -102,12 +95,6 @@ type ClientErrorReports struct {
|
|||
}
|
||||
|
||||
func (h *SettingsSvc) ReportErrors(c *gin.Context) {
|
||||
role := c.MustGet(q.RoleParam).(string)
|
||||
if role == userstore.VisitorRole {
|
||||
c.JSON(q.ErrResp(c, 403, q.ErrUnauthorized))
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
req := &ClientErrorReports{}
|
||||
if err = c.ShouldBindJSON(&req); err != nil {
|
||||
|
|
|
@ -81,18 +81,28 @@ func TestPermissions(t *testing.T) {
|
|||
}
|
||||
|
||||
// tests only check the status code for checking permission
|
||||
t.Run("Users API Permissions", func(t *testing.T) {
|
||||
testUsersAPIs := func(user string, pwd string, requireAuth bool, expectedCodes map[string]int) {
|
||||
desc := user
|
||||
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
if requireAuth {
|
||||
resp, _, errs := cl.Login(user, pwd)
|
||||
assertResp(t, resp, errs, 200, desc)
|
||||
token = client.GetCookie(resp.Cookies(), q.TokenCookie)
|
||||
}
|
||||
t.Run("users API authz tests", func(t *testing.T) {
|
||||
// Login
|
||||
// SetPwd
|
||||
// Self
|
||||
// SetPreferences
|
||||
// IsAuthed
|
||||
// AddUser
|
||||
// AddUser
|
||||
// ListUsers
|
||||
// ForceSetPwd
|
||||
// ForceSetPwdOther
|
||||
// ForceSetPwdOtherAdmin
|
||||
// SetUserSelf
|
||||
// SetUserOthers
|
||||
// SetUserOthers
|
||||
// DelUser
|
||||
// AddRole
|
||||
// ListRoles
|
||||
// DelRole
|
||||
// Logout
|
||||
|
||||
testUsersAPIs := func(desc, user string, pwd string, requireAuth bool, expectedCodes map[string]int) {
|
||||
newPwd := "12345"
|
||||
newRole := userstore.AdminRole
|
||||
newQuota := &userstore.Quota{
|
||||
|
@ -104,9 +114,19 @@ func TestPermissions(t *testing.T) {
|
|||
tmpAdmin, tmpAdminPwd := "tmpAdmin", "1234"
|
||||
tmpNewRole := "tmpNewRole"
|
||||
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
if requireAuth {
|
||||
resp, _, errs := cl.Login(user, pwd)
|
||||
assertResp(t, resp, errs, 200, desc)
|
||||
token = client.GetCookie(resp.Cookies(), q.TokenCookie)
|
||||
} else {
|
||||
resp, _, errs := cl.Login(user, pwd)
|
||||
assertResp(t, resp, errs, 403, desc)
|
||||
}
|
||||
|
||||
resp, _, errs := cl.SetPwd(pwd, newPwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["SetPwd"], fmt.Sprintf("%s-%s", desc, "SetPwd"))
|
||||
|
||||
// set back the password
|
||||
resp, _, errs = cl.SetPwd(newPwd, pwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["SetPwd"], fmt.Sprintf("%s-%s", desc, "SetPwd"))
|
||||
|
@ -122,6 +142,7 @@ func TestPermissions(t *testing.T) {
|
|||
resp, _, errs = cl.IsAuthed(token)
|
||||
assertResp(t, resp, errs, expectedCodes["IsAuthed"], fmt.Sprintf("%s-%s", desc, "IsAuthed"))
|
||||
|
||||
// user management
|
||||
resp, addUserResp, errs := cl.AddUser(tmpUser, tmpPwd, tmpRole, token)
|
||||
assertResp(t, resp, errs, expectedCodes["AddUser"], fmt.Sprintf("%s-%s", desc, "AddUser"))
|
||||
resp, addAdminResp, errs := cl.AddUser(tmpAdmin, tmpAdminPwd, userstore.AdminRole, token)
|
||||
|
@ -150,10 +171,12 @@ func TestPermissions(t *testing.T) {
|
|||
resp, _, errs = cl.ForceSetPwd(selfResp.ID, newPwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["ForceSetPwd"], fmt.Sprintf("%s-%s", desc, "ForceSetPwd"))
|
||||
resp, _, errs = cl.ForceSetPwd(selfResp.ID, pwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["ForceSetPwd"], fmt.Sprintf("%s-%s", desc, "ForceSetPwdBack"))
|
||||
|
||||
resp, _, errs = cl.ForceSetPwd(addUserResp.ID, newPwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["ForceSetPwdOther"], fmt.Sprintf("%s-%s", desc, "ForceSetPwdOther"))
|
||||
resp, _, errs = cl.ForceSetPwd(addUserResp.ID, pwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["ForceSetPwdOther"], fmt.Sprintf("%s-%s", desc, "ForceSetPwdOtherBack"))
|
||||
|
||||
resp, _, errs = cl.ForceSetPwd(addAdminResp.ID, newPwd, token)
|
||||
assertResp(t, resp, errs, expectedCodes["ForceSetPwdOtherAdmin"], fmt.Sprintf("%s-%s", desc, "ForceSetPwdOtherAdmin"))
|
||||
|
@ -165,12 +188,14 @@ func TestPermissions(t *testing.T) {
|
|||
resp, _, errs = cl.SetUser(tmpUserID, userstore.AdminRole, newQuota, token)
|
||||
assertResp(t, resp, errs, expectedCodes["SetUserOthers"], fmt.Sprintf("%s-%s", desc, "SetUserOthers"))
|
||||
resp, _, errs = cl.SetUser(0, userstore.UserRole, newQuota, token)
|
||||
assertResp(t, resp, errs, expectedCodes["SetUserOthers"], fmt.Sprintf("%s-%s", desc, "SetUserOthers"))
|
||||
assertResp(t, resp, errs, expectedCodes["SetUserOthersAdmin"], fmt.Sprintf("%s-%s", desc, "SetUserOthersAdmin"))
|
||||
|
||||
resp, _, errs = cl.DelUser(addUserResp.ID, token)
|
||||
assertResp(t, resp, errs, expectedCodes["DelUser"], fmt.Sprintf("%s-%s", desc, "DelUser"))
|
||||
resp, _, errs = cl.DelUser(addAdminResp.ID, token)
|
||||
assertResp(t, resp, errs, expectedCodes["DelUserAdmin"], fmt.Sprintf("%s-%s", desc, "DelUserAdmin"))
|
||||
|
||||
// test role operations
|
||||
// role management
|
||||
resp, _, errs = cl.AddRole(tmpNewRole, token)
|
||||
assertResp(t, resp, errs, expectedCodes["AddRole"], fmt.Sprintf("%s-%s", desc, "AddRole"))
|
||||
|
||||
|
@ -183,29 +208,33 @@ func TestPermissions(t *testing.T) {
|
|||
if requireAuth {
|
||||
resp, _, errs := cl.Logout(token)
|
||||
assertResp(t, resp, errs, 200, fmt.Sprintf("%s-%s", desc, "logout"))
|
||||
} else {
|
||||
resp, _, errs := cl.Logout(token)
|
||||
assertResp(t, resp, errs, 403, fmt.Sprintf("%s-%s", desc, "logout"))
|
||||
}
|
||||
}
|
||||
|
||||
testUsersAPIs("admin", "1234", true, map[string]int{
|
||||
testUsersAPIs("admin user operations", "admin", "1234", true, map[string]int{
|
||||
"SetPwd": 200,
|
||||
"Self": 200,
|
||||
"SetPreferences": 200,
|
||||
"IsAuthed": 200,
|
||||
"AddUser": 200,
|
||||
"ListUsers": 200,
|
||||
"ForceSetPwd": 403, // can not set admin's password
|
||||
"ForceSetPwd": 403, // force setting admin's password is not allowed
|
||||
"ForceSetPwdOther": 200,
|
||||
"ForceSetPwdOtherAdmin": 403,
|
||||
"SetUserSelf": 200,
|
||||
"SetUserOthers": 200,
|
||||
"SetOtherUser": 200,
|
||||
"SetUserOthersAdmin": 200,
|
||||
"DelUser": 200,
|
||||
"DelUserAdmin": 200,
|
||||
"AddRole": 200,
|
||||
"ListRoles": 200,
|
||||
"DelRole": 200,
|
||||
})
|
||||
|
||||
testUsersAPIs("user", "1234", true, map[string]int{
|
||||
testUsersAPIs("user user operations", "user", "1234", true, map[string]int{
|
||||
"SetPwd": 200,
|
||||
"Self": 200,
|
||||
"SetPreferences": 200,
|
||||
|
@ -217,13 +246,15 @@ func TestPermissions(t *testing.T) {
|
|||
"ForceSetPwdOtherAdmin": 403,
|
||||
"SetUserSelf": 403,
|
||||
"SetUserOthers": 403,
|
||||
"SetUserOthersAdmin": 403,
|
||||
"DelUser": 403,
|
||||
"DelUserAdmin": 403,
|
||||
"AddRole": 403,
|
||||
"ListRoles": 403,
|
||||
"DelRole": 403,
|
||||
})
|
||||
|
||||
testUsersAPIs("visitor", "", false, map[string]int{
|
||||
testUsersAPIs("visitor user operations", "visitor", "", false, map[string]int{
|
||||
"SetPwd": 403,
|
||||
"Self": 403,
|
||||
"SetPreferences": 403,
|
||||
|
@ -235,30 +266,25 @@ func TestPermissions(t *testing.T) {
|
|||
"ForceSetPwdOtherAdmin": 403,
|
||||
"SetUserSelf": 403,
|
||||
"SetUserOthers": 403,
|
||||
"SetUserOthersAdmin": 403,
|
||||
"DelUser": 403,
|
||||
"DelUserAdmin": 403,
|
||||
"AddRole": 403,
|
||||
"ListRoles": 403,
|
||||
"DelRole": 403,
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Files operation API Permissions", func(t *testing.T) {
|
||||
testFolderOpPermission := func(user string, pwd string, requireAuth bool, expectedCodes map[string]int) {
|
||||
// List
|
||||
t.Run("files operation API authz tests", func(t *testing.T) {
|
||||
testFolderOpPermission := func(desc, user string, pwd string, requireAuth bool, targetPaths []string, expectedCodes map[string]int) {
|
||||
// ListHome
|
||||
// List
|
||||
// ListTarget
|
||||
// Mkdir
|
||||
// Move
|
||||
// Create
|
||||
// UploadChunk
|
||||
// UploadStatus
|
||||
// Metadata
|
||||
// Move
|
||||
// Download
|
||||
// Delete
|
||||
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
desc := user
|
||||
|
||||
if requireAuth {
|
||||
resp, _, errs := cl.Login(user, pwd)
|
||||
|
@ -269,36 +295,41 @@ func TestPermissions(t *testing.T) {
|
|||
filesCl := client.NewFilesClient(addr, token)
|
||||
|
||||
resp, lhResp, errs := filesCl.ListHome()
|
||||
assertResp(t, resp, errs, expectedCodes["ListHome"], desc)
|
||||
assertResp(t, resp, errs, expectedCodes["ListHome"], fmt.Sprintf("%s-%s", desc, "ListHome"))
|
||||
|
||||
homePath := lhResp.Cwd
|
||||
if !requireAuth {
|
||||
homePath = "/"
|
||||
}
|
||||
|
||||
resp, _, errs = filesCl.List(homePath)
|
||||
assertResp(t, resp, errs, expectedCodes["List"], desc)
|
||||
|
||||
for _, itemPath := range []string{
|
||||
"/",
|
||||
"admin/",
|
||||
"admin/files",
|
||||
"user2/",
|
||||
"user2/files",
|
||||
} {
|
||||
resp, _, errs = filesCl.List(itemPath)
|
||||
assertResp(t, resp, errs, expectedCodes["ListPaths"], desc)
|
||||
}
|
||||
|
||||
testPath := filepath.Join(lhResp.Cwd, "test")
|
||||
|
||||
resp, _, errs = filesCl.Mkdir(testPath)
|
||||
assertResp(t, resp, errs, expectedCodes["Mkdir"], desc)
|
||||
|
||||
newPath := filepath.Join(lhResp.Cwd, "test2")
|
||||
|
||||
resp, _, errs = filesCl.List(homePath)
|
||||
assertResp(t, resp, errs, expectedCodes["List"], fmt.Sprintf("%s-%s", desc, "List"))
|
||||
|
||||
for _, itemPath := range targetPaths {
|
||||
resp, _, errs = filesCl.List(itemPath)
|
||||
assertResp(t, resp, errs, expectedCodes["ListTarget"], fmt.Sprintf("%s-%s", desc, "ListTarget"))
|
||||
}
|
||||
|
||||
resp, _, errs = filesCl.Mkdir(testPath)
|
||||
assertResp(t, resp, errs, expectedCodes["Mkdir"], fmt.Sprintf("%s-%s", desc, "Mkdir"))
|
||||
|
||||
for _, itemPath := range targetPaths {
|
||||
resp, _, errs = filesCl.Mkdir(filepath.Join(itemPath, "test"))
|
||||
assertResp(t, resp, errs, expectedCodes["MkdirTarget"], fmt.Sprintf("%s-%s", desc, "MkdirTarget"))
|
||||
}
|
||||
|
||||
resp, _, errs = filesCl.Move(testPath, newPath)
|
||||
assertResp(t, resp, errs, expectedCodes["Move"], desc)
|
||||
assertResp(t, resp, errs, expectedCodes["Move"], fmt.Sprintf("%s-%s", desc, "Move"))
|
||||
|
||||
for i, srcDir := range targetPaths {
|
||||
srcPath := filepath.Join(srcDir, "test")
|
||||
dstPath := filepath.Join(homePath, fmt.Sprintf("folder_%d", i))
|
||||
|
||||
resp, _, errs = filesCl.Move(srcPath, dstPath)
|
||||
assertResp(t, resp, errs, expectedCodes["MoveFrom"], fmt.Sprintf("%s-%s", desc, "MoveFrom"))
|
||||
}
|
||||
|
||||
if requireAuth {
|
||||
resp, _, errs := cl.Logout(token)
|
||||
|
@ -306,29 +337,59 @@ func TestPermissions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
testFolderOpPermission("admin", "1234", true, map[string]int{
|
||||
"ListHome": 200,
|
||||
"List": 200,
|
||||
"ListPaths": 200,
|
||||
"Mkdir": 200,
|
||||
"Move": 200,
|
||||
targetPaths := []string{
|
||||
"/",
|
||||
"admin2/",
|
||||
"admin2/files",
|
||||
"user2/",
|
||||
"user2/files",
|
||||
}
|
||||
|
||||
testFolderOpPermission("admin folder operations", "admin", "1234", true, targetPaths, map[string]int{
|
||||
"ListHome": 200,
|
||||
"List": 200,
|
||||
"ListTarget": 200,
|
||||
"Mkdir": 200,
|
||||
"MkdirTarget": 200,
|
||||
"Move": 200,
|
||||
"MoveFrom": 200,
|
||||
})
|
||||
testFolderOpPermission("user", "1234", true, map[string]int{
|
||||
"ListHome": 200,
|
||||
"List": 200,
|
||||
"ListPaths": 403,
|
||||
"Mkdir": 200,
|
||||
"Move": 200,
|
||||
testFolderOpPermission("user folder operations", "user", "1234", true, targetPaths, map[string]int{
|
||||
"ListHome": 200,
|
||||
"List": 200,
|
||||
"ListTarget": 403,
|
||||
"Mkdir": 200,
|
||||
"MkdirTarget": 403,
|
||||
"Move": 200,
|
||||
"MoveFrom": 403,
|
||||
})
|
||||
testFolderOpPermission("visitor", "", false, map[string]int{
|
||||
"ListHome": 403,
|
||||
"List": 403,
|
||||
"ListPaths": 403,
|
||||
"Mkdir": 403,
|
||||
"Move": 403,
|
||||
testFolderOpPermission("visitor folder operations", "visitor", "", false, targetPaths, map[string]int{
|
||||
"ListHome": 403,
|
||||
"List": 403,
|
||||
"ListTarget": 403,
|
||||
"Mkdir": 403,
|
||||
"MkdirTarget": 403,
|
||||
"Move": 403,
|
||||
"MoveFrom": 403,
|
||||
})
|
||||
|
||||
testFileOpPermission := func(user string, pwd string, requireAuth bool, targetPath, targetFile string, expectedCodes map[string]int) {
|
||||
uploadSample := func() {
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
|
||||
resp, _, errs := cl.Login("user2", "1234")
|
||||
if len(errs) > 0 {
|
||||
t.Fatal(errs)
|
||||
} else if resp.StatusCode != 200 {
|
||||
t.Fatal(resp.StatusCode)
|
||||
}
|
||||
token = client.GetCookie(resp.Cookies(), q.TokenCookie)
|
||||
assertUploadOK(t, "user2/files/upload", "101", addr, token)
|
||||
}
|
||||
uploadSample()
|
||||
|
||||
// test file operations in targetPath with targetFile
|
||||
testFileOpPermission := func(desc, user string, pwd string, requireAuth bool, targetPath, targetFile string, expectedCodes map[string]int) {
|
||||
// Create
|
||||
// UploadChunk
|
||||
// UploadStatus
|
||||
|
@ -354,64 +415,77 @@ func TestPermissions(t *testing.T) {
|
|||
token = client.GetCookie(resp.Cookies(), q.TokenCookie)
|
||||
}
|
||||
|
||||
desc := user
|
||||
fileContent := []byte("01010")
|
||||
filePath := filepath.Join(targetPath, "old")
|
||||
fileSize := int64(len(fileContent))
|
||||
filesCl := client.NewFilesClient(addr, token)
|
||||
base64Content := base64.StdEncoding.EncodeToString([]byte(fileContent))
|
||||
newPath := filepath.Join(targetPath, "new")
|
||||
|
||||
resp, _, errs := filesCl.ListHome()
|
||||
resp, lhResp, errs := filesCl.ListHome()
|
||||
assertResp(t, resp, errs, expectedCodes["ListHome"], fmt.Sprintf("%s-%s", desc, "ListHome"))
|
||||
|
||||
resp, _, errs = filesCl.List(targetPath)
|
||||
assertResp(t, resp, errs, expectedCodes["ListTarget"], fmt.Sprintf("%s-%s", desc, "ListTarget"))
|
||||
|
||||
fileContent := []byte("01010")
|
||||
fileSize := int64(len(fileContent))
|
||||
base64Content := base64.StdEncoding.EncodeToString([]byte(fileContent))
|
||||
filePath := filepath.Join(lhResp.Cwd, "old")
|
||||
homeNewPath := filepath.Join(lhResp.Cwd, "new")
|
||||
targetPathFile := filepath.Join(targetPath, user)
|
||||
|
||||
resp, _, errs = filesCl.Create(filePath, fileSize)
|
||||
assertResp(t, resp, errs, expectedCodes["Create"], fmt.Sprintf("%s-%s", desc, "Create"))
|
||||
assertResp(t, resp, errs, expectedCodes["Create"], fmt.Sprintf("%s-%s", desc, "Create1"))
|
||||
resp, _, errs = filesCl.Create(targetPathFile, fileSize)
|
||||
assertResp(t, resp, errs, expectedCodes["CreateTarget"], fmt.Sprintf("%s-%s", desc, "CreateTarget"))
|
||||
|
||||
resp, _, errs = filesCl.UploadStatus(filePath)
|
||||
assertResp(t, resp, errs, expectedCodes["UploadStatus"], fmt.Sprintf("%s-%s", desc, "UploadStatus"))
|
||||
resp, _, errs = filesCl.UploadStatus(targetPathFile)
|
||||
assertResp(t, resp, errs, expectedCodes["UploadStatusTarget"], fmt.Sprintf("%s-%s", desc, "UploadStatusTarget"))
|
||||
|
||||
resp, _, errs = filesCl.ListUploadings()
|
||||
assertResp(t, resp, errs, expectedCodes["ListUploadings"], fmt.Sprintf("%s-%s", desc, "ListUploadings"))
|
||||
|
||||
resp, _, errs = filesCl.DelUploading(filePath)
|
||||
assertResp(t, resp, errs, expectedCodes["DelUploading"], fmt.Sprintf("%s-%s", desc, "DelUploading"))
|
||||
resp, _, errs = filesCl.DelUploading(targetPathFile)
|
||||
assertResp(t, resp, errs, expectedCodes["DelUploadingTarget"], fmt.Sprintf("%s-%s", desc, "DelUploadingTarget"))
|
||||
|
||||
// create again
|
||||
resp, _, errs = filesCl.Create(filePath, fileSize)
|
||||
assertResp(t, resp, errs, expectedCodes["Create"], fmt.Sprintf("%s-%s", desc, "Create"))
|
||||
|
||||
resp, _, errs = filesCl.UploadStatus(filePath)
|
||||
assertResp(t, resp, errs, expectedCodes["UploadStatus"], fmt.Sprintf("%s-%s", desc, "UploadStatus"))
|
||||
assertResp(t, resp, errs, expectedCodes["Create"], fmt.Sprintf("%s-%s", desc, "Create2"))
|
||||
resp, _, errs = filesCl.Create(targetPathFile, fileSize)
|
||||
assertResp(t, resp, errs, expectedCodes["CreateTarget"], fmt.Sprintf("%s-%s", desc, "CreateTarget"))
|
||||
|
||||
resp, _, errs = filesCl.UploadChunk(filePath, base64Content, 0)
|
||||
assertResp(t, resp, errs, expectedCodes["UploadChunk"], fmt.Sprintf("%s-%s", desc, "UploadChunk"))
|
||||
resp, _, errs = filesCl.UploadChunk(targetPathFile, base64Content, 0)
|
||||
assertResp(t, resp, errs, expectedCodes["UploadChunkTarget"], fmt.Sprintf("%s-%s", desc, "UploadChunkTarget"))
|
||||
|
||||
resp, _, errs = filesCl.Metadata(filePath)
|
||||
assertResp(t, resp, errs, expectedCodes["Metadata"], fmt.Sprintf("%s-%s", desc, "Metadata"))
|
||||
|
||||
resp, _, errs = filesCl.Metadata(targetPath)
|
||||
assertResp(t, resp, errs, expectedCodes["MetadataTarget"], fmt.Sprintf("%s-%s", desc, "MetadataTarget"))
|
||||
|
||||
resp, _, errs = filesCl.GenerateHash(filePath)
|
||||
assertResp(t, resp, errs, expectedCodes["GenerateHash"], fmt.Sprintf("%s-%s", desc, "GenerateHash"))
|
||||
|
||||
resp, _, errs = filesCl.GenerateHash(targetFile)
|
||||
resp, _, errs = filesCl.GenerateHash(targetPathFile)
|
||||
assertResp(t, resp, errs, expectedCodes["GenerateHashTarget"], fmt.Sprintf("%s-%s", desc, "GenerateHashTarget"))
|
||||
|
||||
resp, _, errs = filesCl.Download(filePath, map[string]string{})
|
||||
assertResp(t, resp, errs, expectedCodes["Download"], fmt.Sprintf("%s-%s", desc, "Download"))
|
||||
resp, _, errs = filesCl.Download(targetPathFile, map[string]string{})
|
||||
assertResp(t, resp, errs, expectedCodes["DownloadTarget"], fmt.Sprintf("%s-%s", desc, "DownloadTarget"))
|
||||
|
||||
if targetFile != "" {
|
||||
resp, _, errs = filesCl.Download(targetFile, map[string]string{})
|
||||
assertResp(t, resp, errs, expectedCodes["DownloadTarget"], fmt.Sprintf("%s-%s", desc, "DownloadTarget"))
|
||||
assertResp(t, resp, errs, expectedCodes["DownloadTargetFile"], fmt.Sprintf("%s-%s", desc, "DownloadTarget"))
|
||||
}
|
||||
|
||||
resp, _, errs = filesCl.Move(filePath, newPath)
|
||||
resp, _, errs = filesCl.Move(filePath, homeNewPath)
|
||||
assertResp(t, resp, errs, expectedCodes["Move"], fmt.Sprintf("%s-%s", desc, "Move"))
|
||||
// move target is already tested
|
||||
|
||||
resp, _, errs = filesCl.Delete(newPath)
|
||||
resp, _, errs = filesCl.Delete(homeNewPath)
|
||||
assertResp(t, resp, errs, expectedCodes["Delete"], fmt.Sprintf("%s-%s", desc, "Delete"))
|
||||
resp, _, errs = filesCl.Delete(targetPathFile)
|
||||
assertResp(t, resp, errs, expectedCodes["DeleteTarget"], fmt.Sprintf("%s-%s", desc, "DeleteTarget"))
|
||||
|
||||
if requireAuth {
|
||||
resp, _, errs := cl.Logout(token)
|
||||
|
@ -419,78 +493,18 @@ func TestPermissions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
testFileOpPermission("admin", "1234", true, "admin/files", "", map[string]int{
|
||||
"ListHome": 200,
|
||||
"ListTarget": 200,
|
||||
"Create": 200,
|
||||
"ListUploadings": 200,
|
||||
"DelUploading": 200,
|
||||
"UploadChunk": 200,
|
||||
"UploadStatus": 200,
|
||||
"Metadata": 200,
|
||||
"MetadataTarget": 200,
|
||||
"GenerateHash": 200,
|
||||
"GenerateHashTarget": 400,
|
||||
"Move": 200,
|
||||
"Download": 200,
|
||||
"Delete": 200,
|
||||
})
|
||||
testFileOpPermission("user", "1234", true, "user/files", "", map[string]int{
|
||||
"ListHome": 200,
|
||||
"ListTarget": 200,
|
||||
"Create": 200,
|
||||
"ListUploadings": 200,
|
||||
"DelUploading": 200,
|
||||
"UploadChunk": 200,
|
||||
"UploadStatus": 200,
|
||||
"Metadata": 200,
|
||||
"MetadataTarget": 200,
|
||||
"GenerateHash": 200,
|
||||
"GenerateHashTarget": 400,
|
||||
"Move": 200,
|
||||
"Download": 200,
|
||||
"Delete": 200,
|
||||
})
|
||||
testFileOpPermission("visitor", "", false, "user/files", "", map[string]int{
|
||||
"ListHome": 403,
|
||||
"ListTarget": 403,
|
||||
"Create": 403,
|
||||
"ListUploadings": 403,
|
||||
"DelUploading": 403,
|
||||
"UploadChunk": 403,
|
||||
"UploadStatus": 403,
|
||||
"Metadata": 403,
|
||||
"MetadataTarget": 403,
|
||||
"GenerateHash": 403,
|
||||
"GenerateHashTarget": 403,
|
||||
"Move": 403,
|
||||
"Download": 403,
|
||||
"Delete": 403,
|
||||
})
|
||||
|
||||
uploadSample := func() {
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
|
||||
resp, _, errs := cl.Login("user2", "1234")
|
||||
if len(errs) > 0 {
|
||||
t.Fatal(errs)
|
||||
} else if resp.StatusCode != 200 {
|
||||
t.Fatal(resp.StatusCode)
|
||||
}
|
||||
token = client.GetCookie(resp.Cookies(), q.TokenCookie)
|
||||
assertUploadOK(t, "user2/files/upload", "101", addr, token)
|
||||
}
|
||||
uploadSample()
|
||||
|
||||
testFileOpPermission("admin", "1234", true, "user2/files", "user2/files/upload", map[string]int{
|
||||
testFileOpPermission("admin file operations", "admin", "1234", true, "user2/files", "", map[string]int{
|
||||
"ListHome": 200,
|
||||
"ListTarget": 200,
|
||||
"Create": 200,
|
||||
"CreateTarget": 200,
|
||||
"ListUploadings": 200,
|
||||
"DelUploading": 200,
|
||||
"DelUploadingTarget": 200,
|
||||
"UploadChunk": 200,
|
||||
"UploadChunkTarget": 200,
|
||||
"UploadStatus": 200,
|
||||
"UploadStatusTarget": 200,
|
||||
"Metadata": 200,
|
||||
"MetadataTarget": 200,
|
||||
"GenerateHash": 200,
|
||||
|
@ -499,26 +513,54 @@ func TestPermissions(t *testing.T) {
|
|||
"Download": 200,
|
||||
"DownloadTarget": 200,
|
||||
"Delete": 200,
|
||||
"DeleteTarget": 200,
|
||||
})
|
||||
testFileOpPermission("user", "1234", true, "user2/files", "user2/files/upload", map[string]int{
|
||||
testFileOpPermission("user file operations", "user", "1234", true, "user2/files", "", map[string]int{
|
||||
"ListHome": 200,
|
||||
"ListTarget": 403,
|
||||
"Create": 403,
|
||||
"Create": 200,
|
||||
"CreateTarget": 403,
|
||||
"ListUploadings": 200,
|
||||
"DelUploading": 500,
|
||||
"DelUploading": 200,
|
||||
"DelUploadingTarget": 403,
|
||||
"UploadChunk": 200,
|
||||
"UploadChunkTarget": 403,
|
||||
"UploadStatus": 200,
|
||||
"UploadStatusTarget": 403,
|
||||
"Metadata": 200,
|
||||
"MetadataTarget": 403,
|
||||
"GenerateHash": 200,
|
||||
"GenerateHashTarget": 403,
|
||||
"Move": 200,
|
||||
"Download": 200,
|
||||
"DownloadTarget": 403,
|
||||
"Delete": 200,
|
||||
"DeleteTarget": 403,
|
||||
})
|
||||
testFileOpPermission("visitor file operations", "visitor", "", false, "user2/files", "", map[string]int{
|
||||
"ListHome": 403,
|
||||
"ListTarget": 403,
|
||||
"Create": 403,
|
||||
"CreateTarget": 403,
|
||||
"ListUploadings": 403,
|
||||
"DelUploading": 403,
|
||||
"DelUploadingTarget": 403,
|
||||
"UploadChunk": 403,
|
||||
"UploadChunkTarget": 403,
|
||||
"UploadStatus": 403,
|
||||
"UploadStatusTarget": 403,
|
||||
"Metadata": 403,
|
||||
"MetadataTarget": 403,
|
||||
"GenerateHash": 403, // target path is not user's home
|
||||
"GenerateHash": 403,
|
||||
"GenerateHashTarget": 403,
|
||||
"Move": 403,
|
||||
"Download": 403,
|
||||
"DownloadTarget": 403,
|
||||
"Delete": 403,
|
||||
"DeleteTarget": 403,
|
||||
})
|
||||
|
||||
// test sharing permission
|
||||
// sharing permission tests
|
||||
enableSharing := func() {
|
||||
cl := client.NewSingleUserClient(addr)
|
||||
token := &http.Cookie{}
|
||||
|
@ -543,22 +585,28 @@ func TestPermissions(t *testing.T) {
|
|||
}
|
||||
enableSharing()
|
||||
|
||||
testFileOpPermission("user", "1234", true, "share/files", "share/files/share", map[string]int{
|
||||
testFileOpPermission("user file operations in sharing", "user", "1234", true, "share/files", "share/files/share", map[string]int{
|
||||
"ListHome": 200,
|
||||
"ListTarget": 200,
|
||||
"Create": 403,
|
||||
"Create": 200,
|
||||
"CreateTarget": 403,
|
||||
"ListUploadings": 200,
|
||||
"DelUploading": 500,
|
||||
"UploadChunk": 403,
|
||||
"UploadStatus": 403,
|
||||
"Metadata": 403,
|
||||
"DelUploading": 200,
|
||||
"DelUploadingTarget": 403,
|
||||
"UploadChunk": 200,
|
||||
"UploadChunkTarget": 403,
|
||||
"UploadStatus": 200,
|
||||
"UploadStatusTarget": 403,
|
||||
"Metadata": 200,
|
||||
"MetadataTarget": 403,
|
||||
"GenerateHash": 403, // target path is not user's home
|
||||
"GenerateHash": 200,
|
||||
"GenerateHashTarget": 403,
|
||||
"Move": 403,
|
||||
"Download": 404,
|
||||
"DownloadTarget": 200,
|
||||
"Delete": 403,
|
||||
"Move": 200,
|
||||
"Download": 200,
|
||||
"DownloadTarget": 404, // uploading file to sharing folder is not allowd
|
||||
"DownloadTargetFile": 200,
|
||||
"Delete": 200,
|
||||
"DeleteTarget": 403,
|
||||
})
|
||||
|
||||
testShareOpPermission := func(user string, pwd string, requireAuth bool, targetPath string, expectedCodes map[string]int) {
|
||||
|
@ -639,7 +687,7 @@ func TestPermissions(t *testing.T) {
|
|||
"AddSharing": 200,
|
||||
"AddSharingTarget": 403,
|
||||
"IsSharing": 200,
|
||||
"IsSharingTarget": 404, // sharing is deleted by admin
|
||||
"IsSharingTarget": 404, // sharing is deleted in previous test...
|
||||
"ListSharingIDs": 200,
|
||||
"GetSharingDir": 200,
|
||||
"DelSharing": 200,
|
||||
|
@ -650,7 +698,7 @@ func TestPermissions(t *testing.T) {
|
|||
"AddSharing": 403,
|
||||
"AddSharingTarget": 403,
|
||||
"IsSharing": 404,
|
||||
"IsSharingTarget": 404,
|
||||
"IsSharingTarget": 404, // sharing is deleted in previous test...
|
||||
"ListSharingIDs": 403,
|
||||
"GetSharingDir": 400,
|
||||
"DelSharing": 403,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue