github.com/hashicorp/cap@v0.6.0/oidc/examples/spa/route_success.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"fmt"
    10  	"net/http"
    11  	"os"
    12  	"time"
    13  
    14  	"github.com/hashicorp/cap/oidc"
    15  )
    16  
    17  func SuccessHandler(ctx context.Context, rc *requestCache) http.HandlerFunc {
    18  	const op = "SuccessHandler"
    19  	return func(w http.ResponseWriter, r *http.Request) {
    20  		state := r.FormValue("state")
    21  		oidcRequest, err := rc.Read(ctx, state)
    22  		if err != nil {
    23  			fmt.Fprintf(os.Stderr, "error reading state during successful response: %s", err)
    24  			http.Error(w, err.Error(), http.StatusInternalServerError)
    25  			return
    26  		}
    27  		defer rc.Delete(state)
    28  		extended, ok := oidcRequest.(extendedRequest)
    29  		if !ok {
    30  			err := fmt.Errorf("%s: not an extended state", op)
    31  			fmt.Fprint(os.Stderr, err)
    32  			http.Error(w, err.Error(), http.StatusInternalServerError)
    33  			return
    34  		}
    35  
    36  		t := printableToken(extended.t)
    37  		tokenData, err := json.MarshalIndent(t, "", "    ")
    38  		if err != nil {
    39  			fmt.Fprint(os.Stderr, err)
    40  			http.Error(w, err.Error(), http.StatusInternalServerError)
    41  			return
    42  		}
    43  		if _, err := w.Write(tokenData); err != nil {
    44  			http.Error(w, err.Error(), http.StatusInternalServerError)
    45  		}
    46  	}
    47  }
    48  
    49  type respToken struct {
    50  	IDToken      string
    51  	AccessToken  string
    52  	RefreshToken string
    53  	Expiry       time.Time
    54  }
    55  
    56  // printableToken is needed because the oidc.Token redacts the IDToken,
    57  // AccessToken and RefreshToken
    58  func printableToken(t oidc.Token) respToken {
    59  	return respToken{
    60  		IDToken:      string(t.IDToken()),
    61  		AccessToken:  string(t.AccessToken()),
    62  		RefreshToken: string(t.RefreshToken()),
    63  		Expiry:       t.Expiry(),
    64  	}
    65  }