Permalink
Browse files

add UI for forgot password workflow

  • Loading branch information...
1 parent 272b082 commit 072ebdbab9fa22a8dbaa4d83555d32a7dda17c4e @phlipper committed May 6, 2013
View
44 app/controllers/thincloud/authentication/passwords_controller.rb
@@ -0,0 +1,44 @@
+module Thincloud::Authentication
+ # Public: Handle password reset management
+ class PasswordsController < ApplicationController
+
+ before_filter :find_identity, only: [:edit, :update]
+
+ layout Thincloud::Authentication.configuration.layout
+
+ def new
+ render
+ end
+
+ def create
+ PasswordResetWorkflow.call(params[:email])
+ redirect_to login_url,
+ notice: "Email sent with password reset instructions."
+ end
+
+ def edit
+ render
+ end
+
+ def update
+ if UpdateIdentityPassword.call(@identity, identity_params)
+ login_as @identity.user
+ redirect_to after_password_update_path
+ else
+ render :edit
+ end
+ end
+
+
+ private
+
+ def find_identity
+ @identity = Identity.find_by_password_reset_token!(params[:id])
+ end
+
+ def identity_params
+ params.require(:identity).permit(:password, :password_confirmation)
+ end
+
+ end
+end
View
35 app/views/thincloud/authentication/passwords/edit.html.erb
@@ -0,0 +1,35 @@
+<%= form_for @identity, url: password_url(id: @identity.password_reset_token), method: :put do |f| %>
+ <fieldset>
+ <legend>Password Reset</legend>
+
+ <div class="control-group">
+ <%= f.label :password, "Password", class: "control-label" %>
+
+ <div class="controls">
+ <div class="input-prepend">
+ <span class="add-on"><i class="icon-envelope"></i></span>
+ <%= f.password_field :password %>
+ </div>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <%= f.label :password_confirmation, "Password Confirmation", class: "control-label" %>
+
+ <div class="controls">
+ <div class="input-prepend">
+ <span class="add-on"><i class="icon-envelope"></i></span>
+ <%= f.password_field :password_confirmation %>
+ </div>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls">
+ <%= button_tag type: "submit", class: "btn btn-large btn-primary" do %>
+ <i class="icon-ok icon-white"></i> Submit
+ <% end %>
+ </div>
+ </div>
+ </fieldset>
+<% end %>
View
31 app/views/thincloud/authentication/passwords/new.html.erb
@@ -0,0 +1,31 @@
+<%= form_tag passwords_url, method: :post do %>
+ <fieldset>
+ <legend>Password Reset</legend>
+
+ <div class="control-group">
+ <%= label_tag :email, "Email", class: "control-label" %>
+
+ <div class="controls">
+ <div class="input-prepend">
+ <span class="add-on"><i class="icon-envelope"></i></span>
+ <%= email_field_tag :email %>
+ </div>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls">
+ <%= button_tag type: "submit", class: "btn btn-large btn-primary" do %>
+ <i class="icon-ok icon-white"></i> Submit
+ <% end %>
+
+ or
+
+ <%= link_to login_url, class: "btn btn-large" do %>
+ <i class="icon-user"></i> Login
+ <% end %>
+ </div>
+ </div>
+
+ </fieldset>
+<% end %>
View
4 app/views/thincloud/authentication/sessions/_login_form.html.erb
@@ -42,5 +42,9 @@
<% end %>
</div>
</div>
+
+ <div class="control-group">
+ <%= link_to "Forgot Password?", new_password_url %>
+ </div>
</fieldset>
<% end %>
View
2 config/routes.rb
@@ -10,5 +10,7 @@
get "signup", to: "registrations#new", as: "signup"
get "verify/:token", to: "registrations#verify", as: "verify_token"
+ resources :passwords, only: [:new, :edit, :create, :update]
+
root to: "sessions#new"
end
View
6 lib/thincloud/authentication/authenticatable_controller.rb
@@ -91,6 +91,12 @@ def after_verification_path
main_app.root_url
end
+ # Protected: Provides the URL to redirect to after a password update.
+ #
+ # Returns: A string.
+ def after_password_update_path
+ main_app.root_url
+ end
end
View
88 test/controllers/thincloud/authentication/passwords_controller_test.rb
@@ -0,0 +1,88 @@
+require "minitest_helper"
+
+module Thincloud::Authentication
+ describe PasswordsController do
+ describe "GET new" do
+ before { get :new }
+
+ it { assert_response :success }
+ it { assert_template :new }
+ end
+
+ describe "POST create" do
+ before do
+ PasswordResetWorkflow.expects(:call).with("foo@bar.com")
+ post :create, email: "foo@bar.com"
+ end
+
+ it { assert_response :redirect }
+ it { assert_redirected_to login_url }
+ it {
+ flash[:notice].must_equal(
+ "Email sent with password reset instructions."
+ )
+ }
+ end
+
+ describe "GET edit" do
+ describe "with an invalid id" do
+ it "raises an exception" do
+ -> {
+ get :edit, id: "invalid"
+ }.must_raise(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ describe "with a valid id" do
+ let(:identity) { Identity.new(password_reset_token: "abc123") }
+
+ before do
+ Identity.stubs(:find_by_password_reset_token!).with("abc123").returns(
+ identity
+ )
+ get :edit, id: "abc123"
+ end
+
+ it { assert_response :success }
+ it { assert_template :edit }
+ it { assigns[:identity].must_equal identity }
+ end
+ end
+
+ describe "PUT update" do
+ before do
+ attrs = {
+ name: "test", email: "foo@bar.com", password: "test123",
+ password_confirmation: "test123", password_reset_token: "abc123",
+ password_reset_sent_at: 1.hour.ago, user_id: User.create.id
+ }
+ @identity = Identity.create!(attrs)
+ end
+
+ describe "with invalid identity attributes" do
+ before do
+ put :update, id: "abc123", identity: {
+ password: "xxx1", password_confirmation: "xxx2"
+ }
+ end
+
+ it { assert_response :success }
+ it { assert_template :edit }
+ it { assigns[:identity].must_equal @identity }
+ it { assigns[:identity].errors[:password].wont_be_empty }
+ end
+
+ describe "with valid identity attributes" do
+ before do
+ put :update, id: "abc123", identity: {
+ password: "p@ssw0rd1", password_confirmation: "p@ssw0rd1"
+ }
+ end
+
+ it { assert_response :redirect }
+ it { assert_redirected_to "/" }
+ end
+ end
+
+ end
+end
View
2 test/dummy/config/routes.rb
@@ -14,6 +14,8 @@
resources :registrations, only: [:new, :create]
get "signup", to: "registrations#new", as: "signup"
get "verify/:token", to: "registrations#verify", as: "verify_token"
+
+ resources :passwords, only: [:new, :edit, :create, :update]
end
end

0 comments on commit 072ebdb

Please sign in to comment.