Allowing Users to Edit Accounts Without Saving Passwords in Devise & Passing Conditions to :Reject_If in Ruby

Allowing users to edit accounts without saving passwords in devise & passing conditions to :reject_if in Ruby

Try this peace of code while updating user in controller. This is update method for devise version 1.5.3, these two lines will do the trick.

 def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)

params[:user].delete(:password) if params[:user][:password].blank?
params[:user].delete(:password_confirmation) if params[:user][:password_confirmation].blank?

if resource.update_attributes(params[resource_name])
set_flash_message :notice, :updated if is_navigational_format?
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords(resource)
respond_with_navigational(resource){ render_with_scope :edit }
end
end

Devise update user without password

Is this what you're look for? From the Devise wiki

Allow users to edit their account without providing a password

It shows how to do it for rails 3 and rails 4

=======================

John's solution is a simpler alternative

Edit other user as admin in devise, ruby on rails

I figured it out:

  1. add a prefix in routes on devise_for :users,: :path_prefix => 'my'
  2. add this below devise_for: resources :users
  3. copy edit.html.erb from the registration from devise to users.
  4. Change <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>

to: <%= form_for(@user) do |f| %>


  1. Add this to the usercontroller:

       def edit
    @user = User.find(params[:id])
    end

    def update
    @user = User.find(params[:id])
    if @user.update(user_params)
    redirect_to adminpanel_path
    else
    render 'edit'
    end
    end

Done. (strangely, I can't put number 5 in code)

Testing custom devise registration controller update action with Rspec

The test now looks like this and it passes:

describe "PUT #update" do
before :each do
@request.env['devise.mapping'] = Devise.mappings[:user]
user_tom = FactoryGirl.create(:user, email: 'tom@test.com')
sign_in user_tom
end

it "changes user attributes" do
put :update, user: { email: 'jerry@test.com' }
subject.current_user.reload
assigns[:user].should_not be_new_record
expect(subject.current_user.email).to eq 'jerry@test.com'
expect(flash[:notice]).to eq 'You updated your account successfully.'
end
end

Prepend sign_up page with a condition?

To improve on security of previous suggestions, the best one seems to be by coreyward, but it's insecure (regardless if cookies are encrypted or not - see my comment on the OP)

# app/controllers/preauth_controller.rb
def new
end

def create
if params[:answer] == 'correct answer'
# Create a secret value, the `token`, we will share it to the client
# through the `session` and store it on the server in `Rails.cache`
# (or you can use the database if you like)
#
# The fact that this token expires (by default) in 15 minutes is
# a bonus, it will secure the system against later use of a stolen
# cookie. The token is also secure against brute force attack
@token = SecureRandom.base64
session[:preauthorization_token] = @token
Rails.cache.write("users/preauthorization_tokens/#{@token}", "OK")
redirect_to sign_up_path
else
flash[:error] = 'Incorrect answer'
render :new
end
end

# app/controllers/users_controller.rb
before_filter :verify_preauth, only: [:new, :create]

def verify_preauth
# When we approve preauthorization we confirm that the
# `token` is known to the client, if the client knows the token
# let him sign up, else make him go away
token = session[:preauthorization_token]
redirect_to new_preauth_path unless token and Rails.cache.read("users/preauthorization_tokens/#{token}") == "OK"
end

Optional things to do / play with....

  1. delete the successfully used Rails.cache entry when user is created
  2. play with :expires_in settings if you want, you generally want it as short as possible and as long as needed :) but the rails default of 15 minutes is pretty good
  3. there are nicer ways of going around this and similar security issues with cookies - namely you can create a server_session object which does basically the same as session but stores the data in Rails.cache with a random expirable token stored in session used to access the cache entry in much the same way we do here
  4. simply go to server-side sessions and don't worry about session security, but this means longer response times due to your Rails.cache round trip (redis, memcache, AR, ...)
  5. instead of OK into the cache value you can store a hash of values, if you need more data, safely stored on the host, to work this out
  6. ...

CanCan - How to allow users to update and delete only their own objects

Here's what I did:

In ability.rb

def initialize(user)
if user.nil?
can :read, Article
elsif user.admin?
can :manage, Article
else
can [:read, :create], Article
can [:update, :destroy], Article, :user_id => user.id
end
end

And for displaying the links, I've used this:

- if can? :read, Article
= link_to 'Show', article
- if can? :create, Article
= link_to 'New Article', new_article_path
- if can? :update, article
= link_to 'Edit', edit_article_path(article)
- if can? :destroy, article
= link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' }

And it seems to be working now, not sure if that's the best way though.

Devise: Is it possible to NOT send a confirmation email in specific cases ?

So according to devise confirmable module you can skip to send confirmation and email by following code.

 def confirm_your_type_user_without_confirmation_email
# check your condition here and process the following
self.skip_confirmation!
self.confirm!
# condition may end here
end

Now lets call it on create hook.

class User < ActiveRecord::Base
after_create :confirm_your_type_user_without_confirmation_email
....
end

for more reference you may check this:
Devise Confirmable module

The solution should be something similar as I mentioned here above. And its best practice to avoid controller to handle these responsibilities, because its not something your controller should take. :)
I hope my answer will give you some way to solve your problems! Thanks!



Related Topics



Leave a reply



Submit