Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any example how to use updateOwn? #4

Closed
bhargav-sae opened this issue Apr 26, 2017 · 5 comments
Closed

Is there any example how to use updateOwn? #4

bhargav-sae opened this issue Apr 26, 2017 · 5 comments
Labels
question A question rather than an issue.

Comments

@bhargav-sae
Copy link

Could you provide any example how to use updateOwn?

@onury
Copy link
Owner

onury commented Apr 26, 2017

Sure.

Scenario: Role "user" can read any photo resource but update own photos only.

Example:

Define Access Permissions

var ac = new AccessControl();
ac.grant('user')
    .readAny('photo', ['*', '!id'])
    .updateOwn('photo', ['*', '!id']);

Note that the user can only update own photo resource but cannot alter the id of the photo resource, even if its own photo.

Define App Routes

For an express.js app, we'll define 2 routes for the photo resource.

1. Any-photo route: GET /photos/:id

    router.get('/photos/:id', function (req, res, next) {
        var permission = ac.can(req.user.role).readAny('photo');
        if (permission.granted) {
            Photo.find({ id: req.params.id }, function (err, data) {
                if (err || !data) return res.status(404).end();
                // filter data by permission attributes and send.
                res.json(permission.filter(data)); // .id is filtered out
            });
        } else {
            // resource is forbidden for this user/role
            res.status(403).end();
        }
    });

2. Own-photo route: PUT /users/:username/photos/:id

    router.put('/users/:username/photos/:id', function (req, res, next) {
        var role = req.user.role;
        // check if the request is for own photos or any
        var permission = (req.user.name === req.params.username)
            ? ac.can(role).updateOwn('photo')
            : ac.can(role).updateAny('photo');
        
        if (permission.granted) {
            // we filter the posted request body so that only 
            // allowed attributes are used to update the resource.
            var sanitizedData = permission.filter(req.body); // .id is filtered out
            Photo.update(req.params, sanitizedData, function (err, result) {
                // either send 404 if not found or 5xx if a server/database error
                if (err || !result) return res.status(404).end();
                res.json(result);
            });
        } else {
            res.status(403).end(); // forbidden
        }
    });

Hope this makes it clear for you.

@onury onury added the question A question rather than an issue. label Apr 26, 2017
@bhargav-sae
Copy link
Author

I believe for this you have to include :username in route.
what if I do not have any :username in route? for example PUT /photos/:id

@onury
Copy link
Owner

onury commented Apr 28, 2017

That's a design decision. I gave you just one scenario. What you're asking is a question for REST API design.

AccessControl only tells you whether a specific role is authorized to access own/any resource(s). It has no information (or goal) to check whether the actual resource (the record) is owned by a specific, actual user.

It only checks if an action is allowed on "own" (or "any") resource. This is by definition.

The route /photos/:id has no claim of a resource owner (implicit role) in the query params (and probably none in req body). So your middleware should get the original resource owner itself and determine whether this is a request for an own resource. If so, AC can check whether that role can actually preform that action on own resource.

In other words,

  • identifying whether an actual request is for an owned resource
  • checking whether a role can perform some action on own resource(s)

are two different things.

@onury onury closed this as completed Apr 28, 2017
@bhargav-sae
Copy link
Author

@onury alright, thanks for quick replies.

@Vishwas-75
Copy link

updateOwn it should throw an error if req. body consists of inaccessible attributes .
@onury

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question A question rather than an issue.
Projects
None yet
Development

No branches or pull requests

3 participants