Forum: Ruby on Rails crypt_unless_empty (login generator)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Eec43f946d65be32e6b9fd2b3a1582a5?d=identicon&s=25 adam.groves (Guest)
on 2005-11-18 14:05
(Received via mailing list)
I have a form for users to change their account details, including their
password.
 Here's my form:

<label for="user_first">First name(s)</label><br/>
<%= text_field 'user', 'first' %><br/>
<label for="user_name">Surname</label><br/>
<%= text_field 'user', 'name' %><br/>
<label for="user_tel">Telephone</label><br/>
<%= text_field 'user', 'tel' %><br/>
<label for="user_email">email</label><br/>
<%= text_field 'user', 'email' %><br/>
</div>
<div>
<label for="user_login">Login</label><br/>
<%= text_field 'user', 'login' %><br/>
<label for="user_password">Choose password:</label><br/>
<input id="user_password" name="user[password]" size="30"
type="password"
/><br/>
<label for="user_password_confirmation">Confirm password:</label><br/>
<input id="user_password_confirmation"
name="user[password_confirmation]"
size="30" type="password" /><br/>
 and here's my controller method:
 def update_user
@user = User.find(params[:id])
@project = Project.find(params[:project])
@company = Company.find(params[:company])
if @request.post? and @user.update_attributes(params[:user])
User.authenticate(@user.login, @params[:user][:password])
flash[:notice] = 'User was successfully updated'
redirect_back_or_default :action => 'index', :project => @project,
:company
=> @company
end
end
 It's all working well and the errors are listed if fields don't
validate.
However, I want the update to be successful if the two password fields
are
left empty (user doesn't want to change their password). according to
the
comments in the user model, the method crypt_unless_empty should catch
this
before update and I presume allow the record through. This isn't working
for
some reason and I get 3 errors:
 - Password confirmation can't be blank
 - Password can't be blank
 - Password is too short (min is 5 characters)

Does anyone have any suggestions as to why this doesn't work (and how I
can
get it working)?
 Regards
 Adam
 PS: Has anyone used the login generator in a commercial rails
application?
334e21fe251e39fc4e6861831dbe2ba3?d=identicon&s=25 A. Js (ajs)
on 2006-01-04 00:15
adam.groves wrote:
> I have a form for users to change their account details, including their
> password.
>  Here's my form:
>
> <label for="user_first">First name(s)</label><br/>
> <%= text_field 'user', 'first' %><br/>
> <label for="user_name">Surname</label><br/>
> <%= text_field 'user', 'name' %><br/>
> <label for="user_tel">Telephone</label><br/>
> <%= text_field 'user', 'tel' %><br/>
> <label for="user_email">email</label><br/>
> <%= text_field 'user', 'email' %><br/>
> </div>
> <div>
> <label for="user_login">Login</label><br/>
> <%= text_field 'user', 'login' %><br/>
> <label for="user_password">Choose password:</label><br/>
> <input id="user_password" name="user[password]" size="30"
> type="password"
> /><br/>
> <label for="user_password_confirmation">Confirm password:</label><br/>
> <input id="user_password_confirmation"
> name="user[password_confirmation]"
> size="30" type="password" /><br/>
>  and here's my controller method:
>  def update_user
> @user = User.find(params[:id])
> @project = Project.find(params[:project])
> @company = Company.find(params[:company])
> if @request.post? and @user.update_attributes(params[:user])
> User.authenticate(@user.login, @params[:user][:password])
> flash[:notice] = 'User was successfully updated'
> redirect_back_or_default :action => 'index', :project => @project,
> :company
> => @company
> end
> end
>  It's all working well and the errors are listed if fields don't
> validate.
> However, I want the update to be successful if the two password fields
> are
> left empty (user doesn't want to change their password). according to
> the
> comments in the user model, the method crypt_unless_empty should catch
> this
> before update and I presume allow the record through. This isn't working
> for
> some reason and I get 3 errors:
>  - Password confirmation can't be blank
>  - Password can't be blank
>  - Password is too short (min is 5 characters)
>
> Does anyone have any suggestions as to why this doesn't work (and how I
> can
> get it working)?
>  Regards
>  Adam
>  PS: Has anyone used the login generator in a commercial rails
> application?


I'm having a very similar problem and haven't been able to find a
solution.

We want users to be able to edit their settings WITHOUT having to
re-enter their passwords, so we're using before_update
:crypt_unless_empty to properly populate the password field of the
object to be updated.

Unfortunately, it would seem that the object to be updated attempts to
validate its fields BEFORE applying the before_update directives, so
blank passwords are invalidated before they can be corrected by the
crypt_unless_empty function.  This seems like really poor behavior but
it's all I can come up with to explain what we're seeing.  Any advice is
greatly appreciated.  Thanks.
0311b3e219b0e7cd1523eb7eceaac57d?d=identicon&s=25 Rcj Rc (rcj)
on 2006-01-21 08:36
hai
0311b3e219b0e7cd1523eb7eceaac57d?d=identicon&s=25 Rcj Rc (rcj)
on 2006-01-21 08:38
hai


Modify ur model class by including the lines below

validates_uniqueness_of :login, :on => :update
 	validates_confirmation_of :password, :on => :update
 	validates_length_of :login, :within => 3..40, :on => :update
  	validates_length_of :password, :within => 5..10, :on => :create
  	validates_presence_of :login, :password, :password_confirmation ,:on
=> :create
  	validates_confirmation_of :password
  	if !([:password].empty?)
       	User.validates_length_of :password, :within => 5..10
  			end

  			attr_accessor :password
	 		attr_accessible :name,
:password,:first_name,:last_name,:office_phone,:mobile_phone,:email,:login,:password_confirmation
			before_create :crypt_password

			before_update :crypt_unless_empty



sure!!!!!!!! It will work
0c0eb2ade20576ec0905f35600c652bc?d=identicon&s=25 Alex Rudnitski (wiz)
on 2006-01-21 10:32
Adam Groves, I'm also working on login system, the solution you
searching could be  found here http://www.ruby-forum.com/topic/52250 I
make checking if the password field is blank in controller

def edit
  @edituser = User.find_first(["id = ?",params[:id]])
  if @request.post?
    if not @edituser.nil?
      @edituser.login = @params[:edituser][:login]
      @edituser.birthday = @params[:edituser][:birthday]
      @edituser.login = @params[:edituser][:login]
      if not @params[:edituser][:password].nil? and
        @params[:edituser][:password] ==
@params[:edituser][:password_confirmation] and
  @params[:edituser][:password] != ""
  @edituser.password = @params[:edituser][:password]
      end
    end
  end
end

But I have the other problem: how to make password field to be blank by
default, on update user detalis page? Not 40 digits hash pussword. Also
I have problem with updating user birthday date, can anybody tell the
raason? Full dascription here http://www.ruby-forum.com/topic/52250
Cf7e5e4b5ca573eec214191fac420a2f?d=identicon&s=25 Dave Silvester (Guest)
on 2006-02-01 01:34
(Received via mailing list)
On Saturday 21 Jan 2006 09:32, Alex Rudnitski wrote:
> But I have the other problem: how to make password field to be blank by
> default, on update user detalis page? Not 40 digits hash pussword.

I initially got this working by using password_field_tag rather than
password_field on my form, so it just creates the blank password fields
and
never puts the values from the model in them.  Combine that with the
crypt_unless_empty stuff, and you have quite a neat solution, so for
example,
in my form where the user can update their own password I had (THIS IS
NOT MY
FINAL SOLUTION):

<p><label for="user_password">Password</label><br/>
<%= password_field_tag 'user[password]' %></p>

<p><label for="user_password_confirmation">Confirm Password</label><br/>
<%= password_field_tag 'user[password_confirmation]' %></p>


Whenever there is a model error and you have to re-enter something, the
password fields do not retain what you just typed in them, meaning you
have
to type it again. I think this is a fairly standard thing to do - or at
least, hardly unexpected behaviour?  (Net result if you then didn't type
anything in before updating would be that the password would not change,
so
no major disaster there.)


HOWEVER, in order to trick the model into accepting these parameters,
you have
to include the square brackets in the fieldname, which then gives you
invalid
IDs in your HTML.  I couldn't spot a way to manually set the ID on
password_field_tag, so instead I just went for the simplest option,
which was
to specify the HTML directly instead of using helpers go generate it:


<p><label for="user_password">Password</label><br/>
<input id="user_password" name="user[password]" type="password" /></p>

<p><label for="user_password_confirmation">Confirm Password</label><br/>
<input id="user_password_confirmation"
name="user[password_confirmation]"
type="password" /></p>


I'm not sure if that would be considered an un-Rails-like way of doing
it, but
it's extremely simple and it works, so I don't think it's too much of a
sin
overall, unless anyone thinks otherwise?  It follows the KISS principle
at
least.  ;-)

Cheers,

~Dave

--

Dave Silvester
Rent-A-Monkey Website Development
http://www.rentamonkey.com/

PGP Key: http://www.rentamonkey.com/pgpkey.asc
Cf7e5e4b5ca573eec214191fac420a2f?d=identicon&s=25 Dave Silvester (Guest)
on 2006-02-01 01:40
(Received via mailing list)
On Wednesday 01 Feb 2006 00:32, Dave Silvester wrote:
> Whenever there is a model error

D'uh, I meant a "validation" error, not a "model" error... excuse the
brainfart!

~Dave

--

Dave Silvester
Rent-A-Monkey Website Development
http://www.rentamonkey.com/

PGP Key: http://www.rentamonkey.com/pgpkey.asc
This topic is locked and can not be replied to.