Description:
use uuid cookie
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r852:41c96ab8e589 - - 3 files changed: 20 inserted, 2 deleted

@@ -1,152 +1,160
1 1 require 'ipaddr'
2 + require "securerandom"
2 3
3 4 class ApplicationController < ActionController::Base
4 5 protect_from_forgery
5 6
6 7 before_action :current_user
7 8 before_action :nav_announcement
9 + before_action :unique_visitor_id
8 10
9 11 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
10 12 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
11 13 WHITELIST_IGNORE_CONF_KEY = 'right.whitelist_ignore'
12 14 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
13 15
14 16 #report and redirect for unauthorized activities
15 17 def unauthorized_redirect(notice = 'You are not authorized to view the page you requested')
16 18 flash[:notice] = notice
17 19 redirect_to login_main_path
18 20 end
19 21
20 22 # Returns the current logged-in user (if any).
21 23 def current_user
22 24 return nil unless session[:user_id]
23 25 @current_user ||= User.find(session[:user_id])
24 26 end
25 27
26 28 def nav_announcement
27 29 @nav_announcement = Announcement.where(on_nav_bar: true)
28 30 end
29 31
30 32 def admin_authorization
31 33 return false unless check_valid_login
32 34 user = User.includes(:roles).find(session[:user_id])
33 35 unless user.admin?
34 36 unauthorized_redirect
35 37 return false
36 38 end
37 39 return true
38 40 end
39 41
40 42 def authorization_by_roles(allowed_roles)
41 43 return false unless check_valid_login
42 44 unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
43 45 unauthorized_redirect
44 46 return false
45 47 end
46 48 end
47 49
48 50 def testcase_authorization
49 51 #admin always has privileged
50 52 if @current_user.admin?
51 53 return true
52 54 end
53 55
54 56 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
55 57 end
56 58
59 + def unique_visitor_id
60 + unless cookies[:uuid]
61 + value = SecureRandom.uuid
62 + cookies[:uuid] = { value: value, expires: 20.year }
63 + end
64 + end
57 65
58 66 protected
59 67
60 68 #redirect to root (and also force logout)
61 69 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
62 70 def check_valid_login
63 71 #check if logged in
64 72 unless session[:user_id]
65 73 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
66 74 unauthorized_redirect('You need to login but you cannot log in at this time')
67 75 else
68 76 unauthorized_redirect('You need to login')
69 77 end
70 78 return false
71 79 end
72 80
73 81 # check if run in single user mode
74 82 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
75 83 if @current_user==nil || (!@current_user.admin?)
76 84 unauthorized_redirect('You cannot log in at this time')
77 85 return false
78 86 end
79 87 end
80 88
81 89 # check if the user is enabled
82 90 unless @current_user.enabled? || @current_user.admin?
83 91 unauthorized_redirect 'Your account is disabled'
84 92 return false
85 93 end
86 94
87 95 # check if user ip is allowed
88 96 unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
89 97 unless is_request_ip_allowed?
90 98 unauthorized_redirect 'Your IP is not allowed to login at this time.'
91 99 return false
92 100 end
93 101 end
94 102
95 103 if GraderConfiguration.multicontests?
96 104 return true if @current_user.admin?
97 105 begin
98 106 if @current_user.contest_stat(true).forced_logout
99 107 flash[:notice] = 'You have been automatically logged out.'
100 108 redirect_to :controller => 'main', :action => 'index'
101 109 end
102 110 rescue
103 111 end
104 112 end
105 113 return true
106 114 end
107 115
108 116 #redirect to root (and also force logout)
109 117 #if the user use different ip from the previous connection
110 118 # only applicable when MULTIPLE_IP_LOGIN options is false only
111 119 def authenticate_by_ip_address
112 120 #this assume that we have already authenticate normally
113 121 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
114 122 user = User.find(session[:user_id])
115 123 if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip)
116 124 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
117 125 redirect_to :controller => 'main', :action => 'login'
118 126 return false
119 127 end
120 128 unless user.last_ip
121 129 user.last_ip = request.remote_ip
122 130 user.save
123 131 end
124 132 end
125 133 return true
126 134 end
127 135
128 136 def authorization
129 137 return false unless check_valid_login
130 138 user = User.find(session[:user_id])
131 139 unless user.roles.detect { |role|
132 140 role.rights.detect{ |right|
133 141 right.controller == self.class.controller_name and
134 142 (right.action == 'all' || right.action == action_name)
135 143 }
136 144 }
137 145 flash[:notice] = 'You are not authorized to view the page you requested'
138 146 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
139 147 redirect_to :controller => 'main', :action => 'login'
140 148 return false
141 149 end
142 150 end
143 151
144 152 def verify_time_limit
145 153 return true if session[:user_id]==nil
146 154 user = User.find(session[:user_id], :include => :site)
147 155 return true if user==nil || user.site == nil
148 156 if user.contest_finished?
149 157 flash[:notice] = 'Error: the contest you are participating is over.'
150 158 redirect_to :back
151 159 return false
152 160 end
@@ -1,89 +1,99
1 1 class LoginController < ApplicationController
2 2
3 3 @@authenticators = []
4 4
5 5 def index
6 6 # show login screen
7 7 reset_session
8 8 redirect_to :controller => 'main', :action => 'login'
9 9 end
10 10
11 11 def login
12 12 user = get_authenticated_user(params[:login], params[:password])
13 13 unless user
14 14 flash[:notice] = 'Wrong password'
15 15 redirect_to :controller => 'main', :action => 'login'
16 16 return
17 17 end
18 18
19 19 if (!GraderConfiguration['right.bypass_agreement']) and (!params[:accept_agree]) and !user.admin?
20 20 flash[:notice] = 'You must accept the agreement before logging in'
21 21 redirect_to :controller => 'main', :action => 'login'
22 22 return
23 23 end
24 24
25 + #store uuid when login
26 + if user.last_ip.nil?
27 + user.last_ip = cookies[:uuid]
28 + else
29 + if user.last_ip != cookies[:uuid]
30 + user.last_ip =cookies[:uuid]
31 + #log different login
32 + end
33 + end
34 +
25 35 #process logging in
26 36 session[:user_id] = user.id
27 37 session[:admin] = user.admin?
28 38
29 39 # clear forced logout flag for multicontests contest change
30 40 if GraderConfiguration.multicontests?
31 41 contest_stat = user.contest_stat
32 42 if contest_stat.respond_to? :forced_logout
33 43 if contest_stat.forced_logout
34 44 contest_stat.forced_logout = false
35 45 contest_stat.save
36 46 end
37 47 end
38 48 end
39 49
40 50 #save login information
41 - Login.create(user_id: user.id, ip_address: request.remote_ip)
51 + Login.create(user_id: user.id, ip_address: cookies[:uuid])
42 52
43 53 redirect_to :controller => 'main', :action => 'list'
44 54 end
45 55
46 56 def site_login
47 57 begin
48 58 site = Site.find(params[:login][:site_id])
49 59 rescue ActiveRecord::RecordNotFound
50 60 site = nil
51 61 end
52 62 if site==nil
53 63 flash[:notice] = 'Wrong site'
54 64 redirect_to :controller => 'main', :action => 'login' and return
55 65 end
56 66 if (site.password) and (site.password == params[:login][:password])
57 67 session[:site_id] = site.id
58 68 redirect_to :controller => 'site', :action => 'index'
59 69 else
60 70 flash[:notice] = 'Wrong site password'
61 71 redirect_to :controller => 'site', :action => 'login'
62 72 end
63 73 end
64 74
65 75 def logout
66 76 redirect_to root_path
67 77 end
68 78
69 79 def self.add_authenticator(authenticator)
70 80 @@authenticators << authenticator
71 81 end
72 82
73 83 protected
74 84
75 85 def get_authenticated_user(login, password)
76 86 if @@authenticators.empty?
77 87 return User.authenticate(login, password)
78 88 else
79 89 user = User.authenticate(login, password)
80 90 @@authenticators.each do |authenticator|
81 91 if not user
82 92 user = authenticator.authenticate(login, password)
83 93 end
84 94 end
85 95 return user
86 96 end
87 97 end
88 98
89 99 end
@@ -1,139 +1,139
1 1 require 'digest/sha1'
2 2 require 'net/pop'
3 3 require 'net/https'
4 4 require 'net/http'
5 5 require 'json'
6 6
7 7 class User < ActiveRecord::Base
8 8
9 9 has_and_belongs_to_many :roles
10 10
11 11 #has_and_belongs_to_many :groups
12 12 has_many :groups_users, class_name: 'GroupUser'
13 13 has_many :groups, :through => :groups_users
14 14
15 15 has_many :test_requests, -> {order(submitted_at: :desc)}
16 16
17 17 has_many :messages, -> { order(created_at: :desc) },
18 18 :class_name => "Message",
19 19 :foreign_key => "sender_id"
20 20
21 21 has_many :replied_messages, -> { order(created_at: :desc) },
22 22 :class_name => "Message",
23 23 :foreign_key => "receiver_id"
24 24
25 25 has_many :logins
26 26
27 27 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
28 28
29 29 belongs_to :site
30 30 belongs_to :country
31 31
32 32 has_and_belongs_to_many :contests, -> { order(:name)}
33 33
34 34 scope :activated_users, -> {where activated: true}
35 35
36 36 validates_presence_of :login
37 37 validates_uniqueness_of :login
38 38 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
39 39 validates_length_of :login, :within => 3..30
40 40
41 41 validates_presence_of :full_name
42 42 validates_length_of :full_name, :minimum => 1
43 -
43 +
44 44 validates_presence_of :password, :if => :password_required?
45 45 validates_length_of :password, :within => 4..50, :if => :password_required?
46 46 validates_confirmation_of :password, :if => :password_required?
47 47
48 48 validates_format_of :email,
49 49 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
50 50 :if => :email_validation?
51 51 validate :uniqueness_of_email_from_activated_users,
52 52 :if => :email_validation?
53 53 validate :enough_time_interval_between_same_email_registrations,
54 54 :if => :email_validation?
55 55
56 56 # these are for ytopc
57 57 # disable for now
58 58 #validates_presence_of :province
59 59
60 60 attr_accessor :password
61 61
62 62 before_save :encrypt_new_password
63 63 before_save :assign_default_site
64 64 before_save :assign_default_contest
65 65
66 66 # this is for will_paginate
67 67 cattr_reader :per_page
68 68 @@per_page = 50
69 69
70 70 def self.authenticate(login, password)
71 71 user = find_by_login(login)
72 72 if user
73 73 return user if user.authenticated?(password)
74 74 end
75 75 end
76 76
77 77 def authenticated?(password)
78 78 if self.activated
79 79 hashed_password == User.encrypt(password,self.salt)
80 80 else
81 81 false
82 82 end
83 83 end
84 84
85 85 def login_with_name
86 86 "[#{login}] #{full_name}"
87 87 end
88 88
89 89 def admin?
90 90 has_role?('admin')
91 91 end
92 92
93 93 def has_role?(role)
94 94 self.roles.where(name: role).count > 0
95 95 end
96 96
97 97 def email_for_editing
98 98 if self.email==nil
99 99 "(unknown)"
100 100 elsif self.email==''
101 101 "(blank)"
102 102 else
103 103 self.email
104 104 end
105 105 end
106 106
107 107 def email_for_editing=(e)
108 108 self.email=e
109 109 end
110 110
111 111 def alias_for_editing
112 112 if self.alias==nil
113 113 "(unknown)"
114 114 elsif self.alias==''
115 115 "(blank)"
116 116 else
117 117 self.alias
118 118 end
119 119 end
120 120
121 121 def alias_for_editing=(e)
122 122 self.alias=e
123 123 end
124 124
125 125 def activation_key
126 126 if self.hashed_password==nil
127 127 encrypt_new_password
128 128 end
129 129 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
130 130 end
131 131
132 132 def verify_activation_key(key)
133 133 key == activation_key
134 134 end
135 135
136 136 def self.random_password(length=5)
137 137 chars = 'abcdefghjkmnopqrstuvwxyz'
138 138 password = ''
139 139 length.times { password << chars[rand(chars.length - 1)] }
You need to be logged in to leave comments. Login now