Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sample_app
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Đường Sỹ Hoàng
sample_app
Commits
79cf8168
Commit
79cf8168
authored
Nov 14, 2019
by
Đường Sỹ Hoàng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement advanced login
parent
bf9c39bf
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
139 additions
and
11 deletions
+139
-11
app/assets/stylesheets/custom.scss
+14
-0
app/controllers/sessions_controller.rb
+7
-5
app/helpers/sessions_helper.rb
+27
-3
app/models/user.rb
+27
-0
app/views/layouts/application.html.erb
+1
-1
app/views/sessions/new.html.erb
+4
-0
db/migrate/20191113080850_add_remember_digest_to_users.rb
+5
-0
db/schema.rb
+2
-1
test/helpers/sessions_helper_test.rb
+20
-0
test/integration/users_login_test.rb
+15
-0
test/models/user_test.rb
+5
-1
test/test_helper.rb
+12
-0
No files found.
app/assets/stylesheets/custom.scss
View file @
79cf8168
...
...
@@ -176,3 +176,17 @@ input {
color
:
$state-danger-text
;
}
}
.checkbox
{
margin-top
:
-10px
;
margin-bottom
:
10px
;
span
{
margin-left
:
20px
;
font-weight
:
normal
;
}
}
#session_remember_me
{
width
:
auto
;
margin-left
:
0
;
}
app/controllers/sessions_controller.rb
View file @
79cf8168
...
...
@@ -4,10 +4,12 @@ class SessionsController < ApplicationController
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
@user
=
User
.
find_by
(
email:
params
[
:session
][
:email
].
downcase
)
if
@user
&&
@user
.
authenticate
(
params
[
:session
][
:password
])
log_in
@user
params
[
:session
][
:remember_me
]
==
"1"
?
remember
(
@user
)
:
forget
(
@user
)
#remember user
redirect_to
@user
else
flash
.
now
[
:danger
]
=
"Invalid email/password combination"
render
"new"
...
...
@@ -15,7 +17,7 @@ class SessionsController < ApplicationController
end
def
destroy
log_out
log_out
if
logged_in?
redirect_to
root_url
end
end
...
...
app/helpers/sessions_helper.rb
View file @
79cf8168
...
...
@@ -4,10 +4,24 @@ module SessionsHelper
session
[
:user_id
]
=
user
.
id
end
# Returns the current logged-in user (if any)
# Remembers a user in a persistent session.
def
remember
(
user
)
user
.
remember
cookies
.
permanent
.
signed
[
:user_id
]
=
user
.
id
cookies
.
permanent
[
:remember_token
]
=
user
.
remember_token
end
# Returns the user corresponding to the remember token cookie.
def
current_user
if
session
[
:user_id
]
@current_user
||=
User
.
find_by
(
id:
session
[
:user_id
])
if
(
user_id
=
session
[
:user_id
])
@current_user
||=
User
.
find_by
(
id:
user_id
)
elsif
(
user_id
=
cookies
.
signed
[
:user_id
])
#raise # The tests still pass, so this branch is currently untested.
user
=
User
.
find_by
(
id:
user_id
)
if
user
&&
user
.
authenticated?
(
cookies
[
:remember_token
])
log_in
user
@current_user
=
user
end
end
end
...
...
@@ -16,9 +30,19 @@ module SessionsHelper
current_user
.
present?
end
# Forgets a persistent session.
def
forget
(
user
)
user
.
forget
cookies
.
delete
(
:user_id
)
cookies
.
delete
(
:remember_token
)
end
# Logs out the current user
def
log_out
forget
(
current_user
)
session
.
delete
(
:user_id
)
@current_user
=
nil
end
end
app/models/user.rb
View file @
79cf8168
class
User
<
ApplicationRecord
VALID_EMAIL_REGEX
=
/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
attr_accessor
:remember_token
validates
:email
,
presence:
true
,
length:
{
maximum:
255
},
format:
{
with:
VALID_EMAIL_REGEX
}
validates
:name
,
presence:
true
,
length:
{
maximum:
50
},
uniqueness:
{
case_sensitive:
false
}
validates
:password
,
presence:
true
,
length:
{
minimum:
6
}
...
...
@@ -9,8 +11,33 @@ class User < ApplicationRecord
has_secure_password
# 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
# Returns a random token.
def
User
.
new_token
SecureRandom
.
urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions
def
remember
self
.
remember_token
=
User
.
new_token
update_attribute
(
:remember_digest
,
User
.
digest
(
remember_token
))
#BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
# Returns true if the given token matches the digest.
def
authenticated?
(
remember_token
)
return
false
if
remember_digest
.
nil?
BCrypt
::
Password
.
new
(
remember_digest
).
is_password?
(
remember_token
)
end
# Forgets a user.
def
forget
update_attribute
(
:remember_digest
,
nil
)
end
end
app/views/layouts/application.html.erb
View file @
79cf8168
...
...
@@ -13,7 +13,7 @@
</head>
<body>
<header
class=
"navbar navbar-fixed-top navbar-inverse"
>
<%=
render
'layouts/header'
%>
<%=
render
"layouts/header"
%>
<div
class=
"container"
>
<%=
link_to
"sample app"
,
"#"
,
id:
"logo"
%>
<nav>
...
...
app/views/sessions/new.html.erb
View file @
79cf8168
...
...
@@ -8,6 +8,10 @@
<%=
f
.
email_field
:email
,
class:
"form-control"
%>
<%=
f
.
label
:password
%>
<%=
f
.
password_field
:password
,
class:
"form-control"
%>
<%=
f
.
label
:remember_me
,
class:
"checkbox inline"
do
%>
<%=
f
.
check_box
:remember_me
%>
<span>
Remember me on this computer
</span>
<%
end
%>
<%=
f
.
submit
"Log in"
,
class:
"btn btn-primary"
%>
<%
end
%>
<p>
New user?
<%=
link_to
"Sign up now!"
,
signup_path
%>
</p>
...
...
db/migrate/20191113080850_add_remember_digest_to_users.rb
0 → 100644
View file @
79cf8168
class
AddRememberDigestToUsers
<
ActiveRecord
::
Migration
[
5.1
]
def
change
add_column
:users
,
:remember_digest
,
:string
end
end
db/schema.rb
View file @
79cf8168
...
...
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201911
08085254
)
do
ActiveRecord
::
Schema
.
define
(
version:
201911
13080850
)
do
create_table
"users"
,
force: :cascade
do
|
t
|
t
.
string
"name"
...
...
@@ -18,6 +18,7 @@ ActiveRecord::Schema.define(version: 20191108085254) do
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
string
"password_digest"
t
.
string
"remember_digest"
t
.
index
[
"email"
],
name:
"index_users_on_email"
,
unique:
true
end
...
...
test/helpers/sessions_helper_test.rb
0 → 100644
View file @
79cf8168
require
"test_helper"
class
SessionsHelperTest
<
ActionView
::
TestCase
def
setup
@user
=
users
(
:michael
)
remember
(
@user
)
end
test
"current_user returns right user when session is nil"
do
assert_equal
@user
,
current_user
assert
is_logged_in?
end
test
"current_user returns nil when remember digest is wrong"
do
@user
.
update_attribute
(
:remember_digest
,
User
.
digest
(
User
.
new_token
))
assert_nil
current_user
end
end
\ No newline at end of file
test/integration/users_login_test.rb
View file @
79cf8168
...
...
@@ -40,9 +40,24 @@ class UsersLoginTest < ActionDispatch::IntegrationTest
delete
logout_path
assert_not
is_logged_in?
assert_redirected_to
root_url
# Simulate a user clicking logout in a second window.
delete
logout_path
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
test
"login with remembering"
do
log_in_as
(
@user
,
remember_me:
"1"
)
assert_equal
cookies
[
"remember_token"
],
assigns
(
:user
).
remember_token
end
test
"login without remembering"
do
# Log in to set the cookie.
log_in_as
(
@user
,
remember_me:
"1"
)
# Log in again and verify that the cookie is deleted.
log_in_as
(
@user
,
remember_me:
"0"
)
assert_empty
cookies
[
:remember_token
]
end
end
test/models/user_test.rb
View file @
79cf8168
...
...
@@ -63,7 +63,7 @@ class UserTest < ActiveSupport::TestCase
end
test
"password should be present (nonblank)"
do
@user
.
password
=
@user
.
password_confirmation
=
"
"
*
6
@user
.
password
=
@user
.
password_confirmation
=
""
*
6
assert_not
@user
.
valid?
end
...
...
@@ -71,4 +71,8 @@ class UserTest < ActiveSupport::TestCase
@user
.
password
=
@user
.
password_confirmation
=
"a"
*
5
assert_not
@user
.
valid?
end
test
"authenticated? should return false for a user with nil digest"
do
assert_not
@user
.
authenticated?
(
""
)
end
end
test/test_helper.rb
View file @
79cf8168
...
...
@@ -11,4 +11,16 @@ class ActiveSupport::TestCase
def
is_logged_in?
session
[
:user_id
].
present?
end
# Log in as a particular user.
def
log_in_as
(
user
)
session
[
:user_id
]
=
user
.
id
end
end
class
ActionDispatch
::
IntegrationTest
# Log in as a particular user.
def
log_in_as
(
user
,
password:
"password"
,
remember_me:
"1"
)
post
login_path
,
params:
{
session:
{
email:
user
.
email
,
password:
password
,
remember_me:
remember_me
}
}
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment