-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(permissions): implement fine-grained permission control #2145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
PIKACHUIM
merged 11 commits into
OpenListTeam:main
from
Lanfei:feat/fine-grained-permissions
Mar 26, 2026
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
6a8d07b
refactor(permission): rename permission check functions for clarity
Lanfei bd76974
feat(permission): implement fine-grained user permissions for read/wr…
Lanfei ced0414
test(permission): add comprehensive tests for CanRead, CanWrite, and …
Lanfei 5bba669
fix(webdav): use safe type assertion for MetaPassKey to prevent panic
Lanfei 27bab76
fix(permission): treat nil user as system context in CanRead/CanWrite
Lanfei b52c6e0
fix(fsmanage): prevent path traversal in FsRemove
Lanfei 814e995
fix(webdav): align MetaPassKey behavior with FTP auth logic
Lanfei 47a58a1
fix(permission): require write auth for fs list refresh
Lanfei 5b47335
refactor(permission): use MetaCoversPath in CanRead/CanWrite for cons…
Lanfei d618739
Merge branch 'main' into feat/fine-grained-permissions
PIKACHUIM c6d0c79
Merge branch 'main' into feat/fine-grained-permissions
PIKACHUIM File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| package fs | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/OpenListTeam/OpenList/v4/internal/model" | ||
| ) | ||
|
|
||
| func TestWhetherHide(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| user *model.User | ||
| meta *model.Meta | ||
| path string | ||
| want bool | ||
| reason string | ||
| }{ | ||
| { | ||
| name: "nil user", | ||
| user: nil, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: true, | ||
| }, | ||
| path: "/folder", | ||
| want: false, | ||
| reason: "nil user (treated as admin) should not hide", | ||
| }, | ||
| { | ||
| name: "user with can_see_hides permission", | ||
| user: &model.User{ | ||
| Role: model.GENERAL, | ||
| Permission: 1, // bit 0 set = can see hides | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: true, | ||
| }, | ||
| path: "/folder", | ||
| want: false, | ||
| reason: "user with can_see_hides permission should not hide", | ||
| }, | ||
| { | ||
| name: "nil meta", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: nil, | ||
| path: "/folder", | ||
| want: false, | ||
| reason: "nil meta should not hide", | ||
| }, | ||
| { | ||
| name: "empty hide string", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "", | ||
| HSub: true, | ||
| }, | ||
| path: "/folder", | ||
| want: false, | ||
| reason: "empty hide string should not hide", | ||
| }, | ||
| { | ||
| name: "exact path match with HSub=false", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: false, | ||
| }, | ||
| path: "/folder", | ||
| want: true, | ||
| reason: "exact path match should hide for guest", | ||
| }, | ||
| { | ||
| name: "sub path with HSub=true", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: true, | ||
| }, | ||
| path: "/folder/subfolder", | ||
| want: true, | ||
| reason: "sub path with HSub=true should hide for guest", | ||
| }, | ||
| { | ||
| name: "sub path with HSub=false", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: false, | ||
| }, | ||
| path: "/folder/subfolder", | ||
| want: false, | ||
| reason: "sub path with HSub=false should not hide", | ||
| }, | ||
| { | ||
| name: "non-sub path with HSub=true", | ||
| user: &model.User{ | ||
| Role: model.GUEST, | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: true, | ||
| }, | ||
| path: "/other", | ||
| want: false, | ||
| reason: "non-sub path should not hide even with HSub=true", | ||
| }, | ||
| { | ||
| name: "user without can_see_hides permission", | ||
| user: &model.User{ | ||
| Role: model.GENERAL, | ||
| Permission: 0, // bit 0 not set = cannot see hides | ||
| }, | ||
| meta: &model.Meta{ | ||
| Path: "/folder", | ||
| Hide: "secret", | ||
| HSub: true, | ||
| }, | ||
| path: "/folder", | ||
| want: true, | ||
| reason: "user without can_see_hides permission should hide", | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| got := whetherHide(tt.user, tt.meta, tt.path) | ||
| if got != tt.want { | ||
| t.Errorf("whetherHide() = %v, want %v\nReason: %s", | ||
| got, tt.want, tt.reason) | ||
| } | ||
| }) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,20 @@ | ||
| package model | ||
|
|
||
| type Meta struct { | ||
| ID uint `json:"id" gorm:"primaryKey"` | ||
| Path string `json:"path" gorm:"unique" binding:"required"` | ||
| Password string `json:"password"` | ||
| PSub bool `json:"p_sub"` | ||
| Write bool `json:"write"` | ||
| WSub bool `json:"w_sub"` | ||
| Hide string `json:"hide"` | ||
| HSub bool `json:"h_sub"` | ||
| Readme string `json:"readme"` | ||
| RSub bool `json:"r_sub"` | ||
| Header string `json:"header"` | ||
| HeaderSub bool `json:"header_sub"` | ||
| ID uint `json:"id" gorm:"primaryKey"` | ||
| Path string `json:"path" gorm:"unique" binding:"required"` | ||
| ReadUsers []uint `json:"read_users" gorm:"serializer:json"` | ||
| ReadUsersSub bool `json:"read_users_sub"` | ||
| WriteUsers []uint `json:"write_users" gorm:"serializer:json"` | ||
| WriteUsersSub bool `json:"write_users_sub"` | ||
| Password string `json:"password"` | ||
| PSub bool `json:"p_sub"` | ||
| Write bool `json:"write"` | ||
| WSub bool `json:"w_sub"` | ||
| Hide string `json:"hide"` | ||
| HSub bool `json:"h_sub"` | ||
| Readme string `json:"readme"` | ||
| RSub bool `json:"r_sub"` | ||
| Header string `json:"header"` | ||
| HeaderSub bool `json:"header_sub"` | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.