Skip to content

Commit

Permalink
fix: refresh tokens when necessary
Browse files Browse the repository at this point in the history
This change will detect expired sessions and refresh them when
necessary.

Signed-off-by: Donnie Adams <[email protected]>
  • Loading branch information
thedadams committed Jan 20, 2025
1 parent db87549 commit c31a415
Showing 1 changed file with 54 additions and 1 deletion.
55 changes: 54 additions & 1 deletion auth-providers-common/pkg/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type SerializableState struct {
PreferredUsername string `json:"preferredUsername"`
User string `json:"user"`
Email string `json:"email"`
SetCookie string `json:"setCookie"`
}

func ObotGetState(p *oauth2proxy.OAuthProxy) http.HandlerFunc {
Expand Down Expand Up @@ -50,17 +51,69 @@ func ObotGetState(p *oauth2proxy.OAuthProxy) http.HandlerFunc {
return
}

var setCookie string
if state.IsExpired() {
setCookie, err = refreshToken(p, reqObj)
if err != nil {
http.Error(w, fmt.Sprintf("failed to refresh token: %v", err), http.StatusForbidden)
return
}
}

ss := SerializableState{
ExpiresOn: state.ExpiresOn,
AccessToken: state.AccessToken,
PreferredUsername: state.PreferredUsername,
User: state.User,
Email: state.Email,
SetCookie: setCookie,
}

if err := json.NewEncoder(w).Encode(ss); err != nil {
if err = json.NewEncoder(w).Encode(ss); err != nil {
http.Error(w, fmt.Sprintf("failed to encode state: %v", err), http.StatusInternalServerError)
return
}
}
}

func refreshToken(p *oauth2proxy.OAuthProxy, r *http.Request) (string, error) {
w := &response{
headers: make(http.Header),
}

req, err := http.NewRequest(r.Method, "/oauth2/auth", nil)
if err != nil {
return "", fmt.Errorf("failed to create refresh request object: %v", err)
}

req.Header = r.Header
p.ServeHTTP(w, req)

switch w.status {
case http.StatusOK, http.StatusAccepted:
return w.headers.Get("Set-Cookie"), nil
case http.StatusUnauthorized, http.StatusForbidden:
return "", fmt.Errorf("refreshing token returned %d: %s", w.status, w.body)
default:
return "", fmt.Errorf("refreshing token returned unexpected status %d: %s", w.status, w.body)
}
}

type response struct {
headers http.Header
body []byte
status int
}

func (r *response) Header() http.Header {
return r.headers
}

func (r *response) Write(b []byte) (int, error) {
r.body = append(r.body, b...)
return len(b), nil
}

func (r *response) WriteHeader(status int) {
r.status = status
}

0 comments on commit c31a415

Please sign in to comment.