Rails Object Based Permission/Authorization Engine

Serve confident files in a RESTful API (Rails/Paperclip)

For object/model-level authorization of those objects, take a look at canable, rails_authorization in ruby toolbox, and the following questions:

  • CRUD Ownership of Items/Microposts in Rails App
  • Rails object based permission/authorization engine?

If you have trouble with Paperclip, you could take a look at carrierwave or something else from rails_file_uploads in ruby toolbox. Carrierwave has support for storage on filesystem, in DB, or DB-managed filesystem storage (like large object support in carrierwave-postgresql, if you were using postgres).

Best Role-Based Access Control (RBAC) database model

To my rather basic knowledge in that area, the basic actors of an RBAC are:

  • Resources.
  • Permissions.
  • Users.
  • Roles (i.e. Groups).

Resources <- require -> (one or many) Permissions.

Roles <- are collections of -> (one or many) Permissions.

Users <- can have -> (one or many) Roles.

The tables for such a model would be:

  • permission
  • role
  • user
  • role_permission
  • user_role

Now you might want to include resources here as well if you want users of your application to be able to configure which permissions a resource need. But I never needed that. Hope that helps.

Cancan with database roles and abilities: AuthorizationNotPerformed

Within the controller, you need to either call load_and_authorize_resource (at the class level), or within individual actions call authorize! :action, resource where :action and resource are the things to be tested. load_and_authorize_resource adds before_filters to the controller that instantiates an instance variable for the resource (where the method of instantiation is based on the action, and the resource to load is based on the controller name) and also adds a filter to authorize the loaded resource, authorizing on either :read, :create, :update, or :destroy, based on the action that's being hit.

You can read more about it here.

Authorization in social networking website

A general answer is to find the distance between the document owner and a given contact. In Computer Science terms, this is a directed graph.

There's a good article with some SQL queries that covers this topic at http://techportal.inviqa.com/2009/09/07/graphs-in-the-database-sql-meets-social-networks/. Rather than trying to summarize the entire article, here's how to conceptualize the problem:

  • Start with a blank piece of paper.
  • Draw a dot somewhere on the page for each person (in this case, Users A, B, and C). In CS terms, this is a "node".
  • Draw an arrow from a user to all of their contacts. In CS terms, this is a "directed edge", or an "arc".
    • This isn't explicit in the question, but it looks like User C must be a contact of User B, or a contact another of User A's other contacts (since User A can read C2 and C4).
    • So in this case, you would draw from User A -> User B, and User B -> User C.

As an aside, if being a "contact" is mutual, you can draw a line segment (or bidirectional arrow) instead of an arrow. In CS terms, this would be an "undirected" vs. a "directed" graph. Facebook relationships are an undirected relationship; if someone is my friend, then I am also their friend. By contrast, if someone is in my Outlook address book, I'm not necessarily in theirs. So this is a directed relationship.

As more users are added to the drawing, you'll notice that a user's contacts are one step away, and their contacts-of-contacts are two steps away. But you can only travel in the direction of the arrow.

So the problem for contacts is, "How do I find all nodes whose graph distance is one?" And the question for contacts-of-contacts is, "How do I find all nodes whose graph distance is two?". Although "two or less" is probably more appropriate, since you'd expect direct contacts to have access to all of the "contacts-of-contacts" content.

For the general case, there are some SQL queries described in the article that might provide some insight. But for your specific need, I'd consider just using some joins.

Let's consider a Users table, with primary key id along with its other fields, and a HasContact table which has only two columns: userId and contactId. We'll assume that User A has id 1, User B is 2, and User C is 3. HasContact has rows (1, 2) and (2, 3) to represent the relationships described above.

A pretty simple set of SQL joins can produce a list of all friends, or all friends-of-friends.

The following query would return all IDs of a User's contacts:

SELECT contact.id
FROM Users "user"
LEFT JOIN Relationships "rel"
ON user.id = rel.userid
LEFT JOIN Users "contact"
ON rel.contactId = contact.id
WHERE user.id = $id_of_current_user

If you know the user IDs, an authorization query could be quite simple:

SELECT count(*)
FROM Relationships "rel"
WHERE rel.userid = $document_owner_user_id
AND rel.contactid = $id_of_current_user

If the query returns 0, then we know that the current user is not one of the document owner's contacts.

We can update that second query to indicate whether a user is a contact-of-a-contact:

SELECT count(*)
FROM Relationships "rel_1"
INNER JOIN Relationships "rel_2"
ON rel_1.contactId = rel_2.userId
WHERE rel_1.userid = $document_owner_user_id
AND rel_2.contactid = $id_of_current_user

This should return nonzero, as long as there are entries in the Relationships table such that ($document_owner_user_id, X) and (X, $id_of_current_user) both exist. Otherwise, it will return zero.

I know this is a long and somewhat indirect answer, so please comment if you have any questions.

Spree customize/extend user roles and permissions

Finally found it.

After doing some careful research found that spree 1.1.1 had changed the classes by adding "Spree" module to every class, this resulted in url like "spree/admin/overview" which earlier was "admin/overview".

So that worked for me and I was able to control the Permissions for my roles.



Related Topics



Leave a reply



Submit