File size: 2,177 Bytes
d6f631f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package session

import (
	"context"
	"errors"
	"fmt"
	"log/slog"
	"strings"
)

type AuthenticatorContextKey string

const (
	AuthenticationSessionKey AuthenticatorContextKey = "active_organization_id"
)

// GetUserID returns the user ID from the session if any
func GetSessionUserID(ctx context.Context) *string {
	if session := GetActiveSession(ctx); session != nil {
		if session.UserID == "" {
			return nil
		}

		return &session.UserID
	}

	return nil
}

// GetActiveSession returns the active session from the context if it exists
func GetActiveSession(ctx context.Context) *AuthenticationSession {
	if c, ok := ctx.Value(AuthenticationSessionKey).(*AuthenticationSession); ok {
		return c
	}

	return nil
}

// NewAuthenticationSession creates a new authentication session
func NewAuthenticationSession(orgID, orgSlug, orgRole, userID string, orgPermissions []string) (*AuthenticationSession, error) {
	session := &AuthenticationSession{
		UserID:         userID,
		OrgID:          orgID,
		OrgSlug:        orgSlug,
		OrgRole:        orgRole,
		OrgPermissions: orgPermissions,
	}

	if err := session.Validate(); err != nil {
		return nil, fmt.Errorf("failed to validate session: %w", err)
	}

	return session, nil
}

// AuthenticationSession represents the authentication session for a user
type AuthenticationSession struct {
	UserID         string
	OrgID          string
	OrgSlug        string
	OrgRole        string
	OrgPermissions []string
}

// Validate validates the session.
func (s AuthenticationSession) Validate() error {
	var errs []error

	if s.OrgID == "" {
		errs = append(errs, errors.New("orgID is required"))
	}

	if s.OrgRole == "" && len(s.OrgPermissions) == 0 {
		errs = append(errs, errors.New("orgRole or orgPermissions is required"))
	}

	return errors.Join(errs...)
}

// WithLogger returns a new logger with the session context
func (s AuthenticationSession) WithLogger(logger *slog.Logger) *slog.Logger {
	return logger.With(
		slog.String("orgId", s.OrgID),
		slog.String("userId", s.UserID),
		slog.String("orgSlug", s.OrgSlug),
		slog.String("orgRole", s.OrgRole),
		slog.String("orgPermissions", strings.Join(s.OrgPermissions, ",")),
	)
}