-
Notifications
You must be signed in to change notification settings - Fork 2
/
login_callback.go
95 lines (76 loc) · 2.72 KB
/
login_callback.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
package supporter
import (
"context"
"errors"
"net/http"
"time"
"github.com/ministryofjustice/opg-modernising-lpa/internal/dynamo"
"github.com/ministryofjustice/opg-modernising-lpa/internal/onelogin"
"github.com/ministryofjustice/opg-modernising-lpa/internal/page"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sesh"
)
type LoginCallbackOneLoginClient interface {
Exchange(ctx context.Context, code, nonce string) (idToken, accessToken string, err error)
UserInfo(ctx context.Context, accessToken string) (onelogin.UserInfo, error)
}
func LoginCallback(oneLoginClient LoginCallbackOneLoginClient, sessionStore SessionStore, organisationStore OrganisationStore, now func() time.Time, memberStore MemberStore) page.Handler {
return func(appData page.AppData, w http.ResponseWriter, r *http.Request) error {
oneLoginSession, err := sessionStore.OneLogin(r)
if err != nil {
return err
}
idToken, accessToken, err := oneLoginClient.Exchange(r.Context(), r.FormValue("code"), oneLoginSession.Nonce)
if err != nil {
return err
}
userInfo, err := oneLoginClient.UserInfo(r.Context(), accessToken)
if err != nil {
return err
}
loginSession := &sesh.LoginSession{
IDToken: idToken,
Sub: "supporter-" + userInfo.Sub,
Email: userInfo.Email,
}
sessionData := &page.SessionData{SessionID: loginSession.SessionID(), Email: loginSession.Email}
ctx := page.ContextWithSessionData(r.Context(), sessionData)
member, err := memberStore.GetAny(ctx)
if errors.Is(err, dynamo.NotFoundError{}) {
invites, err := memberStore.InvitedMembersByEmail(ctx)
if err != nil {
return err
}
if err := sessionStore.SetLogin(r, w, loginSession); err != nil {
return err
}
if len(invites) > 0 {
return page.Paths.Supporter.EnterReferenceNumber.Redirect(w, r, appData)
}
return page.Paths.Supporter.EnterYourName.Redirect(w, r, appData)
} else if err != nil {
return err
}
organisation, err := organisationStore.Get(ctx)
if errors.Is(err, dynamo.NotFoundError{}) {
if err := sessionStore.SetLogin(r, w, loginSession); err != nil {
return err
}
return page.Paths.Supporter.EnterOrganisationName.Redirect(w, r, appData)
} else if err != nil {
return err
}
loginSession.OrganisationID = organisation.ID
loginSession.OrganisationName = organisation.Name
if err := sessionStore.SetLogin(r, w, loginSession); err != nil {
return err
}
sessionData.OrganisationID = organisation.ID
ctx = page.ContextWithSessionData(r.Context(), sessionData)
member.LastLoggedInAt = now()
member.Email = loginSession.Email
if err := memberStore.Put(ctx, member); err != nil {
return err
}
return page.Paths.Supporter.Dashboard.Redirect(w, r, appData)
}
}