Two different logins and usernames from the same table - ruby-on-rails

I need two kinds login if they refer to different controllers, example:
site.com/consumers
site.com/panel
site.com/consumers login is to make comments and site.com/panel is for the administrative part of advertisers and users.
I'm all consumers and advertisers in the same table users in the database.
Could anyone help me to make two logins do validation on the same table and after login, sends to different views and controllers?
In my route I was trying to use:
devise_for :panel, :class_name => "User"
But the layout of the login is the same, and would need to be different.
== UPDATE ==
I have three classes of people.
1) Consumer
2) advertiser
3) Administrator
The records are in the same table. But each record has a column "type" arrow you like (consumer, advertiser or administrator) So far I've managed to solve.
The problem is this:
When the user accesses via: www.site.com/comment
This user can login to make a comment on the site.
When the user accesses via: www.site.com/panel
This user can login to access the panel from him, he may be, (consumer, advertiser or administrator).
I would like to make two types of logins, one for / comment with the layout of the site and one for the / panel with the panel layout, but doing validation on the same table, in this case (Users).

Your question is a little hard to understand. It looks like your using devise. I am not sure if you are trying to use two different models, and have two different kinds of devise users, perhapse with different permissions? Or if you are trying to direct people to different pages depending on who they are after they login?
I would recommend you checkout after_sign_in_path in devise. You can define it in your application controller. If you are trying to send someone back to a different section of the site depending on where they signed in you could set a session variable and then use it in that function to decide where to send someone.
If you rewrite your question I will try and give a better answer.

Related

User settings and access control in rails

