Signed-off-by: Nikolai Rodionov <iam@allanger.xyz>
This commit is contained in:
24
internal/cache/cache.go
vendored
24
internal/cache/cache.go
vendored
@@ -1 +1,25 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
const (
|
||||
CacheFolderToken = "token"
|
||||
)
|
||||
|
||||
func buildKey(folder, key string) string {
|
||||
return fmt.Sprintf("%s:%s", folder, key)
|
||||
}
|
||||
|
||||
func GetFromCache(ctx context.Context, redis *redis.Client, folder, key string) string {
|
||||
return redis.Get(ctx, buildKey(folder, key)).Val()
|
||||
}
|
||||
|
||||
func SaveToCache(ctx context.Context, redis *redis.Client, folder, key, value string, ttl time.Duration) error {
|
||||
return redis.Set(ctx, buildKey(folder, key), value, ttl).Err()
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/cache"
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/logger"
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/token"
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/repository"
|
||||
@@ -73,9 +73,7 @@ func (ctrl *TokenController) VerifyTokenOwner(ctx context.Context, userID, token
|
||||
log := logger.FromContext(ctx).WithValues("uuid", tokenID, "user_id", userID)
|
||||
log.V(2).Info("Verifying the token owner")
|
||||
|
||||
// First try to get from the redis
|
||||
redisKey := fmt.Sprintf("token:%s", tokenID)
|
||||
realUserID := ctrl.Redis.Get(ctx, redisKey).Val()
|
||||
realUserID := cache.GetFromCache(ctx, ctrl.Redis, cache.CacheFolderToken, tokenID)
|
||||
// If not found in cache, get from postgres
|
||||
if realUserID == "" {
|
||||
query := "SELECT user_id FROM tokens WHERE uuid = $1;"
|
||||
@@ -90,8 +88,7 @@ func (ctrl *TokenController) VerifyTokenOwner(ctx context.Context, userID, token
|
||||
if realUserID != userID {
|
||||
return ErrUserTokenMismatch
|
||||
}
|
||||
err := ctrl.Redis.Set(ctx, redisKey, realUserID, time.Hour)
|
||||
if err != nil {
|
||||
if err := cache.SaveToCache(ctx, ctrl.Redis, cache.CacheFolderToken, realUserID, tokenID, time.Hour); err != nil {
|
||||
log.Info("Couldn't write to cache", "error", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -17,7 +17,7 @@ func newTestTokensController(ctx context.Context) *controllers.TokenController {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateToken_Success(t *testing.T) {
|
||||
func TestIntegrationCreateToken_Success(t *testing.T) {
|
||||
// Create a user for the token
|
||||
ctrlAccount := newTestAccountController(t.Context())
|
||||
accountData := &controllers.AccountData{
|
||||
@@ -43,7 +43,7 @@ func TestCreateToken_Success(t *testing.T) {
|
||||
assert.NotEmpty(t, tokenVal)
|
||||
}
|
||||
|
||||
func TestCreateToken_UserNotExist(t *testing.T) {
|
||||
func TestIntegrationCreateToken_UserNotExist(t *testing.T) {
|
||||
tokenData := &controllers.TokenData{
|
||||
Name: "Test Token",
|
||||
UserID: uuid.NewString(),
|
||||
@@ -62,7 +62,7 @@ func TestCreateToken_UserNotExist(t *testing.T) {
|
||||
assert.Empty(t, tokenVal)
|
||||
}
|
||||
|
||||
func TestGetToken_Success(t *testing.T) {
|
||||
func TestIntegrationGetToken_Success(t *testing.T) {
|
||||
// Create a user for the token
|
||||
ctrlAccount := newTestAccountController(t.Context())
|
||||
accountData := &controllers.AccountData{
|
||||
@@ -95,3 +95,70 @@ func TestGetToken_Success(t *testing.T) {
|
||||
assert.Equal(t, tokenData.Name, token.Name)
|
||||
assert.Equal(t, tokenData.ExpiresAt.Truncate(time.Second), token.ExpiresAt.Truncate(time.Second))
|
||||
}
|
||||
|
||||
func TestIntegrationGetToken_NotExists(t *testing.T) {
|
||||
ctrl := newTestTokensController(t.Context())
|
||||
token, err := ctrl.Get(t.Context(), uuid.NewString(), uuid.NewString())
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, controllers.ErrTokenNotFound)
|
||||
assert.Empty(t, token)
|
||||
}
|
||||
|
||||
func TestIntegrationVerifyTokenOwner_Success(t *testing.T) {
|
||||
// Create a user for the token
|
||||
ctrlAccount := newTestAccountController(t.Context())
|
||||
accountData := &controllers.AccountData{
|
||||
Password: "qwertyu9",
|
||||
Email: newTestUniqueEmail("accounts"),
|
||||
}
|
||||
|
||||
userID, err := ctrlAccount.Create(t.Context(), accountData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tokenData := &controllers.TokenData{
|
||||
Name: "Test Token",
|
||||
UserID: userID,
|
||||
ExpiresAt: time.Now().Add(time.Second * 5),
|
||||
Scopes: map[string][]string{
|
||||
"Test": {"test", "test2"},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := newTestTokensController(t.Context())
|
||||
_, tokenID, err := ctrl.Create(t.Context(), tokenData)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, ctrl.VerifyTokenOwner(t.Context(), userID, tokenID))
|
||||
}
|
||||
|
||||
func TestIntegrationVerifyTokenOwner_WrongOwner(t *testing.T) {
|
||||
// Create a user for the token
|
||||
ctrlAccount := newTestAccountController(t.Context())
|
||||
accountData := &controllers.AccountData{
|
||||
Password: "qwertyu9",
|
||||
Email: newTestUniqueEmail("accounts"),
|
||||
}
|
||||
|
||||
secondAccountData := &controllers.AccountData{
|
||||
Password: "qwertyu9",
|
||||
Email: newTestUniqueEmail("accounts"),
|
||||
}
|
||||
userID, err := ctrlAccount.Create(t.Context(), accountData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
secondUserID, err := ctrlAccount.Create(t.Context(), secondAccountData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tokenData := &controllers.TokenData{
|
||||
Name: "Test Token",
|
||||
UserID: userID,
|
||||
ExpiresAt: time.Now().Add(time.Second * 5),
|
||||
Scopes: map[string][]string{
|
||||
"Test": {"test", "test2"},
|
||||
},
|
||||
}
|
||||
|
||||
ctrl := newTestTokensController(t.Context())
|
||||
_, tokenID, err := ctrl.Create(t.Context(), tokenData)
|
||||
assert.NoError(t, err)
|
||||
assert.ErrorIs(t, ctrl.VerifyTokenOwner(t.Context(), secondUserID, tokenID), controllers.ErrUserTokenMismatch)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user