Compare commits
2 Commits
ed4a10c966
...
db41f565ca
Author | SHA1 | Date | |
---|---|---|---|
db41f565ca | |||
20cb97f90f |
16
api/http.go
16
api/http.go
@ -235,3 +235,19 @@ func (s *HTTPServer) HandlerAPIUserCreate(w http.ResponseWriter, r *http.Request
|
|||||||
w.WriteHeader(http.StatusAccepted)
|
w.WriteHeader(http.StatusAccepted)
|
||||||
s.Logger.Infow("Created user.", "req_id", reqID, "remote_addr", r.RemoteAddr, "username", req.Username)
|
s.Logger.Infow("Created user.", "req_id", reqID, "remote_addr", r.RemoteAddr, "username", req.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HTTPServer) HandlerAPIUserList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
reqID := middleware.GetReqID(r.Context())
|
||||||
|
|
||||||
|
l, err := s.Users.List()
|
||||||
|
if err != nil {
|
||||||
|
s.Logger.Warnw("Error listing users.", "req_id", reqID, "error", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
if err := encoder.Encode(l); err != nil {
|
||||||
|
s.Logger.Warnw("Error encoding response.", "req_id", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,3 +18,7 @@ type ResponseAPIFilePost struct {
|
|||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResponseAPIUserList struct {
|
||||||
|
Usernames []string `json:"usernames"`
|
||||||
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package users
|
package users
|
||||||
|
|
||||||
import "golang.org/x/crypto/bcrypt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
type Role string
|
type Role string
|
||||||
|
|
||||||
@ -16,10 +20,13 @@ type User struct {
|
|||||||
Role Role `json:"role"`
|
Role Role `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrNoSuchUser = fmt.Errorf("no such user")
|
||||||
|
|
||||||
type UserStore interface {
|
type UserStore interface {
|
||||||
Get(username string) (*User, error)
|
Get(username string) (*User, error)
|
||||||
Store(user *User) error
|
Store(user *User) error
|
||||||
Delete(username string) error
|
Delete(username string) error
|
||||||
|
List() ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) ValidatePassword(password string) error {
|
func (u *User) ValidatePassword(password string) error {
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ UserStore = &BoltUserStore{}
|
||||||
|
|
||||||
var keyUsers = []byte("users")
|
var keyUsers = []byte("users")
|
||||||
|
|
||||||
type BoltUserStore struct {
|
type BoltUserStore struct {
|
||||||
@ -67,3 +69,22 @@ func (s *BoltUserStore) Delete(username string) error {
|
|||||||
return bkt.Delete([]byte(username))
|
return bkt.Delete([]byte(username))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
func (s *BoltUserStore) List() ([]string, error) {
|
||||||
|
var ids []string
|
||||||
|
|
||||||
|
err := s.db.View(func(tx *bbolt.Tx) error {
|
||||||
|
bkt := tx.Bucket(keyUsers)
|
||||||
|
|
||||||
|
c := bkt.Cursor()
|
||||||
|
|
||||||
|
for k, _ := c.First(); k != nil; k, _ = c.Next() {
|
||||||
|
ids = append(ids, string(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ UserStore = &MemoryUserStore{}
|
||||||
|
|
||||||
type MemoryUserStore struct {
|
type MemoryUserStore struct {
|
||||||
users map[string]*User
|
users map[string]*User
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
@ -37,3 +39,14 @@ func (s *MemoryUserStore) Delete(username string) error {
|
|||||||
delete(s.users, username)
|
delete(s.users, username)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (s *MemoryUserStore) List() ([]string, error) {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
var ids []string
|
||||||
|
for k := range s.users {
|
||||||
|
ids = append(ids, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
@ -47,5 +47,27 @@ func RunUserStoreTest(newFunc func() (func(), users.UserStore), t *testing.T) {
|
|||||||
t.Errorf("User mismatch: %s", cmp.Diff(user, userMap[k]))
|
t.Errorf("User mismatch: %s", cmp.Diff(user, userMap[k]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l, err := s.List()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error listing users: %s", err)
|
||||||
|
}
|
||||||
|
if len(l) != len(userMap) {
|
||||||
|
t.Errorf("List wrong amount of users.")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, username := range l {
|
||||||
|
if err := s.Delete(username); err != nil {
|
||||||
|
t.Fatalf("Error deleting user: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err = s.List()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error listing after delete: %s", err)
|
||||||
|
}
|
||||||
|
if len(l) != 0 {
|
||||||
|
t.Fatalf("List is not empty after deleting all")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user