Add user config
This commit is contained in:
parent
80cd6d3d72
commit
f9984d8b89
@ -17,7 +17,8 @@ CREATE TABLE users (
|
|||||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
name text NOT NULL UNIQUE,
|
name text NOT NULL UNIQUE,
|
||||||
hash text NOT NULL,
|
hash text NOT NULL,
|
||||||
admin boolean,
|
admin boolean DEFAULT false,
|
||||||
|
rawconfig json DEFAULT '{}',
|
||||||
LIKE base INCLUDING DEFAULTS
|
LIKE base INCLUDING DEFAULTS
|
||||||
);
|
);
|
||||||
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column();
|
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column();
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
package users
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
|
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/auth"
|
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/sqly"
|
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserBackend struct {
|
|
||||||
db *sqlx.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *UserBackend) Get(username string) (auth.User, error) {
|
|
||||||
return Get(db, username)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createUserBackend(db *sqlx.DB) *UserBackend {
|
|
||||||
return &UserBackend{db: db}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoginSubmit(t *testing.T) {
|
|
||||||
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
|
||||||
backend := createUserBackend(db)
|
|
||||||
authorizer := auth.New(backend, "peeper", "cookieName", "cookieKey", 10)
|
|
||||||
e := web.NewEnv(db, authorizer, logrus.NewEntry(logrus.New()), "../templates")
|
|
||||||
e.Mode = web.TestMode
|
|
||||||
e.Router.Handle("/login", e.Handler(loginSubmitHandler)).Methods("POST").Name("loginPost")
|
|
||||||
|
|
||||||
ts := httptest.NewServer(e.Router)
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
cookieJar, _ := cookiejar.New(nil)
|
|
||||||
client := &http.Client{
|
|
||||||
Jar: cookieJar,
|
|
||||||
}
|
|
||||||
|
|
||||||
v := url.Values{}
|
|
||||||
v.Add("username", "plop")
|
|
||||||
v.Add("password", "ploppwd")
|
|
||||||
resp, err := client.PostForm(ts.URL+"/login", v)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
str, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
if string(str) != `{"RouteName":"loginPost","Data":{"FormErrors":{"password":"Invalid username or password"}}}` {
|
|
||||||
t.Fatalf("Unpected content: %s", string(str))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,9 +1,11 @@
|
|||||||
package users
|
package users
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/jmoiron/sqlx/types"
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/random"
|
"gitlab.quimbo.fr/odwrtw/canape-sql/random"
|
||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/sqly"
|
"gitlab.quimbo.fr/odwrtw/canape-sql/sqly"
|
||||||
)
|
)
|
||||||
@ -31,9 +33,43 @@ var ErrUnknownUser = fmt.Errorf("users: user does'nt exist")
|
|||||||
// User represents an user
|
// User represents an user
|
||||||
type User struct {
|
type User struct {
|
||||||
sqly.BaseModel
|
sqly.BaseModel
|
||||||
Name string
|
Name string
|
||||||
Hash string
|
Hash string
|
||||||
Admin bool
|
Admin bool
|
||||||
|
RawConfig types.JSONText
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig unmarshal json from specified config key into v
|
||||||
|
func (u *User) GetConfig(key string, v interface{}) error {
|
||||||
|
var configMap map[string]*json.RawMessage
|
||||||
|
err := u.RawConfig.Unmarshal(&configMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(*configMap[key], v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConfig marshal v into json for specified config key
|
||||||
|
func (u *User) SetConfig(key string, v interface{}) error {
|
||||||
|
var configMap map[string]*json.RawMessage
|
||||||
|
err := u.RawConfig.Unmarshal(&configMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := json.RawMessage(b)
|
||||||
|
configMap[key] = &r
|
||||||
|
b, err = json.Marshal(configMap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.RawConfig.UnmarshalJSON(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token represents a token
|
// Token represents a token
|
||||||
|
@ -193,3 +193,34 @@ func TestAutoUpdateCols(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig(t *testing.T) {
|
||||||
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
|
u := &User{Name: "plop", Hash: "plop"}
|
||||||
|
u.Add(db)
|
||||||
|
|
||||||
|
u, err := Get(db, "plop")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
type test struct {
|
||||||
|
Test string
|
||||||
|
}
|
||||||
|
te := test{"coucou"}
|
||||||
|
err = u.SetConfig("test1", te)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var te2 test
|
||||||
|
err = u.GetConfig("test1", &te2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if te != te2 {
|
||||||
|
t.Fatal("unexpected config")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user