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: 55 inserted, 13 deleted

@@ -1,19 +1,23
1 + require 'ipaddr'
2 +
1 3 class ApplicationController < ActionController::Base
2 4 protect_from_forgery
3 5
4 6 before_action :current_user
5 7
6 8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
7 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 13 #report and redirect for unauthorized activities
10 14 def unauthorized_redirect
11 15 flash[:notice] = 'You are not authorized to view the page you requested'
12 16 redirect_to :controller => 'main', :action => 'login'
13 17 end
14 18
15 19 # Returns the current logged-in user (if any).
16 20 def current_user
17 21 return nil unless session[:user_id]
18 22 @current_user ||= User.find(session[:user_id])
19 23 end
@@ -37,102 +41,127
37 41 end
38 42 end
39 43
40 44 def testcase_authorization
41 45 #admin always has privileged
42 46 if @current_user.admin?
43 47 return true
44 48 end
45 49
46 50 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
47 51 end
48 52
53 +
49 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 58 def authenticate
52 59 unless session[:user_id]
53 60 flash[:notice] = 'You need to login'
54 61 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
55 62 flash[:notice] = 'You need to login but you cannot log in at this time'
56 63 end
57 64 redirect_to :controller => 'main', :action => 'login'
58 65 return false
59 66 end
60 67
61 -
62 68 # check if run in single user mode
63 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 71 flash[:notice] = 'You cannot log in at this time'
66 72 redirect_to :controller => 'main', :action => 'login'
67 73 return false
68 74 end
69 - return true
70 75 end
71 76
72 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 79 flash[:notice] = 'Your account is disabled'
75 80 redirect_to :controller => 'main', :action => 'login'
76 81 return false
77 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 92 if GraderConfiguration.multicontests?
80 93 return true if @current_user.admin?
81 94 begin
82 95 if @current_user.contest_stat(true).forced_logout
83 96 flash[:notice] = 'You have been automatically logged out.'
84 97 redirect_to :controller => 'main', :action => 'index'
85 98 end
86 99 rescue
87 100 end
88 101 end
89 102 return true
90 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 108 def authenticate_by_ip_address
93 109 #this assume that we have already authenticate normally
94 110 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
95 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 113 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
98 114 redirect_to :controller => 'main', :action => 'login'
99 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 116 return false
101 117 end
102 118 unless user.last_ip
103 119 user.last_ip = request.remote_ip
104 120 user.save
105 121 end
106 122 end
107 123 return true
108 124 end
109 125
110 126 def authorization
111 127 return false unless authenticate
112 128 user = User.find(session[:user_id])
113 129 unless user.roles.detect { |role|
114 130 role.rights.detect{ |right|
115 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 135 flash[:notice] = 'You are not authorized to view the page you requested'
120 136 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
121 137 redirect_to :controller => 'main', :action => 'login'
122 138 return false
123 139 end
124 140 end
125 141
126 142 def verify_time_limit
127 143 return true if session[:user_id]==nil
128 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 146 if user.contest_finished?
131 147 flash[:notice] = 'Error: the contest you are participating is over.'
132 148 redirect_to :back
133 149 return false
134 150 end
135 151 return true
136 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
161 + end
162 + end
163 + end
164 + return true
165 + end
166 +
138 167 end
@@ -164,69 +164,82
164 164 :default_value => 'none',
165 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 169 :key => 'system.use_problem_group',
170 170 :value_type => 'boolean',
171 171 :default_value => 'false',
172 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,
181 - value_type,
182 - default_value,
193 + def create_configuration_key(key,
194 + value_type,
195 + default_value,
183 196 description='')
184 - conf = (GraderConfiguration.find_by_key(key) ||
197 + conf = (GraderConfiguration.find_by_key(key) ||
185 198 GraderConfiguration.new(:key => key,
186 199 :value_type => value_type,
187 200 :value => default_value))
188 201 conf.description = description
189 202 conf.save
190 203 end
191 204
192 205 def seed_config
193 206 CONFIGURATIONS.each do |conf|
194 207 if conf.has_key? :description
195 208 desc = conf[:description]
196 209 else
197 210 desc = ''
198 211 end
199 - create_configuration_key(conf[:key],
212 + create_configuration_key(conf[:key],
200 213 conf[:value_type],
201 214 conf[:default_value],
202 215 desc)
203 216 end
204 217 end
205 218
206 219 def seed_roles
207 220 return if Role.find_by_name('admin')
208 221
209 222 role = Role.create(:name => 'admin')
210 223 user_admin_right = Right.create(:name => 'user_admin',
211 224 :controller => 'user_admin',
212 225 :action => 'all')
213 226 problem_admin_right = Right.create(:name=> 'problem_admin',
214 227 :controller => 'problems',
215 228 :action => 'all')
216 229
217 230 graders_right = Right.create(:name => 'graders_admin',
218 231 :controller => 'graders',
219 232 :action => 'all')
220 -
233 +
221 234 role.rights << user_admin_right;
222 235 role.rights << problem_admin_right;
223 236 role.rights << graders_right;
224 237 role.save
225 238 end
226 239
227 240 def seed_root
228 241 return if User.find_by_login('root')
229 242
230 243 root = User.new(:login => 'root',
231 244 :full_name => 'Administrator',
232 245 :alias => 'root')
You need to be logged in to leave comments. Login now