NotAuthorizedErrorTest runs the given method with an authorizer that will fail authz. Asserts that the error returned is a NotAuthorizedError.
(ctx context.Context, az *coderdtest.FakeAuthorizer, testCase expects, callMethod func(ctx context.Context) ([]reflect.Value, error))
| 340 | // NotAuthorizedErrorTest runs the given method with an authorizer that will fail authz. |
| 341 | // Asserts that the error returned is a NotAuthorizedError. |
| 342 | func (s *MethodTestSuite) NotAuthorizedErrorTest(ctx context.Context, az *coderdtest.FakeAuthorizer, testCase expects, callMethod func(ctx context.Context) ([]reflect.Value, error)) { |
| 343 | s.Run("NotAuthorized", func() { |
| 344 | az.AlwaysReturn(rbac.ForbiddenWithInternal(xerrors.New("Always fail authz"), rbac.Subject{}, "", rbac.Object{}, nil)) |
| 345 | // Override the SQL filter to always fail. |
| 346 | az.OverrideSQLFilter("FALSE") |
| 347 | |
| 348 | // If we have assertions, that means the method should FAIL |
| 349 | // if RBAC will disallow the request. The returned error should |
| 350 | // be expected to be a NotAuthorizedError. |
| 351 | resp, err := callMethod(ctx) |
| 352 | |
| 353 | // This is unfortunate, but if we are using `Filter` the error returned will be nil. So filter out |
| 354 | // any case where the error is nil and the response is an empty slice. |
| 355 | if err != nil || !hasEmptyResponse(resp) { |
| 356 | // Expect the default error |
| 357 | if testCase.notAuthorizedExpect == "" { |
| 358 | s.ErrorContainsf(err, "unauthorized", "error string should have a good message") |
| 359 | s.Errorf(err, "method should an error with disallow authz") |
| 360 | s.ErrorAs(err, &dbauthz.NotAuthorizedError{}, "error should be NotAuthorizedError") |
| 361 | } else { |
| 362 | s.ErrorContains(err, testCase.notAuthorizedExpect) |
| 363 | } |
| 364 | } |
| 365 | }) |
| 366 | |
| 367 | s.Run("Canceled", func() { |
| 368 | // Pass in a canceled context |
| 369 | ctx, cancel := context.WithCancel(ctx) |
| 370 | cancel() |
| 371 | az.AlwaysReturn(rbac.ForbiddenWithInternal(&topdown.Error{Code: topdown.CancelErr}, |
| 372 | rbac.Subject{}, "", rbac.Object{}, nil)) |
| 373 | |
| 374 | // If we have assertions, that means the method should FAIL |
| 375 | // if RBAC will disallow the request. The returned error should |
| 376 | // be expected to be a NotAuthorizedError. |
| 377 | resp, err := callMethod(ctx) |
| 378 | |
| 379 | // This is unfortunate, but if we are using `Filter` the error returned will be nil. So filter out |
| 380 | // any case where the error is nil and the response is an empty slice or int64(0). |
| 381 | if err != nil || !hasEmptyResponse(resp) { |
| 382 | if testCase.cancelledCtxExpect == "" { |
| 383 | s.Errorf(err, "method should an error with cancellation") |
| 384 | s.ErrorIsf(err, context.Canceled, "error should match context.Canceled") |
| 385 | } else { |
| 386 | s.ErrorContains(err, testCase.cancelledCtxExpect) |
| 387 | } |
| 388 | } |
| 389 | }) |
| 390 | } |
| 391 | |
| 392 | func hasEmptyResponse(values []reflect.Value) bool { |
| 393 | for _, r := range values { |
no test coverage detected