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

r833:913658e11037 - - 1 file changed: 43 inserted, 0 deleted

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