Description:
switch to strong parameter for mass update (have not finished the problem controller yet)
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r617:f062e467ef5c - - 10 files changed: 42 inserted, 63 deleted

@@ -1,111 +1,117
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.find(:all,
10 @announcements = Announcement.find(:all,
11 :order => "created_at DESC")
11 :order => "created_at DESC")
12
12
13 respond_to do |format|
13 respond_to do |format|
14 format.html # index.html.erb
14 format.html # index.html.erb
15 format.xml { render :xml => @announcements }
15 format.xml { render :xml => @announcements }
16 end
16 end
17 end
17 end
18
18
19 # GET /announcements/1
19 # GET /announcements/1
20 # GET /announcements/1.xml
20 # GET /announcements/1.xml
21 def show
21 def show
22 @announcement = Announcement.find(params[:id])
22 @announcement = Announcement.find(params[:id])
23
23
24 respond_to do |format|
24 respond_to do |format|
25 format.html # show.html.erb
25 format.html # show.html.erb
26 format.xml { render :xml => @announcement }
26 format.xml { render :xml => @announcement }
27 end
27 end
28 end
28 end
29
29
30 # GET /announcements/new
30 # GET /announcements/new
31 # GET /announcements/new.xml
31 # GET /announcements/new.xml
32 def new
32 def new
33 @announcement = Announcement.new
33 @announcement = Announcement.new
34
34
35 respond_to do |format|
35 respond_to do |format|
36 format.html # new.html.erb
36 format.html # new.html.erb
37 format.xml { render :xml => @announcement }
37 format.xml { render :xml => @announcement }
38 end
38 end
39 end
39 end
40
40
41 # GET /announcements/1/edit
41 # GET /announcements/1/edit
42 def edit
42 def edit
43 @announcement = Announcement.find(params[:id])
43 @announcement = Announcement.find(params[:id])
44 end
44 end
45
45
46 # POST /announcements
46 # POST /announcements
47 # POST /announcements.xml
47 # POST /announcements.xml
48 def create
48 def create
49 @announcement = Announcement.new(params[:announcement])
49 @announcement = Announcement.new(params[:announcement])
50
50
51 respond_to do |format|
51 respond_to do |format|
52 if @announcement.save
52 if @announcement.save
53 flash[:notice] = 'Announcement was successfully created.'
53 flash[:notice] = 'Announcement was successfully created.'
54 format.html { redirect_to(@announcement) }
54 format.html { redirect_to(@announcement) }
55 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
55 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
56 else
56 else
57 format.html { render :action => "new" }
57 format.html { render :action => "new" }
58 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
58 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
59 end
59 end
60 end
60 end
61 end
61 end
62
62
63 # PUT /announcements/1
63 # PUT /announcements/1
64 # PUT /announcements/1.xml
64 # PUT /announcements/1.xml
65 def update
65 def update
66 @announcement = Announcement.find(params[:id])
66 @announcement = Announcement.find(params[:id])
67
67
68 respond_to do |format|
68 respond_to do |format|
69 - if @announcement.update_attributes(params[:announcement])
69 + if @announcement.update_attributes(announcement_params)
70 flash[:notice] = 'Announcement was successfully updated.'
70 flash[:notice] = 'Announcement was successfully updated.'
71 format.html { redirect_to(@announcement) }
71 format.html { redirect_to(@announcement) }
72 format.js {}
72 format.js {}
73 format.xml { head :ok }
73 format.xml { head :ok }
74 else
74 else
75 format.html { render :action => "edit" }
75 format.html { render :action => "edit" }
76 format.js {}
76 format.js {}
77 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
77 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
78 end
78 end
79 end
79 end
80 end
80 end
81
81
82 def toggle
82 def toggle
83 @announcement = Announcement.find(params[:id])
83 @announcement = Announcement.find(params[:id])
84 @announcement.update_attributes( published: !@announcement.published? )
84 @announcement.update_attributes( published: !@announcement.published? )
85 respond_to do |format|
85 respond_to do |format|
86 format.js { render partial: 'toggle_button',
86 format.js { render partial: 'toggle_button',
87 locals: {button_id: "#announcement_toggle_#{@announcement.id}",button_on: @announcement.published? } }
87 locals: {button_id: "#announcement_toggle_#{@announcement.id}",button_on: @announcement.published? } }
88 end
88 end
89 end
89 end
90
90
91 def toggle_front
91 def toggle_front
92 @announcement = Announcement.find(params[:id])
92 @announcement = Announcement.find(params[:id])
93 @announcement.update_attributes( frontpage: !@announcement.frontpage? )
93 @announcement.update_attributes( frontpage: !@announcement.frontpage? )
94 respond_to do |format|
94 respond_to do |format|
95 format.js { render partial: 'toggle_button',
95 format.js { render partial: 'toggle_button',
96 locals: {button_id: "#announcement_toggle_front_#{@announcement.id}",button_on: @announcement.frontpage? } }
96 locals: {button_id: "#announcement_toggle_front_#{@announcement.id}",button_on: @announcement.frontpage? } }
97 end
97 end
98 end
98 end
99
99
100 # DELETE /announcements/1
100 # DELETE /announcements/1
101 # DELETE /announcements/1.xml
101 # DELETE /announcements/1.xml
102 def destroy
102 def destroy
103 @announcement = Announcement.find(params[:id])
103 @announcement = Announcement.find(params[:id])
104 @announcement.destroy
104 @announcement.destroy
105
105
106 respond_to do |format|
106 respond_to do |format|
107 format.html { redirect_to(announcements_url) }
107 format.html { redirect_to(announcements_url) }
108 format.xml { head :ok }
108 format.xml { head :ok }
109 end
109 end
110 end
110 end
111 +
112 + private
113 +
114 + def announcement_params
115 + params.require(:announcement).permit(:author, :body, :published, :frontpage, :contest_only,:title, :note)
111 end
116 end
117 + end
@@ -1,30 +1,35
1 class ConfigurationsController < ApplicationController
1 class ConfigurationsController < ApplicationController
2
2
3 before_filter :authenticate
3 before_filter :authenticate
4 before_filter { |controller| controller.authorization_by_roles(['admin'])}
4 before_filter { |controller| controller.authorization_by_roles(['admin'])}
5
5
6
6
7 def index
7 def index
8 @configurations = GraderConfiguration.find(:all,
8 @configurations = GraderConfiguration.find(:all,
9 :order => '`key`')
9 :order => '`key`')
10 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
10 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
11 end
11 end
12
12
13 def reload
13 def reload
14 GraderConfiguration.reload
14 GraderConfiguration.reload
15 redirect_to :action => 'index'
15 redirect_to :action => 'index'
16 end
16 end
17
17
18 def update
18 def update
19 @config = GraderConfiguration.find(params[:id])
19 @config = GraderConfiguration.find(params[:id])
20 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
20 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
21 respond_to do |format|
21 respond_to do |format|
22 - if @config.update_attributes(params[:grader_configuration])
22 + if @config.update_attributes(configuration_params)
23 format.json { head :ok }
23 format.json { head :ok }
24 else
24 else
25 format.json { respond_with_bip(@config) }
25 format.json { respond_with_bip(@config) }
26 end
26 end
27 end
27 end
28 end
28 end
29
29
30 + private
31 + def configuration_params
32 + params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
30 end
33 end
34 +
35 + end
@@ -1,92 +1,98
1 class ContestsController < ApplicationController
1 class ContestsController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 in_place_edit_for :contest, :title
5 in_place_edit_for :contest, :title
6 in_place_edit_for :contest, :enabled
6 in_place_edit_for :contest, :enabled
7
7
8 # GET /contests
8 # GET /contests
9 # GET /contests.xml
9 # GET /contests.xml
10 def index
10 def index
11 @contests = Contest.all
11 @contests = Contest.all
12
12
13 respond_to do |format|
13 respond_to do |format|
14 format.html # index.html.erb
14 format.html # index.html.erb
15 format.xml { render :xml => @contests }
15 format.xml { render :xml => @contests }
16 end
16 end
17 end
17 end
18
18
19 # GET /contests/1
19 # GET /contests/1
20 # GET /contests/1.xml
20 # GET /contests/1.xml
21 def show
21 def show
22 @contest = Contest.find(params[:id])
22 @contest = Contest.find(params[:id])
23
23
24 respond_to do |format|
24 respond_to do |format|
25 format.html # show.html.erb
25 format.html # show.html.erb
26 format.xml { render :xml => @contest }
26 format.xml { render :xml => @contest }
27 end
27 end
28 end
28 end
29
29
30 # GET /contests/new
30 # GET /contests/new
31 # GET /contests/new.xml
31 # GET /contests/new.xml
32 def new
32 def new
33 @contest = Contest.new
33 @contest = Contest.new
34
34
35 respond_to do |format|
35 respond_to do |format|
36 format.html # new.html.erb
36 format.html # new.html.erb
37 format.xml { render :xml => @contest }
37 format.xml { render :xml => @contest }
38 end
38 end
39 end
39 end
40
40
41 # GET /contests/1/edit
41 # GET /contests/1/edit
42 def edit
42 def edit
43 @contest = Contest.find(params[:id])
43 @contest = Contest.find(params[:id])
44 end
44 end
45
45
46 # POST /contests
46 # POST /contests
47 # POST /contests.xml
47 # POST /contests.xml
48 def create
48 def create
49 @contest = Contest.new(params[:contest])
49 @contest = Contest.new(params[:contest])
50
50
51 respond_to do |format|
51 respond_to do |format|
52 if @contest.save
52 if @contest.save
53 flash[:notice] = 'Contest was successfully created.'
53 flash[:notice] = 'Contest was successfully created.'
54 format.html { redirect_to(@contest) }
54 format.html { redirect_to(@contest) }
55 format.xml { render :xml => @contest, :status => :created, :location => @contest }
55 format.xml { render :xml => @contest, :status => :created, :location => @contest }
56 else
56 else
57 format.html { render :action => "new" }
57 format.html { render :action => "new" }
58 format.xml { render :xml => @contest.errors, :status => :unprocessable_entity }
58 format.xml { render :xml => @contest.errors, :status => :unprocessable_entity }
59 end
59 end
60 end
60 end
61 end
61 end
62
62
63 # PUT /contests/1
63 # PUT /contests/1
64 # PUT /contests/1.xml
64 # PUT /contests/1.xml
65 def update
65 def update
66 @contest = Contest.find(params[:id])
66 @contest = Contest.find(params[:id])
67
67
68 respond_to do |format|
68 respond_to do |format|
69 - if @contest.update_attributes(params[:contest])
69 + if @contest.update_attributes(contests_params)
70 flash[:notice] = 'Contest was successfully updated.'
70 flash[:notice] = 'Contest was successfully updated.'
71 format.html { redirect_to(@contest) }
71 format.html { redirect_to(@contest) }
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.xml { render :xml => @contest.errors, :status => :unprocessable_entity }
75 format.xml { render :xml => @contest.errors, :status => :unprocessable_entity }
76 end
76 end
77 end
77 end
78 end
78 end
79
79
80 # DELETE /contests/1
80 # DELETE /contests/1
81 # DELETE /contests/1.xml
81 # DELETE /contests/1.xml
82 def destroy
82 def destroy
83 @contest = Contest.find(params[:id])
83 @contest = Contest.find(params[:id])
84 @contest.destroy
84 @contest.destroy
85
85
86 respond_to do |format|
86 respond_to do |format|
87 format.html { redirect_to(contests_url) }
87 format.html { redirect_to(contests_url) }
88 format.xml { head :ok }
88 format.xml { head :ok }
89 end
89 end
90 end
90 end
91
91
92 + private
93 +
94 + def contests_params
95 + params.require(:contest).permit(:title,:enabled,:name)
92 end
96 end
97 +
98 + end
@@ -1,62 +1,67
1 class SiteController < ApplicationController
1 class SiteController < ApplicationController
2
2
3 before_filter :site_admin_authorization, :except => 'login'
3 before_filter :site_admin_authorization, :except => 'login'
4
4
5 def login
5 def login
6 # Site administrator login
6 # Site administrator login
7 @countries = Country.find(:all, :include => :sites)
7 @countries = Country.find(:all, :include => :sites)
8 @country_select = @countries.collect { |c| [c.name, c.id] }
8 @country_select = @countries.collect { |c| [c.name, c.id] }
9
9
10 @country_select_with_all = [['Any',0]]
10 @country_select_with_all = [['Any',0]]
11 @countries.each do |country|
11 @countries.each do |country|
12 @country_select_with_all << [country.name, country.id]
12 @country_select_with_all << [country.name, country.id]
13 end
13 end
14
14
15 @site_select = []
15 @site_select = []
16 @countries.each do |country|
16 @countries.each do |country|
17 country.sites.each do |site|
17 country.sites.each do |site|
18 @site_select << ["#{site.name}, #{country.name}", site.id]
18 @site_select << ["#{site.name}, #{country.name}", site.id]
19 end
19 end
20 end
20 end
21
21
22 @default_site = Site.first if !GraderConfiguration['contest.multisites']
22 @default_site = Site.first if !GraderConfiguration['contest.multisites']
23
23
24 render :action => 'login', :layout => 'empty'
24 render :action => 'login', :layout => 'empty'
25 end
25 end
26
26
27 def index
27 def index
28 if @site.started
28 if @site.started
29 render :action => 'started', :layout => 'empty'
29 render :action => 'started', :layout => 'empty'
30 else
30 else
31 render :action => 'prompt', :layout => 'empty'
31 render :action => 'prompt', :layout => 'empty'
32 end
32 end
33 end
33 end
34
34
35 def start
35 def start
36 @site.started = true
36 @site.started = true
37 @site.start_time = Time.new.gmtime
37 @site.start_time = Time.new.gmtime
38 @site.save
38 @site.save
39 redirect_to :action => 'index'
39 redirect_to :action => 'index'
40 end
40 end
41
41
42 def logout
42 def logout
43 reset_session
43 reset_session
44 redirect_to :controller => 'main', :action => 'login'
44 redirect_to :controller => 'main', :action => 'login'
45 end
45 end
46
46
47 protected
47 protected
48 def site_admin_authorization
48 def site_admin_authorization
49 if session[:site_id]==nil
49 if session[:site_id]==nil
50 redirect_to :controller => 'site', :action => 'login' and return
50 redirect_to :controller => 'site', :action => 'login' and return
51 end
51 end
52 begin
52 begin
53 @site = Site.find(session[:site_id], :include => :country)
53 @site = Site.find(session[:site_id], :include => :country)
54 rescue ActiveRecord::RecordNotFound
54 rescue ActiveRecord::RecordNotFound
55 @site = nil
55 @site = nil
56 end
56 end
57 if @site==nil
57 if @site==nil
58 redirect_to :controller => 'site', :action => 'login' and return
58 redirect_to :controller => 'site', :action => 'login' and return
59 end
59 end
60 end
60 end
61
61
62 + private
63 + def site_params
64 + params.require(:site).permit()
62 end
65 end
66 +
67 + end
@@ -1,91 +1,97
1 class SitesController < ApplicationController
1 class SitesController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 # GET /sites
5 # GET /sites
6 # GET /sites.xml
6 # GET /sites.xml
7 def index
7 def index
8 @sites = Site.find(:all, :order => 'country_id')
8 @sites = Site.find(:all, :order => 'country_id')
9
9
10 respond_to do |format|
10 respond_to do |format|
11 format.html # index.html.erb
11 format.html # index.html.erb
12 format.xml { render :xml => @sites }
12 format.xml { render :xml => @sites }
13 end
13 end
14 end
14 end
15
15
16 # GET /sites/1
16 # GET /sites/1
17 # GET /sites/1.xml
17 # GET /sites/1.xml
18 def show
18 def show
19 @site = Site.find(params[:id])
19 @site = Site.find(params[:id])
20
20
21 respond_to do |format|
21 respond_to do |format|
22 format.html # show.html.erb
22 format.html # show.html.erb
23 format.xml { render :xml => @site }
23 format.xml { render :xml => @site }
24 end
24 end
25 end
25 end
26
26
27 # GET /sites/new
27 # GET /sites/new
28 # GET /sites/new.xml
28 # GET /sites/new.xml
29 def new
29 def new
30 @site = Site.new
30 @site = Site.new
31
31
32 respond_to do |format|
32 respond_to do |format|
33 format.html # new.html.erb
33 format.html # new.html.erb
34 format.xml { render :xml => @site }
34 format.xml { render :xml => @site }
35 end
35 end
36 end
36 end
37
37
38 # GET /sites/1/edit
38 # GET /sites/1/edit
39 def edit
39 def edit
40 @site = Site.find(params[:id])
40 @site = Site.find(params[:id])
41 end
41 end
42
42
43 # POST /sites
43 # POST /sites
44 # POST /sites.xml
44 # POST /sites.xml
45 def create
45 def create
46 @site = Site.new(params[:site])
46 @site = Site.new(params[:site])
47 @site.clear_start_time_if_not_started
47 @site.clear_start_time_if_not_started
48
48
49 respond_to do |format|
49 respond_to do |format|
50 if @site.save
50 if @site.save
51 flash[:notice] = 'Site was successfully created.'
51 flash[:notice] = 'Site was successfully created.'
52 format.html { redirect_to(@site) }
52 format.html { redirect_to(@site) }
53 format.xml { render :xml => @site, :status => :created, :location => @site }
53 format.xml { render :xml => @site, :status => :created, :location => @site }
54 else
54 else
55 format.html { render :action => "new" }
55 format.html { render :action => "new" }
56 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
56 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
57 end
57 end
58 end
58 end
59 end
59 end
60
60
61 # PUT /sites/1
61 # PUT /sites/1
62 # PUT /sites/1.xml
62 # PUT /sites/1.xml
63 def update
63 def update
64 @site = Site.find(params[:id])
64 @site = Site.find(params[:id])
65 @site.clear_start_time_if_not_started
65 @site.clear_start_time_if_not_started
66
66
67 respond_to do |format|
67 respond_to do |format|
68 - if @site.update_attributes(params[:site])
68 + if @site.update_attributes(site_params)
69 flash[:notice] = 'Site was successfully updated.'
69 flash[:notice] = 'Site was successfully updated.'
70 format.html { redirect_to(@site) }
70 format.html { redirect_to(@site) }
71 format.xml { head :ok }
71 format.xml { head :ok }
72 else
72 else
73 format.html { render :action => "edit" }
73 format.html { render :action => "edit" }
74 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
74 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
75 end
75 end
76 end
76 end
77 end
77 end
78
78
79 # DELETE /sites/1
79 # DELETE /sites/1
80 # DELETE /sites/1.xml
80 # DELETE /sites/1.xml
81 def destroy
81 def destroy
82 @site = Site.find(params[:id])
82 @site = Site.find(params[:id])
83 @site.destroy
83 @site.destroy
84
84
85 respond_to do |format|
85 respond_to do |format|
86 format.html { redirect_to(sites_url) }
86 format.html { redirect_to(sites_url) }
87 format.xml { head :ok }
87 format.xml { head :ok }
88 end
88 end
89 end
89 end
90
90
91 + private
92 +
93 + def site_params
94 + params.require(:site).permit(:name,:started,:start_time,:country_id,:password)
91 end
95 end
96 +
97 + end
@@ -1,137 +1,83
1 class SubmissionsController < ApplicationController
1 class SubmissionsController < ApplicationController
2 before_filter :authenticate
2 before_filter :authenticate
3 before_filter :submission_authorization, only: [:show, :direct_edit_submission]
3 before_filter :submission_authorization, only: [:show, :direct_edit_submission]
4
4
5 # GET /submissions
5 # GET /submissions
6 # GET /submissions.json
6 # GET /submissions.json
7 # Show problem selection and user's submission of that problem
7 # Show problem selection and user's submission of that problem
8 def index
8 def index
9 @user = @current_user
9 @user = @current_user
10 @problems = @user.available_problems
10 @problems = @user.available_problems
11
11
12 if params[:problem_id]==nil
12 if params[:problem_id]==nil
13 @problem = nil
13 @problem = nil
14 @submissions = nil
14 @submissions = nil
15 else
15 else
16 @problem = Problem.find_by_id(params[:problem_id])
16 @problem = Problem.find_by_id(params[:problem_id])
17 if (@problem == nil) or (not @problem.available)
17 if (@problem == nil) or (not @problem.available)
18 redirect_to main_list_path
18 redirect_to main_list_path
19 flash[:notice] = 'Error: submissions for that problem are not viewable.'
19 flash[:notice] = 'Error: submissions for that problem are not viewable.'
20 return
20 return
21 end
21 end
22 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
22 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
23 end
23 end
24 end
24 end
25
25
26 # GET /submissions/1
26 # GET /submissions/1
27 # GET /submissions/1.json
27 # GET /submissions/1.json
28 def show
28 def show
29 @submission = Submission.find(params[:id])
29 @submission = Submission.find(params[:id])
30
30
31 #log the viewing
31 #log the viewing
32 user = User.find(session[:user_id])
32 user = User.find(session[:user_id])
33 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
33 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
34 end
34 end
35
35
36 #on-site new submission on specific problem
36 #on-site new submission on specific problem
37 def direct_edit_problem
37 def direct_edit_problem
38 @problem = Problem.find(params[:problem_id])
38 @problem = Problem.find(params[:problem_id])
39 @source = ''
39 @source = ''
40 render 'edit'
40 render 'edit'
41 end
41 end
42
42
43 # GET /submissions/1/edit
43 # GET /submissions/1/edit
44 def edit
44 def edit
45 @submission = Submission.find(params[:id])
45 @submission = Submission.find(params[:id])
46 @source = @submission.source.to_s
46 @source = @submission.source.to_s
47 @problem = @submission.problem
47 @problem = @submission.problem
48 @lang_id = @submission.language.id
48 @lang_id = @submission.language.id
49 end
49 end
50
50
51
51
52 def get_latest_submission_status
52 def get_latest_submission_status
53 @problem = Problem.find(params[:pid])
53 @problem = Problem.find(params[:pid])
54 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
54 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
55 puts User.find(params[:uid]).login
55 puts User.find(params[:uid]).login
56 puts Problem.find(params[:pid]).name
56 puts Problem.find(params[:pid]).name
57 puts 'nil' unless @submission
57 puts 'nil' unless @submission
58 respond_to do |format|
58 respond_to do |format|
59 format.js
59 format.js
60 end
60 end
61 end
61 end
62
62
63 - # # GET /submissions/new
64 - # # GET /submissions/new.json
65 - # def new
66 - # @submission = Submission.new
67 - #
68 - # respond_to do |format|
69 - # format.html # new.html.erb
70 - # format.json { render json: @submission }
71 - # end
72 - # end
73 - #
74 - #
75 - # # POST /submissions
76 - # # POST /submissions.json
77 - # def create
78 - # @submission = Submission.new(params[:submission])
79 - #
80 - # respond_to do |format|
81 - # if @submission.save
82 - # format.html { redirect_to @submission, notice: 'Submission was successfully created.' }
83 - # format.json { render json: @submission, status: :created, location: @submission }
84 - # else
85 - # format.html { render action: "new" }
86 - # format.json { render json: @submission.errors, status: :unprocessable_entity }
87 - # end
88 - # end
89 - # end
90 - #
91 - # # PUT /submissions/1
92 - # # PUT /submissions/1.json
93 - # def update
94 - # @submission = Submission.find(params[:id])
95 - #
96 - # respond_to do |format|
97 - # if @submission.update_attributes(params[:submission])
98 - # format.html { redirect_to @submission, notice: 'Submission was successfully updated.' }
99 - # format.json { head :no_content }
100 - # else
101 - # format.html { render action: "edit" }
102 - # format.json { render json: @submission.errors, status: :unprocessable_entity }
103 - # end
104 - # end
105 - # end
106 - #
107 - # # DELETE /submissions/1
108 - # # DELETE /submissions/1.json
109 - # def destroy
110 - # @submission = Submission.find(params[:id])
111 - # @submission.destroy
112 - #
113 - # respond_to do |format|
114 - # format.html { redirect_to submissions_url }
115 - # format.json { head :no_content }
116 - # end
117 - # end
118
63
119 protected
64 protected
120 def submission_authorization
65 def submission_authorization
121 #admin always has privileged
66 #admin always has privileged
122 if @current_user.admin?
67 if @current_user.admin?
123 return true
68 return true
124 end
69 end
125
70
126 sub = Submission.find(params[:id])
71 sub = Submission.find(params[:id])
127 if sub.problem.available?
72 if sub.problem.available?
128 puts "sub = #{sub.user.id}, current = #{@current_user.id}"
73 puts "sub = #{sub.user.id}, current = #{@current_user.id}"
129 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
74 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
130 end
75 end
131
76
132 #default to NO
77 #default to NO
133 unauthorized_redirect
78 unauthorized_redirect
134 return false
79 return false
135 end
80 end
136
81
82 +
137 end
83 end
@@ -1,313 +1,313
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.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
32 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["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(params[:user])
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
77
78 added_random_password = false
78 added_random_password = false
79 if items.length>=3
79 if items.length>=3
80 password = items[2].chomp(" ")
80 password = items[2].chomp(" ")
81 user_alias = (items.length>=4) ? items[3] : login
81 user_alias = (items.length>=4) ? items[3] : login
82 else
82 else
83 password = random_password
83 password = random_password
84 user_alias = (items.length>=4) ? items[3] : login
84 user_alias = (items.length>=4) ? items[3] : login
85 added_random_password = true
85 added_random_password = true
86 end
86 end
87
87
88 user = User.find_by_login(login)
88 user = User.find_by_login(login)
89 if (user)
89 if (user)
90 user.full_name = full_name
90 user.full_name = full_name
91 user.password = password
91 user.password = password
92 else
92 else
93 user = User.new({:login => login,
93 user = User.new({:login => login,
94 :full_name => full_name,
94 :full_name => full_name,
95 :password => password,
95 :password => password,
96 :password_confirmation => password,
96 :password_confirmation => password,
97 :alias => user_alias})
97 :alias => user_alias})
98 end
98 end
99 user.activated = true
99 user.activated = true
100 user.save
100 user.save
101
101
102 if added_random_password
102 if added_random_password
103 note << "'#{login}' (+)"
103 note << "'#{login}' (+)"
104 else
104 else
105 note << login
105 note << login
106 end
106 end
107 end
107 end
108 end
108 end
109 flash[:notice] = 'User(s) ' + note.join(', ') +
109 flash[:notice] = 'User(s) ' + note.join(', ') +
110 ' were successfully created. ' +
110 ' were successfully created. ' +
111 '( (+) - created with random passwords.)'
111 '( (+) - created with random passwords.)'
112 redirect_to :action => 'index'
112 redirect_to :action => 'index'
113 end
113 end
114
114
115 def edit
115 def edit
116 @user = User.find(params[:id])
116 @user = User.find(params[:id])
117 end
117 end
118
118
119 def update
119 def update
120 @user = User.find(params[:id])
120 @user = User.find(params[:id])
121 - if @user.update_attributes(params[:user])
121 + if @user.update_attributes(user_params)
122 flash[:notice] = 'User was successfully updated.'
122 flash[:notice] = 'User was successfully updated.'
123 redirect_to :action => 'show', :id => @user
123 redirect_to :action => 'show', :id => @user
124 else
124 else
125 render :action => 'edit'
125 render :action => 'edit'
126 end
126 end
127 end
127 end
128
128
129 def destroy
129 def destroy
130 User.find(params[:id]).destroy
130 User.find(params[:id]).destroy
131 redirect_to :action => 'index'
131 redirect_to :action => 'index'
132 end
132 end
133
133
134 def user_stat
134 def user_stat
135 if params[:commit] == 'download csv'
135 if params[:commit] == 'download csv'
136 @problems = Problem.all
136 @problems = Problem.all
137 else
137 else
138 @problems = Problem.find_available_problems
138 @problems = Problem.find_available_problems
139 end
139 end
140 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
140 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
141 @scorearray = Array.new
141 @scorearray = Array.new
142 @users.each do |u|
142 @users.each do |u|
143 ustat = Array.new
143 ustat = Array.new
144 ustat[0] = u
144 ustat[0] = u
145 @problems.each do |p|
145 @problems.each do |p|
146 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
146 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
147 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
147 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
148 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
148 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
149 else
149 else
150 ustat << [0,false]
150 ustat << [0,false]
151 end
151 end
152 end
152 end
153 @scorearray << ustat
153 @scorearray << ustat
154 end
154 end
155 if params[:commit] == 'download csv' then
155 if params[:commit] == 'download csv' then
156 csv = gen_csv_from_scorearray(@scorearray,@problems)
156 csv = gen_csv_from_scorearray(@scorearray,@problems)
157 send_data csv, filename: 'last_score.csv'
157 send_data csv, filename: 'last_score.csv'
158 else
158 else
159 render template: 'user_admin/user_stat'
159 render template: 'user_admin/user_stat'
160 end
160 end
161 end
161 end
162
162
163 def user_stat_max
163 def user_stat_max
164 if params[:commit] == 'download csv'
164 if params[:commit] == 'download csv'
165 @problems = Problem.all
165 @problems = Problem.all
166 else
166 else
167 @problems = Problem.find_available_problems
167 @problems = Problem.find_available_problems
168 end
168 end
169 @users = User.find(:all, :include => [:contests, :contest_stat])
169 @users = User.find(:all, :include => [:contests, :contest_stat])
170 @scorearray = Array.new
170 @scorearray = Array.new
171 #set up range from param
171 #set up range from param
172 since_id = params.fetch(:since_id, 0).to_i
172 since_id = params.fetch(:since_id, 0).to_i
173 until_id = params.fetch(:until_id, 0).to_i
173 until_id = params.fetch(:until_id, 0).to_i
174 @users.each do |u|
174 @users.each do |u|
175 ustat = Array.new
175 ustat = Array.new
176 ustat[0] = u
176 ustat[0] = u
177 @problems.each do |p|
177 @problems.each do |p|
178 max_points = 0
178 max_points = 0
179 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
179 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
180 max_points = sub.points if sub and sub.points and (sub.points > max_points)
180 max_points = sub.points if sub and sub.points and (sub.points > max_points)
181 end
181 end
182 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
182 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
183 end
183 end
184 @scorearray << ustat
184 @scorearray << ustat
185 end
185 end
186
186
187 if params[:commit] == 'download csv' then
187 if params[:commit] == 'download csv' then
188 csv = gen_csv_from_scorearray(@scorearray,@problems)
188 csv = gen_csv_from_scorearray(@scorearray,@problems)
189 send_data csv, filename: 'max_score.csv'
189 send_data csv, filename: 'max_score.csv'
190 else
190 else
191 render template: 'user_admin/user_stat'
191 render template: 'user_admin/user_stat'
192 end
192 end
193 end
193 end
194
194
195 def import
195 def import
196 if params[:file]==''
196 if params[:file]==''
197 flash[:notice] = 'Error importing no file'
197 flash[:notice] = 'Error importing no file'
198 redirect_to :action => 'index' and return
198 redirect_to :action => 'index' and return
199 end
199 end
200 import_from_file(params[:file])
200 import_from_file(params[:file])
201 end
201 end
202
202
203 def random_all_passwords
203 def random_all_passwords
204 users = User.find(:all)
204 users = User.find(:all)
205 @prefix = params[:prefix] || ''
205 @prefix = params[:prefix] || ''
206 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
206 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
207 @changed = false
207 @changed = false
208 if request.request_method == 'POST'
208 if request.request_method == 'POST'
209 @non_admin_users.each do |user|
209 @non_admin_users.each do |user|
210 password = random_password
210 password = random_password
211 user.password = password
211 user.password = password
212 user.password_confirmation = password
212 user.password_confirmation = password
213 user.save
213 user.save
214 end
214 end
215 @changed = true
215 @changed = true
216 end
216 end
217 end
217 end
218
218
219 # contest management
219 # contest management
220
220
221 def contests
221 def contests
222 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
222 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
223 @contests = Contest.enabled
223 @contests = Contest.enabled
224 end
224 end
225
225
226 def assign_from_list
226 def assign_from_list
227 contest_id = params[:users_contest_id]
227 contest_id = params[:users_contest_id]
228 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
228 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
229 contest = Contest.find(params[:new_contest][:id])
229 contest = Contest.find(params[:new_contest][:id])
230 if !contest
230 if !contest
231 flash[:notice] = 'Error: no contest'
231 flash[:notice] = 'Error: no contest'
232 redirect_to :action => 'contests', :id =>contest_id
232 redirect_to :action => 'contests', :id =>contest_id
233 end
233 end
234
234
235 note = []
235 note = []
236 users.each do |u|
236 users.each do |u|
237 u.contests = [contest]
237 u.contests = [contest]
238 note << u.login
238 note << u.login
239 end
239 end
240 flash[:notice] = 'User(s) ' + note.join(', ') +
240 flash[:notice] = 'User(s) ' + note.join(', ') +
241 " were successfully reassigned to #{contest.title}."
241 " were successfully reassigned to #{contest.title}."
242 redirect_to :action => 'contests', :id =>contest.id
242 redirect_to :action => 'contests', :id =>contest.id
243 end
243 end
244
244
245 def add_to_contest
245 def add_to_contest
246 user = User.find(params[:id])
246 user = User.find(params[:id])
247 contest = Contest.find(params[:contest_id])
247 contest = Contest.find(params[:contest_id])
248 if user and contest
248 if user and contest
249 user.contests << contest
249 user.contests << contest
250 end
250 end
251 redirect_to :action => 'index'
251 redirect_to :action => 'index'
252 end
252 end
253
253
254 def remove_from_contest
254 def remove_from_contest
255 user = User.find(params[:id])
255 user = User.find(params[:id])
256 contest = Contest.find(params[:contest_id])
256 contest = Contest.find(params[:contest_id])
257 if user and contest
257 if user and contest
258 user.contests.delete(contest)
258 user.contests.delete(contest)
259 end
259 end
260 redirect_to :action => 'index'
260 redirect_to :action => 'index'
261 end
261 end
262
262
263 def contest_management
263 def contest_management
264 end
264 end
265
265
266 def manage_contest
266 def manage_contest
267 contest = Contest.find(params[:contest][:id])
267 contest = Contest.find(params[:contest][:id])
268 if !contest
268 if !contest
269 flash[:notice] = 'You did not choose the contest.'
269 flash[:notice] = 'You did not choose the contest.'
270 redirect_to :action => 'contest_management' and return
270 redirect_to :action => 'contest_management' and return
271 end
271 end
272
272
273 operation = params[:operation]
273 operation = params[:operation]
274
274
275 if not ['add','remove','assign'].include? operation
275 if not ['add','remove','assign'].include? operation
276 flash[:notice] = 'You did not choose the operation to perform.'
276 flash[:notice] = 'You did not choose the operation to perform.'
277 redirect_to :action => 'contest_management' and return
277 redirect_to :action => 'contest_management' and return
278 end
278 end
279
279
280 lines = params[:login_list]
280 lines = params[:login_list]
281 if !lines or lines.blank?
281 if !lines or lines.blank?
282 flash[:notice] = 'You entered an empty list.'
282 flash[:notice] = 'You entered an empty list.'
283 redirect_to :action => 'contest_management' and return
283 redirect_to :action => 'contest_management' and return
284 end
284 end
285
285
286 note = []
286 note = []
287 users = []
287 users = []
288 lines.split("\n").each do |line|
288 lines.split("\n").each do |line|
289 user = User.find_by_login(line.chomp)
289 user = User.find_by_login(line.chomp)
290 if user
290 if user
291 if operation=='add'
291 if operation=='add'
292 if ! user.contests.include? contest
292 if ! user.contests.include? contest
293 user.contests << contest
293 user.contests << contest
294 end
294 end
295 elsif operation=='remove'
295 elsif operation=='remove'
296 user.contests.delete(contest)
296 user.contests.delete(contest)
297 else
297 else
298 user.contests = [contest]
298 user.contests = [contest]
299 end
299 end
300
300
301 if params[:reset_timer]
301 if params[:reset_timer]
302 user.contest_stat.forced_logout = true
302 user.contest_stat.forced_logout = true
303 user.contest_stat.reset_timer_and_save
303 user.contest_stat.reset_timer_and_save
304 end
304 end
305
305
306 if params[:notification_emails]
306 if params[:notification_emails]
307 send_contest_update_notification_email(user, contest)
307 send_contest_update_notification_email(user, contest)
308 end
308 end
309
309
310 note << user.login
310 note << user.login
311 users << user
311 users << user
312 end
312 end
313 end
313 end
@@ -346,193 +346,198
346 flash[:notice] = 'Unknown user'
346 flash[:notice] = 'Unknown user'
347 redirect_to :action => 'admin' and return
347 redirect_to :action => 'admin' and return
348 elsif user.login == 'root'
348 elsif user.login == 'root'
349 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
349 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
350 redirect_to :action => 'admin' and return
350 redirect_to :action => 'admin' and return
351 end
351 end
352
352
353 admin_role = Role.find_by_name('admin')
353 admin_role = Role.find_by_name('admin')
354 user.roles.delete(admin_role)
354 user.roles.delete(admin_role)
355 flash[:notice] = 'User permission revoked'
355 flash[:notice] = 'User permission revoked'
356 redirect_to :action => 'admin'
356 redirect_to :action => 'admin'
357 end
357 end
358
358
359 # mass mailing
359 # mass mailing
360
360
361 def mass_mailing
361 def mass_mailing
362 end
362 end
363
363
364 def bulk_mail
364 def bulk_mail
365 lines = params[:login_list]
365 lines = params[:login_list]
366 if !lines or lines.blank?
366 if !lines or lines.blank?
367 flash[:notice] = 'You entered an empty list.'
367 flash[:notice] = 'You entered an empty list.'
368 redirect_to :action => 'mass_mailing' and return
368 redirect_to :action => 'mass_mailing' and return
369 end
369 end
370
370
371 mail_subject = params[:subject]
371 mail_subject = params[:subject]
372 if !mail_subject or mail_subject.blank?
372 if !mail_subject or mail_subject.blank?
373 flash[:notice] = 'You entered an empty mail subject.'
373 flash[:notice] = 'You entered an empty mail subject.'
374 redirect_to :action => 'mass_mailing' and return
374 redirect_to :action => 'mass_mailing' and return
375 end
375 end
376
376
377 mail_body = params[:email_body]
377 mail_body = params[:email_body]
378 if !mail_body or mail_body.blank?
378 if !mail_body or mail_body.blank?
379 flash[:notice] = 'You entered an empty mail body.'
379 flash[:notice] = 'You entered an empty mail body.'
380 redirect_to :action => 'mass_mailing' and return
380 redirect_to :action => 'mass_mailing' and return
381 end
381 end
382
382
383 note = []
383 note = []
384 users = []
384 users = []
385 lines.split("\n").each do |line|
385 lines.split("\n").each do |line|
386 user = User.find_by_login(line.chomp)
386 user = User.find_by_login(line.chomp)
387 if user
387 if user
388 send_mail(user.email, mail_subject, mail_body)
388 send_mail(user.email, mail_subject, mail_body)
389 note << user.login
389 note << user.login
390 end
390 end
391 end
391 end
392
392
393 flash[:notice] = 'User(s) ' + note.join(', ') +
393 flash[:notice] = 'User(s) ' + note.join(', ') +
394 ' were successfully modified. '
394 ' were successfully modified. '
395 redirect_to :action => 'mass_mailing'
395 redirect_to :action => 'mass_mailing'
396 end
396 end
397
397
398 protected
398 protected
399
399
400 def random_password(length=5)
400 def random_password(length=5)
401 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
401 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
402 newpass = ""
402 newpass = ""
403 length.times { newpass << chars[rand(chars.size-1)] }
403 length.times { newpass << chars[rand(chars.size-1)] }
404 return newpass
404 return newpass
405 end
405 end
406
406
407 def import_from_file(f)
407 def import_from_file(f)
408 data_hash = YAML.load(f)
408 data_hash = YAML.load(f)
409 @import_log = ""
409 @import_log = ""
410
410
411 country_data = data_hash[:countries]
411 country_data = data_hash[:countries]
412 site_data = data_hash[:sites]
412 site_data = data_hash[:sites]
413 user_data = data_hash[:users]
413 user_data = data_hash[:users]
414
414
415 # import country
415 # import country
416 countries = {}
416 countries = {}
417 country_data.each_pair do |id,country|
417 country_data.each_pair do |id,country|
418 c = Country.find_by_name(country[:name])
418 c = Country.find_by_name(country[:name])
419 if c!=nil
419 if c!=nil
420 countries[id] = c
420 countries[id] = c
421 @import_log << "Found #{country[:name]}\n"
421 @import_log << "Found #{country[:name]}\n"
422 else
422 else
423 countries[id] = Country.new(:name => country[:name])
423 countries[id] = Country.new(:name => country[:name])
424 countries[id].save
424 countries[id].save
425 @import_log << "Created #{country[:name]}\n"
425 @import_log << "Created #{country[:name]}\n"
426 end
426 end
427 end
427 end
428
428
429 # import sites
429 # import sites
430 sites = {}
430 sites = {}
431 site_data.each_pair do |id,site|
431 site_data.each_pair do |id,site|
432 s = Site.find_by_name(site[:name])
432 s = Site.find_by_name(site[:name])
433 if s!=nil
433 if s!=nil
434 @import_log << "Found #{site[:name]}\n"
434 @import_log << "Found #{site[:name]}\n"
435 else
435 else
436 s = Site.new(:name => site[:name])
436 s = Site.new(:name => site[:name])
437 @import_log << "Created #{site[:name]}\n"
437 @import_log << "Created #{site[:name]}\n"
438 end
438 end
439 s.password = site[:password]
439 s.password = site[:password]
440 s.country = countries[site[:country_id]]
440 s.country = countries[site[:country_id]]
441 s.save
441 s.save
442 sites[id] = s
442 sites[id] = s
443 end
443 end
444
444
445 # import users
445 # import users
446 user_data.each_pair do |id,user|
446 user_data.each_pair do |id,user|
447 u = User.find_by_login(user[:login])
447 u = User.find_by_login(user[:login])
448 if u!=nil
448 if u!=nil
449 @import_log << "Found #{user[:login]}\n"
449 @import_log << "Found #{user[:login]}\n"
450 else
450 else
451 u = User.new(:login => user[:login])
451 u = User.new(:login => user[:login])
452 @import_log << "Created #{user[:login]}\n"
452 @import_log << "Created #{user[:login]}\n"
453 end
453 end
454 u.full_name = user[:name]
454 u.full_name = user[:name]
455 u.password = user[:password]
455 u.password = user[:password]
456 u.country = countries[user[:country_id]]
456 u.country = countries[user[:country_id]]
457 u.site = sites[user[:site_id]]
457 u.site = sites[user[:site_id]]
458 u.activated = true
458 u.activated = true
459 u.email = "empty-#{u.login}@none.com"
459 u.email = "empty-#{u.login}@none.com"
460 if not u.save
460 if not u.save
461 @import_log << "Errors\n"
461 @import_log << "Errors\n"
462 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
462 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
463 end
463 end
464 end
464 end
465
465
466 end
466 end
467
467
468 def logout_users(users)
468 def logout_users(users)
469 users.each do |user|
469 users.each do |user|
470 contest_stat = user.contest_stat(true)
470 contest_stat = user.contest_stat(true)
471 if contest_stat and !contest_stat.forced_logout
471 if contest_stat and !contest_stat.forced_logout
472 contest_stat.forced_logout = true
472 contest_stat.forced_logout = true
473 contest_stat.save
473 contest_stat.save
474 end
474 end
475 end
475 end
476 end
476 end
477
477
478 def send_contest_update_notification_email(user, contest)
478 def send_contest_update_notification_email(user, contest)
479 contest_title_name = GraderConfiguration['contest.name']
479 contest_title_name = GraderConfiguration['contest.name']
480 contest_name = contest.name
480 contest_name = contest.name
481 mail_subject = t('contest.notification.email_subject', {
481 mail_subject = t('contest.notification.email_subject', {
482 :contest_title_name => contest_title_name,
482 :contest_title_name => contest_title_name,
483 :contest_name => contest_name })
483 :contest_name => contest_name })
484 mail_body = t('contest.notification.email_body', {
484 mail_body = t('contest.notification.email_body', {
485 :full_name => user.full_name,
485 :full_name => user.full_name,
486 :contest_title_name => contest_title_name,
486 :contest_title_name => contest_title_name,
487 :contest_name => contest.name,
487 :contest_name => contest.name,
488 })
488 })
489
489
490 logger.info mail_body
490 logger.info mail_body
491 send_mail(user.email, mail_subject, mail_body)
491 send_mail(user.email, mail_subject, mail_body)
492 end
492 end
493
493
494 def find_contest_and_user_from_contest_id(id)
494 def find_contest_and_user_from_contest_id(id)
495 if id!='none'
495 if id!='none'
496 @contest = Contest.find(id)
496 @contest = Contest.find(id)
497 else
497 else
498 @contest = nil
498 @contest = nil
499 end
499 end
500 if @contest
500 if @contest
501 @users = @contest.users
501 @users = @contest.users
502 else
502 else
503 @users = User.find_users_with_no_contest
503 @users = User.find_users_with_no_contest
504 end
504 end
505 return [@contest, @users]
505 return [@contest, @users]
506 end
506 end
507
507
508 def gen_csv_from_scorearray(scorearray,problem)
508 def gen_csv_from_scorearray(scorearray,problem)
509 CSV.generate do |csv|
509 CSV.generate do |csv|
510 #add header
510 #add header
511 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
511 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
512 problem.each { |p| header << p.name }
512 problem.each { |p| header << p.name }
513 header += ['Total','Passed']
513 header += ['Total','Passed']
514 csv << header
514 csv << header
515 #add data
515 #add data
516 scorearray.each do |sc|
516 scorearray.each do |sc|
517 total = num_passed = 0
517 total = num_passed = 0
518 row = Array.new
518 row = Array.new
519 sc.each_index do |i|
519 sc.each_index do |i|
520 if i == 0
520 if i == 0
521 row << sc[i].login
521 row << sc[i].login
522 row << sc[i].full_name
522 row << sc[i].full_name
523 row << sc[i].activated
523 row << sc[i].activated
524 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
524 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
525 row << sc[i].contests.collect {|c| c.name}.join(', ')
525 row << sc[i].contests.collect {|c| c.name}.join(', ')
526 else
526 else
527 row << sc[i][0]
527 row << sc[i][0]
528 total += sc[i][0]
528 total += sc[i][0]
529 num_passed += 1 if sc[i][1]
529 num_passed += 1 if sc[i][1]
530 end
530 end
531 end
531 end
532 row << total
532 row << total
533 row << num_passed
533 row << num_passed
534 csv << row
534 csv << row
535 end
535 end
536 end
536 end
537 end
537 end
538 +
539 + private
540 + def user_params
541 + params.require(:user).permit(:login,:full_name,:hashed_password,:salt,:alias,:email,:site_id,:country_id,:activated,:enabled,:remark,:last_ip,:section)
538 end
542 end
543 + end
@@ -1,226 +1,226
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_many :test_requests, :order => "submitted_at DESC"
11 has_many :test_requests, :order => "submitted_at DESC"
12
12
13 has_many :messages,
13 has_many :messages,
14 :class_name => "Message",
14 :class_name => "Message",
15 :foreign_key => "sender_id",
15 :foreign_key => "sender_id",
16 :order => 'created_at DESC'
16 :order => 'created_at DESC'
17
17
18 has_many :replied_messages,
18 has_many :replied_messages,
19 :class_name => "Message",
19 :class_name => "Message",
20 :foreign_key => "receiver_id",
20 :foreign_key => "receiver_id",
21 :order => 'created_at DESC'
21 :order => 'created_at DESC'
22
22
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24
24
25 belongs_to :site
25 belongs_to :site
26 belongs_to :country
26 belongs_to :country
27
27
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
29
29
30 scope :activated_users, :conditions => {:activated => true}
30 scope :activated_users, :conditions => {:activated => true}
31
31
32 validates_presence_of :login
32 validates_presence_of :login
33 validates_uniqueness_of :login
33 validates_uniqueness_of :login
34 - validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
34 + validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
35 validates_length_of :login, :within => 3..30
35 validates_length_of :login, :within => 3..30
36
36
37 validates_presence_of :full_name
37 validates_presence_of :full_name
38 validates_length_of :full_name, :minimum => 1
38 validates_length_of :full_name, :minimum => 1
39
39
40 validates_presence_of :password, :if => :password_required?
40 validates_presence_of :password, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
43
43
44 validates_format_of :email,
44 validates_format_of :email,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
46 :if => :email_validation?
46 :if => :email_validation?
47 validate :uniqueness_of_email_from_activated_users,
47 validate :uniqueness_of_email_from_activated_users,
48 :if => :email_validation?
48 :if => :email_validation?
49 validate :enough_time_interval_between_same_email_registrations,
49 validate :enough_time_interval_between_same_email_registrations,
50 :if => :email_validation?
50 :if => :email_validation?
51
51
52 # these are for ytopc
52 # these are for ytopc
53 # disable for now
53 # disable for now
54 #validates_presence_of :province
54 #validates_presence_of :province
55
55
56 attr_accessor :password
56 attr_accessor :password
57
57
58 before_save :encrypt_new_password
58 before_save :encrypt_new_password
59 before_save :assign_default_site
59 before_save :assign_default_site
60 before_save :assign_default_contest
60 before_save :assign_default_contest
61
61
62 # this is for will_paginate
62 # this is for will_paginate
63 cattr_reader :per_page
63 cattr_reader :per_page
64 @@per_page = 50
64 @@per_page = 50
65
65
66 def self.authenticate(login, password)
66 def self.authenticate(login, password)
67 user = find_by_login(login)
67 user = find_by_login(login)
68 if user
68 if user
69 return user if user.authenticated?(password)
69 return user if user.authenticated?(password)
70 if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
70 if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
71 user.password = password
71 user.password = password
72 user.save
72 user.save
73 return user
73 return user
74 end
74 end
75 end
75 end
76 end
76 end
77
77
78 def authenticated?(password)
78 def authenticated?(password)
79 if self.activated
79 if self.activated
80 hashed_password == User.encrypt(password,self.salt)
80 hashed_password == User.encrypt(password,self.salt)
81 else
81 else
82 false
82 false
83 end
83 end
84 end
84 end
85
85
86 def authenticated_by_pop3?(password)
86 def authenticated_by_pop3?(password)
87 Net::POP3.enable_ssl
87 Net::POP3.enable_ssl
88 pop = Net::POP3.new('pops.it.chula.ac.th')
88 pop = Net::POP3.new('pops.it.chula.ac.th')
89 authen = true
89 authen = true
90 begin
90 begin
91 pop.start(login, password)
91 pop.start(login, password)
92 pop.finish
92 pop.finish
93 return true
93 return true
94 rescue
94 rescue
95 return false
95 return false
96 end
96 end
97 end
97 end
98
98
99 def authenticated_by_cucas?(password)
99 def authenticated_by_cucas?(password)
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
103 post_args = {
103 post_args = {
104 'appid' => appid,
104 'appid' => appid,
105 'appsecret' => appsecret,
105 'appsecret' => appsecret,
106 'username' => login,
106 'username' => login,
107 'password' => password
107 'password' => password
108 }
108 }
109
109
110 #simple call
110 #simple call
111 begin
111 begin
112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
113 http.use_ssl = true
113 http.use_ssl = true
114 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
114 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
115 result = [ ]
115 result = [ ]
116 http.start do |http|
116 http.start do |http|
117 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
117 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
118 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
118 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
119 resp = http.request(req,param)
119 resp = http.request(req,param)
120 result = JSON.parse resp.body
120 result = JSON.parse resp.body
121 end
121 end
122 return true if result["type"] == "beanStudent"
122 return true if result["type"] == "beanStudent"
123 rescue => e
123 rescue => e
124 return false
124 return false
125 end
125 end
126 return false
126 return false
127 end
127 end
128
128
129 def admin?
129 def admin?
130 self.roles.detect {|r| r.name == 'admin' }
130 self.roles.detect {|r| r.name == 'admin' }
131 end
131 end
132
132
133 def email_for_editing
133 def email_for_editing
134 if self.email==nil
134 if self.email==nil
135 "(unknown)"
135 "(unknown)"
136 elsif self.email==''
136 elsif self.email==''
137 "(blank)"
137 "(blank)"
138 else
138 else
139 self.email
139 self.email
140 end
140 end
141 end
141 end
142
142
143 def email_for_editing=(e)
143 def email_for_editing=(e)
144 self.email=e
144 self.email=e
145 end
145 end
146
146
147 def alias_for_editing
147 def alias_for_editing
148 if self.alias==nil
148 if self.alias==nil
149 "(unknown)"
149 "(unknown)"
150 elsif self.alias==''
150 elsif self.alias==''
151 "(blank)"
151 "(blank)"
152 else
152 else
153 self.alias
153 self.alias
154 end
154 end
155 end
155 end
156
156
157 def alias_for_editing=(e)
157 def alias_for_editing=(e)
158 self.alias=e
158 self.alias=e
159 end
159 end
160
160
161 def activation_key
161 def activation_key
162 if self.hashed_password==nil
162 if self.hashed_password==nil
163 encrypt_new_password
163 encrypt_new_password
164 end
164 end
165 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
165 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
166 end
166 end
167
167
168 def verify_activation_key(key)
168 def verify_activation_key(key)
169 key == activation_key
169 key == activation_key
170 end
170 end
171
171
172 def self.random_password(length=5)
172 def self.random_password(length=5)
173 chars = 'abcdefghjkmnopqrstuvwxyz'
173 chars = 'abcdefghjkmnopqrstuvwxyz'
174 password = ''
174 password = ''
175 length.times { password << chars[rand(chars.length - 1)] }
175 length.times { password << chars[rand(chars.length - 1)] }
176 password
176 password
177 end
177 end
178
178
179 def self.find_non_admin_with_prefix(prefix='')
179 def self.find_non_admin_with_prefix(prefix='')
180 users = User.find(:all)
180 users = User.find(:all)
181 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
181 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
182 end
182 end
183
183
184 # Contest information
184 # Contest information
185
185
186 def self.find_users_with_no_contest()
186 def self.find_users_with_no_contest()
187 users = User.find(:all)
187 users = User.find(:all)
188 return users.find_all { |u| u.contests.length == 0 }
188 return users.find_all { |u| u.contests.length == 0 }
189 end
189 end
190
190
191
191
192 def contest_time_left
192 def contest_time_left
193 if GraderConfiguration.contest_mode?
193 if GraderConfiguration.contest_mode?
194 return nil if site==nil
194 return nil if site==nil
195 return site.time_left
195 return site.time_left
196 elsif GraderConfiguration.indv_contest_mode?
196 elsif GraderConfiguration.indv_contest_mode?
197 time_limit = GraderConfiguration.contest_time_limit
197 time_limit = GraderConfiguration.contest_time_limit
198 if time_limit == nil
198 if time_limit == nil
199 return nil
199 return nil
200 end
200 end
201 if contest_stat==nil or contest_stat.started_at==nil
201 if contest_stat==nil or contest_stat.started_at==nil
202 return (Time.now.gmtime + time_limit) - Time.now.gmtime
202 return (Time.now.gmtime + time_limit) - Time.now.gmtime
203 else
203 else
204 finish_time = contest_stat.started_at + time_limit
204 finish_time = contest_stat.started_at + time_limit
205 current_time = Time.now.gmtime
205 current_time = Time.now.gmtime
206 if current_time > finish_time
206 if current_time > finish_time
207 return 0
207 return 0
208 else
208 else
209 return finish_time - current_time
209 return finish_time - current_time
210 end
210 end
211 end
211 end
212 else
212 else
213 return nil
213 return nil
214 end
214 end
215 end
215 end
216
216
217 def contest_finished?
217 def contest_finished?
218 if GraderConfiguration.contest_mode?
218 if GraderConfiguration.contest_mode?
219 return false if site==nil
219 return false if site==nil
220 return site.finished?
220 return site.finished?
221 elsif GraderConfiguration.indv_contest_mode?
221 elsif GraderConfiguration.indv_contest_mode?
222 return false if self.contest_stat(true)==nil
222 return false if self.contest_stat(true)==nil
223 return contest_time_left == 0
223 return contest_time_left == 0
224 else
224 else
225 return false
225 return false
226 end
226 end
@@ -1,42 +1,42
1 CafeGrader::Application.configure do
1 CafeGrader::Application.configure do
2 # Settings specified here will take precedence over those in config/application.rb
2 # Settings specified here will take precedence over those in config/application.rb
3
3
4 # In the development environment your application's code is reloaded on
4 # In the development environment your application's code is reloaded on
5 # every request. This slows down response time but is perfect for development
5 # every request. This slows down response time but is perfect for development
6 # since you don't have to restart the web server when you make code changes.
6 # since you don't have to restart the web server when you make code changes.
7 config.cache_classes = false
7 config.cache_classes = false
8
8
9 # Log error messages when you accidentally call methods on nil. //DEPRICATED
9 # Log error messages when you accidentally call methods on nil. //DEPRICATED
10 # config.whiny_nils = true // DEPRICATED
10 # config.whiny_nils = true // DEPRICATED
11
11
12 # Show full error reports and disable caching
12 # Show full error reports and disable caching
13 config.consider_all_requests_local = true
13 config.consider_all_requests_local = true
14 config.action_controller.perform_caching = false
14 config.action_controller.perform_caching = false
15
15
16 # Don't care if the mailer can't send
16 # Don't care if the mailer can't send
17 config.action_mailer.raise_delivery_errors = false
17 config.action_mailer.raise_delivery_errors = false
18
18
19 # Print deprecation notices to the Rails logger
19 # Print deprecation notices to the Rails logger
20 config.active_support.deprecation = :log
20 config.active_support.deprecation = :log
21
21
22 # Only use best-standards-support built into browsers
22 # Only use best-standards-support built into browsers
23 config.action_dispatch.best_standards_support = :builtin
23 config.action_dispatch.best_standards_support = :builtin
24
24
25 # Raise exception on mass assignment protection for Active Record models
25 # Raise exception on mass assignment protection for Active Record models
26 - config.active_record.mass_assignment_sanitizer = :strict
26 + # config.active_record.mass_assignment_sanitizer = :strict //DEPRICATED
27
27
28 # Log the query plan for queries taking more than this (works // DEPRICATED
28 # Log the query plan for queries taking more than this (works // DEPRICATED
29 # with SQLite, MySQL, and PostgreSQL) // DEPRICATED
29 # with SQLite, MySQL, and PostgreSQL) // DEPRICATED
30 # config.active_record.auto_explain_threshold_in_seconds = 0.5 // DEPRICATED
30 # config.active_record.auto_explain_threshold_in_seconds = 0.5 // DEPRICATED
31
31
32 # Do not compress assets
32 # Do not compress assets
33 config.assets.compress = false
33 config.assets.compress = false
34
34
35 # Expands the lines which load the assets
35 # Expands the lines which load the assets
36 config.assets.debug = true
36 config.assets.debug = true
37
37
38 # Prevents assets from rendering twice
38 # Prevents assets from rendering twice
39 config.serve_static_assets = true
39 config.serve_static_assets = true
40
40
41 config.eager_load = false
41 config.eager_load = false
42 end
42 end
@@ -1,39 +1,39
1 CafeGrader::Application.configure do
1 CafeGrader::Application.configure do
2 # Settings specified here will take precedence over those in config/application.rb
2 # Settings specified here will take precedence over those in config/application.rb
3
3
4 # The test environment is used exclusively to run your application's
4 # The test environment is used exclusively to run your application's
5 # test suite. You never need to work with it otherwise. Remember that
5 # test suite. You never need to work with it otherwise. Remember that
6 # your test database is "scratch space" for the test suite and is wiped
6 # your test database is "scratch space" for the test suite and is wiped
7 # and recreated between test runs. Don't rely on the data there!
7 # and recreated between test runs. Don't rely on the data there!
8 config.cache_classes = true
8 config.cache_classes = true
9
9
10 # Configure static asset server for tests with Cache-Control for performance
10 # Configure static asset server for tests with Cache-Control for performance
11 config.serve_static_assets = true
11 config.serve_static_assets = true
12 config.static_cache_control = "public, max-age=3600"
12 config.static_cache_control = "public, max-age=3600"
13
13
14 # Log error messages when you accidentally call methods on nil
14 # Log error messages when you accidentally call methods on nil
15 config.whiny_nils = true
15 config.whiny_nils = true
16
16
17 # Show full error reports and disable caching
17 # Show full error reports and disable caching
18 config.consider_all_requests_local = true
18 config.consider_all_requests_local = true
19 config.action_controller.perform_caching = false
19 config.action_controller.perform_caching = false
20
20
21 # Raise exceptions instead of rendering exception templates
21 # Raise exceptions instead of rendering exception templates
22 config.action_dispatch.show_exceptions = false
22 config.action_dispatch.show_exceptions = false
23
23
24 # Disable request forgery protection in test environment
24 # Disable request forgery protection in test environment
25 config.action_controller.allow_forgery_protection = false
25 config.action_controller.allow_forgery_protection = false
26
26
27 # Tell Action Mailer not to deliver emails to the real world.
27 # Tell Action Mailer not to deliver emails to the real world.
28 # The :test delivery method accumulates sent emails in the
28 # The :test delivery method accumulates sent emails in the
29 # ActionMailer::Base.deliveries array.
29 # ActionMailer::Base.deliveries array.
30 config.action_mailer.delivery_method = :test
30 config.action_mailer.delivery_method = :test
31
31
32 # Raise exception on mass assignment protection for Active Record models
32 # Raise exception on mass assignment protection for Active Record models
33 - config.active_record.mass_assignment_sanitizer = :strict
33 + #config.active_record.mass_assignment_sanitizer = :strict // DEPRICATED
34
34
35 # Print deprecation notices to the stderr
35 # Print deprecation notices to the stderr
36 config.active_support.deprecation = :stderr
36 config.active_support.deprecation = :stderr
37
37
38 config.eager_load = false
38 config.eager_load = false
39 end
39 end
You need to be logged in to leave comments. Login now