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