I need help with a design

I have been working on an app but ran into many problems when i was
applying authentication and authorization.

I want to have the following users with the given abilities.

Admin: full control on the entire system, but apart from login , email
and password it does not require any more attributes

company owner: should be able to created the number of companies the
admin approves, and have full control over all of its companies, i
would like to send an invitation to this user type

user: should have different roles and has couple more fields than the
company owner. The super user roles can only have full control over
its own company. user cant create companies and should belong to a
company and cant create companies. owners or super users should be
able to create them via a crud

client: if approved by the admin a company is clients are allowed to
log in to the system, they only have read access to their personal
data and an internal email system. Have lots of fields, ca be
affiliated to a company but the admin has access to all clients in the
system. company owners only have access to their companies clients ,
and the users only to the clients that are affiliated to their
company.

the problem comes now, I have 4 models at the moment, i would like
authentication an authorization systems to be common to all of them. I
have 4 abilities with cancan, and 4 resources with devise, but keeping
up with everything was very redundant, i have 4 login page 4 path to
signout, etc. If i unify all users in a single model an manage
everything with fields in the DB im a little confuse on how to handle
the company users relation since companies belong to owners in the
current design but a company has many users and clients.

I have been thinking of a has many through association with resources
called ownership, employ and affiliation
and use boolean fields or a user type field to differentiate each type
of user. I would need a lot of conditional validations of course.
would STI be helpful or would it require 4 of everything anyway? i
want to have one login page and one ability class.

Anyone has a better solution? i would appreciate some comments on
this.

please help!! T_T

bump

anyone?

I have been working on an app but ran into many problems when i was
applying authentication and authorization.

I want to have the following users with the given abilities.

Note your wording here, you want the following _users_. That is the
clue to what follows.

Admin: full control on the entire system, but apart from login , email
and password it does not require any more attributes

company owner: should be able to created the number of companies the
admin approves, and have full control over all of its companies, i
would like to send an invitation to this user type

user: should have different roles and has couple more fields than the
company owner. The super user roles can only have full control over
its own company. user cant create companies and should belong to a
company and cant create companies. owners or super users should be
able to create them via a crud

client: if approved by the admin a company is clients are allowed to
log in to the system, they only have read access to their personal
data and an internal email system. Have lots of fields, ca be
affiliated to a company but the admin has access to all clients in the
system. company owners only have access to their companies clients ,
and the users only to the clients that are affiliated to their
company.

the problem comes now, I have 4 models at the moment, i would like
authentication an authorization systems to be common to all of them. I
have 4 abilities with cancan, and 4 resources with devise, but keeping
up with everything was very redundant, i have 4 login page 4 path to
signout, etc. If i unify all users in a single model an manage
everything with fields in the DB im a little confuse on how to handle
the company users relation since companies belong to owners in the
current design but a company has many users and clients.

I presume that your models are Admin, Owner, User and Client (or
similar names). The fact that you worded your initial requirement as
I have pointed out above suggests that these are all Users with
different roles. This rationalisation will mean they can all log on
via the same page. Once logged in you can control the features
available using the roles that a particular user has. There will
likely be a roles table. User belongs_to role, Role has_many users
and so on. The settings in the role will indicate what a user can do.

Colin

@colin

Thanks, someone finally cared.

I presume that your models are Admin, Owner, User and Client (or

similar names).

yes exactly, but i created separated models because there would be a lot of conditional validations if i didnt,
for example owners can manage a companies but a user should belong to a company.

The fact that you worded your initial requirement as

I have pointed out above suggests that these are all Users with

different roles.

yes but i would require different controllers and views for each roles/type of user, and what i call user, which is the
company employee in this case, has many roles.

User belongs_to role, Role has_many users

and so on.

im already think of making this a HBTM association, since , but only for the “user” role/type since is the one with many roles.

I though about all this before, but the reason i have hesitated to do it this way is because of the validations, excess in attributes

for the roles/types that dont require them and possible security issues.

I see not way of avoiding the creation of a very fat user model, with lots of accesible attributes dynamically changing and lots of scopes.

@colin

Thanks, someone finally cared.

I presume that your models are Admin, Owner, User and Client (or
similar names).

yes exactly, but i created separated models because there would be a lot of
conditional validations if i didnt,
for example owners can manage a companies but a user should belong to a
company.

I don't see that as a problem.

