Description:
merge from algo-bm
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r405:f3f0ea35cff3 - - 1 file changed: 41 inserted, 2 deleted

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