forked from mystiq/dex
examples/app: add facilities for requesting groups
This commit is contained in:
parent
b02a3a3163
commit
a741bb5711
3 changed files with 73 additions and 58 deletions
|
@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} {
|
|||
return nil
|
||||
}
|
||||
|
||||
var _dataIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x52\xcd\x4e\xc3\x30\x0c\xbe\xef\x29\xac\x9c\xe0\x30\x7a\x47\x6d\x25\x40\xdc\x90\x26\xf1\x02\x53\x9a\x78\x6d\xb4\xfc\x4c\x89\x8b\x36\x4d\x7b\x77\xdc\x96\xae\x5b\x81\x09\x6e\xfe\x14\xfb\xfb\x89\x9d\x37\xe4\x6c\xb9\x00\xc8\xab\xa0\x0f\xe5\x82\x2b\xae\x37\x21\x3a\x90\x8a\x4c\xf0\x85\xc8\x6c\xa8\x8d\x17\x65\xff\xc4\x8f\x24\x2b\x8b\x23\xea\x70\x9c\x40\x07\x75\x09\x4f\x2d\x35\xe8\xc9\x28\x49\x08\x4c\xf6\x78\xd1\xd0\x49\x5d\x4d\x00\xdc\xa9\xe0\x9c\x5c\x26\xdc\xc9\xc8\x13\x1a\xac\x49\x04\x61\x03\xca\x1a\xa6\x59\x1a\x9d\xee\x2f\x25\x32\xd6\x98\x4b\xe6\xc6\xef\x5a\x02\x3a\xec\xb0\x10\x84\x7b\x12\xe0\xa5\xe3\x5a\xc5\x90\xd2\x7a\x60\x12\x50\xce\xa6\x19\x9d\xcd\x70\x3d\x44\x3b\x1e\xc1\x6c\xe0\x61\xb5\x7a\x86\xd3\x69\x6a\xbd\x54\x48\x6d\xe5\x0c\xf3\x7d\x48\xdb\x32\x7c\xeb\xbf\xa8\x8b\xea\x48\xc6\x1a\xa9\x10\xeb\xca\x4a\xbf\x15\x3d\x1b\xda\x84\xff\xa4\x1a\xe6\xbc\x1e\xc7\xf2\xac\x23\xe7\x05\x7d\x37\x37\x5b\x97\x92\xd6\x56\x52\x6d\x05\x38\xa4\x26\xe8\x42\xb0\x9f\x8e\x70\xd0\x7e\x09\x1a\x17\x3f\xd8\xb8\xfa\x33\xee\x39\x1b\x9a\x36\x3f\xed\xed\x56\x80\xd7\xbd\x6a\xa4\xaf\xb1\x57\x1a\x75\x47\xfb\xd7\xa1\xbe\xc2\xf8\x40\xb7\x02\x45\xac\xf9\x1e\x30\x8a\xbf\xa8\xbf\x8f\xcd\x00\xd9\xef\xd2\x79\x36\x9c\x7b\x9e\x0d\xf7\xff\x19\x00\x00\xff\xff\xaf\x0b\xca\x75\x07\x03\x00\x00")
|
||||
var _dataIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x93\xcf\x8a\xe3\x30\x0c\xc6\xef\x7d\x0a\xe1\x7b\x37\xf7\xc5\x29\xec\x0e\xbd\x0d\x14\xe6\x05\x8a\x63\xab\x89\xa9\xff\x61\x2b\x43\x4b\xe9\xbb\x8f\x53\x37\x61\x52\xd2\xa1\x73\x93\xd1\x27\x7d\x3f\x49\x98\x77\x64\xcd\x66\x05\xc0\x1b\xaf\xce\x43\x90\xc3\x83\x8f\x16\x84\x24\xed\x5d\xcd\x2a\xe3\x5b\xed\x58\x49\x0d\xd9\x30\x85\x00\xff\x7a\xea\xd0\x91\x96\x82\x10\x72\xd9\x5f\xae\x5d\xe8\x09\xe8\x1c\xb0\x66\x84\x27\x62\xe0\x84\xcd\xb1\x8c\x3e\xa5\xbd\x34\x3a\xcb\x19\x04\x23\x24\x76\xde\x28\x8c\x39\xe5\xad\x15\xeb\x84\x41\xc4\xdc\x46\x81\xd1\x89\xc0\x1f\xa0\x88\xd7\x5a\xa5\x6f\xee\x55\x58\x26\xd9\x9e\x28\x0a\x48\xd2\x07\x4c\xcf\x29\x70\x50\xed\x8b\xea\x45\x8a\xbb\x78\x4e\x70\xb9\x80\x3e\xc0\x9f\xdd\xee\x3f\x5c\xaf\x13\xc4\xcc\x36\xf5\x8d\xd5\xd9\xf8\x53\x98\x3e\x3f\xdf\x6f\x5b\x1c\x76\x64\x49\xc4\x16\xa9\x66\xfb\xc6\x08\x77\x64\xb7\x6e\x68\x12\xfe\xb2\x55\xa9\x73\x6a\x2c\xe3\xd5\xd0\x7c\xb3\x5a\x80\x7b\xb8\xa8\x14\xc6\x34\x42\x1e\x19\x58\xa4\xce\xab\x9a\x65\x9e\xa1\x61\xf1\x7e\xf3\x0a\x57\x0b\x18\xb3\x73\x66\xcd\x04\x34\x2d\x87\x37\x71\xb3\x54\xf9\x30\xc0\xf6\x24\x3b\xe1\x5a\xbc\x39\x8d\xbe\x23\xfe\x7c\xa8\xfb\x30\xce\xd3\x4f\x03\x45\x6c\xf3\xb5\x30\xb2\x57\xdc\x3f\x46\x31\x40\xf5\xdc\x9a\x57\xe5\x43\xf0\xaa\xfc\x90\xaf\x00\x00\x00\xff\xff\x9c\x89\xe2\x28\x29\x03\x00\x00")
|
||||
|
||||
func dataIndexHtmlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
|
@ -83,7 +83,7 @@ func dataIndexHtml() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "data/index.html", size: 775, mode: os.FileMode(420), modTime: time.Unix(1466378108, 0)}
|
||||
info := bindataFileInfo{name: "data/index.html", size: 809, mode: os.FileMode(436), modTime: time.Unix(1468620773, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<form action="/login">
|
||||
<table>
|
||||
<tr>
|
||||
<td> Authenticate for:
|
||||
<br>
|
||||
(comma-separated list of client-ids)
|
||||
</td>
|
||||
<td> <input type="text" name="cross_client" > </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Authenticate for:<input type="text" name="cross_client" placeholder="comma-separated list of client-ids">
|
||||
</p>
|
||||
<p>
|
||||
Extra scopes:<input type="text" name="extra_scopes" placeholder="comma-separated list of scopes">
|
||||
</p>
|
||||
{{ if .OOB }}
|
||||
<input type="submit" value="Login" formtarget="_blank">
|
||||
{{ else }}
|
||||
|
|
|
@ -218,18 +218,25 @@ func handleLoginFunc(c *oidc.Client) http.HandlerFunc {
|
|||
panic("unable to proceed")
|
||||
}
|
||||
|
||||
xClient := r.Form.Get("cross_client")
|
||||
if xClient != "" {
|
||||
var scopes []string
|
||||
q := u.Query()
|
||||
if scope := q.Get("scope"); scope != "" {
|
||||
scopes = strings.Split(scope, " ")
|
||||
}
|
||||
|
||||
if xClient := r.Form.Get("cross_client"); xClient != "" {
|
||||
xClients := strings.Split(xClient, ",")
|
||||
for i, x := range xClients {
|
||||
xClients[i] = scope.ScopeGoogleCrossClient + x
|
||||
for _, x := range xClients {
|
||||
scopes = append(scopes, scope.ScopeGoogleCrossClient+x)
|
||||
}
|
||||
q := u.Query()
|
||||
scope := q.Get("scope")
|
||||
scopes := strings.Split(scope, " ")
|
||||
scopes = append(scopes, xClients...)
|
||||
scope = strings.Join(scopes, " ")
|
||||
q.Set("scope", scope)
|
||||
}
|
||||
|
||||
if extraScopes := r.Form.Get("extra_scopes"); extraScopes != "" {
|
||||
scopes = append(scopes, strings.Split(extraScopes, ",")...)
|
||||
}
|
||||
|
||||
if scopes != nil {
|
||||
q.Set("scope", strings.Join(scopes, " "))
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
|
@ -292,57 +299,69 @@ func handleResendFunc(c *oidc.Client, issuerURL, resendURL, cbURL url.URL) http.
|
|||
|
||||
func handleCallbackFunc(c *oidc.Client) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
refreshToken := r.URL.Query().Get("refresh_token")
|
||||
code := r.URL.Query().Get("code")
|
||||
if code == "" {
|
||||
|
||||
oac, err := c.OAuthClient()
|
||||
if err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to create OAuth2 client: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
var token oauth2.TokenResponse
|
||||
|
||||
switch {
|
||||
case code != "":
|
||||
if token, err = oac.RequestToken(oauth2.GrantTypeAuthCode, code); err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err))
|
||||
return
|
||||
}
|
||||
case refreshToken != "":
|
||||
if token, err = oac.RequestToken(oauth2.GrantTypeRefreshToken, refreshToken); err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to refresh token: %v", err))
|
||||
return
|
||||
}
|
||||
if token.RefreshToken == "" {
|
||||
token.RefreshToken = refreshToken
|
||||
}
|
||||
default:
|
||||
phttp.WriteError(w, http.StatusBadRequest, "code query param must be set")
|
||||
return
|
||||
}
|
||||
|
||||
tokens, err := exchangeAuthCode(c, code)
|
||||
tok, err := jose.ParseJWT(token.IDToken)
|
||||
if err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest,
|
||||
fmt.Sprintf("unable to verify auth code with issuer: %v", err))
|
||||
phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to parse JWT: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
tok, err := jose.ParseJWT(tokens.IDToken)
|
||||
if err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest,
|
||||
fmt.Sprintf("unable to parse JWT: %v", err))
|
||||
claims := new(bytes.Buffer)
|
||||
if err := json.Indent(claims, tok.Payload, "", " "); err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := tok.Claims()
|
||||
if err != nil {
|
||||
phttp.WriteError(w, http.StatusBadRequest,
|
||||
fmt.Sprintf("unable to construct claims: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
s := fmt.Sprintf(`
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
/* make pre wrap */
|
||||
pre {
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p> Token: %v</p>
|
||||
<p> Claims: %v </p>
|
||||
<a href="/resend?jwt=%s">Resend Verification Email</a>
|
||||
<p> Refresh Token: %v </p>
|
||||
<p> Token: <pre><code>%v</code></pre></p>
|
||||
<p> Claims: <pre><code>%v</code></pre></p>
|
||||
<p> Refresh Token: <pre><code>%v</code></pre></p>
|
||||
<p><a href="%s?refresh_token=%s">Redeem refresh token</a><p>
|
||||
<p><a href="/resend?jwt=%s">Resend Verification Email</a></p>
|
||||
</body>
|
||||
</html>`, tok.Encode(), claims, tok.Encode(), tokens.RefreshToken)
|
||||
</html>`, tok.Encode(), claims.String(), token.RefreshToken, r.URL.Path, token.RefreshToken, tok.Encode())
|
||||
w.Write([]byte(s))
|
||||
}
|
||||
}
|
||||
|
||||
func exchangeAuthCode(c *oidc.Client, code string) (oauth2.TokenResponse, error) {
|
||||
oac, err := c.OAuthClient()
|
||||
if err != nil {
|
||||
return oauth2.TokenResponse{}, err
|
||||
}
|
||||
|
||||
t, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code)
|
||||
if err != nil {
|
||||
return oauth2.TokenResponse{}, err
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue