summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorshumakl <shumakl@purdue.edu>2014-04-03 15:04:42 -0400
committershumakl <shumakl@purdue.edu>2014-04-03 15:04:42 -0400
commit9f19d0e16d7920e07255c0fbe596c518d1aa415f (patch)
tree52e3ee20ebff003449cf6d25584a8372944687ec /app
parentafaeb054e6ac35c186af9c563f85f8ac58076b81 (diff)
fix login with tokens belonging to sessions
Diffstat (limited to 'app')
-rw-r--r--app/controllers/users_controller.rb1
-rw-r--r--app/helpers/sessions_helper.rb31
-rw-r--r--app/models/session.rb39
-rw-r--r--app/models/user.rb66
4 files changed, 57 insertions, 80 deletions
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 8a8b994..60857f1 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -27,7 +27,6 @@ class UsersController < ApplicationController
# POST /users.json
def create
@user = User.new(user_params)
- @user.groups = 0
respond_to do |format|
if @user.save
sign_in @user
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index 9be3abc..54e4b0d 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -1,19 +1,13 @@
module SessionsHelper
-
def sign_in(user)
- #create a new remember token
- remember_token = User.new_remember_token
- #place token inside of the browser
- cookies.permanent[:remember_token] = remember_token
- #save the hashed token to the database
- user.update_attribute(:remember_token,
- User.hash(remember_token))
- #set the current user to be the given user
- self.current_user = user
- end
+ @session = Session.new(user: user)
+ raw_token = @session.create_token
+ @session.save # FIXME: error handling
- # The curret_user=(user) is the conversion of self.current_user = user
- def current_user=(user)
+ @token = Session.hash_token(raw_token)
+ cookies.permanent[:remember_token] = raw_token
+
+ #set the current user to be the given user
@current_user = user
end
@@ -22,8 +16,9 @@ module SessionsHelper
# since the remember token is hashed, we need to hash the cookie
# to find match the remember token
def current_user
- remember_token = User.hash(cookies[:remember_token])
- @current_user ||= User.find_by(remember_token: remember_token)
+ @token ||= Session.hash_token(cookies[:remember_token])
+ @session ||= Session.find_by(token: @token)
+ @current_user ||= (@session.nil? ? nil : @session.user)
end
# checks if someone is currently signed in
@@ -32,9 +27,11 @@ module SessionsHelper
end
def sign_out
- current_user.update_attribute(:remember_token, User.hash(User.new_remember_token))
+ if signed_in?
+ @session.destroy
+ end
+ @current_user = nil
cookies.delete(:remember_token)
- self.current_user = nil
end
# This is for anyone that cares about how long a user is signed
diff --git a/app/models/session.rb b/app/models/session.rb
index a5fd26e..f5e642b 100644
--- a/app/models/session.rb
+++ b/app/models/session.rb
@@ -1,3 +1,42 @@
class Session < ActiveRecord::Base
belongs_to :user
+
+ ##
+ # Create a random remember token for the user. This will be
+ # changed every time the user creates a new session.
+ #
+ # If you want this value, hang on to it; the raw value is
+ # discarded afterward.
+ #
+ # By changing the cookie every new session, any hijacked sessions
+ # (where the attacker steals a cookie to sign in as a certain
+ # user) will expire the next time the user signs back in.
+ #
+ # The random string is of length 16 composed of A-Z, a-z, 0-9
+ # This is the browser's cookie value.
+ def create_token()
+ t = SecureRandom.urlsafe_base64
+ self.token = Session.hash_token(t)
+ t
+ end
+
+ ##
+ # Encrypt the remember token.
+ # This is the encrypted version of the cookie stored on
+ # the database.
+ #
+ # The reasoning for storing a hashed token is so that even if
+ # the database is compromised, the attacker won't be able to use
+ # the remember tokens to sign in.
+ def Session.hash_token(token)
+ # SHA-1 (Secure Hash Algorithm) is a US engineered hash
+ # function that produces a 20 byte hash value which typically
+ # forms a hexadecimal number 40 digits long.
+ # The reason I am not using the Bcrypt algorithm is because
+ # SHA-1 is much faster and I will be calling this on
+ # every page a user accesses.
+ #
+ # https://en.wikipedia.org/wiki/SHA-1
+ Digest::SHA1.hexdigest(token.to_s)
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 85f1982..277d885 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -2,17 +2,14 @@ class User < ActiveRecord::Base
has_and_belongs_to_many :tournaments_played, class_name: "Tournament", foreign_key: "player_id", join_table: "players_tournaments"
has_and_belongs_to_many :tournaments_hosted, class_name: "Tournament", foreign_key: "host_id", join_table: "hosts_tournaments"
has_and_belongs_to_many :teams
+ has_many :sessions
before_save { self.email = email.downcase }
before_save { self.user_name = user_name }
- ##
- # Rails looks for the create_remember_token and runs the method
- # before anything else.
- #
- # This method cannot be called by a user since it is denoted
- # as private.
- before_create :create_remember_token
+ def after_initialize
+ self.permissions = 0
+ end
def in_group?(group)
case group
@@ -93,59 +90,4 @@ class User < ActiveRecord::Base
has_secure_password
validates :password, length: { minimum: 6 }
-
- ##
- # Create a random remember token for the user. This will be
- # changed every time the user creates a new session.
- #
- # By changing the cookie every new session, any hijacked sessions
- # (where the attacker steals a cookie to sign in as a certain
- # user) will expire the next time the user signs back in.
- #
- # The random string is of length 16 composed of A-Z, a-z, 0-9
- # This is the browser's cookie value.
- def User.new_remember_token
- SecureRandom.urlsafe_base64
- end
-
- ##
- # Encrypt the remember token.
- # This is the encrypted version of the cookie stored on
- # the database.
- #
- # The reasoning for storing a hashed token is so that even if
- # the database is compromised, the attacker won't be able to use
- # the remember tokens to sign in.
- def User.hash(token)
- Digest::SHA1.hexdigest(token.to_s)
- end
-
- ##
- # SHA-1 (Secure Hash Algorithm) is a US engineered hash
- # function that produces a 20 byte hash value which typically
- # forms a hexadecimal number 40 digits long.
- # The reason I am not using the Bcrypt algorithm is because
- # SHA-1 is much faster and I will be calling this on
- # every page a user accesses.
- #
- # https://en.wikipedia.org/wiki/SHA-1
-
-
- # Everything under private is hidden so you cannot call.
- private
-
- ##
- # Create_remember_token in order to ensure a user always has
- # a remember token.
- def create_remember_token
- self.remember_token = User.hash(User.new_remember_token)
- end
-
- ##
- # In order to ensure that someone did not accidentally submit
- # two accounts rapidly (which would throw off the validates
- # for user_name and email), I added an index to the Users
- # email and user_name in the database to ensure uniqueness
- # This also gives and index to the user_name and email
- # so finding a user SHOULD be easier for the database.
end