とりあえず、Restful Authentication with all the bells and whistlesを、順番に追っかけてみましょうかね。
app/models/user.mailer.rbに、
- forgot_password
- reset_password
の、2つのメソッドを追加。
こんな感じ。
def forgot_password(user)setup_email(user)@subject += 'You have requested to change your password'@body[:url] = "http://localhost:3000/reset_password/#{user.password_reset_code}"enddef reset_password(user)setup_email(user)@subject += 'Your password has been reset.'end
はい。
次に、app/models/user_observer.rbに追記。
UserMailer.deliver_forgot_password(user) if user.recently_forgot_password?UserMailer.deliver_reset_password(user) if user.recently_reset_password?
で、次に、って、アレ?
permission云々って、書いてあるな...
んー、飛ばすwww
で、app/models/user.rbに
- forgot_password
- reset_password
- recently_forgot_password?
- recently_reset_password?
- make_password_reset_code (protected)
を追加。
以下、コード。
# Forgot passworddef forgot_password@forgotten_password = trueself.make_password_reset_codeend# Reset passworddef reset_password# First update the password_reset_code before setting the# reset_password flag to avoid duplicate email notifications.update_attribute(:password_reset_code, nil)@reset_password = trueend#used in user_observerdef recently_forgot_password?@forgotten_passwordenddef recently_reset_password?@reset_passwordend(略)protected(略)def make_password_reset_codeself.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )end
こんな感じですか。
次。lib/authenticated_system.rbを書き換えてるようですが、permission絡みみたいなんで、飛ばす。
次は、app/controller/users_controller.rb。
とりあえず、indexとeditとupdateのメソッドの追加。
def index@users = User.find(:all)end# render edit.html.erbdef edit@user = current_userenddef update@user = User.find(current_user)if @user.update_attributes(params[:user])flash[:notice] = "User updated"redirect_to :action => 'show', :id => current_userelserender :action => 'edit'endend
ほい。
updateは、viewが無いんだね。
そりゃそうだwww
次は、app/controllers/sessions_controller.rb。
...なんかいるか?
...飛ばすwww
次。
ん?
passwords_controller.rb?
accounts_controller.rb?
roles_controller.rb?
ん?
飛ばすwww
んで?
application.html.erbも、飛ばす。
なんか、role絡みのコードが入ってるし。後だね、後。
次は、app/views/passwords/edit.html.erb。
あれ?
app/views/passwords/new.html.erbとapp/views/accounts/edit.html.erbも、とりあえず、飛ばそう。
あ、そうか!
これ、password変更のロジックだな。
おk。後回しwww
んで、...
なんか、role関係のviewが続くんで、まとめて飛ばし。
次。
やっとだよwww
app/views/sesisons/new.html.erb。
まあ、別にどうでも良いんだけど、とりあえず、users_controllerのnewアクションへのリンクを足す。
new_user_pathなんて云う書き方、今、はじめて気が付いたwww
"アクション名_コントローラ名(単数系)_path"で、そのurlが生成できるんだな。
イヤ、便利っぽくない?www
後で書き換えよう:-)
app/views/user_mailer/activation.erb
<%= h @user.real_name %>, your account has been activated. Welcome aboard!<%=h @url %>
@user.loginは、loginを削除してしまっているんで、real_nameメソッドを使って、本名を使うようにした。
後述のforgot_password.erbとreset_password.erbも一緒。
app/views/user_mailer/forgot_password.erb
<%= h @user.real_name %>, your account has been activated. To visit the site, follow the link below:
<%= @url %>
app/views/user_mailer/reset_password.erb
<%= h @user.real_name %>, Your password has been reset
こんな感じ?
app/views/user_mailer/signup_notification.html.erbは、real_nameとemailを使って、passwordは送らないようにしましょうか。再発行できるんだから、ね?
Your account has been created.Real Name: <%= h @user.real_name %>Email: <%= h @user.email %>Password: <%= h @user.password %>Visit this url to activate your account:<%= h @url %>
って、あれ?
だとすると、さっき飛ばしたロジック、入れとかないと、マズいよね?
じゃあ、入れましょうか。
$ script/generate controller Passwords$ script/generate controller Accounts
んで、
app/controllers/passwords_controller.rb
class PasswordsController <>skip_before_filter :login_required :only => [:new, :creat]
:not_logged_in_required, :only => [:new, :create]# Enter email address to recover passworddef newend# Forgot password actiondef createreturn unless request.post?if @user = User.find_for_forget(params[:email])@user.forgot_password@user.saveflash[:notice] = "A password reset link has been sent to your email address."redirect_to login_pathelseflash[:notice] = "Could not find a user with that email address."render :action => 'new'endend# Action triggered by clicking on the /reset_password/:id link recieved via email# Makes sure the id code is included# Checks that the id code matches a user in the database# Then if everything checks out, shows the password reset fieldsdef editif params[:id].nil?render :action => 'new'returnend@user = User.find_by_password_reset_code(params[:id]) if params[:id]raise if @user.nil?rescuelogger.error "Invalid Reset Code entered."flash[:notice] = "Sorry - That is an invalid password reset code. Please check your code and try again. (Perhaps your email client inserted a carriage return?)"#redirect_back_or_default('/')redirect_to new_user_pathend# Reset password action /reset_password/:id# Checks once again that an id is included and makes sure that the password field isn't blankdef updateif params[:id].nil?render :action => 'new'returnendif params[:password].blank?flash[:notice] = "Password field cannot be blank."render :action => 'edit', :id => params[:id]returnend@user = User.find_by_password_reset_code(params[:id]) if params[:id]raise if @user.nil?return if @user unless params[:password]if (params[:password] == params[:password_confirmation])#Uncomment and comment lines with @user to have the user logged in after reset - not recommended#self.current_user = @user #for the next two lines to work#current_user.password_confirmation = params[:password_confirmation]#current_user.password = params[:password]#@user.reset_password#flash[:notice] = current_user.save ? "Password reset" : "Password not reset"@user.password_confirmation = params[:password_confirmation]@user.password = params[:password]@user.reset_passwordflash[:notice] = @user.save ? "Password reset." : "Password not reset."elseflash[:notice] = "Password mismatch."render :action => 'edit', :id => params[:id]returnendredirect_to login_pathrescuelogger.error "Invalid Reset Code entered"flash[:notice] = "Sorry - That is an invalid password reset code. Please check your code and try again. (Perhaps your email client inserted a carriage return?)"redirect_to new_user_pathendend
ほぼベタ張りwww
しっかし、長えな、これwww
ロジックがどう動いているのか、サッパリ理解してないぞwww
続いて、app/controllers/accounts_controller.rb。
class AccountsController <>skip_before_filter :login_required :only => [:show]before_filter :not_logged_in_required, :only => :show# Activate actiondef show# Uncomment and change paths to have user logged in after activation - not recommended#self.current_user = User.find_and_activate!(params[:id])User.find_and_activate!(params[:id])flash[:notice] = "Your account has been activated! You can now login."redirect_to login_pathrescue User::ArgumentErrorflash[:notice] = 'Activation code not found. Please try creating a new account.'redirect_to new_user_pathrescue User::ActivationCodeNotFoundflash[:notice] = 'Activation code not found. Please try creating a new account.'redirect_to new_user_pathrescue User::AlreadyActivatedflash[:notice] = 'Your account has already been activated. You can log in below.'redirect_to login_pathenddef editend# Change password actiondef updatereturn unless request.post?if User.authenticate(current_user.email, params[:old_password])if ((params[:password] == params[:password_confirmation]) && !params[:password_confirmation].blank?)current_user.password_confirmation = params[:password_confirmation]current_user.password = params[:password]if current_user.saveflash[:notice] = "Password successfully updated."redirect_to root_path #profile_url(current_user.login)elseflash[:error] = "An error occured, your password was not changed."render :action => 'edit'endelseflash[:error] = "New password does not match the password confirmation."@old_password = params[:old_password]render :action => 'edit'endelseflash[:error] = "Your old password is incorrect."render :action => 'edit'endendend
つうか、ね?
newアクション、いるのか?www
あと、User.authenticateでcurrent_user.loginを放り込んでるから、current_user.emailに変更ね。
んじゃあ、viewも作りましょうか。
app/views/passwords/edit.html.erb
<% form_tag url_for(:action => "update", :id => params[:id]) do %>Password:<br /><%= password_field_tag :password %><br />Confirm Password:<br /><%= password_field_tag :password_confirmation %><br /><%= submit_tag "Reset Your Password" %><% end %>
app/views/passwords/new.html.erb
<h2>Forgot Password</h2><% form_tag url_for(:action => 'create') do %>What is the email address used to create your account?<br /><%= text_field_tag :email, "", :size => 50 %><br /><%= submit_tag 'Reset Password' %><% end %>
app/views/accounts/edit.html.erb
<% form_tag url_for(:action => "update") do %><p><label for="old_password" class="block">Old Password</label><br /><%= password_field_tag 'old_password', @old_password, :size => 45 %></p><p><label for="password" class="block">New Password</label><br /><%= password_field_tag 'password', {}, :size => 45 %><br /><small>Between 4 and 40 characters</small></p><p><label for="password_confirmation" class="block">Confirm new password</label><br /><%= password_field_tag 'password_confirmation', {}, :size => 45 %></p><%= submit_tag 'Change password' %><% end %>
な感じで。
何も変えてないぞwwww
んで、config/routes.rbに以下を追記。
map.forgot_password '/forgot_password', :controller => 'passwords', :action => 'new'map.reset_password '/reset_password/:id', :controller => 'passwords', :action => 'edit'map.change_password '/change_password', :controller => 'accounts', :action => 'edit'map.resources :users, :member => { :enable => :put } do |users|users.resource :accountusers.resources :rolesendmap.resource :password
こんな感じで、いいんじゃね?
ね?
0 件のコメント:
コメントを投稿