1 package oauth2
2
3 import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7
8 "edge-infra.dev/pkg/edge/iam/apperror"
9 "edge-infra.dev/pkg/edge/iam/client"
10 "edge-infra.dev/pkg/edge/iam/config"
11 "edge-infra.dev/pkg/edge/iam/log"
12 "edge-infra.dev/pkg/edge/iam/profile"
13 "edge-infra.dev/pkg/edge/iam/session"
14
15 "github.com/gin-gonic/gin"
16 "github.com/ory/fosite"
17 )
18
19
20 func (oauth2 *OAuth2) auth(ctx *gin.Context) error {
21 log := log.Get(ctx.Request.Context())
22
23 requester, err := oauth2.fosite.NewAuthorizeRequest(ctx, ctx.Request)
24 if err != nil {
25 clientID := ctx.Request.URL.Query().Get("client_id")
26 rfcErr := fosite.ErrorToRFC6749Error(err)
27
28
29
30
31
32
33 msg := fmt.Sprintf("failed to process authorize request (client_id=%v). %v", clientID, rfcErr.Error())
34 return apperror.NewRedirectError("/esod?reason=invalid_auth_request", msg, rfcErr)
35 }
36
37 cookieSession, _ := oauth2.store.Get(ctx.Request, "oauth2")
38 client := requester.GetClient().(*client.Client)
39
40
41 hint := ctx.Query("login_hint")
42 if hint != "" {
43 cookieSession.Values = make(map[interface{}]interface{})
44 cookieSession.Values["client_name"] = client.GetClientName()
45 cookieSession.Values["client_id"] = client.GetID()
46
47 setRequestURL(cookieSession, ctx)
48 setLDFeatureFlags(ctx, cookieSession, requester)
49 return oauth2.processLoginHint(ctx, cookieSession, hint, client.GetID(), requester)
50 }
51
52
53 _, wasGivenChallenge := getChallenge(ctx)
54 if cookieSession.IsNew || !wasGivenChallenge {
55 cookieSession.Values = make(map[interface{}]interface{})
56 cookieSession.Values["client_name"] = client.GetClientName()
57 cookieSession.Values["client_id"] = client.GetID()
58 setRequestURL(cookieSession, ctx)
59 setLDFeatureFlags(ctx, cookieSession, requester)
60 if requester.GetRequestedScopes().Has("barcode") {
61 ctx.Redirect(http.StatusFound, "/cloud/federate")
62 return nil
63 }
64
65 if config.DeviceLoginEnabled() {
66 ctx.Redirect(http.StatusFound, "/idp/entry/device")
67 return nil
68 }
69
70 ctx.Redirect(http.StatusFound, "/idp/entry/pin")
71 return nil
72 }
73
74
75 err = ValidateChallenge(ctx, client.GetID(), cookieSession)
76 if err != nil {
77 return apperror.NewRedirectError("/esod?reason=invalid_session", err.Error(), err)
78 }
79
80
81 expectedURL := cookieSession.Values["request_url"].(string) + "&challenge=" + cookieSession.Values["continuation"].(string)
82 if ctx.Request.URL.String() != expectedURL {
83 msg := "possible url tempering detected. requested url not equal to expected url"
84 return apperror.NewRedirectError("/esod?reason=invalid_request_url", msg, nil)
85 }
86
87
88 subject := cookieSession.Values["sub"].(string)
89 if subject == "" {
90 msg := "could not find subject on the cookie session, redirecting to esod with invalid_session"
91 return apperror.NewRedirectError("/esod?reason=invalid_session", msg, nil)
92 }
93
94
95
96
97 for _, scope := range requester.GetRequestedScopes() {
98 requester.GrantScope(scope)
99 }
100
101
102 authSession := session.NewSession(subject)
103
104
105 rls := cookieSession.Values["rls"].(string)
106 authSession.SetRls(rls)
107
108
109 gn, ok := cookieSession.Values["gn"]
110 if ok {
111 authSession.SetGivenName(gn.(string))
112 }
113
114 fn, ok := cookieSession.Values["fn"]
115 if ok {
116 authSession.SetFamilyName(fn.(string))
117 }
118
119 n, ok := cookieSession.Values["n"]
120 if ok {
121 authSession.SetFullName(n.(string))
122 }
123
124 age, ok := cookieSession.Values["age"]
125 if ok {
126 authSession.SetAge(age.(int))
127 }
128
129 dl, ok := cookieSession.Values["device_login"]
130 if ok {
131 authSession.SetDeviceLogin(dl.(string))
132 }
133
134
135 email, ok := cookieSession.Values["email"]
136 if ok {
137 authSession.SetEmail(email.(string))
138 }
139
140
141 addressVal, ok := cookieSession.Values["address"]
142 if ok {
143 address := addressVal.(string)
144 var addressClaim profile.AddressClaim
145 err = json.Unmarshal([]byte(address), &addressClaim)
146 if err != nil {
147 log.Error(err, "failed to unmarshal user's address")
148 } else {
149 addressClaimMap := addressClaim.ToMap()
150 authSession.SetAddress(addressClaimMap)
151 }
152 }
153
154
155 responder, err := oauth2.fosite.NewAuthorizeResponse(ctx, requester, authSession)
156 if err != nil {
157
158
159
160
161
162 return apperror.NewRedirectError("/esod?reason=invalid_auth_response", "failed to create an AuthorizeResponder", err)
163 }
164
165
166 cookieSession.Options.MaxAge = -1
167 err = cookieSession.Save(ctx.Request, ctx.Writer)
168 if err != nil {
169 log.Error(err, "failed to save cookie session post setting the maxAge")
170 }
171
172
173 oauth2.fosite.WriteAuthorizeResponse(ctx.Writer, requester, responder)
174 return nil
175 }
176
View as plain text