Description:
increases max password length to 50
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r776:20ee1ec7fa92 - - 1 file changed: 1 inserted, 1 deleted

@@ -1,369 +1,369
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_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
25 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
26
26
27 belongs_to :site
27 belongs_to :site
28 belongs_to :country
28 belongs_to :country
29
29
30 has_and_belongs_to_many :contests, -> { order(:name); uniq}
30 has_and_belongs_to_many :contests, -> { order(:name); uniq}
31
31
32 scope :activated_users, -> {where activated: true}
32 scope :activated_users, -> {where activated: true}
33
33
34 validates_presence_of :login
34 validates_presence_of :login
35 validates_uniqueness_of :login
35 validates_uniqueness_of :login
36 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
36 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
37 validates_length_of :login, :within => 3..30
37 validates_length_of :login, :within => 3..30
38
38
39 validates_presence_of :full_name
39 validates_presence_of :full_name
40 validates_length_of :full_name, :minimum => 1
40 validates_length_of :full_name, :minimum => 1
41
41
42 validates_presence_of :password, :if => :password_required?
42 validates_presence_of :password, :if => :password_required?
43 - validates_length_of :password, :within => 4..20, :if => :password_required?
43 + validates_length_of :password, :within => 4..50, :if => :password_required?
44 validates_confirmation_of :password, :if => :password_required?
44 validates_confirmation_of :password, :if => :password_required?
45
45
46 validates_format_of :email,
46 validates_format_of :email,
47 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
47 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
48 :if => :email_validation?
48 :if => :email_validation?
49 validate :uniqueness_of_email_from_activated_users,
49 validate :uniqueness_of_email_from_activated_users,
50 :if => :email_validation?
50 :if => :email_validation?
51 validate :enough_time_interval_between_same_email_registrations,
51 validate :enough_time_interval_between_same_email_registrations,
52 :if => :email_validation?
52 :if => :email_validation?
53
53
54 # these are for ytopc
54 # these are for ytopc
55 # disable for now
55 # disable for now
56 #validates_presence_of :province
56 #validates_presence_of :province
57
57
58 attr_accessor :password
58 attr_accessor :password
59
59
60 before_save :encrypt_new_password
60 before_save :encrypt_new_password
61 before_save :assign_default_site
61 before_save :assign_default_site
62 before_save :assign_default_contest
62 before_save :assign_default_contest
63
63
64 # this is for will_paginate
64 # this is for will_paginate
65 cattr_reader :per_page
65 cattr_reader :per_page
66 @@per_page = 50
66 @@per_page = 50
67
67
68 def self.authenticate(login, password)
68 def self.authenticate(login, password)
69 user = find_by_login(login)
69 user = find_by_login(login)
70 if user
70 if user
71 return user if user.authenticated?(password)
71 return user if user.authenticated?(password)
72 end
72 end
73 end
73 end
74
74
75 def authenticated?(password)
75 def authenticated?(password)
76 if self.activated
76 if self.activated
77 hashed_password == User.encrypt(password,self.salt)
77 hashed_password == User.encrypt(password,self.salt)
78 else
78 else
79 false
79 false
80 end
80 end
81 end
81 end
82
82
83 def admin?
83 def admin?
84 self.roles.detect {|r| r.name == 'admin' }
84 self.roles.detect {|r| r.name == 'admin' }
85 end
85 end
86
86
87 def email_for_editing
87 def email_for_editing
88 if self.email==nil
88 if self.email==nil
89 "(unknown)"
89 "(unknown)"
90 elsif self.email==''
90 elsif self.email==''
91 "(blank)"
91 "(blank)"
92 else
92 else
93 self.email
93 self.email
94 end
94 end
95 end
95 end
96
96
97 def email_for_editing=(e)
97 def email_for_editing=(e)
98 self.email=e
98 self.email=e
99 end
99 end
100
100
101 def alias_for_editing
101 def alias_for_editing
102 if self.alias==nil
102 if self.alias==nil
103 "(unknown)"
103 "(unknown)"
104 elsif self.alias==''
104 elsif self.alias==''
105 "(blank)"
105 "(blank)"
106 else
106 else
107 self.alias
107 self.alias
108 end
108 end
109 end
109 end
110
110
111 def alias_for_editing=(e)
111 def alias_for_editing=(e)
112 self.alias=e
112 self.alias=e
113 end
113 end
114
114
115 def activation_key
115 def activation_key
116 if self.hashed_password==nil
116 if self.hashed_password==nil
117 encrypt_new_password
117 encrypt_new_password
118 end
118 end
119 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
119 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
120 end
120 end
121
121
122 def verify_activation_key(key)
122 def verify_activation_key(key)
123 key == activation_key
123 key == activation_key
124 end
124 end
125
125
126 def self.random_password(length=5)
126 def self.random_password(length=5)
127 chars = 'abcdefghjkmnopqrstuvwxyz'
127 chars = 'abcdefghjkmnopqrstuvwxyz'
128 password = ''
128 password = ''
129 length.times { password << chars[rand(chars.length - 1)] }
129 length.times { password << chars[rand(chars.length - 1)] }
130 password
130 password
131 end
131 end
132
132
133 def self.find_non_admin_with_prefix(prefix='')
133 def self.find_non_admin_with_prefix(prefix='')
134 users = User.all
134 users = User.all
135 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
135 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
136 end
136 end
137
137
138 # Contest information
138 # Contest information
139
139
140 def self.find_users_with_no_contest()
140 def self.find_users_with_no_contest()
141 users = User.all
141 users = User.all
142 return users.find_all { |u| u.contests.length == 0 }
142 return users.find_all { |u| u.contests.length == 0 }
143 end
143 end
144
144
145
145
146 def contest_time_left
146 def contest_time_left
147 if GraderConfiguration.contest_mode?
147 if GraderConfiguration.contest_mode?
148 return nil if site==nil
148 return nil if site==nil
149 return site.time_left
149 return site.time_left
150 elsif GraderConfiguration.indv_contest_mode?
150 elsif GraderConfiguration.indv_contest_mode?
151 time_limit = GraderConfiguration.contest_time_limit
151 time_limit = GraderConfiguration.contest_time_limit
152 if time_limit == nil
152 if time_limit == nil
153 return nil
153 return nil
154 end
154 end
155 if contest_stat==nil or contest_stat.started_at==nil
155 if contest_stat==nil or contest_stat.started_at==nil
156 return (Time.now.gmtime + time_limit) - Time.now.gmtime
156 return (Time.now.gmtime + time_limit) - Time.now.gmtime
157 else
157 else
158 finish_time = contest_stat.started_at + time_limit
158 finish_time = contest_stat.started_at + time_limit
159 current_time = Time.now.gmtime
159 current_time = Time.now.gmtime
160 if current_time > finish_time
160 if current_time > finish_time
161 return 0
161 return 0
162 else
162 else
163 return finish_time - current_time
163 return finish_time - current_time
164 end
164 end
165 end
165 end
166 else
166 else
167 return nil
167 return nil
168 end
168 end
169 end
169 end
170
170
171 def contest_finished?
171 def contest_finished?
172 if GraderConfiguration.contest_mode?
172 if GraderConfiguration.contest_mode?
173 return false if site==nil
173 return false if site==nil
174 return site.finished?
174 return site.finished?
175 elsif GraderConfiguration.indv_contest_mode?
175 elsif GraderConfiguration.indv_contest_mode?
176 return false if self.contest_stat(true)==nil
176 return false if self.contest_stat(true)==nil
177 return contest_time_left == 0
177 return contest_time_left == 0
178 else
178 else
179 return false
179 return false
180 end
180 end
181 end
181 end
182
182
183 def contest_started?
183 def contest_started?
184 if GraderConfiguration.indv_contest_mode?
184 if GraderConfiguration.indv_contest_mode?
185 stat = self.contest_stat
185 stat = self.contest_stat
186 return ((stat != nil) and (stat.started_at != nil))
186 return ((stat != nil) and (stat.started_at != nil))
187 elsif GraderConfiguration.contest_mode?
187 elsif GraderConfiguration.contest_mode?
188 return true if site==nil
188 return true if site==nil
189 return site.started
189 return site.started
190 else
190 else
191 return true
191 return true
192 end
192 end
193 end
193 end
194
194
195 def update_start_time
195 def update_start_time
196 stat = self.contest_stat
196 stat = self.contest_stat
197 if stat.nil? or stat.started_at.nil?
197 if stat.nil? or stat.started_at.nil?
198 stat ||= UserContestStat.new(:user => self)
198 stat ||= UserContestStat.new(:user => self)
199 stat.started_at = Time.now.gmtime
199 stat.started_at = Time.now.gmtime
200 stat.save
200 stat.save
201 end
201 end
202 end
202 end
203
203
204 def problem_in_user_contests?(problem)
204 def problem_in_user_contests?(problem)
205 problem_contests = problem.contests.all
205 problem_contests = problem.contests.all
206
206
207 if problem_contests.length == 0 # this is public contest
207 if problem_contests.length == 0 # this is public contest
208 return true
208 return true
209 end
209 end
210
210
211 contests.each do |contest|
211 contests.each do |contest|
212 if problem_contests.find {|c| c.id == contest.id }
212 if problem_contests.find {|c| c.id == contest.id }
213 return true
213 return true
214 end
214 end
215 end
215 end
216 return false
216 return false
217 end
217 end
218
218
219 def available_problems_group_by_contests
219 def available_problems_group_by_contests
220 contest_problems = []
220 contest_problems = []
221 pin = {}
221 pin = {}
222 contests.enabled.each do |contest|
222 contests.enabled.each do |contest|
223 available_problems = contest.problems.available
223 available_problems = contest.problems.available
224 contest_problems << {
224 contest_problems << {
225 :contest => contest,
225 :contest => contest,
226 :problems => available_problems
226 :problems => available_problems
227 }
227 }
228 available_problems.each {|p| pin[p.id] = true}
228 available_problems.each {|p| pin[p.id] = true}
229 end
229 end
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
231 contest_problems << {
231 contest_problems << {
232 :contest => nil,
232 :contest => nil,
233 :problems => other_avaiable_problems
233 :problems => other_avaiable_problems
234 }
234 }
235 return contest_problems
235 return contest_problems
236 end
236 end
237
237
238 def solve_all_available_problems?
238 def solve_all_available_problems?
239 available_problems.each do |p|
239 available_problems.each do |p|
240 u = self
240 u = self
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
242 return false if !p or !sub or sub.points < p.full_score
242 return false if !p or !sub or sub.points < p.full_score
243 end
243 end
244 return true
244 return true
245 end
245 end
246
246
247 #get a list of available problem
247 #get a list of available problem
248 def available_problems
248 def available_problems
249 if not GraderConfiguration.multicontests?
249 if not GraderConfiguration.multicontests?
250 if GraderConfiguration.use_problem_group?
250 if GraderConfiguration.use_problem_group?
251 return available_problems_in_group
251 return available_problems_in_group
252 else
252 else
253 return Problem.available_problems
253 return Problem.available_problems
254 end
254 end
255 else
255 else
256 contest_problems = []
256 contest_problems = []
257 pin = {}
257 pin = {}
258 contests.enabled.each do |contest|
258 contests.enabled.each do |contest|
259 contest.problems.available.each do |problem|
259 contest.problems.available.each do |problem|
260 if not pin.has_key? problem.id
260 if not pin.has_key? problem.id
261 contest_problems << problem
261 contest_problems << problem
262 end
262 end
263 pin[problem.id] = true
263 pin[problem.id] = true
264 end
264 end
265 end
265 end
266 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
266 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
267 return contest_problems + other_avaiable_problems
267 return contest_problems + other_avaiable_problems
268 end
268 end
269 end
269 end
270
270
271 def available_problems_in_group
271 def available_problems_in_group
272 problem = []
272 problem = []
273 self.groups.each do |group|
273 self.groups.each do |group|
274 group.problems.where(available: true).each { |p| problem << p }
274 group.problems.where(available: true).each { |p| problem << p }
275 end
275 end
276 problem.uniq!
276 problem.uniq!
277 if problem
277 if problem
278 problem.sort! do |a,b|
278 problem.sort! do |a,b|
279 case
279 case
280 when a.date_added < b.date_added
280 when a.date_added < b.date_added
281 1
281 1
282 when a.date_added > b.date_added
282 when a.date_added > b.date_added
283 -1
283 -1
284 else
284 else
285 a.name <=> b.name
285 a.name <=> b.name
286 end
286 end
287 end
287 end
288 return problem
288 return problem
289 else
289 else
290 return []
290 return []
291 end
291 end
292 end
292 end
293
293
294 def can_view_problem?(problem)
294 def can_view_problem?(problem)
295 return true if admin?
295 return true if admin?
296 return available_problems.include? problem
296 return available_problems.include? problem
297 end
297 end
298
298
299 def self.clear_last_login
299 def self.clear_last_login
300 User.update_all(:last_ip => nil)
300 User.update_all(:last_ip => nil)
301 end
301 end
302
302
303 protected
303 protected
304 def encrypt_new_password
304 def encrypt_new_password
305 return if password.blank?
305 return if password.blank?
306 self.salt = (10+rand(90)).to_s
306 self.salt = (10+rand(90)).to_s
307 self.hashed_password = User.encrypt(self.password,self.salt)
307 self.hashed_password = User.encrypt(self.password,self.salt)
308 end
308 end
309
309
310 def assign_default_site
310 def assign_default_site
311 # have to catch error when migrating (because self.site is not available).
311 # have to catch error when migrating (because self.site is not available).
312 begin
312 begin
313 if self.site==nil
313 if self.site==nil
314 self.site = Site.find_by_name('default')
314 self.site = Site.find_by_name('default')
315 if self.site==nil
315 if self.site==nil
316 self.site = Site.find(1) # when 'default has be renamed'
316 self.site = Site.find(1) # when 'default has be renamed'
317 end
317 end
318 end
318 end
319 rescue
319 rescue
320 end
320 end
321 end
321 end
322
322
323 def assign_default_contest
323 def assign_default_contest
324 # have to catch error when migrating (because self.site is not available).
324 # have to catch error when migrating (because self.site is not available).
325 begin
325 begin
326 if self.contests.length == 0
326 if self.contests.length == 0
327 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
327 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
328 if default_contest
328 if default_contest
329 self.contests = [default_contest]
329 self.contests = [default_contest]
330 end
330 end
331 end
331 end
332 rescue
332 rescue
333 end
333 end
334 end
334 end
335
335
336 def password_required?
336 def password_required?
337 self.hashed_password.blank? || !self.password.blank?
337 self.hashed_password.blank? || !self.password.blank?
338 end
338 end
339
339
340 def self.encrypt(string,salt)
340 def self.encrypt(string,salt)
341 Digest::SHA1.hexdigest(salt + string)
341 Digest::SHA1.hexdigest(salt + string)
342 end
342 end
343
343
344 def uniqueness_of_email_from_activated_users
344 def uniqueness_of_email_from_activated_users
345 user = User.activated_users.find_by_email(self.email)
345 user = User.activated_users.find_by_email(self.email)
346 if user and (user.login != self.login)
346 if user and (user.login != self.login)
347 self.errors.add(:base,"Email has already been taken")
347 self.errors.add(:base,"Email has already been taken")
348 end
348 end
349 end
349 end
350
350
351 def enough_time_interval_between_same_email_registrations
351 def enough_time_interval_between_same_email_registrations
352 return if !self.new_record?
352 return if !self.new_record?
353 return if self.activated
353 return if self.activated
354 open_user = User.find_by_email(self.email,
354 open_user = User.find_by_email(self.email,
355 :order => 'created_at DESC')
355 :order => 'created_at DESC')
356 if open_user and open_user.created_at and
356 if open_user and open_user.created_at and
357 (open_user.created_at > Time.now.gmtime - 5.minutes)
357 (open_user.created_at > Time.now.gmtime - 5.minutes)
358 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
358 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
359 end
359 end
360 end
360 end
361
361
362 def email_validation?
362 def email_validation?
363 begin
363 begin
364 return VALIDATE_USER_EMAILS
364 return VALIDATE_USER_EMAILS
365 rescue
365 rescue
366 return false
366 return false
367 end
367 end
368 end
368 end
369 end
369 end
You need to be logged in to leave comments. Login now