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

How to allow anonymous access to some resources #3

Open
iotaweb opened this issue Jan 5, 2014 · 2 comments
Open

How to allow anonymous access to some resources #3

iotaweb opened this issue Jan 5, 2014 · 2 comments

Comments

@iotaweb
Copy link

iotaweb commented Jan 5, 2014

OK, I hope this is my last question about authorisation :)

How would I go about providing anonymous to some resources, while securing others. Or indeed, only protecting some actions, e.g. create, update and destroy whilst allowing anonymous access to load and views.

As your library takes care of the route configuration, I'm not sure how to handle these exceptions. An thoughts or ideas much appreciated.

Cheers, Rob

@iotaweb
Copy link
Author

iotaweb commented Jan 7, 2014

Further to this, I have made some modest progress on my own here:

iotaweb@db1e6fd

The approach is to use the auth: { mode: 'try' } route option to allow either anonymous or authenticated access to endpoints. I've then modified the permissions check method to grab the default permissions for anonymous users from the resource schemas additionalProperties, e.g.

Permissions.prototype.check = function(request, resource, action) {

    if (!this.auth) {
        // resource not secured
        return Q.resolve();
    } else {
        if (request.auth.isAuthenticated && request.auth.credentials.permissions) {
            // authenticated users
            var permissions = request.auth.credentials.permissions[resource.name];
        } else  {
            // anonymous users
            var permissions = resource.schema._options.additionalProperties.value.permissions || {};
        }
    }

    if (permissions && permissions[action]) {
        // permission granted
        return Q.resolve();
    }

    var err = new Error('Permission denied');

    err.code = 401;
    return Q.reject(err);
};

An example of default permissions is shown below:

// Load modules

var J = require('jski')();


// Define Page schema

module.exports = J
    .object({
        userId: J.string(),
        title: J.string().minLength(3)
    })
    .title('Page')
    .required('userId', 'title')
    .additionalProperties({
        permissions: {
            load: true,
            create: false,
            update: false,
            destroy: false,
            views: true
        }
    });

This approach seems to be working for me so far and allows for a default set of permissions for each resource that determines what anonymous users can do, but can be superseded by permissions supplied by authenticated user credentials.

I'm keen for any comments on the suitability of this approach, and appreciate it may be outside of where you want to position cores-hapi.

My next task is to look into additional actions for users that permit them to only access/modify their own resources, e.g. something like...

permissions: {
    load: false,
    loadOwn: true,
    create: false,
    createOwn: true,
    update: false,
    updateOwn: true,
    destroy: false,
    destroyOwn: true,
    views: false,
    viewsOwn: true
}

But this doesn't seem right as these additional actions are not mutually exclusive, i.e. load: true would imply loadOwn: true. Any thoughts or suggestions on a better way? This is logged as a separate issue here: #2

@tillre
Copy link
Owner

tillre commented Jan 9, 2014

It would be nice to have finer grained control. We could make the permission check function customizable, so anyone could define their own methods.

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

No branches or pull requests

2 participants