From a54b2eb847d00ba8318eff6f9739cea0bbca4d60 Mon Sep 17 00:00:00 2001 From: Lilleman Date: Tue, 5 Jan 2021 16:49:50 +0100 Subject: [PATCH] Added support for renewal tokens --- src/db/accounts.go | 19 ------------- src/db/renewalTokens.go | 60 +++++++++++++++++++++++++++++++++++++++++ src/handlers/helpers.go | 2 +- src/handlers/post.go | 29 ++++++++++++++++++++ src/main.go | 1 + 5 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 src/db/renewalTokens.go diff --git a/src/db/accounts.go b/src/db/accounts.go index 9160f74..8a25c30 100644 --- a/src/db/accounts.go +++ b/src/db/accounts.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" log "github.com/sirupsen/logrus" - "gitlab.larvit.se/power-plan/auth/src/utils" ) // AccountCreate writes a user to database @@ -112,21 +111,3 @@ func (d Db) AccountGet(accountID string, APIKey string, Name string) (Account, e return account, nil } - -// RenewalTokenGet obtain a new renewal token -func (d Db) RenewalTokenGet(accountID string) (string, error) { - logContext := log.WithFields(log.Fields{"accountID": accountID}) - - logContext.Debug("Creating new renewal token") - - newToken := utils.RandString(60) - - insertSQL := "INSERT INTO \"renewalTokens\" (\"accountId\",token) VALUES($1,$2);" - _, insertErr := d.DbPool.Exec(context.Background(), insertSQL, accountID, newToken) - if insertErr != nil { - logContext.Error("Could not insert into database table \"renewalTokens\", err: " + insertErr.Error()) - return "", insertErr - } - - return newToken, nil -} diff --git a/src/db/renewalTokens.go b/src/db/renewalTokens.go new file mode 100644 index 0000000..1aa7e02 --- /dev/null +++ b/src/db/renewalTokens.go @@ -0,0 +1,60 @@ +package db + +import ( + "context" + + log "github.com/sirupsen/logrus" + "gitlab.larvit.se/power-plan/auth/src/utils" +) + +// RenewalTokenCreate obtain a new renewal token +func (d Db) RenewalTokenCreate(accountID string) (string, error) { + logContext := log.WithFields(log.Fields{"accountID": accountID}) + + logContext.Debug("Creating new renewal token") + + newToken := utils.RandString(60) + + insertSQL := "INSERT INTO \"renewalTokens\" (\"accountId\",token) VALUES($1,$2);" + _, insertErr := d.DbPool.Exec(context.Background(), insertSQL, accountID, newToken) + if insertErr != nil { + logContext.Error("Could not insert into database table \"renewalTokens\", err: " + insertErr.Error()) + return "", insertErr + } + + return newToken, nil +} + +// RenewalTokenGet checks if a valid renewal token exists in database +func (d Db) RenewalTokenGet(token string) (string, error) { + log.Debug("Trying to get a renewal token") + + sql := "SELECT \"accountId\" FROM \"renewalTokens\" WHERE exp >= now() AND token = $1" + + var foundAccountID string + err := d.DbPool.QueryRow(context.Background(), sql, token).Scan(&foundAccountID) + if err != nil { + if err.Error() == "no rows in result set" { + return "", nil + } + + log.Error("Database error when fetching renewal token, err: " + err.Error()) + return "", err + } + + return foundAccountID, nil +} + +// RenewalTokenRm removes a renewal token from the database +func (d Db) RenewalTokenRm(token string) error { + log.Debug("Trying to remove a renewal token") + + sql := "DELETE FROM \"renewalTokens\" WHERE token = $1" + _, err := d.DbPool.Exec(context.Background(), sql, token) + if err != nil { + log.Error("Database error when trying to remove token, err: " + err.Error()) + return err + } + + return nil +} diff --git a/src/handlers/helpers.go b/src/handlers/helpers.go index bf8ba72..5fb609a 100644 --- a/src/handlers/helpers.go +++ b/src/handlers/helpers.go @@ -30,7 +30,7 @@ func (h Handlers) returnTokens(account db.Account, c *fiber.Ctx) error { return c.Status(500).JSON([]ResJSONError{{Error: "Could not create JWT token string"}}) } - renewalToken, renewalTokenErr := h.Db.RenewalTokenGet(account.ID.String()) + renewalToken, renewalTokenErr := h.Db.RenewalTokenCreate(account.ID.String()) if renewalTokenErr != nil { log.Error("Could not create renewal token, err: " + renewalTokenErr.Error()) return c.Status(500).JSON([]ResJSONError{{Error: "Could not create renewal token"}}) diff --git a/src/handlers/post.go b/src/handlers/post.go index 884cff6..26627ca 100644 --- a/src/handlers/post.go +++ b/src/handlers/post.go @@ -114,3 +114,32 @@ func (h Handlers) AccountAuthPassword(c *fiber.Ctx) error { return h.returnTokens(resolvedAccount, c) } + +// TokenRenew creates a new renewal token and JWT from an old renewal token +func (h Handlers) TokenRenew(c *fiber.Ctx) error { + inputToken := string(c.Request().Body()) + inputToken = inputToken[1 : len(inputToken)-1] + + foundAccountID, err := h.Db.RenewalTokenGet(inputToken) + if err != nil { + return c.Status(500).JSON([]ResJSONError{{Error: err.Error()}}) + } else if foundAccountID == "" { + return c.Status(403).JSON([]ResJSONError{{Error: "Invalid token"}}) + } + + resolvedAccount, accountErr := h.Db.AccountGet(foundAccountID, "", "") + if accountErr != nil { + if accountErr.Error() == "no rows in result set" { + return c.Status(500).JSON([]ResJSONError{{Error: "Database missmatch. Token found, but account is missing."}}) + } + log.Error("Something went wrong when trying to fetch account") + return c.Status(500).JSON([]ResJSONError{{Error: "Something went wrong when trying to fetch account"}}) + } + + rmErr := h.Db.RenewalTokenRm(inputToken) + if rmErr != nil { + return c.Status(500).JSON([]ResJSONError{{Error: "Could not remove old token, err: " + rmErr.Error()}}) + } + + return h.returnTokens(resolvedAccount, c) +} diff --git a/src/main.go b/src/main.go index e30f3d0..f6e5f8b 100644 --- a/src/main.go +++ b/src/main.go @@ -77,6 +77,7 @@ func main() { app.Post("/account", handlers.AccountCreate) app.Post("/auth/api-key", handlers.AccountAuthAPIKey) app.Post("/auth/password", handlers.AccountAuthPassword) + app.Post("/renew-token", handlers.TokenRenew) log.WithFields(log.Fields{"WEB_BIND_HOST": os.Getenv("WEB_BIND_HOST")}).Info("Trying to start web server")