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

r748:ff7f37009e5e - - 3 files changed: 15 inserted, 7 deleted

@@ -1,369 +1,369
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_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
25 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
26
26
27 belongs_to :site
27 belongs_to :site
28 belongs_to :country
28 belongs_to :country
29
29
30 has_and_belongs_to_many :contests, -> { order(:name); uniq}
30 has_and_belongs_to_many :contests, -> { order(:name); uniq}
31
31
32 scope :activated_users, -> {where activated: true}
32 scope :activated_users, -> {where activated: true}
33
33
34 validates_presence_of :login
34 validates_presence_of :login
35 validates_uniqueness_of :login
35 validates_uniqueness_of :login
36 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
36 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
37 validates_length_of :login, :within => 3..30
37 validates_length_of :login, :within => 3..30
38
38
39 validates_presence_of :full_name
39 validates_presence_of :full_name
40 validates_length_of :full_name, :minimum => 1
40 validates_length_of :full_name, :minimum => 1
41
41
42 validates_presence_of :password, :if => :password_required?
42 validates_presence_of :password, :if => :password_required?
43 validates_length_of :password, :within => 4..20, :if => :password_required?
43 validates_length_of :password, :within => 4..20, :if => :password_required?
44 validates_confirmation_of :password, :if => :password_required?
44 validates_confirmation_of :password, :if => :password_required?
45
45
46 validates_format_of :email,
46 validates_format_of :email,
47 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
47 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
48 :if => :email_validation?
48 :if => :email_validation?
49 validate :uniqueness_of_email_from_activated_users,
49 validate :uniqueness_of_email_from_activated_users,
50 :if => :email_validation?
50 :if => :email_validation?
51 validate :enough_time_interval_between_same_email_registrations,
51 validate :enough_time_interval_between_same_email_registrations,
52 :if => :email_validation?
52 :if => :email_validation?
53
53
54 # these are for ytopc
54 # these are for ytopc
55 # disable for now
55 # disable for now
56 #validates_presence_of :province
56 #validates_presence_of :province
57
57
58 attr_accessor :password
58 attr_accessor :password
59
59
60 before_save :encrypt_new_password
60 before_save :encrypt_new_password
61 before_save :assign_default_site
61 before_save :assign_default_site
62 before_save :assign_default_contest
62 before_save :assign_default_contest
63
63
64 # this is for will_paginate
64 # this is for will_paginate
65 cattr_reader :per_page
65 cattr_reader :per_page
66 @@per_page = 50
66 @@per_page = 50
67
67
68 def self.authenticate(login, password)
68 def self.authenticate(login, password)
69 user = find_by_login(login)
69 user = find_by_login(login)
70 if user
70 if user
71 return user if user.authenticated?(password)
71 return user if user.authenticated?(password)
72 end
72 end
73 end
73 end
74
74
75 def authenticated?(password)
75 def authenticated?(password)
76 if self.activated
76 if self.activated
77 hashed_password == User.encrypt(password,self.salt)
77 hashed_password == User.encrypt(password,self.salt)
78 else
78 else
79 false
79 false
80 end
80 end
81 end
81 end
82
82
83 def admin?
83 def admin?
84 self.roles.detect {|r| r.name == 'admin' }
84 self.roles.detect {|r| r.name == 'admin' }
85 end
85 end
86
86
87 def email_for_editing
87 def email_for_editing
88 if self.email==nil
88 if self.email==nil
89 "(unknown)"
89 "(unknown)"
90 elsif self.email==''
90 elsif self.email==''
91 "(blank)"
91 "(blank)"
92 else
92 else
93 self.email
93 self.email
94 end
94 end
95 end
95 end
96
96
97 def email_for_editing=(e)
97 def email_for_editing=(e)
98 self.email=e
98 self.email=e
99 end
99 end
100
100
101 def alias_for_editing
101 def alias_for_editing
102 if self.alias==nil
102 if self.alias==nil
103 "(unknown)"
103 "(unknown)"
104 elsif self.alias==''
104 elsif self.alias==''
105 "(blank)"
105 "(blank)"
106 else
106 else
107 self.alias
107 self.alias
108 end
108 end
109 end
109 end
110
110
111 def alias_for_editing=(e)
111 def alias_for_editing=(e)
112 self.alias=e
112 self.alias=e
113 end
113 end
114
114
115 def activation_key
115 def activation_key
116 if self.hashed_password==nil
116 if self.hashed_password==nil
117 encrypt_new_password
117 encrypt_new_password
118 end
118 end
119 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
119 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
120 end
120 end
121
121
122 def verify_activation_key(key)
122 def verify_activation_key(key)
123 key == activation_key
123 key == activation_key
124 end
124 end
125
125
126 def self.random_password(length=5)
126 def self.random_password(length=5)
127 chars = 'abcdefghjkmnopqrstuvwxyz'
127 chars = 'abcdefghjkmnopqrstuvwxyz'
128 password = ''
128 password = ''
129 length.times { password << chars[rand(chars.length - 1)] }
129 length.times { password << chars[rand(chars.length - 1)] }
130 password
130 password
131 end
131 end
132
132
133 def self.find_non_admin_with_prefix(prefix='')
133 def self.find_non_admin_with_prefix(prefix='')
134 users = User.all
134 users = User.all
135 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
135 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
136 end
136 end
137
137
138 # Contest information
138 # Contest information
139
139
140 def self.find_users_with_no_contest()
140 def self.find_users_with_no_contest()
141 users = User.all
141 users = User.all
142 return users.find_all { |u| u.contests.length == 0 }
142 return users.find_all { |u| u.contests.length == 0 }
143 end
143 end
144
144
145
145
146 def contest_time_left
146 def contest_time_left
147 if GraderConfiguration.contest_mode?
147 if GraderConfiguration.contest_mode?
148 return nil if site==nil
148 return nil if site==nil
149 return site.time_left
149 return site.time_left
150 elsif GraderConfiguration.indv_contest_mode?
150 elsif GraderConfiguration.indv_contest_mode?
151 time_limit = GraderConfiguration.contest_time_limit
151 time_limit = GraderConfiguration.contest_time_limit
152 if time_limit == nil
152 if time_limit == nil
153 return nil
153 return nil
154 end
154 end
155 if contest_stat==nil or contest_stat.started_at==nil
155 if contest_stat==nil or contest_stat.started_at==nil
156 return (Time.now.gmtime + time_limit) - Time.now.gmtime
156 return (Time.now.gmtime + time_limit) - Time.now.gmtime
157 else
157 else
158 finish_time = contest_stat.started_at + time_limit
158 finish_time = contest_stat.started_at + time_limit
159 current_time = Time.now.gmtime
159 current_time = Time.now.gmtime
160 if current_time > finish_time
160 if current_time > finish_time
161 return 0
161 return 0
162 else
162 else
163 return finish_time - current_time
163 return finish_time - current_time
164 end
164 end
165 end
165 end
166 else
166 else
167 return nil
167 return nil
168 end
168 end
169 end
169 end
170
170
171 def contest_finished?
171 def contest_finished?
172 if GraderConfiguration.contest_mode?
172 if GraderConfiguration.contest_mode?
173 return false if site==nil
173 return false if site==nil
174 return site.finished?
174 return site.finished?
175 elsif GraderConfiguration.indv_contest_mode?
175 elsif GraderConfiguration.indv_contest_mode?
176 return false if self.contest_stat(true)==nil
176 return false if self.contest_stat(true)==nil
177 return contest_time_left == 0
177 return contest_time_left == 0
178 else
178 else
179 return false
179 return false
180 end
180 end
181 end
181 end
182
182
183 def contest_started?
183 def contest_started?
184 if GraderConfiguration.indv_contest_mode?
184 if GraderConfiguration.indv_contest_mode?
185 stat = self.contest_stat
185 stat = self.contest_stat
186 return ((stat != nil) and (stat.started_at != nil))
186 return ((stat != nil) and (stat.started_at != nil))
187 elsif GraderConfiguration.contest_mode?
187 elsif GraderConfiguration.contest_mode?
188 return true if site==nil
188 return true if site==nil
189 return site.started
189 return site.started
190 else
190 else
191 return true
191 return true
192 end
192 end
193 end
193 end
194
194
195 def update_start_time
195 def update_start_time
196 stat = self.contest_stat
196 stat = self.contest_stat
197 if stat.nil? or stat.started_at.nil?
197 if stat.nil? or stat.started_at.nil?
198 stat ||= UserContestStat.new(:user => self)
198 stat ||= UserContestStat.new(:user => self)
199 stat.started_at = Time.now.gmtime
199 stat.started_at = Time.now.gmtime
200 stat.save
200 stat.save
201 end
201 end
202 end
202 end
203
203
204 def problem_in_user_contests?(problem)
204 def problem_in_user_contests?(problem)
205 problem_contests = problem.contests.all
205 problem_contests = problem.contests.all
206
206
207 if problem_contests.length == 0 # this is public contest
207 if problem_contests.length == 0 # this is public contest
208 return true
208 return true
209 end
209 end
210
210
211 contests.each do |contest|
211 contests.each do |contest|
212 if problem_contests.find {|c| c.id == contest.id }
212 if problem_contests.find {|c| c.id == contest.id }
213 return true
213 return true
214 end
214 end
215 end
215 end
216 return false
216 return false
217 end
217 end
218
218
219 def available_problems_group_by_contests
219 def available_problems_group_by_contests
220 contest_problems = []
220 contest_problems = []
221 pin = {}
221 pin = {}
222 contests.enabled.each do |contest|
222 contests.enabled.each do |contest|
223 available_problems = contest.problems.available
223 available_problems = contest.problems.available
224 contest_problems << {
224 contest_problems << {
225 :contest => contest,
225 :contest => contest,
226 :problems => available_problems
226 :problems => available_problems
227 }
227 }
228 available_problems.each {|p| pin[p.id] = true}
228 available_problems.each {|p| pin[p.id] = true}
229 end
229 end
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
230 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
231 contest_problems << {
231 contest_problems << {
232 :contest => nil,
232 :contest => nil,
233 :problems => other_avaiable_problems
233 :problems => other_avaiable_problems
234 }
234 }
235 return contest_problems
235 return contest_problems
236 end
236 end
237
237
238 def solve_all_available_problems?
238 def solve_all_available_problems?
239 available_problems.each do |p|
239 available_problems.each do |p|
240 u = self
240 u = self
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
241 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
242 return false if !p or !sub or sub.points < p.full_score
242 return false if !p or !sub or sub.points < p.full_score
243 end
243 end
244 return true
244 return true
245 end
245 end
246
246
247 #get a list of available problem
247 #get a list of available problem
248 def available_problems
248 def available_problems
249 if not GraderConfiguration.multicontests?
249 if not GraderConfiguration.multicontests?
250 if GraderConfiguration.use_problem_group?
250 if GraderConfiguration.use_problem_group?
251 return available_problems_in_group
251 return available_problems_in_group
252 else
252 else
253 return Problem.available_problems
253 return Problem.available_problems
254 end
254 end
255 else
255 else
256 contest_problems = []
256 contest_problems = []
257 pin = {}
257 pin = {}
258 contests.enabled.each do |contest|
258 contests.enabled.each do |contest|
259 contest.problems.available.each do |problem|
259 contest.problems.available.each do |problem|
260 if not pin.has_key? problem.id
260 if not pin.has_key? problem.id
261 contest_problems << problem
261 contest_problems << problem
262 end
262 end
263 pin[problem.id] = true
263 pin[problem.id] = true
264 end
264 end
265 end
265 end
266 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
266 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
267 return contest_problems + other_avaiable_problems
267 return contest_problems + other_avaiable_problems
268 end
268 end
269 end
269 end
270
270
271 def available_problems_in_group
271 def available_problems_in_group
272 problem = []
272 problem = []
273 self.groups.each do |group|
273 self.groups.each do |group|
274 group.problems.where(available: true).each { |p| problem << p }
274 group.problems.where(available: true).each { |p| problem << p }
275 end
275 end
276 problem.uniq!
276 problem.uniq!
277 if problem
277 if problem
278 problem.sort! do |a,b|
278 problem.sort! do |a,b|
279 case
279 case
280 when a.date_added < b.date_added
280 when a.date_added < b.date_added
281 1
281 1
282 when a.date_added > b.date_added
282 when a.date_added > b.date_added
283 -1
283 -1
284 else
284 else
285 a.name <=> b.name
285 a.name <=> b.name
286 end
286 end
287 end
287 end
288 return problem
288 return problem
289 else
289 else
290 return []
290 return []
291 end
291 end
292 end
292 end
293
293
294 def can_view_problem?(problem)
294 def can_view_problem?(problem)
295 return true if admin?
295 return true if admin?
296 return available_problems.include? problem
296 return available_problems.include? problem
297 end
297 end
298
298
299 def self.clear_last_login
299 def self.clear_last_login
300 User.update_all(:last_ip => nil)
300 User.update_all(:last_ip => nil)
301 end
301 end
302
302
303 protected
303 protected
304 def encrypt_new_password
304 def encrypt_new_password
305 return if password.blank?
305 return if password.blank?
306 self.salt = (10+rand(90)).to_s
306 self.salt = (10+rand(90)).to_s
307 self.hashed_password = User.encrypt(self.password,self.salt)
307 self.hashed_password = User.encrypt(self.password,self.salt)
308 end
308 end
309
309
310 def assign_default_site
310 def assign_default_site
311 # have to catch error when migrating (because self.site is not available).
311 # have to catch error when migrating (because self.site is not available).
312 begin
312 begin
313 if self.site==nil
313 if self.site==nil
314 self.site = Site.find_by_name('default')
314 self.site = Site.find_by_name('default')
315 if self.site==nil
315 if self.site==nil
316 self.site = Site.find(1) # when 'default has be renamed'
316 self.site = Site.find(1) # when 'default has be renamed'
317 end
317 end
318 end
318 end
319 rescue
319 rescue
320 end
320 end
321 end
321 end
322
322
323 def assign_default_contest
323 def assign_default_contest
324 # have to catch error when migrating (because self.site is not available).
324 # have to catch error when migrating (because self.site is not available).
325 begin
325 begin
326 if self.contests.length == 0
326 if self.contests.length == 0
327 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
327 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
328 if default_contest
328 if default_contest
329 self.contests = [default_contest]
329 self.contests = [default_contest]
330 end
330 end
331 end
331 end
332 rescue
332 rescue
333 end
333 end
334 end
334 end
335
335
336 def password_required?
336 def password_required?
337 self.hashed_password.blank? || !self.password.blank?
337 self.hashed_password.blank? || !self.password.blank?
338 end
338 end
339
339
340 def self.encrypt(string,salt)
340 def self.encrypt(string,salt)
341 Digest::SHA1.hexdigest(salt + string)
341 Digest::SHA1.hexdigest(salt + string)
342 end
342 end
343
343
344 def uniqueness_of_email_from_activated_users
344 def uniqueness_of_email_from_activated_users
345 user = User.activated_users.find_by_email(self.email)
345 user = User.activated_users.find_by_email(self.email)
346 if user and (user.login != self.login)
346 if user and (user.login != self.login)
347 self.errors.add(:base,"Email has already been taken")
347 self.errors.add(:base,"Email has already been taken")
348 end
348 end
349 end
349 end
350
350
351 def enough_time_interval_between_same_email_registrations
351 def enough_time_interval_between_same_email_registrations
352 return if !self.new_record?
352 return if !self.new_record?
353 return if self.activated
353 return if self.activated
354 open_user = User.find_by_email(self.email,
354 open_user = User.find_by_email(self.email,
355 :order => 'created_at DESC')
355 :order => 'created_at DESC')
356 if open_user and open_user.created_at and
356 if open_user and open_user.created_at and
357 (open_user.created_at > Time.now.gmtime - 5.minutes)
357 (open_user.created_at > Time.now.gmtime - 5.minutes)
358 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
358 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
359 end
359 end
360 end
360 end
361
361
362 def email_validation?
362 def email_validation?
363 begin
363 begin
364 return VALIDATE_USER_EMAILS
364 return VALIDATE_USER_EMAILS
365 rescue
365 rescue
366 return false
366 return false
367 end
367 end
368 end
368 end
369 end
369 end
@@ -1,106 +1,106
1 %h1 Users
1 %h1 Users
2
2
3 .panel.panel-primary
3 .panel.panel-primary
4 .panel-title.panel-heading
4 .panel-title.panel-heading
5 Quick Add
5 Quick Add
6 .panel-body
6 .panel-body
7 = form_tag( {method: 'post'}, {class: 'form-inline'}) do
7 = form_tag( {method: 'post'}, {class: 'form-inline'}) do
8 .form-group
8 .form-group
9 = label_tag 'user_login', 'Login'
9 = label_tag 'user_login', 'Login'
10 = text_field 'user', 'login', :size => 10,class: 'form-control'
10 = text_field 'user', 'login', :size => 10,class: 'form-control'
11 .form-group
11 .form-group
12 = label_tag 'user_full_name', 'Full Name'
12 = label_tag 'user_full_name', 'Full Name'
13 = text_field 'user', 'full_name', :size => 10,class: 'form-control'
13 = text_field 'user', 'full_name', :size => 10,class: 'form-control'
14 .form-group
14 .form-group
15 = label_tag 'user_password', 'Password'
15 = label_tag 'user_password', 'Password'
16 = text_field 'user', 'password', :size => 10,class: 'form-control'
16 = text_field 'user', 'password', :size => 10,class: 'form-control'
17 .form-group
17 .form-group
18 = label_tag 'user_password_confirmation', 'Confirm'
18 = label_tag 'user_password_confirmation', 'Confirm'
19 = text_field 'user', 'password_confirmation', :size => 10,class: 'form-control'
19 = text_field 'user', 'password_confirmation', :size => 10,class: 'form-control'
20 .form-group
20 .form-group
21 = label_tag 'user_email', 'email'
21 = label_tag 'user_email', 'email'
22 = text_field 'user', 'email', :size => 10,class: 'form-control'
22 = text_field 'user', 'email', :size => 10,class: 'form-control'
23 =submit_tag "Create", class: 'btn btn-primary'
23 =submit_tag "Create", class: 'btn btn-primary'
24
24
25 .panel.panel-primary
25 .panel.panel-primary
26 .panel-title.panel-heading
26 .panel-title.panel-heading
27 Import from site management
27 Import from site management
28 .panel-body
28 .panel-body
29 = form_tag({:action => 'import'}, :multipart => true,class: 'form form-inline') do
29 = form_tag({:action => 'import'}, :multipart => true,class: 'form form-inline') do
30 .form-group
30 .form-group
31 = label_tag :file, 'File:'
31 = label_tag :file, 'File:'
32 .input-group
32 .input-group
33 %span.input-group-btn
33 %span.input-group-btn
34 %span.btn.btn-default.btn-file
34 %span.btn.btn-default.btn-file
35 Browse
35 Browse
36 = file_field_tag 'file'
36 = file_field_tag 'file'
37 = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
37 = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
38 = submit_tag 'Submit', class: 'btn btn-default'
38 = submit_tag 'Submit', class: 'btn btn-default'
39
39
40
40
41 %p
41 %p
42 = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
42 = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
43 = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
43 = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
44 - = link_to 'Bulk Manage', bulk_manage_user_admin_path , { class: 'btn btn-default btn-info'}
44 + = link_to 'Bulk Manage', { action: :bulk_manage} , { class: 'btn btn-default btn-info'}
45 = link_to 'View administrators',{ :action => 'admin'}, { class: 'btn btn-default '}
45 = link_to 'View administrators',{ :action => 'admin'}, { class: 'btn btn-default '}
46 = link_to 'Random passwords',{ :action => 'random_all_passwords'}, { class: 'btn btn-default '}
46 = link_to 'Random passwords',{ :action => 'random_all_passwords'}, { class: 'btn btn-default '}
47 = link_to 'View active users',{ :action => 'active'}, { class: 'btn btn-default '}
47 = link_to 'View active users',{ :action => 'active'}, { class: 'btn btn-default '}
48 = link_to 'Mass mailing',{ :action => 'mass_mailing'}, { class: 'btn btn-default '}
48 = link_to 'Mass mailing',{ :action => 'mass_mailing'}, { class: 'btn btn-default '}
49
49
50 - if GraderConfiguration.multicontests?
50 - if GraderConfiguration.multicontests?
51 %br/
51 %br/
52 %b Multi-contest:
52 %b Multi-contest:
53 = link_to '[Manage bulk users in contests]', :action => 'contest_management'
53 = link_to '[Manage bulk users in contests]', :action => 'contest_management'
54 View users in:
54 View users in:
55 - @contests.each do |contest|
55 - @contests.each do |contest|
56 = link_to "[#{contest.name}]", :action => 'contests', :id => contest.id
56 = link_to "[#{contest.name}]", :action => 'contests', :id => contest.id
57 = link_to "[no contest]", :action => 'contests', :id => 'none'
57 = link_to "[no contest]", :action => 'contests', :id => 'none'
58
58
59 -# Total #{@user_count} users |
59 -# Total #{@user_count} users |
60 -# - if !@paginated
60 -# - if !@paginated
61 -# Display all users.
61 -# Display all users.
62 -# \#{link_to '[show in pages]', :action => 'index', :page => '1'}
62 -# \#{link_to '[show in pages]', :action => 'index', :page => '1'}
63 -# - else
63 -# - else
64 -# Display in pages.
64 -# Display in pages.
65 -# \#{link_to '[display all]', :action => 'index', :page => 'all'} |
65 -# \#{link_to '[display all]', :action => 'index', :page => 'all'} |
66 -# \#{will_paginate @users, :container => false}
66 -# \#{will_paginate @users, :container => false}
67
67
68
68
69 %table.table.table-hover.table-condense.datatable
69 %table.table.table-hover.table-condense.datatable
70 %thead
70 %thead
71 %th Login
71 %th Login
72 %th Full name
72 %th Full name
73 %th email
73 %th email
74 %th Remark
74 %th Remark
75 %th
75 %th
76 Activated
76 Activated
77 %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'User has already confirmed the email?' } [?]
77 %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'User has already confirmed the email?' } [?]
78 %th
78 %th
79 Enabled
79 Enabled
80 %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'Allow the user to login?' } [?]
80 %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'Allow the user to login?' } [?]
81 %th Last IP
81 %th Last IP
82 %th
82 %th
83 %th
83 %th
84 %th
84 %th
85 %th
85 %th
86 - for user in @users
86 - for user in @users
87 %tr
87 %tr
88 %td= link_to user.login, stat_user_path(user)
88 %td= link_to user.login, stat_user_path(user)
89 %td= user.full_name
89 %td= user.full_name
90 %td= user.email
90 %td= user.email
91 %td= user.remark
91 %td= user.remark
92 %td= toggle_button(user.activated?, toggle_activate_user_path(user),"toggle_activate_user_#{user.id}")
92 %td= toggle_button(user.activated?, toggle_activate_user_path(user),"toggle_activate_user_#{user.id}")
93 %td= toggle_button(user.enabled?, toggle_enable_user_path(user),"toggle_enable_user_#{user.id}")
93 %td= toggle_button(user.enabled?, toggle_enable_user_path(user),"toggle_enable_user_#{user.id}")
94 %td= user.last_ip
94 %td= user.last_ip
95 %td= link_to 'Clear IP', {:action => 'clear_last_ip', :id => user, :page=>params[:page]}, :confirm => 'This will reset last logging in ip of the user, are you sure?', class: 'btn btn-default btn-xs btn-block'
95 %td= link_to 'Clear IP', {:action => 'clear_last_ip', :id => user, :page=>params[:page]}, :confirm => 'This will reset last logging in ip of the user, are you sure?', class: 'btn btn-default btn-xs btn-block'
96 %td= link_to 'Show', {:action => 'show', :id => user}, class: 'btn btn-default btn-xs btn-block'
96 %td= link_to 'Show', {:action => 'show', :id => user}, class: 'btn btn-default btn-xs btn-block'
97 %td= link_to 'Edit', {:action => 'edit', :id => user}, class: 'btn btn-default btn-xs btn-block'
97 %td= link_to 'Edit', {:action => 'edit', :id => user}, class: 'btn btn-default btn-xs btn-block'
98 - %td= link_to 'Destroy', user_admin_destroy_path(user), data: {confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-danger btn-xs btn-block'
98 + %td= link_to 'Destroy', {action: :destroy, id: user}, data: {confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-danger btn-xs btn-block'
99 %br/
99 %br/
100 = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
100 = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
101 = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
101 = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
102
102
103 :javascript
103 :javascript
104 $('.datatable').DataTable({
104 $('.datatable').DataTable({
105 'pageLength': 50
105 'pageLength': 50
106 });
106 });
@@ -1,158 +1,166
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 resources :tags
2 resources :tags
3 get "sources/direct_edit"
3 get "sources/direct_edit"
4
4
5 root :to => 'main#login'
5 root :to => 'main#login'
6
6
7 #logins
7 #logins
8 match 'login/login', to: 'login#login', via: [:get,:post]
8 match 'login/login', to: 'login#login', via: [:get,:post]
9
9
10
10
11 resources :contests
11 resources :contests
12
12
13 resources :sites
13 resources :sites
14
14
15 resources :test
15 resources :test
16
16
17 resources :messages do
17 resources :messages do
18 collection do
18 collection do
19 get 'console'
19 get 'console'
20 end
20 end
21 end
21 end
22
22
23 resources :announcements do
23 resources :announcements do
24 member do
24 member do
25 get 'toggle','toggle_front'
25 get 'toggle','toggle_front'
26 end
26 end
27 end
27 end
28
28
29 resources :problems do
29 resources :problems do
30 member do
30 member do
31 get 'toggle'
31 get 'toggle'
32 get 'toggle_test'
32 get 'toggle_test'
33 get 'toggle_view_testcase'
33 get 'toggle_view_testcase'
34 get 'stat'
34 get 'stat'
35 end
35 end
36 collection do
36 collection do
37 get 'turn_all_off'
37 get 'turn_all_off'
38 get 'turn_all_on'
38 get 'turn_all_on'
39 get 'import'
39 get 'import'
40 get 'manage'
40 get 'manage'
41 end
41 end
42 end
42 end
43
43
44 resources :groups do
44 resources :groups do
45 member do
45 member do
46 post 'add_user', to: 'groups#add_user', as: 'add_user'
46 post 'add_user', to: 'groups#add_user', as: 'add_user'
47 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
47 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
48 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
48 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
49 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
49 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
50 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
50 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
51 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
51 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
52 end
52 end
53 collection do
53 collection do
54
54
55 end
55 end
56 end
56 end
57
57
58 resources :testcases, only: [] do
58 resources :testcases, only: [] do
59 member do
59 member do
60 get 'download_input'
60 get 'download_input'
61 get 'download_sol'
61 get 'download_sol'
62 end
62 end
63 collection do
63 collection do
64 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
64 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
65 end
65 end
66 end
66 end
67
67
68 resources :grader_configuration, controller: 'configurations'
68 resources :grader_configuration, controller: 'configurations'
69
69
70 resources :users do
70 resources :users do
71 member do
71 member do
72 get 'toggle_activate', 'toggle_enable'
72 get 'toggle_activate', 'toggle_enable'
73 get 'stat'
73 get 'stat'
74 end
74 end
75 end
75 end
76
76
77 resources :submissions do
77 resources :submissions do
78 member do
78 member do
79 get 'download'
79 get 'download'
80 get 'compiler_msg'
80 get 'compiler_msg'
81 get 'rejudge'
81 get 'rejudge'
82 end
82 end
83 collection do
83 collection do
84 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
84 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
85 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
85 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
86 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
86 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
87 end
87 end
88 end
88 end
89
89
90
90
91 #user admin
91 #user admin
92 resources :user_admin do
92 resources :user_admin do
93 collection do
93 collection do
94 - get 'bulk_manage', as: 'bulk_manage_user_admin'
94 + get 'bulk_manage'
95 - delete ':id', to: 'user_admin#destroy', as: 'user_admin_destroy'
96 get 'user_stat'
95 get 'user_stat'
96 + get 'import'
97 + get 'new_list'
98 + get 'admin'
99 + get 'random_all_passwords'
100 + get 'active'
101 + get 'mass_mailing'
102 + end
103 + member do
104 + get 'clear_last_ip'
97 end
105 end
98 end
106 end
99
107
100 resources :contest_management, only: [:index] do
108 resources :contest_management, only: [:index] do
101 collection do
109 collection do
102 get 'user_stat'
110 get 'user_stat'
103 get 'clear_stat'
111 get 'clear_stat'
104 get 'clear_all_stat'
112 get 'clear_all_stat'
105 end
113 end
106 end
114 end
107
115
108 #get 'user_admin', to: 'user_admin#index'
116 #get 'user_admin', to: 'user_admin#index'
109 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
117 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
110 #post 'user_admin', to: 'user_admin#create'
118 #post 'user_admin', to: 'user_admin#create'
111 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
119 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
112
120
113 #singular resource
121 #singular resource
114 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
122 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
115 #report
123 #report
116 resource :report, only: [], controller: 'report' do
124 resource :report, only: [], controller: 'report' do
117 get 'login'
125 get 'login'
118 get 'multiple_login'
126 get 'multiple_login'
119 get 'problem_hof/:id', action: 'problem_hof'
127 get 'problem_hof/:id', action: 'problem_hof'
120 get 'current_score'
128 get 'current_score'
121 get 'max_score'
129 get 'max_score'
122 post 'show_max_score'
130 post 'show_max_score'
123 end
131 end
124 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
132 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
125 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
133 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
126 #get "report/login"
134 #get "report/login"
127 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
135 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
128 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
136 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
129
137
130 resource :main, only: [], controller: 'main' do
138 resource :main, only: [], controller: 'main' do
131 get 'list'
139 get 'list'
132 get 'submission(/:id)', action: 'submission', as: 'main_submission'
140 get 'submission(/:id)', action: 'submission', as: 'main_submission'
133 post 'submit'
141 post 'submit'
134 get 'announcements'
142 get 'announcements'
135 get 'help'
143 get 'help'
136 end
144 end
137 #main
145 #main
138 #get "main/list"
146 #get "main/list"
139 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
147 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
140 #post 'main/submit', to: 'main#submit'
148 #post 'main/submit', to: 'main#submit'
141 #get 'main/announcements', to: 'main#announcements'
149 #get 'main/announcements', to: 'main#announcements'
142
150
143
151
144 #
152 #
145 get 'tasks/view/:file.:ext' => 'tasks#view'
153 get 'tasks/view/:file.:ext' => 'tasks#view'
146 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
154 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
147 get 'heartbeat/:id/edit' => 'heartbeat#edit'
155 get 'heartbeat/:id/edit' => 'heartbeat#edit'
148
156
149 #grader
157 #grader
150 get 'graders/list', to: 'graders#list', as: 'grader_list'
158 get 'graders/list', to: 'graders#list', as: 'grader_list'
151
159
152
160
153 # See how all your routes lay out with "rake routes"
161 # See how all your routes lay out with "rake routes"
154
162
155 # This is a legacy wild controller route that's not recommended for RESTful applications.
163 # This is a legacy wild controller route that's not recommended for RESTful applications.
156 # Note: This route will make all actions in every controller accessible via GET requests.
164 # Note: This route will make all actions in every controller accessible via GET requests.
157 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
165 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
158 end
166 end
You need to be logged in to leave comments. Login now