Giter Club home page Giter Club logo

Comments (11)

ricardobeat avatar ricardobeat commented on May 3, 2024

That does looks nice. The complexity of having it's own parser is a bit daunting though. After scouring over NPM, these strike me as simple and effective:

https://github.com/arlac77/entitlement
https://github.com/pvencill/nod

Permissions could be implemented in ghost's own model layer too, the maintenance burden would be roughly the same.

from ghost.

jgable avatar jgable commented on May 3, 2024

node-relations natural language stuff looks interesting, but I'm worried about how it would scale if you have multiple servers. We'd also likely have to write a sqlite store for it.

Nod and entitlement kind of worries me because it doesn't have an extensible data store architecture; looks like it's just in memory. But I like the look and feel of the code for entitlement more than nod.

Just my 2 cents.

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

Starting to flesh out ACL concepts on the wiki ACL

from ghost.

tgriesser avatar tgriesser commented on May 3, 2024

As @ricardobeat mentioned, this stuff could be defined as ACL as methods on the models, so you'd be able to do something like:

Post = Bookshelf.Model.extend({
  ...

  canBeEditedBy: function (user) {
     if (user.get('role') === 'ghostAdmin') {
        return true;
     }
     if (user.get('role') === 'user') {
        if (_.inArray(this.related('authored_posts').pick('id'), this.id) {
           return true
        }
     }
     return when.reject(new Error('Unable to access this post'));
  },

  canBeCreatedBy: function () {
    ...
  }

})

and then something like:

when(post.canBeEditedBy(user)).then(function() {
  ...
})

This would allow us to define a base set of ACL pieces, similar to the base model, and then allow us to override per model. You'd also rely on passing in the user object, so you could define different settings as an ACL table per-user, and then determine how the different models interpret the different settings... and you'd probably want to use promises since different validations may or may not need async stuff.

Just a suggestion, I've used this approach before and it seems to work alright.

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

I think the ACL needs to operate on, but be separate to the models.

We want to be able to support really complex workflows in the future. The advanced case being that a user/role may only be able to make certain post state transitions (i.e draft -> complete) but transitions may be dynamically defined. Looking at the libraries out there, we may have to build our own to accomplish this particular feature in a really nice way.

I'd also like to allow for the more advanced case that a user has a permission, rather than a specific role.
Additionally we should be able to cater for rules which don't apply to a model - for example access to a page in the admin system which is not defined by any model or the ability to view a specific dashboard widget.

Although a lot of these features are far down the roadmap, we do need to keep them in mind whilst implementing the ACL now, so that we can lock it down to something simple, and open it up both in core and to plugins in the near future.

Most importantly, defining rules on the model as suggested makes them very complex to understand and to debug. The rules should be clearly defined in a standardised format in one place.

See Wiki:ACL for the beginnings of a spec and Telescope: ACL: User Roles for some discussion on this.

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

The discussion on this both in telescope and here seems to have died. Is there something I can provide to make this easier? Should we just pick a package and have a stab at implementing it?

I think that the set of permissions documented for posts is reasonably sane:

  • X can browse posts Y - special case that there are no posts X can browse?
  • X can read post Y - these two are probably the same thing
  • X can create post
  • X can edit posts Y
  • X can change state of post Y to Z < this is quite complex and probably needs to be implemented as X can change state of post Y AND X can do action Z
  • X can delete post Y

I think we also need to consider the first permission, of whether or not X can browse posts Y in more detail
Whether or not a user can browse/read a post will depend on the state of the post - is it published / draft etc. I'm not sure if there is any other limiting feature.

There may also be rules around ownership - so an author can only edit their own posts, but an editor can edit any.

From telescope, the current idea is to have 3 user roles:

  • admin - full perms
  • editor - post only perms
  • author - very locked down post perms

Any more thoughts on what the best package might be?

from ghost.

jgable avatar jgable commented on May 3, 2024

I started putting together a little implementation of this with the following goals:

  • Separate from Models
  • Uses the entitlement module
  • Syntax something like permissions.canThis(someUser).edit.posts().then(function() { or permissions.allowThis(someUser).to.edit.posts().then(function() { ... })

Just trying to get something together for you to take a look at right now.

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

Not sure where to best continue discussing this. The following is very much half-baked thoughts:

At the moment, permissions are built around an action type, object type and optional object id. Objects may or may not be bookshelf models. The canThis syntax takes an action, and then the object type and can be passed a model, or an id, and there's also the concept of multiples mentioned in the comments.

If you pass it an id (set of ids), then we check this against the object ids in permissions. If you pass it a model then we get the id from the model and do the same.

What I'm thinking / wondering is if we could change the behaviour for if it's a model slightly.. we could try to test if there's a direct match for the model id.. but if not we could see if the model we're passed has a function we can call like.. post.canBeEditedBy(userOrUserId).. so we compose a function from the action, if the function exists we expect a boolean response.

This gives us tonnes of flexibility and I think is just a small extension of what we already have?

But I literally dreamt this up on the way to work this morning and haven't thought it through. If we can do something like this, it's way more useful & higher priority than the fancy allow syntax (which is cool though :) ).

from ghost.

jgable avatar jgable commented on May 3, 2024

I think that's a neat idea. The canBeEditedBy might be hard to implement as a dynamic thing, but I like the idea of a standard interface for extending permissions.

How about calling it a Permissable interface? Each model that wants to opt-in to the extended permissions checking can implement something like

ModelThingy = Ghost.BookShelf.extend({

  permissable: function (objectIdOrModel, actionType) { ... }

});

It should return a promise and have its own logic for checking stuff. I can work that in to the canThis flow pretty easily. I'll start putting something together unless I hear otherwise.

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

That sounds amazing!

from ghost.

ErisDS avatar ErisDS commented on May 3, 2024

So we now have an ACL library in place, all we need to do I think is hook it up and that can all be done in separate issues :) Really love this so far 👍

from ghost.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.