init push
This commit is contained in:
57
internal/shared/pkg/appctx/appctx.go
Normal file
57
internal/shared/pkg/appctx/appctx.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package appctx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"wucher/internal/shared/pkg/uuidv7"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
const userIDKey contextKey = "appctx-user-id"
|
||||
|
||||
func WithUserID(ctx context.Context, userID []byte) context.Context {
|
||||
if len(userID) == 0 {
|
||||
return ctx
|
||||
}
|
||||
|
||||
copyID := make([]byte, len(userID))
|
||||
copy(copyID, userID)
|
||||
return context.WithValue(ctx, userIDKey, copyID)
|
||||
}
|
||||
|
||||
func GetUserID(ctx context.Context) []byte {
|
||||
if ctx == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
raw := ctx.Value(userIDKey)
|
||||
if raw == nil {
|
||||
if getter, ok := any(ctx).(interface{ UserValue(any) any }); ok {
|
||||
raw = getter.UserValue("user_id")
|
||||
}
|
||||
}
|
||||
|
||||
switch v := raw.(type) {
|
||||
case []byte:
|
||||
if len(v) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := make([]byte, len(v))
|
||||
copy(out, v)
|
||||
return out
|
||||
case string:
|
||||
s := strings.TrimSpace(v)
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
id, err := uuidv7.ParseString(s)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return id
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
46
internal/shared/pkg/appctx/appctx_test.go
Normal file
46
internal/shared/pkg/appctx/appctx_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package appctx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"wucher/internal/shared/pkg/uuidv7"
|
||||
)
|
||||
|
||||
func TestWithUserIDAndGetUserID(t *testing.T) {
|
||||
id, err := uuidv7.ParseString("00000000-0000-0000-0000-000000000001")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := WithUserID(context.Background(), id)
|
||||
got := GetUserID(ctx)
|
||||
if len(got) != len(id) {
|
||||
t.Fatalf("expected %d bytes, got %d", len(id), len(got))
|
||||
}
|
||||
if string(got) != string(id) {
|
||||
t.Fatalf("expected %x, got %x", id, got)
|
||||
}
|
||||
|
||||
got[0] ^= 0xff
|
||||
if string(GetUserID(ctx)) == string(got) {
|
||||
t.Fatal("GetUserID returned a reference to internal data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserIDFromLegacyContext(t *testing.T) {
|
||||
ctx := &legacyContext{Context: context.Background(), userID: []byte("legacy")}
|
||||
got := GetUserID(ctx)
|
||||
if string(got) != "legacy" {
|
||||
t.Fatalf("expected legacy user id, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
type legacyContext struct {
|
||||
context.Context
|
||||
userID []byte
|
||||
}
|
||||
|
||||
func (c *legacyContext) UserValue(_ any) any {
|
||||
return c.userID
|
||||
}
|
||||
Reference in New Issue
Block a user