From 3fb249f1706c4f08366772897457745f1b20753e Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 22:29:52 +0100 Subject: [PATCH 01/16] wrap errors in jwx.go --- go.mod | 4 ++- go.sum | 13 ++++++++ golangci.yml | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ pkg/jwx/jwx.go | 37 ++++++++++++++++----- 4 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 golangci.yml diff --git a/go.mod b/go.mod index 76974eca..1a45827f 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,11 @@ module github.com/Nerzal/gocloak/v3 require ( + github.com/Nerzal/gocloak/v4 v4.8.0 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/go-resty/resty/v2 v2.0.0 - github.com/stretchr/testify v1.3.0 + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.4.0 ) go 1.13 diff --git a/go.sum b/go.sum index 030b81b6..3d49443b 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,30 @@ +github.com/Nerzal/gocloak v1.0.0 h1:WllsbIu1dYvdvka1/BbY7khZBJSTjSkGwyDsHHLQmIw= +github.com/Nerzal/gocloak/v4 v4.8.0 h1:Ts932I0mbrkvoUxo4U0XmfqiNsbzraq+ZMoKV0KDT64= +github.com/Nerzal/gocloak/v4 v4.8.0/go.mod h1:/7LwujSlsqBA3haXobPxOPVZMP9iQ9zlQJAbP0ZhO4I= 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/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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/go-resty/resty/v2 v2.0.0 h1:9Nq/U+V4xsoDnDa/iTrABDWUCuk3Ne92XFHPe6dKWUc= github.com/go-resty/resty/v2 v2.0.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +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/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/golangci.yml b/golangci.yml new file mode 100644 index 00000000..a6a2275e --- /dev/null +++ b/golangci.yml @@ -0,0 +1,90 @@ +linters-settings: + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + golint: + min-confidence: 0 + gocyclo: + min-complexity: 10 + maligned: + suggest-new: true + dupl: + threshold: 100 + goconst: + min-len: 3 + min-occurrences: 3 + depguard: + list-type: blacklist + packages: + # logging is allowed only by logutils.Log, logrus + # is allowed to use only in logutils package + - github.com/sirupsen/logrus + misspell: + locale: US + lll: + line-length: 170 + goimports: + local-prefixes: github.com/golangci/golangci-lint + prealloc: + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + nakedret: + # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + max-func-lines: 30 + gocritic: + enabled-tags: + - performance + - style + - experimental + disabled-checks: + - wrapperFunc + errcheck: + # report about not checking of errors in type assertions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + wsl: + # If true append is only allowed to be cuddled if appending value is + # matching variables, fields or types on line above. Default is true. + strict-append: true + # Allow calls and assignments to be cuddled as long as the lines have any + # matching variables, fields or types. Default is true. + allow-assign-and-call: true + # Allow multiline assignments to be cuddled. Default is true. + allow-multiline-assign: true + # Allow declarations (var) to be cuddled. + allow-cuddle-declarations: true + # Allow trailing comments in ending of blocks + allow-trailing-comment: false + # Force newlines in end of case at this limit (0 = never). + force-case-trailing-whitespace: 0 +linters: + enable-all: true + +run: + skip-dirs: + - test/testdata_etc + - pkg/golinters/goanalysis/(checker|passes) + - docs + - coverage + - test + - configs + - cmd + tests: false +issues: + exclude-rules: + - text: "weak cryptographic primitive" + linters: + - gosec +# golangci.com configuration +# https://github.com/golangci/golangci/wiki/Configuration +service: + golangci-lint-version: 1.23.x # use the fixed version to not introduce new linters unexpectedly + prepare: +#- echo "here I can run custom commands, but no preparation needed for this repo" \ No newline at end of file diff --git a/pkg/jwx/jwx.go b/pkg/jwx/jwx.go index 59396db2..2ca5be24 100644 --- a/pkg/jwx/jwx.go +++ b/pkg/jwx/jwx.go @@ -11,38 +11,44 @@ import ( "strings" jwt "github.com/dgrijalva/jwt-go" + "github.com/pkg/errors" ) // DecodeAccessTokenHeader decodes the header of the accessToken func DecodeAccessTokenHeader(token string) (*DecodedAccessTokenHeader, error) { + const errMessage = "could not decode access token header" token = strings.Replace(token, "Bearer ", "", 1) headerString := strings.Split(token, ".") decodedData, err := base64.RawStdEncoding.DecodeString(headerString[0]) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } result := &DecodedAccessTokenHeader{} err = json.Unmarshal(decodedData, result) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } return result, nil } func decodePublicKey(e, n *string) (*rsa.PublicKey, error) { + const errMessage = "could not decode public key" + decN, err := base64.RawURLEncoding.DecodeString(*n) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } + nInt := big.NewInt(0) nInt.SetBytes(decN) decE, err := base64.RawURLEncoding.DecodeString(*e) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } + var eBytes []byte if len(decE) < 8 { eBytes = make([]byte, 8-len(decE), 8) @@ -55,17 +61,20 @@ func decodePublicKey(e, n *string) (*rsa.PublicKey, error) { var eInt uint64 err = binary.Read(eReader, binary.BigEndian, &eInt) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } + pKey := rsa.PublicKey{N: nInt, E: int(eInt)} return &pKey, nil } // DecodeAccessToken currently only supports RSA - sorry for that func DecodeAccessToken(accessToken string, e, n *string) (*jwt.Token, *jwt.MapClaims, error) { + const errMessage = "could not decode accessToken" + rsaPublicKey, err := decodePublicKey(e, n) if err != nil { - return nil, nil, err + return nil, nil, errors.Wrap(err, errMessage) } claims := &jwt.MapClaims{} @@ -77,14 +86,20 @@ func DecodeAccessToken(accessToken string, e, n *string) (*jwt.Token, *jwt.MapCl return rsaPublicKey, nil }) - return token2, claims, err + if err != nil { + return nil, nil, errors.Wrap(err, errMessage) + } + + return token2, claims, nil } // DecodeAccessTokenCustomClaims currently only supports RSA - sorry for that func DecodeAccessTokenCustomClaims(accessToken string, e, n *string, customClaims jwt.Claims) (*jwt.Token, error) { + const errMessage = "could not decode accessToken with custom claims" + rsaPublicKey, err := decodePublicKey(e, n) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } token2, err := jwt.ParseWithClaims(accessToken, customClaims, func(token *jwt.Token) (interface{}, error) { @@ -95,5 +110,9 @@ func DecodeAccessTokenCustomClaims(accessToken string, e, n *string, customClaim return rsaPublicKey, nil }) - return token2, err + if err != nil { + return nil, errors.Wrap(err, errMessage) + } + + return token2, nil } From 0fb79d2631176c0e00e730dc3dfea549ea55de2c Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 22:31:21 +0100 Subject: [PATCH 02/16] fix broken json tag in Group --- models.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models.go b/models.go index b135c1c6..dee6a478 100644 --- a/models.go +++ b/models.go @@ -222,7 +222,7 @@ type Group struct { Name *string `json:"name,omitempty"` Path *string `json:"path,omitempty"` SubGroups []*Group `json:"subGroups,omitempty"` - Attributes map[string][]string `json:"attributes,emitempty"` + Attributes map[string][]string `json:"attributes,omitempty"` Access map[string]bool `json:"access,omitempty"` ClientRoles map[string][]string `json:"clientRoles,omitempty"` RealmRoles []string `json:"realmRoles,omitempty"` From 1da913667f7d434d274388dc8a98deec188362f5 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:06:02 +0100 Subject: [PATCH 03/16] wrap errors in client.go --- client.go | 503 ++++++++++++++++++++++++++++++++++++++---------------- go.mod | 5 +- go.sum | 6 +- 3 files changed, 356 insertions(+), 158 deletions(-) diff --git a/client.go b/client.go index d62330e3..440ff029 100644 --- a/client.go +++ b/client.go @@ -2,14 +2,14 @@ package gocloak import ( "encoding/base64" - "errors" "fmt" "strings" "time" - "github.com/Nerzal/gocloak/v3/pkg/jwx" + "github.com/Nerzal/gocloak/v4/pkg/jwx" "github.com/dgrijalva/jwt-go" "github.com/go-resty/resty/v2" + "github.com/pkg/errors" ) type gocloak struct { @@ -58,15 +58,18 @@ func (client *gocloak) getRequestWithBasicAuth(clientID string, clientSecret str return req } -func checkForError(resp *resty.Response, err error) error { +func checkForError(resp *resty.Response, err error, errMessage string) error { if err != nil { - return err + return errors.Wrap(err, errMessage) } + if resp == nil { return errors.New("Empty response") } + if resp.IsError() { var msg string + e := resp.Error().(*HTTPErrorResponse) if e != nil && len(e.ErrorMessage) > 0 { msg = fmt.Sprintf("%s: %s", resp.Status(), e.ErrorMessage) @@ -75,11 +78,14 @@ func checkForError(resp *resty.Response, err error) error { } else { msg = resp.Status() } + if resp.StatusCode() == 409 { return &ObjectAlreadyExists{ErrorMessage: msg} } + return errors.New(msg) } + return nil } @@ -134,13 +140,15 @@ func (client *gocloak) getAdminRealmURL(realm string, path ...string) string { } func (client *gocloak) GetServerInfo(accessToken string) (*ServerInfoRepesentation, error) { + var errMessage = "could not get server info" var result ServerInfoRepesentation + resp, err := client.getRequestWithBearerAuth(accessToken). SetResult(&result). Get(makeURL(client.basePath, "auth", "admin", "serverinfo")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -148,26 +156,30 @@ func (client *gocloak) GetServerInfo(accessToken string) (*ServerInfoRepesentati // GetUserInfo calls the UserInfo endpoint func (client *gocloak) GetUserInfo(accessToken string, realm string) (*UserInfo, error) { + const errMessage = "could not get user info" + var result UserInfo resp, err := client.getRequestWithBearerAuth(accessToken). SetResult(&result). Get(client.getRealmURL(realm, openIDConnect, "userinfo")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil } func (client *gocloak) getNewCerts(realm string) (*CertResponse, error) { + const errMessage = "could not get newCerts" + var result CertResponse resp, err := client.getRequest(). SetResult(&result). Get(client.getRealmURL(realm, openIDConnect, "certs")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -175,31 +187,38 @@ func (client *gocloak) getNewCerts(realm string) (*CertResponse, error) { // GetCerts fetches certificates for the given realm from the public /open-id-connect/certs endpoint func (client *gocloak) GetCerts(realm string) (*CertResponse, error) { + const errMessage = "could not get certs" + if cert, ok := client.certsCache[realm]; ok { return cert, nil } + cert, err := client.getNewCerts(realm) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } + client.certsCache[realm] = cert timer := time.NewTimer(client.Config.CertsInvalidateTime) go func() { <-timer.C delete(client.certsCache, realm) }() + return cert, nil } // GetIssuer gets the issuer of the given realm func (client *gocloak) GetIssuer(realm string) (*IssuerResponse, error) { + const errMessage = "could not get issuer" + var result IssuerResponse resp, err := client.getRequest(). SetResult(&result). Get(client.getRealmURL(realm)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, err.Error()); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -207,6 +226,8 @@ func (client *gocloak) GetIssuer(realm string) (*IssuerResponse, error) { // RetrospectToken calls the openid-connect introspect endpoint func (client *gocloak) RetrospectToken(accessToken string, clientID, clientSecret string, realm string) (*RetrospecTokenResult, error) { + const errMessage = "could not introspect requesting party token" + var result RetrospecTokenResult resp, err := client.getRequestWithBasicAuth(clientID, clientSecret). SetFormData(map[string]string{ @@ -216,8 +237,8 @@ func (client *gocloak) RetrospectToken(accessToken string, clientID, clientSecre SetResult(&result). Post(client.getRealmURL(realm, tokenEndpoint, "introspect")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -225,19 +246,21 @@ func (client *gocloak) RetrospectToken(accessToken string, clientID, clientSecre // DecodeAccessToken decodes the accessToken func (client *gocloak) DecodeAccessToken(accessToken, realm string) (*jwt.Token, *jwt.MapClaims, error) { + const errMessage = "could not decode access token" + decodedHeader, err := jwx.DecodeAccessTokenHeader(accessToken) if err != nil { - return nil, nil, err + return nil, nil, errors.Wrap(err, errMessage) } certResult, err := client.GetCerts(realm) if err != nil { - return nil, nil, err + return nil, nil, errors.Wrap(err, errMessage) } usedKey := findUsedKey(decodedHeader.Kid, certResult.Keys) if usedKey == nil { - return nil, nil, errors.New("cannot find a key to decode the token") + return nil, nil, errors.Wrap(errors.New("cannot find a key to decode the token"), errMessage) } return jwx.DecodeAccessToken(accessToken, usedKey.E, usedKey.N) @@ -245,38 +268,44 @@ func (client *gocloak) DecodeAccessToken(accessToken, realm string) (*jwt.Token, // DecodeAccessTokenCustomClaims decodes the accessToken and writes claims into the given claims func (client *gocloak) DecodeAccessTokenCustomClaims(accessToken string, realm string, claims jwt.Claims) (*jwt.Token, error) { + const errMessage = "could not decode access token with custom claims" + decodedHeader, err := jwx.DecodeAccessTokenHeader(accessToken) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } certResult, err := client.GetCerts(realm) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } usedKey := findUsedKey(decodedHeader.Kid, certResult.Keys) if usedKey == nil { - return nil, errors.New("cannot find a key to decode the token") + return nil, errors.Wrap(errors.New("cannot find a key to decode the token"), errMessage) } return jwx.DecodeAccessTokenCustomClaims(accessToken, usedKey.E, usedKey.N, claims) } func (client *gocloak) GetToken(realm string, options TokenOptions) (*JWT, error) { + const errMessage = "could not get token" + var token JWT var req *resty.Request + if !NilOrEmpty(options.ClientSecret) { req = client.getRequestWithBasicAuth(*(options.ClientID), *(options.ClientSecret)) } else { req = client.getRequest() } + resp, err := req.SetFormData(options.FormData()). SetResult(&token). Post(client.getRealmURL(realm, tokenEndpoint)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &token, nil @@ -324,6 +353,8 @@ func (client *gocloak) Login(clientID, clientSecret, realm, username, password s // Logout logs out users with refresh token func (client *gocloak) Logout(clientID, clientSecret, realm, refreshToken string) error { + const errMessage = "could not logout" + resp, err := client.getRequestWithBasicAuth(clientID, clientSecret). SetFormData(map[string]string{ "client_id": clientID, @@ -331,10 +362,12 @@ func (client *gocloak) Logout(clientID, clientSecret, realm, refreshToken string }). Post(client.getRealmURL(realm, logoutEndpoint)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) LogoutPublicClient(clientID, realm, accessToken, refreshToken string) error { + const errMessage = "could not logout public client" + resp, err := client.getRequestWithBearerAuth(accessToken). SetFormData(map[string]string{ "client_id": clientID, @@ -342,7 +375,7 @@ func (client *gocloak) LogoutPublicClient(clientID, realm, accessToken, refreshT }). Post(client.getRealmURL(realm, logoutEndpoint)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // RequestPermission request a permission @@ -359,173 +392,214 @@ func (client *gocloak) RequestPermission(clientID, clientSecret, realm, username // ExecuteActionsEmail executes an actions email func (client *gocloak) ExecuteActionsEmail(token, realm string, params ExecuteActionsEmail) error { + const errMessage = "could not execute actions email" + queryParams, err := GetQueryParams(params) if err != nil { - return err + return errors.Wrap(err, errMessage) } + resp, err := client.getRequestWithBearerAuth(token). SetBody(params.Actions). SetQueryParams(queryParams). Put(client.getAdminRealmURL(realm, "users", *(params.UserID), "execute-actions-email")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) CreateGroup(token, realm string, group Group) (string, error) { + const errMessage = "could not create group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(group). Post(client.getAdminRealmURL(realm, "groups")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } return getID(resp), nil } // CreateChildGroup creates a new child group func (client *gocloak) CreateChildGroup(token string, realm string, groupID string, group Group) (string, error) { + const errMessage = "could not create child group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(group). Post(client.getAdminRealmURL(realm, "groups", groupID, "children")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } func (client *gocloak) CreateComponent(token, realm string, component Component) (string, error) { + const errMessage = "could not create component" + resp, err := client.getRequestWithBearerAuth(token). SetBody(component). Post(client.getAdminRealmURL(realm, "components")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } func (client *gocloak) CreateClient(token, realm string, newClient Client) (string, error) { + const errMessage = "could not create client" + resp, err := client.getRequestWithBearerAuth(token). SetBody(newClient). Post(client.getAdminRealmURL(realm, "clients")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } // CreateClientRole creates a new role for a client func (client *gocloak) CreateClientRole(token, realm, clientID string, role Role) (string, error) { + const errMessage = "could not create client role" + resp, err := client.getRequestWithBearerAuth(token). SetBody(role). Post(client.getAdminRealmURL(realm, "clients", clientID, "roles")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } // CreateClientScope creates a new client scope func (client *gocloak) CreateClientScope(token, realm string, scope ClientScope) (string, error) { + const errMessage = "could not create client scope" + resp, err := client.getRequestWithBearerAuth(token). SetBody(scope). Post(client.getAdminRealmURL(realm, "client-scopes")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } func (client *gocloak) UpdateGroup(token, realm string, updatedGroup Group) error { + const errMessage = "could not update group" + if NilOrEmpty(updatedGroup.ID) { - return errors.New("ID of a group required") + return errors.Wrap(errors.New("ID of a group required"), errMessage) } resp, err := client.getRequestWithBearerAuth(token). SetBody(updatedGroup). Put(client.getAdminRealmURL(realm, "groups", PString(updatedGroup.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // UpdateClient updates the given Client func (client *gocloak) UpdateClient(token, realm string, updatedClient Client) error { + const errMessage = "could not update client" + if NilOrEmpty(updatedClient.ID) { - return errors.New("ID of a client required") + return errors.Wrap(errors.New("ID of a client required"), errMessage) } + resp, err := client.getRequestWithBearerAuth(token). SetBody(updatedClient). Put(client.getAdminRealmURL(realm, "clients", PString(updatedClient.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) UpdateRole(token, realm, clientID string, role Role) error { + const errMessage = "could not update role" + resp, err := client.getRequestWithBearerAuth(token). SetBody(role). Put(client.getAdminRealmURL(realm, "clients", clientID, "roles", PString(role.Name))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) UpdateClientScope(token string, realm string, scope ClientScope) error { + const errMessage = "could not update client scope" + resp, err := client.getRequestWithBearerAuth(token). SetBody(scope). Put(client.getAdminRealmURL(realm, "client-scopes", PString(scope.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) DeleteGroup(token string, realm string, groupID string) error { + const errMessage = "could not delete group" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "groups", groupID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClient deletes a given client func (client *gocloak) DeleteClient(token string, realm string, clientID string) error { + const errMessage = "could not delete client" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) DeleteComponent(token string, realm string, componentID string) error { + const errMessage = "could not delete component" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "components", componentID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientRole deletes a given role func (client *gocloak) DeleteClientRole(token, realm, clientID, roleName string) error { + const errMessage = "could not delete client role" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "roles", roleName)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) DeleteClientScope(token string, realm string, scopeID string) error { + const errMessage = "could not delete client scope" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "client-scopes", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetClient returns a client func (client *gocloak) GetClient(token string, realm string, clientID string) (*Client, error) { + const errMessage = "could not get client" + var result Client resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -533,14 +607,16 @@ func (client *gocloak) GetClient(token string, realm string, clientID string) (* // GetClientsDefaultScopes returns a list of the client's default scopes func (client *gocloak) GetClientsDefaultScopes(token string, realm string, clientID string) ([]*ClientScope, error) { + const errMessage = "could not get clients default scopes" + var result []*ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "default-client-scopes")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -548,30 +624,36 @@ func (client *gocloak) GetClientsDefaultScopes(token string, realm string, clien // AddDefaultScopeToClient adds a client scope to the list of client's default scopes func (client *gocloak) AddDefaultScopeToClient(token string, realm string, clientID string, scopeID string) error { + const errMessage = "could not add default scope to client" + resp, err := client.getRequestWithBearerAuth(token). Put(client.getAdminRealmURL(realm, "clients", clientID, "default-client-scopes", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // RemoveDefaultScopeFromClient removes a client scope from the list of client's default scopes func (client *gocloak) RemoveDefaultScopeFromClient(token string, realm string, clientID string, scopeID string) error { + const errMessage = "could not remove default scope from client" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "default-client-scopes", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetClientsOptionalScopes returns a list of the client's optional scopes func (client *gocloak) GetClientsOptionalScopes(token string, realm string, clientID string) ([]*ClientScope, error) { + const errMessage = "could not get clients optional scopes" + var result []*ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "optional-client-scopes")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -579,30 +661,36 @@ func (client *gocloak) GetClientsOptionalScopes(token string, realm string, clie // AddOptionalScopeToClient adds a client scope to the list of client's optional scopes func (client *gocloak) AddOptionalScopeToClient(token string, realm string, clientID string, scopeID string) error { + const errMessage = "could not add optional scope to client" + resp, err := client.getRequestWithBearerAuth(token). Put(client.getAdminRealmURL(realm, "clients", clientID, "optional-client-scopes", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // RemoveOptionalScopeFromClient deletes a client scope from the list of client's optional scopes func (client *gocloak) RemoveOptionalScopeFromClient(token string, realm string, clientID string, scopeID string) error { + const errMessage = "could not remove optional scope from client" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "optional-client-scopes", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetDefaultOptionalClientScopes returns a list of default realm optional scopes func (client *gocloak) GetDefaultOptionalClientScopes(token string, realm string) ([]*ClientScope, error) { + const errMessage = "could not get default optional client scopes" + var result []*ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "default-optional-client-scopes")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -610,14 +698,16 @@ func (client *gocloak) GetDefaultOptionalClientScopes(token string, realm string // GetDefaultDefaultClientScopes returns a list of default realm default scopes func (client *gocloak) GetDefaultDefaultClientScopes(token string, realm string) ([]*ClientScope, error) { + const errMessage = "could not get default client scopes" + var result []*ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "default-default-client-scopes")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -625,14 +715,16 @@ func (client *gocloak) GetDefaultDefaultClientScopes(token string, realm string) // GetClientScope returns a clientscope func (client *gocloak) GetClientScope(token string, realm string, scopeID string) (*ClientScope, error) { + const errMessage = "could not get client scope" + var result ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "client-scopes", scopeID)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -640,14 +732,16 @@ func (client *gocloak) GetClientScope(token string, realm string, scopeID string // GetClientScopes returns all client scopes func (client *gocloak) GetClientScopes(token string, realm string) ([]*ClientScope, error) { + const errMessage = "could not get client scopes" + var result []*ClientScope resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "client-scopes")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -655,13 +749,16 @@ func (client *gocloak) GetClientScopes(token string, realm string) ([]*ClientSco // GetClientSecret returns a client's secret func (client *gocloak) GetClientSecret(token string, realm string, clientID string) (*CredentialRepresentation, error) { + const errMessage = "could not get client secret" + var result CredentialRepresentation + resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "client-secret")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -669,85 +766,103 @@ func (client *gocloak) GetClientSecret(token string, realm string, clientID stri // GetClientServiceAccount retrieves the service account "user" for a client if enabled func (client *gocloak) GetClientServiceAccount(token string, realm string, clientID string) (*User, error) { + const errMessage = "could not get client service account" + var result User resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "service-account-user")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil } func (client *gocloak) RegenerateClientSecret(token string, realm string, clientID string) (*CredentialRepresentation, error) { + const errMessage = "could not regenerate client secret" + var result CredentialRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Post(client.getAdminRealmURL(realm, "clients", clientID, "client-secret")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } + return &result, nil } // GetClientOfflineSessions returns offline sessions associated with the client func (client *gocloak) GetClientOfflineSessions(token, realm, clientID string) ([]*UserSessionRepresentation, error) { + const errMessage = "could not get client offline sessions" + var res []*UserSessionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&res). Get(client.getAdminRealmURL(realm, "clients", clientID, "offline-sessions")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } + return res, nil } // GetClientUserSessions returns user sessions associated with the client func (client *gocloak) GetClientUserSessions(token, realm, clientID string) ([]*UserSessionRepresentation, error) { + const errMessage = "could not get client user sessions" + var res []*UserSessionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&res). Get(client.getAdminRealmURL(realm, "clients", clientID, "user-sessions")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } + return res, nil } // CreateClientProtocolMapper creates a protocol mapper in client scope func (client *gocloak) CreateClientProtocolMapper(token, realm, clientID string, mapper ProtocolMapperRepresentation) (string, error) { + const errMessage = "could not create client protocol mapper" + resp, err := client.getRequestWithBearerAuth(token). SetBody(mapper). Post(client.getAdminRealmURL(realm, "clients", clientID, "protocol-mappers", "models")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } // DeleteClientProtocolMapper deletes a protocol mapper in client scope func (client *gocloak) DeleteClientProtocolMapper(token, realm, clientID, mapperID string) error { + const errMessage = "could not delete client protocol mapper" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "protocol-mappers", "models", mapperID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetKeyStoreConfig get keystoreconfig of the realm func (client *gocloak) GetKeyStoreConfig(token string, realm string) (*KeyStoreConfig, error) { + const errMessage = "could not get key store config" + var result KeyStoreConfig resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "keys")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -755,26 +870,30 @@ func (client *gocloak) GetKeyStoreConfig(token string, realm string) (*KeyStoreC // GetComponents get all components in realm func (client *gocloak) GetComponents(token string, realm string) ([]*Component, error) { + const errMessage = "could not get components" + var result []*Component resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "components")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil } func (client *gocloak) getRoleMappings(token string, realm string, path string, objectID string) (*MappingsRepresentation, error) { + const errMessage = "could not get role mappings" + var result MappingsRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, path, objectID, "role-mappings")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -792,13 +911,16 @@ func (client *gocloak) GetRoleMappingByUserID(token string, realm string, userID // GetGroup get group with id in realm func (client *gocloak) GetGroup(token string, realm string, groupID string) (*Group, error) { + const errMessage = "could not get group" + var result Group + resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "groups", groupID)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -806,10 +928,12 @@ func (client *gocloak) GetGroup(token string, realm string, groupID string) (*Gr // GetGroups get all groups in realm func (client *gocloak) GetGroups(token string, realm string, params GetGroupsParams) ([]*Group, error) { + const errMessage = "could not get groups" + var result []*Group queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } resp, err := client.getRequestWithBearerAuth(token). @@ -817,8 +941,8 @@ func (client *gocloak) GetGroups(token string, realm string, params GetGroupsPar SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "groups")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -826,10 +950,12 @@ func (client *gocloak) GetGroups(token string, realm string, params GetGroupsPar // GetGroupMembers get a list of users of group with id in realm func (client *gocloak) GetGroupMembers(token string, realm string, groupID string, params GetGroupsParams) ([]*User, error) { + const errMessage = "could not get group members" + var result []*User queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } resp, err := client.getRequestWithBearerAuth(token). @@ -837,8 +963,8 @@ func (client *gocloak) GetGroupMembers(token string, realm string, groupID strin SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "groups", groupID, "members")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -846,13 +972,15 @@ func (client *gocloak) GetGroupMembers(token string, realm string, groupID strin // GetClientRoles get all roles for the given client in realm func (client *gocloak) GetClientRoles(token string, realm string, clientID string) ([]*Role, error) { + const errMessage = "could not get client roles" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "roles")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -860,13 +988,15 @@ func (client *gocloak) GetClientRoles(token string, realm string, clientID strin // GetClientRole get a role for the given client in a realm by role name func (client *gocloak) GetClientRole(token string, realm string, clientID string, roleName string) (*Role, error) { + const errMessage = "could not get client role" + var result Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "roles", roleName)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -874,18 +1004,20 @@ func (client *gocloak) GetClientRole(token string, realm string, clientID string // GetClients gets all clients in realm func (client *gocloak) GetClients(token string, realm string, params GetClientsParams) ([]*Client, error) { + const errMessage = "could not get clients" + var result []*Client queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "clients")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -909,25 +1041,31 @@ func (client *gocloak) UserAttributeContains(attributes map[string][]string, att // CreateRealmRole creates a role in a realm func (client *gocloak) CreateRealmRole(token string, realm string, role Role) (string, error) { + const errMessage = "could not create realm role" + resp, err := client.getRequestWithBearerAuth(token). SetBody(role). Post(client.getAdminRealmURL(realm, "roles")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } // GetRealmRole returns a role from a realm by role's name func (client *gocloak) GetRealmRole(token string, realm string, roleName string) (*Role, error) { + const errMessage = "could not get realm role" + var result Role + resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "roles", roleName)) - if err = checkForError(resp, err); err != nil { - return nil, err + if err = checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -935,13 +1073,15 @@ func (client *gocloak) GetRealmRole(token string, realm string, roleName string) // GetRealmRoles get all roles of the given realm. func (client *gocloak) GetRealmRoles(token string, realm string) ([]*Role, error) { + const errMessage = "could not get realm roles" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "roles")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -949,13 +1089,15 @@ func (client *gocloak) GetRealmRoles(token string, realm string) ([]*Role, error // GetRealmRolesByUserID returns all roles assigned to the given user func (client *gocloak) GetRealmRolesByUserID(token string, realm string, userID string) ([]*Role, error) { + const errMessage = "could not get realm roles by user id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "realm")) - if err = checkForError(resp, err); err != nil { - return nil, err + if err = checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -963,12 +1105,14 @@ func (client *gocloak) GetRealmRolesByUserID(token string, realm string, userID // GetRealmRolesByGroupID returns all roles assigned to the given group func (client *gocloak) GetRealmRolesByGroupID(token string, realm string, groupID string) ([]*Role, error) { + const errMessage = "could not get realm roles by group id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). Get(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "realm")) - if err = checkForError(resp, err); err != nil { - return nil, err + if err = checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -976,53 +1120,65 @@ func (client *gocloak) GetRealmRolesByGroupID(token string, realm string, groupI // UpdateRealmRole updates a role in a realm func (client *gocloak) UpdateRealmRole(token string, realm string, roleName string, role Role) error { + const errMessage = "could not update realm role" + resp, err := client.getRequestWithBearerAuth(token). SetBody(role). Put(client.getAdminRealmURL(realm, "roles", roleName)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteRealmRole deletes a role in a realm by role's name func (client *gocloak) DeleteRealmRole(token string, realm string, roleName string) error { + const errMessage = "could not delete realm role" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "roles", roleName)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // AddRealmRoleToUser adds realm-level role mappings func (client *gocloak) AddRealmRoleToUser(token string, realm string, userID string, roles []Role) error { + const errMessage = "could not add realm role to user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "realm")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteRealmRoleFromUser deletes realm-level role mappings func (client *gocloak) DeleteRealmRoleFromUser(token string, realm string, userID string, roles []Role) error { + const errMessage = "could not delete realm role from user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "realm")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) AddRealmRoleComposite(token string, realm string, roleName string, roles []Role) error { + const errMessage = "could not add realm role composite" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "roles", roleName, "composites")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) DeleteRealmRoleComposite(token string, realm string, roleName string, roles []Role) error { + const errMessage = "could not delete realm role composite" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "roles", roleName, "composites")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // ----- @@ -1031,13 +1187,15 @@ func (client *gocloak) DeleteRealmRoleComposite(token string, realm string, role // GetRealm returns top-level representation of the realm func (client *gocloak) GetRealm(token string, realm string) (*RealmRepresentation, error) { + const errMessage = "could not get realm" + var result RealmRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm)) - if err = checkForError(resp, err); err != nil { - return nil, err + if err = checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -1045,13 +1203,15 @@ func (client *gocloak) GetRealm(token string, realm string) (*RealmRepresentatio // GetRealms returns top-level representation of all realms func (client *gocloak) GetRealms(token string) ([]*RealmRepresentation, error) { + const errMessage = "could not get realms" + var result []*RealmRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL("")) - if err = checkForError(resp, err); err != nil { - return nil, err + if err = checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -1059,28 +1219,36 @@ func (client *gocloak) GetRealms(token string) ([]*RealmRepresentation, error) { // CreateRealm creates a realm func (client *gocloak) CreateRealm(token string, realm RealmRepresentation) (string, error) { + const errMessage = "could not create realm" + resp, err := client.getRequestWithBearerAuth(token). SetBody(&realm). Post(client.getAdminRealmURL("")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } return getID(resp), nil } // DeleteRealm removes a realm func (client *gocloak) DeleteRealm(token string, realm string) error { + const errMessage = "could not delete realm" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm)) - return checkForError(resp, err) + + return checkForError(resp, err, errMessage) } // ClearRealmCache clears realm cache func (client *gocloak) ClearRealmCache(token string, realm string) error { + const errMessage = "could not clear realm cache" + resp, err := client.getRequestWithBearerAuth(token). Post(client.getAdminRealmURL(realm, "clear-realm-cache")) - return checkForError(resp, err) + + return checkForError(resp, err, errMessage) } // ----- @@ -1089,28 +1257,35 @@ func (client *gocloak) ClearRealmCache(token string, realm string) error { // CreateUser creates the given user in the given realm and returns it's userID func (client *gocloak) CreateUser(token string, realm string, user User) (string, error) { + const errMessage = "could not create user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(user). Post(client.getAdminRealmURL(realm, "users")) - if err := checkForError(resp, err); err != nil { - return "", err + if err := checkForError(resp, err, errMessage); err != nil { + return "", errors.Wrap(err, errMessage) } + return getID(resp), nil } // DeleteUser delete a given user func (client *gocloak) DeleteUser(token string, realm string, userID string) error { + const errMessage = "could not delete user" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "users", userID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetUserByID fetches a user from the given realm with the given userID func (client *gocloak) GetUserByID(accessToken string, realm string, userID string) (*User, error) { + const errMessage = "could not get user by id" + if userID == "" { - return nil, errors.New("userID shall not be empty") + return nil, errors.Wrap(errors.New("userID shall not be empty"), errMessage) } var result User @@ -1118,8 +1293,8 @@ func (client *gocloak) GetUserByID(accessToken string, realm string, userID stri SetResult(&result). Get(client.getAdminRealmURL(realm, "users", userID)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return &result, nil @@ -1127,13 +1302,15 @@ func (client *gocloak) GetUserByID(accessToken string, realm string, userID stri // GetUserCount gets the user count in the realm func (client *gocloak) GetUserCount(token string, realm string) (int, error) { + const errMessage = "could not get user count" + var result int resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "users", "count")) - if err := checkForError(resp, err); err != nil { - return -1, err + if err := checkForError(resp, err, errMessage); err != nil { + return -1, errors.Wrap(err, errMessage) } return result, nil @@ -1141,13 +1318,15 @@ func (client *gocloak) GetUserCount(token string, realm string) (int, error) { // GetUserGroups get all groups for user func (client *gocloak) GetUserGroups(token string, realm string, userID string) ([]*UserGroup, error) { + const errMessage = "could not get user groups" + var result []*UserGroup resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "users", userID, "groups")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -1155,10 +1334,12 @@ func (client *gocloak) GetUserGroups(token string, realm string, userID string) // GetUsers get all users in realm func (client *gocloak) GetUsers(token string, realm string, params GetUsersParams) ([]*User, error) { + const errMessage = "could not get users" + var result []*User queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } resp, err := client.getRequestWithBearerAuth(token). @@ -1166,8 +1347,8 @@ func (client *gocloak) GetUsers(token string, realm string, params GetUsersParam SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "users")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -1175,13 +1356,15 @@ func (client *gocloak) GetUsers(token string, realm string, params GetUsersParam // GetUsersByRoleName returns all users have a given role func (client *gocloak) GetUsersByRoleName(token string, realm string, roleName string) ([]*User, error) { + const errMessage = "could not get users by role name" + var result []*User resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "roles", roleName, "users")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } return result, nil @@ -1189,79 +1372,97 @@ func (client *gocloak) GetUsersByRoleName(token string, realm string, roleName s // SetPassword sets a new password for the user with the given id. Needs elevated privileges func (client *gocloak) SetPassword(token string, userID string, realm string, password string, temporary bool) error { + const errMessage = "could not set password" + requestBody := SetPasswordRequest{Password: &password, Temporary: &temporary, Type: StringP("password")} resp, err := client.getRequestWithBearerAuth(token). SetBody(requestBody). Put(client.getAdminRealmURL(realm, "users", userID, "reset-password")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // UpdateUser updates a given user func (client *gocloak) UpdateUser(token string, realm string, user User) error { + const errMessage = "could not update user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(user). Put(client.getAdminRealmURL(realm, "users", PString(user.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // AddUserToGroup puts given user to given group func (client *gocloak) AddUserToGroup(token string, realm string, userID string, groupID string) error { + const errMessage = "could not add user to group" + resp, err := client.getRequestWithBearerAuth(token). Put(client.getAdminRealmURL(realm, "users", userID, "groups", groupID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteUserFromGroup deletes given user from given group func (client *gocloak) DeleteUserFromGroup(token string, realm string, userID string, groupID string) error { + const errMessage = "could not delete user from group" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "users", userID, "groups", groupID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetUserSessions returns user sessions associated with the user func (client *gocloak) GetUserSessions(token, realm, userID string) ([]*UserSessionRepresentation, error) { + const errMessage = "could not get user sessions" + var res []*UserSessionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&res). Get(client.getAdminRealmURL(realm, "users", userID, "sessions")) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } + return res, nil } // GetUserOfflineSessionsForClient returns offline sessions associated with the user and client func (client *gocloak) GetUserOfflineSessionsForClient(token, realm, userID, clientID string) ([]*UserSessionRepresentation, error) { + const errMessage = "could not get user offline sessions for client" + var res []*UserSessionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&res). Get(client.getAdminRealmURL(realm, "users", userID, "offline-sessions", clientID)) - if err := checkForError(resp, err); err != nil { - return nil, err + if err := checkForError(resp, err, errMessage); err != nil { + return nil, errors.Wrap(err, errMessage) } + return res, nil } // AddClientRoleToUser adds client-level role mappings func (client *gocloak) AddClientRoleToUser(token string, realm string, clientID string, userID string, roles []Role) error { + const errMessage = "could not add client role to user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientRoleFromUser adds client-level role mappings func (client *gocloak) DeleteClientRoleFromUser(token string, realm string, clientID string, userID string, roles []Role) error { + const errMessage = "could not delete client role from user" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } diff --git a/go.mod b/go.mod index 1a45827f..578b0675 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,12 @@ -module github.com/Nerzal/gocloak/v3 +module github.com/Nerzal/gocloak/v4 require ( - github.com/Nerzal/gocloak/v4 v4.8.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/go-resty/resty/v2 v2.0.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.4.0 + gopkg.in/yaml.v2 v2.2.7 // indirect ) go 1.13 diff --git a/go.sum b/go.sum index 3d49443b..5cdb531d 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,3 @@ -github.com/Nerzal/gocloak v1.0.0 h1:WllsbIu1dYvdvka1/BbY7khZBJSTjSkGwyDsHHLQmIw= -github.com/Nerzal/gocloak/v4 v4.8.0 h1:Ts932I0mbrkvoUxo4U0XmfqiNsbzraq+ZMoKV0KDT64= -github.com/Nerzal/gocloak/v4 v4.8.0/go.mod h1:/7LwujSlsqBA3haXobPxOPVZMP9iQ9zlQJAbP0ZhO4I= 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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -15,8 +12,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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= @@ -24,6 +19,7 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= From bce5189f75f6176c02c166f70a5492da2916fa4b Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:09:38 +0100 Subject: [PATCH 04/16] go mod tidied --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index 44f18aa7..b3eea8e8 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,7 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= From 0bd1f15d9233c745b2b69dcdb723dffe7c26f344 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:09:53 +0100 Subject: [PATCH 05/16] go fmt'd --- client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.go b/client.go index 6cf994d8..0577787c 100644 --- a/client.go +++ b/client.go @@ -194,7 +194,7 @@ func (client *gocloak) GetCerts(realm string) (*CertResponse, error) { client.certsLock.Lock() defer client.certsLock.Unlock() - + if cert, ok := client.certsCache[realm]; ok { return cert, nil } From fa5c63b23a5086768532ee18a1cce95cc19b90ae Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:29:43 +0100 Subject: [PATCH 06/16] wrap more errors --- client.go | 227 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 168 insertions(+), 59 deletions(-) diff --git a/client.go b/client.go index 0577787c..a05b44f2 100644 --- a/client.go +++ b/client.go @@ -322,6 +322,8 @@ func (client *gocloak) GetToken(realm string, options TokenOptions) (*JWT, error // GetRequestingPartyToken returns a requesting party token with permissions granted by the server func (client *gocloak) GetRequestingPartyToken(token, realm string, options RequestingPartyTokenOptions) (*JWT, error) { + const errMessage = "could not get requesting party token" + var res JWT resp, err := client.getRequestWithBearerAuth(token). @@ -330,7 +332,7 @@ func (client *gocloak) GetRequestingPartyToken(token, realm string, options Requ SetResult(&res). Post(client.getRealmURL(realm, tokenEndpoint)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -858,11 +860,13 @@ func (client *gocloak) CreateClientProtocolMapper(token, realm, clientID string, // UpdateClientProtocolMapper updates a protocol mapper in client scope func (client *gocloak) UpdateClientProtocolMapper(token, realm, clientID string, mapperID string, mapper ProtocolMapperRepresentation) error { + const errMessage = "could not update client protocol mapper" + resp, err := client.getRequestWithBearerAuth(token). SetBody(mapper). Put(client.getAdminRealmURL(realm, "clients", clientID, "protocol-mappers", "models", mapperID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientProtocolMapper deletes a protocol mapper in client scope @@ -909,13 +913,15 @@ func (client *gocloak) GetComponents(token string, realm string) ([]*Component, // GetDefaultGroups returns a list of default groups func (client *gocloak) GetDefaultGroups(token string, realm string) ([]*Group, error) { + const errMessage = "could not get default groups" + var result []*Group resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "default-groups")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -924,18 +930,22 @@ func (client *gocloak) GetDefaultGroups(token string, realm string) ([]*Group, e // AddDefaultGroup adds group to the list of default groups func (client *gocloak) AddDefaultGroup(token string, realm string, groupID string) error { + const errMessage = "could not add default group" + resp, err := client.getRequestWithBearerAuth(token). Put(client.getAdminRealmURL(realm, "default-groups", groupID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // RemoveDefaultGroup removes group from the list of default groups func (client *gocloak) RemoveDefaultGroup(token string, realm string, groupID string) error { + const errMessage = "could not remove default group" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "default-groups", groupID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) getRoleMappings(token string, realm string, path string, objectID string) (*MappingsRepresentation, error) { @@ -1042,12 +1052,14 @@ func (client *gocloak) GetClientRoles(token string, realm string, clientID strin // GetRealmRolesByUserID returns all client roles assigned to the given user func (client *gocloak) GetClientRolesByUserID(token string, realm string, clientID string, userID string) ([]*Role, error) { + const errMessage = "could not client roles by user id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "clients", clientID)) - if err = checkForError(resp, err); err != nil { + if err = checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1056,12 +1068,14 @@ func (client *gocloak) GetClientRolesByUserID(token string, realm string, client // GetClientRolesByGroupID returns all client roles assigned to the given group func (client *gocloak) GetClientRolesByGroupID(token string, realm string, clientID string, groupID string) ([]*Role, error) { + const errMessage = "could not get client roles by group id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "clients", clientID)) - if err = checkForError(resp, err); err != nil { + if err = checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1070,12 +1084,14 @@ func (client *gocloak) GetClientRolesByGroupID(token string, realm string, clien // GetCompositeClientRolesByRoleID returns all client composite roles associated with the given client role func (client *gocloak) GetCompositeClientRolesByRoleID(token string, realm string, clientID string, roleID string) ([]*Role, error) { + const errMessage = "could not get composite client roles by role id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "roles-by-id", roleID, "composites", "clients", clientID)) - if err = checkForError(resp, err); err != nil { + if err = checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1084,12 +1100,14 @@ func (client *gocloak) GetCompositeClientRolesByRoleID(token string, realm strin // GetCompositeClientRolesByUserID returns all client roles and composite roles assigned to the given user func (client *gocloak) GetCompositeClientRolesByUserID(token string, realm string, clientID string, userID string) ([]*Role, error) { + const errMessage = "could not get composite client roles by user id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "clients", clientID, "composite")) - if err = checkForError(resp, err); err != nil { + if err = checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1098,12 +1116,14 @@ func (client *gocloak) GetCompositeClientRolesByUserID(token string, realm strin // GetCompositeClientRolesByGroupID returns all client roles and composite roles assigned to the given group func (client *gocloak) GetCompositeClientRolesByGroupID(token string, realm string, clientID string, groupID string) ([]*Role, error) { + const errMessage = "could not get composite client roles by group id" + var result []*Role resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "clients", clientID, "composite")) - if err = checkForError(resp, err); err != nil { + if err = checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1287,20 +1307,24 @@ func (client *gocloak) DeleteRealmRoleFromUser(token string, realm string, userI // AddRealmRoleToGroup adds realm-level role mappings func (client *gocloak) AddRealmRoleToGroup(token string, realm string, groupID string, roles []Role) error { + const errMessage = "could not add realm role to group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "realm")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteRealmRoleFromGroup deletes realm-level role mappings func (client *gocloak) DeleteRealmRoleFromGroup(token string, realm string, groupID string, roles []Role) error { + const errMessage = "could not delete realm role from group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "realm")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } func (client *gocloak) AddRealmRoleComposite(token string, realm string, roleName string, roles []Role) error { @@ -1375,11 +1399,13 @@ func (client *gocloak) CreateRealm(token string, realm RealmRepresentation) (str // UpdateRealm updates a given realm func (client *gocloak) UpdateRealm(token string, realm RealmRepresentation) error { + const errMessage = "could not update realm" + resp, err := client.getRequestWithBearerAuth(token). SetBody(realm). Put(client.getAdminRealmURL(PString(realm.Realm))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteRealm removes a realm @@ -1404,16 +1430,22 @@ func (client *gocloak) ClearRealmCache(token string, realm string) error { // ClearUserCache clears realm cache func (client *gocloak) ClearUserCache(token string, realm string) error { + const errMessage = "could not clear user cache" + resp, err := client.getRequestWithBearerAuth(token). Post(client.getAdminRealmURL(realm, "clear-user-cache")) - return checkForError(resp, err) + + return checkForError(resp, err, errMessage) } // ClearKeysCache clears realm cache func (client *gocloak) ClearKeysCache(token string, realm string) error { + const errMessage = "could not clear keys cache" + resp, err := client.getRequestWithBearerAuth(token). Post(client.getAdminRealmURL(realm, "clear-keys-cache")) - return checkForError(resp, err) + + return checkForError(resp, err, errMessage) } // ----- @@ -1537,6 +1569,8 @@ func (client *gocloak) GetUsersByRoleName(token string, realm string, roleName s // GetUsersByClientRoleName returns all users have a given client role func (client *gocloak) GetUsersByClientRoleName(token string, realm string, clientID string, roleName string, params GetUsersByRoleParams) ([]*User, error) { + const errMessage = "could not get users by client role name" + var result []*User queryParams, err := GetQueryParams(params) if err != nil { @@ -1548,7 +1582,7 @@ func (client *gocloak) GetUsersByClientRoleName(token string, realm string, clie SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "clients", clientID, "roles", roleName, "users")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1643,11 +1677,13 @@ func (client *gocloak) AddClientRoleToUser(token string, realm string, clientID // AddClientRoleToGroup adds a client role to the group func (client *gocloak) AddClientRoleToGroup(token string, realm string, clientID string, groupID string, roles []Role) error { + const errMessage = "could not add client role to group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientRoleFromUser adds client-level role mappings @@ -1658,34 +1694,40 @@ func (client *gocloak) DeleteClientRoleFromUser(token string, realm string, clie SetBody(roles). Delete(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientRoleFromGroup removes a client role from from the group func (client *gocloak) DeleteClientRoleFromGroup(token string, realm string, clientID string, groupID string, roles []Role) error { + const errMessage = "could not client role from group" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "clients", clientID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // AddClientRoleComposite adds roles as composite func (client *gocloak) AddClientRoleComposite(token string, realm string, roleID string, roles []Role) error { + const errMessage = "could not add client role composite" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Post(client.getAdminRealmURL(realm, "roles-by-id", roleID, "composites")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteClientRoleComposite deletes composites from a role func (client *gocloak) DeleteClientRoleComposite(token string, realm string, roleID string, roles []Role) error { + const errMessage = "could not delete client role composite" + resp, err := client.getRequestWithBearerAuth(token). SetBody(roles). Delete(client.getAdminRealmURL(realm, "roles-by-id", roleID, "composites")) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // ------------------ @@ -1694,11 +1736,13 @@ func (client *gocloak) DeleteClientRoleComposite(token string, realm string, rol // CreateIdentityProvider creates an identity provider in a realm func (client *gocloak) CreateIdentityProvider(token string, realm string, providerRep IdentityProviderRepresentation) (string, error) { + const errMessage = "could not create identity provider" + resp, err := client.getRequestWithBearerAuth(token). SetBody(providerRep). Post(client.getAdminRealmURL(realm, "identity-provider", "instances")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return "", err } @@ -1707,12 +1751,14 @@ func (client *gocloak) CreateIdentityProvider(token string, realm string, provid // GetIdentityProviders returns list of identity providers in a realm func (client *gocloak) GetIdentityProviders(token string, realm string) ([]*IdentityProviderRepresentation, error) { + const errMessage = "could not get identity providers" + result := []*IdentityProviderRepresentation{} resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "identity-provider", "instances")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1721,12 +1767,14 @@ func (client *gocloak) GetIdentityProviders(token string, realm string) ([]*Iden // GetIdentityProvider gets the identity provider in a realm func (client *gocloak) GetIdentityProvider(token string, realm string, alias string) (*IdentityProviderRepresentation, error) { + const errMessage = "could not get identity provider" + result := IdentityProviderRepresentation{} resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "identity-provider", "instances", alias)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } @@ -1735,102 +1783,125 @@ func (client *gocloak) GetIdentityProvider(token string, realm string, alias str // UpdateIdentityProvider updates the identity provider in a realm func (client *gocloak) UpdateIdentityProvider(token string, realm string, alias string, providerRep IdentityProviderRepresentation) error { + const errMessage = "could not update identity provider" + resp, err := client.getRequestWithBearerAuth(token). SetBody(providerRep). Put(client.getAdminRealmURL(realm, "identity-provider", "instances", alias)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteIdentityProvider deletes the identity provider in a realm func (client *gocloak) DeleteIdentityProvider(token string, realm string, alias string) error { + const errMessage = "could not delete identity provider" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "identity-provider", "instances", alias)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetResource returns a client's resource with the given id func (client *gocloak) GetResource(token string, realm string, clientID string, resourceID string) (*ResourceRepresentation, error) { + const errMessage = "could not get resource" + var result ResourceRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "resource", resourceID)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // GetResources returns resources associated with the client func (client *gocloak) GetResources(token string, realm string, clientID string, params GetResourceParams) ([]*ResourceRepresentation, error) { + const errMessage = "could not get resources" + queryParams, err := GetQueryParams(params) if err != nil { return nil, err } + var result []*ResourceRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "resource")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return result, err + + return result, nil } // CreateResource creates a resource associated with the client func (client *gocloak) CreateResource(token, realm string, clientID string, resource ResourceRepresentation) (*ResourceRepresentation, error) { + const errMessage = "could not create resource" + var result ResourceRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetBody(resource). Post(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "resource")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + return &result, nil } // UpdateResource updates a resource associated with the client func (client *gocloak) UpdateResource(token string, realm string, clientID string, resource ResourceRepresentation) error { + const errMessage = "could not update resource" + if NilOrEmpty(resource.ID) { return errors.New("ID of a resource required") } + resp, err := client.getRequestWithBearerAuth(token). SetBody(resource). Put(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "resource", *(resource.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteResource deletes a resource associated with the client func (client *gocloak) DeleteResource(token string, realm string, clientID string, resourceID string) error { + const errMessage = "could not delete resource" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "resource", resourceID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetScope returns a client's scope with the given id func (client *gocloak) GetScope(token string, realm string, clientID string, scopeID string) (*ScopeRepresentation, error) { + const errMessage = "could not get scope" + var result ScopeRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "scope", scopeID)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // GetScopes returns scopes associated with the client func (client *gocloak) GetScopes(token string, realm string, clientID string, params GetScopeParams) ([]*ScopeRepresentation, error) { + const errMessage = "could not get scopes" + queryParams, err := GetQueryParams(params) if err != nil { return nil, err @@ -1841,64 +1912,78 @@ func (client *gocloak) GetScopes(token string, realm string, clientID string, pa SetQueryParams(queryParams). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "scope")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return result, err + + return result, nil } // CreateScope creates a scope associated with the client func (client *gocloak) CreateScope(token string, realm string, clientID string, scope ScopeRepresentation) (*ScopeRepresentation, error) { + const errMessage = "could not create scope" + var result ScopeRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetBody(scope). Post(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "scope")) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // UpdateScope updates a scope associated with the client func (client *gocloak) UpdateScope(token string, realm string, clientID string, scope ScopeRepresentation) error { + const errMessage = "could not update scope" + if NilOrEmpty(scope.ID) { return errors.New("ID of a scope required") } + resp, err := client.getRequestWithBearerAuth(token). SetBody(scope). Put(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "scope", *(scope.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeleteScope deletes a scope associated with the client func (client *gocloak) DeleteScope(token string, realm string, clientID string, scopeID string) error { + const errMessage = "could not delete scope" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "scope", scopeID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetPolicy returns a client's policy with the given id func (client *gocloak) GetPolicy(token string, realm string, clientID string, policyID string) (*PolicyRepresentation, error) { + const errMessage = "could not get policy" + var result PolicyRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "policy", policyID)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // GetPolicies returns policies associated with the client func (client *gocloak) GetPolicies(token string, realm string, clientID string, params GetPolicyParams) ([]*PolicyRepresentation, error) { + const errMessage = "could not get policies" + queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } var adminURL string @@ -1914,67 +1999,82 @@ func (client *gocloak) GetPolicies(token string, realm string, clientID string, SetQueryParams(queryParams). Get(adminURL) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return result, err + + return result, nil } // CreatePolicy creates a policy associated with the client func (client *gocloak) CreatePolicy(token string, realm string, clientID string, policy PolicyRepresentation) (*PolicyRepresentation, error) { + const errMessage = "could not create policy" + if NilOrEmpty(policy.Type) { return nil, errors.New("type of a policy required") } + var result PolicyRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetBody(policy). Post(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "policy", *(policy.Type))) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // UpdatePolicy updates a policy associated with the client func (client *gocloak) UpdatePolicy(token string, realm string, clientID string, policy PolicyRepresentation) error { + const errMessage = "could not update policy" + if NilOrEmpty(policy.ID) { return errors.New("ID of a policy required") } + resp, err := client.getRequestWithBearerAuth(token). SetBody(policy). Put(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "policy", *(policy.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeletePolicy deletes a policy associated with the client func (client *gocloak) DeletePolicy(token string, realm string, clientID string, policyID string) error { + const errMessage = "could not delete policy" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "policy", policyID)) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // GetPermission returns a client's permission with the given id func (client *gocloak) GetPermission(token string, realm string, clientID string, permissionID string) (*PermissionRepresentation, error) { + const errMessage = "could not get permission" + var result PermissionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). Get(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", permissionID)) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // GetPolicies returns permissions associated with the client func (client *gocloak) GetPermissions(token string, realm string, clientID string, params GetPermissionParams) ([]*PermissionRepresentation, error) { + const errMessage = "could not get permissions" + queryParams, err := GetQueryParams(params) if err != nil { - return nil, err + return nil, errors.Wrap(err, errMessage) } var adminURL string @@ -1990,31 +2090,38 @@ func (client *gocloak) GetPermissions(token string, realm string, clientID strin SetQueryParams(queryParams). Get(adminURL) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return result, err + + return result, nil } // CreatePermission creates a permission associated with the client func (client *gocloak) CreatePermission(token string, realm string, clientID string, permission PermissionRepresentation) (*PermissionRepresentation, error) { + const errMessage = "could not craete permission" + if NilOrEmpty(permission.Type) { return nil, errors.New("type of a permission required") } + var result PermissionRepresentation resp, err := client.getRequestWithBearerAuth(token). SetResult(&result). SetBody(permission). Post(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", *(permission.Type))) - if err := checkForError(resp, err); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } - return &result, err + + return &result, nil } // UpdatePermission updates a permission associated with the client func (client *gocloak) UpdatePermission(token string, realm string, clientID string, permission PermissionRepresentation) error { + const errMessage = "could not update permission" + if NilOrEmpty(permission.ID) { return errors.New("ID of a permission required") } @@ -2022,11 +2129,13 @@ func (client *gocloak) UpdatePermission(token string, realm string, clientID str SetBody(permission). Put(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", *(permission.ID))) - return checkForError(resp, err) + return checkForError(resp, err, errMessage) } // DeletePermission deletes a policy associated with the client func (client *gocloak) DeletePermission(token string, realm string, clientID string, permissionID string) error { + const errMessage = "could not delete permission" + resp, err := client.getRequestWithBearerAuth(token). Delete(client.getAdminRealmURL(realm, "clients", clientID, "authz", "resource-server", "permission", permissionID)) From 33b1a7a8b5dcdfdf4969d44806185a4a53b14837 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:42:09 +0100 Subject: [PATCH 07/16] refactor APIError --- client_test.go | 1 + models.go | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client_test.go b/client_test.go index 5c64b154..cdd394a1 100644 --- a/client_test.go +++ b/client_test.go @@ -252,6 +252,7 @@ func CreatePolicy(t *testing.T, client GoCloak, clientID string, policy PolicyRe clientID, policy) assert.NoError(t, err, "CreatePolicy failed") + t.Logf("Created Policy ID: %s ", *(createdPolicy.ID)) tearDown := func() { diff --git a/models.go b/models.go index fb051733..e563b095 100644 --- a/models.go +++ b/models.go @@ -2,6 +2,7 @@ package gocloak import ( "encoding/json" + "strconv" "strings" ) @@ -54,15 +55,15 @@ func (s *StringOrArray) MarshalJSON() ([]byte, error) { return json.Marshal([]string(*s)) } -// APIError represents an api error +// APIError holds message and statusCode for api errors type APIError struct { - Code int - Message string + Code int `json:"code"` + Message string `json:"message"` } // Error stringifies the APIError func (apiError APIError) Error() string { - return apiError.Message + return "Code: " + strconv.Itoa(apiError.Code) + " Message: " + apiError.Message } // CertResponseKey is returned by the certs endpoint From e17380a5b01bc5c1f5f75b1ab9157efabf072822 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:45:03 +0100 Subject: [PATCH 08/16] generate api error on resp.IsError() --- client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index a05b44f2..e1f8490c 100644 --- a/client.go +++ b/client.go @@ -86,7 +86,10 @@ func checkForError(resp *resty.Response, err error, errMessage string) error { return &ObjectAlreadyExists{ErrorMessage: msg} } - return errors.New(msg) + return &APIError{ + Code: resp.StatusCode(), + Message: msg, + } } return nil From 58b8128a9473490b2ecb91c744cab1aab0d731f6 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:51:07 +0100 Subject: [PATCH 09/16] update golangci-lint and nancy --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1d296685..5fa1572e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -3,8 +3,8 @@ on: - push - pull_request env: - LINT_VERSION: "v1.22.2" - NANCY_VERSION: "v0.0.39" + LINT_VERSION: "v1.23.6" + NANCY_VERSION: "v0.0.41" jobs: tests: runs-on: ubuntu-latest From b3eb86fa29156e02269186c74c56e9b449d527b9 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:56:20 +0100 Subject: [PATCH 10/16] remove objectallreadyexist error --- client.go | 4 ---- client_test.go | 4 +++- errors.go | 15 --------------- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/client.go b/client.go index e1f8490c..f1d3ad62 100644 --- a/client.go +++ b/client.go @@ -82,10 +82,6 @@ func checkForError(resp *resty.Response, err error, errMessage string) error { msg = resp.Status() } - if resp.StatusCode() == 409 { - return &ObjectAlreadyExists{ErrorMessage: msg} - } - return &APIError{ Code: resp.StatusCode(), Message: msg, diff --git a/client_test.go b/client_test.go index cdd394a1..11853fd9 100644 --- a/client_test.go +++ b/client_test.go @@ -305,7 +305,9 @@ func SetUpTestUser(t testing.TB, client GoCloak) { cfg.GoCloak.Realm, user, ) - if IsObjectAlreadyExists(err) { + + apiError := err.(*APIError) + if apiError.Code == http.StatusConflict { users, err := client.GetUsers( token.AccessToken, cfg.GoCloak.Realm, diff --git a/errors.go b/errors.go index b8e9c64f..83dbbd23 100644 --- a/errors.go +++ b/errors.go @@ -1,20 +1,5 @@ package gocloak -// ObjectAlreadyExists is used when keycloak answers with 409 -type ObjectAlreadyExists struct { - ErrorMessage string -} - -func (e *ObjectAlreadyExists) Error() string { - return e.ErrorMessage -} - -// IsObjectAlreadyExists is a helper to verify tht the err is ObjectAlreadyExists -func IsObjectAlreadyExists(err error) bool { - _, ok := err.(*ObjectAlreadyExists) - return ok -} - // HTTPErrorResponse is a model of an error response type HTTPErrorResponse struct { ErrorMessage string `json:"errorMessage,omitempty"` From 6f70c3ff1cd1b6a060f19105caeffbb04b6e50ab Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Thu, 20 Feb 2020 23:58:32 +0100 Subject: [PATCH 11/16] removed doubled golangci-lint config --- golangci.yml | 90 ---------------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 golangci.yml diff --git a/golangci.yml b/golangci.yml deleted file mode 100644 index a6a2275e..00000000 --- a/golangci.yml +++ /dev/null @@ -1,90 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - settings: - printf: - funcs: - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - golint: - min-confidence: 0 - gocyclo: - min-complexity: 10 - maligned: - suggest-new: true - dupl: - threshold: 100 - goconst: - min-len: 3 - min-occurrences: 3 - depguard: - list-type: blacklist - packages: - # logging is allowed only by logutils.Log, logrus - # is allowed to use only in logutils package - - github.com/sirupsen/logrus - misspell: - locale: US - lll: - line-length: 170 - goimports: - local-prefixes: github.com/golangci/golangci-lint - prealloc: - simple: true - range-loops: true # Report preallocation suggestions on range loops, true by default - for-loops: false # Report preallocation suggestions on for loops, false by default - nakedret: - # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 - max-func-lines: 30 - gocritic: - enabled-tags: - - performance - - style - - experimental - disabled-checks: - - wrapperFunc - errcheck: - # report about not checking of errors in type assertions: `a := b.(MyStruct)`; - # default is false: such cases aren't reported by default. - check-type-assertions: false - wsl: - # If true append is only allowed to be cuddled if appending value is - # matching variables, fields or types on line above. Default is true. - strict-append: true - # Allow calls and assignments to be cuddled as long as the lines have any - # matching variables, fields or types. Default is true. - allow-assign-and-call: true - # Allow multiline assignments to be cuddled. Default is true. - allow-multiline-assign: true - # Allow declarations (var) to be cuddled. - allow-cuddle-declarations: true - # Allow trailing comments in ending of blocks - allow-trailing-comment: false - # Force newlines in end of case at this limit (0 = never). - force-case-trailing-whitespace: 0 -linters: - enable-all: true - -run: - skip-dirs: - - test/testdata_etc - - pkg/golinters/goanalysis/(checker|passes) - - docs - - coverage - - test - - configs - - cmd - tests: false -issues: - exclude-rules: - - text: "weak cryptographic primitive" - linters: - - gosec -# golangci.com configuration -# https://github.com/golangci/golangci/wiki/Configuration -service: - golangci-lint-version: 1.23.x # use the fixed version to not introduce new linters unexpectedly - prepare: -#- echo "here I can run custom commands, but no preparation needed for this repo" \ No newline at end of file From fae97214a10df27d40b71744f33fd90a8474bdf6 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 22 Feb 2020 20:51:47 +0100 Subject: [PATCH 12/16] refactor APIError Error() method --- client.go | 108 ++++++++++++++++++++++++++----------------------- client_test.go | 20 +++++++++ models.go | 3 +- 3 files changed, 78 insertions(+), 53 deletions(-) diff --git a/client.go b/client.go index f1d3ad62..c07118f4 100644 --- a/client.go +++ b/client.go @@ -58,16 +58,22 @@ func (client *gocloak) getRequestWithBasicAuth(clientID string, clientSecret str httpBasicAuth := base64.URLEncoding.EncodeToString([]byte(clientID + ":" + clientSecret)) req.SetHeader("Authorization", "Basic "+httpBasicAuth) } + return req } func checkForError(resp *resty.Response, err error, errMessage string) error { if err != nil { - return errors.Wrap(err, errMessage) + return &APIError{ + Code: resp.StatusCode(), + Message: errMessage, + } } if resp == nil { - return errors.New("empty response") + return &APIError{ + Message: "empty response", + } } if resp.IsError() { @@ -150,7 +156,7 @@ func (client *gocloak) GetServerInfo(accessToken string) (*ServerInfoRepesentati Get(makeURL(client.basePath, "auth", "admin", "serverinfo")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -166,7 +172,7 @@ func (client *gocloak) GetUserInfo(accessToken string, realm string) (*UserInfo, Get(client.getRealmURL(realm, openIDConnect, "userinfo")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -181,7 +187,7 @@ func (client *gocloak) getNewCerts(realm string) (*CertResponse, error) { Get(client.getRealmURL(realm, openIDConnect, "certs")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -226,7 +232,7 @@ func (client *gocloak) GetIssuer(realm string) (*IssuerResponse, error) { Get(client.getRealmURL(realm)) if err := checkForError(resp, err, err.Error()); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -246,7 +252,7 @@ func (client *gocloak) RetrospectToken(accessToken string, clientID, clientSecre Post(client.getRealmURL(realm, tokenEndpoint, "introspect")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -313,7 +319,7 @@ func (client *gocloak) GetToken(realm string, options TokenOptions) (*JWT, error Post(client.getRealmURL(realm, tokenEndpoint)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &token, nil @@ -430,7 +436,7 @@ func (client *gocloak) CreateGroup(token, realm string, group Group) (string, er Post(client.getAdminRealmURL(realm, "groups")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil } @@ -444,7 +450,7 @@ func (client *gocloak) CreateChildGroup(token string, realm string, groupID stri Post(client.getAdminRealmURL(realm, "groups", groupID, "children")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -458,7 +464,7 @@ func (client *gocloak) CreateComponent(token, realm string, component Component) Post(client.getAdminRealmURL(realm, "components")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -472,7 +478,7 @@ func (client *gocloak) CreateClient(token, realm string, newClient Client) (stri Post(client.getAdminRealmURL(realm, "clients")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -487,7 +493,7 @@ func (client *gocloak) CreateClientRole(token, realm, clientID string, role Role Post(client.getAdminRealmURL(realm, "clients", clientID, "roles")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -502,7 +508,7 @@ func (client *gocloak) CreateClientScope(token, realm string, scope ClientScope) Post(client.getAdminRealmURL(realm, "client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -614,7 +620,7 @@ func (client *gocloak) GetClient(token string, realm string, clientID string) (* Get(client.getAdminRealmURL(realm, "clients", clientID)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -631,7 +637,7 @@ func (client *gocloak) GetClientsDefaultScopes(token string, realm string, clien Get(client.getAdminRealmURL(realm, "clients", clientID, "default-client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -668,7 +674,7 @@ func (client *gocloak) GetClientsOptionalScopes(token string, realm string, clie Get(client.getAdminRealmURL(realm, "clients", clientID, "optional-client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -705,7 +711,7 @@ func (client *gocloak) GetDefaultOptionalClientScopes(token string, realm string Get(client.getAdminRealmURL(realm, "default-optional-client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -722,7 +728,7 @@ func (client *gocloak) GetDefaultDefaultClientScopes(token string, realm string) Get(client.getAdminRealmURL(realm, "default-default-client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -739,7 +745,7 @@ func (client *gocloak) GetClientScope(token string, realm string, scopeID string Get(client.getAdminRealmURL(realm, "client-scopes", scopeID)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -756,7 +762,7 @@ func (client *gocloak) GetClientScopes(token string, realm string) ([]*ClientSco Get(client.getAdminRealmURL(realm, "client-scopes")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -773,7 +779,7 @@ func (client *gocloak) GetClientSecret(token string, realm string, clientID stri Get(client.getAdminRealmURL(realm, "clients", clientID, "client-secret")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -789,7 +795,7 @@ func (client *gocloak) GetClientServiceAccount(token string, realm string, clien Get(client.getAdminRealmURL(realm, "clients", clientID, "service-account-user")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -804,7 +810,7 @@ func (client *gocloak) RegenerateClientSecret(token string, realm string, client Post(client.getAdminRealmURL(realm, "clients", clientID, "client-secret")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -820,7 +826,7 @@ func (client *gocloak) GetClientOfflineSessions(token, realm, clientID string) ( Get(client.getAdminRealmURL(realm, "clients", clientID, "offline-sessions")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return res, nil @@ -836,7 +842,7 @@ func (client *gocloak) GetClientUserSessions(token, realm, clientID string) ([]* Get(client.getAdminRealmURL(realm, "clients", clientID, "user-sessions")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return res, nil @@ -851,7 +857,7 @@ func (client *gocloak) CreateClientProtocolMapper(token, realm, clientID string, Post(client.getAdminRealmURL(realm, "clients", clientID, "protocol-mappers", "models")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -888,7 +894,7 @@ func (client *gocloak) GetKeyStoreConfig(token string, realm string) (*KeyStoreC Get(client.getAdminRealmURL(realm, "keys")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -904,7 +910,7 @@ func (client *gocloak) GetComponents(token string, realm string) ([]*Component, Get(client.getAdminRealmURL(realm, "components")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -956,7 +962,7 @@ func (client *gocloak) getRoleMappings(token string, realm string, path string, Get(client.getAdminRealmURL(realm, path, objectID, "role-mappings")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -983,7 +989,7 @@ func (client *gocloak) GetGroup(token string, realm string, groupID string) (*Gr Get(client.getAdminRealmURL(realm, "groups", groupID)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -1005,7 +1011,7 @@ func (client *gocloak) GetGroups(token string, realm string, params GetGroupsPar Get(client.getAdminRealmURL(realm, "groups")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1027,7 +1033,7 @@ func (client *gocloak) GetGroupMembers(token string, realm string, groupID strin Get(client.getAdminRealmURL(realm, "groups", groupID, "members")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1043,7 +1049,7 @@ func (client *gocloak) GetClientRoles(token string, realm string, clientID strin Get(client.getAdminRealmURL(realm, "clients", clientID, "roles")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1139,7 +1145,7 @@ func (client *gocloak) GetClientRole(token string, realm string, clientID string Get(client.getAdminRealmURL(realm, "clients", clientID, "roles", roleName)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -1160,7 +1166,7 @@ func (client *gocloak) GetClients(token string, realm string, params GetClientsP Get(client.getAdminRealmURL(realm, "clients")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1191,7 +1197,7 @@ func (client *gocloak) CreateRealmRole(token string, realm string, role Role) (s Post(client.getAdminRealmURL(realm, "roles")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -1208,7 +1214,7 @@ func (client *gocloak) GetRealmRole(token string, realm string, roleName string) Get(client.getAdminRealmURL(realm, "roles", roleName)) if err = checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -1224,7 +1230,7 @@ func (client *gocloak) GetRealmRoles(token string, realm string) ([]*Role, error Get(client.getAdminRealmURL(realm, "roles")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1240,7 +1246,7 @@ func (client *gocloak) GetRealmRolesByUserID(token string, realm string, userID Get(client.getAdminRealmURL(realm, "users", userID, "role-mappings", "realm")) if err = checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1255,7 +1261,7 @@ func (client *gocloak) GetRealmRolesByGroupID(token string, realm string, groupI Get(client.getAdminRealmURL(realm, "groups", groupID, "role-mappings", "realm")) if err = checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1360,7 +1366,7 @@ func (client *gocloak) GetRealm(token string, realm string) (*RealmRepresentatio Get(client.getAdminRealmURL(realm)) if err = checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -1376,7 +1382,7 @@ func (client *gocloak) GetRealms(token string) ([]*RealmRepresentation, error) { Get(client.getAdminRealmURL("")) if err = checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1391,7 +1397,7 @@ func (client *gocloak) CreateRealm(token string, realm RealmRepresentation) (str Post(client.getAdminRealmURL("")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil } @@ -1460,7 +1466,7 @@ func (client *gocloak) CreateUser(token string, realm string, user User) (string Post(client.getAdminRealmURL(realm, "users")) if err := checkForError(resp, err, errMessage); err != nil { - return "", errors.Wrap(err, errMessage) + return "", err } return getID(resp), nil @@ -1490,7 +1496,7 @@ func (client *gocloak) GetUserByID(accessToken string, realm string, userID stri Get(client.getAdminRealmURL(realm, "users", userID)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return &result, nil @@ -1522,7 +1528,7 @@ func (client *gocloak) GetUserGroups(token string, realm string, userID string) Get(client.getAdminRealmURL(realm, "users", userID, "groups")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1544,7 +1550,7 @@ func (client *gocloak) GetUsers(token string, realm string, params GetUsersParam Get(client.getAdminRealmURL(realm, "users")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1560,7 +1566,7 @@ func (client *gocloak) GetUsersByRoleName(token string, realm string, roleName s Get(client.getAdminRealmURL(realm, "roles", roleName, "users")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return result, nil @@ -1641,7 +1647,7 @@ func (client *gocloak) GetUserSessions(token, realm, userID string) ([]*UserSess Get(client.getAdminRealmURL(realm, "users", userID, "sessions")) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return res, nil @@ -1657,7 +1663,7 @@ func (client *gocloak) GetUserOfflineSessionsForClient(token, realm, userID, cli Get(client.getAdminRealmURL(realm, "users", userID, "offline-sessions", clientID)) if err := checkForError(resp, err, errMessage); err != nil { - return nil, errors.Wrap(err, errMessage) + return nil, err } return res, nil diff --git a/client_test.go b/client_test.go index 11853fd9..71862dd7 100644 --- a/client_test.go +++ b/client_test.go @@ -3308,3 +3308,23 @@ func TestGocloak_CreateListGetUpdateDeletePermission(t *testing.T) { assert.NoError(t, err, "GetPermission failed") assert.Equal(t, *(createdPermission.Name), *(updatedPermission.Name)) } + +func TestGoCloak_CheckError(t *testing.T) { + t.Parallel() + cfg := GetConfig(t) + client := NewClientWithDebug(t) + token := GetAdminToken(t, client) + + _, err := client.GetClient(token.AccessToken, cfg.Admin.Realm, "random_client") + assert.Error(t, err) + + t.Log(err) + + expectedError := &APIError{ + Code: http.StatusNotFound, + Message: "404 Not Found: Could not find client", + } + + apiError := err.(*APIError) + assert.Equal(t, expectedError, apiError) +} diff --git a/models.go b/models.go index e563b095..041d4c0e 100644 --- a/models.go +++ b/models.go @@ -2,7 +2,6 @@ package gocloak import ( "encoding/json" - "strconv" "strings" ) @@ -63,7 +62,7 @@ type APIError struct { // Error stringifies the APIError func (apiError APIError) Error() string { - return "Code: " + strconv.Itoa(apiError.Code) + " Message: " + apiError.Message + return apiError.Message } // CertResponseKey is returned by the certs endpoint From 0ec9891c2a72c866bd70a533bd88a70b519d90b1 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 22 Feb 2020 21:28:18 +0100 Subject: [PATCH 13/16] fixed readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0381c347..ed4c06ad 100644 --- a/README.md +++ b/README.md @@ -255,10 +255,10 @@ docker run -d \ -e KEYCLOAK_USER=admin \ -e KEYCLOAK_PASSWORD=secret \ -e KEYCLOAK_IMPORT=/tmp/gocloak-realm.json \ - -v `pwd`/testdata/gocloak-realm.json:/tmp/gocloak-realm.json \ + -v "`pwd`/testdata/gocloak-realm.json:/tmp/gocloak-realm.json" \ -p 8080:8080 \ --name gocloak-test \ - quay.io/keycloak/keycloak + quay.io/keycloak/keycloak:latest -Dkeycloak.profile.feature.upload_scripts=enabled go test ``` From 14c91d737e2e3ee5449d69c200a049cf49949dd4 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 22 Feb 2020 21:32:05 +0100 Subject: [PATCH 14/16] set code to 0 if no response was returned --- client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.go b/client.go index c07118f4..e851b2e2 100644 --- a/client.go +++ b/client.go @@ -65,7 +65,7 @@ func (client *gocloak) getRequestWithBasicAuth(clientID string, clientSecret str func checkForError(resp *resty.Response, err error, errMessage string) error { if err != nil { return &APIError{ - Code: resp.StatusCode(), + Code: 0, Message: errMessage, } } From cb245ddf8ba284429555fe16aea70b5fe085f0cc Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 22 Feb 2020 21:34:52 +0100 Subject: [PATCH 15/16] fix getIssuer --- client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.go b/client.go index e851b2e2..cfea5c70 100644 --- a/client.go +++ b/client.go @@ -231,7 +231,7 @@ func (client *gocloak) GetIssuer(realm string) (*IssuerResponse, error) { SetResult(&result). Get(client.getRealmURL(realm)) - if err := checkForError(resp, err, err.Error()); err != nil { + if err := checkForError(resp, err, errMessage); err != nil { return nil, err } From c4977b4348c496cfef3533194a570f7f710dd9d8 Mon Sep 17 00:00:00 2001 From: Tobias Theel Date: Sat, 22 Feb 2020 21:40:20 +0100 Subject: [PATCH 16/16] fix setuptestuser --- client_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client_test.go b/client_test.go index 8969cf3b..cc62e246 100644 --- a/client_test.go +++ b/client_test.go @@ -306,8 +306,8 @@ func SetUpTestUser(t testing.TB, client GoCloak) { user, ) - apiError := err.(*APIError) - if apiError.Code == http.StatusConflict { + apiError, ok := err.(*APIError) + if ok && apiError.Code == http.StatusConflict { users, err := client.GetUsers( token.AccessToken, cfg.GoCloak.Realm,