Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

helpers: Improve ACL asserts #15

Merged
merged 2 commits into from
Jun 12, 2014
Merged

Conversation

bajtos
Copy link
Contributor

@bajtos bajtos commented Jun 9, 2014

Modify _it.shouldBeAllowed to include the actual status code
in the assertion error.

Modify _it.shouldBeDenied to assert the exact value of the status
code. Expect the status code configured via app.get('aclErrorStatus'),
add a parameter allowing callers to override this value.

Allow tests to send arbitrary request body in the requests being tested. This is needed for loopback tests of User.create to pass valid User data in order to prevent 422 validation error.

This is a follow-up for #12.

/to @ritch please review
/cc @karlmikko

@bajtos
Copy link
Contributor Author

bajtos commented Jun 9, 2014

Added one more commit to allow tests to send arbitrary request body in the requests being tested. This is needed for loopback tests of User.create to pass valid User data in order to prevent 422 validation error.

@bajtos
Copy link
Contributor Author

bajtos commented Jun 10, 2014

I decided to change the way how the custom ACL error status code is configured and use test context instead of function parameter.

describe('/users', function() {
  beforeEach(function() {
    this.aclErrorStatus = app.models.User.settings.aclErrorStatus;
  });

  lt.it.shouldBeDeniedWhenCalledAnonymously('GET', urlForUser);
  lt.it.shouldBeDeniedWhenCalledUnauthenticated('GET', urlForUser);
  //...
});

@ritch
Copy link
Contributor

ritch commented Jun 10, 2014

I could see that the two modules may get out of sync in the future.

This is a good point. As long as our tests fail when this happens it will be easy to fix though. A bigger concern is using incompatible versions, but that isn't isolated to this feature and its part of on going discussions around peer dependencies. A solution there would put my mind at ease about this example of modules getting out of sync.

_it.shouldBeStatus(401)

I'd take a patch for this and other helper methods like it. But I wouldn't use this over _it.shouldBeAllowed(). The idea is that you are testing the access control, not the HTTP response status code. If your API specifies that a given request should return a status code, you should assert that in another test. LoopBack's access control must be flexible to end application requirements. Something like this seems pretty clean to me:

lt.describe.whenCalledRemotely('GET', '/my-models', function() {
  lt.it.shouldBeDenied();
  lt.it.shouldBeStatus(483);
});

@bajtos We could make this a bit more explicit from the loopback side by setting:

X-Access-Control-Status: DENY

when an access control denies a request. Then we would assert that this header exists and is set to the given value. The status code would not be checked in the shouldBeAllowed() / shouldBeDenied() tests.

@ritch
Copy link
Contributor

ritch commented Jun 10, 2014

This is good to merge. 👍

@karlmikko
Copy link

/to @ritch
/cc @bajtos

In strongloop/loopback#301 we discuss sending 404 as a configurable option for ACL failure. In this case you wouldn't want to send X-Access-Control-Status: DENY as it would give away the resource actually exists, defeating the purpose of sending 404.

I am going to work on this PR tomorrow (it is 3am for me now), do you want me to include this header also?

@ritch
Copy link
Contributor

ritch commented Jun 10, 2014

@karlmikko
@bajtos

Actually, we should include it in the body / error object and enable it only when loopback is configured to show detailed errors (eg. not in production). This is similar behavior as showing stack traces in error messages, so it should use the same setting, or otherwise easy to configure both.

@bajtos
Copy link
Contributor Author

bajtos commented Jun 12, 2014

@ritch @karlmikko

I have created a new issue to discuss the compatibility check: #18.

_it.shouldBeStatus(401)

I'd take a patch for this and other helper methods like it. But I wouldn't use this over _it.shouldBeAllowed(). The idea is that you are testing the access control, not the HTTP response status code. If your API specifies that a given request should return a status code, you should assert that in another test. LoopBack's access control must be flexible to end application requirements.

I agree the test code should say "I am testing the access control" and use shouldBeAllowed and shouldBeDenied. Under the hood, these two methods must take great care to interpret the responses correctly and pass only when the request was truly allowed or denied. It should also infer as much information from the app config as possible, so that the test code does not need to include specific status codes. That is the intention of my patch - you write _it.shouldBeDenied and the test passes only if the response indicates the ACL engine rejected the request.

@karlmikko In strongloop/loopback#301 we discuss sending 404 as a configurable option for ACL failure. In this case you wouldn't want to send X-Access-Control-Status: DENY as it would give away the resource actually exists, defeating the purpose of sending 404.

@ritch Actually, we should include it in the body / error object and enable it only when loopback is configured to show detailed errors (eg. not in production). This is similar behavior as showing stack traces in error messages, so it should use the same setting, or otherwise easy to configure both.

As far as I am concerned, 301 can be landed without X-Access-Control-Status header or sending the ACL result in the error details, as that can be implemented later in a new pull request.

Here is my proposal: either move this discussion to loopback#301 or create a new issue in loopback repository to track the additional feature request.

Miroslav Bajtoš added 2 commits June 12, 2014 10:14
Modify `_it.shouldBeAllowed` to include the actual status code
in the assertion error.

Modify `_it.shouldBeDenied` to assert the exact value of the status
code. Expect the status code configured via `app.get('aclErrorStatus')`,
add a parameter allowing callers to override this value.
Allow tests to send arbitrary request body in the requests being tested.
bajtos added a commit that referenced this pull request Jun 12, 2014
@bajtos bajtos merged commit 57df074 into master Jun 12, 2014
@bajtos bajtos deleted the feature/improve-access-checks branch June 12, 2014 08:15
@karlmikko
Copy link

+1 move to 301 as it is all tied up with that issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants