From fd3925cdb0bb4306d844341cb18eb610509a4c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Delattre?= Date: Thu, 3 May 2018 14:27:00 +0200 Subject: [PATCH] Allow admins to generate a user token --- backend/admins/users.go | 29 +++++++++++++++++++++++++++++ backend/auth/auth.go | 36 ++++++++++++++++++++++-------------- backend/routes.go | 1 + backend/tokens/tokens.go | 4 ++-- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/backend/admins/users.go b/backend/admins/users.go index 726d718..a9122b3 100644 --- a/backend/admins/users.go +++ b/backend/admins/users.go @@ -9,6 +9,7 @@ import ( "gitlab.quimbo.fr/odwrtw/canape/backend/users" "gitlab.quimbo.fr/odwrtw/canape/backend/web" + "github.com/gorilla/mux" "github.com/sirupsen/logrus" ) @@ -28,6 +29,34 @@ func GetUsersHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error return env.RenderJSON(w, users) } +// GenerateUserToken generates a user token +func GenerateUserToken(env *web.Env, w http.ResponseWriter, r *http.Request) error { + log := env.Log.WithFields(logrus.Fields{ + "function": "admin.GenerateUserToken", + }) + log.Debug("Generating user token") + + vars := mux.Vars(r) + username := vars["username"] + + user, err := users.Get(env.Database, username) + if err != nil { + return err + } + + t, err := env.Auth.GenerateJWTToken(r, user) + if err != nil { + return err + } + t.Description = "generated token for polochon" + + if err := t.Add(env.Database); err != nil { + return err + } + + return env.RenderJSON(w, t) +} + // UpdateUserHandler updates the user data func UpdateUserHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error { log := env.Log.WithFields(logrus.Fields{ diff --git a/backend/auth/auth.go b/backend/auth/auth.go index 08eb044..85bd3c0 100644 --- a/backend/auth/auth.go +++ b/backend/auth/auth.go @@ -70,19 +70,8 @@ func (a *Authorizer) GenHash(password string) (string, error) { return string(b), nil } -// Login cheks password and creates a jwt token -func (a *Authorizer) Login(r *http.Request, username, password string) (*tokens.Token, error) { - u, err := a.Backend.GetUser(username) - if err != nil { - return nil, err - } - - // Compare the password - err = bcrypt.CompareHashAndPassword([]byte(u.GetHash()), []byte(password+a.Pepper)) - if err != nil { - return nil, ErrInvalidPassword - } - +// GenerateJWTToken generates a JWT token for a user +func (a *Authorizer) GenerateJWTToken(r *http.Request, u User) (*tokens.Token, error) { // Create a jwt token jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ // Not before @@ -101,10 +90,29 @@ func (a *Authorizer) Login(r *http.Request, username, password string) (*tokens. return nil, err } - t := &tokens.Token{ + return &tokens.Token{ Token: ss, Username: u.GetName(), IP: getIPFromRequest(r), + }, nil +} + +// Login cheks password and creates a jwt token +func (a *Authorizer) Login(r *http.Request, username, password string) (*tokens.Token, error) { + u, err := a.Backend.GetUser(username) + if err != nil { + return nil, err + } + + // Compare the password + err = bcrypt.CompareHashAndPassword([]byte(u.GetHash()), []byte(password+a.Pepper)) + if err != nil { + return nil, ErrInvalidPassword + } + + t, err := a.GenerateJWTToken(r, u) + if err != nil { + return nil, err } if err := t.Add(a.db); err != nil { diff --git a/backend/routes.go b/backend/routes.go index 303a210..6b369dc 100644 --- a/backend/routes.go +++ b/backend/routes.go @@ -66,4 +66,5 @@ func setupRoutes(env *web.Env) { env.Handle("/admins/users", admin.GetUsersHandler).WithRole(users.AdminRole).Methods("GET") env.Handle("/admins/users", admin.UpdateUserHandler).WithRole(users.AdminRole).Methods("POST") env.Handle("/admins/stats", admin.GetStatsHandler).WithRole(users.AdminRole).Methods("GET") + env.Handle("/admins/tokens/{username}", admin.GenerateUserToken).WithRole(users.AdminRole).Methods("POST") } diff --git a/backend/tokens/tokens.go b/backend/tokens/tokens.go index e76c366..b9a669f 100644 --- a/backend/tokens/tokens.go +++ b/backend/tokens/tokens.go @@ -11,7 +11,7 @@ import ( ) const ( - addTokenQuery = `INSERT INTO tokens (token, username, ip) VALUES ($1, $2, $3);` + addTokenQuery = `INSERT INTO tokens (token, username, ip, description) VALUES ($1, $2, $3, $4);` getTokenQuery = `SELECT * FROM tokens WHERE token=$1;` getUserTokenQuery = `SELECT * FROM tokens WHERE username=$1 and token=$2;` getUserTokensQuery = `SELECT * FROM tokens WHERE username=$1;` @@ -37,7 +37,7 @@ type Token struct { // Add a token to the database func (t *Token) Add(db *sqlx.DB) error { - _, err := db.Queryx(addTokenQuery, t.Token, t.Username, t.IP) + _, err := db.Queryx(addTokenQuery, t.Token, t.Username, t.IP, t.Description) if err != nil { return err }