Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/db/user.go
2322 views
1
package db
2
3
import (
4
"encoding/base64"
5
"fmt"
6
"github.com/alist-org/alist/v3/internal/model"
7
"github.com/alist-org/alist/v3/pkg/utils"
8
"github.com/go-webauthn/webauthn/webauthn"
9
"github.com/pkg/errors"
10
"gorm.io/gorm"
11
"path"
12
"slices"
13
"strings"
14
)
15
16
func GetUserByRole(role int) (*model.User, error) {
17
var users []model.User
18
if err := db.Find(&users).Error; err != nil {
19
return nil, err
20
}
21
for i := range users {
22
if users[i].Role.Contains(role) {
23
return &users[i], nil
24
}
25
}
26
return nil, gorm.ErrRecordNotFound
27
}
28
29
func GetUsersByRole(roleID int) ([]model.User, error) {
30
var users []model.User
31
if err := db.Find(&users).Error; err != nil {
32
return nil, err
33
}
34
var result []model.User
35
for _, u := range users {
36
if slices.Contains(u.Role, roleID) {
37
result = append(result, u)
38
}
39
}
40
return result, nil
41
}
42
43
func GetUserByName(username string) (*model.User, error) {
44
user := model.User{Username: username}
45
if err := db.Where(user).First(&user).Error; err != nil {
46
return nil, errors.Wrapf(err, "failed find user")
47
}
48
return &user, nil
49
}
50
51
func GetUserBySSOID(ssoID string) (*model.User, error) {
52
user := model.User{SsoID: ssoID}
53
if err := db.Where(user).First(&user).Error; err != nil {
54
return nil, errors.Wrapf(err, "The single sign on platform is not bound to any users")
55
}
56
return &user, nil
57
}
58
59
func GetUserById(id uint) (*model.User, error) {
60
var u model.User
61
if err := db.First(&u, id).Error; err != nil {
62
return nil, errors.Wrapf(err, "failed get old user")
63
}
64
return &u, nil
65
}
66
67
func CreateUser(u *model.User) error {
68
return errors.WithStack(db.Create(u).Error)
69
}
70
71
func UpdateUser(u *model.User) error {
72
return errors.WithStack(db.Save(u).Error)
73
}
74
75
func GetUsers(pageIndex, pageSize int) (users []model.User, count int64, err error) {
76
userDB := db.Model(&model.User{})
77
if err := userDB.Count(&count).Error; err != nil {
78
return nil, 0, errors.Wrapf(err, "failed get users count")
79
}
80
if err := userDB.Order(columnName("id")).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&users).Error; err != nil {
81
return nil, 0, errors.Wrapf(err, "failed get find users")
82
}
83
return users, count, nil
84
}
85
86
func GetAllUsers() ([]model.User, error) {
87
var users []model.User
88
if err := db.Find(&users).Error; err != nil {
89
return nil, errors.WithStack(err)
90
}
91
return users, nil
92
}
93
94
func DeleteUserById(id uint) error {
95
return errors.WithStack(db.Delete(&model.User{}, id).Error)
96
}
97
98
func UpdateAuthn(userID uint, authn string) error {
99
return db.Model(&model.User{ID: userID}).Update("authn", authn).Error
100
}
101
102
func RegisterAuthn(u *model.User, credential *webauthn.Credential) error {
103
if u == nil {
104
return errors.New("user is nil")
105
}
106
exists := u.WebAuthnCredentials()
107
if credential != nil {
108
exists = append(exists, *credential)
109
}
110
res, err := utils.Json.Marshal(exists)
111
if err != nil {
112
return err
113
}
114
return UpdateAuthn(u.ID, string(res))
115
}
116
117
func RemoveAuthn(u *model.User, id string) error {
118
exists := u.WebAuthnCredentials()
119
for i := 0; i < len(exists); i++ {
120
idEncoded := base64.StdEncoding.EncodeToString(exists[i].ID)
121
if idEncoded == id {
122
exists[len(exists)-1], exists[i] = exists[i], exists[len(exists)-1]
123
exists = exists[:len(exists)-1]
124
break
125
}
126
}
127
128
res, err := utils.Json.Marshal(exists)
129
if err != nil {
130
return err
131
}
132
return UpdateAuthn(u.ID, string(res))
133
}
134
135
func UpdateUserBasePathPrefix(oldPath, newPath string, usersOpt ...[]model.User) ([]string, error) {
136
var users []model.User
137
var modifiedUsernames []string
138
139
oldPathClean := path.Clean(oldPath)
140
141
if len(usersOpt) > 0 {
142
users = usersOpt[0]
143
} else {
144
if err := db.Find(&users).Error; err != nil {
145
return nil, errors.WithMessage(err, "failed to load users")
146
}
147
}
148
149
for _, user := range users {
150
basePath := path.Clean(user.BasePath)
151
updated := false
152
153
if basePath == oldPathClean {
154
user.BasePath = path.Clean(newPath)
155
updated = true
156
} else if strings.HasPrefix(basePath, oldPathClean+"/") {
157
user.BasePath = path.Clean(newPath + basePath[len(oldPathClean):])
158
updated = true
159
}
160
161
if updated {
162
if err := UpdateUser(&user); err != nil {
163
return nil, errors.WithMessagef(err, "failed to update user ID %d", user.ID)
164
}
165
modifiedUsernames = append(modifiedUsernames, user.Username)
166
}
167
}
168
169
return modifiedUsernames, nil
170
}
171
172
func CountUsersByRoleAndEnabledExclude(roleID uint, excludeUserID uint) (int64, error) {
173
var count int64
174
jsonValue := fmt.Sprintf("[%d]", roleID)
175
err := db.Model(&model.User{}).
176
Where("disabled = ? AND id != ?", false, excludeUserID).
177
Where("JSON_CONTAINS(role, ?)", jsonValue).
178
Count(&count).Error
179
return count, err
180
}
181
182