test(authz): refine authz tests

This commit is contained in:
hexxa 2022-02-24 22:28:28 +08:00 committed by Hexxa
parent 731e4029c9
commit 0967ca53dc
6 changed files with 241 additions and 229 deletions

View file

@ -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{}

View file

@ -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() {

View file

@ -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))

View file

@ -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"
)

View file

@ -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 {

View file

@ -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,