Description:
NEED TESTING move to stronger parameter for xxx.new(params[
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r637:d56b2e7de528 - - 4 files changed: 10 inserted, 6 deleted

@@ -1,116 +1,116
1 class AnnouncementsController < ApplicationController
1 class AnnouncementsController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 in_place_edit_for :announcement, :published
5 in_place_edit_for :announcement, :published
6
6
7 # GET /announcements
7 # GET /announcements
8 # GET /announcements.xml
8 # GET /announcements.xml
9 def index
9 def index
10 @announcements = Announcement.order(created_at: :desc)
10 @announcements = Announcement.order(created_at: :desc)
11
11
12 respond_to do |format|
12 respond_to do |format|
13 format.html # index.html.erb
13 format.html # index.html.erb
14 format.xml { render :xml => @announcements }
14 format.xml { render :xml => @announcements }
15 end
15 end
16 end
16 end
17
17
18 # GET /announcements/1
18 # GET /announcements/1
19 # GET /announcements/1.xml
19 # GET /announcements/1.xml
20 def show
20 def show
21 @announcement = Announcement.find(params[:id])
21 @announcement = Announcement.find(params[:id])
22
22
23 respond_to do |format|
23 respond_to do |format|
24 format.html # show.html.erb
24 format.html # show.html.erb
25 format.xml { render :xml => @announcement }
25 format.xml { render :xml => @announcement }
26 end
26 end
27 end
27 end
28
28
29 # GET /announcements/new
29 # GET /announcements/new
30 # GET /announcements/new.xml
30 # GET /announcements/new.xml
31 def new
31 def new
32 @announcement = Announcement.new
32 @announcement = Announcement.new
33
33
34 respond_to do |format|
34 respond_to do |format|
35 format.html # new.html.erb
35 format.html # new.html.erb
36 format.xml { render :xml => @announcement }
36 format.xml { render :xml => @announcement }
37 end
37 end
38 end
38 end
39
39
40 # GET /announcements/1/edit
40 # GET /announcements/1/edit
41 def edit
41 def edit
42 @announcement = Announcement.find(params[:id])
42 @announcement = Announcement.find(params[:id])
43 end
43 end
44
44
45 # POST /announcements
45 # POST /announcements
46 # POST /announcements.xml
46 # POST /announcements.xml
47 def create
47 def create
48 - @announcement = Announcement.new(params[:announcement])
48 + @announcement = Announcement.new(announcement_params)
49
49
50 respond_to do |format|
50 respond_to do |format|
51 if @announcement.save
51 if @announcement.save
52 flash[:notice] = 'Announcement was successfully created.'
52 flash[:notice] = 'Announcement was successfully created.'
53 format.html { redirect_to(@announcement) }
53 format.html { redirect_to(@announcement) }
54 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
54 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
55 else
55 else
56 format.html { render :action => "new" }
56 format.html { render :action => "new" }
57 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
57 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
58 end
58 end
59 end
59 end
60 end
60 end
61
61
62 # PUT /announcements/1
62 # PUT /announcements/1
63 # PUT /announcements/1.xml
63 # PUT /announcements/1.xml
64 def update
64 def update
65 @announcement = Announcement.find(params[:id])
65 @announcement = Announcement.find(params[:id])
66
66
67 respond_to do |format|
67 respond_to do |format|
68 if @announcement.update_attributes(announcement_params)
68 if @announcement.update_attributes(announcement_params)
69 flash[:notice] = 'Announcement was successfully updated.'
69 flash[:notice] = 'Announcement was successfully updated.'
70 format.html { redirect_to(@announcement) }
70 format.html { redirect_to(@announcement) }
71 format.js {}
71 format.js {}
72 format.xml { head :ok }
72 format.xml { head :ok }
73 else
73 else
74 format.html { render :action => "edit" }
74 format.html { render :action => "edit" }
75 format.js {}
75 format.js {}
76 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
76 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
77 end
77 end
78 end
78 end
79 end
79 end
80
80
81 def toggle
81 def toggle
82 @announcement = Announcement.find(params[:id])
82 @announcement = Announcement.find(params[:id])
83 @announcement.update_attributes( published: !@announcement.published? )
83 @announcement.update_attributes( published: !@announcement.published? )
84 respond_to do |format|
84 respond_to do |format|
85 format.js { render partial: 'toggle_button',
85 format.js { render partial: 'toggle_button',
86 locals: {button_id: "#announcement_toggle_#{@announcement.id}",button_on: @announcement.published? } }
86 locals: {button_id: "#announcement_toggle_#{@announcement.id}",button_on: @announcement.published? } }
87 end
87 end
88 end
88 end
89
89
90 def toggle_front
90 def toggle_front
91 @announcement = Announcement.find(params[:id])
91 @announcement = Announcement.find(params[:id])
92 @announcement.update_attributes( frontpage: !@announcement.frontpage? )
92 @announcement.update_attributes( frontpage: !@announcement.frontpage? )
93 respond_to do |format|
93 respond_to do |format|
94 format.js { render partial: 'toggle_button',
94 format.js { render partial: 'toggle_button',
95 locals: {button_id: "#announcement_toggle_front_#{@announcement.id}",button_on: @announcement.frontpage? } }
95 locals: {button_id: "#announcement_toggle_front_#{@announcement.id}",button_on: @announcement.frontpage? } }
96 end
96 end
97 end
97 end
98
98
99 # DELETE /announcements/1
99 # DELETE /announcements/1
100 # DELETE /announcements/1.xml
100 # DELETE /announcements/1.xml
101 def destroy
101 def destroy
102 @announcement = Announcement.find(params[:id])
102 @announcement = Announcement.find(params[:id])
103 @announcement.destroy
103 @announcement.destroy
104
104
105 respond_to do |format|
105 respond_to do |format|
106 format.html { redirect_to(announcements_url) }
106 format.html { redirect_to(announcements_url) }
107 format.xml { head :ok }
107 format.xml { head :ok }
108 end
108 end
109 end
109 end
110
110
111 private
111 private
112
112
113 def announcement_params
113 def announcement_params
114 params.require(:announcement).permit(:author, :body, :published, :frontpage, :contest_only,:title, :note)
114 params.require(:announcement).permit(:author, :body, :published, :frontpage, :contest_only,:title, :note)
115 end
115 end
116 end
116 end
@@ -1,294 +1,294
1 class ProblemsController < ApplicationController
1 class ProblemsController < ApplicationController
2
2
3 before_action :authenticate, :authorization
3 before_action :authenticate, :authorization
4 before_action :testcase_authorization, only: [:show_testcase]
4 before_action :testcase_authorization, only: [:show_testcase]
5
5
6 in_place_edit_for :problem, :name
6 in_place_edit_for :problem, :name
7 in_place_edit_for :problem, :full_name
7 in_place_edit_for :problem, :full_name
8 in_place_edit_for :problem, :full_score
8 in_place_edit_for :problem, :full_score
9
9
10 def index
10 def index
11 @problems = Problem.order(date_added: :desc)
11 @problems = Problem.order(date_added: :desc)
12 end
12 end
13
13
14 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
14 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
15 verify :method => :post, :only => [ :create, :quick_create,
15 verify :method => :post, :only => [ :create, :quick_create,
16 :do_manage,
16 :do_manage,
17 :do_import,
17 :do_import,
18 ],
18 ],
19 :redirect_to => { :action => :index }
19 :redirect_to => { :action => :index }
20
20
21 def show
21 def show
22 @problem = Problem.find(params[:id])
22 @problem = Problem.find(params[:id])
23 end
23 end
24
24
25 def new
25 def new
26 @problem = Problem.new
26 @problem = Problem.new
27 @description = nil
27 @description = nil
28 end
28 end
29
29
30 def create
30 def create
31 - @problem = Problem.new(params[:problem])
31 + @problem = Problem.new(problem_params)
32 @description = Description.new(params[:description])
32 @description = Description.new(params[:description])
33 if @description.body!=''
33 if @description.body!=''
34 if !@description.save
34 if !@description.save
35 render :action => new and return
35 render :action => new and return
36 end
36 end
37 else
37 else
38 @description = nil
38 @description = nil
39 end
39 end
40 @problem.description = @description
40 @problem.description = @description
41 if @problem.save
41 if @problem.save
42 flash[:notice] = 'Problem was successfully created.'
42 flash[:notice] = 'Problem was successfully created.'
43 redirect_to action: :index
43 redirect_to action: :index
44 else
44 else
45 render :action => 'new'
45 render :action => 'new'
46 end
46 end
47 end
47 end
48
48
49 def quick_create
49 def quick_create
50 - @problem = Problem.new(params[:problem])
50 + @problem = Problem.new(problem_params)
51 @problem.full_name = @problem.name if @problem.full_name == ''
51 @problem.full_name = @problem.name if @problem.full_name == ''
52 @problem.full_score = 100
52 @problem.full_score = 100
53 @problem.available = false
53 @problem.available = false
54 @problem.test_allowed = true
54 @problem.test_allowed = true
55 @problem.output_only = false
55 @problem.output_only = false
56 @problem.date_added = Time.new
56 @problem.date_added = Time.new
57 if @problem.save
57 if @problem.save
58 flash[:notice] = 'Problem was successfully created.'
58 flash[:notice] = 'Problem was successfully created.'
59 redirect_to action: :index
59 redirect_to action: :index
60 else
60 else
61 flash[:notice] = 'Error saving problem'
61 flash[:notice] = 'Error saving problem'
62 redirect_to action: :index
62 redirect_to action: :index
63 end
63 end
64 end
64 end
65
65
66 def edit
66 def edit
67 @problem = Problem.find(params[:id])
67 @problem = Problem.find(params[:id])
68 @description = @problem.description
68 @description = @problem.description
69 end
69 end
70
70
71 def update
71 def update
72 @problem = Problem.find(params[:id])
72 @problem = Problem.find(params[:id])
73 @description = @problem.description
73 @description = @problem.description
74 if @description.nil? and params[:description][:body]!=''
74 if @description.nil? and params[:description][:body]!=''
75 @description = Description.new(params[:description])
75 @description = Description.new(params[:description])
76 if !@description.save
76 if !@description.save
77 flash[:notice] = 'Error saving description'
77 flash[:notice] = 'Error saving description'
78 render :action => 'edit' and return
78 render :action => 'edit' and return
79 end
79 end
80 @problem.description = @description
80 @problem.description = @description
81 elsif @description
81 elsif @description
82 if !@description.update_attributes(params[:description])
82 if !@description.update_attributes(params[:description])
83 flash[:notice] = 'Error saving description'
83 flash[:notice] = 'Error saving description'
84 render :action => 'edit' and return
84 render :action => 'edit' and return
85 end
85 end
86 end
86 end
87 if params[:file] and params[:file].content_type != 'application/pdf'
87 if params[:file] and params[:file].content_type != 'application/pdf'
88 flash[:notice] = 'Error: Uploaded file is not PDF'
88 flash[:notice] = 'Error: Uploaded file is not PDF'
89 render :action => 'edit' and return
89 render :action => 'edit' and return
90 end
90 end
91 if @problem.update_attributes(problem_params)
91 if @problem.update_attributes(problem_params)
92 flash[:notice] = 'Problem was successfully updated.'
92 flash[:notice] = 'Problem was successfully updated.'
93 unless params[:file] == nil or params[:file] == ''
93 unless params[:file] == nil or params[:file] == ''
94 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
94 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
95 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
95 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
96 if not FileTest.exists? out_dirname
96 if not FileTest.exists? out_dirname
97 Dir.mkdir out_dirname
97 Dir.mkdir out_dirname
98 end
98 end
99
99
100 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
100 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
101 if FileTest.exists? out_filename
101 if FileTest.exists? out_filename
102 File.delete out_filename
102 File.delete out_filename
103 end
103 end
104
104
105 File.open(out_filename,"wb") do |file|
105 File.open(out_filename,"wb") do |file|
106 file.write(params[:file].read)
106 file.write(params[:file].read)
107 end
107 end
108 @problem.description_filename = "#{@problem.name}.pdf"
108 @problem.description_filename = "#{@problem.name}.pdf"
109 @problem.save
109 @problem.save
110 end
110 end
111 redirect_to :action => 'show', :id => @problem
111 redirect_to :action => 'show', :id => @problem
112 else
112 else
113 render :action => 'edit'
113 render :action => 'edit'
114 end
114 end
115 end
115 end
116
116
117 def destroy
117 def destroy
118 p = Problem.find(params[:id]).destroy
118 p = Problem.find(params[:id]).destroy
119 redirect_to action: :index
119 redirect_to action: :index
120 end
120 end
121
121
122 def toggle
122 def toggle
123 @problem = Problem.find(params[:id])
123 @problem = Problem.find(params[:id])
124 @problem.update_attributes(available: !(@problem.available) )
124 @problem.update_attributes(available: !(@problem.available) )
125 respond_to do |format|
125 respond_to do |format|
126 format.js { }
126 format.js { }
127 end
127 end
128 end
128 end
129
129
130 def toggle_test
130 def toggle_test
131 @problem = Problem.find(params[:id])
131 @problem = Problem.find(params[:id])
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 respond_to do |format|
133 respond_to do |format|
134 format.js { }
134 format.js { }
135 end
135 end
136 end
136 end
137
137
138 def toggle_view_testcase
138 def toggle_view_testcase
139 @problem = Problem.find(params[:id])
139 @problem = Problem.find(params[:id])
140 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
140 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
141 respond_to do |format|
141 respond_to do |format|
142 format.js { }
142 format.js { }
143 end
143 end
144 end
144 end
145
145
146 def turn_all_off
146 def turn_all_off
147 Problem.available.all.each do |problem|
147 Problem.available.all.each do |problem|
148 problem.available = false
148 problem.available = false
149 problem.save
149 problem.save
150 end
150 end
151 redirect_to action: :index
151 redirect_to action: :index
152 end
152 end
153
153
154 def turn_all_on
154 def turn_all_on
155 Problem.where.not(available: true).each do |problem|
155 Problem.where.not(available: true).each do |problem|
156 problem.available = true
156 problem.available = true
157 problem.save
157 problem.save
158 end
158 end
159 redirect_to action: :index
159 redirect_to action: :index
160 end
160 end
161
161
162 def stat
162 def stat
163 @problem = Problem.find(params[:id])
163 @problem = Problem.find(params[:id])
164 unless @problem.available or session[:admin]
164 unless @problem.available or session[:admin]
165 redirect_to :controller => 'main', :action => 'list'
165 redirect_to :controller => 'main', :action => 'list'
166 return
166 return
167 end
167 end
168 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
168 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
169
169
170 #stat summary
170 #stat summary
171 range =65
171 range =65
172 @histogram = { data: Array.new(range,0), summary: {} }
172 @histogram = { data: Array.new(range,0), summary: {} }
173 user = Hash.new(0)
173 user = Hash.new(0)
174 @submissions.find_each do |sub|
174 @submissions.find_each do |sub|
175 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
175 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
176 @histogram[:data][d.to_i] += 1 if d < range
176 @histogram[:data][d.to_i] += 1 if d < range
177 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
177 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
178 end
178 end
179 @histogram[:summary][:max] = [@histogram[:data].max,1].max
179 @histogram[:summary][:max] = [@histogram[:data].max,1].max
180
180
181 @summary = { attempt: user.count, solve: 0 }
181 @summary = { attempt: user.count, solve: 0 }
182 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
182 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
183 end
183 end
184
184
185 def manage
185 def manage
186 @problems = Problem.order(date_added: :desc)
186 @problems = Problem.order(date_added: :desc)
187 end
187 end
188
188
189 def do_manage
189 def do_manage
190 if params.has_key? 'change_date_added'
190 if params.has_key? 'change_date_added'
191 change_date_added
191 change_date_added
192 elsif params.has_key? 'add_to_contest'
192 elsif params.has_key? 'add_to_contest'
193 add_to_contest
193 add_to_contest
194 elsif params.has_key? 'enable_problem'
194 elsif params.has_key? 'enable_problem'
195 set_available(true)
195 set_available(true)
196 elsif params.has_key? 'disable_problem'
196 elsif params.has_key? 'disable_problem'
197 set_available(false)
197 set_available(false)
198 end
198 end
199 redirect_to :action => 'manage'
199 redirect_to :action => 'manage'
200 end
200 end
201
201
202 def import
202 def import
203 @allow_test_pair_import = allow_test_pair_import?
203 @allow_test_pair_import = allow_test_pair_import?
204 end
204 end
205
205
206 def do_import
206 def do_import
207 old_problem = Problem.find_by_name(params[:name])
207 old_problem = Problem.find_by_name(params[:name])
208 if !allow_test_pair_import? and params.has_key? :import_to_db
208 if !allow_test_pair_import? and params.has_key? :import_to_db
209 params.delete :import_to_db
209 params.delete :import_to_db
210 end
210 end
211 @problem, import_log = Problem.create_from_import_form_params(params,
211 @problem, import_log = Problem.create_from_import_form_params(params,
212 old_problem)
212 old_problem)
213
213
214 if !@problem.errors.empty?
214 if !@problem.errors.empty?
215 render :action => 'import' and return
215 render :action => 'import' and return
216 end
216 end
217
217
218 if old_problem!=nil
218 if old_problem!=nil
219 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
219 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
220 end
220 end
221 @log = import_log
221 @log = import_log
222 end
222 end
223
223
224 def remove_contest
224 def remove_contest
225 problem = Problem.find(params[:id])
225 problem = Problem.find(params[:id])
226 contest = Contest.find(params[:contest_id])
226 contest = Contest.find(params[:contest_id])
227 if problem!=nil and contest!=nil
227 if problem!=nil and contest!=nil
228 problem.contests.delete(contest)
228 problem.contests.delete(contest)
229 end
229 end
230 redirect_to :action => 'manage'
230 redirect_to :action => 'manage'
231 end
231 end
232
232
233 ##################################
233 ##################################
234 protected
234 protected
235
235
236 def allow_test_pair_import?
236 def allow_test_pair_import?
237 if defined? ALLOW_TEST_PAIR_IMPORT
237 if defined? ALLOW_TEST_PAIR_IMPORT
238 return ALLOW_TEST_PAIR_IMPORT
238 return ALLOW_TEST_PAIR_IMPORT
239 else
239 else
240 return false
240 return false
241 end
241 end
242 end
242 end
243
243
244 def change_date_added
244 def change_date_added
245 problems = get_problems_from_params
245 problems = get_problems_from_params
246 year = params[:date_added][:year].to_i
246 year = params[:date_added][:year].to_i
247 month = params[:date_added][:month].to_i
247 month = params[:date_added][:month].to_i
248 day = params[:date_added][:day].to_i
248 day = params[:date_added][:day].to_i
249 date = Date.new(year,month,day)
249 date = Date.new(year,month,day)
250 problems.each do |p|
250 problems.each do |p|
251 p.date_added = date
251 p.date_added = date
252 p.save
252 p.save
253 end
253 end
254 end
254 end
255
255
256 def add_to_contest
256 def add_to_contest
257 problems = get_problems_from_params
257 problems = get_problems_from_params
258 contest = Contest.find(params[:contest][:id])
258 contest = Contest.find(params[:contest][:id])
259 if contest!=nil and contest.enabled
259 if contest!=nil and contest.enabled
260 problems.each do |p|
260 problems.each do |p|
261 p.contests << contest
261 p.contests << contest
262 end
262 end
263 end
263 end
264 end
264 end
265
265
266 def set_available(avail)
266 def set_available(avail)
267 problems = get_problems_from_params
267 problems = get_problems_from_params
268 problems.each do |p|
268 problems.each do |p|
269 p.available = avail
269 p.available = avail
270 p.save
270 p.save
271 end
271 end
272 end
272 end
273
273
274 def get_problems_from_params
274 def get_problems_from_params
275 problems = []
275 problems = []
276 params.keys.each do |k|
276 params.keys.each do |k|
277 if k.index('prob-')==0
277 if k.index('prob-')==0
278 name, id, order = k.split('-')
278 name, id, order = k.split('-')
279 problems << Problem.find(id)
279 problems << Problem.find(id)
280 end
280 end
281 end
281 end
282 problems
282 problems
283 end
283 end
284
284
285 def get_problems_stat
285 def get_problems_stat
286 end
286 end
287
287
288 private
288 private
289
289
290 def problem_params
290 def problem_params
291 params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description)
291 params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description)
292 end
292 end
293
293
294 end
294 end
@@ -1,555 +1,555
1 require 'csv'
1 require 'csv'
2
2
3 class UserAdminController < ApplicationController
3 class UserAdminController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :admin_authorization
7 before_filter :admin_authorization
8
8
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 verify :method => :post, :only => [
10 verify :method => :post, :only => [
11 :create, :create_from_list,
11 :create, :create_from_list,
12 :update,
12 :update,
13 :manage_contest,
13 :manage_contest,
14 :bulk_mail
14 :bulk_mail
15 ],
15 ],
16 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
17
17
18 def index
18 def index
19 @user_count = User.count
19 @user_count = User.count
20 if params[:page] == 'all'
20 if params[:page] == 'all'
21 @users = User.all
21 @users = User.all
22 @paginated = false
22 @paginated = false
23 else
23 else
24 @users = User.paginate :page => params[:page]
24 @users = User.paginate :page => params[:page]
25 @paginated = true
25 @paginated = true
26 end
26 end
27 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
27 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
28 @contests = Contest.enabled
28 @contests = Contest.enabled
29 end
29 end
30
30
31 def active
31 def active
32 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
32 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
33 @users = []
33 @users = []
34 sessions.each do |session|
34 sessions.each do |session|
35 if session.data[:user_id]
35 if session.data[:user_id]
36 @users << User.find(session.data[:user_id])
36 @users << User.find(session.data[:user_id])
37 end
37 end
38 end
38 end
39 end
39 end
40
40
41 def show
41 def show
42 @user = User.find(params[:id])
42 @user = User.find(params[:id])
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 end
47 end
48
48
49 def create
49 def create
50 - @user = User.new(params[:user])
50 + @user = User.new(user_params)
51 @user.activated = true
51 @user.activated = true
52 if @user.save
52 if @user.save
53 flash[:notice] = 'User was successfully created.'
53 flash[:notice] = 'User was successfully created.'
54 redirect_to :action => 'index'
54 redirect_to :action => 'index'
55 else
55 else
56 render :action => 'new'
56 render :action => 'new'
57 end
57 end
58 end
58 end
59
59
60 def clear_last_ip
60 def clear_last_ip
61 @user = User.find(params[:id])
61 @user = User.find(params[:id])
62 @user.last_ip = nil
62 @user.last_ip = nil
63 @user.save
63 @user.save
64 redirect_to action: 'index', page: params[:page]
64 redirect_to action: 'index', page: params[:page]
65 end
65 end
66
66
67 def create_from_list
67 def create_from_list
68 lines = params[:user_list]
68 lines = params[:user_list]
69
69
70 note = []
70 note = []
71
71
72 lines.split("\n").each do |line|
72 lines.split("\n").each do |line|
73 items = line.chomp.split(',')
73 items = line.chomp.split(',')
74 if items.length>=2
74 if items.length>=2
75 login = items[0]
75 login = items[0]
76 full_name = items[1]
76 full_name = items[1]
77 remark =''
77 remark =''
78 user_alias = ''
78 user_alias = ''
79
79
80 added_random_password = false
80 added_random_password = false
81 if items.length >= 3 and items[2].chomp(" ").length > 0;
81 if items.length >= 3 and items[2].chomp(" ").length > 0;
82 password = items[2].chomp(" ")
82 password = items[2].chomp(" ")
83 else
83 else
84 password = random_password
84 password = random_password
85 add_random_password=true;
85 add_random_password=true;
86 end
86 end
87
87
88 if items.length>= 4 and items[3].chomp(" ").length > 0;
88 if items.length>= 4 and items[3].chomp(" ").length > 0;
89 user_alias = items[3].chomp(" ")
89 user_alias = items[3].chomp(" ")
90 else
90 else
91 user_alias = login
91 user_alias = login
92 end
92 end
93
93
94 if items.length>=5
94 if items.length>=5
95 remark = items[4].strip;
95 remark = items[4].strip;
96 end
96 end
97
97
98 user = User.find_by_login(login)
98 user = User.find_by_login(login)
99 if (user)
99 if (user)
100 user.full_name = full_name
100 user.full_name = full_name
101 user.password = password
101 user.password = password
102 user.remark = remark
102 user.remark = remark
103 else
103 else
104 user = User.new({:login => login,
104 user = User.new({:login => login,
105 :full_name => full_name,
105 :full_name => full_name,
106 :password => password,
106 :password => password,
107 :password_confirmation => password,
107 :password_confirmation => password,
108 :alias => user_alias,
108 :alias => user_alias,
109 :remark => remark})
109 :remark => remark})
110 end
110 end
111 user.activated = true
111 user.activated = true
112 user.save
112 user.save
113
113
114 if added_random_password
114 if added_random_password
115 note << "'#{login}' (+)"
115 note << "'#{login}' (+)"
116 else
116 else
117 note << login
117 note << login
118 end
118 end
119 end
119 end
120 end
120 end
121 flash[:success] = 'User(s) ' + note.join(', ') +
121 flash[:success] = 'User(s) ' + note.join(', ') +
122 ' were successfully created. ' +
122 ' were successfully created. ' +
123 '( (+) - created with random passwords.)'
123 '( (+) - created with random passwords.)'
124 redirect_to :action => 'index'
124 redirect_to :action => 'index'
125 end
125 end
126
126
127 def edit
127 def edit
128 @user = User.find(params[:id])
128 @user = User.find(params[:id])
129 end
129 end
130
130
131 def update
131 def update
132 @user = User.find(params[:id])
132 @user = User.find(params[:id])
133 if @user.update_attributes(user_params)
133 if @user.update_attributes(user_params)
134 flash[:notice] = 'User was successfully updated.'
134 flash[:notice] = 'User was successfully updated.'
135 redirect_to :action => 'show', :id => @user
135 redirect_to :action => 'show', :id => @user
136 else
136 else
137 render :action => 'edit'
137 render :action => 'edit'
138 end
138 end
139 end
139 end
140
140
141 def destroy
141 def destroy
142 User.find(params[:id]).destroy
142 User.find(params[:id]).destroy
143 redirect_to :action => 'index'
143 redirect_to :action => 'index'
144 end
144 end
145
145
146 def user_stat
146 def user_stat
147 if params[:commit] == 'download csv'
147 if params[:commit] == 'download csv'
148 @problems = Problem.all
148 @problems = Problem.all
149 else
149 else
150 @problems = Problem.available_problems
150 @problems = Problem.available_problems
151 end
151 end
152 @users = User.includes(:contests, :contest_stat).where(enabled: true)
152 @users = User.includes(:contests, :contest_stat).where(enabled: true)
153 @scorearray = Array.new
153 @scorearray = Array.new
154 @users.each do |u|
154 @users.each do |u|
155 ustat = Array.new
155 ustat = Array.new
156 ustat[0] = u
156 ustat[0] = u
157 @problems.each do |p|
157 @problems.each do |p|
158 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
158 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
159 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
159 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
160 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
160 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
161 else
161 else
162 ustat << [0,false]
162 ustat << [0,false]
163 end
163 end
164 end
164 end
165 @scorearray << ustat
165 @scorearray << ustat
166 end
166 end
167 if params[:commit] == 'download csv' then
167 if params[:commit] == 'download csv' then
168 csv = gen_csv_from_scorearray(@scorearray,@problems)
168 csv = gen_csv_from_scorearray(@scorearray,@problems)
169 send_data csv, filename: 'last_score.csv'
169 send_data csv, filename: 'last_score.csv'
170 else
170 else
171 render template: 'user_admin/user_stat'
171 render template: 'user_admin/user_stat'
172 end
172 end
173 end
173 end
174
174
175 def user_stat_max
175 def user_stat_max
176 if params[:commit] == 'download csv'
176 if params[:commit] == 'download csv'
177 @problems = Problem.all
177 @problems = Problem.all
178 else
178 else
179 @problems = Problem.available_problems
179 @problems = Problem.available_problems
180 end
180 end
181 @users = User.includes(:contests).includes(:contest_stat).all
181 @users = User.includes(:contests).includes(:contest_stat).all
182 @scorearray = Array.new
182 @scorearray = Array.new
183 #set up range from param
183 #set up range from param
184 since_id = params.fetch(:since_id, 0).to_i
184 since_id = params.fetch(:since_id, 0).to_i
185 until_id = params.fetch(:until_id, 0).to_i
185 until_id = params.fetch(:until_id, 0).to_i
186 @users.each do |u|
186 @users.each do |u|
187 ustat = Array.new
187 ustat = Array.new
188 ustat[0] = u
188 ustat[0] = u
189 @problems.each do |p|
189 @problems.each do |p|
190 max_points = 0
190 max_points = 0
191 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
191 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
192 max_points = sub.points if sub and sub.points and (sub.points > max_points)
192 max_points = sub.points if sub and sub.points and (sub.points > max_points)
193 end
193 end
194 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
194 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
195 end
195 end
196 @scorearray << ustat
196 @scorearray << ustat
197 end
197 end
198
198
199 if params[:commit] == 'download csv' then
199 if params[:commit] == 'download csv' then
200 csv = gen_csv_from_scorearray(@scorearray,@problems)
200 csv = gen_csv_from_scorearray(@scorearray,@problems)
201 send_data csv, filename: 'max_score.csv'
201 send_data csv, filename: 'max_score.csv'
202 else
202 else
203 render template: 'user_admin/user_stat'
203 render template: 'user_admin/user_stat'
204 end
204 end
205 end
205 end
206
206
207 def import
207 def import
208 if params[:file]==''
208 if params[:file]==''
209 flash[:notice] = 'Error importing no file'
209 flash[:notice] = 'Error importing no file'
210 redirect_to :action => 'index' and return
210 redirect_to :action => 'index' and return
211 end
211 end
212 import_from_file(params[:file])
212 import_from_file(params[:file])
213 end
213 end
214
214
215 def random_all_passwords
215 def random_all_passwords
216 users = User.all
216 users = User.all
217 @prefix = params[:prefix] || ''
217 @prefix = params[:prefix] || ''
218 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
218 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
219 @changed = false
219 @changed = false
220 if request.request_method == 'POST'
220 if request.request_method == 'POST'
221 @non_admin_users.each do |user|
221 @non_admin_users.each do |user|
222 password = random_password
222 password = random_password
223 user.password = password
223 user.password = password
224 user.password_confirmation = password
224 user.password_confirmation = password
225 user.save
225 user.save
226 end
226 end
227 @changed = true
227 @changed = true
228 end
228 end
229 end
229 end
230
230
231 # contest management
231 # contest management
232
232
233 def contests
233 def contests
234 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
234 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
235 @contests = Contest.enabled
235 @contests = Contest.enabled
236 end
236 end
237
237
238 def assign_from_list
238 def assign_from_list
239 contest_id = params[:users_contest_id]
239 contest_id = params[:users_contest_id]
240 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
240 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
241 contest = Contest.find(params[:new_contest][:id])
241 contest = Contest.find(params[:new_contest][:id])
242 if !contest
242 if !contest
243 flash[:notice] = 'Error: no contest'
243 flash[:notice] = 'Error: no contest'
244 redirect_to :action => 'contests', :id =>contest_id
244 redirect_to :action => 'contests', :id =>contest_id
245 end
245 end
246
246
247 note = []
247 note = []
248 users.each do |u|
248 users.each do |u|
249 u.contests = [contest]
249 u.contests = [contest]
250 note << u.login
250 note << u.login
251 end
251 end
252 flash[:notice] = 'User(s) ' + note.join(', ') +
252 flash[:notice] = 'User(s) ' + note.join(', ') +
253 " were successfully reassigned to #{contest.title}."
253 " were successfully reassigned to #{contest.title}."
254 redirect_to :action => 'contests', :id =>contest.id
254 redirect_to :action => 'contests', :id =>contest.id
255 end
255 end
256
256
257 def add_to_contest
257 def add_to_contest
258 user = User.find(params[:id])
258 user = User.find(params[:id])
259 contest = Contest.find(params[:contest_id])
259 contest = Contest.find(params[:contest_id])
260 if user and contest
260 if user and contest
261 user.contests << contest
261 user.contests << contest
262 end
262 end
263 redirect_to :action => 'index'
263 redirect_to :action => 'index'
264 end
264 end
265
265
266 def remove_from_contest
266 def remove_from_contest
267 user = User.find(params[:id])
267 user = User.find(params[:id])
268 contest = Contest.find(params[:contest_id])
268 contest = Contest.find(params[:contest_id])
269 if user and contest
269 if user and contest
270 user.contests.delete(contest)
270 user.contests.delete(contest)
271 end
271 end
272 redirect_to :action => 'index'
272 redirect_to :action => 'index'
273 end
273 end
274
274
275 def contest_management
275 def contest_management
276 end
276 end
277
277
278 def manage_contest
278 def manage_contest
279 contest = Contest.find(params[:contest][:id])
279 contest = Contest.find(params[:contest][:id])
280 if !contest
280 if !contest
281 flash[:notice] = 'You did not choose the contest.'
281 flash[:notice] = 'You did not choose the contest.'
282 redirect_to :action => 'contest_management' and return
282 redirect_to :action => 'contest_management' and return
283 end
283 end
284
284
285 operation = params[:operation]
285 operation = params[:operation]
286
286
287 if not ['add','remove','assign'].include? operation
287 if not ['add','remove','assign'].include? operation
288 flash[:notice] = 'You did not choose the operation to perform.'
288 flash[:notice] = 'You did not choose the operation to perform.'
289 redirect_to :action => 'contest_management' and return
289 redirect_to :action => 'contest_management' and return
290 end
290 end
291
291
292 lines = params[:login_list]
292 lines = params[:login_list]
293 if !lines or lines.blank?
293 if !lines or lines.blank?
294 flash[:notice] = 'You entered an empty list.'
294 flash[:notice] = 'You entered an empty list.'
295 redirect_to :action => 'contest_management' and return
295 redirect_to :action => 'contest_management' and return
296 end
296 end
297
297
298 note = []
298 note = []
299 users = []
299 users = []
300 lines.split("\n").each do |line|
300 lines.split("\n").each do |line|
301 user = User.find_by_login(line.chomp)
301 user = User.find_by_login(line.chomp)
302 if user
302 if user
303 if operation=='add'
303 if operation=='add'
304 if ! user.contests.include? contest
304 if ! user.contests.include? contest
305 user.contests << contest
305 user.contests << contest
306 end
306 end
307 elsif operation=='remove'
307 elsif operation=='remove'
308 user.contests.delete(contest)
308 user.contests.delete(contest)
309 else
309 else
310 user.contests = [contest]
310 user.contests = [contest]
311 end
311 end
312
312
313 if params[:reset_timer]
313 if params[:reset_timer]
314 user.contest_stat.forced_logout = true
314 user.contest_stat.forced_logout = true
315 user.contest_stat.reset_timer_and_save
315 user.contest_stat.reset_timer_and_save
316 end
316 end
317
317
318 if params[:notification_emails]
318 if params[:notification_emails]
319 send_contest_update_notification_email(user, contest)
319 send_contest_update_notification_email(user, contest)
320 end
320 end
321
321
322 note << user.login
322 note << user.login
323 users << user
323 users << user
324 end
324 end
325 end
325 end
326
326
327 if params[:reset_timer]
327 if params[:reset_timer]
328 logout_users(users)
328 logout_users(users)
329 end
329 end
330
330
331 flash[:notice] = 'User(s) ' + note.join(', ') +
331 flash[:notice] = 'User(s) ' + note.join(', ') +
332 ' were successfully modified. '
332 ' were successfully modified. '
333 redirect_to :action => 'contest_management'
333 redirect_to :action => 'contest_management'
334 end
334 end
335
335
336 # admin management
336 # admin management
337
337
338 def admin
338 def admin
339 @admins = User.all.find_all {|user| user.admin? }
339 @admins = User.all.find_all {|user| user.admin? }
340 end
340 end
341
341
342 def grant_admin
342 def grant_admin
343 login = params[:login]
343 login = params[:login]
344 user = User.find_by_login(login)
344 user = User.find_by_login(login)
345 if user!=nil
345 if user!=nil
346 admin_role = Role.find_by_name('admin')
346 admin_role = Role.find_by_name('admin')
347 user.roles << admin_role
347 user.roles << admin_role
348 else
348 else
349 flash[:notice] = 'Unknown user'
349 flash[:notice] = 'Unknown user'
350 end
350 end
351 flash[:notice] = 'User added as admins'
351 flash[:notice] = 'User added as admins'
352 redirect_to :action => 'admin'
352 redirect_to :action => 'admin'
353 end
353 end
354
354
355 def revoke_admin
355 def revoke_admin
356 user = User.find(params[:id])
356 user = User.find(params[:id])
357 if user==nil
357 if user==nil
358 flash[:notice] = 'Unknown user'
358 flash[:notice] = 'Unknown user'
359 redirect_to :action => 'admin' and return
359 redirect_to :action => 'admin' and return
360 elsif user.login == 'root'
360 elsif user.login == 'root'
361 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
361 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
362 redirect_to :action => 'admin' and return
362 redirect_to :action => 'admin' and return
363 end
363 end
364
364
365 admin_role = Role.find_by_name('admin')
365 admin_role = Role.find_by_name('admin')
366 user.roles.delete(admin_role)
366 user.roles.delete(admin_role)
367 flash[:notice] = 'User permission revoked'
367 flash[:notice] = 'User permission revoked'
368 redirect_to :action => 'admin'
368 redirect_to :action => 'admin'
369 end
369 end
370
370
371 # mass mailing
371 # mass mailing
372
372
373 def mass_mailing
373 def mass_mailing
374 end
374 end
375
375
376 def bulk_mail
376 def bulk_mail
377 lines = params[:login_list]
377 lines = params[:login_list]
378 if !lines or lines.blank?
378 if !lines or lines.blank?
379 flash[:notice] = 'You entered an empty list.'
379 flash[:notice] = 'You entered an empty list.'
380 redirect_to :action => 'mass_mailing' and return
380 redirect_to :action => 'mass_mailing' and return
381 end
381 end
382
382
383 mail_subject = params[:subject]
383 mail_subject = params[:subject]
384 if !mail_subject or mail_subject.blank?
384 if !mail_subject or mail_subject.blank?
385 flash[:notice] = 'You entered an empty mail subject.'
385 flash[:notice] = 'You entered an empty mail subject.'
386 redirect_to :action => 'mass_mailing' and return
386 redirect_to :action => 'mass_mailing' and return
387 end
387 end
388
388
389 mail_body = params[:email_body]
389 mail_body = params[:email_body]
390 if !mail_body or mail_body.blank?
390 if !mail_body or mail_body.blank?
391 flash[:notice] = 'You entered an empty mail body.'
391 flash[:notice] = 'You entered an empty mail body.'
392 redirect_to :action => 'mass_mailing' and return
392 redirect_to :action => 'mass_mailing' and return
393 end
393 end
394
394
395 note = []
395 note = []
396 users = []
396 users = []
397 lines.split("\n").each do |line|
397 lines.split("\n").each do |line|
398 user = User.find_by_login(line.chomp)
398 user = User.find_by_login(line.chomp)
399 if user
399 if user
400 send_mail(user.email, mail_subject, mail_body)
400 send_mail(user.email, mail_subject, mail_body)
401 note << user.login
401 note << user.login
402 end
402 end
403 end
403 end
404
404
405 flash[:notice] = 'User(s) ' + note.join(', ') +
405 flash[:notice] = 'User(s) ' + note.join(', ') +
406 ' were successfully modified. '
406 ' were successfully modified. '
407 redirect_to :action => 'mass_mailing'
407 redirect_to :action => 'mass_mailing'
408 end
408 end
409
409
410 protected
410 protected
411
411
412 def random_password(length=5)
412 def random_password(length=5)
413 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
413 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
414 newpass = ""
414 newpass = ""
415 length.times { newpass << chars[rand(chars.size-1)] }
415 length.times { newpass << chars[rand(chars.size-1)] }
416 return newpass
416 return newpass
417 end
417 end
418
418
419 def import_from_file(f)
419 def import_from_file(f)
420 data_hash = YAML.load(f)
420 data_hash = YAML.load(f)
421 @import_log = ""
421 @import_log = ""
422
422
423 country_data = data_hash[:countries]
423 country_data = data_hash[:countries]
424 site_data = data_hash[:sites]
424 site_data = data_hash[:sites]
425 user_data = data_hash[:users]
425 user_data = data_hash[:users]
426
426
427 # import country
427 # import country
428 countries = {}
428 countries = {}
429 country_data.each_pair do |id,country|
429 country_data.each_pair do |id,country|
430 c = Country.find_by_name(country[:name])
430 c = Country.find_by_name(country[:name])
431 if c!=nil
431 if c!=nil
432 countries[id] = c
432 countries[id] = c
433 @import_log << "Found #{country[:name]}\n"
433 @import_log << "Found #{country[:name]}\n"
434 else
434 else
435 countries[id] = Country.new(:name => country[:name])
435 countries[id] = Country.new(:name => country[:name])
436 countries[id].save
436 countries[id].save
437 @import_log << "Created #{country[:name]}\n"
437 @import_log << "Created #{country[:name]}\n"
438 end
438 end
439 end
439 end
440
440
441 # import sites
441 # import sites
442 sites = {}
442 sites = {}
443 site_data.each_pair do |id,site|
443 site_data.each_pair do |id,site|
444 s = Site.find_by_name(site[:name])
444 s = Site.find_by_name(site[:name])
445 if s!=nil
445 if s!=nil
446 @import_log << "Found #{site[:name]}\n"
446 @import_log << "Found #{site[:name]}\n"
447 else
447 else
448 s = Site.new(:name => site[:name])
448 s = Site.new(:name => site[:name])
449 @import_log << "Created #{site[:name]}\n"
449 @import_log << "Created #{site[:name]}\n"
450 end
450 end
451 s.password = site[:password]
451 s.password = site[:password]
452 s.country = countries[site[:country_id]]
452 s.country = countries[site[:country_id]]
453 s.save
453 s.save
454 sites[id] = s
454 sites[id] = s
455 end
455 end
456
456
457 # import users
457 # import users
458 user_data.each_pair do |id,user|
458 user_data.each_pair do |id,user|
459 u = User.find_by_login(user[:login])
459 u = User.find_by_login(user[:login])
460 if u!=nil
460 if u!=nil
461 @import_log << "Found #{user[:login]}\n"
461 @import_log << "Found #{user[:login]}\n"
462 else
462 else
463 u = User.new(:login => user[:login])
463 u = User.new(:login => user[:login])
464 @import_log << "Created #{user[:login]}\n"
464 @import_log << "Created #{user[:login]}\n"
465 end
465 end
466 u.full_name = user[:name]
466 u.full_name = user[:name]
467 u.password = user[:password]
467 u.password = user[:password]
468 u.country = countries[user[:country_id]]
468 u.country = countries[user[:country_id]]
469 u.site = sites[user[:site_id]]
469 u.site = sites[user[:site_id]]
470 u.activated = true
470 u.activated = true
471 u.email = "empty-#{u.login}@none.com"
471 u.email = "empty-#{u.login}@none.com"
472 if not u.save
472 if not u.save
473 @import_log << "Errors\n"
473 @import_log << "Errors\n"
474 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
474 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
475 end
475 end
476 end
476 end
477
477
478 end
478 end
479
479
480 def logout_users(users)
480 def logout_users(users)
481 users.each do |user|
481 users.each do |user|
482 contest_stat = user.contest_stat(true)
482 contest_stat = user.contest_stat(true)
483 if contest_stat and !contest_stat.forced_logout
483 if contest_stat and !contest_stat.forced_logout
484 contest_stat.forced_logout = true
484 contest_stat.forced_logout = true
485 contest_stat.save
485 contest_stat.save
486 end
486 end
487 end
487 end
488 end
488 end
489
489
490 def send_contest_update_notification_email(user, contest)
490 def send_contest_update_notification_email(user, contest)
491 contest_title_name = GraderConfiguration['contest.name']
491 contest_title_name = GraderConfiguration['contest.name']
492 contest_name = contest.name
492 contest_name = contest.name
493 mail_subject = t('contest.notification.email_subject', {
493 mail_subject = t('contest.notification.email_subject', {
494 :contest_title_name => contest_title_name,
494 :contest_title_name => contest_title_name,
495 :contest_name => contest_name })
495 :contest_name => contest_name })
496 mail_body = t('contest.notification.email_body', {
496 mail_body = t('contest.notification.email_body', {
497 :full_name => user.full_name,
497 :full_name => user.full_name,
498 :contest_title_name => contest_title_name,
498 :contest_title_name => contest_title_name,
499 :contest_name => contest.name,
499 :contest_name => contest.name,
500 })
500 })
501
501
502 logger.info mail_body
502 logger.info mail_body
503 send_mail(user.email, mail_subject, mail_body)
503 send_mail(user.email, mail_subject, mail_body)
504 end
504 end
505
505
506 def find_contest_and_user_from_contest_id(id)
506 def find_contest_and_user_from_contest_id(id)
507 if id!='none'
507 if id!='none'
508 @contest = Contest.find(id)
508 @contest = Contest.find(id)
509 else
509 else
510 @contest = nil
510 @contest = nil
511 end
511 end
512 if @contest
512 if @contest
513 @users = @contest.users
513 @users = @contest.users
514 else
514 else
515 @users = User.find_users_with_no_contest
515 @users = User.find_users_with_no_contest
516 end
516 end
517 return [@contest, @users]
517 return [@contest, @users]
518 end
518 end
519
519
520 def gen_csv_from_scorearray(scorearray,problem)
520 def gen_csv_from_scorearray(scorearray,problem)
521 CSV.generate do |csv|
521 CSV.generate do |csv|
522 #add header
522 #add header
523 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
523 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
524 problem.each { |p| header << p.name }
524 problem.each { |p| header << p.name }
525 header += ['Total','Passed']
525 header += ['Total','Passed']
526 csv << header
526 csv << header
527 #add data
527 #add data
528 scorearray.each do |sc|
528 scorearray.each do |sc|
529 total = num_passed = 0
529 total = num_passed = 0
530 row = Array.new
530 row = Array.new
531 sc.each_index do |i|
531 sc.each_index do |i|
532 if i == 0
532 if i == 0
533 row << sc[i].login
533 row << sc[i].login
534 row << sc[i].full_name
534 row << sc[i].full_name
535 row << sc[i].activated
535 row << sc[i].activated
536 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
536 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
537 row << sc[i].contests.collect {|c| c.name}.join(', ')
537 row << sc[i].contests.collect {|c| c.name}.join(', ')
538 else
538 else
539 row << sc[i][0]
539 row << sc[i][0]
540 total += sc[i][0]
540 total += sc[i][0]
541 num_passed += 1 if sc[i][1]
541 num_passed += 1 if sc[i][1]
542 end
542 end
543 end
543 end
544 row << total
544 row << total
545 row << num_passed
545 row << num_passed
546 csv << row
546 csv << row
547 end
547 end
548 end
548 end
549 end
549 end
550
550
551 private
551 private
552 def user_params
552 def user_params
553 params.require(:user).permit(:login,:full_name,:hashed_password,:salt,:alias,:email,:site_id,:country_id,:activated,:enabled,:remark,:last_ip,:section)
553 params.require(:user).permit(:login,:full_name,:hashed_password,:salt,:alias,:email,:site_id,:country_id,:activated,:enabled,:remark,:last_ip,:section)
554 end
554 end
555 end
555 end
@@ -1,214 +1,218
1 require 'net/smtp'
1 require 'net/smtp'
2
2
3 class UsersController < ApplicationController
3 class UsersController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :authenticate, :except => [:new,
7 before_filter :authenticate, :except => [:new,
8 :register,
8 :register,
9 :confirm,
9 :confirm,
10 :forget,
10 :forget,
11 :retrieve_password]
11 :retrieve_password]
12
12
13 before_filter :verify_online_registration, :only => [:new,
13 before_filter :verify_online_registration, :only => [:new,
14 :register,
14 :register,
15 :forget,
15 :forget,
16 :retrieve_password]
16 :retrieve_password]
17 before_filter :authenticate, :profile_authorization, only: [:profile]
17 before_filter :authenticate, :profile_authorization, only: [:profile]
18
18
19 verify :method => :post, :only => [:chg_passwd],
19 verify :method => :post, :only => [:chg_passwd],
20 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
21
21
22 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
23 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
24
24
25 def index
25 def index
26 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
27 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
28 else
28 else
29 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
30 end
30 end
31 end
31 end
32
32
33 def chg_passwd
33 def chg_passwd
34 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
35 user.password = params[:passwd]
35 user.password = params[:passwd]
36 user.password_confirmation = params[:passwd_verify]
36 user.password_confirmation = params[:passwd_verify]
37 if user.save
37 if user.save
38 flash[:notice] = 'password changed'
38 flash[:notice] = 'password changed'
39 else
39 else
40 flash[:notice] = 'Error: password changing failed'
40 flash[:notice] = 'Error: password changing failed'
41 end
41 end
42 redirect_to :action => 'index'
42 redirect_to :action => 'index'
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 render :action => 'new', :layout => 'empty'
47 render :action => 'new', :layout => 'empty'
48 end
48 end
49
49
50 def register
50 def register
51 if(params[:cancel])
51 if(params[:cancel])
52 redirect_to :controller => 'main', :action => 'login'
52 redirect_to :controller => 'main', :action => 'login'
53 return
53 return
54 end
54 end
55 - @user = User.new(params[:user])
55 + @user = User.new(user_params)
56 @user.password_confirmation = @user.password = User.random_password
56 @user.password_confirmation = @user.password = User.random_password
57 @user.activated = false
57 @user.activated = false
58 if (@user.valid?) and (@user.save)
58 if (@user.valid?) and (@user.save)
59 if send_confirmation_email(@user)
59 if send_confirmation_email(@user)
60 render :action => 'new_splash', :layout => 'empty'
60 render :action => 'new_splash', :layout => 'empty'
61 else
61 else
62 @admin_email = GraderConfiguration['system.admin_email']
62 @admin_email = GraderConfiguration['system.admin_email']
63 render :action => 'email_error', :layout => 'empty'
63 render :action => 'email_error', :layout => 'empty'
64 end
64 end
65 else
65 else
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 render :action => 'new', :layout => 'empty'
67 render :action => 'new', :layout => 'empty'
68 end
68 end
69 end
69 end
70
70
71 def confirm
71 def confirm
72 login = params[:login]
72 login = params[:login]
73 key = params[:activation]
73 key = params[:activation]
74 @user = User.find_by_login(login)
74 @user = User.find_by_login(login)
75 if (@user) and (@user.verify_activation_key(key))
75 if (@user) and (@user.verify_activation_key(key))
76 if @user.valid? # check uniquenss of email
76 if @user.valid? # check uniquenss of email
77 @user.activated = true
77 @user.activated = true
78 @user.save
78 @user.save
79 @result = :successful
79 @result = :successful
80 else
80 else
81 @result = :email_used
81 @result = :email_used
82 end
82 end
83 else
83 else
84 @result = :failed
84 @result = :failed
85 end
85 end
86 render :action => 'confirm', :layout => 'empty'
86 render :action => 'confirm', :layout => 'empty'
87 end
87 end
88
88
89 def forget
89 def forget
90 render :action => 'forget', :layout => 'empty'
90 render :action => 'forget', :layout => 'empty'
91 end
91 end
92
92
93 def retrieve_password
93 def retrieve_password
94 email = params[:email]
94 email = params[:email]
95 user = User.find_by_email(email)
95 user = User.find_by_email(email)
96 if user
96 if user
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 if last_updated_time > Time.now.gmtime - 5.minutes
98 if last_updated_time > Time.now.gmtime - 5.minutes
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 else
100 else
101 user.password = user.password_confirmation = User.random_password
101 user.password = user.password_confirmation = User.random_password
102 user.save
102 user.save
103 send_new_password_email(user)
103 send_new_password_email(user)
104 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
105 end
105 end
106 else
106 else
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 end
108 end
109 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
110 end
110 end
111
111
112 def stat
112 def stat
113 @user = User.find(params[:id])
113 @user = User.find(params[:id])
114 @submission = Submission.includes(:problem).where(user_id: params[:id])
114 @submission = Submission.includes(:problem).where(user_id: params[:id])
115
115
116 range = 120
116 range = 120
117 @histogram = { data: Array.new(range,0), summary: {} }
117 @histogram = { data: Array.new(range,0), summary: {} }
118 @summary = {count: 0, solve: 0, attempt: 0}
118 @summary = {count: 0, solve: 0, attempt: 0}
119 problem = Hash.new(0)
119 problem = Hash.new(0)
120
120
121 @submission.find_each do |sub|
121 @submission.find_each do |sub|
122 #histogram
122 #histogram
123 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
123 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 @histogram[:data][d.to_i] += 1 if d < range
124 @histogram[:data][d.to_i] += 1 if d < range
125
125
126 @summary[:count] += 1
126 @summary[:count] += 1
127 next unless sub.problem
127 next unless sub.problem
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 end
129 end
130
130
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @summary[:attempt] = problem.count
132 @summary[:attempt] = problem.count
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 end
134 end
135
135
136 def toggle_activate
136 def toggle_activate
137 @user = User.find(params[:id])
137 @user = User.find(params[:id])
138 @user.update_attributes( activated: !@user.activated? )
138 @user.update_attributes( activated: !@user.activated? )
139 respond_to do |format|
139 respond_to do |format|
140 format.js { render partial: 'toggle_button',
140 format.js { render partial: 'toggle_button',
141 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
141 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 end
142 end
143 end
143 end
144
144
145 def toggle_enable
145 def toggle_enable
146 @user = User.find(params[:id])
146 @user = User.find(params[:id])
147 @user.update_attributes( enabled: !@user.enabled? )
147 @user.update_attributes( enabled: !@user.enabled? )
148 respond_to do |format|
148 respond_to do |format|
149 format.js { render partial: 'toggle_button',
149 format.js { render partial: 'toggle_button',
150 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
150 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 end
151 end
152 end
152 end
153
153
154 protected
154 protected
155
155
156 def verify_online_registration
156 def verify_online_registration
157 if !GraderConfiguration['system.online_registration']
157 if !GraderConfiguration['system.online_registration']
158 redirect_to :controller => 'main', :action => 'login'
158 redirect_to :controller => 'main', :action => 'login'
159 end
159 end
160 end
160 end
161
161
162 def send_confirmation_email(user)
162 def send_confirmation_email(user)
163 contest_name = GraderConfiguration['contest.name']
163 contest_name = GraderConfiguration['contest.name']
164 activation_url = url_for(:action => 'confirm',
164 activation_url = url_for(:action => 'confirm',
165 :login => user.login,
165 :login => user.login,
166 :activation => user.activation_key)
166 :activation => user.activation_key)
167 home_url = url_for(:controller => 'main', :action => 'index')
167 home_url = url_for(:controller => 'main', :action => 'index')
168 mail_subject = "[#{contest_name}] Confirmation"
168 mail_subject = "[#{contest_name}] Confirmation"
169 mail_body = t('registration.email_body', {
169 mail_body = t('registration.email_body', {
170 :full_name => user.full_name,
170 :full_name => user.full_name,
171 :contest_name => contest_name,
171 :contest_name => contest_name,
172 :login => user.login,
172 :login => user.login,
173 :password => user.password,
173 :password => user.password,
174 :activation_url => activation_url,
174 :activation_url => activation_url,
175 :admin_email => GraderConfiguration['system.admin_email']
175 :admin_email => GraderConfiguration['system.admin_email']
176 })
176 })
177
177
178 logger.info mail_body
178 logger.info mail_body
179
179
180 send_mail(user.email, mail_subject, mail_body)
180 send_mail(user.email, mail_subject, mail_body)
181 end
181 end
182
182
183 def send_new_password_email(user)
183 def send_new_password_email(user)
184 contest_name = GraderConfiguration['contest.name']
184 contest_name = GraderConfiguration['contest.name']
185 mail_subject = "[#{contest_name}] Password recovery"
185 mail_subject = "[#{contest_name}] Password recovery"
186 mail_body = t('registration.password_retrieval.email_body', {
186 mail_body = t('registration.password_retrieval.email_body', {
187 :full_name => user.full_name,
187 :full_name => user.full_name,
188 :contest_name => contest_name,
188 :contest_name => contest_name,
189 :login => user.login,
189 :login => user.login,
190 :password => user.password,
190 :password => user.password,
191 :admin_email => GraderConfiguration['system.admin_email']
191 :admin_email => GraderConfiguration['system.admin_email']
192 })
192 })
193
193
194 logger.info mail_body
194 logger.info mail_body
195
195
196 send_mail(user.email, mail_subject, mail_body)
196 send_mail(user.email, mail_subject, mail_body)
197 end
197 end
198
198
199 # allow viewing of regular user profile only when options allow so
199 # allow viewing of regular user profile only when options allow so
200 # only admins can view admins profile
200 # only admins can view admins profile
201 def profile_authorization
201 def profile_authorization
202 #if view admins' profile, allow only admin
202 #if view admins' profile, allow only admin
203 return false unless(params[:id])
203 return false unless(params[:id])
204 user = User.find(params[:id])
204 user = User.find(params[:id])
205 return false unless user
205 return false unless user
206 return admin_authorization if user.admin?
206 return admin_authorization if user.admin?
207 return true if GraderConfiguration["right.user_view_submission"]
207 return true if GraderConfiguration["right.user_view_submission"]
208
208
209 #finally, we allow only admin
209 #finally, we allow only admin
210 admin_authorization
210 admin_authorization
211 end
211 end
212 -
212 +
213 + private
214 + def user_params
215 + params.require(:user).permit(:login, :full_name, :email)
216 + end
213
217
214 end
218 end
You need to be logged in to leave comments. Login now