Users database
This commit is contained in:
parent
d844432641
commit
9a50ccd2fc
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ calibre.db
|
||||
bouquins.json
|
||||
Gopkg.lock
|
||||
vendor/
|
||||
users.db
|
||||
|
@ -8,6 +8,7 @@ Bouquins in Go
|
||||
* tests
|
||||
* auth downloads
|
||||
* csrf
|
||||
* userdb commands (init, migrate, add/remove user/email)
|
||||
|
||||
## Minify JS
|
||||
|
||||
@ -47,6 +48,7 @@ Options:
|
||||
|
||||
* calibre-path path to calibre data
|
||||
* db-path path to calibre SQLite database (default <calibre-path>/metadata.db)
|
||||
* user-db-path path to users SQLite database (default ./users.db)
|
||||
* bind-address HTTP socket bind address
|
||||
* prod (boolean) use minified javascript/CSS
|
||||
* cookie-secret random string for cookie encryption
|
||||
@ -55,3 +57,9 @@ Options:
|
||||
* name provider name
|
||||
* client-id OAuth client ID
|
||||
* client-secret OAuth secret
|
||||
|
||||
## Users SQL
|
||||
|
||||
CREATE TABLE accounts (id varchar(36) PRIMARY KEY NOT NULL, name varchar(255) NOT NULL);
|
||||
CREATE TABLE authentifiers (id varchar(36) NOT NULL, authentifier varchar(320) PRIMARY KEY NOT NULL, FOREIGN KEY(id) REFERENCES account(id));
|
||||
|
||||
|
@ -127,11 +127,12 @@ func (app *Bouquins) CallbackPage(res http.ResponseWriter, req *http.Request) er
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// FIXME list allowed users
|
||||
if userEmail == "meutel@gmail.com" || userEmail == "meutel+github@meutel.net" {
|
||||
app.SessionSet(sessionUser, "Meutel", res, req)
|
||||
log.Println("User logged in", userEmail)
|
||||
return RedirectHome(res, req)
|
||||
user, err := Account(userEmail)
|
||||
if err != nil {
|
||||
log.Println("Error loading user", err)
|
||||
return fmt.Errorf("Unknown user")
|
||||
}
|
||||
return fmt.Errorf("Unknown user")
|
||||
app.SessionSet(sessionUser, user.DisplayName, res, req)
|
||||
log.Println("User logged in", user.DisplayName)
|
||||
return RedirectHome(res, req)
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ type Conf struct {
|
||||
DbPath string `json:"db-path"`
|
||||
CalibrePath string `json:"calibre-path"`
|
||||
Prod bool `json:"prod"`
|
||||
UserDbPath string `json:"user-db-path"`
|
||||
CookieSecret string `json:"cookie-secret"`
|
||||
ExternalURL string `json:"external-url"`
|
||||
ProvidersConf []ProviderConf `json:"providers"`
|
||||
@ -85,12 +86,20 @@ type ProviderConf struct {
|
||||
|
||||
// Bouquins contains application common resources: templates, database
|
||||
type Bouquins struct {
|
||||
Tpl *template.Template
|
||||
DB *sql.DB
|
||||
Tpl *template.Template
|
||||
*sql.DB
|
||||
UserDB *sql.DB
|
||||
*Conf
|
||||
OAuthConf map[string]*oauth2.Config
|
||||
Cookies *sessions.CookieStore
|
||||
}
|
||||
|
||||
// UserAccount is an user account
|
||||
type UserAccount struct {
|
||||
ID string // UUID
|
||||
DisplayName string
|
||||
}
|
||||
|
||||
// Series is a book series.
|
||||
type Series struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
|
@ -104,6 +104,8 @@ const (
|
||||
AND authors.id != ? ORDER BY authors.id`
|
||||
sqlAuthor = "SELECT name FROM authors WHERE id = ?"
|
||||
|
||||
sqlAccount = "SELECT accounts.id, name FROM accounts, authentifiers WHERE authentifiers.id = accounts.id AND authentifiers.authentifier = ?"
|
||||
|
||||
defaultLimit = 10
|
||||
|
||||
qtBook QueryType = iota
|
||||
@ -162,7 +164,10 @@ var queries = map[Query]string{
|
||||
Query{qtAuthorBooks, false, false}: sqlAuthorBooks,
|
||||
Query{qtAuthorCoauthors, false, false}: sqlAuthorAuthors,
|
||||
}
|
||||
var stmts = make(map[Query]*sql.Stmt)
|
||||
var (
|
||||
stmts = make(map[Query]*sql.Stmt)
|
||||
stmtAccount *sql.Stmt
|
||||
)
|
||||
|
||||
// QueryType is a type of query, with variants for sort and order
|
||||
type QueryType uint
|
||||
@ -214,6 +219,13 @@ func (app *Bouquins) PrepareAll() error {
|
||||
}
|
||||
stmts[q] = stmt
|
||||
}
|
||||
// users.db
|
||||
var err error
|
||||
stmtAccount, err = app.UserDB.Prepare(sqlAccount)
|
||||
if err != nil {
|
||||
log.Println(err, sqlAccount)
|
||||
errcount++
|
||||
}
|
||||
if errcount > 0 {
|
||||
return fmt.Errorf("%d errors on queries, see logs", errcount)
|
||||
}
|
||||
|
11
bouquins/dbusers.go
Normal file
11
bouquins/dbusers.go
Normal file
@ -0,0 +1,11 @@
|
||||
package bouquins
|
||||
|
||||
// Account returns user account from authentifier
|
||||
func Account(authentifier string) (*UserAccount, error) {
|
||||
account := new(UserAccount)
|
||||
err := stmtAccount.QueryRow(authentifier).Scan(&account.ID, &account.DisplayName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return account, nil
|
||||
}
|
36
main.go
36
main.go
@ -15,8 +15,6 @@ import (
|
||||
"meutel.net/meutel/go-bouquins/bouquins"
|
||||
)
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
// ReadConfig loads configuration file and initialize default value
|
||||
func ReadConfig() (*bouquins.Conf, error) {
|
||||
conf := new(bouquins.Conf)
|
||||
@ -39,13 +37,16 @@ func ReadConfig() (*bouquins.Conf, error) {
|
||||
if conf.DbPath == "" {
|
||||
conf.DbPath = conf.CalibrePath + "/metadata.db"
|
||||
}
|
||||
if conf.UserDbPath == "" {
|
||||
conf.UserDbPath = "./users.db"
|
||||
}
|
||||
if conf.BindAddress == "" {
|
||||
conf.BindAddress = ":9000"
|
||||
}
|
||||
return conf, err
|
||||
}
|
||||
|
||||
func initApp() *bouquins.Conf {
|
||||
func initApp() *bouquins.Bouquins {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
conf, err := ReadConfig()
|
||||
if err != nil {
|
||||
@ -56,23 +57,33 @@ func initApp() *bouquins.Conf {
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
db, err = sql.Open("sqlite3", conf.DbPath)
|
||||
db, err := sql.Open("sqlite3", conf.DbPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
userdb, err := sql.Open("sqlite3", conf.UserDbPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
oauthConf := make(map[string]*oauth2.Config)
|
||||
for _, provider := range bouquins.Providers {
|
||||
oauthConf[provider.Name()] = provider.Config(conf)
|
||||
app := &bouquins.Bouquins{
|
||||
Tpl: tpl,
|
||||
DB: db,
|
||||
UserDB: userdb,
|
||||
Conf: conf,
|
||||
OAuthConf: make(map[string]*oauth2.Config),
|
||||
Cookies: sessions.NewCookieStore([]byte(conf.CookieSecret)),
|
||||
}
|
||||
for _, provider := range bouquins.Providers {
|
||||
app.OAuthConf[provider.Name()] = provider.Config(conf)
|
||||
}
|
||||
app := &bouquins.Bouquins{Tpl: tpl, DB: db, OAuthConf: oauthConf, Cookies: sessions.NewCookieStore([]byte(conf.CookieSecret))}
|
||||
err = app.PrepareAll()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
assets(conf.CalibrePath)
|
||||
router(app)
|
||||
return conf
|
||||
return app
|
||||
}
|
||||
|
||||
func assets(calibre string) {
|
||||
@ -109,7 +120,8 @@ func router(app *bouquins.Bouquins) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
conf := initApp()
|
||||
defer db.Close()
|
||||
http.ListenAndServe(conf.BindAddress, nil)
|
||||
app := initApp()
|
||||
defer app.DB.Close()
|
||||
defer app.UserDB.Close()
|
||||
http.ListenAndServe(app.Conf.BindAddress, nil)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user