Description:
fix pop3 authen
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r395:52cd3037bb5e - - 1 file changed: 2 inserted, 1 deleted

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