Description:
add pop3 authentication for chula create both bookmark and branch so that github will work too
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r390:edc9bac52078 - - 1 file changed: 17 inserted, 0 deleted

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