Create users package
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
c6b282fbcc
commit
d4b7702bad
5
auth.go
5
auth.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
@ -17,11 +18,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type AuthService struct {
|
type AuthService struct {
|
||||||
users UserStore
|
users users.UserStore
|
||||||
hmacSecret []byte
|
hmacSecret []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthService(store UserStore, signingSecret []byte) *AuthService {
|
func NewAuthService(store users.UserStore, signingSecret []byte) *AuthService {
|
||||||
return &AuthService{users: store, hmacSecret: signingSecret}
|
return &AuthService{users: store, hmacSecret: signingSecret}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
auth_test.go
16
auth_test.go
@ -1,21 +1,23 @@
|
|||||||
package gpaste_test
|
package gpaste_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
"git.t-juice.club/torjus/gpaste"
|
||||||
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAuth(t *testing.T) {
|
func TestAuth(t *testing.T) {
|
||||||
t.Run("Token", func(t *testing.T) {
|
t.Run("Token", func(t *testing.T) {
|
||||||
us := gpaste.NewMemoryUserStore()
|
us := users.NewMemoryUserStore()
|
||||||
secret := []byte(randomString(16))
|
secret := []byte(randomString(16))
|
||||||
as := gpaste.NewAuthService(us, secret)
|
as := gpaste.NewAuthService(us, secret)
|
||||||
|
|
||||||
username := randomString(8)
|
username := randomString(8)
|
||||||
password := randomString(16)
|
password := randomString(16)
|
||||||
|
|
||||||
user := &gpaste.User{Username: username}
|
user := &users.User{Username: username}
|
||||||
if err := user.SetPassword(password); err != nil {
|
if err := user.SetPassword(password); err != nil {
|
||||||
t.Fatalf("error setting user password: %s", err)
|
t.Fatalf("error setting user password: %s", err)
|
||||||
}
|
}
|
||||||
@ -37,3 +39,13 @@ func TestAuth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomString(length int) string {
|
||||||
|
const charset = "abcdefghijklmnopqrstabcdefghijklmnopqrstuvwxyz" +
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
b := make([]byte, length)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = charset[rand.Intn(len(charset))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
9
http.go
9
http.go
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -14,7 +15,7 @@ import (
|
|||||||
|
|
||||||
type HTTPServer struct {
|
type HTTPServer struct {
|
||||||
Files FileStore
|
Files FileStore
|
||||||
Users UserStore
|
Users users.UserStore
|
||||||
Auth *AuthService
|
Auth *AuthService
|
||||||
config *ServerConfig
|
config *ServerConfig
|
||||||
Logger *zap.SugaredLogger
|
Logger *zap.SugaredLogger
|
||||||
@ -29,12 +30,12 @@ func NewHTTPServer(cfg *ServerConfig) *HTTPServer {
|
|||||||
AccessLogger: zap.NewNop().Sugar(),
|
AccessLogger: zap.NewNop().Sugar(),
|
||||||
}
|
}
|
||||||
srv.Files = NewMemoryFileStore()
|
srv.Files = NewMemoryFileStore()
|
||||||
srv.Users = NewMemoryUserStore()
|
srv.Users = users.NewMemoryUserStore()
|
||||||
srv.Auth = NewAuthService(srv.Users, []byte(srv.config.SigningSecret))
|
srv.Auth = NewAuthService(srv.Users, []byte(srv.config.SigningSecret))
|
||||||
|
|
||||||
// Create initial user
|
// Create initial user
|
||||||
// TODO: Do properly
|
// TODO: Do properly
|
||||||
user := &User{Username: "admin"}
|
user := &users.User{Username: "admin"}
|
||||||
user.SetPassword("admin")
|
user.SetPassword("admin")
|
||||||
srv.Users.Store(user)
|
srv.Users.Store(user)
|
||||||
|
|
||||||
@ -214,7 +215,7 @@ func (s *HTTPServer) HandlerAPIUserCreate(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Ensure user does not already exist
|
// TODO: Ensure user does not already exist
|
||||||
user := &User{Username: req.Username}
|
user := &users.User{Username: req.Username}
|
||||||
if err := user.SetPassword(req.Password); err != nil {
|
if err := user.SetPassword(req.Password); err != nil {
|
||||||
s.Logger.Warnw("Error setting user password.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr)
|
s.Logger.Warnw("Error setting user password.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
"git.t-juice.club/torjus/gpaste"
|
||||||
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHandlers(t *testing.T) {
|
func TestHandlers(t *testing.T) {
|
||||||
@ -101,7 +102,7 @@ func TestHandlers(t *testing.T) {
|
|||||||
// TODO: Add test
|
// TODO: Add test
|
||||||
username := "admin"
|
username := "admin"
|
||||||
password := "admin"
|
password := "admin"
|
||||||
user := &gpaste.User{Username: username}
|
user := &users.User{Username: username}
|
||||||
if err := user.SetPassword(password); err != nil {
|
if err := user.SetPassword(password); err != nil {
|
||||||
t.Fatalf("Error setting user password: %s", err)
|
t.Fatalf("Error setting user password: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package gpaste
|
package users
|
||||||
|
|
||||||
import "golang.org/x/crypto/bcrypt"
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package gpaste_test
|
package users_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestUser(t *testing.T) {
|
||||||
@ -15,7 +15,7 @@ func TestUser(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for username, password := range userMap {
|
for username, password := range userMap {
|
||||||
user := &gpaste.User{Username: username}
|
user := &users.User{Username: username}
|
||||||
if err := user.SetPassword(password); err != nil {
|
if err := user.SetPassword(password); err != nil {
|
||||||
t.Fatalf("Error setting password: %s", err)
|
t.Fatalf("Error setting password: %s", err)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package gpaste
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
@ -1,18 +1,18 @@
|
|||||||
package gpaste_test
|
package users_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBoltUserStore(t *testing.T) {
|
func TestBoltUserStore(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
newFunc := func() (func(), gpaste.UserStore) {
|
newFunc := func() (func(), users.UserStore) {
|
||||||
tmpFile := filepath.Join(tmpDir, randomString(8))
|
tmpFile := filepath.Join(tmpDir, randomString(8))
|
||||||
|
|
||||||
store, err := gpaste.NewBoltUserStore(tmpFile)
|
store, err := users.NewBoltUserStore(tmpFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error creating store: %s", err)
|
t.Fatalf("Error creating store: %s", err)
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package gpaste
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
15
users/userstore_memory_test.go
Normal file
15
users/userstore_memory_test.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package users_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMemoryUserStore(t *testing.T) {
|
||||||
|
newFunc := func() (func(), users.UserStore) {
|
||||||
|
return func() {}, users.NewMemoryUserStore()
|
||||||
|
}
|
||||||
|
|
||||||
|
RunUserStoreTest(newFunc, t)
|
||||||
|
}
|
@ -1,26 +1,26 @@
|
|||||||
package gpaste_test
|
package users_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
"git.t-juice.club/torjus/gpaste/users"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunUserStoreTest(newFunc func() (func(), gpaste.UserStore), t *testing.T) {
|
func RunUserStoreTest(newFunc func() (func(), users.UserStore), t *testing.T) {
|
||||||
t.Run("Basics", func(t *testing.T) {
|
t.Run("Basics", func(t *testing.T) {
|
||||||
cleanup, s := newFunc()
|
cleanup, s := newFunc()
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
userMap := make(map[string]*gpaste.User)
|
userMap := make(map[string]*users.User)
|
||||||
passwordMap := make(map[string]string)
|
passwordMap := make(map[string]string)
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
username := randomString(8)
|
username := randomString(8)
|
||||||
password := randomString(16)
|
password := randomString(16)
|
||||||
passwordMap[username] = password
|
passwordMap[username] = password
|
||||||
user := &gpaste.User{
|
user := &users.User{
|
||||||
Username: username,
|
Username: username,
|
||||||
Roles: []gpaste.Role{gpaste.RoleAdmin},
|
Roles: []users.Role{users.RoleAdmin},
|
||||||
}
|
}
|
||||||
if err := user.SetPassword(password); err != nil {
|
if err := user.SetPassword(password); err != nil {
|
||||||
t.Fatalf("Error setting password: %s", err)
|
t.Fatalf("Error setting password: %s", err)
|
@ -1,15 +0,0 @@
|
|||||||
package gpaste_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.t-juice.club/torjus/gpaste"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMemoryUserStore(t *testing.T) {
|
|
||||||
newFunc := func() (func(), gpaste.UserStore) {
|
|
||||||
return func() {}, gpaste.NewMemoryUserStore()
|
|
||||||
}
|
|
||||||
|
|
||||||
RunUserStoreTest(newFunc, t)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user