Skip to content

Commit

Permalink
fix(permission): enhance the strictness of permissions (#7705 close #…
Browse files Browse the repository at this point in the history
…7680)

* fix(permission): enhance the strictness of permissions

* fix: add initial permissions to admin
  • Loading branch information
KirCute authored Dec 25, 2024
1 parent 5ecf5e8 commit 48916cd
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 33 deletions.
13 changes: 7 additions & 6 deletions internal/bootstrap/data/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ func initUser() {
if errors.Is(err, gorm.ErrRecordNotFound) {
salt := random.String(16)
admin = &model.User{
Username: "admin",
Salt: salt,
PwdHash: model.TwoHashPwd(adminPassword, salt),
Role: model.ADMIN,
BasePath: "/",
Authn: "[]",
Username: "admin",
Salt: salt,
PwdHash: model.TwoHashPwd(adminPassword, salt),
Role: model.ADMIN,
BasePath: "/",
Authn: "[]",
Permission: 0xFF, // 0(can see hidden) - 7(can remove)
}
if err := op.CreateUser(admin); err != nil {
panic(err)
Expand Down
42 changes: 22 additions & 20 deletions internal/model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,18 @@ type User struct {
Role int `json:"role"` // user's role
Disabled bool `json:"disabled"`
// Determine permissions by bit
// 0: can see hidden files
// 1: can access without password
// 2: can add offline download tasks
// 3: can mkdir and upload
// 4: can rename
// 5: can move
// 6: can copy
// 7: can remove
// 8: webdav read
// 9: webdav write
// 0: can see hidden files
// 1: can access without password
// 2: can add offline download tasks
// 3: can mkdir and upload
// 4: can rename
// 5: can move
// 6: can copy
// 7: can remove
// 8: webdav read
// 9: webdav write
// 10: ftp/sftp login and read
// 11: ftp/sftp write
Permission int32 `json:"permission"`
OtpSecret string `json:"-"`
SsoID string `json:"sso_id"` // unique by sso platform
Expand Down Expand Up @@ -78,43 +80,43 @@ func (u *User) SetPassword(pwd string) *User {
}

func (u *User) CanSeeHides() bool {
return u.IsAdmin() || u.Permission&1 == 1
return u.Permission&1 == 1
}

func (u *User) CanAccessWithoutPassword() bool {
return u.IsAdmin() || (u.Permission>>1)&1 == 1
return (u.Permission>>1)&1 == 1
}

func (u *User) CanAddOfflineDownloadTasks() bool {
return u.IsAdmin() || (u.Permission>>2)&1 == 1
return (u.Permission>>2)&1 == 1
}

func (u *User) CanWrite() bool {
return u.IsAdmin() || (u.Permission>>3)&1 == 1
return (u.Permission>>3)&1 == 1
}

func (u *User) CanRename() bool {
return u.IsAdmin() || (u.Permission>>4)&1 == 1
return (u.Permission>>4)&1 == 1
}

func (u *User) CanMove() bool {
return u.IsAdmin() || (u.Permission>>5)&1 == 1
return (u.Permission>>5)&1 == 1
}

func (u *User) CanCopy() bool {
return u.IsAdmin() || (u.Permission>>6)&1 == 1
return (u.Permission>>6)&1 == 1
}

func (u *User) CanRemove() bool {
return u.IsAdmin() || (u.Permission>>7)&1 == 1
return (u.Permission>>7)&1 == 1
}

func (u *User) CanWebdavRead() bool {
return u.IsAdmin() || (u.Permission>>8)&1 == 1
return (u.Permission>>8)&1 == 1
}

func (u *User) CanWebdavManage() bool {
return u.IsAdmin() || (u.Permission>>9)&1 == 1
return (u.Permission>>9)&1 == 1
}

func (u *User) CanFTPAccess() bool {
Expand Down
28 changes: 21 additions & 7 deletions server/webdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/internal/setting"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/server/webdav"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -99,12 +98,27 @@ func WebDAVAuth(c *gin.Context) {
c.Abort()
return
}
if !user.CanWebdavManage() && utils.SliceContains([]string{"PUT", "DELETE", "PROPPATCH", "MKCOL", "COPY", "MOVE"}, c.Request.Method) {
if c.Request.Method == "OPTIONS" {
c.Set("user", guest)
c.Next()
return
}
if (c.Request.Method == "PUT" || c.Request.Method == "MKCOL") && (!user.CanWebdavManage() || !user.CanWrite()) {
c.Status(http.StatusForbidden)
c.Abort()
return
}
if c.Request.Method == "MOVE" && (!user.CanWebdavManage() || (!user.CanMove() && !user.CanRename())) {
c.Status(http.StatusForbidden)
c.Abort()
return
}
if c.Request.Method == "COPY" && (!user.CanWebdavManage() || !user.CanCopy()) {
c.Status(http.StatusForbidden)
c.Abort()
return
}
if c.Request.Method == "DELETE" && (!user.CanWebdavManage() || !user.CanRemove()) {
c.Status(http.StatusForbidden)
c.Abort()
return
}
if c.Request.Method == "PROPPATCH" && !user.CanWebdavManage() {
c.Status(http.StatusForbidden)
c.Abort()
return
Expand Down
7 changes: 7 additions & 0 deletions server/webdav/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ func moveFiles(ctx context.Context, src, dst string, overwrite bool) (status int
dstDir := path.Dir(dst)
srcName := path.Base(src)
dstName := path.Base(dst)
user := ctx.Value("user").(*model.User)
if srcDir != dstDir && !user.CanMove() {
return http.StatusForbidden, nil
}
if srcName != dstName && !user.CanRename() {
return http.StatusForbidden, nil
}
if srcDir == dstDir {
err = fs.Rename(ctx, src, dstName)
} else {
Expand Down

1 comment on commit 48916cd

@Clouddark75
Copy link

@Clouddark75 Clouddark75 commented on 48916cd Dec 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can no longer access webdav after this on the beta build, and on the site, whenever you try to refresh, it will prompt a password box. However, even if you don't input anything, it will still let you in. The thing is, I don't have any "meta" enabled, so I can't access webdav. On the website, it keeps asking for a password if you refresh inside of a list (not by the browser itself). Any fix for this? Thanks.

Please sign in to comment.