diff --git a/auth/auth.go b/auth/auth.go
index 8b4230e..be689d3 100644
--- a/auth/auth.go
+++ b/auth/auth.go
@@ -91,6 +91,25 @@ func (a *Authorizer) Login(rw http.ResponseWriter, req *http.Request, username,
return nil
}
+func (a *Authorizer) RegenSecret(user User, w http.ResponseWriter, r *http.Request) error {
+ cookie, err := a.cookiejar.Get(r, a.cookieName)
+ if err != nil {
+ return err
+ }
+ // genereate secret
+ b, err := bcrypt.GenerateFromPassword([]byte(user.GetHash()), a.cost)
+ if err != nil {
+ return err
+ }
+ cookie.Values["secret"] = string(b)
+
+ err = cookie.Save(r, w)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
// Logout remove cookie info
func (a *Authorizer) Logout(rw http.ResponseWriter, req *http.Request) error {
cookie, err := a.cookiejar.Get(req, a.cookieName)
diff --git a/main.go b/main.go
index 3fdbb88..840e3c3 100644
--- a/main.go
+++ b/main.go
@@ -1,8 +1,6 @@
package main
import (
- "os"
-
"gitlab.quimbo.fr/odwrtw/canape-sql/auth"
"gitlab.quimbo.fr/odwrtw/canape-sql/movies"
"gitlab.quimbo.fr/odwrtw/canape-sql/users"
@@ -28,8 +26,7 @@ func main() {
pgdsn := "postgres://test:test@127.0.0.1:5432/test?sslmode=disable"
db, err := sqlx.Connect("postgres", pgdsn)
if err != nil {
- log.Error(err)
- os.Exit(1)
+ log.Panic(err)
}
uBackend := &UserBackend{db}
authorizer := auth.New(uBackend, "peeper", "cookieName", "cookieKey", 10)
@@ -37,16 +34,16 @@ func main() {
env := web.NewEnv(db, authorizer, log, "./templates")
authMiddleware := auth.NewMiddleware(env.Auth)
- env.Handle("users.login", "/users/login", users.LoginHandler)
- env.Handle("users.logout", "/users/logout", users.LogoutHandler)
- env.HandleRole("users.details", "/users/details", users.DetailsHandler, users.UserRole)
+ env.Handle("users.login", "/users/login", users.Login)
+ env.Handle("users.logout", "/users/logout", users.Logout)
+ env.HandleRole("users.details", "/users/details", users.Details, users.UserRole)
+ env.HandleRole("users.edit", "/users/edit", users.Edit, users.UserRole)
- env.HandleRole("movies.polochon", "/", movies.PolochonMovies, users.UserRole)
+ env.HandleRole("movies.polochon", "/movies/polochon", movies.FromPolochon, users.UserRole)
err = env.SetLoginRoute("users.login")
if err != nil {
- log.Error(err)
- os.Exit(1)
+ log.Panic(err)
}
n := negroni.Classic()
diff --git a/movies/handlers.go b/movies/handlers.go
index 9465833..40ac01a 100644
--- a/movies/handlers.go
+++ b/movies/handlers.go
@@ -14,7 +14,7 @@ import (
"gitlab.quimbo.fr/odwrtw/papi"
)
-func PolochonMovies(env *web.Env, w http.ResponseWriter, r *http.Request) error {
+func FromPolochon(env *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r)
user, ok := v.(*users.User)
diff --git a/templates/users/details.tmpl b/templates/users/details.tmpl
new file mode 100644
index 0000000..557b892
--- /dev/null
+++ b/templates/users/details.tmpl
@@ -0,0 +1,26 @@
+
+
+
+
+
{{ $.Data.user.Name }}'s informations
+
+
+
+
+ Polochon URL
+
+
{{ $.Data.polochon.URL }}
+
+
+
+ Polochon token
+
+
{{ $.Data.polochon.Token }}
+
+
+
+
+
+
diff --git a/templates/users/edit.tmpl b/templates/users/edit.tmpl
new file mode 100644
index 0000000..df59aac
--- /dev/null
+++ b/templates/users/edit.tmpl
@@ -0,0 +1,43 @@
+
+
+
+
diff --git a/users/handlers.go b/users/handlers.go
index bc677b1..b3e5796 100644
--- a/users/handlers.go
+++ b/users/handlers.go
@@ -5,12 +5,15 @@ import (
"net/http"
"github.com/gorilla/Schema"
+ "github.com/kr/pretty"
"gitlab.quimbo.fr/odwrtw/canape-sql/auth"
+ "gitlab.quimbo.fr/odwrtw/canape-sql/config"
"gitlab.quimbo.fr/odwrtw/canape-sql/web"
)
-func LoginHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
+// Login login user
+func Login(e *web.Env, w http.ResponseWriter, r *http.Request) error {
if r.Method == "GET" {
return e.Rends(w, r, "users/login")
}
@@ -53,21 +56,101 @@ func LoginHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
return nil
}
-func LogoutHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
+// Logout just logout
+func Logout(e *web.Env, w http.ResponseWriter, r *http.Request) error {
e.Auth.Logout(w, r)
route := e.GetLoginRouteGetter()()
http.Redirect(w, r, route, http.StatusTemporaryRedirect)
return nil
}
-func DetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
- u := auth.GetCurrentUser(r)
- if u == nil {
- return nil
- }
- _, ok := u.(*User)
+// Details show user details
+func Details(env *web.Env, w http.ResponseWriter, r *http.Request) error {
+ v := auth.GetCurrentUser(r)
+ user, ok := v.(*User)
if !ok {
- return fmt.Errorf("Invalid user type")
+ return fmt.Errorf("invalid user type")
}
- return nil
+
+ var polochonConfig config.UserPolochon
+ err := user.GetConfig("polochon", &polochonConfig)
+ if err != nil {
+ return err
+ }
+
+ web.SetData(r, "user", user)
+ web.SetData(r, "polochon", polochonConfig)
+ return env.Rends(w, r, "users/details")
+}
+
+// Edit allow editing user info and configuration
+func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error {
+ v := auth.GetCurrentUser(r)
+ user, ok := v.(*User)
+ if !ok {
+ return fmt.Errorf("invalid user type")
+ }
+ var polochonConfig config.UserPolochon
+ err := user.GetConfig("polochon", &polochonConfig)
+ if err != nil {
+ return err
+ }
+
+ if r.Method == "GET" {
+ web.SetData(r, "user", user)
+ web.SetData(r, "polochon", polochonConfig)
+ return env.Rends(w, r, "users/edit")
+ }
+
+ type editForm struct {
+ PolochonURL string
+ PolochonToken string
+ Password string
+ PasswordVerify string
+ }
+
+ err = r.ParseForm()
+ if err != nil {
+ return err
+ }
+
+ form := new(editForm)
+ decoder := schema.NewDecoder()
+ err = decoder.Decode(form, r.PostForm)
+ if err != nil {
+ return err
+ }
+
+ polochonConfig.URL = form.PolochonURL
+ polochonConfig.Token = form.PolochonToken
+
+ err = user.SetConfig("polochon", polochonConfig)
+ if err != nil {
+ return err
+ }
+
+ if form.Password != "" || form.PasswordVerify != "" {
+ if form.Password != form.PasswordVerify {
+ // TODO: manage form error
+ }
+ user.Hash, err = env.Auth.GenHash(form.Password)
+ if err != nil {
+ return err
+ }
+ }
+
+ err = user.Update(env.Database)
+ if err != nil {
+ pretty.Println(err)
+ return err
+ }
+
+ err = env.Auth.RegenSecret(user, w, r)
+ if err != nil {
+ return err
+ }
+
+ web.SetData(r, "user", user)
+ web.SetData(r, "polochon", polochonConfig)
+ return env.Rends(w, r, "users/edit")
}
diff --git a/users/users.go b/users/users.go
index 6b590d7..3069c4f 100644
--- a/users/users.go
+++ b/users/users.go
@@ -11,9 +11,9 @@ import (
)
const (
- addUserQuery = `INSERT INTO users (name, hash, admin) VALUES ($1, $2, $3) RETURNING id;`
+ addUserQuery = `INSERT INTO users (name, hash, admin, rawconfig) VALUES ($1, $2, $3, $4) RETURNING id;`
getUserQuery = `SELECT * FROM users WHERE name=$1;`
- updateUserQuery = `UPDATE users SET name=:name, hash=:hash, admin=:admin RETURNING *;`
+ updateUserQuery = `UPDATE users SET name=:name, hash=:hash, admin=:admin, rawconfig=:rawconfig WHERE id=:id RETURNING *;`
deleteUseQuery = `DELETE FROM users WHERE id=:id;`
addTokenQuery = `INSERT INTO tokens (value, user_id) VALUES ($1, $2) RETURNING id;`
@@ -97,7 +97,7 @@ func Get(q sqlx.Queryer, name string) (*User, error) {
// Add user to database or raises an error
func (u *User) Add(q sqlx.Queryer) error {
var id string
- err := q.QueryRowx(addUserQuery, u.Name, u.Hash, u.Admin).Scan(&id)
+ err := q.QueryRowx(addUserQuery, u.Name, u.Hash, u.Admin, u.RawConfig).Scan(&id)
if err != nil {
return err
}
diff --git a/web/env.go b/web/env.go
index 1871d97..8724c63 100644
--- a/web/env.go
+++ b/web/env.go
@@ -34,20 +34,28 @@ type Env struct {
// NewEnv returns a new *Env
func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir string) *Env {
- return &Env{
+ e := &Env{
Database: db,
Log: log,
Router: mux.NewRouter(),
- Render: render.New(render.Options{
- Directory: templatesDir,
- Layout: "layout",
- Funcs: tmplFuncs,
- DisableHTTPErrorRendering: true,
- RequirePartials: true,
- }),
- Auth: auth,
- Mode: ProductionMode,
+ Auth: auth,
+ Mode: ProductionMode,
}
+
+ tmplFuncs = append(tmplFuncs, map[string]interface{}{
+ "URL": func(name string, pairs ...string) (string, error) {
+ return e.GetURL(name, pairs...)
+ },
+ })
+
+ e.Render = render.New(render.Options{
+ Directory: templatesDir,
+ Layout: "layout",
+ Funcs: tmplFuncs,
+ DisableHTTPErrorRendering: true,
+ RequirePartials: true,
+ })
+ return e
}
func (e *Env) SetLoginRoute(name string) error {