Description:
fix cucas authen, the old code work on 2.1.2 but not 1.9.2
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r407:b11b67ad58fb - - 1 file changed: 8 inserted, 1 deleted

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