Skip to content

Commit

Permalink
Merge 87a38ee into 9c2b6bb
Browse files Browse the repository at this point in the history
  • Loading branch information
lshepstone committed Dec 22, 2014
2 parents 9c2b6bb + 87a38ee commit 9d0a087
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ group :assets do
end

group :test, :development do
gem 'factory_girl_rails'
gem 'pry-rails'
gem 'timecop'
end

group :test do
Expand Down
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ GEM
diff-lcs (1.2.5)
erubis (2.7.0)
execjs (2.2.2)
factory_girl (4.5.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.5.0)
factory_girl (~> 4.5.0)
railties (>= 3.0.0)
hike (1.2.3)
hitimes (1.2.2)
i18n (0.6.11)
Expand Down Expand Up @@ -158,6 +163,7 @@ GEM
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
timecop (0.7.1)
timers (4.0.1)
hitimes
tzinfo (1.2.2)
Expand All @@ -176,6 +182,7 @@ DEPENDENCIES
capybara
coffee-rails (~> 4.0.0)
dough-ruby!
factory_girl_rails
jquery-rails
launchy
pg
Expand All @@ -185,4 +192,5 @@ DEPENDENCIES
sass-rails (~> 4.0.4)
sidekiq
site_prism
timecop
uglifier (>= 1.3.0)
19 changes: 19 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ class ApplicationController < ActionController::Base
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception

before_action :authenticate

def display_search_box_in_header?
false
end
Expand All @@ -26,4 +28,21 @@ def display_adviser_sign_in?
end

helper_method :display_adviser_sign_in?

private

def authenticate
authenticate_token or redirect_to(error_path) unless current_user
end

def current_user
@current_user ||= Principal.find_by!(id: session[:user_id]) if session.key?(:user_id)
end

def authenticate_token
@current_user = Principal.authenticate(params[:token]) do |principal|
session[:user_id] = principal.id
principal
end
end
end
2 changes: 2 additions & 0 deletions app/controllers/contacts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class ContactsController < ApplicationController
before_action :authenticate, except: [:create]

def create
@message = ContactForm.new(params[:contact])

Expand Down
4 changes: 4 additions & 0 deletions app/controllers/firms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class FirmsController < ApplicationController
def index
end
end
6 changes: 6 additions & 0 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class PagesController < ApplicationController
before_action :authenticate, except: [:error]

def error
end
end
2 changes: 2 additions & 0 deletions app/controllers/principals_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class PrincipalsController < ApplicationController
skip_before_filter :authenticate

def pre_qualification_form
@prequalification = PreQualificationForm.new
end
Expand Down
8 changes: 8 additions & 0 deletions app/models/principal.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
class Principal < ActiveRecord::Base
before_create :generate_token

def self.authenticate(token)
principal = self.find_by(token: token)
if principal
principal.touch(:last_sign_in_at)
yield(principal)
end
end

private

def generate_token
Expand Down
7 changes: 7 additions & 0 deletions app/views/firms/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<main role="main">
<div class="l-constrained">
<div class="l-constrained__padded">
<h2>Firms</h2>
</div>
</div>
</main>
7 changes: 7 additions & 0 deletions app/views/pages/error.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<main role="main">
<div class="l-constrained">
<div class="l-constrained__padded">
<h2>Error</h2>
</div>
</div>
</main>
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Rails.application.routes.draw do
root 'principals#pre_qualification_form'

get 'error', to: 'pages#error'

resources :principals do
collection do
get 'prequalify', action: 'pre_qualification_form'
Expand All @@ -10,4 +12,5 @@
end

resource :contact, only: :create
resources :firms, only: :index
end
5 changes: 5 additions & 0 deletions db/migrate/20141222150416_add_last_sign_in_at_to_principal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddLastSignInAtToPrincipal < ActiveRecord::Migration
def change
add_column :principals, :last_sign_in_at, :datetime
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20141221140208) do
ActiveRecord::Schema.define(version: 20141222150416) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -37,6 +37,7 @@
t.boolean "confirmed_disclaimer", default: false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "last_sign_in_at"
end

add_index "principals", ["fca_number"], name: "index_principals_on_fca_number", unique: true, using: :btree
Expand Down
4 changes: 4 additions & 0 deletions spec/factories/principal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FactoryGirl.define do
factory :principal do
end
end
34 changes: 34 additions & 0 deletions spec/features/verify_principal_email_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
RSpec.feature 'Verify principal e-mail address' do
let(:firms_page) { FirmsPage.new }

before { Timecop.freeze(Time.local(1990)) }
after { Timecop.return }

scenario 'when the link in the confirmation e-mail is followed' do
given_i_am_a_verified_principal
when_i_follow_the_customised_link
then_my_email_is_verified
and_i_see_the_firms_page
end

def given_i_am_a_verified_principal
@principal = FactoryGirl.create(:principal)
end

def when_i_follow_the_customised_link
firms_page.load(query: {token: @principal.token})
end

def then_my_email_is_verified
@principal.reload

# We use the presence of a last sign-in date as an indication
# that the principal's e-mail address is valid (they received
# a link with their personal token in a confirmation e-mail).
expect(@principal.last_sign_in_at).to eql(Time.now)
end

def and_i_see_the_firms_page
expect(firms_page).to be_displayed
end
end
29 changes: 29 additions & 0 deletions spec/requests/token_authentication_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
RSpec.describe 'Token Authentication', type: :request do
let(:principal) { FactoryGirl.create(:principal) }

describe 'GET /firms' do
before do
get firms_path(token: token)
end

context 'with a valid token' do
let(:token) { principal.token }

it 'returns 200 response' do
expect(response.status).to be(200)
end
end

context 'with an invalid token' do
let(:token) { 'invalid-token' }

it 'returns 302 response' do
expect(response.status).to be(302)
end

it 'redirects to the error page' do
expect(response).to redirect_to(error_path)
end
end
end
end
4 changes: 4 additions & 0 deletions spec/support/error_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class ErrorPage < SitePrism::Page
set_url '/error'
set_url_matcher /\/error/
end
4 changes: 4 additions & 0 deletions spec/support/firms_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class FirmsPage < SitePrism::Page
set_url '/firms{?query*}'
set_url_matcher /\/firms(:?(\?.*)?)$/
end

0 comments on commit 9d0a087

Please sign in to comment.