Commit 9c90e762 by Tô Ngọc Ánh

Merge branch 'sign-in-out' into 'master'

Sign in out

See merge request !6
parents a3a7461b b9374d4b
Pipeline #670 failed with stages
in 0 seconds
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
// Place all the styles related to the sessions controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
...@@ -2,4 +2,5 @@ class ApplicationController < ActionController::Base ...@@ -2,4 +2,5 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception. # Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead. # For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception protect_from_forgery with: :exception
include SessionsHelper
end end
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
# Sign the user in and redirect to the user's show page.
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
end
end
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
self.current_user = user
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
@current_user = user
end
def current_user
remember_token = User.digest(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
end
...@@ -4,5 +4,20 @@ class User < ActiveRecord::Base ...@@ -4,5 +4,20 @@ class User < ActiveRecord::Base
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 } validates :password, length: { minimum: 6 }
before_save { self.email = email.downcase } before_save { self.email = email.downcase }
before_create :create_remember_token
has_secure_password has_secure_password
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
end end
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<ul class="nav pull-right"> <ul class="nav pull-right">
<li><%= link_to "Home", home_path %></li> <li><%= link_to "Home", home_path %></li>
<li><%= link_to "Help", help_path %></li> <li><%= link_to "Help", help_path %></li>
<li><%= link_to "Sign in", '#' %></li> <li><%= link_to "Sign in", signin_path %></li>
</ul> </ul>
</nav> </nav>
</div> </div>
......
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
\ No newline at end of file
...@@ -42,7 +42,7 @@ Rails.application.configure do ...@@ -42,7 +42,7 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information # Use the lowest log level to ensure availability of diagnostic information
# when problems arise. # when problems arise.
......
...@@ -7,5 +7,8 @@ Rails.application.routes.draw do ...@@ -7,5 +7,8 @@ Rails.application.routes.draw do
get '/about', to: 'static_pages#about' get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact' get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new' get '/signup', to: 'users#new'
get '/signin', to: 'sessions#new'
delete '/signout', to: 'sessions#destroy'
resources :users resources :users
resources :sessions, only: [:new, :create, :destroy]
end end
class AddRememberTokenToUsers < ActiveRecord::Migration
def change
add_column :users, :remember_token, :string
add_index :users, :remember_token
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20200630043304) do ActiveRecord::Schema.define(version: 20200702072601) do
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "name" t.string "name"
...@@ -19,8 +19,10 @@ ActiveRecord::Schema.define(version: 20200630043304) do ...@@ -19,8 +19,10 @@ ActiveRecord::Schema.define(version: 20200630043304) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "password_digest" t.string "password_digest"
t.string "remember_token"
end end
add_index "users", ["email"], name: "index_users_on_email", unique: true add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["remember_token"], name: "index_users_on_remember_token"
end end
...@@ -93,4 +93,12 @@ describe User do ...@@ -93,4 +93,12 @@ describe User do
before { @user.password = @user.password_confirmation = "a" * 5 } before { @user.password = @user.password_confirmation = "a" * 5 }
it { should be_invalid } it { should be_invalid }
end end
it { should respond_to(:password_confirmation) }
it { should respond_to(:remember_token) }
it { should respond_to(:authenticate) }
describe "remember token" do
before { @user.save }
its(:remember_token) { should_not be_blank }
end
end end
require 'spec_helper'
describe "AuthenticationPages" do
subject { page }
describe "signin page" do
before { visit signin_path }
it { should have_content('Sign in') }
it { should have_title('Sign in') }
end
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_title('Sign in') }
it { should have_selector('div.alert.alert-error') }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before do
fill_in "Email", with: user.email.upcase
fill_in "Password", with: user.password
click_button "Sign in"
end
it { should have_title(user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment