Help modeling a User/Group permission structure


#1

Hello,

I’ve worked through some rails tutorials and am trying to create
something a little more complicated for learning purposes. I’m trying
to extend a blog application into more of a cms with a basic user/
group permission system.

Basically, I have Users, Articles and Groups. Users can have a role
of either: Author or Viewer. Some articles are private and some are
public. For private articles, I’d like to have a system where an
article can be permissioned to either a group or to an individual user
or even both.

When a website visitor tries to access an article AND the article is
‘Private’, I’d like for the system to prompt the visitor to login.
Once logged in, I want the system to then check if this user has
permission to view the article. Permission being defined as: if this
user is either in a group that has permission to the article OR the
user himself has explicit permission to that article.

Here’s what I currently have - does this make sense? I’m mostly
struggling with the Article_Private_Access model and whether this is a
good approach.

Users:
name
email
password
role (role is either ‘Author’ or ‘Viewer’)

Group_Users
group_id
user_id

Groups:
name

Articles
user_id
access_type (‘Private’ or ‘Public’)
title
body

Article_Private_Access (** this serves to link Articles with
permissioned Users or Groups)
article_id
access_type (‘Group’ or ‘User’)
access_id (this id would point to either a User record, or a
Group record)


User model:
has_and_belongs_to_many :groups
has_many :article

Group model:
has_and_belongs_to_many :users

Article model:
belongs_to :user

I’m just not sure whether to use the Article_Private_Access table and/
or how to model it. I was thinking this table would contain a list of
Users and/or Groups that had access to a particular Article. But I’m
a bit lost now…

Any help would be greatly appreciated.

Thanks.


#2

The tables you have seem to make sense to me.

For the Article Private Access table appears to be a one to one on
Article, you could dispense with this table and put the fields into
the Articles table. Either as you have them, access_type, access_id.
Or access_id, group_id. With the latter, an article could be
accessible by a group or a user or both.

If you only want Access by group OR user, then another approach might
be to use two different article tables,
eg. Group_Article and User_Article. I am doing something similar at
the moment, where I have bookings that can belong to an Order or a
Quote. I am still thinking about it, but it looks to me like having
order_bookings and quote_bookings may possibly be a cleaner solution.
In your case however, that is probably not the case.

Others may have better ideas. HTH
tonypm


#3

thanks for the response. as for breaking articles into 2 tables, i
prefer to keep a single table. i think in your case 2 tables would be
better.

also, i’m not sure how there would be a 1-1 relationship between my
article_private_access table with articles.

here’s how i envision the data

Users
id name
1 Jim
2 John
3 Mary
4 Ed
5 Fred

Articles
id title user_id access_type
1 Some article title 1 PRIVATE

Groups
id name
1 Group1

Groups_Users
group_id user_id
1 2
1 4

Article_Private_Access
article_id access_type access_id
1 Group 1
1 User 3

This would allow “Article 1” (published by Jim) to be accessible by:
Group1 (which contains John, Ed) and accessible by user Mary. Fred
would not be entitled to access this article

Is there an easier way? I feel as though I may have a lot of logic to
loop through these Article_Private_Access lists that I’d like to
simplify.


#4

thanks for the response. as for breaking articles into 2 tables, i
prefer to keep a single table. i think in your case 2 tables would be
better.

also, i’m not sure how there would be a 1-1 relationship between my
article_private_access table with articles.

here’s how i envision the data

Users
id name
1 Jim
2 John
3 Mary
4 Ed
5 Fred

Articles
id title user_id access_type
1 Some article title 1 PRIVATE

Groups
id name
1 Group1

Groups_Users
group_id user_id
1 2
1 4

Article_Private_Access
article_id access_type access_id
1 Group 1
1 User 3

This would allow “Article 1” (published by Jim) to be accessible by:
Group1 (which contains John, Ed) and accessible by user Mary. Fred
would not be entitled to access this article

Is there an easier way? I feel as though I may have a lot of logic to
loop through these Article_Private_Access lists that I’d like to
simplify.