I have a webapp build with rails. Nothing complicated so far. Now I would like to restrict some areas for the user. I would like to implement two roles, User and Admin. Clearly the admin can do much more, like use DELETE in some of the controller methods. But there is even more. The user should be able to set some settings. For example he can set his profile to private, so only his friends can see his content. I am not sure how to build all of this with rails.
I did some research and found those two:
https://github.com/elabs/pundit
https://github.com/ledermann/rails-settings
Maybe a combination of those two would get me to the way I want the app to be?
If the app is going to be used used by real users i would go for the devise gem(https://github.com/plataformatec/devise) It allows user to create accounts, retrieve lost passwords etc. By default it allows users to edit their "profile"(rather their personal data), it should be easy to add a checkbox to toggle public/private profiles.
In conjunction with cancancan(https://github.com/CanCanCommunity/cancancan) you can assign roles to users, without having two different classes(Users and Admins for example).

Multiple users authenticating and authorizing

I am a bit confused with Authorizing and Authenticating at the moment.
First I need to tell you about my project. It will have two main models: Users and Pros. Users are people requesting a service. Pros are people offering services. Pros can have very different jobs and thus very different type of data stored in my project. I plan to have different models for different types of jobs held by the Pros (photographers, wedding planners..). Those models will have relationships and "own" different other models (images added with paperclip, links to websites...).
I guess I need to use gems for both Authentication and Authorizing (I have Devise and Pundit in mind)
now my questions:
I would like to have all Users and Pros login through the same form.
I guess this is very a Devise thing. Though after having read a bit about Devise, it seems there is a login for each of the Models. but this thread mentions Devise "groups"
https://gorails.com/forum/devise-with-multiple-user-models-with-single-login-form
Will it definitely solve my problem of a single form login ?
I would like to have each of the Pros submodels show a preview of their records to any type of users or even guests. But when a Pro is logged in they can access to an extended profile view with more information (all personnal data that can be changed, price requests from users, etc...). Can you confirm this is Pundit job here ?
Pundit is the perfect choice for achieving your second point. You can limit certain actions (such as edit/update) to be achievable only by the Pro who owns the account. The code for those actions in the ProPolicy would look something like:
def edit?
update?
end
def update?
record.pro == user
end
In terms of your question about multiple user model authentication using Devise, can you explain why you are set on having just one login form for both users? You could have a dropdown on the login button where the user can select if he is a normal User or a Pro. Or you could even have a checkbox/select on the form where they select which type of login they want to use.
If not, then you will somehow have to check your database to see if the login exists in either the Pro or User tables. However, I suppose that would mean that you cannot have both a Pro and a User account using the same email.

Rails: How to restrict actions to only certain users?

I am currently doing a project for uploading pics. There are users, albums, and pics. I added a friendship model so that people can friend each other like a social network. However, I noticed that I put a lot of <% if current_user.friends.include?(#user) %> in the view to check if the user of the page I'm showing is a friend of the logged in client, and therefore allowing them to have certain privileges and forms and etc.. Is there a better way or place to do this than to pollute my views with if/else statements ? Also, I don't feel like my method is very secure since someone could always manually enter the url and mess with info that they're not supposed to.
You want an authorization framework such as CanCan.
In an ability file, you configure it that a user can, say, view something or edit some other thing, only if the user is a friend of the owner. Then in the view or the controller, you can just check that the user is authorized to do the appropriate action.
For specific details about setting up an ability based on details of the models (i.e. whether the owner is a friend of the current user), go to this documentation and look for "Hash of Conditions".
Consider using something like the mosaic-access gem, which allows you to white/blacklist controllers and specific actions for the currently logged in user.

Ruby on Rails private link sharing: Google Docs Style

What would be the best way to go about giving users the ability to share a private link that enables anyone who clicks it to view a certain page/document/item that have privacy restrictions in place?
In my case:
A User creates events which are limited to certain groups of relationships in the database (namely: friends, friends of friends, etc.) I have a :before_filter in the event controller that checks the eligibility of the current logged in user to make sure that that user has permission to see the event. If they don't they get booted to the root page with an error message.
However, I want a special scenario to exist where a user can create an event with those same privacy settings and IN ADDITION, be able to share a special link with his or her friends via e-mail, facebook, etc. Those users do NOT need an account (but will need to make one in order to sign up for the event). This is important because there is also a :before_filter in the application_controller which makes sure a user is logged in.
I'm thinking there is something I could do with routing here... Right now I just have the simple /events/72 setup. Should each event have two different links: a normal one, and a "special code" version which enables them to bypass those two :before_filter?
What are people's thoughts?
I agree with David Lyod's answer (separating this concern in a different controller).
But for creating the hash I strongly recommend you salting the hash with some secret phrase.
require "digest"
Digest::SHA512.hexdigest("#{created_at}#{user_id}.mysupersonicsecretSALT")
Doing this it is not possible, without the knowlegde of the secret phrase, to calculate the hashes and test them against your system until it hits an existing one.
If you're handling sensitive data you should not be lazy.
Cheers,
Lukas
I would have a separate controller that uses a hash value to reference the event.
Something simple like the created_at + user_id hashed to create a unique reference.
You could also simply skip the check on a certain action but I would much prefer the first solution .

User profile/account URLs

I'm required to provide functions for both users and administrators to edit account and profile details in a web application. An example of a URL for the public side of these profiles is:
http://example.com/user/joe
I'm still torn between two ways to design these URLs. I've thought of either this:
http://example.com/user/joe/edit
Or something non-specific and separate to the profiles:
http://example.com/account
The benefit of the first one is that it allows administrators to do their job through the same functions. This avoids building a whole different backend specifically for administrators. I suppose the negative here is that I'd have to be careful with authorization and make sure nobody can edit what they are not supposed to edit.
The second is a more standard way of doing things, it'd turn out to be simpler and easier to secure, though it means a separate interface for administrative users.
What is SO's opinions on this? Are there any more pros/cons for either way? Which method would you recommend to use?
I would have a different view for the administrator with such a security sensitive area. It makes things much more explicit having a separate view. It is likely even an administrator would only be able to edit certain user information and thus have a different view to the user editing themselves.
It makes the authorization much clearer even if the two views shared a common edit form
If you are using an MVC approach, then my suggestion would be:
http://example.com/user/edit/1234
or
http://example.com/user/edit/joe
Where user is the controller, edit the controller method and 1234 or joe the user id or username respectively.
But as Gumbo commented, administrators should not be allowed to edit user information. They should have some mecanism to disable the account in case of a profile has offensive content or false info. Forcing the user to update it to get the account active again.
The way we do it is the admin and the user share the same view. Items which are admin-only are protected from editing or viewing by the user.
The reason for the single view is:
It reduces the number of 'moving parts' - when a new field is added to the user screen, it only needs to be added once,
It is easier to move items to/from the user's purview. If all of a sudden, management decides to allow a user to manage their "FizzBar" then we only need make the change in one place, and
It is easier to segregate the roles and the functions at the controller level.
I think that you should go with the second approach. It's more secure and flexible, and shouldn't be harder to code than profile editing the profile inline.

Resources