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

r406:b2fd7182e3dc - - 1 file changed: 3 inserted, 14 deleted

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