authenticate: fix impersonation getting cleared (#411)

This commit is contained in:
Bobby DeSimone 2019-11-30 10:54:32 -08:00 committed by GitHub
parent edba21e0c9
commit 74cd9eabbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 11 deletions

View file

@ -142,7 +142,14 @@ func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) {
return
}
s.SetImpersonation(r.FormValue(urlutil.QueryImpersonateEmail), r.FormValue(urlutil.QueryImpersonateGroups))
// user impersonation
if impersonate := r.FormValue(urlutil.QueryImpersonateAction); impersonate != "" {
s.SetImpersonation(r.FormValue(urlutil.QueryImpersonateEmail), r.FormValue(urlutil.QueryImpersonateGroups))
if err := a.sessionStore.SaveSession(w, r, s); err != nil {
httputil.ErrorResponse(w, r, httputil.Error(err.Error(), http.StatusBadRequest, err))
return
}
}
newSession := s.NewSession(a.RedirectURL.Host, jwtAudience)

View file

@ -121,6 +121,8 @@ func TestAuthenticate_SignIn(t *testing.T) {
{"bad callback uri set", "https", "corp.example.example", map[string]string{urlutil.QueryCallbackURI: "^", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &sessions.MockSessionStore{Session: &sessions.State{Email: "user@pomerium.io", AccessToken: &oauth2.Token{Expiry: time.Now().Add(10 * time.Second)}}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusBadRequest},
{"good programmatic request", "https", "corp.example.example", map[string]string{urlutil.QueryIsProgrammatic: "true", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &sessions.MockSessionStore{Session: &sessions.State{Email: "user@pomerium.io", AccessToken: &oauth2.Token{Expiry: time.Now().Add(10 * time.Second)}}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
{"good additional audience", "https", "corp.example.example", map[string]string{urlutil.QueryForwardAuth: "x.y.z", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &sessions.MockSessionStore{Session: &sessions.State{Email: "user@pomerium.io", AccessToken: &oauth2.Token{Expiry: time.Now().Add(10 * time.Second)}}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
{"good user impersonate", "https", "corp.example.example", map[string]string{urlutil.QueryImpersonateAction: "set", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &sessions.MockSessionStore{Session: &sessions.State{Email: "user@pomerium.io", AccessToken: &oauth2.Token{Expiry: time.Now().Add(10 * time.Second)}}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusFound},
{"bad user impersonate save failure", "https", "corp.example.example", map[string]string{urlutil.QueryImpersonateAction: "set", urlutil.QueryRedirectURI: "https://dst.some.example/"}, &sessions.MockSessionStore{SaveError: errors.New("err"), Session: &sessions.State{Email: "user@pomerium.io", AccessToken: &oauth2.Token{Expiry: time.Now().Add(10 * time.Second)}}}, identity.MockProvider{}, &mock.Encoder{}, http.StatusBadRequest},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View file

@ -201,7 +201,7 @@
<label>
<span>Email</span>
<input
name="email"
name="{{ .ImpersonateEmail }}"
type="email"
class="field"
value=""
@ -211,7 +211,7 @@
<label>
<span>Group</span>
<input
name="group"
name=" {{ .ImpersonateGroups }}"
type="text"
class="field"
value=""
@ -222,8 +222,13 @@
</section>
<div class="flex">
{{ .csrfField }}
<button class="button full" type="submit">
Impersonate session
<button
name="{{ .ImpersonateAction }}"
value="set"
class="button full"
type="submit"
>
Impersonate
</button>
</div>
</form>

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,7 @@ const (
QueryCallbackURI = "pomerium_callback_uri"
QueryImpersonateEmail = "pomerium_impersonate_email"
QueryImpersonateGroups = "pomerium_impersonate_groups"
QueryImpersonateAction = "pomerium_impersonate_action"
QueryIsProgrammatic = "pomerium_programmatic"
QueryForwardAuth = "pomerium_forward_auth"
QueryPomeriumJWT = "pomerium_jwt"

View file

@ -98,9 +98,12 @@ func (p *Proxy) UserDashboard(w http.ResponseWriter, r *http.Request) {
}
p.templates.ExecuteTemplate(w, "dashboard.html", map[string]interface{}{
"Session": session,
"IsAdmin": isAdmin,
"csrfField": csrf.TemplateField(r),
"Session": session,
"IsAdmin": isAdmin,
"csrfField": csrf.TemplateField(r),
"ImpersonateAction": urlutil.QueryImpersonateAction,
"ImpersonateEmail": urlutil.QueryImpersonateEmail,
"ImpersonateGroups": urlutil.QueryImpersonateGroups,
})
}
@ -126,8 +129,9 @@ func (p *Proxy) Impersonate(w http.ResponseWriter, r *http.Request) {
signinURL := *p.authenticateSigninURL
q := signinURL.Query()
q.Set(urlutil.QueryRedirectURI, redirectURL.String())
q.Set(urlutil.QueryImpersonateEmail, r.FormValue("email"))
q.Set(urlutil.QueryImpersonateGroups, r.FormValue("group"))
q.Set(urlutil.QueryImpersonateAction, r.FormValue(urlutil.QueryImpersonateAction))
q.Set(urlutil.QueryImpersonateEmail, r.FormValue(urlutil.QueryImpersonateEmail))
q.Set(urlutil.QueryImpersonateGroups, r.FormValue(urlutil.QueryImpersonateGroups))
signinURL.RawQuery = q.Encode()
httputil.Redirect(w, r, urlutil.NewSignedURL(p.SharedKey, &signinURL).String(), http.StatusFound)
}