Feature 03 task 4: CSRF protection and GET /api/v1/me (#22)
CI / ci (push) Successful in 1m26s
CI / ci (push) Successful in 1m26s
Co-authored-by: dev_agent <dev_agent@cubecraftlabs.com> Co-committed-by: dev_agent <dev_agent@cubecraftlabs.com>
This commit was merged in pull request #22.
This commit is contained in:
+19
-9
@@ -19,17 +19,27 @@ func (s Session) Actor() Actor {
|
||||
return Actor{Subject: s.Subject, Email: s.Email, Name: s.Name, Groups: slices.Clone(s.Groups)}
|
||||
}
|
||||
|
||||
type actorKey struct{}
|
||||
type sessionKey struct{}
|
||||
|
||||
// WithActor returns a copy of ctx carrying actor. The session middleware
|
||||
// calls it for every authenticated request.
|
||||
func WithActor(ctx context.Context, actor Actor) context.Context {
|
||||
return context.WithValue(ctx, actorKey{}, actor)
|
||||
// WithSession returns a copy of ctx carrying s. The session middleware calls
|
||||
// it for every authenticated request.
|
||||
func WithSession(ctx context.Context, s Session) context.Context {
|
||||
return context.WithValue(ctx, sessionKey{}, s)
|
||||
}
|
||||
|
||||
// ActorFrom returns the actor WithActor stored in ctx. ok is false when ctx
|
||||
// has none, which behind the session middleware means a wiring bug.
|
||||
// SessionFrom returns the session WithSession stored in ctx. ok is false when
|
||||
// ctx has none, which behind the session middleware means a wiring bug.
|
||||
func SessionFrom(ctx context.Context) (s Session, ok bool) {
|
||||
s, ok = ctx.Value(sessionKey{}).(Session)
|
||||
return s, ok
|
||||
}
|
||||
|
||||
// ActorFrom returns the actor of the session WithSession stored in ctx. ok is
|
||||
// false when ctx has none.
|
||||
func ActorFrom(ctx context.Context) (actor Actor, ok bool) {
|
||||
actor, ok = ctx.Value(actorKey{}).(Actor)
|
||||
return actor, ok
|
||||
s, ok := SessionFrom(ctx)
|
||||
if !ok {
|
||||
return Actor{}, false
|
||||
}
|
||||
return s.Actor(), true
|
||||
}
|
||||
|
||||
@@ -11,10 +11,18 @@ func TestActorContext(t *testing.T) {
|
||||
if _, ok := ActorFrom(context.Background()); ok {
|
||||
t.Error("ActorFrom found an actor in an empty context")
|
||||
}
|
||||
want := Actor{Subject: "user-123", Email: "cook@example.com", Name: "Home Cook", Groups: []string{"mealquest-admin"}}
|
||||
got, ok := ActorFrom(WithActor(context.Background(), want))
|
||||
if !ok || got.Subject != want.Subject || got.Email != want.Email || got.Name != want.Name || !slices.Equal(got.Groups, want.Groups) {
|
||||
t.Errorf("ActorFrom = %+v (ok=%v), want %+v", got, ok, want)
|
||||
if _, ok := SessionFrom(context.Background()); ok {
|
||||
t.Error("SessionFrom found a session in an empty context")
|
||||
}
|
||||
s := Session{Subject: "user-123", Email: "cook@example.com", Name: "Home Cook", Groups: []string{"mealquest-admin"}, CSRFToken: "t"}
|
||||
ctx := WithSession(context.Background(), s)
|
||||
gotSession, ok := SessionFrom(ctx)
|
||||
if !ok || gotSession.Subject != s.Subject || gotSession.CSRFToken != s.CSRFToken {
|
||||
t.Errorf("SessionFrom = %+v (ok=%v), want %+v", gotSession, ok, s)
|
||||
}
|
||||
got, ok := ActorFrom(ctx)
|
||||
if !ok || got.Subject != s.Subject || got.Email != s.Email || got.Name != s.Name || !slices.Equal(got.Groups, s.Groups) {
|
||||
t.Errorf("ActorFrom = %+v (ok=%v), want the session's actor", got, ok)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user