feat(admin): enable multi-users (#67)

* feat(userstore): support ListUsers

* feat(userstore): support del users

* feat(multiusers): support list users and delete user apis

* feat(client/web): add new apis to web client

* fix(ui/panes): move each pane out of the container

* feat(ui): add admin pane

* feat(users): support force set password api

* feat(ui/admin-pane): add functions to admin pane

* feat(users): support self API and move uploading folder to home

* fix(users): remove home folder when deleting user

* fix(ui): remove useless function

* feat(ui/panes): hide admin menu if user is not admin

* fix(server/files): list home path is incorrect

* fix(server): 1.listHome return incorrect cwd 2.addUser init folder with incorrect uid 3.check ns before using

* test(server): add regression test cases

* test(users, files): add e2e test for concurrent operations

* fix(test): clean ups
This commit is contained in:
Hexxa 2021-07-30 21:59:33 -05:00 committed by GitHub
parent 916ec7c2dc
commit aefaca98b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1562 additions and 478 deletions

View file

@ -26,20 +26,22 @@ const (
)
type User struct {
ID uint64
Name string
Pwd string
Role string
ID uint64 `json:"id,string"`
Name string `json:"name"`
Pwd string `json:"pwd"`
Role string `json:"role"`
}
type IUserStore interface {
Init(rootName, rootPwd string) error
IsInited() bool
AddUser(user *User) error
DelUser(id uint64) error
GetUser(id uint64) (*User, error)
GetUserByName(name string) (*User, error)
SetName(id uint64, name string) error
SetPwd(id uint64, pwd string) error
ListUsers() ([]*User, error)
SetRole(id uint64, role string) error
AddRole(role string) error
DelRole(role string) error
@ -135,6 +137,27 @@ func (us *KVUserStore) AddUser(user *User) error {
return us.store.SetStringIn(RolesNs, userID, user.Role)
}
func (us *KVUserStore) DelUser(id uint64) error {
us.mtx.Lock()
defer us.mtx.Unlock()
userID := fmt.Sprint(id)
name, ok := us.store.GetStringIn(NamesNs, userID)
if !ok {
return fmt.Errorf("userID (%s) exists", userID)
}
// TODO: add complement operations if part of the actions fails
err1 := us.store.DelStringIn(NamesNs, userID)
err2 := us.store.DelStringIn(IDsNs, name)
err3 := us.store.DelStringIn(PwdsNs, userID)
err4 := us.store.DelStringIn(RolesNs, userID)
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
return fmt.Errorf("get name(%s) id(%s) pwd(%s) role(%s)", err1, err2, err3, err4)
}
return nil
}
func (us *KVUserStore) GetUser(id uint64) (*User, error) {
us.mtx.RLock()
defer us.mtx.RUnlock()
@ -258,6 +281,37 @@ func (us *KVUserStore) SetRole(id uint64, role string) error {
return us.store.SetStringIn(RolesNs, userID, role)
}
func (us *KVUserStore) ListUsers() ([]*User, error) {
us.mtx.RLock()
defer us.mtx.RUnlock()
idToName, err := us.store.ListStringsIn(NamesNs)
if err != nil {
return nil, err
}
roles, err := us.store.ListStringsIn(RolesNs)
if err != nil {
return nil, err
}
users := []*User{}
for id, name := range idToName {
intID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
return nil, err
}
users = append(users, &User{
ID: intID,
Name: name,
Role: roles[id],
})
}
return users, nil
}
func (us *KVUserStore) AddRole(role string) error {
us.mtx.Lock()
defer us.mtx.Unlock()