Commit 33064d7a by Mai Hoang Thai Ha

Merge branch 'basic-login' into 'master'

Implement basic login

See merge request !7
parents 3d0e9d16 1c3a26b5
Pipeline #1263 failed with stages
in 0 seconds
......@@ -179,3 +179,21 @@ input {
color: $state-danger-text;
}
}
@media (max-width: 800px) {
footer {
small {
display: block;
float: none;
margin-bottom: 1em;
}
ul {
float: none;
padding: 0;
li {
float: none;
margin-left: 0;
}
}
}
}
\ No newline at end of file
// Place all the styles related to the Sessions controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
class ApplicationController < ActionController::Base
def hello
render html: "hello, world!"
end
include SessionsHelper
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])
log_in user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out
redirect_to root_url
end
end
......@@ -11,6 +11,7 @@ class UsersController < ApplicationController
def create
@user = User.new(user_params)
if @user.save
log_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
......
module SessionsHelper
#Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Return the curent lofed-in user (if any)
def current_user
if session[:user_id]
@current_user ||= User.find_by(id: session[:user_id])
end
end
# Return true if the user is loffed in, false otherwise
def logged_in?
!current_user.nil?
end
def log_out
session.delete(:user_id)
@current_user = nil
end
end
......@@ -13,6 +13,9 @@ import "channels"
//= require bootstrap-sprockets
//= require_tree .
require("jquery")
import "bootstrap"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
......@@ -7,4 +7,11 @@ class User < ApplicationRecord
uniqueness: true
has_secure_password
validates :password, presence: true, length: {minimum: 6}
# Returns the hash digest of the given string
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
end
\ No newline at end of file
......@@ -2,10 +2,41 @@
<div class="container">
<%= link_to "sample app", root_path, id: "logo" %>
<nav>
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<ul class="nav navbar-nav navbar-right collapse navbar-collapse"
id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Help", help_path %></li>
<li><%= link_to "Log in", '#' %></li>
<% if logged_in? %>
<li><%= link_to "Users", '#' %></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle='dropdown'>
Account <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Profile", current_user %></li>
<li><%= link_to "Settings", '#' %></li>
<li class="divider"></li>
<li>
<%= link_to "Log out", logout_path, method: :delete %>
</li>
</ul>
</li>
<% else %>
<li><%= link_to "Log in", login_path %></li>
<% end %>
</ul>
</nav>
</div>
......
<% provide(:title, "Log in") %>
<h1>Log in</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(url: login_path, scope: :session, local: true) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
\ No newline at end of file
Rails.application.routes.draw do
get 'sessions/new'
get 'users/new'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery'
})
)
module.exports = environment
......@@ -6,6 +6,8 @@
"@rails/activestorage": "^6.0.0",
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.4.0",
"bootstrap": "3.4.1",
"jquery": "3.4.1",
"turbolinks": "^5.2.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12"
......
require "test_helper"
class SessionsControllerTest < ActionDispatch::IntegrationTest
test "should get new" do
get login_path
assert_response :success
end
end
#empty
\ No newline at end of file
michael:
name: Michael Example
email: michael@example.com
password_digest: <%= User.digest('password') %>
\ No newline at end of file
require "test_helper"
class UsersLoginTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "login with valid email/invalid password" do
get login_path
assert_template 'sessions/new'
post login_path, params: { session: { email: @user.email,
password: "invalid" } }
assert_not is_logged_in?
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
test "login with valid information followed by logout" do
get login_path
post login_path, params: { session: { email: @user.email,
password: 'password' } }
assert is_logged_in?
assert_redirected_to @user
follow_redirect!
assert_template 'users/show'
assert_select "a[href=?]", login_path, count: 0
assert_select "a[href=?]", logout_path
assert_select "a[href=?]", user_path(@user)
delete logout_path
assert_not is_logged_in?
assert_redirected_to root_url
follow_redirect!
assert_select "a[href=?]", login_path
assert_select "a[href=?]", logout_path, count: 0
assert_select "a[href=?]", user_path(@user), count: 0
end
end
......@@ -22,5 +22,6 @@ class UsersSignupTest < ActionDispatch::IntegrationTest
end
follow_redirect!
assert_template 'users/show'
assert is_logged_in?
end
end
......@@ -12,4 +12,7 @@ class ActiveSupport::TestCase
fixtures :all
# Add more helper methods to be used by all tests here...
def is_logged_in?
!session[:user_id].nil?
end
end
......@@ -1491,6 +1491,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap@3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72"
integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
......@@ -3733,6 +3738,11 @@ jest-worker@^26.5.0:
merge-stream "^2.0.0"
supports-color "^7.0.0"
jquery@3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
......
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