2021-03-28 08:52:34 +00:00
|
|
|
package goscrobble
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"math/rand"
|
2021-04-01 10:17:46 +00:00
|
|
|
"time"
|
2021-03-28 08:52:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
|
2021-04-06 08:28:04 +00:00
|
|
|
type RefreshToken struct {
|
|
|
|
UUID string
|
|
|
|
User string
|
|
|
|
Token string
|
|
|
|
Expiry time.Time
|
|
|
|
}
|
|
|
|
|
2021-04-01 10:17:46 +00:00
|
|
|
// generateToken - Generates a unique token for user input
|
2021-03-28 08:52:34 +00:00
|
|
|
func generateToken(n int) string {
|
2021-04-01 10:17:46 +00:00
|
|
|
rand.Seed(time.Now().UnixNano())
|
2021-03-28 08:52:34 +00:00
|
|
|
b := make([]byte, n)
|
|
|
|
for i := range b {
|
|
|
|
b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
|
|
|
|
}
|
|
|
|
return string(b)
|
|
|
|
}
|
|
|
|
|
2021-03-31 08:40:20 +00:00
|
|
|
func getUserUuidForToken(token string) (string, error) {
|
2021-03-28 08:52:34 +00:00
|
|
|
var uuid string
|
2021-03-29 07:56:34 +00:00
|
|
|
cachedKey := getRedisVal("user_token:" + token)
|
|
|
|
if cachedKey == "" {
|
2021-12-25 09:24:47 +00:00
|
|
|
err := db.QueryRow("SELECT uuid FROM users WHERE token = $1 AND active = true", token).Scan(&uuid)
|
2021-03-29 07:56:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", errors.New("Invalid Token")
|
|
|
|
}
|
|
|
|
setRedisVal("user_token:"+token, uuid)
|
|
|
|
} else {
|
|
|
|
uuid = cachedKey
|
2021-03-28 08:52:34 +00:00
|
|
|
}
|
2021-03-29 07:56:34 +00:00
|
|
|
|
2021-03-28 08:52:34 +00:00
|
|
|
return uuid, nil
|
|
|
|
}
|
2021-04-06 08:28:04 +00:00
|
|
|
|
|
|
|
func insertRefreshToken(userUuid string, token string) error {
|
|
|
|
uuid := newUUID()
|
2021-12-25 09:24:47 +00:00
|
|
|
_, err := db.Exec(`INSERT INTO refresh_tokens (uuid, "user", token) VALUES ($1,$2,$3)`,
|
2021-04-06 08:28:04 +00:00
|
|
|
uuid, userUuid, token)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func deleteRefreshToken(token string) error {
|
2021-12-25 09:24:47 +00:00
|
|
|
_, err := db.Exec("DELETE FROM refresh_tokens WHERE token = $1", token)
|
2021-04-06 08:28:04 +00:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func isValidRefreshToken(refreshTokenStr string) (User, error) {
|
|
|
|
var refresh RefreshToken
|
2021-12-25 09:24:47 +00:00
|
|
|
err := db.QueryRow("SELECT uuid, user, token, expiry FROM refresh_tokens WHERE token = $1",
|
2021-04-06 08:28:04 +00:00
|
|
|
refreshTokenStr).Scan(&refresh.UUID, &refresh.User, &refresh.Token, &refresh.Expiry)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, errors.New("Invalid Refresh Token")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate Expiry
|
|
|
|
if refresh.Expiry.Unix() < time.Now().Unix() {
|
|
|
|
return User{}, errors.New("Invalid Refresh Token")
|
|
|
|
}
|
|
|
|
|
|
|
|
user, err := getUserByUUID(refresh.User)
|
|
|
|
if err != nil {
|
|
|
|
return User{}, errors.New("Invalid Refresh Token")
|
|
|
|
}
|
|
|
|
|
|
|
|
return user, nil
|
|
|
|
}
|