Description:
change depricated before_filter to before_action
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r745:75264caa616f - - 20 files changed: 38 inserted, 31 deleted

@@ -1,93 +1,94
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 #rails
3 #rails
4 gem 'rails', '~>5.0'
4 gem 'rails', '~>5.0'
5 gem 'activerecord-session_store'
5 gem 'activerecord-session_store'
6
6
7
7
8 # Bundle edge Rails instead:
8 # Bundle edge Rails instead:
9 # gem 'rails', :git => 'git://github.com/rails/rails.git'
9 # gem 'rails', :git => 'git://github.com/rails/rails.git'
10
10
11 #---------------- database ---------------------
11 #---------------- database ---------------------
12 #the database
12 #the database
13 gem 'mysql2'
13 gem 'mysql2'
14 #for testing
14 #for testing
15 gem 'sqlite3'
15 gem 'sqlite3'
16 + gem 'rails-controller-testing'
16 #for dumping database into yaml
17 #for dumping database into yaml
17 gem 'yaml_db'
18 gem 'yaml_db'
18
19
19 # Gems used only for assets and not required
20 # Gems used only for assets and not required
20 # in production environments by default.
21 # in production environments by default.
21 gem 'sass-rails'
22 gem 'sass-rails'
22 gem 'coffee-rails'
23 gem 'coffee-rails'
23
24
24 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
25 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
25 # gem 'therubyracer', :platforms => :ruby
26 # gem 'therubyracer', :platforms => :ruby
26
27
27 gem 'uglifier'
28 gem 'uglifier'
28
29
29 gem 'haml'
30 gem 'haml'
30 gem 'haml-rails'
31 gem 'haml-rails'
31 # gem 'prototype-rails'
32 # gem 'prototype-rails'
32
33
33 # To use ActiveModel has_secure_password
34 # To use ActiveModel has_secure_password
34 # gem 'bcrypt-ruby', '~> 3.0.0'
35 # gem 'bcrypt-ruby', '~> 3.0.0'
35
36
36 # To use Jbuilder templates for JSON
37 # To use Jbuilder templates for JSON
37 # gem 'jbuilder'
38 # gem 'jbuilder'
38
39
39 # Use unicorn as the app server
40 # Use unicorn as the app server
40 # gem 'unicorn'
41 # gem 'unicorn'
41
42
42 # Deploy with Capistrano
43 # Deploy with Capistrano
43 # gem 'capistrano'
44 # gem 'capistrano'
44
45
45 # To use debugger
46 # To use debugger
46 # gem 'debugger'
47 # gem 'debugger'
47 #
48 #
48
49
49 #in-place editor
50 #in-place editor
50 gem 'best_in_place', '~> 3.0.1'
51 gem 'best_in_place', '~> 3.0.1'
51
52
52 # jquery addition
53 # jquery addition
53 gem 'jquery-rails'
54 gem 'jquery-rails'
54 gem 'jquery-ui-rails'
55 gem 'jquery-ui-rails'
55 gem 'jquery-timepicker-addon-rails'
56 gem 'jquery-timepicker-addon-rails'
56 gem 'jquery-tablesorter'
57 gem 'jquery-tablesorter'
57 gem 'jquery-countdown-rails'
58 gem 'jquery-countdown-rails'
58
59
59 #syntax highlighter
60 #syntax highlighter
60 gem 'rouge'
61 gem 'rouge'
61
62
62 #bootstrap add-ons
63 #bootstrap add-ons
63 gem 'bootstrap-sass', '~> 3.4.1'
64 gem 'bootstrap-sass', '~> 3.4.1'
64 gem 'sassc-rails', '>= 2.1.0'
65 gem 'sassc-rails', '>= 2.1.0'
65 gem 'bootstrap-switch-rails'
66 gem 'bootstrap-switch-rails'
66 gem 'bootstrap-toggle-rails'
67 gem 'bootstrap-toggle-rails'
67 gem 'autoprefixer-rails'
68 gem 'autoprefixer-rails'
68 gem 'momentjs-rails'
69 gem 'momentjs-rails'
69 gem 'rails_bootstrap_sortable'
70 gem 'rails_bootstrap_sortable'
70 gem 'bootstrap-datepicker-rails'
71 gem 'bootstrap-datepicker-rails'
71 gem 'bootstrap3-datetimepicker-rails'
72 gem 'bootstrap3-datetimepicker-rails'
72 gem 'jquery-datatables-rails'
73 gem 'jquery-datatables-rails'
73
74
74 #----------- user interface -----------------
75 #----------- user interface -----------------
75 #select 2
76 #select 2
76 gem 'select2-rails'
77 gem 'select2-rails'
77 #ace editor
78 #ace editor
78 gem 'ace-rails-ap'
79 gem 'ace-rails-ap'
79 #paginator
80 #paginator
80 gem 'will_paginate', '~> 3.0.7'
81 gem 'will_paginate', '~> 3.0.7'
81
82
82 gem 'mail'
83 gem 'mail'
83 gem 'rdiscount'
84 gem 'rdiscount'
84 gem 'dynamic_form'
85 gem 'dynamic_form'
85 gem 'in_place_editing'
86 gem 'in_place_editing'
86 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
87 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
87
88
88
89
89 #---------------- testiing -----------------------
90 #---------------- testiing -----------------------
90 gem 'minitest-reporters'
91 gem 'minitest-reporters'
91
92
92 #---------------- for console --------------------
93 #---------------- for console --------------------
93 gem 'fuzzy-string-match'
94 gem 'fuzzy-string-match'
@@ -1,274 +1,279
1 GIT
1 GIT
2 remote: https://github.com/sikachu/verification.git
2 remote: https://github.com/sikachu/verification.git
3 revision: ff31697b940d7b0e2ec65f08764215c96104e76d
3 revision: ff31697b940d7b0e2ec65f08764215c96104e76d
4 specs:
4 specs:
5 verification (1.0.3)
5 verification (1.0.3)
6 actionpack (>= 3.0.0, < 5.1)
6 actionpack (>= 3.0.0, < 5.1)
7 activesupport (>= 3.0.0, < 5.1)
7 activesupport (>= 3.0.0, < 5.1)
8
8
9 GEM
9 GEM
10 remote: https://rubygems.org/
10 remote: https://rubygems.org/
11 specs:
11 specs:
12 RubyInline (3.12.4)
12 RubyInline (3.12.4)
13 ZenTest (~> 4.3)
13 ZenTest (~> 4.3)
14 ZenTest (4.11.2)
14 ZenTest (4.11.2)
15 ace-rails-ap (4.2)
15 ace-rails-ap (4.2)
16 actioncable (5.0.7.2)
16 actioncable (5.0.7.2)
17 actionpack (= 5.0.7.2)
17 actionpack (= 5.0.7.2)
18 nio4r (>= 1.2, < 3.0)
18 nio4r (>= 1.2, < 3.0)
19 websocket-driver (~> 0.6.1)
19 websocket-driver (~> 0.6.1)
20 actionmailer (5.0.7.2)
20 actionmailer (5.0.7.2)
21 actionpack (= 5.0.7.2)
21 actionpack (= 5.0.7.2)
22 actionview (= 5.0.7.2)
22 actionview (= 5.0.7.2)
23 activejob (= 5.0.7.2)
23 activejob (= 5.0.7.2)
24 mail (~> 2.5, >= 2.5.4)
24 mail (~> 2.5, >= 2.5.4)
25 rails-dom-testing (~> 2.0)
25 rails-dom-testing (~> 2.0)
26 actionpack (5.0.7.2)
26 actionpack (5.0.7.2)
27 actionview (= 5.0.7.2)
27 actionview (= 5.0.7.2)
28 activesupport (= 5.0.7.2)
28 activesupport (= 5.0.7.2)
29 rack (~> 2.0)
29 rack (~> 2.0)
30 rack-test (~> 0.6.3)
30 rack-test (~> 0.6.3)
31 rails-dom-testing (~> 2.0)
31 rails-dom-testing (~> 2.0)
32 rails-html-sanitizer (~> 1.0, >= 1.0.2)
32 rails-html-sanitizer (~> 1.0, >= 1.0.2)
33 actionview (5.0.7.2)
33 actionview (5.0.7.2)
34 activesupport (= 5.0.7.2)
34 activesupport (= 5.0.7.2)
35 builder (~> 3.1)
35 builder (~> 3.1)
36 erubis (~> 2.7.0)
36 erubis (~> 2.7.0)
37 rails-dom-testing (~> 2.0)
37 rails-dom-testing (~> 2.0)
38 rails-html-sanitizer (~> 1.0, >= 1.0.3)
38 rails-html-sanitizer (~> 1.0, >= 1.0.3)
39 activejob (5.0.7.2)
39 activejob (5.0.7.2)
40 activesupport (= 5.0.7.2)
40 activesupport (= 5.0.7.2)
41 globalid (>= 0.3.6)
41 globalid (>= 0.3.6)
42 activemodel (5.0.7.2)
42 activemodel (5.0.7.2)
43 activesupport (= 5.0.7.2)
43 activesupport (= 5.0.7.2)
44 activerecord (5.0.7.2)
44 activerecord (5.0.7.2)
45 activemodel (= 5.0.7.2)
45 activemodel (= 5.0.7.2)
46 activesupport (= 5.0.7.2)
46 activesupport (= 5.0.7.2)
47 arel (~> 7.0)
47 arel (~> 7.0)
48 activerecord-session_store (1.1.3)
48 activerecord-session_store (1.1.3)
49 actionpack (>= 4.0)
49 actionpack (>= 4.0)
50 activerecord (>= 4.0)
50 activerecord (>= 4.0)
51 multi_json (~> 1.11, >= 1.11.2)
51 multi_json (~> 1.11, >= 1.11.2)
52 rack (>= 1.5.2, < 3)
52 rack (>= 1.5.2, < 3)
53 railties (>= 4.0)
53 railties (>= 4.0)
54 activesupport (5.0.7.2)
54 activesupport (5.0.7.2)
55 concurrent-ruby (~> 1.0, >= 1.0.2)
55 concurrent-ruby (~> 1.0, >= 1.0.2)
56 i18n (>= 0.7, < 2)
56 i18n (>= 0.7, < 2)
57 minitest (~> 5.1)
57 minitest (~> 5.1)
58 tzinfo (~> 1.1)
58 tzinfo (~> 1.1)
59 ansi (1.5.0)
59 ansi (1.5.0)
60 arel (7.1.4)
60 arel (7.1.4)
61 autoprefixer-rails (9.5.1.1)
61 autoprefixer-rails (9.5.1.1)
62 execjs
62 execjs
63 best_in_place (3.0.3)
63 best_in_place (3.0.3)
64 actionpack (>= 3.2)
64 actionpack (>= 3.2)
65 railties (>= 3.2)
65 railties (>= 3.2)
66 bootstrap-datepicker-rails (1.8.0.1)
66 bootstrap-datepicker-rails (1.8.0.1)
67 railties (>= 3.0)
67 railties (>= 3.0)
68 bootstrap-sass (3.4.1)
68 bootstrap-sass (3.4.1)
69 autoprefixer-rails (>= 5.2.1)
69 autoprefixer-rails (>= 5.2.1)
70 sassc (>= 2.0.0)
70 sassc (>= 2.0.0)
71 bootstrap-switch-rails (3.3.4)
71 bootstrap-switch-rails (3.3.4)
72 bootstrap-toggle-rails (2.2.1.0)
72 bootstrap-toggle-rails (2.2.1.0)
73 bootstrap3-datetimepicker-rails (4.17.47)
73 bootstrap3-datetimepicker-rails (4.17.47)
74 momentjs-rails (>= 2.8.1)
74 momentjs-rails (>= 2.8.1)
75 builder (3.2.3)
75 builder (3.2.3)
76 coffee-rails (4.2.2)
76 coffee-rails (4.2.2)
77 coffee-script (>= 2.2.0)
77 coffee-script (>= 2.2.0)
78 railties (>= 4.0.0)
78 railties (>= 4.0.0)
79 coffee-script (2.4.1)
79 coffee-script (2.4.1)
80 coffee-script-source
80 coffee-script-source
81 execjs
81 execjs
82 coffee-script-source (1.12.2)
82 coffee-script-source (1.12.2)
83 concurrent-ruby (1.1.5)
83 concurrent-ruby (1.1.5)
84 crass (1.0.4)
84 crass (1.0.4)
85 dynamic_form (1.1.4)
85 dynamic_form (1.1.4)
86 erubis (2.7.0)
86 erubis (2.7.0)
87 execjs (2.7.0)
87 execjs (2.7.0)
88 ffi (1.11.1)
88 ffi (1.11.1)
89 fuzzy-string-match (1.0.1)
89 fuzzy-string-match (1.0.1)
90 RubyInline (>= 3.8.6)
90 RubyInline (>= 3.8.6)
91 globalid (0.4.2)
91 globalid (0.4.2)
92 activesupport (>= 4.2.0)
92 activesupport (>= 4.2.0)
93 haml (5.1.0)
93 haml (5.1.0)
94 temple (>= 0.8.0)
94 temple (>= 0.8.0)
95 tilt
95 tilt
96 haml-rails (1.0.0)
96 haml-rails (1.0.0)
97 actionpack (>= 4.0.1)
97 actionpack (>= 4.0.1)
98 activesupport (>= 4.0.1)
98 activesupport (>= 4.0.1)
99 haml (>= 4.0.6, < 6.0)
99 haml (>= 4.0.6, < 6.0)
100 html2haml (>= 1.0.1)
100 html2haml (>= 1.0.1)
101 railties (>= 4.0.1)
101 railties (>= 4.0.1)
102 html2haml (2.2.0)
102 html2haml (2.2.0)
103 erubis (~> 2.7.0)
103 erubis (~> 2.7.0)
104 haml (>= 4.0, < 6)
104 haml (>= 4.0, < 6)
105 nokogiri (>= 1.6.0)
105 nokogiri (>= 1.6.0)
106 ruby_parser (~> 3.5)
106 ruby_parser (~> 3.5)
107 i18n (1.6.0)
107 i18n (1.6.0)
108 concurrent-ruby (~> 1.0)
108 concurrent-ruby (~> 1.0)
109 in_place_editing (1.2.0)
109 in_place_editing (1.2.0)
110 jquery-countdown-rails (2.0.2)
110 jquery-countdown-rails (2.0.2)
111 jquery-datatables-rails (3.4.0)
111 jquery-datatables-rails (3.4.0)
112 actionpack (>= 3.1)
112 actionpack (>= 3.1)
113 jquery-rails
113 jquery-rails
114 railties (>= 3.1)
114 railties (>= 3.1)
115 sass-rails
115 sass-rails
116 jquery-rails (4.3.3)
116 jquery-rails (4.3.3)
117 rails-dom-testing (>= 1, < 3)
117 rails-dom-testing (>= 1, < 3)
118 railties (>= 4.2.0)
118 railties (>= 4.2.0)
119 thor (>= 0.14, < 2.0)
119 thor (>= 0.14, < 2.0)
120 jquery-tablesorter (1.26.1)
120 jquery-tablesorter (1.26.1)
121 railties (>= 3.2, < 6)
121 railties (>= 3.2, < 6)
122 jquery-timepicker-addon-rails (1.4.1)
122 jquery-timepicker-addon-rails (1.4.1)
123 railties (>= 3.1)
123 railties (>= 3.1)
124 jquery-ui-rails (6.0.1)
124 jquery-ui-rails (6.0.1)
125 railties (>= 3.2.16)
125 railties (>= 3.2.16)
126 loofah (2.2.3)
126 loofah (2.2.3)
127 crass (~> 1.0.2)
127 crass (~> 1.0.2)
128 nokogiri (>= 1.5.9)
128 nokogiri (>= 1.5.9)
129 mail (2.7.1)
129 mail (2.7.1)
130 mini_mime (>= 0.1.1)
130 mini_mime (>= 0.1.1)
131 method_source (0.9.2)
131 method_source (0.9.2)
132 mini_mime (1.0.1)
132 mini_mime (1.0.1)
133 mini_portile2 (2.4.0)
133 mini_portile2 (2.4.0)
134 minitest (5.11.3)
134 minitest (5.11.3)
135 minitest-reporters (1.3.6)
135 minitest-reporters (1.3.6)
136 ansi
136 ansi
137 builder
137 builder
138 minitest (>= 5.0)
138 minitest (>= 5.0)
139 ruby-progressbar
139 ruby-progressbar
140 momentjs-rails (2.20.1)
140 momentjs-rails (2.20.1)
141 railties (>= 3.1)
141 railties (>= 3.1)
142 multi_json (1.13.1)
142 multi_json (1.13.1)
143 mysql2 (0.5.2)
143 mysql2 (0.5.2)
144 nio4r (2.3.1)
144 nio4r (2.3.1)
145 nokogiri (1.10.3)
145 nokogiri (1.10.3)
146 mini_portile2 (~> 2.4.0)
146 mini_portile2 (~> 2.4.0)
147 rack (2.0.7)
147 rack (2.0.7)
148 rack-test (0.6.3)
148 rack-test (0.6.3)
149 rack (>= 1.0)
149 rack (>= 1.0)
150 rails (5.0.7.2)
150 rails (5.0.7.2)
151 actioncable (= 5.0.7.2)
151 actioncable (= 5.0.7.2)
152 actionmailer (= 5.0.7.2)
152 actionmailer (= 5.0.7.2)
153 actionpack (= 5.0.7.2)
153 actionpack (= 5.0.7.2)
154 actionview (= 5.0.7.2)
154 actionview (= 5.0.7.2)
155 activejob (= 5.0.7.2)
155 activejob (= 5.0.7.2)
156 activemodel (= 5.0.7.2)
156 activemodel (= 5.0.7.2)
157 activerecord (= 5.0.7.2)
157 activerecord (= 5.0.7.2)
158 activesupport (= 5.0.7.2)
158 activesupport (= 5.0.7.2)
159 bundler (>= 1.3.0)
159 bundler (>= 1.3.0)
160 railties (= 5.0.7.2)
160 railties (= 5.0.7.2)
161 sprockets-rails (>= 2.0.0)
161 sprockets-rails (>= 2.0.0)
162 + rails-controller-testing (1.0.4)
163 + actionpack (>= 5.0.1.x)
164 + actionview (>= 5.0.1.x)
165 + activesupport (>= 5.0.1.x)
162 rails-dom-testing (2.0.3)
166 rails-dom-testing (2.0.3)
163 activesupport (>= 4.2.0)
167 activesupport (>= 4.2.0)
164 nokogiri (>= 1.6)
168 nokogiri (>= 1.6)
165 rails-html-sanitizer (1.0.4)
169 rails-html-sanitizer (1.0.4)
166 loofah (~> 2.2, >= 2.2.2)
170 loofah (~> 2.2, >= 2.2.2)
167 rails_bootstrap_sortable (2.0.6)
171 rails_bootstrap_sortable (2.0.6)
168 momentjs-rails (>= 2.8.3)
172 momentjs-rails (>= 2.8.3)
169 railties (5.0.7.2)
173 railties (5.0.7.2)
170 actionpack (= 5.0.7.2)
174 actionpack (= 5.0.7.2)
171 activesupport (= 5.0.7.2)
175 activesupport (= 5.0.7.2)
172 method_source
176 method_source
173 rake (>= 0.8.7)
177 rake (>= 0.8.7)
174 thor (>= 0.18.1, < 2.0)
178 thor (>= 0.18.1, < 2.0)
175 rake (12.3.2)
179 rake (12.3.2)
176 rb-fsevent (0.10.3)
180 rb-fsevent (0.10.3)
177 rb-inotify (0.10.0)
181 rb-inotify (0.10.0)
178 ffi (~> 1.0)
182 ffi (~> 1.0)
179 rdiscount (2.2.0.1)
183 rdiscount (2.2.0.1)
180 rouge (3.3.0)
184 rouge (3.3.0)
181 ruby-progressbar (1.10.0)
185 ruby-progressbar (1.10.0)
182 ruby_parser (3.13.1)
186 ruby_parser (3.13.1)
183 sexp_processor (~> 4.9)
187 sexp_processor (~> 4.9)
184 sass (3.7.4)
188 sass (3.7.4)
185 sass-listen (~> 4.0.0)
189 sass-listen (~> 4.0.0)
186 sass-listen (4.0.0)
190 sass-listen (4.0.0)
187 rb-fsevent (~> 0.9, >= 0.9.4)
191 rb-fsevent (~> 0.9, >= 0.9.4)
188 rb-inotify (~> 0.9, >= 0.9.7)
192 rb-inotify (~> 0.9, >= 0.9.7)
189 sass-rails (5.0.7)
193 sass-rails (5.0.7)
190 railties (>= 4.0.0, < 6)
194 railties (>= 4.0.0, < 6)
191 sass (~> 3.1)
195 sass (~> 3.1)
192 sprockets (>= 2.8, < 4.0)
196 sprockets (>= 2.8, < 4.0)
193 sprockets-rails (>= 2.0, < 4.0)
197 sprockets-rails (>= 2.0, < 4.0)
194 tilt (>= 1.1, < 3)
198 tilt (>= 1.1, < 3)
195 sassc (2.0.1)
199 sassc (2.0.1)
196 ffi (~> 1.9)
200 ffi (~> 1.9)
197 rake
201 rake
198 sassc-rails (2.1.1)
202 sassc-rails (2.1.1)
199 railties (>= 4.0.0)
203 railties (>= 4.0.0)
200 sassc (>= 2.0)
204 sassc (>= 2.0)
201 sprockets (> 3.0)
205 sprockets (> 3.0)
202 sprockets-rails
206 sprockets-rails
203 tilt
207 tilt
204 select2-rails (4.0.3)
208 select2-rails (4.0.3)
205 thor (~> 0.14)
209 thor (~> 0.14)
206 sexp_processor (4.12.0)
210 sexp_processor (4.12.0)
207 sprockets (3.7.2)
211 sprockets (3.7.2)
208 concurrent-ruby (~> 1.0)
212 concurrent-ruby (~> 1.0)
209 rack (> 1, < 3)
213 rack (> 1, < 3)
210 sprockets-rails (3.2.1)
214 sprockets-rails (3.2.1)
211 actionpack (>= 4.0)
215 actionpack (>= 4.0)
212 activesupport (>= 4.0)
216 activesupport (>= 4.0)
213 sprockets (>= 3.0.0)
217 sprockets (>= 3.0.0)
214 sqlite3 (1.4.1)
218 sqlite3 (1.4.1)
215 temple (0.8.1)
219 temple (0.8.1)
216 thor (0.20.3)
220 thor (0.20.3)
217 thread_safe (0.3.6)
221 thread_safe (0.3.6)
218 tilt (2.0.9)
222 tilt (2.0.9)
219 tzinfo (1.2.5)
223 tzinfo (1.2.5)
220 thread_safe (~> 0.1)
224 thread_safe (~> 0.1)
221 uglifier (4.1.20)
225 uglifier (4.1.20)
222 execjs (>= 0.3.0, < 3)
226 execjs (>= 0.3.0, < 3)
223 websocket-driver (0.6.5)
227 websocket-driver (0.6.5)
224 websocket-extensions (>= 0.1.0)
228 websocket-extensions (>= 0.1.0)
225 websocket-extensions (0.1.4)
229 websocket-extensions (0.1.4)
226 will_paginate (3.0.12)
230 will_paginate (3.0.12)
227 yaml_db (0.7.0)
231 yaml_db (0.7.0)
228 rails (>= 3.0)
232 rails (>= 3.0)
229 rake (>= 0.8.7)
233 rake (>= 0.8.7)
230
234
231 PLATFORMS
235 PLATFORMS
232 ruby
236 ruby
233
237
234 DEPENDENCIES
238 DEPENDENCIES
235 ace-rails-ap
239 ace-rails-ap
236 activerecord-session_store
240 activerecord-session_store
237 autoprefixer-rails
241 autoprefixer-rails
238 best_in_place (~> 3.0.1)
242 best_in_place (~> 3.0.1)
239 bootstrap-datepicker-rails
243 bootstrap-datepicker-rails
240 bootstrap-sass (~> 3.4.1)
244 bootstrap-sass (~> 3.4.1)
241 bootstrap-switch-rails
245 bootstrap-switch-rails
242 bootstrap-toggle-rails
246 bootstrap-toggle-rails
243 bootstrap3-datetimepicker-rails
247 bootstrap3-datetimepicker-rails
244 coffee-rails
248 coffee-rails
245 dynamic_form
249 dynamic_form
246 fuzzy-string-match
250 fuzzy-string-match
247 haml
251 haml
248 haml-rails
252 haml-rails
249 in_place_editing
253 in_place_editing
250 jquery-countdown-rails
254 jquery-countdown-rails
251 jquery-datatables-rails
255 jquery-datatables-rails
252 jquery-rails
256 jquery-rails
253 jquery-tablesorter
257 jquery-tablesorter
254 jquery-timepicker-addon-rails
258 jquery-timepicker-addon-rails
255 jquery-ui-rails
259 jquery-ui-rails
256 mail
260 mail
257 minitest-reporters
261 minitest-reporters
258 momentjs-rails
262 momentjs-rails
259 mysql2
263 mysql2
260 rails (~> 5.0)
264 rails (~> 5.0)
265 + rails-controller-testing
261 rails_bootstrap_sortable
266 rails_bootstrap_sortable
262 rdiscount
267 rdiscount
263 rouge
268 rouge
264 sass-rails
269 sass-rails
265 sassc-rails (>= 2.1.0)
270 sassc-rails (>= 2.1.0)
266 select2-rails
271 select2-rails
267 sqlite3
272 sqlite3
268 uglifier
273 uglifier
269 verification!
274 verification!
270 will_paginate (~> 3.0.7)
275 will_paginate (~> 3.0.7)
271 yaml_db
276 yaml_db
272
277
273 BUNDLED WITH
278 BUNDLED WITH
274 1.17.2
279 1.17.2
@@ -1,116 +1,116
1 class AnnouncementsController < ApplicationController
1 class AnnouncementsController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_action :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(announcement_params)
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)
114 params.require(:announcement).permit(:author, :body, :published, :frontpage, :contest_only, :title)
115 end
115 end
116 end
116 end
@@ -1,138 +1,138
1 class ApplicationController < ActionController::Base
1 class ApplicationController < ActionController::Base
2 protect_from_forgery
2 protect_from_forgery
3
3
4 - before_filter :current_user
4 + before_action :current_user
5
5
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
8
8
9 #report and redirect for unauthorized activities
9 #report and redirect for unauthorized activities
10 def unauthorized_redirect
10 def unauthorized_redirect
11 flash[:notice] = 'You are not authorized to view the page you requested'
11 flash[:notice] = 'You are not authorized to view the page you requested'
12 redirect_to :controller => 'main', :action => 'login'
12 redirect_to :controller => 'main', :action => 'login'
13 end
13 end
14
14
15 # Returns the current logged-in user (if any).
15 # Returns the current logged-in user (if any).
16 def current_user
16 def current_user
17 return nil unless session[:user_id]
17 return nil unless session[:user_id]
18 @current_user ||= User.find(session[:user_id])
18 @current_user ||= User.find(session[:user_id])
19 end
19 end
20
20
21 def admin_authorization
21 def admin_authorization
22 return false unless authenticate
22 return false unless authenticate
23 user = User.includes(:roles).find(session[:user_id])
23 user = User.includes(:roles).find(session[:user_id])
24 unless user.admin?
24 unless user.admin?
25 unauthorized_redirect
25 unauthorized_redirect
26 return false
26 return false
27 end
27 end
28 return true
28 return true
29 end
29 end
30
30
31 def authorization_by_roles(allowed_roles)
31 def authorization_by_roles(allowed_roles)
32 return false unless authenticate
32 return false unless authenticate
33 user = User.find(session[:user_id])
33 user = User.find(session[:user_id])
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
35 unauthorized_redirect
35 unauthorized_redirect
36 return false
36 return false
37 end
37 end
38 end
38 end
39
39
40 def testcase_authorization
40 def testcase_authorization
41 #admin always has privileged
41 #admin always has privileged
42 if @current_user.admin?
42 if @current_user.admin?
43 return true
43 return true
44 end
44 end
45
45
46 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
46 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
47 end
47 end
48
48
49 protected
49 protected
50
50
51 def authenticate
51 def authenticate
52 unless session[:user_id]
52 unless session[:user_id]
53 flash[:notice] = 'You need to login'
53 flash[:notice] = 'You need to login'
54 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
54 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
55 flash[:notice] = 'You need to login but you cannot log in at this time'
55 flash[:notice] = 'You need to login but you cannot log in at this time'
56 end
56 end
57 redirect_to :controller => 'main', :action => 'login'
57 redirect_to :controller => 'main', :action => 'login'
58 return false
58 return false
59 end
59 end
60
60
61
61
62 # check if run in single user mode
62 # check if run in single user mode
63 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
63 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
64 if @current_user==nil or (not @current_user.admin?)
64 if @current_user==nil or (not @current_user.admin?)
65 flash[:notice] = 'You cannot log in at this time'
65 flash[:notice] = 'You cannot log in at this time'
66 redirect_to :controller => 'main', :action => 'login'
66 redirect_to :controller => 'main', :action => 'login'
67 return false
67 return false
68 end
68 end
69 return true
69 return true
70 end
70 end
71
71
72 # check if the user is enabled
72 # check if the user is enabled
73 unless @current_user.enabled? or @current_user.admin?
73 unless @current_user.enabled? or @current_user.admin?
74 flash[:notice] = 'Your account is disabled'
74 flash[:notice] = 'Your account is disabled'
75 redirect_to :controller => 'main', :action => 'login'
75 redirect_to :controller => 'main', :action => 'login'
76 return false
76 return false
77 end
77 end
78
78
79 if GraderConfiguration.multicontests?
79 if GraderConfiguration.multicontests?
80 return true if @current_user.admin?
80 return true if @current_user.admin?
81 begin
81 begin
82 if @current_user.contest_stat(true).forced_logout
82 if @current_user.contest_stat(true).forced_logout
83 flash[:notice] = 'You have been automatically logged out.'
83 flash[:notice] = 'You have been automatically logged out.'
84 redirect_to :controller => 'main', :action => 'index'
84 redirect_to :controller => 'main', :action => 'index'
85 end
85 end
86 rescue
86 rescue
87 end
87 end
88 end
88 end
89 return true
89 return true
90 end
90 end
91
91
92 def authenticate_by_ip_address
92 def authenticate_by_ip_address
93 #this assume that we have already authenticate normally
93 #this assume that we have already authenticate normally
94 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
94 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
95 user = User.find(session[:user_id])
95 user = User.find(session[:user_id])
96 if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
96 if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
97 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
97 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
98 redirect_to :controller => 'main', :action => 'login'
98 redirect_to :controller => 'main', :action => 'login'
99 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
99 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
100 return false
100 return false
101 end
101 end
102 unless user.last_ip
102 unless user.last_ip
103 user.last_ip = request.remote_ip
103 user.last_ip = request.remote_ip
104 user.save
104 user.save
105 end
105 end
106 end
106 end
107 return true
107 return true
108 end
108 end
109
109
110 def authorization
110 def authorization
111 return false unless authenticate
111 return false unless authenticate
112 user = User.find(session[:user_id])
112 user = User.find(session[:user_id])
113 unless user.roles.detect { |role|
113 unless user.roles.detect { |role|
114 role.rights.detect{ |right|
114 role.rights.detect{ |right|
115 right.controller == self.class.controller_name and
115 right.controller == self.class.controller_name and
116 (right.action == 'all' or right.action == action_name)
116 (right.action == 'all' or right.action == action_name)
117 }
117 }
118 }
118 }
119 flash[:notice] = 'You are not authorized to view the page you requested'
119 flash[:notice] = 'You are not authorized to view the page you requested'
120 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
120 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
121 redirect_to :controller => 'main', :action => 'login'
121 redirect_to :controller => 'main', :action => 'login'
122 return false
122 return false
123 end
123 end
124 end
124 end
125
125
126 def verify_time_limit
126 def verify_time_limit
127 return true if session[:user_id]==nil
127 return true if session[:user_id]==nil
128 user = User.find(session[:user_id], :include => :site)
128 user = User.find(session[:user_id], :include => :site)
129 return true if user==nil or user.site == nil
129 return true if user==nil or user.site == nil
130 if user.contest_finished?
130 if user.contest_finished?
131 flash[:notice] = 'Error: the contest you are participating is over.'
131 flash[:notice] = 'Error: the contest you are participating is over.'
132 redirect_to :back
132 redirect_to :back
133 return false
133 return false
134 end
134 end
135 return true
135 return true
136 end
136 end
137
137
138 end
138 end
@@ -1,34 +1,34
1 class ConfigurationsController < ApplicationController
1 class ConfigurationsController < ApplicationController
2
2
3 - before_filter :authenticate
3 + before_action :authenticate
4 - before_filter { |controller| controller.authorization_by_roles(['admin'])}
4 + before_action { |controller| controller.authorization_by_roles(['admin'])}
5
5
6
6
7 def index
7 def index
8 @configurations = GraderConfiguration.order(:key)
8 @configurations = GraderConfiguration.order(:key)
9 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
9 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
10 end
10 end
11
11
12 def reload
12 def reload
13 GraderConfiguration.reload
13 GraderConfiguration.reload
14 redirect_to :action => 'index'
14 redirect_to :action => 'index'
15 end
15 end
16
16
17 def update
17 def update
18 @config = GraderConfiguration.find(params[:id])
18 @config = GraderConfiguration.find(params[:id])
19 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
19 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
20 respond_to do |format|
20 respond_to do |format|
21 if @config.update_attributes(configuration_params)
21 if @config.update_attributes(configuration_params)
22 format.json { head :ok }
22 format.json { head :ok }
23 else
23 else
24 format.json { respond_with_bip(@config) }
24 format.json { respond_with_bip(@config) }
25 end
25 end
26 end
26 end
27 end
27 end
28
28
29 private
29 private
30 def configuration_params
30 def configuration_params
31 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
31 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
32 end
32 end
33
33
34 end
34 end
@@ -1,50 +1,50
1 class ContestManagementController < ApplicationController
1 class ContestManagementController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_action :admin_authorization
4
4
5 def index
5 def index
6 @num_contests = Contest.count()
6 @num_contests = Contest.count()
7 end
7 end
8
8
9 def user_stat
9 def user_stat
10 if not GraderConfiguration.indv_contest_mode?
10 if not GraderConfiguration.indv_contest_mode?
11 redirect_to :action => 'index' and return
11 redirect_to :action => 'index' and return
12 end
12 end
13
13
14 @users = User.all
14 @users = User.all
15 @start_times = {}
15 @start_times = {}
16 UserContestStat.all.each do |stat|
16 UserContestStat.all.each do |stat|
17 @start_times[stat.user_id] = stat.started_at
17 @start_times[stat.user_id] = stat.started_at
18 end
18 end
19 end
19 end
20
20
21 def clear_stat
21 def clear_stat
22 user = User.find(params[:id])
22 user = User.find(params[:id])
23 if user.contest_stat!=nil
23 if user.contest_stat!=nil
24 user.contest_stat.destroy
24 user.contest_stat.destroy
25 end
25 end
26 redirect_to :action => 'user_stat'
26 redirect_to :action => 'user_stat'
27 end
27 end
28
28
29 def clear_all_stat
29 def clear_all_stat
30 if not GraderConfiguration.indv_contest_mode?
30 if not GraderConfiguration.indv_contest_mode?
31 redirect_to :action => 'index' and return
31 redirect_to :action => 'index' and return
32 end
32 end
33
33
34 UserContestStat.delete_all()
34 UserContestStat.delete_all()
35 flash[:notice] = 'All start time statistic cleared.'
35 flash[:notice] = 'All start time statistic cleared.'
36 redirect_to :action => 'index'
36 redirect_to :action => 'index'
37 end
37 end
38
38
39 def change_contest_mode
39 def change_contest_mode
40 if ['standard', 'contest', 'indv-contest', 'analysis'].include? params[:id]
40 if ['standard', 'contest', 'indv-contest', 'analysis'].include? params[:id]
41 config = GraderConfiguration.find_by_key('system.mode')
41 config = GraderConfiguration.find_by_key('system.mode')
42 config.value = params[:id]
42 config.value = params[:id]
43 config.save
43 config.save
44 else
44 else
45 flash[:notice] = 'Wrong contest mode value'
45 flash[:notice] = 'Wrong contest mode value'
46 end
46 end
47 redirect_to :action => 'index'
47 redirect_to :action => 'index'
48 end
48 end
49
49
50 end
50 end
@@ -1,98 +1,98
1 class ContestsController < ApplicationController
1 class ContestsController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_action :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(contests_params)
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
92 private
93
93
94 def contests_params
94 def contests_params
95 params.require(:contest).permit(:title,:enabled,:name)
95 params.require(:contest).permit(:title,:enabled,:name)
96 end
96 end
97
97
98 end
98 end
@@ -1,93 +1,93
1 class GradersController < ApplicationController
1 class GradersController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_action :admin_authorization
4
4
5 verify :method => :post, :only => ['clear_all',
5 verify :method => :post, :only => ['clear_all',
6 'start_exam',
6 'start_exam',
7 'start_grading',
7 'start_grading',
8 'stop_all',
8 'stop_all',
9 'clear_terminated'],
9 'clear_terminated'],
10 :redirect_to => {:action => 'index'}
10 :redirect_to => {:action => 'index'}
11
11
12 def index
12 def index
13 redirect_to :action => 'list'
13 redirect_to :action => 'list'
14 end
14 end
15
15
16 def list
16 def list
17 @grader_processes = GraderProcess.find_running_graders
17 @grader_processes = GraderProcess.find_running_graders
18 @stalled_processes = GraderProcess.find_stalled_process
18 @stalled_processes = GraderProcess.find_stalled_process
19
19
20 @terminated_processes = GraderProcess.find_terminated_graders
20 @terminated_processes = GraderProcess.find_terminated_graders
21
21
22 @last_task = Task.last
22 @last_task = Task.last
23 @last_test_request = TestRequest.last
23 @last_test_request = TestRequest.last
24 @submission = Submission.order("id desc").limit(20)
24 @submission = Submission.order("id desc").limit(20)
25 @backlog_submission = Submission.where('graded_at is null')
25 @backlog_submission = Submission.where('graded_at is null')
26 end
26 end
27
27
28 def clear
28 def clear
29 grader_proc = GraderProcess.find(params[:id])
29 grader_proc = GraderProcess.find(params[:id])
30 grader_proc.destroy if grader_proc!=nil
30 grader_proc.destroy if grader_proc!=nil
31 redirect_to :action => 'list'
31 redirect_to :action => 'list'
32 end
32 end
33
33
34 def clear_terminated
34 def clear_terminated
35 GraderProcess.find_terminated_graders.each do |p|
35 GraderProcess.find_terminated_graders.each do |p|
36 p.destroy
36 p.destroy
37 end
37 end
38 redirect_to :action => 'list'
38 redirect_to :action => 'list'
39 end
39 end
40
40
41 def clear_all
41 def clear_all
42 GraderProcess.all.each do |p|
42 GraderProcess.all.each do |p|
43 p.destroy
43 p.destroy
44 end
44 end
45 redirect_to :action => 'list'
45 redirect_to :action => 'list'
46 end
46 end
47
47
48 def view
48 def view
49 if params[:type]=='Task'
49 if params[:type]=='Task'
50 redirect_to :action => 'task', :id => params[:id]
50 redirect_to :action => 'task', :id => params[:id]
51 else
51 else
52 redirect_to :action => 'test_request', :id => params[:id]
52 redirect_to :action => 'test_request', :id => params[:id]
53 end
53 end
54 end
54 end
55
55
56 def test_request
56 def test_request
57 @test_request = TestRequest.find(params[:id])
57 @test_request = TestRequest.find(params[:id])
58 end
58 end
59
59
60 def task
60 def task
61 @task = Task.find(params[:id])
61 @task = Task.find(params[:id])
62 end
62 end
63
63
64
64
65 # various grader controls
65 # various grader controls
66
66
67 def stop
67 def stop
68 grader_proc = GraderProcess.find(params[:id])
68 grader_proc = GraderProcess.find(params[:id])
69 GraderScript.stop_grader(grader_proc.pid)
69 GraderScript.stop_grader(grader_proc.pid)
70 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
70 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
71 redirect_to :action => 'list'
71 redirect_to :action => 'list'
72 end
72 end
73
73
74 def stop_all
74 def stop_all
75 GraderScript.stop_graders(GraderProcess.find_running_graders +
75 GraderScript.stop_graders(GraderProcess.find_running_graders +
76 GraderProcess.find_stalled_process)
76 GraderProcess.find_stalled_process)
77 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
77 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
78 redirect_to :action => 'list'
78 redirect_to :action => 'list'
79 end
79 end
80
80
81 def start_grading
81 def start_grading
82 GraderScript.start_grader('grading')
82 GraderScript.start_grader('grading')
83 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
83 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
84 redirect_to :action => 'list'
84 redirect_to :action => 'list'
85 end
85 end
86
86
87 def start_exam
87 def start_exam
88 GraderScript.start_grader('exam')
88 GraderScript.start_grader('exam')
89 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
89 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
90 redirect_to :action => 'list'
90 redirect_to :action => 'list'
91 end
91 end
92
92
93 end
93 end
@@ -1,46 +1,46
1 class HeartbeatController < ApplicationController
1 class HeartbeatController < ApplicationController
2 - before_filter :admin_authorization, :only => ['index']
2 + before_action :admin_authorization, :only => ['index']
3
3
4 def edit
4 def edit
5 #@user = User.find_by_login(params[:id])
5 #@user = User.find_by_login(params[:id])
6 #unless @user
6 #unless @user
7 # render text: "LOGIN_NOT_FOUND"
7 # render text: "LOGIN_NOT_FOUND"
8 # return
8 # return
9 #end
9 #end
10
10
11 #hb = HeartBeat.where(user_id: @user.id, ip_address: request.remote_ip).first
11 #hb = HeartBeat.where(user_id: @user.id, ip_address: request.remote_ip).first
12 #puts "status = #{params[:status]}"
12 #puts "status = #{params[:status]}"
13 #if hb
13 #if hb
14 # if params[:status]
14 # if params[:status]
15 # hb.status = params[:status]
15 # hb.status = params[:status]
16 # hb.save
16 # hb.save
17 # end
17 # end
18 # hb.touch
18 # hb.touch
19 #else
19 #else
20 # HeartBeat.creae(user_id: @user.id, ip_address: request.remote_ip)
20 # HeartBeat.creae(user_id: @user.id, ip_address: request.remote_ip)
21 #end
21 #end
22 #HeartBeat.create(user_id: @user.id, ip_address: request.remote_ip, status: params[:status])
22 #HeartBeat.create(user_id: @user.id, ip_address: request.remote_ip, status: params[:status])
23
23
24 res = GraderConfiguration['right.heartbeat_response']
24 res = GraderConfiguration['right.heartbeat_response']
25 res.strip! if res
25 res.strip! if res
26 full = GraderConfiguration['right.heartbeat_response_full']
26 full = GraderConfiguration['right.heartbeat_response_full']
27 full.strip! if full
27 full.strip! if full
28
28
29 if full and full != ''
29 if full and full != ''
30 l = Login.where(ip_address: request.remote_ip).last
30 l = Login.where(ip_address: request.remote_ip).last
31 @user = l.user
31 @user = l.user
32 if @user.solve_all_available_problems?
32 if @user.solve_all_available_problems?
33 render text: (full || 'OK')
33 render text: (full || 'OK')
34 else
34 else
35 render text: (res || 'OK')
35 render text: (res || 'OK')
36 end
36 end
37 else
37 else
38 render text: (GraderConfiguration['right.heartbeat_response'] || 'OK')
38 render text: (GraderConfiguration['right.heartbeat_response'] || 'OK')
39 end
39 end
40 end
40 end
41
41
42 def index
42 def index
43 @hb = HeartBeat.where("updated_at >= ?",Time.zone.now-2.hours).includes(:user).order(:user_id).all
43 @hb = HeartBeat.where("updated_at >= ?",Time.zone.now-2.hours).includes(:user).order(:user_id).all
44 @num = HeartBeat.where("updated_at >= ?",Time.zone.now-5.minutes).count(:user_id,distinct: true)
44 @num = HeartBeat.where("updated_at >= ?",Time.zone.now-5.minutes).count(:user_id,distinct: true)
45 end
45 end
46 end
46 end
@@ -1,376 +1,376
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 - before_filter :authenticate, :except => [:index, :login]
3 + before_action :authenticate, :except => [:index, :login]
4 - before_filter :check_viewability, :except => [:index, :login]
4 + before_action :check_viewability, :except => [:index, :login]
5
5
6 - append_before_filter :confirm_and_update_start_time,
6 + append_before_action :confirm_and_update_start_time,
7 :except => [:index,
7 :except => [:index,
8 :login,
8 :login,
9 :confirm_contest_start]
9 :confirm_contest_start]
10
10
11 # to prevent log in box to be shown when user logged out of the
11 # to prevent log in box to be shown when user logged out of the
12 # system only in some tab
12 # system only in some tab
13 - prepend_before_filter :reject_announcement_refresh_when_logged_out,
13 + prepend_before_action :reject_announcement_refresh_when_logged_out,
14 :only => [:announcements]
14 :only => [:announcements]
15
15
16 - before_filter :authenticate_by_ip_address, :only => [:list]
16 + before_action :authenticate_by_ip_address, :only => [:list]
17
17
18 # COMMENTED OUT: filter in each action instead
18 # COMMENTED OUT: filter in each action instead
19 # before_filter :verify_time_limit, :only => [:submit]
19 # before_filter :verify_time_limit, :only => [:submit]
20
20
21 verify :method => :post, :only => [:submit],
21 verify :method => :post, :only => [:submit],
22 :redirect_to => { :action => :index }
22 :redirect_to => { :action => :index }
23
23
24 # COMMENT OUT: only need when having high load
24 # COMMENT OUT: only need when having high load
25 # caches_action :index, :login
25 # caches_action :index, :login
26
26
27 # NOTE: This method is not actually needed, 'config/routes.rb' has
27 # NOTE: This method is not actually needed, 'config/routes.rb' has
28 # assigned action login as a default action.
28 # assigned action login as a default action.
29 def index
29 def index
30 redirect_to :action => 'login'
30 redirect_to :action => 'login'
31 end
31 end
32
32
33 def login
33 def login
34 saved_notice = flash[:notice]
34 saved_notice = flash[:notice]
35 reset_session
35 reset_session
36 flash.now[:notice] = saved_notice
36 flash.now[:notice] = saved_notice
37
37
38 # EXPERIMENT:
38 # EXPERIMENT:
39 # Hide login if in single user mode and the url does not
39 # Hide login if in single user mode and the url does not
40 # explicitly specify /login
40 # explicitly specify /login
41 #
41 #
42 # logger.info "PATH: #{request.path}"
42 # logger.info "PATH: #{request.path}"
43 # if GraderConfiguration['system.single_user_mode'] and
43 # if GraderConfiguration['system.single_user_mode'] and
44 # request.path!='/main/login'
44 # request.path!='/main/login'
45 # @hidelogin = true
45 # @hidelogin = true
46 # end
46 # end
47
47
48 @announcements = Announcement.frontpage
48 @announcements = Announcement.frontpage
49 render :action => 'login', :layout => 'empty'
49 render :action => 'login', :layout => 'empty'
50 end
50 end
51
51
52 def list
52 def list
53 prepare_list_information
53 prepare_list_information
54 end
54 end
55
55
56 def help
56 def help
57 @user = User.find(session[:user_id])
57 @user = User.find(session[:user_id])
58 end
58 end
59
59
60 def submit
60 def submit
61 user = User.find(session[:user_id])
61 user = User.find(session[:user_id])
62
62
63 @submission = Submission.new
63 @submission = Submission.new
64 @submission.problem_id = params[:submission][:problem_id]
64 @submission.problem_id = params[:submission][:problem_id]
65 @submission.user = user
65 @submission.user = user
66 @submission.language_id = 0
66 @submission.language_id = 0
67 if (params['file']) and (params['file']!='')
67 if (params['file']) and (params['file']!='')
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
70 @submission.source_filename = params['file'].original_filename
70 @submission.source_filename = params['file'].original_filename
71 end
71 end
72
72
73 if (params[:editor_text])
73 if (params[:editor_text])
74 language = Language.find_by_id(params[:language_id])
74 language = Language.find_by_id(params[:language_id])
75 @submission.source = params[:editor_text]
75 @submission.source = params[:editor_text]
76 @submission.source_filename = "live_edit.#{language.ext}"
76 @submission.source_filename = "live_edit.#{language.ext}"
77 @submission.language = language
77 @submission.language = language
78 end
78 end
79
79
80 @submission.submitted_at = Time.new.gmtime
80 @submission.submitted_at = Time.new.gmtime
81 @submission.ip_address = request.remote_ip
81 @submission.ip_address = request.remote_ip
82
82
83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
84 @submission.errors.add(:base,"The contest is over.")
84 @submission.errors.add(:base,"The contest is over.")
85 prepare_list_information
85 prepare_list_information
86 render :action => 'list' and return
86 render :action => 'list' and return
87 end
87 end
88
88
89 if @submission.valid?(@current_user)
89 if @submission.valid?(@current_user)
90 if @submission.save == false
90 if @submission.save == false
91 flash[:notice] = 'Error saving your submission'
91 flash[:notice] = 'Error saving your submission'
92 elsif Task.create(:submission_id => @submission.id,
92 elsif Task.create(:submission_id => @submission.id,
93 :status => Task::STATUS_INQUEUE) == false
93 :status => Task::STATUS_INQUEUE) == false
94 flash[:notice] = 'Error adding your submission to task queue'
94 flash[:notice] = 'Error adding your submission to task queue'
95 end
95 end
96 else
96 else
97 prepare_list_information
97 prepare_list_information
98 render :action => 'list' and return
98 render :action => 'list' and return
99 end
99 end
100 redirect_to edit_submission_path(@submission)
100 redirect_to edit_submission_path(@submission)
101 end
101 end
102
102
103 def source
103 def source
104 submission = Submission.find(params[:id])
104 submission = Submission.find(params[:id])
105 if ((submission.user_id == session[:user_id]) and
105 if ((submission.user_id == session[:user_id]) and
106 (submission.problem != nil) and
106 (submission.problem != nil) and
107 (submission.problem.available))
107 (submission.problem.available))
108 send_data(submission.source,
108 send_data(submission.source,
109 {:filename => submission.download_filename,
109 {:filename => submission.download_filename,
110 :type => 'text/plain'})
110 :type => 'text/plain'})
111 else
111 else
112 flash[:notice] = 'Error viewing source'
112 flash[:notice] = 'Error viewing source'
113 redirect_to :action => 'list'
113 redirect_to :action => 'list'
114 end
114 end
115 end
115 end
116
116
117 def compiler_msg
117 def compiler_msg
118 @submission = Submission.find(params[:id])
118 @submission = Submission.find(params[:id])
119 if @submission.user_id == session[:user_id]
119 if @submission.user_id == session[:user_id]
120 render :action => 'compiler_msg', :layout => 'empty'
120 render :action => 'compiler_msg', :layout => 'empty'
121 else
121 else
122 flash[:notice] = 'Error viewing source'
122 flash[:notice] = 'Error viewing source'
123 redirect_to :action => 'list'
123 redirect_to :action => 'list'
124 end
124 end
125 end
125 end
126
126
127 def result
127 def result
128 if !GraderConfiguration.show_grading_result
128 if !GraderConfiguration.show_grading_result
129 redirect_to :action => 'list' and return
129 redirect_to :action => 'list' and return
130 end
130 end
131 @user = User.find(session[:user_id])
131 @user = User.find(session[:user_id])
132 @submission = Submission.find(params[:id])
132 @submission = Submission.find(params[:id])
133 if @submission.user!=@user
133 if @submission.user!=@user
134 flash[:notice] = 'You are not allowed to view result of other users.'
134 flash[:notice] = 'You are not allowed to view result of other users.'
135 redirect_to :action => 'list' and return
135 redirect_to :action => 'list' and return
136 end
136 end
137 prepare_grading_result(@submission)
137 prepare_grading_result(@submission)
138 end
138 end
139
139
140 def load_output
140 def load_output
141 if !GraderConfiguration.show_grading_result or params[:num]==nil
141 if !GraderConfiguration.show_grading_result or params[:num]==nil
142 redirect_to :action => 'list' and return
142 redirect_to :action => 'list' and return
143 end
143 end
144 @user = User.find(session[:user_id])
144 @user = User.find(session[:user_id])
145 @submission = Submission.find(params[:id])
145 @submission = Submission.find(params[:id])
146 if @submission.user!=@user
146 if @submission.user!=@user
147 flash[:notice] = 'You are not allowed to view result of other users.'
147 flash[:notice] = 'You are not allowed to view result of other users.'
148 redirect_to :action => 'list' and return
148 redirect_to :action => 'list' and return
149 end
149 end
150 case_num = params[:num].to_i
150 case_num = params[:num].to_i
151 out_filename = output_filename(@user.login,
151 out_filename = output_filename(@user.login,
152 @submission.problem.name,
152 @submission.problem.name,
153 @submission.id,
153 @submission.id,
154 case_num)
154 case_num)
155 if !FileTest.exists?(out_filename)
155 if !FileTest.exists?(out_filename)
156 flash[:notice] = 'Output not found.'
156 flash[:notice] = 'Output not found.'
157 redirect_to :action => 'list' and return
157 redirect_to :action => 'list' and return
158 end
158 end
159
159
160 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
160 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
161 response.headers['Content-Type'] = "application/force-download"
161 response.headers['Content-Type'] = "application/force-download"
162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
163 response.headers["X-Sendfile"] = out_filename
163 response.headers["X-Sendfile"] = out_filename
164 response.headers['Content-length'] = File.size(out_filename)
164 response.headers['Content-length'] = File.size(out_filename)
165 render :nothing => true
165 render :nothing => true
166 else
166 else
167 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
167 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
168 end
168 end
169 end
169 end
170
170
171 def error
171 def error
172 @user = User.find(session[:user_id])
172 @user = User.find(session[:user_id])
173 end
173 end
174
174
175 # announcement refreshing and hiding methods
175 # announcement refreshing and hiding methods
176
176
177 def announcements
177 def announcements
178 if params.has_key? 'recent'
178 if params.has_key? 'recent'
179 prepare_announcements(params[:recent])
179 prepare_announcements(params[:recent])
180 else
180 else
181 prepare_announcements
181 prepare_announcements
182 end
182 end
183 render(:partial => 'announcement',
183 render(:partial => 'announcement',
184 :collection => @announcements,
184 :collection => @announcements,
185 :locals => {:announcement_effect => true})
185 :locals => {:announcement_effect => true})
186 end
186 end
187
187
188 def confirm_contest_start
188 def confirm_contest_start
189 user = User.find(session[:user_id])
189 user = User.find(session[:user_id])
190 if request.method == 'POST'
190 if request.method == 'POST'
191 user.update_start_time
191 user.update_start_time
192 redirect_to :action => 'list'
192 redirect_to :action => 'list'
193 else
193 else
194 @contests = user.contests
194 @contests = user.contests
195 @user = user
195 @user = user
196 end
196 end
197 end
197 end
198
198
199 protected
199 protected
200
200
201 def prepare_announcements(recent=nil)
201 def prepare_announcements(recent=nil)
202 if GraderConfiguration.show_tasks_to?(@user)
202 if GraderConfiguration.show_tasks_to?(@user)
203 @announcements = Announcement.published(true)
203 @announcements = Announcement.published(true)
204 else
204 else
205 @announcements = Announcement.published
205 @announcements = Announcement.published
206 end
206 end
207 if recent!=nil
207 if recent!=nil
208 recent_id = recent.to_i
208 recent_id = recent.to_i
209 @announcements = @announcements.find_all { |a| a.id > recent_id }
209 @announcements = @announcements.find_all { |a| a.id > recent_id }
210 end
210 end
211 end
211 end
212
212
213 def prepare_list_information
213 def prepare_list_information
214 @user = User.find(session[:user_id])
214 @user = User.find(session[:user_id])
215 if not GraderConfiguration.multicontests?
215 if not GraderConfiguration.multicontests?
216 @problems = @user.available_problems
216 @problems = @user.available_problems
217 else
217 else
218 @contest_problems = @user.available_problems_group_by_contests
218 @contest_problems = @user.available_problems_group_by_contests
219 @problems = @user.available_problems
219 @problems = @user.available_problems
220 end
220 end
221 @prob_submissions = {}
221 @prob_submissions = {}
222 @problems.each do |p|
222 @problems.each do |p|
223 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
223 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
224 if sub!=nil
224 if sub!=nil
225 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
225 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
226 else
226 else
227 @prob_submissions[p.id] = { :count => 0, :submission => nil }
227 @prob_submissions[p.id] = { :count => 0, :submission => nil }
228 end
228 end
229 end
229 end
230 prepare_announcements
230 prepare_announcements
231 end
231 end
232
232
233 def check_viewability
233 def check_viewability
234 @user = User.find(session[:user_id])
234 @user = User.find(session[:user_id])
235 if (!GraderConfiguration.show_tasks_to?(@user)) and
235 if (!GraderConfiguration.show_tasks_to?(@user)) and
236 ((action_name=='submission') or (action_name=='submit'))
236 ((action_name=='submission') or (action_name=='submit'))
237 redirect_to :action => 'list' and return
237 redirect_to :action => 'list' and return
238 end
238 end
239 end
239 end
240
240
241 def prepare_grading_result(submission)
241 def prepare_grading_result(submission)
242 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
242 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
243 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
243 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
244 else
244 else
245 # guess task info from problem.full_score
245 # guess task info from problem.full_score
246 cases = submission.problem.full_score / 10
246 cases = submission.problem.full_score / 10
247 grading_info = {
247 grading_info = {
248 'testruns' => cases,
248 'testruns' => cases,
249 'testcases' => cases
249 'testcases' => cases
250 }
250 }
251 end
251 end
252 @test_runs = []
252 @test_runs = []
253 if grading_info['testruns'].is_a? Integer
253 if grading_info['testruns'].is_a? Integer
254 trun_count = grading_info['testruns']
254 trun_count = grading_info['testruns']
255 trun_count.times do |i|
255 trun_count.times do |i|
256 @test_runs << [ read_grading_result(@user.login,
256 @test_runs << [ read_grading_result(@user.login,
257 submission.problem.name,
257 submission.problem.name,
258 submission.id,
258 submission.id,
259 i+1) ]
259 i+1) ]
260 end
260 end
261 else
261 else
262 grading_info['testruns'].keys.sort.each do |num|
262 grading_info['testruns'].keys.sort.each do |num|
263 run = []
263 run = []
264 testrun = grading_info['testruns'][num]
264 testrun = grading_info['testruns'][num]
265 testrun.each do |c|
265 testrun.each do |c|
266 run << read_grading_result(@user.login,
266 run << read_grading_result(@user.login,
267 submission.problem.name,
267 submission.problem.name,
268 submission.id,
268 submission.id,
269 c)
269 c)
270 end
270 end
271 @test_runs << run
271 @test_runs << run
272 end
272 end
273 end
273 end
274 end
274 end
275
275
276 def grading_result_dir(user_name, problem_name, submission_id, case_num)
276 def grading_result_dir(user_name, problem_name, submission_id, case_num)
277 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
277 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
278 end
278 end
279
279
280 def output_filename(user_name, problem_name, submission_id, case_num)
280 def output_filename(user_name, problem_name, submission_id, case_num)
281 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
281 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
282 return "#{dir}/output.txt"
282 return "#{dir}/output.txt"
283 end
283 end
284
284
285 def read_grading_result(user_name, problem_name, submission_id, case_num)
285 def read_grading_result(user_name, problem_name, submission_id, case_num)
286 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
286 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
287 result_file_name = "#{dir}/result"
287 result_file_name = "#{dir}/result"
288 if !FileTest.exists?(result_file_name)
288 if !FileTest.exists?(result_file_name)
289 return {:num => case_num, :msg => 'program did not run'}
289 return {:num => case_num, :msg => 'program did not run'}
290 else
290 else
291 results = File.open(result_file_name).readlines
291 results = File.open(result_file_name).readlines
292 run_stat = extract_running_stat(results)
292 run_stat = extract_running_stat(results)
293 output_filename = "#{dir}/output.txt"
293 output_filename = "#{dir}/output.txt"
294 if FileTest.exists?(output_filename)
294 if FileTest.exists?(output_filename)
295 output_file = true
295 output_file = true
296 output_size = File.size(output_filename)
296 output_size = File.size(output_filename)
297 else
297 else
298 output_file = false
298 output_file = false
299 output_size = 0
299 output_size = 0
300 end
300 end
301
301
302 return {
302 return {
303 :num => case_num,
303 :num => case_num,
304 :msg => results[0],
304 :msg => results[0],
305 :run_stat => run_stat,
305 :run_stat => run_stat,
306 :output => output_file,
306 :output => output_file,
307 :output_size => output_size
307 :output_size => output_size
308 }
308 }
309 end
309 end
310 end
310 end
311
311
312 # copied from grader/script/lib/test_request_helper.rb
312 # copied from grader/script/lib/test_request_helper.rb
313 def extract_running_stat(results)
313 def extract_running_stat(results)
314 running_stat_line = results[-1]
314 running_stat_line = results[-1]
315
315
316 # extract exit status line
316 # extract exit status line
317 run_stat = ""
317 run_stat = ""
318 if !(/[Cc]orrect/.match(results[0]))
318 if !(/[Cc]orrect/.match(results[0]))
319 run_stat = results[0].chomp
319 run_stat = results[0].chomp
320 else
320 else
321 run_stat = 'Program exited normally'
321 run_stat = 'Program exited normally'
322 end
322 end
323
323
324 logger.info "Stat line: #{running_stat_line}"
324 logger.info "Stat line: #{running_stat_line}"
325
325
326 # extract running time
326 # extract running time
327 if res = /r(.*)u(.*)s/.match(running_stat_line)
327 if res = /r(.*)u(.*)s/.match(running_stat_line)
328 seconds = (res[1].to_f + res[2].to_f)
328 seconds = (res[1].to_f + res[2].to_f)
329 time_stat = "Time used: #{seconds} sec."
329 time_stat = "Time used: #{seconds} sec."
330 else
330 else
331 seconds = nil
331 seconds = nil
332 time_stat = "Time used: n/a sec."
332 time_stat = "Time used: n/a sec."
333 end
333 end
334
334
335 # extract memory usage
335 # extract memory usage
336 if res = /s(.*)m/.match(running_stat_line)
336 if res = /s(.*)m/.match(running_stat_line)
337 memory_used = res[1].to_i
337 memory_used = res[1].to_i
338 else
338 else
339 memory_used = -1
339 memory_used = -1
340 end
340 end
341
341
342 return {
342 return {
343 :msg => "#{run_stat}\n#{time_stat}",
343 :msg => "#{run_stat}\n#{time_stat}",
344 :running_time => seconds,
344 :running_time => seconds,
345 :exit_status => run_stat,
345 :exit_status => run_stat,
346 :memory_usage => memory_used
346 :memory_usage => memory_used
347 }
347 }
348 end
348 end
349
349
350 def confirm_and_update_start_time
350 def confirm_and_update_start_time
351 user = User.find(session[:user_id])
351 user = User.find(session[:user_id])
352 if (GraderConfiguration.indv_contest_mode? and
352 if (GraderConfiguration.indv_contest_mode? and
353 GraderConfiguration['contest.confirm_indv_contest_start'] and
353 GraderConfiguration['contest.confirm_indv_contest_start'] and
354 !user.contest_started?)
354 !user.contest_started?)
355 redirect_to :action => 'confirm_contest_start' and return
355 redirect_to :action => 'confirm_contest_start' and return
356 end
356 end
357 if not GraderConfiguration.analysis_mode?
357 if not GraderConfiguration.analysis_mode?
358 user.update_start_time
358 user.update_start_time
359 end
359 end
360 end
360 end
361
361
362 def reject_announcement_refresh_when_logged_out
362 def reject_announcement_refresh_when_logged_out
363 if not session[:user_id]
363 if not session[:user_id]
364 render :text => 'Access forbidden', :status => 403
364 render :text => 'Access forbidden', :status => 403
365 end
365 end
366
366
367 if GraderConfiguration.multicontests?
367 if GraderConfiguration.multicontests?
368 user = User.find(session[:user_id])
368 user = User.find(session[:user_id])
369 if user.contest_stat.forced_logout
369 if user.contest_stat.forced_logout
370 render :text => 'Access forbidden', :status => 403
370 render :text => 'Access forbidden', :status => 403
371 end
371 end
372 end
372 end
373 end
373 end
374
374
375 end
375 end
376
376
@@ -1,86 +1,86
1 class MessagesController < ApplicationController
1 class MessagesController < ApplicationController
2
2
3 - before_filter :authenticate
3 + before_action :authenticate
4
4
5 verify :method => :post, :only => ['create'],
5 verify :method => :post, :only => ['create'],
6 :redirect_to => { :action => 'list' }
6 :redirect_to => { :action => 'list' }
7
7
8 before_filter :admin_authorization, :only => ['console','show',
8 before_filter :admin_authorization, :only => ['console','show',
9 'reply','hide','list_all']
9 'reply','hide','list_all']
10
10
11 def list
11 def list
12 @user = User.find(session[:user_id])
12 @user = User.find(session[:user_id])
13 @messages = Message.find_all_sent_by_user(@user)
13 @messages = Message.find_all_sent_by_user(@user)
14 end
14 end
15
15
16 def console
16 def console
17 @user = User.find(session[:user_id])
17 @user = User.find(session[:user_id])
18 @messages = Message.find_all_system_unreplied_messages
18 @messages = Message.find_all_system_unreplied_messages
19 end
19 end
20
20
21 def show
21 def show
22 @message = Message.find(params[:id])
22 @message = Message.find(params[:id])
23 end
23 end
24
24
25 def list_all
25 def list_all
26 @user = User.find(session[:user_id])
26 @user = User.find(session[:user_id])
27 @messages = Message.where(receiver_id: nil).order(:created_at)
27 @messages = Message.where(receiver_id: nil).order(:created_at)
28 end
28 end
29
29
30 def create
30 def create
31 user = User.find(session[:user_id])
31 user = User.find(session[:user_id])
32 @message = Message.new(params[:message])
32 @message = Message.new(params[:message])
33 @message.sender = user
33 @message.sender = user
34 if @message.body == '' or !@message.save
34 if @message.body == '' or !@message.save
35 flash[:notice] = 'An error occurred'
35 flash[:notice] = 'An error occurred'
36 else
36 else
37 flash[:notice] = 'New message posted'
37 flash[:notice] = 'New message posted'
38 end
38 end
39 redirect_to :action => 'list'
39 redirect_to :action => 'list'
40 end
40 end
41
41
42 def reply
42 def reply
43 user = User.find(session[:user_id])
43 user = User.find(session[:user_id])
44 @message = Message.new(params[:r_message])
44 @message = Message.new(params[:r_message])
45 @message.sender = user
45 @message.sender = user
46 if @message.body == '' or !@message.save
46 if @message.body == '' or !@message.save
47 flash[:notice] = 'An error occurred'
47 flash[:notice] = 'An error occurred'
48 redirect_to :action => 'show', :id => @message.replying_message_id
48 redirect_to :action => 'show', :id => @message.replying_message_id
49 else
49 else
50 flash[:notice] = 'Message replied'
50 flash[:notice] = 'Message replied'
51 rep_msg = @message.replying_message
51 rep_msg = @message.replying_message
52 rep_msg.replied = true
52 rep_msg.replied = true
53 rep_msg.save
53 rep_msg.save
54 redirect_to :action => 'console'
54 redirect_to :action => 'console'
55 end
55 end
56 end
56 end
57
57
58 def hide
58 def hide
59 message = Message.find(params[:id])
59 message = Message.find(params[:id])
60 message.replied = true
60 message.replied = true
61 message.save
61 message.save
62 flash[:notice] = 'Message hidden (just marked replied)'
62 flash[:notice] = 'Message hidden (just marked replied)'
63 redirect_to :action => 'console'
63 redirect_to :action => 'console'
64 end
64 end
65
65
66 protected
66 protected
67 def build_replying_message_hierarchy(user)
67 def build_replying_message_hierarchy(user)
68 @all_messages = {}
68 @all_messages = {}
69
69
70
70
71 # manually build replies hierarchy (to improve efficiency)
71 # manually build replies hierarchy (to improve efficiency)
72 [@messages, @replied_messages].each do |collection|
72 [@messages, @replied_messages].each do |collection|
73 collection.each do |m|
73 collection.each do |m|
74 @all_messages[m.id] = {:msg => m, :replies => []}
74 @all_messages[m.id] = {:msg => m, :replies => []}
75 end
75 end
76 end
76 end
77
77
78 @all_messages.each do |m|
78 @all_messages.each do |m|
79 rep_id = m.replying_message_id
79 rep_id = m.replying_message_id
80 if @all_messages[rep_id]!=nil
80 if @all_messages[rep_id]!=nil
81 @all_messages[rep_id][:replies] << m
81 @all_messages[rep_id][:replies] << m
82 end
82 end
83 end
83 end
84 end
84 end
85
85
86 end
86 end
@@ -1,393 +1,393
1 require 'csv'
1 require 'csv'
2
2
3 class ReportController < ApplicationController
3 class ReportController < ApplicationController
4
4
5 - before_filter :authenticate
5 + before_action :authenticate
6
6
7 - before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
7 + before_action :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
8
8
9 - before_filter(only: [:problem_hof]) { |c|
9 + before_action(only: [:problem_hof]) { |c|
10 return false unless authenticate
10 return false unless authenticate
11
11
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
13 }
13 }
14
14
15 def max_score
15 def max_score
16 end
16 end
17
17
18 def current_score
18 def current_score
19 @problems = Problem.available_problems
19 @problems = Problem.available_problems
20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
22
22
23 #rencer accordingly
23 #rencer accordingly
24 if params[:button] == 'download' then
24 if params[:button] == 'download' then
25 csv = gen_csv_from_scorearray(@scorearray,@problems)
25 csv = gen_csv_from_scorearray(@scorearray,@problems)
26 send_data csv, filename: 'max_score.csv'
26 send_data csv, filename: 'max_score.csv'
27 else
27 else
28 #render template: 'user_admin/user_stat'
28 #render template: 'user_admin/user_stat'
29 render 'current_score'
29 render 'current_score'
30 end
30 end
31 end
31 end
32
32
33 def show_max_score
33 def show_max_score
34 #process parameters
34 #process parameters
35 #problems
35 #problems
36 @problems = []
36 @problems = []
37 if params[:problem_id]
37 if params[:problem_id]
38 params[:problem_id].each do |id|
38 params[:problem_id].each do |id|
39 next unless id.strip != ""
39 next unless id.strip != ""
40 pid = Problem.find_by_id(id.to_i)
40 pid = Problem.find_by_id(id.to_i)
41 @problems << pid if pid
41 @problems << pid if pid
42 end
42 end
43 end
43 end
44
44
45 #users
45 #users
46 @users = if params[:users] == "all" then
46 @users = if params[:users] == "all" then
47 User.includes(:contests).includes(:contest_stat)
47 User.includes(:contests).includes(:contest_stat)
48 else
48 else
49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
49 User.includes(:contests).includes(:contest_stat).where(enabled: true)
50 end
50 end
51
51
52 #set up range from param
52 #set up range from param
53 @since_id = params.fetch(:from_id, 0).to_i
53 @since_id = params.fetch(:from_id, 0).to_i
54 @until_id = params.fetch(:to_id, 0).to_i
54 @until_id = params.fetch(:to_id, 0).to_i
55 @since_id = nil if @since_id == 0
55 @since_id = nil if @since_id == 0
56 @until_id = nil if @until_id == 0
56 @until_id = nil if @until_id == 0
57
57
58 #calculate the routine
58 #calculate the routine
59 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
59 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
60
60
61 #rencer accordingly
61 #rencer accordingly
62 if params[:button] == 'download' then
62 if params[:button] == 'download' then
63 csv = gen_csv_from_scorearray(@scorearray,@problems)
63 csv = gen_csv_from_scorearray(@scorearray,@problems)
64 send_data csv, filename: 'max_score.csv'
64 send_data csv, filename: 'max_score.csv'
65 else
65 else
66 #render template: 'user_admin/user_stat'
66 #render template: 'user_admin/user_stat'
67 render 'max_score'
67 render 'max_score'
68 end
68 end
69
69
70 end
70 end
71
71
72 def score
72 def score
73 if params[:commit] == 'download csv'
73 if params[:commit] == 'download csv'
74 @problems = Problem.all
74 @problems = Problem.all
75 else
75 else
76 @problems = Problem.available_problems
76 @problems = Problem.available_problems
77 end
77 end
78 @users = User.includes(:contests, :contest_stat).where(enabled: true)
78 @users = User.includes(:contests, :contest_stat).where(enabled: true)
79 @scorearray = Array.new
79 @scorearray = Array.new
80 @users.each do |u|
80 @users.each do |u|
81 ustat = Array.new
81 ustat = Array.new
82 ustat[0] = u
82 ustat[0] = u
83 @problems.each do |p|
83 @problems.each do |p|
84 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
84 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
85 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
85 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
86 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
86 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
87 else
87 else
88 ustat << [0,false]
88 ustat << [0,false]
89 end
89 end
90 end
90 end
91 @scorearray << ustat
91 @scorearray << ustat
92 end
92 end
93 if params[:commit] == 'download csv' then
93 if params[:commit] == 'download csv' then
94 csv = gen_csv_from_scorearray(@scorearray,@problems)
94 csv = gen_csv_from_scorearray(@scorearray,@problems)
95 send_data csv, filename: 'last_score.csv'
95 send_data csv, filename: 'last_score.csv'
96 else
96 else
97 render template: 'user_admin/user_stat'
97 render template: 'user_admin/user_stat'
98 end
98 end
99
99
100 end
100 end
101
101
102 def login_stat
102 def login_stat
103 @logins = Array.new
103 @logins = Array.new
104
104
105 date_and_time = '%Y-%m-%d %H:%M'
105 date_and_time = '%Y-%m-%d %H:%M'
106 begin
106 begin
107 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
107 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
108 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
108 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
109 rescue
109 rescue
110 @since_time = DateTime.new(1000,1,1)
110 @since_time = DateTime.new(1000,1,1)
111 end
111 end
112 begin
112 begin
113 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
113 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
114 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
114 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
115 rescue
115 rescue
116 @until_time = DateTime.new(3000,1,1)
116 @until_time = DateTime.new(3000,1,1)
117 end
117 end
118
118
119 User.all.each do |user|
119 User.all.each do |user|
120 @logins << { id: user.id,
120 @logins << { id: user.id,
121 login: user.login,
121 login: user.login,
122 full_name: user.full_name,
122 full_name: user.full_name,
123 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
123 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
124 user.id,@since_time,@until_time)
124 user.id,@since_time,@until_time)
125 .count(:id),
125 .count(:id),
126 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
126 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
127 user.id,@since_time,@until_time)
127 user.id,@since_time,@until_time)
128 .minimum(:created_at),
128 .minimum(:created_at),
129 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
129 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
130 user.id,@since_time,@until_time)
130 user.id,@since_time,@until_time)
131 .maximum(:created_at),
131 .maximum(:created_at),
132 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
132 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
133 user.id,@since_time,@until_time)
133 user.id,@since_time,@until_time)
134 .select(:ip_address).uniq
134 .select(:ip_address).uniq
135
135
136 }
136 }
137 end
137 end
138 end
138 end
139
139
140 def submission_stat
140 def submission_stat
141
141
142 date_and_time = '%Y-%m-%d %H:%M'
142 date_and_time = '%Y-%m-%d %H:%M'
143 begin
143 begin
144 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
144 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
145 rescue
145 rescue
146 @since_time = DateTime.new(1000,1,1)
146 @since_time = DateTime.new(1000,1,1)
147 end
147 end
148 begin
148 begin
149 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
149 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
150 rescue
150 rescue
151 @until_time = DateTime.new(3000,1,1)
151 @until_time = DateTime.new(3000,1,1)
152 end
152 end
153
153
154 @submissions = {}
154 @submissions = {}
155
155
156 User.find_each do |user|
156 User.find_each do |user|
157 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
157 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
158 end
158 end
159
159
160 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
160 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
161 if @submissions[s.user_id]
161 if @submissions[s.user_id]
162 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
162 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
163 a = Problem.find_by_id(s.problem_id)
163 a = Problem.find_by_id(s.problem_id)
164 @submissions[s.user_id][:sub][s.problem_id] =
164 @submissions[s.user_id][:sub][s.problem_id] =
165 { prob_name: (a ? a.full_name : '(NULL)'),
165 { prob_name: (a ? a.full_name : '(NULL)'),
166 sub_ids: [s.id] }
166 sub_ids: [s.id] }
167 else
167 else
168 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
168 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
169 end
169 end
170 @submissions[s.user_id][:count] += 1
170 @submissions[s.user_id][:count] += 1
171 end
171 end
172 end
172 end
173 end
173 end
174
174
175 def problem_hof
175 def problem_hof
176 # gen problem list
176 # gen problem list
177 @user = User.find(session[:user_id])
177 @user = User.find(session[:user_id])
178 @problems = @user.available_problems
178 @problems = @user.available_problems
179
179
180 # get selected problems or the default
180 # get selected problems or the default
181 if params[:id]
181 if params[:id]
182 begin
182 begin
183 @problem = Problem.available.find(params[:id])
183 @problem = Problem.available.find(params[:id])
184 rescue
184 rescue
185 redirect_to action: :problem_hof
185 redirect_to action: :problem_hof
186 flash[:notice] = 'Error: submissions for that problem are not viewable.'
186 flash[:notice] = 'Error: submissions for that problem are not viewable.'
187 return
187 return
188 end
188 end
189 end
189 end
190
190
191 return unless @problem
191 return unless @problem
192
192
193 @by_lang = {} #aggregrate by language
193 @by_lang = {} #aggregrate by language
194
194
195 range =65
195 range =65
196 @histogram = { data: Array.new(range,0), summary: {} }
196 @histogram = { data: Array.new(range,0), summary: {} }
197 @summary = {count: 0, solve: 0, attempt: 0}
197 @summary = {count: 0, solve: 0, attempt: 0}
198 user = Hash.new(0)
198 user = Hash.new(0)
199 Submission.where(problem_id: @problem.id).find_each do |sub|
199 Submission.where(problem_id: @problem.id).find_each do |sub|
200 #histogram
200 #histogram
201 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
201 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
202 @histogram[:data][d.to_i] += 1 if d < range
202 @histogram[:data][d.to_i] += 1 if d < range
203
203
204 next unless sub.points
204 next unless sub.points
205 @summary[:count] += 1
205 @summary[:count] += 1
206 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
206 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
207
207
208 lang = Language.find_by_id(sub.language_id)
208 lang = Language.find_by_id(sub.language_id)
209 next unless lang
209 next unless lang
210 next unless sub.points >= @problem.full_score
210 next unless sub.points >= @problem.full_score
211
211
212 #initialize
212 #initialize
213 unless @by_lang.has_key?(lang.pretty_name)
213 unless @by_lang.has_key?(lang.pretty_name)
214 @by_lang[lang.pretty_name] = {
214 @by_lang[lang.pretty_name] = {
215 runtime: { avail: false, value: 2**30-1 },
215 runtime: { avail: false, value: 2**30-1 },
216 memory: { avail: false, value: 2**30-1 },
216 memory: { avail: false, value: 2**30-1 },
217 length: { avail: false, value: 2**30-1 },
217 length: { avail: false, value: 2**30-1 },
218 first: { avail: false, value: DateTime.new(3000,1,1) }
218 first: { avail: false, value: DateTime.new(3000,1,1) }
219 }
219 }
220 end
220 end
221
221
222 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
222 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
223 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
223 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
224 end
224 end
225
225
226 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
226 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
227 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
227 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
228 end
228 end
229
229
230 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and sub.user and
230 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and sub.user and
231 !sub.user.admin?
231 !sub.user.admin?
232 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
232 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
233 end
233 end
234
234
235 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
235 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
236 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
236 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
237 end
237 end
238 end
238 end
239
239
240 #process user_id
240 #process user_id
241 @by_lang.each do |lang,prop|
241 @by_lang.each do |lang,prop|
242 prop.each do |k,v|
242 prop.each do |k,v|
243 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
243 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
244 end
244 end
245 end
245 end
246
246
247 #sum into best
247 #sum into best
248 if @by_lang and @by_lang.first
248 if @by_lang and @by_lang.first
249 @best = @by_lang.first[1].clone
249 @best = @by_lang.first[1].clone
250 @by_lang.each do |lang,prop|
250 @by_lang.each do |lang,prop|
251 if @best[:runtime][:value] >= prop[:runtime][:value]
251 if @best[:runtime][:value] >= prop[:runtime][:value]
252 @best[:runtime] = prop[:runtime]
252 @best[:runtime] = prop[:runtime]
253 @best[:runtime][:lang] = lang
253 @best[:runtime][:lang] = lang
254 end
254 end
255 if @best[:memory][:value] >= prop[:memory][:value]
255 if @best[:memory][:value] >= prop[:memory][:value]
256 @best[:memory] = prop[:memory]
256 @best[:memory] = prop[:memory]
257 @best[:memory][:lang] = lang
257 @best[:memory][:lang] = lang
258 end
258 end
259 if @best[:length][:value] >= prop[:length][:value]
259 if @best[:length][:value] >= prop[:length][:value]
260 @best[:length] = prop[:length]
260 @best[:length] = prop[:length]
261 @best[:length][:lang] = lang
261 @best[:length][:lang] = lang
262 end
262 end
263 if @best[:first][:value] >= prop[:first][:value]
263 if @best[:first][:value] >= prop[:first][:value]
264 @best[:first] = prop[:first]
264 @best[:first] = prop[:first]
265 @best[:first][:lang] = lang
265 @best[:first][:lang] = lang
266 end
266 end
267 end
267 end
268 end
268 end
269
269
270 @histogram[:summary][:max] = [@histogram[:data].max,1].max
270 @histogram[:summary][:max] = [@histogram[:data].max,1].max
271 @summary[:attempt] = user.count
271 @summary[:attempt] = user.count
272 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
272 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
273 end
273 end
274
274
275 def stuck #report struggling user,problem
275 def stuck #report struggling user,problem
276 # init
276 # init
277 user,problem = nil
277 user,problem = nil
278 solve = true
278 solve = true
279 tries = 0
279 tries = 0
280 @struggle = Array.new
280 @struggle = Array.new
281 record = {}
281 record = {}
282 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
282 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
283 next unless sub.problem and sub.user
283 next unless sub.problem and sub.user
284 if user != sub.user_id or problem != sub.problem_id
284 if user != sub.user_id or problem != sub.problem_id
285 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
285 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
286 record = {user: sub.user, problem: sub.problem}
286 record = {user: sub.user, problem: sub.problem}
287 user,problem = sub.user_id, sub.problem_id
287 user,problem = sub.user_id, sub.problem_id
288 solve = false
288 solve = false
289 tries = 0
289 tries = 0
290 end
290 end
291 if sub.points >= sub.problem.full_score
291 if sub.points >= sub.problem.full_score
292 solve = true
292 solve = true
293 else
293 else
294 tries += 1
294 tries += 1
295 end
295 end
296 end
296 end
297 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
297 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
298 @struggle = @struggle[0..50]
298 @struggle = @struggle[0..50]
299 end
299 end
300
300
301
301
302 def multiple_login
302 def multiple_login
303 #user with multiple IP
303 #user with multiple IP
304 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
304 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
305 last,count = 0,0
305 last,count = 0,0
306 first = 0
306 first = 0
307 @users = []
307 @users = []
308 raw.each do |r|
308 raw.each do |r|
309 if last != r.user.login
309 if last != r.user.login
310 count = 1
310 count = 1
311 last = r.user.login
311 last = r.user.login
312 first = r
312 first = r
313 else
313 else
314 @users << first if count == 1
314 @users << first if count == 1
315 @users << r
315 @users << r
316 count += 1
316 count += 1
317 end
317 end
318 end
318 end
319
319
320 #IP with multiple user
320 #IP with multiple user
321 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
321 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
322 last,count = 0,0
322 last,count = 0,0
323 first = 0
323 first = 0
324 @ip = []
324 @ip = []
325 raw.each do |r|
325 raw.each do |r|
326 if last != r.ip_address
326 if last != r.ip_address
327 count = 1
327 count = 1
328 last = r.ip_address
328 last = r.ip_address
329 first = r
329 first = r
330 else
330 else
331 @ip << first if count == 1
331 @ip << first if count == 1
332 @ip << r
332 @ip << r
333 count += 1
333 count += 1
334 end
334 end
335 end
335 end
336 end
336 end
337
337
338 def cheat_report
338 def cheat_report
339 date_and_time = '%Y-%m-%d %H:%M'
339 date_and_time = '%Y-%m-%d %H:%M'
340 begin
340 begin
341 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
341 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
342 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
342 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
343 rescue
343 rescue
344 @since_time = Time.zone.now.ago( 90.minutes)
344 @since_time = Time.zone.now.ago( 90.minutes)
345 end
345 end
346 begin
346 begin
347 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
347 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
348 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
348 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
349 rescue
349 rescue
350 @until_time = Time.zone.now
350 @until_time = Time.zone.now
351 end
351 end
352
352
353 #multi login
353 #multi login
354 @ml = Login.joins(:user).where("logins.created_at >= ? and logins.created_at <= ?",@since_time,@until_time).select('users.login,count(distinct ip_address) as count,users.full_name').group("users.id").having("count > 1")
354 @ml = Login.joins(:user).where("logins.created_at >= ? and logins.created_at <= ?",@since_time,@until_time).select('users.login,count(distinct ip_address) as count,users.full_name').group("users.id").having("count > 1")
355
355
356 st = <<-SQL
356 st = <<-SQL
357 SELECT l2.*
357 SELECT l2.*
358 FROM logins l2 INNER JOIN
358 FROM logins l2 INNER JOIN
359 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
359 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
360 FROM logins l
360 FROM logins l
361 INNER JOIN users u ON l.user_id = u.id
361 INNER JOIN users u ON l.user_id = u.id
362 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
362 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
363 GROUP BY u.id
363 GROUP BY u.id
364 HAVING count > 1
364 HAVING count > 1
365 ) ml ON l2.user_id = ml.id
365 ) ml ON l2.user_id = ml.id
366 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
366 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
367 UNION
367 UNION
368 SELECT l2.*
368 SELECT l2.*
369 FROM logins l2 INNER JOIN
369 FROM logins l2 INNER JOIN
370 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
370 (SELECT l.ip_address,COUNT(DISTINCT u.id) as count
371 FROM logins l
371 FROM logins l
372 INNER JOIN users u ON l.user_id = u.id
372 INNER JOIN users u ON l.user_id = u.id
373 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
373 WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}'
374 GROUP BY l.ip_address
374 GROUP BY l.ip_address
375 HAVING count > 1
375 HAVING count > 1
376 ) ml on ml.ip_address = l2.ip_address
376 ) ml on ml.ip_address = l2.ip_address
377 INNER JOIN users u ON l2.user_id = u.id
377 INNER JOIN users u ON l2.user_id = u.id
378 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
378 WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}'
379 ORDER BY ip_address,created_at
379 ORDER BY ip_address,created_at
380 SQL
380 SQL
381 @mld = Login.find_by_sql(st)
381 @mld = Login.find_by_sql(st)
382
382
383 st = <<-SQL
383 st = <<-SQL
384 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
384 SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id
385 FROM submissions s INNER JOIN
385 FROM submissions s INNER JOIN
386 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
386 (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name
387 FROM logins l
387 FROM logins l
388 INNER JOIN users u ON l.user_id = u.id
388 INNER JOIN users u ON l.user_id = u.id
389 WHERE l.created_at >= ? and l.created_at <= ?
389 WHERE l.created_at >= ? and l.created_at <= ?
390 GROUP BY u.id
390 GROUP BY u.id
391 HAVING count > 1
391 HAVING count > 1
392 ) ml ON s.user_id = ml.id
392 ) ml ON s.user_id = ml.id
393 WHERE s.submitted_at >= ? and s.submitted_at <= ?
393 WHERE s.submitted_at >= ? and s.submitted_at <= ?
@@ -1,67 +1,67
1 class SiteController < ApplicationController
1 class SiteController < ApplicationController
2
2
3 - before_filter :site_admin_authorization, :except => 'login'
3 + before_action :site_admin_authorization, :except => 'login'
4
4
5 def login
5 def login
6 # Site administrator login
6 # Site administrator login
7 @countries = Country.includes(:sites).all
7 @countries = Country.includes(:sites).all
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
62 private
63 def site_params
63 def site_params
64 params.require(:site).permit()
64 params.require(:site).permit()
65 end
65 end
66
66
67 end
67 end
@@ -1,97 +1,97
1 class SitesController < ApplicationController
1 class SitesController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_action :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.order(:country_id)
8 @sites = Site.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(site_params)
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
91 private
92
92
93 def site_params
93 def site_params
94 params.require(:site).permit(:name,:started,:start_time,:country_id,:password)
94 params.require(:site).permit(:name,:started,:start_time,:country_id,:password)
95 end
95 end
96
96
97 end
97 end
@@ -1,75 +1,75
1 class TasksController < ApplicationController
1 class TasksController < ApplicationController
2
2
3 - before_filter :authenticate, :check_viewability
3 + before_action :authenticate, :check_viewability
4
4
5 def index
5 def index
6 redirect_to :action => 'list'
6 redirect_to :action => 'list'
7 end
7 end
8
8
9 def list
9 def list
10 @problems = @user.available_problems
10 @problems = @user.available_problems
11 end
11 end
12
12
13 # this has contest-wide access control
13 # this has contest-wide access control
14 def view
14 def view
15 base_name = params[:file]
15 base_name = params[:file]
16 base_filename = File.basename("#{base_name}.#{params[:ext]}")
16 base_filename = File.basename("#{base_name}.#{params[:ext]}")
17 filename = "#{Problem.download_file_basedir}/#{base_filename}"
17 filename = "#{Problem.download_file_basedir}/#{base_filename}"
18
18
19 if !FileTest.exists?(filename)
19 if !FileTest.exists?(filename)
20 redirect_to :action => 'index' and return
20 redirect_to :action => 'index' and return
21 end
21 end
22
22
23 send_file_to_user(filename, base_filename)
23 send_file_to_user(filename, base_filename)
24 end
24 end
25
25
26 # this has problem-level access control
26 # this has problem-level access control
27 def download
27 def download
28 problem = Problem.find(params[:id])
28 problem = Problem.find(params[:id])
29 unless @current_user.can_view_problem? problem
29 unless @current_user.can_view_problem? problem
30 redirect_to :action => 'index' and return
30 redirect_to :action => 'index' and return
31 end
31 end
32
32
33 base_name = params[:file]
33 base_name = params[:file]
34 base_filename = File.basename("#{base_name}.#{params[:ext]}")
34 base_filename = File.basename("#{base_name}.#{params[:ext]}")
35 filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
35 filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
36 puts "SENDING: #{filename}"
36 puts "SENDING: #{filename}"
37
37
38 if !FileTest.exists?(filename)
38 if !FileTest.exists?(filename)
39 redirect_to :action => 'index' and return
39 redirect_to :action => 'index' and return
40 end
40 end
41
41
42 puts "SENDING: #{filename}"
42 puts "SENDING: #{filename}"
43
43
44 send_file_to_user(filename, base_filename)
44 send_file_to_user(filename, base_filename)
45 end
45 end
46
46
47 protected
47 protected
48
48
49 def send_file_to_user(filename, base_filename)
49 def send_file_to_user(filename, base_filename)
50 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
50 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
51 response.headers['Content-Type'] = "application/force-download"
51 response.headers['Content-Type'] = "application/force-download"
52 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
52 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
53 response.headers["X-Sendfile"] = filename
53 response.headers["X-Sendfile"] = filename
54 response.headers['Content-length'] = File.size(filename)
54 response.headers['Content-length'] = File.size(filename)
55 render :nothing => true
55 render :nothing => true
56 else
56 else
57 if params[:ext]=='pdf'
57 if params[:ext]=='pdf'
58 content_type = 'application/pdf'
58 content_type = 'application/pdf'
59 else
59 else
60 content_type = 'application/octet-stream'
60 content_type = 'application/octet-stream'
61 end
61 end
62
62
63 send_file filename, :stream => false, :disposition => 'inline', :filename => base_filename, :type => content_type
63 send_file filename, :stream => false, :disposition => 'inline', :filename => base_filename, :type => content_type
64 end
64 end
65 end
65 end
66
66
67 def check_viewability
67 def check_viewability
68 @user = User.find(session[:user_id])
68 @user = User.find(session[:user_id])
69 if @user==nil or !GraderConfiguration.show_tasks_to?(@user)
69 if @user==nil or !GraderConfiguration.show_tasks_to?(@user)
70 redirect_to :controller => 'main', :action => 'list'
70 redirect_to :controller => 'main', :action => 'list'
71 return false
71 return false
72 end
72 end
73 end
73 end
74
74
75 end
75 end
@@ -1,118 +1,118
1 class TestController < ApplicationController
1 class TestController < ApplicationController
2
2
3 - before_filter :authenticate, :check_viewability
3 + before_action :authenticate, :check_viewability
4
4
5 #
5 #
6 # COMMENT OUT: filter in each action instead
6 # COMMENT OUT: filter in each action instead
7 #
7 #
8 # before_filter :verify_time_limit, :only => [:submit]
8 # before_filter :verify_time_limit, :only => [:submit]
9
9
10 verify :method => :post, :only => [:submit],
10 verify :method => :post, :only => [:submit],
11 :redirect_to => { :action => :index }
11 :redirect_to => { :action => :index }
12
12
13 def index
13 def index
14 prepare_index_information
14 prepare_index_information
15 end
15 end
16
16
17 def submit
17 def submit
18 @user = User.find(session[:user_id])
18 @user = User.find(session[:user_id])
19
19
20 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
20 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
21
21
22 if ! @submitted_test_request.errors.empty?
22 if ! @submitted_test_request.errors.empty?
23 prepare_index_information
23 prepare_index_information
24 render :action => 'index' and return
24 render :action => 'index' and return
25 end
25 end
26
26
27 if GraderConfiguration.time_limit_mode?
27 if GraderConfiguration.time_limit_mode?
28 if @user.contest_finished?
28 if @user.contest_finished?
29 @submitted_test_request.errors.add(:base,'Contest is over.')
29 @submitted_test_request.errors.add(:base,'Contest is over.')
30 prepare_index_information
30 prepare_index_information
31 render :action => 'index' and return
31 render :action => 'index' and return
32 end
32 end
33
33
34 if !GraderConfiguration.allow_test_request(@user)
34 if !GraderConfiguration.allow_test_request(@user)
35 prepare_index_information
35 prepare_index_information
36 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
36 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
37 redirect_to :action => 'index' and return
37 redirect_to :action => 'index' and return
38 end
38 end
39 end
39 end
40
40
41 if @submitted_test_request.save
41 if @submitted_test_request.save
42 redirect_to :action => 'index'
42 redirect_to :action => 'index'
43 else
43 else
44 prepare_index_information
44 prepare_index_information
45 render :action => 'index'
45 render :action => 'index'
46 end
46 end
47 end
47 end
48
48
49 def read
49 def read
50 user = User.find(session[:user_id])
50 user = User.find(session[:user_id])
51 begin
51 begin
52 test_request = TestRequest.find(params[:id])
52 test_request = TestRequest.find(params[:id])
53 rescue
53 rescue
54 test_request = nil
54 test_request = nil
55 end
55 end
56 if test_request==nil or test_request.user_id != user.id
56 if test_request==nil or test_request.user_id != user.id
57 flash[:notice] = 'Invalid output'
57 flash[:notice] = 'Invalid output'
58 redirect_to :action => 'index'
58 redirect_to :action => 'index'
59 return
59 return
60 end
60 end
61 if test_request.output_file_name!=nil
61 if test_request.output_file_name!=nil
62 data = File.open(test_request.output_file_name).read(2048)
62 data = File.open(test_request.output_file_name).read(2048)
63 if data==nil
63 if data==nil
64 data=""
64 data=""
65 end
65 end
66 send_data(data,
66 send_data(data,
67 {:filename => 'output.txt',
67 {:filename => 'output.txt',
68 :type => 'text/plain'})
68 :type => 'text/plain'})
69 return
69 return
70 end
70 end
71 redirect_to :action => 'index'
71 redirect_to :action => 'index'
72 end
72 end
73
73
74 def result
74 def result
75 @user = User.find(session[:user_id])
75 @user = User.find(session[:user_id])
76 begin
76 begin
77 @test_request = TestRequest.find(params[:id])
77 @test_request = TestRequest.find(params[:id])
78 rescue
78 rescue
79 @test_request = nil
79 @test_request = nil
80 end
80 end
81 if @test_request==nil or @test_request.user_id != @user.id
81 if @test_request==nil or @test_request.user_id != @user.id
82 flash[:notice] = 'Invalid request'
82 flash[:notice] = 'Invalid request'
83 redirect_to :action => 'index'
83 redirect_to :action => 'index'
84 return
84 return
85 end
85 end
86 end
86 end
87
87
88 protected
88 protected
89
89
90 def prepare_index_information
90 def prepare_index_information
91 @user = User.find(session[:user_id])
91 @user = User.find(session[:user_id])
92 @submissions = Submission.find_last_for_all_available_problems(@user.id)
92 @submissions = Submission.find_last_for_all_available_problems(@user.id)
93 all_problems = @submissions.collect { |submission| submission.problem }
93 all_problems = @submissions.collect { |submission| submission.problem }
94 @problems = []
94 @problems = []
95 all_problems.each do |problem|
95 all_problems.each do |problem|
96 if problem.test_allowed
96 if problem.test_allowed
97 @problems << problem
97 @problems << problem
98 end
98 end
99 end
99 end
100 @test_requests = []
100 @test_requests = []
101 @user.test_requests.each do |ts|
101 @user.test_requests.each do |ts|
102 if ts.problem and ts.problem.available
102 if ts.problem and ts.problem.available
103 @test_requests << ts
103 @test_requests << ts
104 end
104 end
105 end
105 end
106 end
106 end
107
107
108 def check_viewability
108 def check_viewability
109 user = User.find(session[:user_id])
109 user = User.find(session[:user_id])
110 if !GraderConfiguration.show_tasks_to?(user)
110 if !GraderConfiguration.show_tasks_to?(user)
111 redirect_to :controller => 'main', :action => 'list'
111 redirect_to :controller => 'main', :action => 'list'
112 end
112 end
113 if (!GraderConfiguration.show_submitbox_to?(user)) and (action_name=='submit')
113 if (!GraderConfiguration.show_submitbox_to?(user)) and (action_name=='submit')
114 redirect_to :controller => 'test', :action => 'index'
114 redirect_to :controller => 'test', :action => 'index'
115 end
115 end
116 end
116 end
117
117
118 end
118 end
@@ -1,391 +1,391
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_action :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 @users = User.all
27 @users = User.all
28 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
28 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
29 @contests = Contest.enabled
29 @contests = Contest.enabled
30 end
30 end
31
31
32 def active
32 def active
33 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
33 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
34 @users = []
34 @users = []
35 sessions.each do |session|
35 sessions.each do |session|
36 if session.data[:user_id]
36 if session.data[:user_id]
37 @users << User.find(session.data[:user_id])
37 @users << User.find(session.data[:user_id])
38 end
38 end
39 end
39 end
40 end
40 end
41
41
42 def show
42 def show
43 @user = User.find(params[:id])
43 @user = User.find(params[:id])
44 end
44 end
45
45
46 def new
46 def new
47 @user = User.new
47 @user = User.new
48 end
48 end
49
49
50 def create
50 def create
51 @user = User.new(user_params)
51 @user = User.new(user_params)
52 @user.activated = true
52 @user.activated = true
53 if @user.save
53 if @user.save
54 flash[:notice] = 'User was successfully created.'
54 flash[:notice] = 'User was successfully created.'
55 redirect_to :action => 'index'
55 redirect_to :action => 'index'
56 else
56 else
57 render :action => 'new'
57 render :action => 'new'
58 end
58 end
59 end
59 end
60
60
61 def clear_last_ip
61 def clear_last_ip
62 @user = User.find(params[:id])
62 @user = User.find(params[:id])
63 @user.last_ip = nil
63 @user.last_ip = nil
64 @user.save
64 @user.save
65 redirect_to action: 'index', page: params[:page]
65 redirect_to action: 'index', page: params[:page]
66 end
66 end
67
67
68 def create_from_list
68 def create_from_list
69 lines = params[:user_list]
69 lines = params[:user_list]
70
70
71 note = []
71 note = []
72
72
73 lines.split("\n").each do |line|
73 lines.split("\n").each do |line|
74 items = line.chomp.split(',')
74 items = line.chomp.split(',')
75 if items.length>=2
75 if items.length>=2
76 login = items[0]
76 login = items[0]
77 full_name = items[1]
77 full_name = items[1]
78 remark =''
78 remark =''
79 user_alias = ''
79 user_alias = ''
80
80
81 added_random_password = false
81 added_random_password = false
82 if items.length >= 3 and items[2].chomp(" ").length > 0;
82 if items.length >= 3 and items[2].chomp(" ").length > 0;
83 password = items[2].chomp(" ")
83 password = items[2].chomp(" ")
84 else
84 else
85 password = random_password
85 password = random_password
86 add_random_password=true;
86 add_random_password=true;
87 end
87 end
88
88
89 if items.length>= 4 and items[3].chomp(" ").length > 0;
89 if items.length>= 4 and items[3].chomp(" ").length > 0;
90 user_alias = items[3].chomp(" ")
90 user_alias = items[3].chomp(" ")
91 else
91 else
92 user_alias = login
92 user_alias = login
93 end
93 end
94
94
95 if items.length>=5
95 if items.length>=5
96 remark = items[4].strip;
96 remark = items[4].strip;
97 end
97 end
98
98
99 user = User.find_by_login(login)
99 user = User.find_by_login(login)
100 if (user)
100 if (user)
101 user.full_name = full_name
101 user.full_name = full_name
102 user.password = password
102 user.password = password
103 user.remark = remark
103 user.remark = remark
104 else
104 else
105 user = User.new({:login => login,
105 user = User.new({:login => login,
106 :full_name => full_name,
106 :full_name => full_name,
107 :password => password,
107 :password => password,
108 :password_confirmation => password,
108 :password_confirmation => password,
109 :alias => user_alias,
109 :alias => user_alias,
110 :remark => remark})
110 :remark => remark})
111 end
111 end
112 user.activated = true
112 user.activated = true
113 user.save
113 user.save
114
114
115 if added_random_password
115 if added_random_password
116 note << "'#{login}' (+)"
116 note << "'#{login}' (+)"
117 else
117 else
118 note << login
118 note << login
119 end
119 end
120 end
120 end
121 end
121 end
122 flash[:success] = 'User(s) ' + note.join(', ') +
122 flash[:success] = 'User(s) ' + note.join(', ') +
123 ' were successfully created. ' +
123 ' were successfully created. ' +
124 '( (+) - created with random passwords.)'
124 '( (+) - created with random passwords.)'
125 redirect_to :action => 'index'
125 redirect_to :action => 'index'
126 end
126 end
127
127
128 def edit
128 def edit
129 @user = User.find(params[:id])
129 @user = User.find(params[:id])
130 end
130 end
131
131
132 def update
132 def update
133 @user = User.find(params[:id])
133 @user = User.find(params[:id])
134 if @user.update_attributes(user_params)
134 if @user.update_attributes(user_params)
135 flash[:notice] = 'User was successfully updated.'
135 flash[:notice] = 'User was successfully updated.'
136 redirect_to :action => 'show', :id => @user
136 redirect_to :action => 'show', :id => @user
137 else
137 else
138 render :action => 'edit'
138 render :action => 'edit'
139 end
139 end
140 end
140 end
141
141
142 def destroy
142 def destroy
143 User.find(params[:id]).destroy
143 User.find(params[:id]).destroy
144 redirect_to :action => 'index'
144 redirect_to :action => 'index'
145 end
145 end
146
146
147 def user_stat
147 def user_stat
148 if params[:commit] == 'download csv'
148 if params[:commit] == 'download csv'
149 @problems = Problem.all
149 @problems = Problem.all
150 else
150 else
151 @problems = Problem.available_problems
151 @problems = Problem.available_problems
152 end
152 end
153 @users = User.includes(:contests, :contest_stat).where(enabled: true)
153 @users = User.includes(:contests, :contest_stat).where(enabled: true)
154 @scorearray = Array.new
154 @scorearray = Array.new
155 @users.each do |u|
155 @users.each do |u|
156 ustat = Array.new
156 ustat = Array.new
157 ustat[0] = u
157 ustat[0] = u
158 @problems.each do |p|
158 @problems.each do |p|
159 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
159 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
160 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
160 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
161 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
161 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
162 else
162 else
163 ustat << [0,false]
163 ustat << [0,false]
164 end
164 end
165 end
165 end
166 @scorearray << ustat
166 @scorearray << ustat
167 end
167 end
168 if params[:commit] == 'download csv' then
168 if params[:commit] == 'download csv' then
169 csv = gen_csv_from_scorearray(@scorearray,@problems)
169 csv = gen_csv_from_scorearray(@scorearray,@problems)
170 send_data csv, filename: 'last_score.csv'
170 send_data csv, filename: 'last_score.csv'
171 else
171 else
172 render template: 'user_admin/user_stat'
172 render template: 'user_admin/user_stat'
173 end
173 end
174 end
174 end
175
175
176 def user_stat_max
176 def user_stat_max
177 if params[:commit] == 'download csv'
177 if params[:commit] == 'download csv'
178 @problems = Problem.all
178 @problems = Problem.all
179 else
179 else
180 @problems = Problem.available_problems
180 @problems = Problem.available_problems
181 end
181 end
182 @users = User.includes(:contests).includes(:contest_stat).all
182 @users = User.includes(:contests).includes(:contest_stat).all
183 @scorearray = Array.new
183 @scorearray = Array.new
184 #set up range from param
184 #set up range from param
185 since_id = params.fetch(:since_id, 0).to_i
185 since_id = params.fetch(:since_id, 0).to_i
186 until_id = params.fetch(:until_id, 0).to_i
186 until_id = params.fetch(:until_id, 0).to_i
187 @users.each do |u|
187 @users.each do |u|
188 ustat = Array.new
188 ustat = Array.new
189 ustat[0] = u
189 ustat[0] = u
190 @problems.each do |p|
190 @problems.each do |p|
191 max_points = 0
191 max_points = 0
192 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
192 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
193 max_points = sub.points if sub and sub.points and (sub.points > max_points)
193 max_points = sub.points if sub and sub.points and (sub.points > max_points)
194 end
194 end
195 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
195 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
196 end
196 end
197 @scorearray << ustat
197 @scorearray << ustat
198 end
198 end
199
199
200 if params[:commit] == 'download csv' then
200 if params[:commit] == 'download csv' then
201 csv = gen_csv_from_scorearray(@scorearray,@problems)
201 csv = gen_csv_from_scorearray(@scorearray,@problems)
202 send_data csv, filename: 'max_score.csv'
202 send_data csv, filename: 'max_score.csv'
203 else
203 else
204 render template: 'user_admin/user_stat'
204 render template: 'user_admin/user_stat'
205 end
205 end
206 end
206 end
207
207
208 def import
208 def import
209 if params[:file]==''
209 if params[:file]==''
210 flash[:notice] = 'Error importing no file'
210 flash[:notice] = 'Error importing no file'
211 redirect_to :action => 'index' and return
211 redirect_to :action => 'index' and return
212 end
212 end
213 import_from_file(params[:file])
213 import_from_file(params[:file])
214 end
214 end
215
215
216 def random_all_passwords
216 def random_all_passwords
217 users = User.all
217 users = User.all
218 @prefix = params[:prefix] || ''
218 @prefix = params[:prefix] || ''
219 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
219 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
220 @changed = false
220 @changed = false
221 if request.request_method == 'POST'
221 if request.request_method == 'POST'
222 @non_admin_users.each do |user|
222 @non_admin_users.each do |user|
223 password = random_password
223 password = random_password
224 user.password = password
224 user.password = password
225 user.password_confirmation = password
225 user.password_confirmation = password
226 user.save
226 user.save
227 end
227 end
228 @changed = true
228 @changed = true
229 end
229 end
230 end
230 end
231
231
232
232
233 # contest management
233 # contest management
234
234
235 def contests
235 def contests
236 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
236 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
237 @contests = Contest.enabled
237 @contests = Contest.enabled
238 end
238 end
239
239
240 def assign_from_list
240 def assign_from_list
241 contest_id = params[:users_contest_id]
241 contest_id = params[:users_contest_id]
242 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
242 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
243 contest = Contest.find(params[:new_contest][:id])
243 contest = Contest.find(params[:new_contest][:id])
244 if !contest
244 if !contest
245 flash[:notice] = 'Error: no contest'
245 flash[:notice] = 'Error: no contest'
246 redirect_to :action => 'contests', :id =>contest_id
246 redirect_to :action => 'contests', :id =>contest_id
247 end
247 end
248
248
249 note = []
249 note = []
250 users.each do |u|
250 users.each do |u|
251 u.contests = [contest]
251 u.contests = [contest]
252 note << u.login
252 note << u.login
253 end
253 end
254 flash[:notice] = 'User(s) ' + note.join(', ') +
254 flash[:notice] = 'User(s) ' + note.join(', ') +
255 " were successfully reassigned to #{contest.title}."
255 " were successfully reassigned to #{contest.title}."
256 redirect_to :action => 'contests', :id =>contest.id
256 redirect_to :action => 'contests', :id =>contest.id
257 end
257 end
258
258
259 def add_to_contest
259 def add_to_contest
260 user = User.find(params[:id])
260 user = User.find(params[:id])
261 contest = Contest.find(params[:contest_id])
261 contest = Contest.find(params[:contest_id])
262 if user and contest
262 if user and contest
263 user.contests << contest
263 user.contests << contest
264 end
264 end
265 redirect_to :action => 'index'
265 redirect_to :action => 'index'
266 end
266 end
267
267
268 def remove_from_contest
268 def remove_from_contest
269 user = User.find(params[:id])
269 user = User.find(params[:id])
270 contest = Contest.find(params[:contest_id])
270 contest = Contest.find(params[:contest_id])
271 if user and contest
271 if user and contest
272 user.contests.delete(contest)
272 user.contests.delete(contest)
273 end
273 end
274 redirect_to :action => 'index'
274 redirect_to :action => 'index'
275 end
275 end
276
276
277 def contest_management
277 def contest_management
278 end
278 end
279
279
280 def manage_contest
280 def manage_contest
281 contest = Contest.find(params[:contest][:id])
281 contest = Contest.find(params[:contest][:id])
282 if !contest
282 if !contest
283 flash[:notice] = 'You did not choose the contest.'
283 flash[:notice] = 'You did not choose the contest.'
284 redirect_to :action => 'contest_management' and return
284 redirect_to :action => 'contest_management' and return
285 end
285 end
286
286
287 operation = params[:operation]
287 operation = params[:operation]
288
288
289 if not ['add','remove','assign'].include? operation
289 if not ['add','remove','assign'].include? operation
290 flash[:notice] = 'You did not choose the operation to perform.'
290 flash[:notice] = 'You did not choose the operation to perform.'
291 redirect_to :action => 'contest_management' and return
291 redirect_to :action => 'contest_management' and return
292 end
292 end
293
293
294 lines = params[:login_list]
294 lines = params[:login_list]
295 if !lines or lines.blank?
295 if !lines or lines.blank?
296 flash[:notice] = 'You entered an empty list.'
296 flash[:notice] = 'You entered an empty list.'
297 redirect_to :action => 'contest_management' and return
297 redirect_to :action => 'contest_management' and return
298 end
298 end
299
299
300 note = []
300 note = []
301 users = []
301 users = []
302 lines.split("\n").each do |line|
302 lines.split("\n").each do |line|
303 user = User.find_by_login(line.chomp)
303 user = User.find_by_login(line.chomp)
304 if user
304 if user
305 if operation=='add'
305 if operation=='add'
306 if ! user.contests.include? contest
306 if ! user.contests.include? contest
307 user.contests << contest
307 user.contests << contest
308 end
308 end
309 elsif operation=='remove'
309 elsif operation=='remove'
310 user.contests.delete(contest)
310 user.contests.delete(contest)
311 else
311 else
312 user.contests = [contest]
312 user.contests = [contest]
313 end
313 end
314
314
315 if params[:reset_timer]
315 if params[:reset_timer]
316 user.contest_stat.forced_logout = true
316 user.contest_stat.forced_logout = true
317 user.contest_stat.reset_timer_and_save
317 user.contest_stat.reset_timer_and_save
318 end
318 end
319
319
320 if params[:notification_emails]
320 if params[:notification_emails]
321 send_contest_update_notification_email(user, contest)
321 send_contest_update_notification_email(user, contest)
322 end
322 end
323
323
324 note << user.login
324 note << user.login
325 users << user
325 users << user
326 end
326 end
327 end
327 end
328
328
329 if params[:reset_timer]
329 if params[:reset_timer]
330 logout_users(users)
330 logout_users(users)
331 end
331 end
332
332
333 flash[:notice] = 'User(s) ' + note.join(', ') +
333 flash[:notice] = 'User(s) ' + note.join(', ') +
334 ' were successfully modified. '
334 ' were successfully modified. '
335 redirect_to :action => 'contest_management'
335 redirect_to :action => 'contest_management'
336 end
336 end
337
337
338 # admin management
338 # admin management
339
339
340 def admin
340 def admin
341 @admins = User.all.find_all {|user| user.admin? }
341 @admins = User.all.find_all {|user| user.admin? }
342 end
342 end
343
343
344 def grant_admin
344 def grant_admin
345 login = params[:login]
345 login = params[:login]
346 user = User.find_by_login(login)
346 user = User.find_by_login(login)
347 if user!=nil
347 if user!=nil
348 admin_role = Role.find_by_name('admin')
348 admin_role = Role.find_by_name('admin')
349 user.roles << admin_role
349 user.roles << admin_role
350 else
350 else
351 flash[:notice] = 'Unknown user'
351 flash[:notice] = 'Unknown user'
352 end
352 end
353 flash[:notice] = 'User added as admins'
353 flash[:notice] = 'User added as admins'
354 redirect_to :action => 'admin'
354 redirect_to :action => 'admin'
355 end
355 end
356
356
357 def revoke_admin
357 def revoke_admin
358 user = User.find(params[:id])
358 user = User.find(params[:id])
359 if user==nil
359 if user==nil
360 flash[:notice] = 'Unknown user'
360 flash[:notice] = 'Unknown user'
361 redirect_to :action => 'admin' and return
361 redirect_to :action => 'admin' and return
362 elsif user.login == 'root'
362 elsif user.login == 'root'
363 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
363 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
364 redirect_to :action => 'admin' and return
364 redirect_to :action => 'admin' and return
365 end
365 end
366
366
367 admin_role = Role.find_by_name('admin')
367 admin_role = Role.find_by_name('admin')
368 user.roles.delete(admin_role)
368 user.roles.delete(admin_role)
369 flash[:notice] = 'User permission revoked'
369 flash[:notice] = 'User permission revoked'
370 redirect_to :action => 'admin'
370 redirect_to :action => 'admin'
371 end
371 end
372
372
373 # mass mailing
373 # mass mailing
374
374
375 def mass_mailing
375 def mass_mailing
376 end
376 end
377
377
378 def bulk_mail
378 def bulk_mail
379 lines = params[:login_list]
379 lines = params[:login_list]
380 if !lines or lines.blank?
380 if !lines or lines.blank?
381 flash[:notice] = 'You entered an empty list.'
381 flash[:notice] = 'You entered an empty list.'
382 redirect_to :action => 'mass_mailing' and return
382 redirect_to :action => 'mass_mailing' and return
383 end
383 end
384
384
385 mail_subject = params[:subject]
385 mail_subject = params[:subject]
386 if !mail_subject or mail_subject.blank?
386 if !mail_subject or mail_subject.blank?
387 flash[:notice] = 'You entered an empty mail subject.'
387 flash[:notice] = 'You entered an empty mail subject.'
388 redirect_to :action => 'mass_mailing' and return
388 redirect_to :action => 'mass_mailing' and return
389 end
389 end
390
390
391 mail_body = params[:email_body]
391 mail_body = params[:email_body]
@@ -1,222 +1,222
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_action :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_action :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_action :authenticate, :profile_authorization, only: [:profile]
18
18
19 - before_filter :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
19 + before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
20
20
21
21
22 verify :method => :post, :only => [:chg_passwd],
22 verify :method => :post, :only => [:chg_passwd],
23 :redirect_to => { :action => :index }
23 :redirect_to => { :action => :index }
24
24
25 #in_place_edit_for :user, :alias_for_editing
25 #in_place_edit_for :user, :alias_for_editing
26 #in_place_edit_for :user, :email_for_editing
26 #in_place_edit_for :user, :email_for_editing
27
27
28 def index
28 def index
29 if !GraderConfiguration['system.user_setting_enabled']
29 if !GraderConfiguration['system.user_setting_enabled']
30 redirect_to :controller => 'main', :action => 'list'
30 redirect_to :controller => 'main', :action => 'list'
31 else
31 else
32 @user = User.find(session[:user_id])
32 @user = User.find(session[:user_id])
33 end
33 end
34 end
34 end
35
35
36 def chg_passwd
36 def chg_passwd
37 user = User.find(session[:user_id])
37 user = User.find(session[:user_id])
38 user.password = params[:passwd]
38 user.password = params[:passwd]
39 user.password_confirmation = params[:passwd_verify]
39 user.password_confirmation = params[:passwd_verify]
40 if user.save
40 if user.save
41 flash[:notice] = 'password changed'
41 flash[:notice] = 'password changed'
42 else
42 else
43 flash[:notice] = 'Error: password changing failed'
43 flash[:notice] = 'Error: password changing failed'
44 end
44 end
45 redirect_to :action => 'index'
45 redirect_to :action => 'index'
46 end
46 end
47
47
48 def new
48 def new
49 @user = User.new
49 @user = User.new
50 render :action => 'new', :layout => 'empty'
50 render :action => 'new', :layout => 'empty'
51 end
51 end
52
52
53 def register
53 def register
54 if(params[:cancel])
54 if(params[:cancel])
55 redirect_to :controller => 'main', :action => 'login'
55 redirect_to :controller => 'main', :action => 'login'
56 return
56 return
57 end
57 end
58 @user = User.new(user_params)
58 @user = User.new(user_params)
59 @user.password_confirmation = @user.password = User.random_password
59 @user.password_confirmation = @user.password = User.random_password
60 @user.activated = false
60 @user.activated = false
61 if (@user.valid?) and (@user.save)
61 if (@user.valid?) and (@user.save)
62 if send_confirmation_email(@user)
62 if send_confirmation_email(@user)
63 render :action => 'new_splash', :layout => 'empty'
63 render :action => 'new_splash', :layout => 'empty'
64 else
64 else
65 @admin_email = GraderConfiguration['system.admin_email']
65 @admin_email = GraderConfiguration['system.admin_email']
66 render :action => 'email_error', :layout => 'empty'
66 render :action => 'email_error', :layout => 'empty'
67 end
67 end
68 else
68 else
69 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
69 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
70 render :action => 'new', :layout => 'empty'
70 render :action => 'new', :layout => 'empty'
71 end
71 end
72 end
72 end
73
73
74 def confirm
74 def confirm
75 login = params[:login]
75 login = params[:login]
76 key = params[:activation]
76 key = params[:activation]
77 @user = User.find_by_login(login)
77 @user = User.find_by_login(login)
78 if (@user) and (@user.verify_activation_key(key))
78 if (@user) and (@user.verify_activation_key(key))
79 if @user.valid? # check uniquenss of email
79 if @user.valid? # check uniquenss of email
80 @user.activated = true
80 @user.activated = true
81 @user.save
81 @user.save
82 @result = :successful
82 @result = :successful
83 else
83 else
84 @result = :email_used
84 @result = :email_used
85 end
85 end
86 else
86 else
87 @result = :failed
87 @result = :failed
88 end
88 end
89 render :action => 'confirm', :layout => 'empty'
89 render :action => 'confirm', :layout => 'empty'
90 end
90 end
91
91
92 def forget
92 def forget
93 render :action => 'forget', :layout => 'empty'
93 render :action => 'forget', :layout => 'empty'
94 end
94 end
95
95
96 def retrieve_password
96 def retrieve_password
97 email = params[:email]
97 email = params[:email]
98 user = User.find_by_email(email)
98 user = User.find_by_email(email)
99 if user
99 if user
100 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
100 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
101 if last_updated_time > Time.now.gmtime - 5.minutes
101 if last_updated_time > Time.now.gmtime - 5.minutes
102 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
102 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
103 else
103 else
104 user.password = user.password_confirmation = User.random_password
104 user.password = user.password_confirmation = User.random_password
105 user.save
105 user.save
106 send_new_password_email(user)
106 send_new_password_email(user)
107 flash[:notice] = 'New password has been mailed to you.'
107 flash[:notice] = 'New password has been mailed to you.'
108 end
108 end
109 else
109 else
110 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
110 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
111 end
111 end
112 redirect_to :action => 'forget'
112 redirect_to :action => 'forget'
113 end
113 end
114
114
115 def stat
115 def stat
116 @user = User.find(params[:id])
116 @user = User.find(params[:id])
117 @submission = Submission.joins(:problem).where(user_id: params[:id])
117 @submission = Submission.joins(:problem).where(user_id: params[:id])
118 @submission = @submission.where('problems.available = true') unless current_user.admin?
118 @submission = @submission.where('problems.available = true') unless current_user.admin?
119
119
120 range = 120
120 range = 120
121 @histogram = { data: Array.new(range,0), summary: {} }
121 @histogram = { data: Array.new(range,0), summary: {} }
122 @summary = {count: 0, solve: 0, attempt: 0}
122 @summary = {count: 0, solve: 0, attempt: 0}
123 problem = Hash.new(0)
123 problem = Hash.new(0)
124
124
125 @submission.find_each do |sub|
125 @submission.find_each do |sub|
126 #histogram
126 #histogram
127 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
127 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
128 @histogram[:data][d.to_i] += 1 if d < range
128 @histogram[:data][d.to_i] += 1 if d < range
129
129
130 @summary[:count] += 1
130 @summary[:count] += 1
131 next unless sub.problem
131 next unless sub.problem
132 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
132 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
133 end
133 end
134
134
135 @histogram[:summary][:max] = [@histogram[:data].max,1].max
135 @histogram[:summary][:max] = [@histogram[:data].max,1].max
136 @summary[:attempt] = problem.count
136 @summary[:attempt] = problem.count
137 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
137 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
138 end
138 end
139
139
140 def toggle_activate
140 def toggle_activate
141 @user = User.find(params[:id])
141 @user = User.find(params[:id])
142 @user.update_attributes( activated: !@user.activated? )
142 @user.update_attributes( activated: !@user.activated? )
143 respond_to do |format|
143 respond_to do |format|
144 format.js { render partial: 'toggle_button',
144 format.js { render partial: 'toggle_button',
145 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
145 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
146 end
146 end
147 end
147 end
148
148
149 def toggle_enable
149 def toggle_enable
150 @user = User.find(params[:id])
150 @user = User.find(params[:id])
151 @user.update_attributes( enabled: !@user.enabled? )
151 @user.update_attributes( enabled: !@user.enabled? )
152 respond_to do |format|
152 respond_to do |format|
153 format.js { render partial: 'toggle_button',
153 format.js { render partial: 'toggle_button',
154 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
154 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
155 end
155 end
156 end
156 end
157
157
158 protected
158 protected
159
159
160 def verify_online_registration
160 def verify_online_registration
161 if !GraderConfiguration['system.online_registration']
161 if !GraderConfiguration['system.online_registration']
162 redirect_to :controller => 'main', :action => 'login'
162 redirect_to :controller => 'main', :action => 'login'
163 end
163 end
164 end
164 end
165
165
166 def send_confirmation_email(user)
166 def send_confirmation_email(user)
167 contest_name = GraderConfiguration['contest.name']
167 contest_name = GraderConfiguration['contest.name']
168 activation_url = url_for(:action => 'confirm',
168 activation_url = url_for(:action => 'confirm',
169 :login => user.login,
169 :login => user.login,
170 :activation => user.activation_key)
170 :activation => user.activation_key)
171 home_url = url_for(:controller => 'main', :action => 'index')
171 home_url = url_for(:controller => 'main', :action => 'index')
172 mail_subject = "[#{contest_name}] Confirmation"
172 mail_subject = "[#{contest_name}] Confirmation"
173 mail_body = t('registration.email_body', {
173 mail_body = t('registration.email_body', {
174 :full_name => user.full_name,
174 :full_name => user.full_name,
175 :contest_name => contest_name,
175 :contest_name => contest_name,
176 :login => user.login,
176 :login => user.login,
177 :password => user.password,
177 :password => user.password,
178 :activation_url => activation_url,
178 :activation_url => activation_url,
179 :admin_email => GraderConfiguration['system.admin_email']
179 :admin_email => GraderConfiguration['system.admin_email']
180 })
180 })
181
181
182 logger.info mail_body
182 logger.info mail_body
183
183
184 send_mail(user.email, mail_subject, mail_body)
184 send_mail(user.email, mail_subject, mail_body)
185 end
185 end
186
186
187 def send_new_password_email(user)
187 def send_new_password_email(user)
188 contest_name = GraderConfiguration['contest.name']
188 contest_name = GraderConfiguration['contest.name']
189 mail_subject = "[#{contest_name}] Password recovery"
189 mail_subject = "[#{contest_name}] Password recovery"
190 mail_body = t('registration.password_retrieval.email_body', {
190 mail_body = t('registration.password_retrieval.email_body', {
191 :full_name => user.full_name,
191 :full_name => user.full_name,
192 :contest_name => contest_name,
192 :contest_name => contest_name,
193 :login => user.login,
193 :login => user.login,
194 :password => user.password,
194 :password => user.password,
195 :admin_email => GraderConfiguration['system.admin_email']
195 :admin_email => GraderConfiguration['system.admin_email']
196 })
196 })
197
197
198 logger.info mail_body
198 logger.info mail_body
199
199
200 send_mail(user.email, mail_subject, mail_body)
200 send_mail(user.email, mail_subject, mail_body)
201 end
201 end
202
202
203 # allow viewing of regular user profile only when options allow so
203 # allow viewing of regular user profile only when options allow so
204 # only admins can view admins profile
204 # only admins can view admins profile
205 def profile_authorization
205 def profile_authorization
206 #if view admins' profile, allow only admin
206 #if view admins' profile, allow only admin
207 return false unless(params[:id])
207 return false unless(params[:id])
208 user = User.find(params[:id])
208 user = User.find(params[:id])
209 return false unless user
209 return false unless user
210 return admin_authorization if user.admin?
210 return admin_authorization if user.admin?
211 return true if GraderConfiguration["right.user_view_submission"]
211 return true if GraderConfiguration["right.user_view_submission"]
212
212
213 #finally, we allow only admin
213 #finally, we allow only admin
214 admin_authorization
214 admin_authorization
215 end
215 end
216
216
217 private
217 private
218 def user_params
218 def user_params
219 params.require(:user).permit(:login, :full_name, :email)
219 params.require(:user).permit(:login, :full_name, :email)
220 end
220 end
221
221
222 end
222 end
@@ -1,114 +1,115
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 resources :tags
2 resources :tags
3 get "sources/direct_edit"
3 get "sources/direct_edit"
4
4
5 root :to => 'main#login'
5 root :to => 'main#login'
6
6
7 #logins
7 #logins
8 - get 'login/login', to: 'login#login'
8 + match 'login/login', to: 'login#login', via: [:get,:post]
9 +
9
10
10 resources :contests
11 resources :contests
11
12
12 resources :sites
13 resources :sites
13
14
14 resources :announcements do
15 resources :announcements do
15 member do
16 member do
16 get 'toggle','toggle_front'
17 get 'toggle','toggle_front'
17 end
18 end
18 end
19 end
19
20
20 resources :problems do
21 resources :problems do
21 member do
22 member do
22 get 'toggle'
23 get 'toggle'
23 get 'toggle_test'
24 get 'toggle_test'
24 get 'toggle_view_testcase'
25 get 'toggle_view_testcase'
25 get 'stat'
26 get 'stat'
26 end
27 end
27 collection do
28 collection do
28 get 'turn_all_off'
29 get 'turn_all_off'
29 get 'turn_all_on'
30 get 'turn_all_on'
30 get 'import'
31 get 'import'
31 get 'manage'
32 get 'manage'
32 end
33 end
33 end
34 end
34
35
35 resources :groups do
36 resources :groups do
36 member do
37 member do
37 post 'add_user', to: 'groups#add_user', as: 'add_user'
38 post 'add_user', to: 'groups#add_user', as: 'add_user'
38 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
39 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
39 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
40 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
40 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
41 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
41 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
42 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
42 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
43 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
43 end
44 end
44 collection do
45 collection do
45
46
46 end
47 end
47 end
48 end
48
49
49 resources :testcases, only: [] do
50 resources :testcases, only: [] do
50 member do
51 member do
51 get 'download_input'
52 get 'download_input'
52 get 'download_sol'
53 get 'download_sol'
53 end
54 end
54 collection do
55 collection do
55 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
56 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
56 end
57 end
57 end
58 end
58
59
59 resources :grader_configuration, controller: 'configurations'
60 resources :grader_configuration, controller: 'configurations'
60
61
61 resources :users do
62 resources :users do
62 member do
63 member do
63 get 'toggle_activate', 'toggle_enable'
64 get 'toggle_activate', 'toggle_enable'
64 get 'stat'
65 get 'stat'
65 end
66 end
66 end
67 end
67
68
68 resources :submissions do
69 resources :submissions do
69 member do
70 member do
70 get 'download'
71 get 'download'
71 get 'compiler_msg'
72 get 'compiler_msg'
72 get 'rejudge'
73 get 'rejudge'
73 end
74 end
74 collection do
75 collection do
75 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
76 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
76 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
77 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
77 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
78 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
78 end
79 end
79 end
80 end
80
81
81
82
82
83
83 #main
84 #main
84 get "main/list"
85 get "main/list"
85 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
86 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
86
87
87 #user admin
88 #user admin
88 get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
89 get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
89 post 'user_admin', to: 'user_admin#create'
90 post 'user_admin', to: 'user_admin#create'
90 delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
91 delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
91
92
92 #report
93 #report
93 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
94 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
94 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
95 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
95 get "report/login"
96 get "report/login"
96 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
97 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
97 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
98 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
98
99
99
100
100 #
101 #
101 get 'tasks/view/:file.:ext' => 'tasks#view'
102 get 'tasks/view/:file.:ext' => 'tasks#view'
102 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
103 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
103 get 'heartbeat/:id/edit' => 'heartbeat#edit'
104 get 'heartbeat/:id/edit' => 'heartbeat#edit'
104
105
105 #grader
106 #grader
106 get 'graders/list', to: 'graders#list', as: 'grader_list'
107 get 'graders/list', to: 'graders#list', as: 'grader_list'
107
108
108
109
109 # See how all your routes lay out with "rake routes"
110 # See how all your routes lay out with "rake routes"
110
111
111 # This is a legacy wild controller route that's not recommended for RESTful applications.
112 # This is a legacy wild controller route that's not recommended for RESTful applications.
112 # Note: This route will make all actions in every controller accessible via GET requests.
113 # Note: This route will make all actions in every controller accessible via GET requests.
113 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
114 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
114 end
115 end
@@ -1,40 +1,40
1 require 'test_helper'
1 require 'test_helper'
2
2
3 class LoginTest < ActionDispatch::IntegrationTest
3 class LoginTest < ActionDispatch::IntegrationTest
4 # test "the truth" do
4 # test "the truth" do
5 # assert true
5 # assert true
6 # end
6 # end
7
7
8 test "login with invalid information" do
8 test "login with invalid information" do
9 get root_path
9 get root_path
10 assert_response :success
10 assert_response :success
11 - post login_login_path, login: "root", password: "hahaha"
11 + post login_login_path, params: {login: "root", password: "hahaha"}
12 assert_redirected_to root_path
12 assert_redirected_to root_path
13 end
13 end
14
14
15 test "normal user login" do
15 test "normal user login" do
16 get root_path
16 get root_path
17 assert_response :success
17 assert_response :success
18 - post login_login_path, {login: "john", password: "hello" }
18 + post login_login_path, params: {login: "john", password: "hello" }
19 assert_redirected_to main_list_path
19 assert_redirected_to main_list_path
20 end
20 end
21
21
22 test "normal user login in single_user mode" do
22 test "normal user login in single_user mode" do
23 GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
23 GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
24 GraderConfiguration.reload
24 GraderConfiguration.reload
25 get root_path
25 get root_path
26 assert_response :success
26 assert_response :success
27 - post login_login_path, {login: "john", password: "hello" }
27 + post login_login_path, params: {login: "john", password: "hello" }
28 follow_redirect!
28 follow_redirect!
29 assert_redirected_to root_path
29 assert_redirected_to root_path
30 end
30 end
31
31
32 test "root login in in single_user mode" do
32 test "root login in in single_user mode" do
33 GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
33 GraderConfiguration.find_by(key: GraderConfiguration::SINGLE_USER_KEY).update_attributes(value: 'true')
34 GraderConfiguration.reload
34 GraderConfiguration.reload
35 get root_path
35 get root_path
36 assert_response :success
36 assert_response :success
37 - post login_login_path, {login: "admin", password: "admin" }
37 + post login_login_path, params: {login: "admin", password: "admin" }
38 assert_redirected_to main_list_path
38 assert_redirected_to main_list_path
39 end
39 end
40 end
40 end
You need to be logged in to leave comments. Login now