diff --git a/Gopkg.lock b/Gopkg.lock index 5bd387a..a2657da 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -10,12 +10,12 @@ revision = "065b426bd41667456c1a924468f507673629c46b" [[projects]] - digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b" - name = "github.com/davecgh/go-spew" - packages = ["spew"] + digest = "1:0c07a9cb3d3c845439a4fcaae6c8bdd0e7727cbbd3acf1e032e5d4a2dc132306" + name = "github.com/gbrlsnchs/jwt" + packages = ["."] pruneopts = "" - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" + revision = "808efa0714baff8c25cc65ef8681966740beb9f9" + version = "v2.0.0" [[projects]] digest = "1:bcb38c8fc9b21bb8682ce2d605a7d4aeb618abc7f827e3ac0b27c0371fdb23fb" @@ -33,14 +33,6 @@ revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" -[[projects]] - digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - [[projects]] branch = "master" digest = "1:386e12afcfd8964907c92dffd106860c0dedd71dbefae14397b77b724a13343b" @@ -60,17 +52,6 @@ revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" version = "v1.0.0" -[[projects]] - digest = "1:a30066593578732a356dc7e5d7f78d69184ca65aeeff5939241a3ab10559bb06" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - ] - pruneopts = "" - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" - [[projects]] branch = "master" digest = "1:2ea6df0f542cc95a5e374e9cdd81eaa599ed0d55366eef92d2f6b9efa2795c07" @@ -185,11 +166,9 @@ analyzer-version = 1 input-imports = [ "github.com/coreos/go-oidc", - "github.com/davecgh/go-spew/spew", + "github.com/gbrlsnchs/jwt", "github.com/pkg/errors", "github.com/spf13/pflag", - "github.com/stretchr/testify/assert", - "github.com/stretchr/testify/require", "gopkg.in/h2non/gentleman.v2", "gopkg.in/h2non/gentleman.v2/plugin", "gopkg.in/h2non/gentleman.v2/plugins/body", diff --git a/Gopkg.toml b/Gopkg.toml index 4c9711f..7aa9efa 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -32,3 +32,8 @@ [[constraint]] name = "gopkg.in/h2non/gentleman.v2" version = "2.0.0" + + +[[constraint]] + name = "github.com/gbrlsnchs/jwt" + version = "2.0.0" diff --git a/keycloak_client.go b/keycloak_client.go index 1a40f37..4bee7dc 100644 --- a/keycloak_client.go +++ b/keycloak_client.go @@ -13,6 +13,8 @@ import ( "gopkg.in/h2non/gentleman.v2/plugin" "gopkg.in/h2non/gentleman.v2/plugins/query" "gopkg.in/h2non/gentleman.v2/plugins/timeout" + + jwt "github.com/gbrlsnchs/jwt" ) // Config is the keycloak client http config. @@ -129,9 +131,14 @@ func (c *Client) VerifyToken(realmName string, accessToken string) error { // get is a HTTP get method. func (c *Client) get(accessToken string, data interface{}, plugins ...plugin.Plugin) error { + var err error var req = c.httpClient.Get() + req = applyPlugins(req, plugins...) + req, err = setAuthorisationAndHostHeaders(req, accessToken) - req = applyPlugins(req, accessToken, plugins...) + if err != nil { + return err + } var resp *gentleman.Response { @@ -163,8 +170,15 @@ func (c *Client) get(accessToken string, data interface{}, plugins ...plugin.Plu } func (c *Client) post(accessToken string, data interface{}, plugins ...plugin.Plugin) (string, error) { + var err error var req = c.httpClient.Post() - req = applyPlugins(req, accessToken, plugins...) + req = applyPlugins(req, plugins...) + req, err = setAuthorisationAndHostHeaders(req, accessToken) + + if err != nil { + return "", err + } + var resp *gentleman.Response { var err error @@ -197,8 +211,14 @@ func (c *Client) post(accessToken string, data interface{}, plugins ...plugin.Pl } func (c *Client) delete(accessToken string, plugins ...plugin.Plugin) error { + var err error var req = c.httpClient.Delete() - req = applyPlugins(req, accessToken, plugins...) + req = applyPlugins(req, plugins...) + req, err = setAuthorisationAndHostHeaders(req, accessToken) + + if err != nil { + return err + } var resp *gentleman.Response { @@ -222,8 +242,14 @@ func (c *Client) delete(accessToken string, plugins ...plugin.Plugin) error { } func (c *Client) put(accessToken string, plugins ...plugin.Plugin) error { + var err error var req = c.httpClient.Put() - req = applyPlugins(req, accessToken, plugins...) + req = applyPlugins(req, plugins...) + req, err = setAuthorisationAndHostHeaders(req, accessToken) + + if err != nil { + return err + } var resp *gentleman.Response { @@ -246,15 +272,61 @@ func (c *Client) put(accessToken string, plugins ...plugin.Plugin) error { } } -// applyPlugins apply all the plugins to the request req. -func applyPlugins(req *gentleman.Request, accessToken string, plugins ...plugin.Plugin) *gentleman.Request { +func setAuthorisationAndHostHeaders(req *gentleman.Request, accessToken string) (*gentleman.Request, error) { + host, err := extractHostFromToken(accessToken) + + if err != nil { + return req, err + } + var r = req.SetHeader("Authorization", fmt.Sprintf("Bearer %s", accessToken)) + return r.SetHeader("Host", host), nil +} + +// applyPlugins apply all the plugins to the request req. +func applyPlugins(req *gentleman.Request, plugins ...plugin.Plugin) *gentleman.Request { + var r = req for _, p := range plugins { r = r.Use(p) } return r } +func extractHostFromToken(token string) (string, error) { + issuer, err := extractIssuerFromToken(token) + + if err != nil { + return "", err + } + + var u *url.URL + { + var err error + u, err = url.Parse(issuer) + if err != nil { + return "", errors.Wrap(err, "could not parse Token issuer URL") + } + } + + return u.Host, nil +} + +func extractIssuerFromToken(token string) (string, error) { + payload, _, err := jwt.Parse(token) + + if err != nil { + return "", fmt.Errorf("Error while parsing token") + } + + var jot jwt.JWT + + if err = jwt.Unmarshal(payload, &jot); err != nil { + return "", fmt.Errorf("Error while unmarshalling token") + } + + return jot.Issuer, nil +} + // createQueryPlugins create query parameters with the key values paramKV. func createQueryPlugins(paramKV ...string) []plugin.Plugin { var plugins = []plugin.Plugin{}