Description:
bring back cucas login to algo-bm
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r496:038086c2ebdc - - 1 file changed: 47 inserted, 0 deleted

@@ -1,176 +1,223
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_many :test_requests, :order => "submitted_at DESC"
11 has_many :test_requests, :order => "submitted_at DESC"
12
12
13 has_many :messages,
13 has_many :messages,
14 :class_name => "Message",
14 :class_name => "Message",
15 :foreign_key => "sender_id",
15 :foreign_key => "sender_id",
16 :order => 'created_at DESC'
16 :order => 'created_at DESC'
17
17
18 has_many :replied_messages,
18 has_many :replied_messages,
19 :class_name => "Message",
19 :class_name => "Message",
20 :foreign_key => "receiver_id",
20 :foreign_key => "receiver_id",
21 :order => 'created_at DESC'
21 :order => 'created_at DESC'
22
22
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24
24
25 belongs_to :site
25 belongs_to :site
26 belongs_to :country
26 belongs_to :country
27
27
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
29
29
30 scope :activated_users, :conditions => {:activated => true}
30 scope :activated_users, :conditions => {:activated => true}
31
31
32 validates_presence_of :login
32 validates_presence_of :login
33 validates_uniqueness_of :login
33 validates_uniqueness_of :login
34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
35 validates_length_of :login, :within => 3..30
35 validates_length_of :login, :within => 3..30
36
36
37 validates_presence_of :full_name
37 validates_presence_of :full_name
38 validates_length_of :full_name, :minimum => 1
38 validates_length_of :full_name, :minimum => 1
39
39
40 validates_presence_of :password, :if => :password_required?
40 validates_presence_of :password, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
43
43
44 validates_format_of :email,
44 validates_format_of :email,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
46 :if => :email_validation?
46 :if => :email_validation?
47 validate :uniqueness_of_email_from_activated_users,
47 validate :uniqueness_of_email_from_activated_users,
48 :if => :email_validation?
48 :if => :email_validation?
49 validate :enough_time_interval_between_same_email_registrations,
49 validate :enough_time_interval_between_same_email_registrations,
50 :if => :email_validation?
50 :if => :email_validation?
51
51
52 # these are for ytopc
52 # these are for ytopc
53 # disable for now
53 # disable for now
54 #validates_presence_of :province
54 #validates_presence_of :province
55
55
56 attr_accessor :password
56 attr_accessor :password
57
57
58 before_save :encrypt_new_password
58 before_save :encrypt_new_password
59 before_save :assign_default_site
59 before_save :assign_default_site
60 before_save :assign_default_contest
60 before_save :assign_default_contest
61
61
62 # this is for will_paginate
62 # this is for will_paginate
63 cattr_reader :per_page
63 cattr_reader :per_page
64 @@per_page = 50
64 @@per_page = 50
65
65
66 def self.authenticate(login, password)
66 def self.authenticate(login, password)
67 user = find_by_login(login)
67 user = find_by_login(login)
68 if user
68 if user
69 return user if user.authenticated?(password)
69 return user if user.authenticated?(password)
70 + if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
71 + user.password = password
72 + user.save
73 + return user
74 + end
70 end
75 end
71 end
76 end
72
77
73 def authenticated?(password)
78 def authenticated?(password)
74 if self.activated
79 if self.activated
75 hashed_password == User.encrypt(password,self.salt)
80 hashed_password == User.encrypt(password,self.salt)
76 else
81 else
77 false
82 false
78 end
83 end
79 end
84 end
80
85
86 + def authenticated_by_pop3?(password)
87 + Net::POP3.enable_ssl
88 + pop = Net::POP3.new('pops.it.chula.ac.th')
89 + authen = true
90 + begin
91 + pop.start(login, password)
92 + pop.finish
93 + return true
94 + rescue
95 + return false
96 + end
97 + end
98 +
99 + def authenticated_by_cucas?(password)
100 + url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
101 + appid = '41508763e340d5858c00f8c1a0f5a2bb'
102 + appsecret ='d9cbb5863091dbe186fded85722a1e31'
103 + post_args = {
104 + 'appid' => appid,
105 + 'appsecret' => appsecret,
106 + 'username' => login,
107 + 'password' => password
108 + }
109 +
110 + #simple call
111 + begin
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)
119 + result = JSON.parse resp.body
120 + end
121 + return true if result["type"] == "beanStudent"
122 + rescue
123 + return false
124 + end
125 + return false
126 + end
127 +
81 def admin?
128 def admin?
82 self.roles.detect {|r| r.name == 'admin' }
129 self.roles.detect {|r| r.name == 'admin' }
83 end
130 end
84
131
85 def email_for_editing
132 def email_for_editing
86 if self.email==nil
133 if self.email==nil
87 "(unknown)"
134 "(unknown)"
88 elsif self.email==''
135 elsif self.email==''
89 "(blank)"
136 "(blank)"
90 else
137 else
91 self.email
138 self.email
92 end
139 end
93 end
140 end
94
141
95 def email_for_editing=(e)
142 def email_for_editing=(e)
96 self.email=e
143 self.email=e
97 end
144 end
98
145
99 def alias_for_editing
146 def alias_for_editing
100 if self.alias==nil
147 if self.alias==nil
101 "(unknown)"
148 "(unknown)"
102 elsif self.alias==''
149 elsif self.alias==''
103 "(blank)"
150 "(blank)"
104 else
151 else
105 self.alias
152 self.alias
106 end
153 end
107 end
154 end
108
155
109 def alias_for_editing=(e)
156 def alias_for_editing=(e)
110 self.alias=e
157 self.alias=e
111 end
158 end
112
159
113 def activation_key
160 def activation_key
114 if self.hashed_password==nil
161 if self.hashed_password==nil
115 encrypt_new_password
162 encrypt_new_password
116 end
163 end
117 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
164 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
118 end
165 end
119
166
120 def verify_activation_key(key)
167 def verify_activation_key(key)
121 key == activation_key
168 key == activation_key
122 end
169 end
123
170
124 def self.random_password(length=5)
171 def self.random_password(length=5)
125 chars = 'abcdefghjkmnopqrstuvwxyz'
172 chars = 'abcdefghjkmnopqrstuvwxyz'
126 password = ''
173 password = ''
127 length.times { password << chars[rand(chars.length - 1)] }
174 length.times { password << chars[rand(chars.length - 1)] }
128 password
175 password
129 end
176 end
130
177
131 def self.find_non_admin_with_prefix(prefix='')
178 def self.find_non_admin_with_prefix(prefix='')
132 users = User.find(:all)
179 users = User.find(:all)
133 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
180 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
134 end
181 end
135
182
136 # Contest information
183 # Contest information
137
184
138 def self.find_users_with_no_contest()
185 def self.find_users_with_no_contest()
139 users = User.find(:all)
186 users = User.find(:all)
140 return users.find_all { |u| u.contests.length == 0 }
187 return users.find_all { |u| u.contests.length == 0 }
141 end
188 end
142
189
143
190
144 def contest_time_left
191 def contest_time_left
145 if GraderConfiguration.contest_mode?
192 if GraderConfiguration.contest_mode?
146 return nil if site==nil
193 return nil if site==nil
147 return site.time_left
194 return site.time_left
148 elsif GraderConfiguration.indv_contest_mode?
195 elsif GraderConfiguration.indv_contest_mode?
149 time_limit = GraderConfiguration.contest_time_limit
196 time_limit = GraderConfiguration.contest_time_limit
150 if time_limit == nil
197 if time_limit == nil
151 return nil
198 return nil
152 end
199 end
153 if contest_stat==nil or contest_stat.started_at==nil
200 if contest_stat==nil or contest_stat.started_at==nil
154 return (Time.now.gmtime + time_limit) - Time.now.gmtime
201 return (Time.now.gmtime + time_limit) - Time.now.gmtime
155 else
202 else
156 finish_time = contest_stat.started_at + time_limit
203 finish_time = contest_stat.started_at + time_limit
157 current_time = Time.now.gmtime
204 current_time = Time.now.gmtime
158 if current_time > finish_time
205 if current_time > finish_time
159 return 0
206 return 0
160 else
207 else
161 return finish_time - current_time
208 return finish_time - current_time
162 end
209 end
163 end
210 end
164 else
211 else
165 return nil
212 return nil
166 end
213 end
167 end
214 end
168
215
169 def contest_finished?
216 def contest_finished?
170 if GraderConfiguration.contest_mode?
217 if GraderConfiguration.contest_mode?
171 return false if site==nil
218 return false if site==nil
172 return site.finished?
219 return site.finished?
173 elsif GraderConfiguration.indv_contest_mode?
220 elsif GraderConfiguration.indv_contest_mode?
174 return false if self.contest_stat(true)==nil
221 return false if self.contest_stat(true)==nil
175 return contest_time_left == 0
222 return contest_time_left == 0
176 else
223 else
You need to be logged in to leave comments. Login now