How to render particular attributes of an object using devise? - authentication

I am using devise gem, everything works great, but the problem is after the login the entire user object is rendered. So if I send a json request to login it will return everything that the user object holds, I was able to limit to particular attributes using a rabl file during registration. What I did was just created a create.rabl in the views/devise/registration. But the same thing is not working for login. So how can i limit the resource attributes using devise.

After login, devise redirects, probably to user#show, so create a view file views/users/show.json.rabl that contains the attributes you want to return, for example,
object #users
attributes :id, :name, :email

Check out http://railscasts.com/episodes/322-rabl

Related

Using the ActiveAdmin Submit button in relation to attr_accessible

I'm currently changing around how my ActiveAdmin interface works so that it integrates both attr_accessible items and CanCan. In some of my models I have a specific controller action for the Submit button on the form such as
= f.actions do
= f.action :submit, label: 'Update Password'
And in that Update Password method I am able to do the update_attributes(*,as: #admin_user.role.name.to_sym) where #admin_user is the current admin user. This allows only admin users with the permitted role to update their password.
The problem I have is when ActiveAdmin is doing the generic update, specifically
=f.action :submit
How can I pass options to ActiveAdmin so that when it does the update it will use the specified role? I know that the buttons use Formtasti, and that the :label method is part of that, but I can't seem to find anything about using passing other options.
One option for me is to write an override for the edit method in each of my models, but that kinda defeats the purpose of ActiveAdmin, doesn't it?
Now, my CanCan abilities already have been set so that only certain roles can access certain items. Does this override the attr_accessible items? I know that if the item is not attr_accessible, even if it's manageable in CanCan, will not change via mass-assignment.
What I really need to know is that if I were a hacker, could I inject an update_attributes(params[:whatever], as: :admin) and it would block it because of CanCan's Ability? Is it worth it to have both the item be protected via attr_accessibleand CanCan's Ability class?
ActiveAdmin and SimpleForm do not support the as: [role] feature which I was trying to work with. However, this isn't a problem with strong_parameters in Rails 4 since it's a completely different way of handling mass-assignment.
Also, CanCan does block out any mass-assignment hacks since you can't mass-assign unless you have access to the form, and if you don't have explicit :edit, :update, or :manage permission then you don't have access to the form.

Devise: Load a partial instead of showing a notice for non confirmed members

Is there a way to load a view for no confirmed users that login?
Default behaviour is to show a notice: " You have to confirm your account before continuing."
I tried
overrule the sessions#create method of devise checking for current_user.confirmed_at.blank?
in the after_singin_path check for current_user.confirmed_at.blank? and render the view instead
My goal is to render a custom view instead of the notice but cannot hook into the right location. Who knows how to accomplish this? thx!
You can simply copy the code from the devise github and place in your controllers/devise. then change any action or method you want to.
You may also just extend the devise session controller and override any action you want to.
class Abc < Devise::SessionsController
# this just reopens the class.
# Remember classes are never "closed" in ruby!
end
I like the ruby way of solving this, I guess that in your UsersController after a POST request the user will be returned and signed in using the sign_in(Object) helper Devise provides.
Also I suggest using a confirmed boolean instead of timestamp.
Why not check for the value using an if else statement the ruby way:
user.confirmed ? sign_in(user) : render :partial => 'path/partial'
Hope this might help you out

How to remove the active admin sign-up link?

I don't want to sign-up new user to (active admin) admin panel..so that I want to customize the login page of active admin.
How can I remove the sign-up link from the admin-login page in active admin.
How can I do the same...?
The question is quite old, but I just came across the same problem. My solution is:
mkdir -p app/views/active_admin/devise/shared
touch app/views/active_admin/devise/shared/_links.erb
I have also disabled the routes:
devise_for :users, ActiveAdmin::Devise.config.merge(skip: [:confirmations, :passwords, :registrations, :unlocks])
If this rule applies to all of your admin pages, you could use a different layout file that didn't include the links (or the partial that included them.
You could set a variable in the controller (e.g. #hide_login) then conditionally display them (e.g. <%= link_to("Sign Up", sign_up_path) unless #hide_login %>)
I have worked on a number of applications where the admin interface is really a separate part of the app, accessible only to internal users, and in this case it can be helpful to put your administrative models/views/controllers in their own namespace ( e.g. Admin::ManageUsers) which makes it easy to globally apply certain rules in a before_filter (including, possibly defining the default layout).
There are several posibilities to do this as you know you should have a controller (I mostly use AdminController) wich has an index action.
then in de index view there probably is a render partial wich renders the login/sign-up form
you can locate the elemement wich renders the sign-up link.
If you somehow can't find this you can go to your Terminal/CMD
end type
grep -lr "sign-up" *
this will find the sign-up link somewhere then just delete it or hide it like above message suggests

How do I keep the current devise session from being destroyed automatically when navigating from page to page?

I've looked through the posts about devise's current_user, but none of them solve my problem. I can access current_user from my rails 3 views (erb files), but can not access it in the controller.
<%= current_user.name %>
works in the erb.
#user = current_user
does not work in the controller. What am I missing?
---------edited------
I am getting nil as value. It turns out I am able to use
#user = current_user
in my index controller, but some how once it goes to a different action (like create) the session is destroyed.
So the real question now is:
How do I keep the current user signed in when going from page to page?
Finally figured out what the problem was: needed to get a fixed rails.js file from
https://github.com/fermion/jquery-ujs/blob/master/src/rails.js
Many thanks to #Patrick Connor link to his answer
Devise session immediately expiring on .js call [AJAX]

Passing controller method attributes in before_filter methods in Rails 3

I'm trying to only allow access to galleries by users who have permission to view them. Galleries have many shared_users through permissions, and vice versa. Galleries also have only one owner. Owners and shared users are both of the User class. This all works fine. The issue that I'm having, however, is with my access filters.
I'm using the following code to see if a user is allowed to see the gallery they are trying to access:
def authenticate_viewers!
if user_signed_in? && current_user.can_view?(#gallery)
return true
end
redirect_to root_url,
:notice => "You must have permission to view this gallery."
return false
end
As you can see, can_view? requires the #gallery that I'm setting up in the show method, but a before_filter won't let you access the attributes set up in the method, since it resolves before the method executes. Using an after_filter works, as long as an unauthorized user doesn't try to view the gallery. If it does, I get a DoubleRender error, since after_filter allows the page to render, then tries to redirect.
I just thought that I could perhaps use params[:id] instead of #gallery, though I haven't tried it yet, and ultimately this may be more efficient (passing an integer instead of an object). In any case, is there a way to make my current code work? or is it in my best interest to switch to using the params (if that's even going to work)?
Wow, okay. It's really helpful just to start writing questions here on SO, because as I do, I typically get a brainstorm of how to solve the problem. Instead of using the #gallery object, I just use a Gallery.find(params[:id]) and everything works like a charm. Thank God I don't have to rewrite all my code.