Description:
add ip whitelisting
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r755:17c54fa350f2 - - 2 files changed: 49 inserted, 7 deleted

@@ -1,138 +1,167
1 + require 'ipaddr'
2 +
1 class ApplicationController < ActionController::Base
3 class ApplicationController < ActionController::Base
2 protect_from_forgery
4 protect_from_forgery
3
5
4 before_action :current_user
6 before_action :current_user
5
7
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
9 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
10 + ALLOW_WHITELIST_IP_ONLY_CONF_KEY = 'right.allow_whitelist_ip_only'
11 + WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
8
12
9 #report and redirect for unauthorized activities
13 #report and redirect for unauthorized activities
10 def unauthorized_redirect
14 def unauthorized_redirect
11 flash[:notice] = 'You are not authorized to view the page you requested'
15 flash[:notice] = 'You are not authorized to view the page you requested'
12 redirect_to :controller => 'main', :action => 'login'
16 redirect_to :controller => 'main', :action => 'login'
13 end
17 end
14
18
15 # Returns the current logged-in user (if any).
19 # Returns the current logged-in user (if any).
16 def current_user
20 def current_user
17 return nil unless session[:user_id]
21 return nil unless session[:user_id]
18 @current_user ||= User.find(session[:user_id])
22 @current_user ||= User.find(session[:user_id])
19 end
23 end
20
24
21 def admin_authorization
25 def admin_authorization
22 return false unless authenticate
26 return false unless authenticate
23 user = User.includes(:roles).find(session[:user_id])
27 user = User.includes(:roles).find(session[:user_id])
24 unless user.admin?
28 unless user.admin?
25 unauthorized_redirect
29 unauthorized_redirect
26 return false
30 return false
27 end
31 end
28 return true
32 return true
29 end
33 end
30
34
31 def authorization_by_roles(allowed_roles)
35 def authorization_by_roles(allowed_roles)
32 return false unless authenticate
36 return false unless authenticate
33 user = User.find(session[:user_id])
37 user = User.find(session[:user_id])
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
38 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
35 unauthorized_redirect
39 unauthorized_redirect
36 return false
40 return false
37 end
41 end
38 end
42 end
39
43
40 def testcase_authorization
44 def testcase_authorization
41 #admin always has privileged
45 #admin always has privileged
42 if @current_user.admin?
46 if @current_user.admin?
43 return true
47 return true
44 end
48 end
45
49
46 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
50 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
47 end
51 end
48
52
53 +
49 protected
54 protected
50
55
56 + #redirect to root (and also force logout)
57 + #if the user is not logged_in or the system is in "ADMIN ONLY" mode
51 def authenticate
58 def authenticate
52 unless session[:user_id]
59 unless session[:user_id]
53 flash[:notice] = 'You need to login'
60 flash[:notice] = 'You need to login'
54 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
61 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
55 flash[:notice] = 'You need to login but you cannot log in at this time'
62 flash[:notice] = 'You need to login but you cannot log in at this time'
56 end
63 end
57 redirect_to :controller => 'main', :action => 'login'
64 redirect_to :controller => 'main', :action => 'login'
58 return false
65 return false
59 end
66 end
60
67
61 -
62 # check if run in single user mode
68 # check if run in single user mode
63 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
69 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
64 - if @current_user==nil or (not @current_user.admin?)
70 + if @current_user==nil || (not @current_user.admin?)
65 flash[:notice] = 'You cannot log in at this time'
71 flash[:notice] = 'You cannot log in at this time'
66 redirect_to :controller => 'main', :action => 'login'
72 redirect_to :controller => 'main', :action => 'login'
67 return false
73 return false
68 end
74 end
69 - return true
70 end
75 end
71
76
72 # check if the user is enabled
77 # check if the user is enabled
73 - unless @current_user.enabled? or @current_user.admin?
78 + unless @current_user.enabled? || @current_user.admin?
74 flash[:notice] = 'Your account is disabled'
79 flash[:notice] = 'Your account is disabled'
75 redirect_to :controller => 'main', :action => 'login'
80 redirect_to :controller => 'main', :action => 'login'
76 return false
81 return false
77 end
82 end
78
83
84 + # check if user ip is allowed
85 + unless @current_user.admin? || !GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
86 + unless is_request_ip_allowed?
87 + flash[:notice] = 'Your IP is not allowed'
88 + redirect_to root_path
89 + end
90 + end
91 +
79 if GraderConfiguration.multicontests?
92 if GraderConfiguration.multicontests?
80 return true if @current_user.admin?
93 return true if @current_user.admin?
81 begin
94 begin
82 if @current_user.contest_stat(true).forced_logout
95 if @current_user.contest_stat(true).forced_logout
83 flash[:notice] = 'You have been automatically logged out.'
96 flash[:notice] = 'You have been automatically logged out.'
84 redirect_to :controller => 'main', :action => 'index'
97 redirect_to :controller => 'main', :action => 'index'
85 end
98 end
86 rescue
99 rescue
87 end
100 end
88 end
101 end
89 return true
102 return true
90 end
103 end
91
104
105 + #redirect to root (and also force logout)
106 + #if the user use different ip from the previous connection
107 + # only applicable when MULTIPLE_IP_LOGIN options is false only
92 def authenticate_by_ip_address
108 def authenticate_by_ip_address
93 #this assume that we have already authenticate normally
109 #this assume that we have already authenticate normally
94 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
110 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
95 user = User.find(session[:user_id])
111 user = User.find(session[:user_id])
96 - if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
112 + if (not @current_user.admin? && user.last_ip && user.last_ip != request.remote_ip)
97 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
113 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
98 redirect_to :controller => 'main', :action => 'login'
114 redirect_to :controller => 'main', :action => 'login'
99 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
115 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
100 return false
116 return false
101 end
117 end
102 unless user.last_ip
118 unless user.last_ip
103 user.last_ip = request.remote_ip
119 user.last_ip = request.remote_ip
104 user.save
120 user.save
105 end
121 end
106 end
122 end
107 return true
123 return true
108 end
124 end
109
125
110 def authorization
126 def authorization
111 return false unless authenticate
127 return false unless authenticate
112 user = User.find(session[:user_id])
128 user = User.find(session[:user_id])
113 unless user.roles.detect { |role|
129 unless user.roles.detect { |role|
114 role.rights.detect{ |right|
130 role.rights.detect{ |right|
115 right.controller == self.class.controller_name and
131 right.controller == self.class.controller_name and
116 - (right.action == 'all' or right.action == action_name)
132 + (right.action == 'all' || right.action == action_name)
117 }
133 }
118 }
134 }
119 flash[:notice] = 'You are not authorized to view the page you requested'
135 flash[:notice] = 'You are not authorized to view the page you requested'
120 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
136 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
121 redirect_to :controller => 'main', :action => 'login'
137 redirect_to :controller => 'main', :action => 'login'
122 return false
138 return false
123 end
139 end
124 end
140 end
125
141
126 def verify_time_limit
142 def verify_time_limit
127 return true if session[:user_id]==nil
143 return true if session[:user_id]==nil
128 user = User.find(session[:user_id], :include => :site)
144 user = User.find(session[:user_id], :include => :site)
129 - return true if user==nil or user.site == nil
145 + return true if user==nil || user.site == nil
130 if user.contest_finished?
146 if user.contest_finished?
131 flash[:notice] = 'Error: the contest you are participating is over.'
147 flash[:notice] = 'Error: the contest you are participating is over.'
132 redirect_to :back
148 redirect_to :back
133 return false
149 return false
134 end
150 end
135 return true
151 return true
136 end
152 end
137
153
154 + def is_request_ip_allowed?
155 + if GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
156 + user_ip = IPAddr.new(request.remote_ip)
157 + GraderConfiguration[WHITELIST_IP_LIST_CONF_KEY].delete(' ').split(',').each do |ips|
158 + allow_ips = IPAddr.new(ips)
159 + unless allow_ips.includes(user_ip)
160 + return false
138 end
161 end
162 + end
163 + end
164 + return true
165 + end
166 +
167 + end
@@ -152,48 +152,61
152 :default_value => 'false'
152 :default_value => 'false'
153 },
153 },
154
154
155 {
155 {
156 :key => 'contest.confirm_indv_contest_start',
156 :key => 'contest.confirm_indv_contest_start',
157 :value_type => 'boolean',
157 :value_type => 'boolean',
158 :default_value => 'false'
158 :default_value => 'false'
159 },
159 },
160
160
161 {
161 {
162 :key => 'contest.default_contest_name',
162 :key => 'contest.default_contest_name',
163 :value_type => 'string',
163 :value_type => 'string',
164 :default_value => 'none',
164 :default_value => 'none',
165 :description => "New user will be assigned to this contest automatically, if it exists. Set to 'none' if there is no default contest."
165 :description => "New user will be assigned to this contest automatically, if it exists. Set to 'none' if there is no default contest."
166 },
166 },
167
167
168 {
168 {
169 :key => 'system.use_problem_group',
169 :key => 'system.use_problem_group',
170 :value_type => 'boolean',
170 :value_type => 'boolean',
171 :default_value => 'false',
171 :default_value => 'false',
172 :description => "If true, available problem to the user will be only ones associated with the group of the user."
172 :description => "If true, available problem to the user will be only ones associated with the group of the user."
173 },
173 },
174
174
175
175
176 + {
177 + :key => 'right.whitelist_ip_only',
178 + :value_type => 'boolean',
179 + :default_value => 'false',
180 + :description => "If true, non-admin user will be able to use the system only when their ip is in the 'whitelist_ip'."
181 + },
182 +
183 + {
184 + :key => 'right.whitelist_ip',
185 + :value_type => 'string',
186 + :default_value => '0.0.0.0/0',
187 + :description => "list of whitelist ip, given in comma separated CIDR notation. For example '161.200.92.0/23, 161.200.80.1/32'"
188 + },
176
189
177 ]
190 ]
178
191
179
192
180 def create_configuration_key(key,
193 def create_configuration_key(key,
181 value_type,
194 value_type,
182 default_value,
195 default_value,
183 description='')
196 description='')
184 conf = (GraderConfiguration.find_by_key(key) ||
197 conf = (GraderConfiguration.find_by_key(key) ||
185 GraderConfiguration.new(:key => key,
198 GraderConfiguration.new(:key => key,
186 :value_type => value_type,
199 :value_type => value_type,
187 :value => default_value))
200 :value => default_value))
188 conf.description = description
201 conf.description = description
189 conf.save
202 conf.save
190 end
203 end
191
204
192 def seed_config
205 def seed_config
193 CONFIGURATIONS.each do |conf|
206 CONFIGURATIONS.each do |conf|
194 if conf.has_key? :description
207 if conf.has_key? :description
195 desc = conf[:description]
208 desc = conf[:description]
196 else
209 else
197 desc = ''
210 desc = ''
198 end
211 end
199 create_configuration_key(conf[:key],
212 create_configuration_key(conf[:key],
You need to be logged in to leave comments. Login now