The fact that you worded your initial requirement as
I have pointed out above suggests that these are all Users with
different roles.

yes but i would require different controllers and views for each roles/type
of user, and what i call user, which is the
company employee in this case, has many roles.

You have that already with the different models. You can either
continue with separate controllers/views or merge them as seems most
appropriate. Remember a controller does not need to map to a model.

User belongs_to role, Role has_many users
and so on.

im already think of making this a HBTM association, since , but only for the
"user" role/type since is the one with many roles.

I though about all this before, but the reason i have hesitated to do it
this way is because of the validations, excess in attributes
for the roles/types that dont require them and possible security issues.

I see not way of avoiding the creation of a very fat user model, with lots
of accesible attributes dynamically changing and lots of scopes.

Again that is not necessarily a problem, though it is all a matter of
degree of course.
If you really think that here you have different types of users rather
than users with different roles you could look at STI as an
alternative.

Colin

Remember a controller does not need to map to a model.

Yes i know, thanks.

Again that is not necessarily a problem, though it is all a matter of

degree of course.

If you really think that here you have different types of users rather

than users with different roles you could look at STI as an

alternative.

Well i know is not a problem, but i wanted to know if there is a better way to do all this.
STI creates a problem when authenticating user and creating permissions, i would need an ability and a login per user type.

Hi,

Your task is cannot be that complicated, but for first reading it
seemed, and a bit long.

Try to draw it first!
First you have to find out: the user experience! It will make clear
what datas you need, so what models, which kind of controllers you
have to write with different actions. And from this writing a before
filter will be easier.
You haven't wrote how you solved the user authentication - from
scratch?
In FireFox there is an excellent Add-on, called Pencil, with this you
can make a sketch easily!

Now I cannot spend more time with this, but write me in private more
detailed, if you would like to, and in these days I will try to help.
good luck
gezope

Just to make things a bit more clear, my app will be very similar to shopify. Im worrying about this first and later i will worry about the CMS part.

Now I cannot spend more time with this, but write me in private more

detailed, if you would like to, and in these days I will try to help.

good luck

gezope

Thanks a lot. How can i get in contact with you?

Hi,

Your task is cannot be that complicated, but for first reading it
seemed, and a bit long.

Try to draw it first!
First you have to find out: the user experience! It will make clear
what datas you need, so what models,

I disagree here, the models required should not be based upon the user
experience required but on the underlying objects in the real world -
users, companies and so on in this particular case. Unless I
misunderstand what is meant by 'user experience'.

Colin

Colin Law wrote:

Hi,

Your task is cannot be that complicated, but for first reading it
seemed, and a bit long.

Try to draw it first!
First you have to find out: the user experience! It will make clear
what datas you need, so what models,

I disagree here, the models required should not be based upon the user
experience required but on the underlying objects in the real world -
users, companies and so on in this particular case. Unless I
misunderstand what is meant by 'user experience'.

I agree with Zoltan -- and I suspect you do too -- in this sense: when I
put together an application, I usually think first about how I want it
to present itself to the user and what the user should be able to
accomplish (and write Cucumber scenarios accordingly). Only as a result
of making those scenarios reality do I write model classes or anything
else.

In other words: first define what you want the user to do, and only then
figure out the code to make it happen.

Colin

Best,

I think my point is that the identification of models that are
required should not be based on what is required in views or what the
user experience is as he moves around the site. It is based on
considering the underlying objects in the system. So in the OP's
case, whether he should have different models for user, owner and so
on or have one model, user, with different roles is not principally to
do with how the app should appear or behave, except in the very
broadest sense that there is a requirement for such objects.

The whole design process is iterative of course, but I think I would
rephrase your suggestion as follows:
First think (and preferably talk) about the underlying objects in the
system so as to get a first stab at the models required (not the code,
just what the models are likely to be), then define what you want the
user to do, and then figure out the code to make it happen. Round and
round ad nauseum. That is not to say that I think this is the one and
only 'right' way to do it. Different people's minds work in different
ways and others may find an alternative design process suits them
better.

Colin

Radhames Brito wrote:

I have been working on an app but ran into many problems when i was
applying authentication and authorization.

I want to have the following users with the given abilities.

Is there any reason that you cannot usefully employ existing
authentication mechanisms like Auth_Logic or Devise? And what about
Declarative_Authorization? Is there any reason why this does not suit
your authorization needs?

