try different packags structures
This commit is contained in:
parent
f6ba7ab75e
commit
f19df22e8e
36 changed files with 1821 additions and 23 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -10,3 +10,6 @@
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
|
|
||||||
|
**/__debug_bin
|
||||||
|
.vscode
|
||||||
|
|
1
docs.go
1
docs.go
|
@ -1 +0,0 @@
|
||||||
package oidc
|
|
90
example/client/api/api.go
Normal file
90
example/client/api/api.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/caos/go-oidc/pkg/oidc"
|
||||||
|
"github.com/caos/go-oidc/pkg/oidc/defaults"
|
||||||
|
"github.com/caos/utils/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
publicURL string = "/public"
|
||||||
|
protectedURL string = "/protected"
|
||||||
|
protectedExchangeURL string = "/protected/exchange"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
clientID := os.Getenv("CLIENT_ID")
|
||||||
|
clientSecret := os.Getenv("CLIENT_SECRET")
|
||||||
|
issuer := os.Getenv("ISSUER")
|
||||||
|
port := os.Getenv("PORT")
|
||||||
|
|
||||||
|
// ctx := context.Background()
|
||||||
|
|
||||||
|
providerConfig := &oidc.ProviderConfig{
|
||||||
|
ClientID: clientID,
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
Issuer: issuer,
|
||||||
|
}
|
||||||
|
provider, err := defaults.NewDefaultProvider(providerConfig)
|
||||||
|
logging.Log("APP-nx6PeF").OnError(err).Panic("error creating provider")
|
||||||
|
|
||||||
|
http.HandleFunc(publicURL, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("OK"))
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc(protectedURL, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ok, token := checkToken(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, err := provider.Introspect(r.Context(), token)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(resp)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc(protectedExchangeURL, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ok, token := checkToken(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tokens, err := provider.DelegationTokenExchange(r.Context(), token, oidc.WithResource([]string{"Test"}))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to exchange token: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(tokens)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
lis := fmt.Sprintf("127.0.0.1:%s", port)
|
||||||
|
log.Printf("listening on http://%s/", lis)
|
||||||
|
log.Fatal(http.ListenAndServe(lis, nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkToken(w http.ResponseWriter, r *http.Request) (bool, string) {
|
||||||
|
token := r.Header.Get("authorization")
|
||||||
|
if token == "" {
|
||||||
|
http.Error(w, "Auth header missing", http.StatusUnauthorized)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
return true, token
|
||||||
|
}
|
95
example/client/app/app.go
Normal file
95
example/client/app/app.go
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/client"
|
||||||
|
"github.com/caos/oidc/pkg/client/defaults"
|
||||||
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
|
"github.com/caos/oidc/pkg/utils"
|
||||||
|
"github.com/caos/utils/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
callbackPath string = "/auth/callback"
|
||||||
|
hashKey []byte = []byte("test")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
clientID := os.Getenv("CLIENT_ID")
|
||||||
|
clientSecret := os.Getenv("CLIENT_SECRET")
|
||||||
|
issuer := os.Getenv("ISSUER")
|
||||||
|
port := os.Getenv("PORT")
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
rpConfig := &client.RelayingPartyConfig{
|
||||||
|
ClientID: clientID,
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
Issuer: issuer,
|
||||||
|
CallbackURL: fmt.Sprintf("http://localhost:%v%v", port, callbackPath),
|
||||||
|
Scopes: []string{"openid", "profile", "email"},
|
||||||
|
}
|
||||||
|
cookieHandler := utils.NewCookieHandler(hashKey, nil, utils.WithUnsecure())
|
||||||
|
provider, err := defaults.NewDefaultRelayingParty(rpConfig, defaults.WithCookieHandler(cookieHandler))
|
||||||
|
logging.Log("APP-nx6PeF").OnError(err).Panic("error creating provider")
|
||||||
|
|
||||||
|
// state := "foobar"
|
||||||
|
state := uuid.New().String()
|
||||||
|
|
||||||
|
http.Handle("/login", provider.AuthURLHandler(state))
|
||||||
|
// http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// http.Redirect(w, r, provider.AuthURL(state), http.StatusFound)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// http.HandleFunc(callbackPath, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// tokens, err := provider.CodeExchange(ctx, r.URL.Query().Get("code"))
|
||||||
|
// if err != nil {
|
||||||
|
// http.Error(w, "failed to exchange token: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// data, err := json.Marshal(tokens)
|
||||||
|
// if err != nil {
|
||||||
|
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// w.Write(data)
|
||||||
|
// })
|
||||||
|
|
||||||
|
var marshal = func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string) {
|
||||||
|
_ = state
|
||||||
|
data, err := json.Marshal(tokens)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Handle(callbackPath, provider.CodeExchangeHandler(marshal))
|
||||||
|
|
||||||
|
http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tokens, err := provider.ClientCredentials(ctx, "urn:abraxas:iam:audience_client_id:TM-V3")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to exchange token: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(tokens)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
})
|
||||||
|
lis := fmt.Sprintf("127.0.0.1:%s", port)
|
||||||
|
logging.Log("APP-upQxIG").Infof("listening on http://%s/", lis)
|
||||||
|
log.Fatal(http.ListenAndServe("127.0.0.1:5556", nil))
|
||||||
|
}
|
1
example/doc.go
Normal file
1
example/doc.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package example
|
22
example/go.mod
Normal file
22
example/go.mod
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module github.com/caos/oidc/example
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
replace github.com/caos/oidc => /Users/livio/workspaces/go/src/github.com/caos/oidc
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/oidc => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/oidc
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/server => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/server
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/client => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/client
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/utils => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/utils
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/caos/oidc/pkg/client v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/oidc/pkg/oidc v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/oidc/pkg/server v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/oidc/pkg/utils v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef
|
||||||
|
github.com/google/uuid v1.1.1
|
||||||
|
)
|
128
example/go.sum
Normal file
128
example/go.sum
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||||
|
github.com/caos/go-oidc v2.0.0+incompatible h1:/DthUByy4DOIcENkqpCoFvz6Bv9N3+EwzlKa5fpDRXA=
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef h1:/a781PnuLvuTOj0PEJ7ByhgqjpC30Jsk+11uGcuxjjA=
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef/go.mod h1:m66FVMc4qkzUaWkRP1acVnYKagyTr9uGpvhCWvnlJoE=
|
||||||
|
github.com/caos/utils/config v0.0.0-20191002113340-78986eef31d3/go.mod h1:4iI2a+qaiRFiLV1RAPG5dLp67M+NP2832toQbG9Uu74=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef h1:ZkyR2deIvTjvULYw6bInjRR4YNfktQ9F6/z0VijtfmU=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef/go.mod h1:1QHTbh4VS/6qN5fOApyEa70ESW+nDri3XE7j3oIzbyU=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef h1:wpkm8hj2qNBOchILsfjLAqMWS1a4C+/7E4RM/NQ7T2U=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||||
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||||
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||||
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||||
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
12
go.mod
12
go.mod
|
@ -1,12 +0,0 @@
|
||||||
module github.com/caos/oidc
|
|
||||||
|
|
||||||
go 1.13
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef
|
|
||||||
github.com/gorilla/mux v1.7.3
|
|
||||||
github.com/stretchr/testify v1.4.0
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
|
||||||
golang.org/x/text v0.3.2
|
|
||||||
gopkg.in/square/go-jose.v2 v2.4.0
|
|
||||||
)
|
|
14
pkg/oidc/go.mod
Normal file
14
pkg/oidc/go.mod
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module github.com/caos/oidc/pkg/oidc
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang/protobuf v1.3.2 // indirect
|
||||||
|
github.com/stretchr/testify v1.4.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f // indirect
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||||
|
golang.org/x/text v0.3.2
|
||||||
|
google.golang.org/appengine v1.6.5 // indirect
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0
|
||||||
|
)
|
43
pkg/oidc/go.sum
Normal file
43
pkg/oidc/go.sum
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||||
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
@ -1,4 +1,4 @@
|
||||||
package oidc
|
package grants
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
75
pkg/oidc/grants/tokenexchange/tokenexchange.go
Normal file
75
pkg/oidc/grants/tokenexchange/tokenexchange.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package tokenexchange
|
||||||
|
|
||||||
|
const (
|
||||||
|
AccessTokenType = "urn:ietf:params:oauth:token-type:access_token"
|
||||||
|
RefreshTokenType = "urn:ietf:params:oauth:token-type:refresh_token"
|
||||||
|
IDTokenType = "urn:ietf:params:oauth:token-type:id_token"
|
||||||
|
JWTTokenType = "urn:ietf:params:oauth:token-type:jwt"
|
||||||
|
DelegationTokenType = AccessTokenType
|
||||||
|
|
||||||
|
TokenExchangeGrantType = "urn:ietf:params:oauth:grant-type:token-exchange"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TokenExchangeRequest struct {
|
||||||
|
grantType string `schema:"grant_type"`
|
||||||
|
subjectToken string `schema:"subject_token"`
|
||||||
|
subjectTokenType string `schema:"subject_token_type"`
|
||||||
|
actorToken string `schema:"actor_token"`
|
||||||
|
actorTokenType string `schema:"actor_token_type"`
|
||||||
|
resource []string `schema:"resource"`
|
||||||
|
audience []string `schema:"audience"`
|
||||||
|
scope []string `schema:"scope"`
|
||||||
|
requestedTokenType string `schema:"requested_token_type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTokenExchangeRequest(subjectToken, subjectTokenType string, opts ...TokenExchangeOption) *TokenExchangeRequest {
|
||||||
|
t := &TokenExchangeRequest{
|
||||||
|
grantType: TokenExchangeGrantType,
|
||||||
|
subjectToken: subjectToken,
|
||||||
|
subjectTokenType: subjectTokenType,
|
||||||
|
requestedTokenType: AccessTokenType,
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(t)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenExchangeOption func(*TokenExchangeRequest)
|
||||||
|
|
||||||
|
func WithActorToken(token, tokenType string) func(*TokenExchangeRequest) {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.actorToken = token
|
||||||
|
req.actorTokenType = tokenType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAudience(audience []string) func(*TokenExchangeRequest) {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.audience = audience
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithGrantType(grantType string) TokenExchangeOption {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.grantType = grantType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithRequestedTokenType(tokenType string) func(*TokenExchangeRequest) {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.requestedTokenType = tokenType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithResource(resource []string) func(*TokenExchangeRequest) {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.resource = resource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithScope(scope []string) func(*TokenExchangeRequest) {
|
||||||
|
return func(req *TokenExchangeRequest) {
|
||||||
|
req.scope = scope
|
||||||
|
}
|
||||||
|
}
|
13
pkg/oidc/identity_provider.go
Normal file
13
pkg/oidc/identity_provider.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package oidc
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type IdentityProvider interface {
|
||||||
|
// Configuration
|
||||||
|
// Storage() Storage
|
||||||
|
HandleDiscovery(w http.ResponseWriter, r *http.Request)
|
||||||
|
HandleAuthorize(w http.ResponseWriter, r *http.Request)
|
||||||
|
HandleExchange(w http.ResponseWriter, r *http.Request)
|
||||||
|
HandleUserinfo(w http.ResponseWriter, r *http.Request)
|
||||||
|
HttpHandler() *http.Server
|
||||||
|
}
|
22
pkg/oidc/keyset.go
Normal file
22
pkg/oidc/keyset.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package oidc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gopkg.in/square/go-jose.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeySet is a set of publc JSON Web Keys that can be used to validate the signature
|
||||||
|
// of JSON web tokens. This is expected to be backed by a remote key set through
|
||||||
|
// provider metadata discovery or an in-memory set of keys delivered out-of-band.
|
||||||
|
type KeySet interface {
|
||||||
|
// VerifySignature parses the JSON web token, verifies the signature, and returns
|
||||||
|
// the raw payload. Header and claim fields are validated by other parts of the
|
||||||
|
// package. For example, the KeySet does not need to check values such as signature
|
||||||
|
// algorithm, issuer, and audience since the IDTokenVerifier validates these values
|
||||||
|
// independently.
|
||||||
|
//
|
||||||
|
// If VerifySignature makes HTTP requests to verify the token, it's expected to
|
||||||
|
// use any HTTP client associated with the context through ClientContext.
|
||||||
|
VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error)
|
||||||
|
}
|
16
pkg/op/go.mod
Normal file
16
pkg/op/go.mod
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
module github.com/caos/oidc/pkg/server
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
replace github.com/caos/oidc => /Users/livio/workspaces/go/src/github.com/caos/oidc
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/caos/oidc v0.0.0-20191119072320-6412f213450c
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef // indirect
|
||||||
|
github.com/gorilla/mux v1.7.3
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
||||||
|
google.golang.org/grpc v1.25.1 // indirect
|
||||||
|
)
|
|
@ -1,16 +1,22 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||||
github.com/caos/utils v0.0.0-20191104132131-b318678afbef h1:/a781PnuLvuTOj0PEJ7ByhgqjpC30Jsk+11uGcuxjjA=
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef h1:/a781PnuLvuTOj0PEJ7ByhgqjpC30Jsk+11uGcuxjjA=
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef/go.mod h1:m66FVMc4qkzUaWkRP1acVnYKagyTr9uGpvhCWvnlJoE=
|
||||||
github.com/caos/utils/config v0.0.0-20191002113340-78986eef31d3/go.mod h1:4iI2a+qaiRFiLV1RAPG5dLp67M+NP2832toQbG9Uu74=
|
github.com/caos/utils/config v0.0.0-20191002113340-78986eef31d3/go.mod h1:4iI2a+qaiRFiLV1RAPG5dLp67M+NP2832toQbG9Uu74=
|
||||||
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef h1:ZkyR2deIvTjvULYw6bInjRR4YNfktQ9F6/z0VijtfmU=
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef h1:ZkyR2deIvTjvULYw6bInjRR4YNfktQ9F6/z0VijtfmU=
|
||||||
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef/go.mod h1:1QHTbh4VS/6qN5fOApyEa70ESW+nDri3XE7j3oIzbyU=
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef/go.mod h1:1QHTbh4VS/6qN5fOApyEa70ESW+nDri3XE7j3oIzbyU=
|
||||||
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3 h1:HYlIp17vhqqUc9YOURRHOX948dSNfGYMo+aC+oaJvb0=
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3 h1:HYlIp17vhqqUc9YOURRHOX948dSNfGYMo+aC+oaJvb0=
|
||||||
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef h1:wpkm8hj2qNBOchILsfjLAqMWS1a4C+/7E4RM/NQ7T2U=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
@ -20,24 +26,30 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||||
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM=
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
@ -48,10 +60,9 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -63,8 +74,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY=
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY=
|
||||||
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
@ -74,19 +86,24 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
|
||||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
|
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
|
||||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||||
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=
|
|
||||||
gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
202
pkg/rp/defaults/default_rp.go
Normal file
202
pkg/rp/defaults/default_rp.go
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc/grants"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
|
grants_tx "github.com/caos/oidc/pkg/oidc/grants/tokenexchange"
|
||||||
|
"github.com/caos/oidc/pkg/rp"
|
||||||
|
"github.com/caos/oidc/pkg/rp/tokenexchange"
|
||||||
|
"github.com/caos/oidc/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
idTokenKey = "id_token"
|
||||||
|
stateParam = "state"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DefaultRP struct {
|
||||||
|
endpoints rp.Endpoints
|
||||||
|
|
||||||
|
oauthConfig oauth2.Config
|
||||||
|
config *rp.Config
|
||||||
|
|
||||||
|
httpClient *http.Client
|
||||||
|
cookieHandler *utils.CookieHandler
|
||||||
|
|
||||||
|
verifier rp.Verifier
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultRelayingParty(rpConfig *rp.Config, rpOpts ...DefaultReplayingPartyOpts) (tokenexchange.DelegationTokenExchangeRP, error) {
|
||||||
|
p := &DefaultRP{
|
||||||
|
config: rpConfig,
|
||||||
|
httpClient: utils.DefaultHTTPClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, optFunc := range rpOpts {
|
||||||
|
optFunc(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.discover(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.verifier == nil {
|
||||||
|
// p.verifier = NewVerifier(rpConfig.Issuer, rpConfig.ClientID, utils.NewRemoteKeySet(p.httpClient, p.endpoints.JKWsURL)) //TODO: keys endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DefaultReplayingPartyOpts func(p *DefaultRP)
|
||||||
|
|
||||||
|
func WithCookieHandler(cookieHandler *utils.CookieHandler) DefaultReplayingPartyOpts {
|
||||||
|
return func(p *DefaultRP) {
|
||||||
|
p.cookieHandler = cookieHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHTTPClient(client *http.Client) DefaultReplayingPartyOpts {
|
||||||
|
return func(p *DefaultRP) {
|
||||||
|
p.httpClient = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) AuthURL(state string) string {
|
||||||
|
return p.oauthConfig.AuthCodeURL(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) AuthURLHandler(state string) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if err := p.trySetStateCookie(w, state); err != nil {
|
||||||
|
http.Error(w, "failed to create state cookie: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, p.AuthURL(state), http.StatusFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) CodeExchange(ctx context.Context, code string) (tokens *oidc.Tokens, err error) {
|
||||||
|
token, err := p.oauthConfig.Exchange(ctx, code)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err //TODO: our error
|
||||||
|
}
|
||||||
|
idTokenString, ok := token.Extra(idTokenKey).(string)
|
||||||
|
if !ok {
|
||||||
|
//TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
idToken, err := p.verifier.Verify(ctx, token.AccessToken, idTokenString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err //TODO: err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oidc.Tokens{Token: token, IDTokenClaims: idToken}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) CodeExchangeHandler(callback func(http.ResponseWriter, *http.Request, *oidc.Tokens, string)) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
state, err := p.tryReadStateCookie(w, r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to get state: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tokens, err := p.CodeExchange(r.Context(), r.URL.Query().Get("code"))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to exchange token: "+err.Error(), http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback(w, r, tokens, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (p *DefaultRP) Introspect(ctx context.Context, accessToken string) (oidc.TokenIntrospectResponse, error) {
|
||||||
|
// // req := &http.Request{}
|
||||||
|
// // resp, err := p.httpClient.Do(req)
|
||||||
|
// // if err != nil {
|
||||||
|
|
||||||
|
// // }
|
||||||
|
// // p.endpoints.IntrospectURL
|
||||||
|
// return nil, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (p *DefaultRP) Userinfo() {}
|
||||||
|
|
||||||
|
func (p *DefaultRP) TokenExchange(ctx context.Context, request *grants_tx.TokenExchangeRequest) (newToken *oauth2.Token, err error) {
|
||||||
|
return p.callTokenEndpoint(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) callTokenEndpoint(request interface{}) (newToken *oauth2.Token, err error) {
|
||||||
|
req, err := utils.FormRequest(p.endpoints.TokenURL, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
auth := base64.StdEncoding.EncodeToString([]byte(p.config.ClientID + ":" + p.config.ClientSecret))
|
||||||
|
req.Header.Set("Authorization", "Basic "+auth)
|
||||||
|
token := new(oauth2.Token)
|
||||||
|
if err := utils.HttpRequest(p.httpClient, req, token); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) ClientCredentials(ctx context.Context, scopes ...string) (newToken *oauth2.Token, err error) {
|
||||||
|
return p.callTokenEndpoint(grants.ClientCredentialsGrantBasic(scopes...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) DelegationTokenExchange(ctx context.Context, subjectToken string, reqOpts ...grants_tx.TokenExchangeOption) (newToken *oauth2.Token, err error) {
|
||||||
|
return p.TokenExchange(ctx, DelegationTokenRequest(subjectToken, reqOpts...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) discover() error {
|
||||||
|
wellKnown := strings.TrimSuffix(p.config.Issuer, "/") + oidc.DiscoveryEndpoint
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", wellKnown, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
discoveryConfig := new(oidc.DiscoveryConfiguration)
|
||||||
|
|
||||||
|
err = utils.HttpRequest(p.httpClient, req, &discoveryConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
p.endpoints = rp.GetEndpoints(discoveryConfig)
|
||||||
|
p.oauthConfig = oauth2.Config{
|
||||||
|
ClientID: p.config.ClientID,
|
||||||
|
ClientSecret: p.config.ClientSecret,
|
||||||
|
Endpoint: p.endpoints.Endpoint,
|
||||||
|
RedirectURL: p.config.CallbackURL,
|
||||||
|
Scopes: p.config.Scopes,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) trySetStateCookie(w http.ResponseWriter, state string) error {
|
||||||
|
if p.cookieHandler != nil {
|
||||||
|
if err := p.cookieHandler.SetQueryCookie(w, stateParam, state); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DefaultRP) tryReadStateCookie(w http.ResponseWriter, r *http.Request) (state string, err error) {
|
||||||
|
if p.cookieHandler == nil {
|
||||||
|
return r.FormValue(stateParam), nil
|
||||||
|
}
|
||||||
|
state, err = p.cookieHandler.CheckQueryCookie(r, stateParam)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
p.cookieHandler.DeleteCookie(w, stateParam)
|
||||||
|
return state, nil
|
||||||
|
}
|
13
pkg/rp/defaults/delegation.go
Normal file
13
pkg/rp/defaults/delegation.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/oidc/pkg/oidc/grants/tokenexchange"
|
||||||
|
)
|
||||||
|
|
||||||
|
//DelegationTokenRequest is an implementation of TokenExchangeRequest
|
||||||
|
//it exchanges a "urn:ietf:params:oauth:token-type:access_token" with an optional
|
||||||
|
//"urn:ietf:params:oauth:token-type:access_token" actor token for a
|
||||||
|
//"urn:ietf:params:oauth:token-type:access_token" delegation token
|
||||||
|
func DelegationTokenRequest(subjectToken string, opts ...tokenexchange.TokenExchangeOption) *tokenexchange.TokenExchangeRequest {
|
||||||
|
return tokenexchange.NewTokenExchangeRequest(subjectToken, tokenexchange.AccessTokenType, opts...)
|
||||||
|
}
|
58
pkg/rp/defaults/error.go
Normal file
58
pkg/rp/defaults/error.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrIssuerInvalid = func(expected, actual string) *validationError {
|
||||||
|
return ValidationError("Issuer does not match. Expected: %s, got: %s", expected, actual)
|
||||||
|
}
|
||||||
|
ErrAudienceMissingClientID = func(clientID string) *validationError {
|
||||||
|
return ValidationError("Audience is not valid. Audience must contain client_id (%s)", clientID)
|
||||||
|
}
|
||||||
|
ErrAzpMissing = func() *validationError {
|
||||||
|
return ValidationError("Authorized Party is not set. If Token is valid for multiple audiences, azp must not be empty")
|
||||||
|
}
|
||||||
|
ErrAzpInvalid = func(azp, clientID string) *validationError {
|
||||||
|
return ValidationError("Authorized Party is not valid. azp (%s) must be equal to client_id (%s)", azp, clientID)
|
||||||
|
}
|
||||||
|
ErrExpInvalid = func(exp time.Time) *validationError {
|
||||||
|
return ValidationError("Token has expired %v", exp)
|
||||||
|
}
|
||||||
|
ErrIatInFuture = func(exp, now time.Time) *validationError {
|
||||||
|
return ValidationError("IssuedAt of token is in the future (%v, now with offset: %v)", exp, now)
|
||||||
|
}
|
||||||
|
ErrIatToOld = func(maxAge, iat time.Time) *validationError {
|
||||||
|
return ValidationError("IssuedAt of token must not be older than %v, but was %v (%v to old)", maxAge, iat, maxAge.Sub(iat))
|
||||||
|
}
|
||||||
|
ErrNonceInvalid = func(expected, actual string) *validationError {
|
||||||
|
return ValidationError("nonce does not match. Expected: %s, got: %s", expected, actual)
|
||||||
|
}
|
||||||
|
ErrAcrInvalid = func(expected []string, actual string) *validationError {
|
||||||
|
return ValidationError("acr is invalid. Expected one of: %v, got: %s", expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrAuthTimeNotPresent = func() *validationError {
|
||||||
|
return ValidationError("claim `auth_time` of token is missing")
|
||||||
|
}
|
||||||
|
ErrAuthTimeToOld = func(maxAge, authTime time.Time) *validationError {
|
||||||
|
return ValidationError("Auth Time of token must not be older than %v, but was %v (%v to old)", maxAge, authTime, maxAge.Sub(authTime))
|
||||||
|
}
|
||||||
|
ErrSignatureInvalidPayload = func() *validationError {
|
||||||
|
return ValidationError("Signature does not match Payload")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidationError(message string, args ...interface{}) *validationError {
|
||||||
|
return &validationError{fmt.Sprintf(message, args...)} //TODO: impl
|
||||||
|
}
|
||||||
|
|
||||||
|
type validationError struct {
|
||||||
|
message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *validationError) Error() string {
|
||||||
|
return v.message
|
||||||
|
}
|
456
pkg/rp/defaults/verifier.go
Normal file
456
pkg/rp/defaults/verifier.go
Normal file
|
@ -0,0 +1,456 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gopkg.in/square/go-jose.v2"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
|
"github.com/caos/oidc/pkg/rp"
|
||||||
|
str_utils "github.com/caos/utils/strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewVerifier(issuer, clientID string, keySet oidc.KeySet, confOpts ...ConfFunc) rp.Verifier {
|
||||||
|
conf := &verifierConfig{
|
||||||
|
issuer: issuer,
|
||||||
|
clientID: clientID,
|
||||||
|
iat: &iatConfig{
|
||||||
|
// offset: time.Duration(500 * time.Millisecond),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range confOpts {
|
||||||
|
if opt != nil {
|
||||||
|
opt(conf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &Verifier{config: conf, keySet: keySet}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Verifier struct {
|
||||||
|
config *verifierConfig
|
||||||
|
keySet oidc.KeySet
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfFunc func(*verifierConfig)
|
||||||
|
|
||||||
|
func WithIgnoreIssuedAt() func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.iat.ignore = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithIssuedAtOffset(offset time.Duration) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.iat.offset = offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithIssuedAtMaxAge(maxAge time.Duration) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.iat.maxAge = maxAge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithNonce(nonce string) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.nonce = nonce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithACRVerifier(verifier ACRVerifier) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.acr = verifier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAuthTimeMaxAge(maxAge time.Duration) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.maxAge = maxAge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSupportedSigningAlgorithms(algs ...string) func(*verifierConfig) {
|
||||||
|
return func(conf *verifierConfig) {
|
||||||
|
conf.supportedSignAlgs = algs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func WithVerifierHTTPClient(client *http.Client) func(*verifierConfig) {
|
||||||
|
// return func(conf *verifierConfig) {
|
||||||
|
// conf.httpClient = client
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
type verifierConfig struct {
|
||||||
|
issuer string
|
||||||
|
clientID string
|
||||||
|
nonce string
|
||||||
|
iat *iatConfig
|
||||||
|
acr ACRVerifier
|
||||||
|
maxAge time.Duration
|
||||||
|
supportedSignAlgs []string
|
||||||
|
|
||||||
|
// httpClient *http.Client
|
||||||
|
|
||||||
|
now time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type iatConfig struct {
|
||||||
|
ignore bool
|
||||||
|
offset time.Duration
|
||||||
|
maxAge time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type ACRVerifier func(string) error
|
||||||
|
|
||||||
|
func DefaultACRVerifier(possibleValues []string) func(string) error {
|
||||||
|
return func(acr string) error {
|
||||||
|
if !str_utils.Contains(possibleValues, acr) {
|
||||||
|
return ErrAcrInvalid(possibleValues, acr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) Verify(ctx context.Context, accessToken, idTokenString string) (*oidc.IDTokenClaims, error) {
|
||||||
|
v.config.now = time.Now().UTC()
|
||||||
|
idToken, err := v.VerifyIDToken(ctx, idTokenString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := v.verifyAccessToken(accessToken, idToken.AccessTokenHash, idToken.Signature); err != nil { //TODO: sig from token
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return idToken, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) now() time.Time {
|
||||||
|
if v.config.now.IsZero() {
|
||||||
|
v.config.now = time.Now().UTC().Round(time.Second)
|
||||||
|
}
|
||||||
|
return v.config.now
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) VerifyIDToken(ctx context.Context, idTokenString string) (*oidc.IDTokenClaims, error) {
|
||||||
|
//1. if encrypted --> decrypt
|
||||||
|
decrypted, err := v.decryptToken(idTokenString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
claims, payload, err := v.parseToken(decrypted)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// token, err := jwt.ParseWithClaims(decrypted, claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
//2, check issuer (exact match)
|
||||||
|
if err := v.checkIssuer(claims.Issuer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//3. check aud (aud must contain client_id, all aud strings must be allowed)
|
||||||
|
if err = v.checkAudience(claims.Audiences); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = v.checkAuthorizedParty(claims.Audiences, claims.AuthorizedParty); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//6. check signature by keys
|
||||||
|
//7. check alg default is rs256
|
||||||
|
//8. check if alg is mac based (hs...) -> audience contains client_id. for validation use utf-8 representation of your client_secret
|
||||||
|
claims.Signature, err = v.checkSignature(ctx, decrypted, payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//9. check exp before now
|
||||||
|
if err = v.checkExpiration(claims.Expiration); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//10. check iat duration is optional (can be checked)
|
||||||
|
if err = v.checkIssuedAt(claims.IssuedAt); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//11. check nonce (check if optional possible) id_token.nonce == sentNonce
|
||||||
|
if err = v.checkNonce(claims.Nonce); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//12. if acr requested check acr
|
||||||
|
if err = v.checkAuthorizationContextClassReference(claims.AuthenticationContextClassReference); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//13. if auth_time requested check if auth_time is less than max age
|
||||||
|
if err = v.checkAuthTime(claims.AuthTime); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//return idtoken struct, err
|
||||||
|
|
||||||
|
return claims, nil
|
||||||
|
// })
|
||||||
|
// _ = token
|
||||||
|
// return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) parseToken(tokenString string) (*oidc.IDTokenClaims, []byte, error) {
|
||||||
|
parts := strings.Split(tokenString, ".")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
return nil, nil, ValidationError("token contains an invalid number of segments") //TODO: err NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed)
|
||||||
|
}
|
||||||
|
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("oidc: malformed jwt payload: %v", err)
|
||||||
|
}
|
||||||
|
idToken := new(oidc.IDTokenClaims)
|
||||||
|
err = json.Unmarshal(payload, idToken)
|
||||||
|
return idToken, payload, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) checkIssuer(issuer string) error {
|
||||||
|
if v.config.issuer != issuer {
|
||||||
|
return ErrIssuerInvalid(v.config.issuer, issuer)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) checkAudience(audiences []string) error {
|
||||||
|
if !str_utils.Contains(audiences, v.config.clientID) {
|
||||||
|
return ErrAudienceMissingClientID(v.config.clientID)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: check aud trusted
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//4. if multiple aud strings --> check if azp
|
||||||
|
//5. if azp --> check azp == client_id
|
||||||
|
func (v *Verifier) checkAuthorizedParty(audiences []string, authorizedParty string) error {
|
||||||
|
if len(audiences) > 1 {
|
||||||
|
if authorizedParty == "" {
|
||||||
|
return ErrAzpMissing()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if authorizedParty != "" && authorizedParty != v.config.clientID {
|
||||||
|
return ErrAzpInvalid(authorizedParty, v.config.clientID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) checkSignature(ctx context.Context, idTokenString string, payload []byte) (jose.SignatureAlgorithm, error) {
|
||||||
|
jws, err := jose.ParseSigned(idTokenString)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(jws.Signatures) == 0 {
|
||||||
|
return "", nil //TODO: error
|
||||||
|
}
|
||||||
|
if len(jws.Signatures) > 1 {
|
||||||
|
return "", nil //TODO: error
|
||||||
|
}
|
||||||
|
sig := jws.Signatures[0]
|
||||||
|
supportedSigAlgs := v.config.supportedSignAlgs
|
||||||
|
if len(supportedSigAlgs) == 0 {
|
||||||
|
supportedSigAlgs = []string{"RS256"}
|
||||||
|
}
|
||||||
|
if !str_utils.Contains(supportedSigAlgs, sig.Header.Algorithm) {
|
||||||
|
return "", fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
|
||||||
|
}
|
||||||
|
|
||||||
|
signedPayload, err := v.keySet.VerifySignature(ctx, jws)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
//TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(signedPayload, payload) {
|
||||||
|
return "", ErrSignatureInvalidPayload() //TODO: err
|
||||||
|
}
|
||||||
|
return jose.SignatureAlgorithm(sig.Header.Algorithm), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// type KeySet struct {
|
||||||
|
// remoteURL url.URL
|
||||||
|
// httpClient *http.Client
|
||||||
|
// keys []jose.JSONWebKey
|
||||||
|
|
||||||
|
// m sync.Mutex
|
||||||
|
// inflight *inflight
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (k *KeySet) GetKey(ctx context.Context, keyID string) (*jose.JSONWebKey, error) {
|
||||||
|
// key, err := k.getKey(keyID)
|
||||||
|
// if err != nil {
|
||||||
|
// //lock
|
||||||
|
// k.updateKeys(ctx)
|
||||||
|
// //unlock
|
||||||
|
// return k.getKey(keyID)
|
||||||
|
// }
|
||||||
|
// return key, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (k *KeySet) getKey(keyID string) (*jose.JSONWebKey, error) {
|
||||||
|
// k.m.Lock()
|
||||||
|
// keys := k.keys
|
||||||
|
// k.m.Unlock()
|
||||||
|
// for _, key := range keys {
|
||||||
|
// if key.KeyID == keyID {
|
||||||
|
// return &key, nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return nil, nil //TODO: err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (k *KeySet) retrieveNewKeys(ctx context.Context) ([]jose.JSONWebKey, error) {
|
||||||
|
// resp, err := k.httpClient.Get(k.remoteURL.String())
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// if resp.StatusCode != http.StatusOK {
|
||||||
|
// return nil, nil //TODO: errs
|
||||||
|
// }
|
||||||
|
|
||||||
|
// defer resp.Body.Close()
|
||||||
|
// body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var keySet jose.JSONWebKeySet
|
||||||
|
// err = json.Unmarshal(body, keySet)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return keySet.Keys, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (k *KeySet) updateKeys(ctx context.Context) error {
|
||||||
|
// k.inflight
|
||||||
|
// k.m.Lock()
|
||||||
|
// k.keys = keySet.Keys
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (v *Verifier) checkExpiration(expiration time.Time) error {
|
||||||
|
expiration = expiration.Round(time.Second)
|
||||||
|
if !v.now().Before(expiration) {
|
||||||
|
return ErrExpInvalid(expiration)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) checkIssuedAt(issuedAt time.Time) error {
|
||||||
|
if v.config.iat.ignore {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
issuedAt = issuedAt.Round(time.Second)
|
||||||
|
offset := v.now().Add(v.config.iat.offset).Round(time.Second)
|
||||||
|
if issuedAt.After(offset) {
|
||||||
|
return ErrIatInFuture(issuedAt, offset)
|
||||||
|
}
|
||||||
|
if v.config.iat.maxAge == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
maxAge := v.now().Add(-v.config.iat.maxAge).Round(time.Second)
|
||||||
|
if issuedAt.Before(maxAge) {
|
||||||
|
return ErrIatToOld(maxAge, issuedAt)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (v *Verifier) checkNonce(nonce string) error {
|
||||||
|
if v.config.nonce == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if v.config.nonce != nonce {
|
||||||
|
return ErrNonceInvalid(v.config.nonce, nonce)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (v *Verifier) checkAuthorizationContextClassReference(acr string) error {
|
||||||
|
if v.config.acr != nil {
|
||||||
|
return v.config.acr(acr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (v *Verifier) checkAuthTime(authTime time.Time) error {
|
||||||
|
if v.config.maxAge == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if authTime.IsZero() {
|
||||||
|
return ErrAuthTimeNotPresent()
|
||||||
|
}
|
||||||
|
authTime = authTime.Round(time.Second)
|
||||||
|
maxAge := v.now().Add(-v.config.maxAge).Round(time.Second)
|
||||||
|
if authTime.Before(maxAge) {
|
||||||
|
return ErrAuthTimeToOld(maxAge, authTime)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Verifier) decryptToken(tokenString string) (string, error) {
|
||||||
|
return tokenString, nil //TODO: impl
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (v *Verifier) parseIDToken(tokenString string) (IDToken, error) {
|
||||||
|
// var claims jwt.StandardClaims
|
||||||
|
// token, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// claims.VerifyIssuer(v.config.Issuer, true)
|
||||||
|
|
||||||
|
// // return token.Header["alg"]
|
||||||
|
// })
|
||||||
|
|
||||||
|
// payload, err := parseJWT(rawIDToken)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
|
||||||
|
// }
|
||||||
|
// var token IDToken
|
||||||
|
// if err := json.Unmarshal(payload, &token); err != nil {
|
||||||
|
// return nil, fmt.Errorf("oidc: failed to unmarshal claims: %v", err)
|
||||||
|
// }
|
||||||
|
// return token, nil //TODO: impl
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (v *Verifier) verifyAccessToken(accessToken, atHash string, sigAlgorithm jose.SignatureAlgorithm) error {
|
||||||
|
if atHash == "" {
|
||||||
|
return nil //TODO: return error
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenHash, err := getHashAlgorithm(sigAlgorithm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenHash.Write([]byte(accessToken)) // hash documents that Write will never return an error
|
||||||
|
sum := tokenHash.Sum(nil)[:tokenHash.Size()/2]
|
||||||
|
actual := base64.RawURLEncoding.EncodeToString(sum)
|
||||||
|
if actual != atHash {
|
||||||
|
return nil //TODO: error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHashAlgorithm(sigAlgorithm jose.SignatureAlgorithm) (hash.Hash, error) {
|
||||||
|
switch sigAlgorithm {
|
||||||
|
case jose.RS256, jose.ES256, jose.PS256:
|
||||||
|
return sha256.New(), nil
|
||||||
|
case jose.RS384, jose.ES384, jose.PS384:
|
||||||
|
return sha512.New384(), nil
|
||||||
|
case jose.RS512, jose.ES512, jose.PS512:
|
||||||
|
return sha512.New(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("oidc: unsupported signing algorithm %q", sigAlgorithm)
|
||||||
|
}
|
||||||
|
}
|
18
pkg/rp/go.mod
Normal file
18
pkg/rp/go.mod
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
module github.com/caos/oidc/pkg/client
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/caos/oidc/pkg/oidc v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/oidc/pkg/rp v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/oidc/pkg/utils v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/oidc => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/oidc
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/rp => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/rp
|
||||||
|
|
||||||
|
replace github.com/caos/oidc/pkg/utils => /Users/livio/workspaces/go/src/github.com/caos/oidc/pkg/utils
|
117
pkg/rp/go.sum
Normal file
117
pkg/rp/go.sum
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef h1:/a781PnuLvuTOj0PEJ7ByhgqjpC30Jsk+11uGcuxjjA=
|
||||||
|
github.com/caos/utils v0.0.0-20191104132131-b318678afbef/go.mod h1:m66FVMc4qkzUaWkRP1acVnYKagyTr9uGpvhCWvnlJoE=
|
||||||
|
github.com/caos/utils/config v0.0.0-20191002113340-78986eef31d3/go.mod h1:4iI2a+qaiRFiLV1RAPG5dLp67M+NP2832toQbG9Uu74=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef h1:ZkyR2deIvTjvULYw6bInjRR4YNfktQ9F6/z0VijtfmU=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef/go.mod h1:1QHTbh4VS/6qN5fOApyEa70ESW+nDri3XE7j3oIzbyU=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef h1:wpkm8hj2qNBOchILsfjLAqMWS1a4C+/7E4RM/NQ7T2U=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||||
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
|
||||||
|
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
|
||||||
|
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||||
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||||
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=
|
||||||
|
gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
84
pkg/rp/relaying_party.go
Normal file
84
pkg/rp/relaying_party.go
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package rp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
//RelayingParty declares the minimal interface for oidc clients
|
||||||
|
type RelayingParty interface {
|
||||||
|
|
||||||
|
//AuthURL returns the authorization endpoint with a given state
|
||||||
|
AuthURL(state string) string
|
||||||
|
|
||||||
|
//AuthURLHandler should implement the AuthURL func as http.HandlerFunc
|
||||||
|
//(redirecting to the auth endpoint)
|
||||||
|
AuthURLHandler(state string) http.HandlerFunc
|
||||||
|
|
||||||
|
//CodeExchange implements the OIDC Token Request (oauth2 Authorization Code Grant)
|
||||||
|
//returning an `Access Token` and `ID Token Claims`
|
||||||
|
CodeExchange(ctx context.Context, code string) (*oidc.Tokens, error)
|
||||||
|
|
||||||
|
//CodeExchangeHandler extends the CodeExchange func,
|
||||||
|
//calling the provided callback func on success with additional returned `state`
|
||||||
|
CodeExchangeHandler(callback func(http.ResponseWriter, *http.Request, *oidc.Tokens, string)) http.HandlerFunc
|
||||||
|
|
||||||
|
//ClientCredentials implements the oauth2 Client Credentials Grant
|
||||||
|
//requesting an `Access Token` for the client itself, without user context
|
||||||
|
ClientCredentials(ctx context.Context, scopes ...string) (*oauth2.Token, error)
|
||||||
|
|
||||||
|
//Introspects calls the Introspect Endpoint
|
||||||
|
//for validating an (access) token
|
||||||
|
// Introspect(ctx context.Context, token string) (TokenIntrospectResponse, error)
|
||||||
|
|
||||||
|
//Userinfo implements the OIDC Userinfo call
|
||||||
|
//returning the info of the user for the requested scopes of an access token
|
||||||
|
Userinfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
//PasswortGrantRP extends the `RelayingParty` interface with the oauth2 `Password Grant`
|
||||||
|
//
|
||||||
|
//This interface is separated from the standard `RelayingParty` interface as the `password grant`
|
||||||
|
//is part of the oauth2 and therefore OIDC specification, but should only be used when there's no
|
||||||
|
//other possibility, so IMHO never ever. Ever.
|
||||||
|
type PasswortGrantRP interface {
|
||||||
|
RelayingParty
|
||||||
|
|
||||||
|
//PasswordGrant implements the oauth2 `Password Grant`,
|
||||||
|
//requesting an access token with the users `username` and `password`
|
||||||
|
PasswordGrant(context.Context, string, string) (*oauth2.Token, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ClientID string
|
||||||
|
ClientSecret string
|
||||||
|
CallbackURL string
|
||||||
|
Issuer string
|
||||||
|
Scopes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionFunc func(RelayingParty)
|
||||||
|
|
||||||
|
type Endpoints struct {
|
||||||
|
oauth2.Endpoint
|
||||||
|
IntrospectURL string
|
||||||
|
UserinfoURL string
|
||||||
|
JKWsURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEndpoints(discoveryConfig *oidc.DiscoveryConfiguration) Endpoints {
|
||||||
|
return Endpoints{
|
||||||
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: discoveryConfig.AuthorizationEndpoint,
|
||||||
|
AuthStyle: oauth2.AuthStyleAutoDetect,
|
||||||
|
TokenURL: discoveryConfig.TokenEndpoint,
|
||||||
|
},
|
||||||
|
IntrospectURL: discoveryConfig.IntrospectionEndpoint,
|
||||||
|
UserinfoURL: discoveryConfig.UserinfoEndpoint,
|
||||||
|
JKWsURL: discoveryConfig.JwksURI,
|
||||||
|
}
|
||||||
|
}
|
28
pkg/rp/tokenexchange/relaying_party.go
Normal file
28
pkg/rp/tokenexchange/relaying_party.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package tokenexchange
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc/grants/tokenexchange"
|
||||||
|
"github.com/caos/oidc/pkg/rp"
|
||||||
|
)
|
||||||
|
|
||||||
|
//TokenExchangeRP extends the `RelayingParty` interface for the *draft* oauth2 `Token Exchange`
|
||||||
|
type TokenExchangeRP interface {
|
||||||
|
rp.RelayingParty
|
||||||
|
|
||||||
|
//TokenExchange implement the `Token Echange Grant` exchanging some token for an other
|
||||||
|
TokenExchange(context.Context, *tokenexchange.TokenExchangeRequest) (*oauth2.Token, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//DelegationTokenExchangeRP extends the `TokenExchangeRP` interface
|
||||||
|
//for the specific `delegation token` request
|
||||||
|
type DelegationTokenExchangeRP interface {
|
||||||
|
TokenExchangeRP
|
||||||
|
|
||||||
|
//DelegationTokenExchange implement the `Token Exchange Grant`
|
||||||
|
//providing an access token in request for a `delegation` token for a given resource / audience
|
||||||
|
DelegationTokenExchange(context.Context, string, ...tokenexchange.TokenExchangeOption) (*oauth2.Token, error)
|
||||||
|
}
|
15
pkg/rp/verifier.go
Normal file
15
pkg/rp/verifier.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package rp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/oidc/pkg/oidc"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Verifier implement the Token Response Validation as defined in OIDC specification
|
||||||
|
//https://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation
|
||||||
|
type Verifier interface {
|
||||||
|
|
||||||
|
//Verify checks the access_token and id_token and returns the `id token claims`
|
||||||
|
Verify(ctx context.Context, accessToken, idTokenString string) (*oidc.IDTokenClaims, error)
|
||||||
|
}
|
102
pkg/utils/cookie.go
Normal file
102
pkg/utils/cookie.go
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/securecookie"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CookieHandler struct {
|
||||||
|
securecookie *securecookie.SecureCookie
|
||||||
|
secureOnly bool
|
||||||
|
sameSite http.SameSite
|
||||||
|
maxAge int
|
||||||
|
domain string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCookieHandler(hashKey, encryptKey []byte, opts ...CookieHandlerOpt) *CookieHandler {
|
||||||
|
c := &CookieHandler{
|
||||||
|
securecookie: securecookie.New(hashKey, encryptKey),
|
||||||
|
secureOnly: true,
|
||||||
|
sameSite: http.SameSiteNoneMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(c)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type CookieHandlerOpt func(*CookieHandler)
|
||||||
|
|
||||||
|
func WithUnsecure() CookieHandlerOpt {
|
||||||
|
return func(c *CookieHandler) {
|
||||||
|
c.secureOnly = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSameSite(sameSite http.SameSite) CookieHandlerOpt {
|
||||||
|
return func(c *CookieHandler) {
|
||||||
|
c.sameSite = sameSite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithMaxAge(maxAge int) CookieHandlerOpt {
|
||||||
|
return func(c *CookieHandler) {
|
||||||
|
c.maxAge = maxAge
|
||||||
|
c.securecookie.MaxAge(maxAge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithDomain(domain string) CookieHandlerOpt {
|
||||||
|
return func(c *CookieHandler) {
|
||||||
|
c.domain = domain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CookieHandler) CheckQueryCookie(r *http.Request, name string) (string, error) {
|
||||||
|
cookie, err := r.Cookie(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var value string
|
||||||
|
if err := c.securecookie.Decode(name, cookie.Value, &value); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if value != r.FormValue(name) {
|
||||||
|
return "", errors.New(name + " does not compare")
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CookieHandler) SetQueryCookie(w http.ResponseWriter, name, value string) error {
|
||||||
|
encoded, err := c.securecookie.Encode(name, value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: name,
|
||||||
|
Value: encoded,
|
||||||
|
Domain: c.domain,
|
||||||
|
Path: "/",
|
||||||
|
MaxAge: c.maxAge,
|
||||||
|
HttpOnly: true,
|
||||||
|
Secure: c.secureOnly,
|
||||||
|
SameSite: c.sameSite,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CookieHandler) DeleteCookie(w http.ResponseWriter, name string) {
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: name,
|
||||||
|
Value: "",
|
||||||
|
Domain: c.domain,
|
||||||
|
Path: "/",
|
||||||
|
MaxAge: -1,
|
||||||
|
HttpOnly: true,
|
||||||
|
Secure: c.secureOnly,
|
||||||
|
SameSite: c.sameSite,
|
||||||
|
})
|
||||||
|
}
|
14
pkg/utils/go.mod
Normal file
14
pkg/utils/go.mod
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module github.com/caos/oidc/pkg/utils
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef // indirect
|
||||||
|
github.com/gorilla/schema v1.1.0
|
||||||
|
github.com/gorilla/securecookie v1.1.1
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
||||||
|
google.golang.org/grpc v1.25.1 // indirect
|
||||||
|
)
|
108
pkg/utils/go.sum
Normal file
108
pkg/utils/go.sum
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||||
|
github.com/caos/utils/config v0.0.0-20191002113340-78986eef31d3/go.mod h1:4iI2a+qaiRFiLV1RAPG5dLp67M+NP2832toQbG9Uu74=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef h1:ZkyR2deIvTjvULYw6bInjRR4YNfktQ9F6/z0VijtfmU=
|
||||||
|
github.com/caos/utils/logging v0.0.0-20191104132131-b318678afbef/go.mod h1:1QHTbh4VS/6qN5fOApyEa70ESW+nDri3XE7j3oIzbyU=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3 h1:HYlIp17vhqqUc9YOURRHOX948dSNfGYMo+aC+oaJvb0=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191002113340-78986eef31d3/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef h1:wpkm8hj2qNBOchILsfjLAqMWS1a4C+/7E4RM/NQ7T2U=
|
||||||
|
github.com/caos/utils/pairs v0.0.0-20191104132131-b318678afbef/go.mod h1:UZHeoVF6vhET4wTA/alcu0KOy65P2WI3AFlMvThGDcE=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||||
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3 h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.11.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
|
||||||
|
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY=
|
||||||
|
golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
|
||||||
|
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
|
||||||
|
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk=
|
||||||
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
|
||||||
|
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||||
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
57
pkg/utils/http.go
Normal file
57
pkg/utils/http.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultHTTPClient = &http.Client{
|
||||||
|
Timeout: time.Duration(30 * time.Second),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func FormRequest(endpoint string, request interface{}) (*http.Request, error) {
|
||||||
|
form := make(map[string][]string)
|
||||||
|
encoder := schema.NewEncoder()
|
||||||
|
if err := encoder.Encode(request, form); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body := strings.NewReader(url.Values(form).Encode())
|
||||||
|
req, err := http.NewRequest("POST", endpoint, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func HttpRequest(client *http.Client, req *http.Request, response interface{}) error {
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read response body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("http status not ok: %s %s", resp.Status, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, response)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal response: %v %s", err, body)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue