diff --git a/api/go.mod b/api/go.mod index 534f7140f9c0d..efcde1d3b4ef7 100644 --- a/api/go.mod +++ b/api/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/gogo/protobuf v1.3.2 github.com/google/go-cmp v0.5.7 - github.com/gravitational/trace v1.1.17 + github.com/gravitational/trace v1.2.0 github.com/jonboulle/clockwork v0.2.2 github.com/russellhaering/gosaml2 v0.6.1-0.20210916051624-757d23f1bc28 github.com/sirupsen/logrus v1.8.1 diff --git a/api/go.sum b/api/go.sum index f158c4a5b6c2b..24d61185ec74f 100644 --- a/api/go.sum +++ b/api/go.sum @@ -136,8 +136,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gravitational/trace v1.1.17 h1:BkF30oLm1aKMZ5SPVbnlVbYtYEsG26zHxA4dJ+Z46dM= -github.com/gravitational/trace v1.1.17/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= +github.com/gravitational/trace v1.2.0 h1:ODrkITHAmumFOTgCLb2zScMRCT2VQVXyIzDpN2CyN6s= +github.com/gravitational/trace v1.2.0/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= diff --git a/go.mod b/go.mod index 7dc689aa85c42..e3ac7e299fba6 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,7 @@ require ( github.com/gravitational/reporting v0.0.0-20210923183620-237377721140 github.com/gravitational/roundtrip v1.0.1 github.com/gravitational/teleport/api v0.0.0 - github.com/gravitational/trace v1.1.19-0.20220627095334-f3550c86f648 + github.com/gravitational/trace v1.2.0 github.com/gravitational/ttlmap v0.0.0-20171116003245-91fd36b9004c github.com/grpc-ecosystem/go-grpc-middleware/providers/openmetrics/v2 v2.0.0-20220308023801-e4a6915ea237 github.com/hashicorp/golang-lru v0.5.4 diff --git a/go.sum b/go.sum index 79d6d555d02a4..fada5c88e7e0b 100644 --- a/go.sum +++ b/go.sum @@ -606,8 +606,8 @@ github.com/gravitational/roundtrip v1.0.1/go.mod h1:qccpLd30tAJVSpx7aOEEnws4ZT3n github.com/gravitational/sftp v1.13.6-0.20220706192634-fe0df089a5e3 h1:D6um8saAfTIVcD3iyeXZw6YPSkZXEkaRH8qNmICL7LA= github.com/gravitational/sftp v1.13.6-0.20220706192634-fe0df089a5e3/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf/go.mod h1:zXqxTI6jXDdKnlf8s+nT+3c8LrwUEy3yNpO4XJL90lA= -github.com/gravitational/trace v1.1.19-0.20220627095334-f3550c86f648 h1:077EB1f9UVtnwjyVR+IiVB9Dls4YAKLjhtY9xBggMp8= -github.com/gravitational/trace v1.1.19-0.20220627095334-f3550c86f648/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= +github.com/gravitational/trace v1.2.0 h1:ODrkITHAmumFOTgCLb2zScMRCT2VQVXyIzDpN2CyN6s= +github.com/gravitational/trace v1.2.0/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= github.com/gravitational/ttlmap v0.0.0-20171116003245-91fd36b9004c h1:C2iWDiod8vQ3YnOiCdMP9qYeg2UifQ8KSk36r0NswSE= github.com/gravitational/ttlmap v0.0.0-20171116003245-91fd36b9004c/go.mod h1:erKVikttPjeHKDCQZcqowEqiccy23cJAqPadZgfjNm8= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 2a5e77dbfb51e..c572f9fa1fd98 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -1509,16 +1509,14 @@ func (a *Server) WithUserLock(username string, authenticateFn func() error) erro user.GetName(), defaults.MaxAccountRecoveryAttempts, apiutils.HumanTimeFormat(status.RecoveryAttemptLockExpires)) err := trace.AccessDenied(MaxFailedAttemptsErrMsg) - err.AddField(ErrFieldKeyUserMaxedAttempts, true) - return err + return trace.WithField(err, ErrFieldKeyUserMaxedAttempts, true) } if status.LockExpires.After(a.clock.Now().UTC()) { log.Debugf("%v exceeds %v failed login attempts, locked until %v", user.GetName(), defaults.MaxLoginAttempts, apiutils.HumanTimeFormat(status.LockExpires)) err := trace.AccessDenied(MaxFailedAttemptsErrMsg) - err.AddField(ErrFieldKeyUserMaxedAttempts, true) - return err + return trace.WithField(err, ErrFieldKeyUserMaxedAttempts, true) } } fnErr := authenticateFn() @@ -1562,8 +1560,7 @@ func (a *Server) WithUserLock(username string, authenticateFn func() error) erro } retErr := trace.AccessDenied(MaxFailedAttemptsErrMsg) - retErr.AddField(ErrFieldKeyUserMaxedAttempts, true) - return retErr + return trace.WithField(retErr, ErrFieldKeyUserMaxedAttempts, true) } // PreAuthenticatedSignIn is for MFA authentication methods where the password diff --git a/lib/auth/github.go b/lib/auth/github.go index 666b07dc1307b..f060e59aa3762 100644 --- a/lib/auth/github.go +++ b/lib/auth/github.go @@ -282,19 +282,20 @@ func (a *Server) validateGithubAuthCallback(ctx context.Context, diagCtx *ssoDia // optional parameter: error_description errDesc := q.Get("error_description") - return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, errParam, q).AddUserMessage("Github returned error: %v [%v]", errDesc, errParam) + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, errParam, q) + return nil, trace.WithUserMessage(oauthErr, "Github returned error: %v [%v]", errDesc, errParam) } code := q.Get("code") if code == "" { - return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, - "code query param must be set", q).AddUserMessage("Invalid parameters received from Github.") + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, "code query param must be set", q) + return nil, trace.WithUserMessage(oauthErr, "Invalid parameters received from Github.") } stateToken := q.Get("state") if stateToken == "" { - return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, - "missing state query param", q).AddUserMessage("Invalid parameters received from Github.") + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, "missing state query param", q) + return nil, trace.WithUserMessage(oauthErr, "Invalid parameters received from Github.") } diagCtx.requestID = stateToken diff --git a/lib/auth/oidc.go b/lib/auth/oidc.go index 5059507982170..b7c64d2f68c0f 100644 --- a/lib/auth/oidc.go +++ b/lib/auth/oidc.go @@ -411,19 +411,20 @@ func (a *Server) validateOIDCAuthCallback(ctx context.Context, diagCtx *ssoDiagC // optional parameter: error_description errDesc := q.Get("error_description") - return nil, trace.OAuth2(oauth2.ErrorInvalidRequest, errParam, q).AddUserMessage("OIDC provider returned error: %v [%v]", errDesc, errParam) + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, errParam, q) + return nil, trace.WithUserMessage(oauthErr, "OIDC provider returned error: %v [%v]", errDesc, errParam) } code := q.Get("code") if code == "" { - return nil, trace.OAuth2( - oauth2.ErrorInvalidRequest, "code query param must be set", q).AddUserMessage("Invalid parameters received from OIDC provider.") + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, "code query param must be set", q) + return nil, trace.WithUserMessage(oauthErr, "Invalid parameters received from OIDC provider.") } stateToken := q.Get("state") if stateToken == "" { - return nil, trace.OAuth2( - oauth2.ErrorInvalidRequest, "missing state query param", q).AddUserMessage("Invalid parameters received from OIDC provider.") + oauthErr := trace.OAuth2(oauth2.ErrorInvalidRequest, "missing state query param", q) + return nil, trace.WithUserMessage(oauthErr, "Invalid parameters received from OIDC provider.") } diagCtx.requestID = stateToken @@ -485,8 +486,8 @@ func (a *Server) validateOIDCAuthCallback(ctx context.Context, diagCtx *ssoDiagC log.Debugf("OIDC user %q expires at: %v.", ident.Email, ident.ExpiresAt) if len(connector.GetClaimsToRoles()) == 0 { - return nil, trace.BadParameter("no claims to roles mapping, check connector documentation"). - AddUserMessage("Claims-to-roles mapping is empty, SSO user will never have any roles.") + badParamErr := trace.BadParameter("no claims to roles mapping, check connector documentation") + return nil, trace.WithUserMessage(badParamErr, "Claims-to-roles mapping is empty, SSO user will never have any roles.") } log.Debugf("Applying %v OIDC claims to roles mappings.", len(connector.GetClaimsToRoles())) diagCtx.info.OIDCClaimsToRoles = connector.GetClaimsToRoles() diff --git a/lib/auth/saml.go b/lib/auth/saml.go index e96c67353bb44..f91380ac4abf3 100644 --- a/lib/auth/saml.go +++ b/lib/auth/saml.go @@ -474,7 +474,8 @@ func (a *Server) validateSAMLResponse(ctx context.Context, diagCtx *ssoDiagConte assertionInfo, err := provider.RetrieveAssertionInfo(samlResponse) if err != nil { - return nil, trace.AccessDenied("received response with incorrect or missing attribute statements, please check the identity provider configuration to make sure that mappings for claims/attribute statements are set up correctly. , failed to retrieve SAML assertion info from response: %v.", err).AddUserMessage("Failed to retrieve assertion info. This may indicate IdP configuration error.") + errAccessDenied := trace.AccessDenied("received response with incorrect or missing attribute statements, please check the identity provider configuration to make sure that mappings for claims/attribute statements are set up correctly. , failed to retrieve SAML assertion info from response: %v.", err) + return nil, trace.WithUserMessage(errAccessDenied, "Failed to retrieve assertion info. This may indicate IdP configuration error.") } if assertionInfo != nil { @@ -492,11 +493,13 @@ func (a *Server) validateSAMLResponse(ctx context.Context, diagCtx *ssoDiagConte } if assertionInfo.WarningInfo.InvalidTime { - return nil, trace.AccessDenied("invalid time in SAML assertion info").AddUserMessage("SAML assertion info contained warning: invalid time.") + errAccessDenied := trace.AccessDenied("invalid time in SAML assertion info") + return nil, trace.WithUserMessage(errAccessDenied, "SAML assertion info contained warning: invalid time.") } if assertionInfo.WarningInfo.NotInAudience { - return nil, trace.AccessDenied("no audience in SAML assertion info").AddUserMessage("SAML: not in expected audience. Check auth connector audience field and IdP configuration for typos and other errors.") + errAccessDenied := trace.AccessDenied("no audience in SAML assertion info") + return nil, trace.WithUserMessage(errAccessDenied, "SAML: not in expected audience. Check auth connector audience field and IdP configuration for typos and other errors.") } log.Debugf("Obtained SAML assertions for %q.", assertionInfo.NameID) @@ -517,7 +520,8 @@ func (a *Server) validateSAMLResponse(ctx context.Context, diagCtx *ssoDiagConte diagCtx.info.SAMLAttributesToRoles = connector.GetAttributesToRoles() if len(connector.GetAttributesToRoles()) == 0 { - return nil, trace.BadParameter("no attributes to roles mapping, check connector documentation").AddUserMessage("Attributes-to-roles mapping is empty, SSO user will never have any roles.") + errBadParam := trace.BadParameter("no attributes to roles mapping, check connector documentation") + return nil, trace.WithUserMessage(errBadParam, "Attributes-to-roles mapping is empty, SSO user will never have any roles.") } log.Debugf("Applying %v SAML attribute to roles mappings.", len(connector.GetAttributesToRoles())) diff --git a/lib/services/lock.go b/lib/services/lock.go index aac395449c2e4..a3aa4bce1b2d7 100644 --- a/lib/services/lock.go +++ b/lib/services/lock.go @@ -35,8 +35,7 @@ func LockInForceAccessDenied(lock types.Lock) error { s += ": " + msg } err := trace.AccessDenied(s) - err.AddField("lock-in-force", lock) - return err + return trace.WithField(err, "lock-in-force", lock) } // StrictLockingModeAccessDenied is an AccessDenied error returned when strict