It seems to me to be a mis-application of effort to write from the
ground up that which is already freely available and maintained for you.

I agree with Zoltan – and I suspect you do too – in this sense: when I

put together an application, I usually think first about how I want it

to present itself to the user and what the user should be able to

accomplish (and write Cucumber scenarios accordingly). Only as a result

of making those scenarios reality do I write model classes or anything

else.

In other words: first define what you want the user to do, and only then

figure out the code to make it happen.

This approach should be very beneficial, i always begin by thinking of entities and their relations, and only when i get to the presentation layer i start thinking about the user experience. I will definitively try going this way to see if everything come out faster.

Is there any reason that you cannot usefully employ existing

authentication mechanisms like Auth_Logic or Devise? And what about

Declarative_Authorization? Is there any reason why this does not suit

your authorization needs?

It seems to me to be a mis-application of effort to write from the

ground up that which is already freely available and maintained for you.

creating a model for each user was the easiest way at first, but in that case i need a different login page for each and that detriments the user experience. Devise is awesome, but i have found it inflexible. I wanted to make an ajax login and it was harder than necessary. I tried to make all users login with one login page and i had to first learn how to use warden and hack devise quite a bit, in fact i did all that, but every change was like going against the concept devise was build for (easy of use , etc).

Authlogic is more flexible but it wont allow one page login for all users easily. Cancan requires a different ability per model so there is a lot of redundancy when i need to define permissions for one type of user and almost the same for another type of user. Thats why i have been thinking of joining everything in one model, but first i wanted to ask to see if that was the best/only way to overcome all those obstacles.

Colin Law wrote:
[...]

The whole design process is iterative of course, but I think I would
rephrase your suggestion as follows:
First think (and preferably talk) about the underlying objects in the
system so as to get a first stab at the models required (not the code,
just what the models are likely to be), then define what you want the
user to do, and then figure out the code to make it happen.

No, absolutely not. There is no point in thinking about the models
involved before thinking about the desired functionality.

Round and
round ad nauseum. That is not to say that I think this is the one and
only 'right' way to do it.

No, of course there's more than one right way. But I think yours is one
of the many wrong ways: it is inappropriate to start considering
implementation details before you know what the implementation should do
for the end user.

I'll turn the question around: why would you want to consider
implementation before functionality? What possible benefits could it
produce?

Best,

Colin Law wrote:
[...]

The whole design process is iterative of course, but I think I would
rephrase your suggestion as follows:
First think (and preferably talk) about the underlying objects in the
system so as to get a first stab at the models required (not the code,
just what the models are likely to be), then define what you want the
user to do, and then figure out the code to make it happen.

No, absolutely not. There is no point in thinking about the models
involved before thinking about the desired functionality.

Round and
round ad nauseum. That is not to say that I think this is the one and
only 'right' way to do it.

No, of course there's more than one right way. But I think yours is one
of the many wrong ways: it is inappropriate to start considering
implementation details before you know what the implementation should do
for the end user.

I'll turn the question around: why would you want to consider
implementation before functionality? What possible benefits could it
produce?

Well of course you need some idea of functionality before anything can
be designed. If I can bring back a quote from your earlier post:

... when I
put together an application, I usually think first about how I want it
to present itself to the user and what the user should be able to
accomplish (and write Cucumber scenarios accordingly). Only as a result
of making those scenarios reality do I write model classes or anything
else.

I am suggesting that there is a phase before considering in detail how
the application should present itself to the user. For example to
take the ubiquitous shopping app, before considering how the logon
page should operate there is the decision that there will be users and
that there should be a page where the user can logon. Similarly
before considering how precisely the user adds a product to his
shopping cart there is the decision that there will be products and
shopping carts. It is at this stage that initial stabs at what the
models will be can be made (note that I am not suggesting writing any
code here, merely thinking about what the models will be). It does
not seem feasible that one can write a Cucumber scenario for user
logon and then go from that to the idea that maybe one needs a user
model. Is it not true that the concept of a User must exist before
one can write the scenario? Note again that I am not suggesting
writing any code at this time, just thinking about what the models
should be.

Colin

Colin Law wrote:

involved before thinking about the desired functionality.
I'll turn the question around: why would you want to consider
implementation before functionality? �What possible benefits could it
produce?

Well of course you need some idea of functionality before anything can
be designed. If I can bring back a quote from your earlier post:

... when I
put together an application, I usually think first about how I want it
to present itself to the user and what the user should be able to
accomplish (and write Cucumber scenarios accordingly). Only as a result
of making those scenarios reality do I write model classes or anything
else.

I am suggesting that there is a phase before considering in detail how
the application should present itself to the user.

There is the phase of deciding in very general terms what the broad goal
of the application is -- in your case, something like "people should be
able to order products from us".

For example to
take the ubiquitous shopping app, before considering how the logon
page should operate there is the decision that there will be users and
that there should be a page where the user can logon.

Sort of. Out of the idea that users can order products comes the idea
that we need a way to tell the system who's ordering. From that idea
may come the fact that we want user accounts and a login interface.
That's probably as far as I'd go down that particular path in initial
requirements gathering with my client.

Similarly
before considering how precisely the user adds a product to his
shopping cart there is the decision that there will be products and
shopping carts.

First step: Users should be able to order products.
Second step: We want to present them a shopping cart interface to do so.
Third step: Users should be able to do the following things from that
interface.

The domain concepts emerge from requirements gathering. They are not
considered before it so much as simultaneously with it in my experience.

It is at this stage that initial stabs at what the
models will be can be made (note that I am not suggesting writing any
code here, merely thinking about what the models will be).

No! It's premature. The business domain objects are a good start for
guessing what model classes you'll need, but it's absolutely wrong to be
thinking like a programmer when you're doing business analysis.

It does
not seem feasible that one can write a Cucumber scenario for user
logon and then go from that to the idea that maybe one needs a user
model.

I assure you, it is entirely feasible. I do it all the time: write a
Cucumber scenario with perhaps only the vaguest idea of what models I
need, then start experimenting with the best way to make it pass.
Remember, Cucumber scenarios are written in English for a reason:
they're meant to test user-facing behavior, not code. You could
completely rearchitect a system and still have the Cucumber scenarios
pass.

Is it not true that the concept of a User must exist before
one can write the scenario?

The business concept, sure. But it's premature to translate that into a
concept of a User class in the requirements gathering stage.

(To be fair, user management is simple in most cases and requires a User
class. But I've been doing stuff with my medical records application
where I may have a bunch of features gleaned from the client and
translated to Cucumber stories -- and still have no idea what the
underlying models should look like.)

  Note again that I am not suggesting
writing any code at this time, just thinking about what the models
should be.

And I'm telling you that that's a bad idea. Don't think about models
till you actually need to write them.

Colin

Best,

Radhames Brito wrote:

Authlogic is more flexible but it wont allow one page login for all
users easily.

I do not understand what you mean by this. I have authlogic in
production where there is but one authentication view used by every
user. Each session created thereby has its own credentials and the user
instance thereafter obtains its permissions from the
declarative_authorization roles and rights configuration file.

I will not pretend that dealing with these two formidable packages was
without its difficulties, particularly in the the beginning when my
ignorance of them was complete. However, once one grasps the concepts
upon which each is based then elaboration of the resulting security
system is far easier than I ever thought possible.

Cancan requires a different ability per model so there is a lot of
redundancy when i need to define permissions for one type
of user and almost the same for another type of user. Thats why i have
been thinking of joining everything in one model, but first i wanted
ask to see if that was the best/only way to overcome all those obstacles.

I have not used CanCan (Ryan Biggs wrote that for one of his Railscasts
episodes did he not?) but from what I can gather from your other
messages it seems that you conflate authentication with authorization at
several points. Authlogic, Devise and similar packages simply identify
a particular set of credentials as having a unique accessor instance in
the system. Declarative_Authorization and CanCan type packages tie
access to specific bits of the application to specific accessor
identities. Both need some form of implementation of the idea of a
session to be of much use.

My own experience with RBAC is that it proves best to stay away from
things that you do not fully understand until you need to address them
directly and can afford the time to master the intricacies involved.
Imagining what you will need in the absence of concrete requirements is
a great time waster.

For an initial implementation of authentication and authorization I
would create some minimal methods in the application controller to
handle hard coded identities, rights and roles and then go ahead build
the application. At some point the need for users will present itself
and then you can implement your user models/classes modifying the stub
methods to handle authorization alone. When authorization becomes the
natural focus of development then it is time to look at things like
Authlogic and CanCan.

I think that you will find the this approach permits you to remain
focused on the value-added part of your project and leaves the
administrative pieces on the periphery until their requirements are
largely defined by the rest of your application.