main
 1package web
 2
 3import (
 4	"fmt"
 5	"net/http"
 6	"time"
 7
 8	"github.com/golang-jwt/jwt"
 9	"github.com/hashicorp/uuid"
10)
11
12var (
13	tokens = map[string]string{}
14)
15
16type TokenRequest struct {
17	GrantType   string
18	Code        string
19	RedirectUri string
20}
21
22type TokenResponse struct {
23	AccessToken  string
24	TokenType    string
25	RefreshToken string
26	ExpiresIn    int
27	IdToken      string
28}
29
30func (h *HttpContext) Token(w http.ResponseWriter, r *http.Request) {
31	if r.Method == "POST" {
32		tr := &TokenRequest{
33			GrantType:   r.FormValue("grant_type"),
34			Code:        r.FormValue("code"),
35			RedirectUri: r.FormValue("redirect_uri"),
36		}
37		if tr.GrantType == "authorization_code" {
38			// Authorization Code Flow https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
39			r := &TokenResponse{
40				AccessToken:  tokens[tr.Code],
41				TokenType:    "Bearer",
42				RefreshToken: "TODO::",
43				ExpiresIn:    3600,
44				IdToken:      h.createIdToken(r.FormValue("client_id")),
45			}
46
47			w.Header().Set("Content-Type", "application/json")
48			w.Header().Set("Cache-Control", "no-store")
49			w.Header().Set("Pragma", "no-cache")
50			fmt.Fprintf(w, `{"access_token": "%s","token_type": "%s","refresh_token": "%s","expires_in": %d,"id_token": "%s"}`, r.AccessToken, r.TokenType, r.RefreshToken, r.ExpiresIn, r.IdToken)
51		} else {
52			w.WriteHeader(http.StatusNotFound)
53			fmt.Fprintf(w, "Not Found\n")
54		}
55	}
56}
57
58func (h *HttpContext) createIdToken(clientId string) string {
59	now := time.Now()
60	if clientId == "" {
61		clientId = "clientId"
62	}
63	expiresAt := now.Add(time.Hour * time.Duration(1))
64	idToken := jwt.NewWithClaims(jwt.SigningMethodRS256, &jwt.StandardClaims{
65		Issuer:    h.cfg.Issuer,
66		Subject:   "1",
67		Audience:  clientId,
68		ExpiresAt: expiresAt.Unix(),
69		NotBefore: now.Unix(),
70		IssuedAt:  now.Unix(),
71		Id:        uuid.GenerateUUID(),
72	})
73
74	key, _ := jwt.ParseRSAPrivateKeyFromPEM(h.cfg.KeyData)
75	signedIdToken, _ := idToken.SignedString(key)
76	return signedIdToken
77}