-
Notifications
You must be signed in to change notification settings - Fork 279
/
events.go
101 lines (87 loc) · 2.62 KB
/
events.go
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
91
92
93
94
95
96
97
98
99
100
101
package authenticate
import (
"context"
"net/http"
"net/url"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/grpc/identity"
"github.com/pomerium/pomerium/pkg/hpke"
)
// AuthEventKind is the type of an authentication event
type AuthEventKind string
const (
// AuthEventSignInRequest is an authentication event for a sign in request before IdP redirect
AuthEventSignInRequest AuthEventKind = "sign_in_request"
// AuthEventSignInComplete is an authentication event for a sign in request after IdP redirect
AuthEventSignInComplete AuthEventKind = "sign_in_complete"
)
// AuthEvent is a log event for an authentication event
type AuthEvent struct {
// Event is the type of authentication event
Event AuthEventKind
// IP is the IP address of the client
IP string
// Version is the version of the Pomerium client
Version string
// RequestUUID is the UUID of the request
RequestUUID string
// PubKey is the public key of the client
PubKey string
// UID is the IdP user ID of the user
UID *string
// Email is the email of the user
Email *string
// Domain is the domain of the request (for sign in complete events)
Domain *string
}
// AuthEventFn is a function that handles an authentication event
type AuthEventFn func(context.Context, AuthEvent)
func (a *Authenticate) logAuthenticateEvent(r *http.Request, profile *identity.Profile) {
if a.cfg.authEventFn == nil {
return
}
state := a.state.Load()
ctx := r.Context()
pub, params, err := hpke.DecryptURLValues(state.hpkePrivateKey, r.Form)
if err != nil {
log.Warn(ctx).Err(err).Msg("log authenticate event: failed to decrypt request params")
}
evt := AuthEvent{
IP: httputil.GetClientIP(r),
Version: params.Get(urlutil.QueryVersion),
RequestUUID: params.Get(urlutil.QueryRequestUUID),
PubKey: pub.String(),
}
if uid := getUserClaim(profile, "sub"); uid != nil {
evt.UID = uid
}
if email := getUserClaim(profile, "email"); email != nil {
evt.Email = email
}
if evt.UID != nil {
evt.Event = AuthEventSignInComplete
} else {
evt.Event = AuthEventSignInRequest
}
if redirectURL, err := url.Parse(params.Get(urlutil.QueryRedirectURI)); err == nil {
domain := redirectURL.Hostname()
evt.Domain = &domain
}
a.cfg.authEventFn(ctx, evt)
}
func getUserClaim(profile *identity.Profile, field string) *string {
if profile == nil {
return nil
}
if profile.Claims == nil {
return nil
}
val, ok := profile.Claims.Fields[field]
if !ok || val == nil {
return nil
}
txt := val.GetStringValue()
return &txt
}