Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/op/role.go
1560 views
1
package op
2
3
import (
4
"fmt"
5
"strconv"
6
"time"
7
8
"github.com/Xhofe/go-cache"
9
"github.com/alist-org/alist/v3/internal/conf"
10
"github.com/alist-org/alist/v3/internal/db"
11
"github.com/alist-org/alist/v3/internal/errs"
12
"github.com/alist-org/alist/v3/internal/model"
13
"github.com/alist-org/alist/v3/pkg/singleflight"
14
"github.com/alist-org/alist/v3/pkg/utils"
15
)
16
17
var roleCache = cache.NewMemCache[*model.Role](cache.WithShards[*model.Role](2))
18
var roleG singleflight.Group[*model.Role]
19
20
func init() {
21
model.FetchRole = GetRole
22
}
23
24
func GetRole(id uint) (*model.Role, error) {
25
key := fmt.Sprint(id)
26
if r, ok := roleCache.Get(key); ok {
27
return r, nil
28
}
29
r, err, _ := roleG.Do(key, func() (*model.Role, error) {
30
_r, err := db.GetRole(id)
31
if err != nil {
32
return nil, err
33
}
34
roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
35
return _r, nil
36
})
37
return r, err
38
}
39
40
func GetRoleByName(name string) (*model.Role, error) {
41
if r, ok := roleCache.Get(name); ok {
42
return r, nil
43
}
44
r, err, _ := roleG.Do(name, func() (*model.Role, error) {
45
_r, err := db.GetRoleByName(name)
46
if err != nil {
47
return nil, err
48
}
49
roleCache.Set(name, _r, cache.WithEx[*model.Role](time.Hour))
50
return _r, nil
51
})
52
return r, err
53
}
54
55
func GetDefaultRoleID() int {
56
item, err := GetSettingItemByKey(conf.DefaultRole)
57
if err == nil && item != nil && item.Value != "" {
58
if id, err := strconv.Atoi(item.Value); err == nil && id != 0 {
59
return id
60
}
61
if r, err := db.GetRoleByName(item.Value); err == nil {
62
return int(r.ID)
63
}
64
}
65
var r model.Role
66
if err := db.GetDb().Where("`default` = ?", true).First(&r).Error; err == nil {
67
return int(r.ID)
68
}
69
return int(model.GUEST)
70
}
71
72
func GetRolesByUserID(userID uint) ([]model.Role, error) {
73
user, err := GetUserById(userID)
74
if err != nil {
75
return nil, err
76
}
77
78
var roles []model.Role
79
for _, roleID := range user.Role {
80
key := fmt.Sprint(roleID)
81
82
if r, ok := roleCache.Get(key); ok {
83
roles = append(roles, *r)
84
continue
85
}
86
87
r, err, _ := roleG.Do(key, func() (*model.Role, error) {
88
_r, err := db.GetRole(uint(roleID))
89
if err != nil {
90
return nil, err
91
}
92
roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
93
return _r, nil
94
})
95
if err != nil {
96
return nil, err
97
}
98
roles = append(roles, *r)
99
}
100
101
return roles, nil
102
}
103
104
func GetRoles(pageIndex, pageSize int) ([]model.Role, int64, error) {
105
return db.GetRoles(pageIndex, pageSize)
106
}
107
108
func CreateRole(r *model.Role) error {
109
for i := range r.PermissionScopes {
110
r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)
111
}
112
roleCache.Del(fmt.Sprint(r.ID))
113
roleCache.Del(r.Name)
114
if err := db.CreateRole(r); err != nil {
115
return err
116
}
117
if r.Default {
118
roleCache.Clear()
119
item, err := GetSettingItemByKey(conf.DefaultRole)
120
if err != nil {
121
return err
122
}
123
item.Value = strconv.Itoa(int(r.ID))
124
if err := SaveSettingItem(item); err != nil {
125
return err
126
}
127
}
128
return nil
129
}
130
131
func UpdateRole(r *model.Role) error {
132
old, err := db.GetRole(r.ID)
133
if err != nil {
134
return err
135
}
136
switch old.Name {
137
case "admin":
138
return errs.ErrChangeDefaultRole
139
case "guest":
140
r.Name = "guest"
141
}
142
for i := range r.PermissionScopes {
143
r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)
144
}
145
//if len(old.PermissionScopes) > 0 && len(r.PermissionScopes) > 0 &&
146
// old.PermissionScopes[0].Path != r.PermissionScopes[0].Path {
147
//
148
// oldPath := old.PermissionScopes[0].Path
149
// newPath := r.PermissionScopes[0].Path
150
//
151
// users, err := db.GetUsersByRole(int(r.ID))
152
// if err != nil {
153
// return errors.WithMessage(err, "failed to get users by role")
154
// }
155
//
156
// modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldPath, newPath, users)
157
// if err != nil {
158
// return errors.WithMessage(err, "failed to update user base path when role updated")
159
// }
160
//
161
// for _, name := range modifiedUsernames {
162
// userCache.Del(name)
163
// }
164
//}
165
roleCache.Del(fmt.Sprint(r.ID))
166
roleCache.Del(r.Name)
167
if err := db.UpdateRole(r); err != nil {
168
return err
169
}
170
if r.Default {
171
roleCache.Clear()
172
item, err := GetSettingItemByKey(conf.DefaultRole)
173
if err != nil {
174
return err
175
}
176
item.Value = strconv.Itoa(int(r.ID))
177
if err := SaveSettingItem(item); err != nil {
178
return err
179
}
180
}
181
return nil
182
}
183
184
func DeleteRole(id uint) error {
185
old, err := db.GetRole(id)
186
if err != nil {
187
return err
188
}
189
if old.Name == "admin" || old.Name == "guest" {
190
return errs.ErrChangeDefaultRole
191
}
192
roleCache.Del(fmt.Sprint(id))
193
roleCache.Del(old.Name)
194
return db.DeleteRole(id)
195
}
196
197