Description:
more test and clean up authorization
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r756:aa79958f6521 - - 13 files changed: 53 inserted, 38 deleted

@@ -1,337 +1,356
1 GEM
1 GEM
2 remote: https://rubygems.org/
2 remote: https://rubygems.org/
3 specs:
3 specs:
4 RubyInline (3.12.4)
4 RubyInline (3.12.4)
5 ZenTest (~> 4.3)
5 ZenTest (~> 4.3)
6 ZenTest (4.11.2)
6 ZenTest (4.11.2)
7 ace-rails-ap (4.2)
7 ace-rails-ap (4.2)
8 actioncable (5.2.3)
8 actioncable (5.2.3)
9 actionpack (= 5.2.3)
9 actionpack (= 5.2.3)
10 nio4r (~> 2.0)
10 nio4r (~> 2.0)
11 websocket-driver (>= 0.6.1)
11 websocket-driver (>= 0.6.1)
12 actionmailer (5.2.3)
12 actionmailer (5.2.3)
13 actionpack (= 5.2.3)
13 actionpack (= 5.2.3)
14 actionview (= 5.2.3)
14 actionview (= 5.2.3)
15 activejob (= 5.2.3)
15 activejob (= 5.2.3)
16 mail (~> 2.5, >= 2.5.4)
16 mail (~> 2.5, >= 2.5.4)
17 rails-dom-testing (~> 2.0)
17 rails-dom-testing (~> 2.0)
18 actionpack (5.2.3)
18 actionpack (5.2.3)
19 actionview (= 5.2.3)
19 actionview (= 5.2.3)
20 activesupport (= 5.2.3)
20 activesupport (= 5.2.3)
21 rack (~> 2.0)
21 rack (~> 2.0)
22 rack-test (>= 0.6.3)
22 rack-test (>= 0.6.3)
23 rails-dom-testing (~> 2.0)
23 rails-dom-testing (~> 2.0)
24 rails-html-sanitizer (~> 1.0, >= 1.0.2)
24 rails-html-sanitizer (~> 1.0, >= 1.0.2)
25 actionview (5.2.3)
25 actionview (5.2.3)
26 activesupport (= 5.2.3)
26 activesupport (= 5.2.3)
27 builder (~> 3.1)
27 builder (~> 3.1)
28 erubi (~> 1.4)
28 erubi (~> 1.4)
29 rails-dom-testing (~> 2.0)
29 rails-dom-testing (~> 2.0)
30 rails-html-sanitizer (~> 1.0, >= 1.0.3)
30 rails-html-sanitizer (~> 1.0, >= 1.0.3)
31 activejob (5.2.3)
31 activejob (5.2.3)
32 activesupport (= 5.2.3)
32 activesupport (= 5.2.3)
33 globalid (>= 0.3.6)
33 globalid (>= 0.3.6)
34 activemodel (5.2.3)
34 activemodel (5.2.3)
35 activesupport (= 5.2.3)
35 activesupport (= 5.2.3)
36 activerecord (5.2.3)
36 activerecord (5.2.3)
37 activemodel (= 5.2.3)
37 activemodel (= 5.2.3)
38 activesupport (= 5.2.3)
38 activesupport (= 5.2.3)
39 arel (>= 9.0)
39 arel (>= 9.0)
40 activerecord-session_store (1.1.3)
40 activerecord-session_store (1.1.3)
41 actionpack (>= 4.0)
41 actionpack (>= 4.0)
42 activerecord (>= 4.0)
42 activerecord (>= 4.0)
43 multi_json (~> 1.11, >= 1.11.2)
43 multi_json (~> 1.11, >= 1.11.2)
44 rack (>= 1.5.2, < 3)
44 rack (>= 1.5.2, < 3)
45 railties (>= 4.0)
45 railties (>= 4.0)
46 activestorage (5.2.3)
46 activestorage (5.2.3)
47 actionpack (= 5.2.3)
47 actionpack (= 5.2.3)
48 activerecord (= 5.2.3)
48 activerecord (= 5.2.3)
49 marcel (~> 0.3.1)
49 marcel (~> 0.3.1)
50 activesupport (5.2.3)
50 activesupport (5.2.3)
51 concurrent-ruby (~> 1.0, >= 1.0.2)
51 concurrent-ruby (~> 1.0, >= 1.0.2)
52 i18n (>= 0.7, < 2)
52 i18n (>= 0.7, < 2)
53 minitest (~> 5.1)
53 minitest (~> 5.1)
54 tzinfo (~> 1.1)
54 tzinfo (~> 1.1)
55 addressable (2.6.0)
55 addressable (2.6.0)
56 public_suffix (>= 2.0.2, < 4.0)
56 public_suffix (>= 2.0.2, < 4.0)
57 ansi (1.5.0)
57 ansi (1.5.0)
58 arel (9.0.0)
58 arel (9.0.0)
59 autoprefixer-rails (9.5.1.1)
59 autoprefixer-rails (9.5.1.1)
60 execjs
60 execjs
61 best_in_place (3.0.3)
61 best_in_place (3.0.3)
62 actionpack (>= 3.2)
62 actionpack (>= 3.2)
63 railties (>= 3.2)
63 railties (>= 3.2)
64 bindex (0.7.0)
64 bindex (0.7.0)
65 bootsnap (1.4.4)
65 bootsnap (1.4.4)
66 msgpack (~> 1.0)
66 msgpack (~> 1.0)
67 bootstrap-datepicker-rails (1.8.0.1)
67 bootstrap-datepicker-rails (1.8.0.1)
68 railties (>= 3.0)
68 railties (>= 3.0)
69 bootstrap-sass (3.4.1)
69 bootstrap-sass (3.4.1)
70 autoprefixer-rails (>= 5.2.1)
70 autoprefixer-rails (>= 5.2.1)
71 sassc (>= 2.0.0)
71 sassc (>= 2.0.0)
72 bootstrap-switch-rails (3.3.4)
72 bootstrap-switch-rails (3.3.4)
73 bootstrap-toggle-rails (2.2.1.0)
73 bootstrap-toggle-rails (2.2.1.0)
74 bootstrap3-datetimepicker-rails (4.17.47)
74 bootstrap3-datetimepicker-rails (4.17.47)
75 momentjs-rails (>= 2.8.1)
75 momentjs-rails (>= 2.8.1)
76 builder (3.2.3)
76 builder (3.2.3)
77 byebug (11.0.1)
77 byebug (11.0.1)
78 capybara (3.25.0)
78 capybara (3.25.0)
79 addressable
79 addressable
80 mini_mime (>= 0.1.3)
80 mini_mime (>= 0.1.3)
81 nokogiri (~> 1.8)
81 nokogiri (~> 1.8)
82 rack (>= 1.6.0)
82 rack (>= 1.6.0)
83 rack-test (>= 0.6.3)
83 rack-test (>= 0.6.3)
84 regexp_parser (~> 1.5)
84 regexp_parser (~> 1.5)
85 xpath (~> 3.2)
85 xpath (~> 3.2)
86 childprocess (1.0.1)
86 childprocess (1.0.1)
87 rake (< 13.0)
87 rake (< 13.0)
88 coffee-rails (4.2.2)
88 coffee-rails (4.2.2)
89 coffee-script (>= 2.2.0)
89 coffee-script (>= 2.2.0)
90 railties (>= 4.0.0)
90 railties (>= 4.0.0)
91 coffee-script (2.4.1)
91 coffee-script (2.4.1)
92 coffee-script-source
92 coffee-script-source
93 execjs
93 execjs
94 coffee-script-source (1.12.2)
94 coffee-script-source (1.12.2)
95 concurrent-ruby (1.1.5)
95 concurrent-ruby (1.1.5)
96 crass (1.0.4)
96 crass (1.0.4)
97 + diff-lcs (1.3)
97 dynamic_form (1.1.4)
98 dynamic_form (1.1.4)
98 erubi (1.8.0)
99 erubi (1.8.0)
99 erubis (2.7.0)
100 erubis (2.7.0)
100 execjs (2.7.0)
101 execjs (2.7.0)
101 ffi (1.11.1)
102 ffi (1.11.1)
102 fuzzy-string-match (1.0.1)
103 fuzzy-string-match (1.0.1)
103 RubyInline (>= 3.8.6)
104 RubyInline (>= 3.8.6)
104 globalid (0.4.2)
105 globalid (0.4.2)
105 activesupport (>= 4.2.0)
106 activesupport (>= 4.2.0)
106 haml (5.1.0)
107 haml (5.1.0)
107 temple (>= 0.8.0)
108 temple (>= 0.8.0)
108 tilt
109 tilt
109 haml-rails (1.0.0)
110 haml-rails (1.0.0)
110 actionpack (>= 4.0.1)
111 actionpack (>= 4.0.1)
111 activesupport (>= 4.0.1)
112 activesupport (>= 4.0.1)
112 haml (>= 4.0.6, < 6.0)
113 haml (>= 4.0.6, < 6.0)
113 html2haml (>= 1.0.1)
114 html2haml (>= 1.0.1)
114 railties (>= 4.0.1)
115 railties (>= 4.0.1)
115 html2haml (2.2.0)
116 html2haml (2.2.0)
116 erubis (~> 2.7.0)
117 erubis (~> 2.7.0)
117 haml (>= 4.0, < 6)
118 haml (>= 4.0, < 6)
118 nokogiri (>= 1.6.0)
119 nokogiri (>= 1.6.0)
119 ruby_parser (~> 3.5)
120 ruby_parser (~> 3.5)
120 i18n (1.6.0)
121 i18n (1.6.0)
121 concurrent-ruby (~> 1.0)
122 concurrent-ruby (~> 1.0)
122 in_place_editing (1.2.0)
123 in_place_editing (1.2.0)
123 jbuilder (2.9.1)
124 jbuilder (2.9.1)
124 activesupport (>= 4.2.0)
125 activesupport (>= 4.2.0)
125 jquery-countdown-rails (2.0.2)
126 jquery-countdown-rails (2.0.2)
126 jquery-datatables-rails (3.4.0)
127 jquery-datatables-rails (3.4.0)
127 actionpack (>= 3.1)
128 actionpack (>= 3.1)
128 jquery-rails
129 jquery-rails
129 railties (>= 3.1)
130 railties (>= 3.1)
130 sass-rails
131 sass-rails
131 jquery-rails (4.3.3)
132 jquery-rails (4.3.3)
132 rails-dom-testing (>= 1, < 3)
133 rails-dom-testing (>= 1, < 3)
133 railties (>= 4.2.0)
134 railties (>= 4.2.0)
134 thor (>= 0.14, < 2.0)
135 thor (>= 0.14, < 2.0)
135 jquery-tablesorter (1.26.1)
136 jquery-tablesorter (1.26.1)
136 railties (>= 3.2, < 6)
137 railties (>= 3.2, < 6)
137 jquery-timepicker-addon-rails (1.4.1)
138 jquery-timepicker-addon-rails (1.4.1)
138 railties (>= 3.1)
139 railties (>= 3.1)
139 jquery-ui-rails (6.0.1)
140 jquery-ui-rails (6.0.1)
140 railties (>= 3.2.16)
141 railties (>= 3.2.16)
141 listen (3.1.5)
142 listen (3.1.5)
142 rb-fsevent (~> 0.9, >= 0.9.4)
143 rb-fsevent (~> 0.9, >= 0.9.4)
143 rb-inotify (~> 0.9, >= 0.9.7)
144 rb-inotify (~> 0.9, >= 0.9.7)
144 ruby_dep (~> 1.2)
145 ruby_dep (~> 1.2)
145 loofah (2.2.3)
146 loofah (2.2.3)
146 crass (~> 1.0.2)
147 crass (~> 1.0.2)
147 nokogiri (>= 1.5.9)
148 nokogiri (>= 1.5.9)
148 mail (2.7.1)
149 mail (2.7.1)
149 mini_mime (>= 0.1.1)
150 mini_mime (>= 0.1.1)
150 marcel (0.3.3)
151 marcel (0.3.3)
151 mimemagic (~> 0.3.2)
152 mimemagic (~> 0.3.2)
152 method_source (0.9.2)
153 method_source (0.9.2)
153 mimemagic (0.3.3)
154 mimemagic (0.3.3)
154 mini_mime (1.0.1)
155 mini_mime (1.0.1)
155 mini_portile2 (2.4.0)
156 mini_portile2 (2.4.0)
156 minitest (5.11.3)
157 minitest (5.11.3)
157 minitest-reporters (1.3.6)
158 minitest-reporters (1.3.6)
158 ansi
159 ansi
159 builder
160 builder
160 minitest (>= 5.0)
161 minitest (>= 5.0)
161 ruby-progressbar
162 ruby-progressbar
162 momentjs-rails (2.20.1)
163 momentjs-rails (2.20.1)
163 railties (>= 3.1)
164 railties (>= 3.1)
164 msgpack (1.3.0)
165 msgpack (1.3.0)
165 multi_json (1.13.1)
166 multi_json (1.13.1)
166 mysql2 (0.5.2)
167 mysql2 (0.5.2)
167 nio4r (2.3.1)
168 nio4r (2.3.1)
168 nokogiri (1.10.3)
169 nokogiri (1.10.3)
169 mini_portile2 (~> 2.4.0)
170 mini_portile2 (~> 2.4.0)
170 public_suffix (3.1.1)
171 public_suffix (3.1.1)
171 puma (4.0.0)
172 puma (4.0.0)
172 nio4r (~> 2.0)
173 nio4r (~> 2.0)
173 rack (2.0.7)
174 rack (2.0.7)
174 rack-test (1.1.0)
175 rack-test (1.1.0)
175 rack (>= 1.0, < 3)
176 rack (>= 1.0, < 3)
176 rails (5.2.3)
177 rails (5.2.3)
177 actioncable (= 5.2.3)
178 actioncable (= 5.2.3)
178 actionmailer (= 5.2.3)
179 actionmailer (= 5.2.3)
179 actionpack (= 5.2.3)
180 actionpack (= 5.2.3)
180 actionview (= 5.2.3)
181 actionview (= 5.2.3)
181 activejob (= 5.2.3)
182 activejob (= 5.2.3)
182 activemodel (= 5.2.3)
183 activemodel (= 5.2.3)
183 activerecord (= 5.2.3)
184 activerecord (= 5.2.3)
184 activestorage (= 5.2.3)
185 activestorage (= 5.2.3)
185 activesupport (= 5.2.3)
186 activesupport (= 5.2.3)
186 bundler (>= 1.3.0)
187 bundler (>= 1.3.0)
187 railties (= 5.2.3)
188 railties (= 5.2.3)
188 sprockets-rails (>= 2.0.0)
189 sprockets-rails (>= 2.0.0)
189 rails-controller-testing (1.0.4)
190 rails-controller-testing (1.0.4)
190 actionpack (>= 5.0.1.x)
191 actionpack (>= 5.0.1.x)
191 actionview (>= 5.0.1.x)
192 actionview (>= 5.0.1.x)
192 activesupport (>= 5.0.1.x)
193 activesupport (>= 5.0.1.x)
193 rails-dom-testing (2.0.3)
194 rails-dom-testing (2.0.3)
194 activesupport (>= 4.2.0)
195 activesupport (>= 4.2.0)
195 nokogiri (>= 1.6)
196 nokogiri (>= 1.6)
196 rails-html-sanitizer (1.0.4)
197 rails-html-sanitizer (1.0.4)
197 loofah (~> 2.2, >= 2.2.2)
198 loofah (~> 2.2, >= 2.2.2)
198 rails_bootstrap_sortable (2.0.6)
199 rails_bootstrap_sortable (2.0.6)
199 momentjs-rails (>= 2.8.3)
200 momentjs-rails (>= 2.8.3)
200 railties (5.2.3)
201 railties (5.2.3)
201 actionpack (= 5.2.3)
202 actionpack (= 5.2.3)
202 activesupport (= 5.2.3)
203 activesupport (= 5.2.3)
203 method_source
204 method_source
204 rake (>= 0.8.7)
205 rake (>= 0.8.7)
205 thor (>= 0.19.0, < 2.0)
206 thor (>= 0.19.0, < 2.0)
206 rake (12.3.2)
207 rake (12.3.2)
207 rb-fsevent (0.10.3)
208 rb-fsevent (0.10.3)
208 rb-inotify (0.10.0)
209 rb-inotify (0.10.0)
209 ffi (~> 1.0)
210 ffi (~> 1.0)
210 rdiscount (2.2.0.1)
211 rdiscount (2.2.0.1)
211 regexp_parser (1.5.1)
212 regexp_parser (1.5.1)
212 rouge (3.3.0)
213 rouge (3.3.0)
214 + rspec-core (3.8.2)
215 + rspec-support (~> 3.8.0)
216 + rspec-expectations (3.8.4)
217 + diff-lcs (>= 1.2.0, < 2.0)
218 + rspec-support (~> 3.8.0)
219 + rspec-mocks (3.8.1)
220 + diff-lcs (>= 1.2.0, < 2.0)
221 + rspec-support (~> 3.8.0)
222 + rspec-rails (3.8.2)
223 + actionpack (>= 3.0)
224 + activesupport (>= 3.0)
225 + railties (>= 3.0)
226 + rspec-core (~> 3.8.0)
227 + rspec-expectations (~> 3.8.0)
228 + rspec-mocks (~> 3.8.0)
229 + rspec-support (~> 3.8.0)
230 + rspec-support (3.8.2)
213 ruby-progressbar (1.10.0)
231 ruby-progressbar (1.10.0)
214 ruby_dep (1.5.0)
232 ruby_dep (1.5.0)
215 ruby_parser (3.13.1)
233 ruby_parser (3.13.1)
216 sexp_processor (~> 4.9)
234 sexp_processor (~> 4.9)
217 rubyzip (1.2.3)
235 rubyzip (1.2.3)
218 sass (3.7.4)
236 sass (3.7.4)
219 sass-listen (~> 4.0.0)
237 sass-listen (~> 4.0.0)
220 sass-listen (4.0.0)
238 sass-listen (4.0.0)
221 rb-fsevent (~> 0.9, >= 0.9.4)
239 rb-fsevent (~> 0.9, >= 0.9.4)
222 rb-inotify (~> 0.9, >= 0.9.7)
240 rb-inotify (~> 0.9, >= 0.9.7)
223 sass-rails (5.0.7)
241 sass-rails (5.0.7)
224 railties (>= 4.0.0, < 6)
242 railties (>= 4.0.0, < 6)
225 sass (~> 3.1)
243 sass (~> 3.1)
226 sprockets (>= 2.8, < 4.0)
244 sprockets (>= 2.8, < 4.0)
227 sprockets-rails (>= 2.0, < 4.0)
245 sprockets-rails (>= 2.0, < 4.0)
228 tilt (>= 1.1, < 3)
246 tilt (>= 1.1, < 3)
229 sassc (2.0.1)
247 sassc (2.0.1)
230 ffi (~> 1.9)
248 ffi (~> 1.9)
231 rake
249 rake
232 sassc-rails (2.1.1)
250 sassc-rails (2.1.1)
233 railties (>= 4.0.0)
251 railties (>= 4.0.0)
234 sassc (>= 2.0)
252 sassc (>= 2.0)
235 sprockets (> 3.0)
253 sprockets (> 3.0)
236 sprockets-rails
254 sprockets-rails
237 tilt
255 tilt
238 select2-rails (4.0.3)
256 select2-rails (4.0.3)
239 thor (~> 0.14)
257 thor (~> 0.14)
240 selenium-webdriver (3.142.3)
258 selenium-webdriver (3.142.3)
241 childprocess (>= 0.5, < 2.0)
259 childprocess (>= 0.5, < 2.0)
242 rubyzip (~> 1.2, >= 1.2.2)
260 rubyzip (~> 1.2, >= 1.2.2)
243 sexp_processor (4.12.0)
261 sexp_processor (4.12.0)
244 simple_form (4.1.0)
262 simple_form (4.1.0)
245 actionpack (>= 5.0)
263 actionpack (>= 5.0)
246 activemodel (>= 5.0)
264 activemodel (>= 5.0)
247 spring (2.1.0)
265 spring (2.1.0)
248 spring-watcher-listen (2.0.1)
266 spring-watcher-listen (2.0.1)
249 listen (>= 2.7, < 4.0)
267 listen (>= 2.7, < 4.0)
250 spring (>= 1.2, < 3.0)
268 spring (>= 1.2, < 3.0)
251 sprockets (3.7.2)
269 sprockets (3.7.2)
252 concurrent-ruby (~> 1.0)
270 concurrent-ruby (~> 1.0)
253 rack (> 1, < 3)
271 rack (> 1, < 3)
254 sprockets-rails (3.2.1)
272 sprockets-rails (3.2.1)
255 actionpack (>= 4.0)
273 actionpack (>= 4.0)
256 activesupport (>= 4.0)
274 activesupport (>= 4.0)
257 sprockets (>= 3.0.0)
275 sprockets (>= 3.0.0)
258 sqlite3 (1.4.1)
276 sqlite3 (1.4.1)
259 temple (0.8.1)
277 temple (0.8.1)
260 thor (0.20.3)
278 thor (0.20.3)
261 thread_safe (0.3.6)
279 thread_safe (0.3.6)
262 tilt (2.0.9)
280 tilt (2.0.9)
263 tzinfo (1.2.5)
281 tzinfo (1.2.5)
264 thread_safe (~> 0.1)
282 thread_safe (~> 0.1)
265 uglifier (4.1.20)
283 uglifier (4.1.20)
266 execjs (>= 0.3.0, < 3)
284 execjs (>= 0.3.0, < 3)
267 web-console (3.7.0)
285 web-console (3.7.0)
268 actionview (>= 5.0)
286 actionview (>= 5.0)
269 activemodel (>= 5.0)
287 activemodel (>= 5.0)
270 bindex (>= 0.4.0)
288 bindex (>= 0.4.0)
271 railties (>= 5.0)
289 railties (>= 5.0)
272 webdriver (0.1.0)
290 webdriver (0.1.0)
273 websocket-driver (0.7.1)
291 websocket-driver (0.7.1)
274 websocket-extensions (>= 0.1.0)
292 websocket-extensions (>= 0.1.0)
275 websocket-extensions (0.1.4)
293 websocket-extensions (0.1.4)
276 will_paginate (3.0.12)
294 will_paginate (3.0.12)
277 xpath (3.2.0)
295 xpath (3.2.0)
278 nokogiri (~> 1.8)
296 nokogiri (~> 1.8)
279 yaml_db (0.7.0)
297 yaml_db (0.7.0)
280 rails (>= 3.0)
298 rails (>= 3.0)
281 rake (>= 0.8.7)
299 rake (>= 0.8.7)
282
300
283 PLATFORMS
301 PLATFORMS
284 ruby
302 ruby
285
303
286 DEPENDENCIES
304 DEPENDENCIES
287 ace-rails-ap
305 ace-rails-ap
288 activerecord-session_store
306 activerecord-session_store
289 autoprefixer-rails
307 autoprefixer-rails
290 best_in_place (~> 3.0.1)
308 best_in_place (~> 3.0.1)
291 bootsnap (>= 1.1.0)
309 bootsnap (>= 1.1.0)
292 bootstrap-datepicker-rails
310 bootstrap-datepicker-rails
293 bootstrap-sass (~> 3.4.1)
311 bootstrap-sass (~> 3.4.1)
294 bootstrap-switch-rails
312 bootstrap-switch-rails
295 bootstrap-toggle-rails
313 bootstrap-toggle-rails
296 bootstrap3-datetimepicker-rails
314 bootstrap3-datetimepicker-rails
297 byebug
315 byebug
298 capybara (>= 2.15)
316 capybara (>= 2.15)
299 coffee-rails
317 coffee-rails
300 dynamic_form
318 dynamic_form
301 fuzzy-string-match
319 fuzzy-string-match
302 haml
320 haml
303 haml-rails
321 haml-rails
304 in_place_editing
322 in_place_editing
305 jbuilder (~> 2.5)
323 jbuilder (~> 2.5)
306 jquery-countdown-rails
324 jquery-countdown-rails
307 jquery-datatables-rails
325 jquery-datatables-rails
308 jquery-rails
326 jquery-rails
309 jquery-tablesorter
327 jquery-tablesorter
310 jquery-timepicker-addon-rails
328 jquery-timepicker-addon-rails
311 jquery-ui-rails
329 jquery-ui-rails
312 listen (>= 3.0.5, < 3.2)
330 listen (>= 3.0.5, < 3.2)
313 mail
331 mail
314 minitest-reporters
332 minitest-reporters
315 momentjs-rails
333 momentjs-rails
316 mysql2
334 mysql2
317 puma
335 puma
318 rails (~> 5.2)
336 rails (~> 5.2)
319 rails-controller-testing
337 rails-controller-testing
320 rails_bootstrap_sortable
338 rails_bootstrap_sortable
321 rdiscount
339 rdiscount
322 rouge
340 rouge
341 + rspec-rails
323 sassc-rails
342 sassc-rails
324 select2-rails
343 select2-rails
325 selenium-webdriver
344 selenium-webdriver
326 simple_form
345 simple_form
327 spring
346 spring
328 spring-watcher-listen (~> 2.0.0)
347 spring-watcher-listen (~> 2.0.0)
329 sqlite3
348 sqlite3
330 uglifier
349 uglifier
331 web-console (>= 3.3.0)
350 web-console (>= 3.3.0)
332 webdriver
351 webdriver
333 will_paginate (~> 3.0.7)
352 will_paginate (~> 3.0.7)
334 yaml_db
353 yaml_db
335
354
336 BUNDLED WITH
355 BUNDLED WITH
337 1.17.2
356 1.17.2
@@ -1,167 +1,166
1 require 'ipaddr'
1 require 'ipaddr'
2
2
3 class ApplicationController < ActionController::Base
3 class ApplicationController < ActionController::Base
4 protect_from_forgery
4 protect_from_forgery
5
5
6 before_action :current_user
6 before_action :current_user
7
7
8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
9 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
9 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
10 ALLOW_WHITELIST_IP_ONLY_CONF_KEY = 'right.allow_whitelist_ip_only'
10 ALLOW_WHITELIST_IP_ONLY_CONF_KEY = 'right.allow_whitelist_ip_only'
11 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
11 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
12
12
13 #report and redirect for unauthorized activities
13 #report and redirect for unauthorized activities
14 - def unauthorized_redirect
14 + def unauthorized_redirect(notice = 'You are not authorized to view the page you requested')
15 - flash[:notice] = 'You are not authorized to view the page you requested'
15 + flash[:notice] = notice
16 - redirect_to :controller => 'main', :action => 'login'
16 + redirect_to login_main_path
17 end
17 end
18
18
19 # Returns the current logged-in user (if any).
19 # Returns the current logged-in user (if any).
20 def current_user
20 def current_user
21 return nil unless session[:user_id]
21 return nil unless session[:user_id]
22 @current_user ||= User.find(session[:user_id])
22 @current_user ||= User.find(session[:user_id])
23 end
23 end
24
24
25 def admin_authorization
25 def admin_authorization
26 - return false unless authenticate
26 + return false unless check_valid_login
27 user = User.includes(:roles).find(session[:user_id])
27 user = User.includes(:roles).find(session[:user_id])
28 unless user.admin?
28 unless user.admin?
29 unauthorized_redirect
29 unauthorized_redirect
30 return false
30 return false
31 end
31 end
32 return true
32 return true
33 end
33 end
34
34
35 def authorization_by_roles(allowed_roles)
35 def authorization_by_roles(allowed_roles)
36 - return false unless authenticate
36 + return false unless check_valid_login
37 user = User.find(session[:user_id])
37 user = User.find(session[:user_id])
38 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
38 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
39 unauthorized_redirect
39 unauthorized_redirect
40 return false
40 return false
41 end
41 end
42 end
42 end
43
43
44 def testcase_authorization
44 def testcase_authorization
45 #admin always has privileged
45 #admin always has privileged
46 if @current_user.admin?
46 if @current_user.admin?
47 return true
47 return true
48 end
48 end
49
49
50 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
50 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
51 end
51 end
52
52
53
53
54 protected
54 protected
55
55
56 #redirect to root (and also force logout)
56 #redirect to root (and also force logout)
57 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
57 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
58 - def authenticate
58 + def check_valid_login
59 + #check if logged in
59 unless session[:user_id]
60 unless session[:user_id]
60 - flash[:notice] = 'You need to login'
61 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
61 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
62 - flash[:notice] = 'You need to login but you cannot log in at this time'
62 + unauthorized_redirect('You need to login but you cannot log in at this time')
63 + else
64 + unauthorized_redirect('You need to login')
63 end
65 end
64 - redirect_to :controller => 'main', :action => 'login'
65 return false
66 return false
66 end
67 end
67
68
68 # check if run in single user mode
69 # check if run in single user mode
69 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
70 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
70 if @current_user==nil || (not @current_user.admin?)
71 if @current_user==nil || (not @current_user.admin?)
71 - flash[:notice] = 'You cannot log in at this time'
72 + unauthorized_redirect('You cannot log in at this time')
72 - redirect_to :controller => 'main', :action => 'login'
73 return false
73 return false
74 end
74 end
75 end
75 end
76
76
77 # check if the user is enabled
77 # check if the user is enabled
78 unless @current_user.enabled? || @current_user.admin?
78 unless @current_user.enabled? || @current_user.admin?
79 - flash[:notice] = 'Your account is disabled'
79 + unauthorized_redirect 'Your account is disabled'
80 - redirect_to :controller => 'main', :action => 'login'
81 return false
80 return false
82 end
81 end
83
82
84 # check if user ip is allowed
83 # check if user ip is allowed
85 unless @current_user.admin? || !GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
84 unless @current_user.admin? || !GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
86 unless is_request_ip_allowed?
85 unless is_request_ip_allowed?
87 - flash[:notice] = 'Your IP is not allowed'
86 + unauthorized_redirect 'Your IP is not allowed'
88 - redirect_to root_path
87 + return false
89 end
88 end
90 end
89 end
91
90
92 if GraderConfiguration.multicontests?
91 if GraderConfiguration.multicontests?
93 return true if @current_user.admin?
92 return true if @current_user.admin?
94 begin
93 begin
95 if @current_user.contest_stat(true).forced_logout
94 if @current_user.contest_stat(true).forced_logout
96 flash[:notice] = 'You have been automatically logged out.'
95 flash[:notice] = 'You have been automatically logged out.'
97 redirect_to :controller => 'main', :action => 'index'
96 redirect_to :controller => 'main', :action => 'index'
98 end
97 end
99 rescue
98 rescue
100 end
99 end
101 end
100 end
102 return true
101 return true
103 end
102 end
104
103
105 #redirect to root (and also force logout)
104 #redirect to root (and also force logout)
106 #if the user use different ip from the previous connection
105 #if the user use different ip from the previous connection
107 # only applicable when MULTIPLE_IP_LOGIN options is false only
106 # only applicable when MULTIPLE_IP_LOGIN options is false only
108 def authenticate_by_ip_address
107 def authenticate_by_ip_address
109 #this assume that we have already authenticate normally
108 #this assume that we have already authenticate normally
110 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
109 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
111 user = User.find(session[:user_id])
110 user = User.find(session[:user_id])
112 if (not @current_user.admin? && user.last_ip && user.last_ip != request.remote_ip)
111 if (not @current_user.admin? && user.last_ip && user.last_ip != request.remote_ip)
113 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
112 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
114 redirect_to :controller => 'main', :action => 'login'
113 redirect_to :controller => 'main', :action => 'login'
115 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
114 puts "CHEAT: user #{user.login} tried to login from '#{request.remote_ip}' while last ip is '#{user.last_ip}' at #{Time.zone.now}"
116 return false
115 return false
117 end
116 end
118 unless user.last_ip
117 unless user.last_ip
119 user.last_ip = request.remote_ip
118 user.last_ip = request.remote_ip
120 user.save
119 user.save
121 end
120 end
122 end
121 end
123 return true
122 return true
124 end
123 end
125
124
126 def authorization
125 def authorization
127 - return false unless authenticate
126 + return false unless check_valid_login
128 user = User.find(session[:user_id])
127 user = User.find(session[:user_id])
129 unless user.roles.detect { |role|
128 unless user.roles.detect { |role|
130 role.rights.detect{ |right|
129 role.rights.detect{ |right|
131 right.controller == self.class.controller_name and
130 right.controller == self.class.controller_name and
132 (right.action == 'all' || right.action == action_name)
131 (right.action == 'all' || right.action == action_name)
133 }
132 }
134 }
133 }
135 flash[:notice] = 'You are not authorized to view the page you requested'
134 flash[:notice] = 'You are not authorized to view the page you requested'
136 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
135 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
137 redirect_to :controller => 'main', :action => 'login'
136 redirect_to :controller => 'main', :action => 'login'
138 return false
137 return false
139 end
138 end
140 end
139 end
141
140
142 def verify_time_limit
141 def verify_time_limit
143 return true if session[:user_id]==nil
142 return true if session[:user_id]==nil
144 user = User.find(session[:user_id], :include => :site)
143 user = User.find(session[:user_id], :include => :site)
145 return true if user==nil || user.site == nil
144 return true if user==nil || user.site == nil
146 if user.contest_finished?
145 if user.contest_finished?
147 flash[:notice] = 'Error: the contest you are participating is over.'
146 flash[:notice] = 'Error: the contest you are participating is over.'
148 redirect_to :back
147 redirect_to :back
149 return false
148 return false
150 end
149 end
151 return true
150 return true
152 end
151 end
153
152
154 def is_request_ip_allowed?
153 def is_request_ip_allowed?
155 if GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
154 if GraderConfiguration[ALLOW_WHITELIST_IP_ONLY_CONF_KEY]
156 user_ip = IPAddr.new(request.remote_ip)
155 user_ip = IPAddr.new(request.remote_ip)
157 GraderConfiguration[WHITELIST_IP_LIST_CONF_KEY].delete(' ').split(',').each do |ips|
156 GraderConfiguration[WHITELIST_IP_LIST_CONF_KEY].delete(' ').split(',').each do |ips|
158 allow_ips = IPAddr.new(ips)
157 allow_ips = IPAddr.new(ips)
159 unless allow_ips.includes(user_ip)
158 unless allow_ips.includes(user_ip)
160 return false
159 return false
161 end
160 end
162 end
161 end
163 end
162 end
164 return true
163 return true
165 end
164 end
166
165
167 end
166 end
@@ -1,34 +1,32
1 class ConfigurationsController < ApplicationController
1 class ConfigurationsController < ApplicationController
2
2
3 - before_action :authenticate
3 + before_action :admin_authorization
4 - before_action { |controller| controller.authorization_by_roles(['admin'])}
5 -
6
4
7 def index
5 def index
8 @configurations = GraderConfiguration.order(:key)
6 @configurations = GraderConfiguration.order(:key)
9 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
7 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
10 end
8 end
11
9
12 def reload
10 def reload
13 GraderConfiguration.reload
11 GraderConfiguration.reload
14 redirect_to :action => 'index'
12 redirect_to :action => 'index'
15 end
13 end
16
14
17 def update
15 def update
18 @config = GraderConfiguration.find(params[:id])
16 @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'
17 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|
18 respond_to do |format|
21 if @config.update_attributes(configuration_params)
19 if @config.update_attributes(configuration_params)
22 format.json { head :ok }
20 format.json { head :ok }
23 else
21 else
24 format.json { respond_with_bip(@config) }
22 format.json { respond_with_bip(@config) }
25 end
23 end
26 end
24 end
27 end
25 end
28
26
29 private
27 private
30 def configuration_params
28 def configuration_params
31 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
29 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
32 end
30 end
33
31
34 end
32 end
@@ -1,104 +1,104
1 class GroupsController < ApplicationController
1 class GroupsController < ApplicationController
2 before_action :set_group, only: [:show, :edit, :update, :destroy,
2 before_action :set_group, only: [:show, :edit, :update, :destroy,
3 :add_user, :remove_user,:remove_all_user,
3 :add_user, :remove_user,:remove_all_user,
4 :add_problem, :remove_problem,:remove_all_problem,
4 :add_problem, :remove_problem,:remove_all_problem,
5 ]
5 ]
6 - before_action :authenticate, :admin_authorization
6 + before_action :admin_authorization
7
7
8 # GET /groups
8 # GET /groups
9 def index
9 def index
10 @groups = Group.all
10 @groups = Group.all
11 end
11 end
12
12
13 # GET /groups/1
13 # GET /groups/1
14 def show
14 def show
15 end
15 end
16
16
17 # GET /groups/new
17 # GET /groups/new
18 def new
18 def new
19 @group = Group.new
19 @group = Group.new
20 end
20 end
21
21
22 # GET /groups/1/edit
22 # GET /groups/1/edit
23 def edit
23 def edit
24 end
24 end
25
25
26 # POST /groups
26 # POST /groups
27 def create
27 def create
28 @group = Group.new(group_params)
28 @group = Group.new(group_params)
29
29
30 if @group.save
30 if @group.save
31 redirect_to @group, notice: 'Group was successfully created.'
31 redirect_to @group, notice: 'Group was successfully created.'
32 else
32 else
33 render :new
33 render :new
34 end
34 end
35 end
35 end
36
36
37 # PATCH/PUT /groups/1
37 # PATCH/PUT /groups/1
38 def update
38 def update
39 if @group.update(group_params)
39 if @group.update(group_params)
40 redirect_to @group, notice: 'Group was successfully updated.'
40 redirect_to @group, notice: 'Group was successfully updated.'
41 else
41 else
42 render :edit
42 render :edit
43 end
43 end
44 end
44 end
45
45
46 # DELETE /groups/1
46 # DELETE /groups/1
47 def destroy
47 def destroy
48 @group.destroy
48 @group.destroy
49 redirect_to groups_url, notice: 'Group was successfully destroyed.'
49 redirect_to groups_url, notice: 'Group was successfully destroyed.'
50 end
50 end
51
51
52 def remove_user
52 def remove_user
53 user = User.find(params[:user_id])
53 user = User.find(params[:user_id])
54 @group.users.delete(user)
54 @group.users.delete(user)
55 redirect_to group_path(@group), flash: {success: "User #{user.login} was removed from the group #{@group.name}"}
55 redirect_to group_path(@group), flash: {success: "User #{user.login} was removed from the group #{@group.name}"}
56 end
56 end
57
57
58 def remove_all_user
58 def remove_all_user
59 @group.users.clear
59 @group.users.clear
60 redirect_to group_path(@group), alert: 'All users removed'
60 redirect_to group_path(@group), alert: 'All users removed'
61 end
61 end
62
62
63 def remove_all_problem
63 def remove_all_problem
64 @group.problems.clear
64 @group.problems.clear
65 redirect_to group_path(@group), alert: 'All problems removed'
65 redirect_to group_path(@group), alert: 'All problems removed'
66 end
66 end
67
67
68 def add_user
68 def add_user
69 user = User.find(params[:user_id])
69 user = User.find(params[:user_id])
70 begin
70 begin
71 @group.users << user
71 @group.users << user
72 redirect_to group_path(@group), flash: { success: "User #{user.login} was add to the group #{@group.name}"}
72 redirect_to group_path(@group), flash: { success: "User #{user.login} was add to the group #{@group.name}"}
73 rescue => e
73 rescue => e
74 redirect_to group_path(@group), alert: e.message
74 redirect_to group_path(@group), alert: e.message
75 end
75 end
76 end
76 end
77
77
78 def remove_problem
78 def remove_problem
79 problem = Problem.find(params[:problem_id])
79 problem = Problem.find(params[:problem_id])
80 @group.problems.delete(problem)
80 @group.problems.delete(problem)
81 redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was removed from the group #{@group.name}" }
81 redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was removed from the group #{@group.name}" }
82 end
82 end
83
83
84 def add_problem
84 def add_problem
85 problem = Problem.find(params[:problem_id])
85 problem = Problem.find(params[:problem_id])
86 begin
86 begin
87 @group.problems << problem
87 @group.problems << problem
88 redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was add to the group #{@group.name}" }
88 redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was add to the group #{@group.name}" }
89 rescue => e
89 rescue => e
90 redirect_to group_path(@group), alert: e.message
90 redirect_to group_path(@group), alert: e.message
91 end
91 end
92 end
92 end
93
93
94 private
94 private
95 # Use callbacks to share common setup or constraints between actions.
95 # Use callbacks to share common setup or constraints between actions.
96 def set_group
96 def set_group
97 @group = Group.find(params[:id])
97 @group = Group.find(params[:id])
98 end
98 end
99
99
100 # Only allow a trusted parameter "white list" through.
100 # Only allow a trusted parameter "white list" through.
101 def group_params
101 def group_params
102 params.require(:group).permit(:name, :description)
102 params.require(:group).permit(:name, :description)
103 end
103 end
104 end
104 end
@@ -1,216 +1,211
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 - before_action :authenticate, :except => [:index, :login]
3 + before_action :check_valid_login, :except => [:login]
4 before_action :check_viewability, :except => [:index, :login]
4 before_action :check_viewability, :except => [:index, :login]
5
5
6 append_before_action :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_action :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_action :authenticate_by_ip_address, :only => [:list]
16 before_action :authenticate_by_ip_address, :only => [:list]
17
17
18 - # NOTE: This method is not actually needed, 'config/routes.rb' has
19 - # assigned action login as a default action.
20 - def index
21 - redirect_to :action => 'login'
22 - end
23 -
24 #reset login, clear session
18 #reset login, clear session
19 + #front page
25 def login
20 def login
26 saved_notice = flash[:notice]
21 saved_notice = flash[:notice]
27 reset_session
22 reset_session
28 flash.now[:notice] = saved_notice
23 flash.now[:notice] = saved_notice
29
24
30 # EXPERIMENT:
25 # EXPERIMENT:
31 # Hide login if in single user mode and the url does not
26 # Hide login if in single user mode and the url does not
32 # explicitly specify /login
27 # explicitly specify /login
33 #
28 #
34 # logger.info "PATH: #{request.path}"
29 # logger.info "PATH: #{request.path}"
35 # if GraderConfiguration['system.single_user_mode'] and
30 # if GraderConfiguration['system.single_user_mode'] and
36 # request.path!='/main/login'
31 # request.path!='/main/login'
37 # @hidelogin = true
32 # @hidelogin = true
38 # end
33 # end
39
34
40 @announcements = Announcement.frontpage
35 @announcements = Announcement.frontpage
41 render :action => 'login', :layout => 'empty'
36 render :action => 'login', :layout => 'empty'
42 end
37 end
43
38
44 def logout
39 def logout
45 reset_session
40 reset_session
46 redirect_to root_path
41 redirect_to root_path
47 end
42 end
48
43
49 def list
44 def list
50 prepare_list_information
45 prepare_list_information
51 end
46 end
52
47
53 def help
48 def help
54 @user = User.find(session[:user_id])
49 @user = User.find(session[:user_id])
55 end
50 end
56
51
57 def submit
52 def submit
58 user = User.find(session[:user_id])
53 user = User.find(session[:user_id])
59
54
60 @submission = Submission.new
55 @submission = Submission.new
61 @submission.problem_id = params[:submission][:problem_id]
56 @submission.problem_id = params[:submission][:problem_id]
62 @submission.user = user
57 @submission.user = user
63 @submission.language_id = 0
58 @submission.language_id = 0
64 if (params['file']) and (params['file']!='')
59 if (params['file']) and (params['file']!='')
65 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
60 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
66 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
61 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
67 @submission.source_filename = params['file'].original_filename
62 @submission.source_filename = params['file'].original_filename
68 end
63 end
69
64
70 if (params[:editor_text])
65 if (params[:editor_text])
71 language = Language.find_by_id(params[:language_id])
66 language = Language.find_by_id(params[:language_id])
72 @submission.source = params[:editor_text]
67 @submission.source = params[:editor_text]
73 @submission.source_filename = "live_edit.#{language.ext}"
68 @submission.source_filename = "live_edit.#{language.ext}"
74 @submission.language = language
69 @submission.language = language
75 end
70 end
76
71
77 @submission.submitted_at = Time.new.gmtime
72 @submission.submitted_at = Time.new.gmtime
78 @submission.ip_address = request.remote_ip
73 @submission.ip_address = request.remote_ip
79
74
80 if GraderConfiguration.time_limit_mode? and user.contest_finished?
75 if GraderConfiguration.time_limit_mode? and user.contest_finished?
81 @submission.errors.add(:base,"The contest is over.")
76 @submission.errors.add(:base,"The contest is over.")
82 prepare_list_information
77 prepare_list_information
83 render :action => 'list' and return
78 render :action => 'list' and return
84 end
79 end
85
80
86 if @submission.valid?(@current_user)
81 if @submission.valid?(@current_user)
87 if @submission.save == false
82 if @submission.save == false
88 flash[:notice] = 'Error saving your submission'
83 flash[:notice] = 'Error saving your submission'
89 elsif Task.create(:submission_id => @submission.id,
84 elsif Task.create(:submission_id => @submission.id,
90 :status => Task::STATUS_INQUEUE) == false
85 :status => Task::STATUS_INQUEUE) == false
91 flash[:notice] = 'Error adding your submission to task queue'
86 flash[:notice] = 'Error adding your submission to task queue'
92 end
87 end
93 else
88 else
94 prepare_list_information
89 prepare_list_information
95 render :action => 'list' and return
90 render :action => 'list' and return
96 end
91 end
97 redirect_to edit_submission_path(@submission)
92 redirect_to edit_submission_path(@submission)
98 end
93 end
99
94
100 def source
95 def source
101 submission = Submission.find(params[:id])
96 submission = Submission.find(params[:id])
102 if ((submission.user_id == session[:user_id]) and
97 if ((submission.user_id == session[:user_id]) and
103 (submission.problem != nil) and
98 (submission.problem != nil) and
104 (submission.problem.available))
99 (submission.problem.available))
105 send_data(submission.source,
100 send_data(submission.source,
106 {:filename => submission.download_filename,
101 {:filename => submission.download_filename,
107 :type => 'text/plain'})
102 :type => 'text/plain'})
108 else
103 else
109 flash[:notice] = 'Error viewing source'
104 flash[:notice] = 'Error viewing source'
110 redirect_to :action => 'list'
105 redirect_to :action => 'list'
111 end
106 end
112 end
107 end
113
108
114 def compiler_msg
109 def compiler_msg
115 @submission = Submission.find(params[:id])
110 @submission = Submission.find(params[:id])
116 if @submission.user_id == session[:user_id]
111 if @submission.user_id == session[:user_id]
117 render :action => 'compiler_msg', :layout => 'empty'
112 render :action => 'compiler_msg', :layout => 'empty'
118 else
113 else
119 flash[:notice] = 'Error viewing source'
114 flash[:notice] = 'Error viewing source'
120 redirect_to :action => 'list'
115 redirect_to :action => 'list'
121 end
116 end
122 end
117 end
123
118
124 def result
119 def result
125 if !GraderConfiguration.show_grading_result
120 if !GraderConfiguration.show_grading_result
126 redirect_to :action => 'list' and return
121 redirect_to :action => 'list' and return
127 end
122 end
128 @user = User.find(session[:user_id])
123 @user = User.find(session[:user_id])
129 @submission = Submission.find(params[:id])
124 @submission = Submission.find(params[:id])
130 if @submission.user!=@user
125 if @submission.user!=@user
131 flash[:notice] = 'You are not allowed to view result of other users.'
126 flash[:notice] = 'You are not allowed to view result of other users.'
132 redirect_to :action => 'list' and return
127 redirect_to :action => 'list' and return
133 end
128 end
134 prepare_grading_result(@submission)
129 prepare_grading_result(@submission)
135 end
130 end
136
131
137 def load_output
132 def load_output
138 if !GraderConfiguration.show_grading_result or params[:num]==nil
133 if !GraderConfiguration.show_grading_result or params[:num]==nil
139 redirect_to :action => 'list' and return
134 redirect_to :action => 'list' and return
140 end
135 end
141 @user = User.find(session[:user_id])
136 @user = User.find(session[:user_id])
142 @submission = Submission.find(params[:id])
137 @submission = Submission.find(params[:id])
143 if @submission.user!=@user
138 if @submission.user!=@user
144 flash[:notice] = 'You are not allowed to view result of other users.'
139 flash[:notice] = 'You are not allowed to view result of other users.'
145 redirect_to :action => 'list' and return
140 redirect_to :action => 'list' and return
146 end
141 end
147 case_num = params[:num].to_i
142 case_num = params[:num].to_i
148 out_filename = output_filename(@user.login,
143 out_filename = output_filename(@user.login,
149 @submission.problem.name,
144 @submission.problem.name,
150 @submission.id,
145 @submission.id,
151 case_num)
146 case_num)
152 if !FileTest.exists?(out_filename)
147 if !FileTest.exists?(out_filename)
153 flash[:notice] = 'Output not found.'
148 flash[:notice] = 'Output not found.'
154 redirect_to :action => 'list' and return
149 redirect_to :action => 'list' and return
155 end
150 end
156
151
157 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
152 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
158 response.headers['Content-Type'] = "application/force-download"
153 response.headers['Content-Type'] = "application/force-download"
159 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
154 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
160 response.headers["X-Sendfile"] = out_filename
155 response.headers["X-Sendfile"] = out_filename
161 response.headers['Content-length'] = File.size(out_filename)
156 response.headers['Content-length'] = File.size(out_filename)
162 render :nothing => true
157 render :nothing => true
163 else
158 else
164 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
159 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
165 end
160 end
166 end
161 end
167
162
168 def error
163 def error
169 @user = User.find(session[:user_id])
164 @user = User.find(session[:user_id])
170 end
165 end
171
166
172 # announcement refreshing and hiding methods
167 # announcement refreshing and hiding methods
173
168
174 def announcements
169 def announcements
175 if params.has_key? 'recent'
170 if params.has_key? 'recent'
176 prepare_announcements(params[:recent])
171 prepare_announcements(params[:recent])
177 else
172 else
178 prepare_announcements
173 prepare_announcements
179 end
174 end
180 render(:partial => 'announcement',
175 render(:partial => 'announcement',
181 :collection => @announcements,
176 :collection => @announcements,
182 :locals => {:announcement_effect => true})
177 :locals => {:announcement_effect => true})
183 end
178 end
184
179
185 def confirm_contest_start
180 def confirm_contest_start
186 user = User.find(session[:user_id])
181 user = User.find(session[:user_id])
187 if request.method == 'POST'
182 if request.method == 'POST'
188 user.update_start_time
183 user.update_start_time
189 redirect_to :action => 'list'
184 redirect_to :action => 'list'
190 else
185 else
191 @contests = user.contests
186 @contests = user.contests
192 @user = user
187 @user = user
193 end
188 end
194 end
189 end
195
190
196 protected
191 protected
197
192
198 def prepare_announcements(recent=nil)
193 def prepare_announcements(recent=nil)
199 if GraderConfiguration.show_tasks_to?(@user)
194 if GraderConfiguration.show_tasks_to?(@user)
200 @announcements = Announcement.published(true)
195 @announcements = Announcement.published(true)
201 else
196 else
202 @announcements = Announcement.published
197 @announcements = Announcement.published
203 end
198 end
204 if recent!=nil
199 if recent!=nil
205 recent_id = recent.to_i
200 recent_id = recent.to_i
206 @announcements = @announcements.find_all { |a| a.id > recent_id }
201 @announcements = @announcements.find_all { |a| a.id > recent_id }
207 end
202 end
208 end
203 end
209
204
210 def prepare_list_information
205 def prepare_list_information
211 @user = User.find(session[:user_id])
206 @user = User.find(session[:user_id])
212 if not GraderConfiguration.multicontests?
207 if not GraderConfiguration.multicontests?
213 @problems = @user.available_problems
208 @problems = @user.available_problems
214 else
209 else
215 @contest_problems = @user.available_problems_group_by_contests
210 @contest_problems = @user.available_problems_group_by_contests
216 @problems = @user.available_problems
211 @problems = @user.available_problems
@@ -1,196 +1,199
1 class ProblemsController < ApplicationController
1 class ProblemsController < ApplicationController
2
2
3 - before_action :authenticate, :authorization
3 + before_action :admin_authorization
4 - before_action :testcase_authorization, only: [:show_testcase]
4 +
5 + #NOTE: ghost from the past?
6 + #before_action :testcase_authorization, only: [:show_testcase]
7 +
5
8
6 in_place_edit_for :problem, :name
9 in_place_edit_for :problem, :name
7 in_place_edit_for :problem, :full_name
10 in_place_edit_for :problem, :full_name
8 in_place_edit_for :problem, :full_score
11 in_place_edit_for :problem, :full_score
9
12
10 def index
13 def index
11 @problems = Problem.order(date_added: :desc)
14 @problems = Problem.order(date_added: :desc)
12 end
15 end
13
16
14
17
15 def show
18 def show
16 @problem = Problem.find(params[:id])
19 @problem = Problem.find(params[:id])
17 end
20 end
18
21
19 def new
22 def new
20 @problem = Problem.new
23 @problem = Problem.new
21 @description = nil
24 @description = nil
22 end
25 end
23
26
24 def create
27 def create
25 @problem = Problem.new(problem_params)
28 @problem = Problem.new(problem_params)
26 @description = Description.new(problem_params[:description])
29 @description = Description.new(problem_params[:description])
27 if @description.body!=''
30 if @description.body!=''
28 if !@description.save
31 if !@description.save
29 render :action => new and return
32 render :action => new and return
30 end
33 end
31 else
34 else
32 @description = nil
35 @description = nil
33 end
36 end
34 @problem.description = @description
37 @problem.description = @description
35 if @problem.save
38 if @problem.save
36 flash[:notice] = 'Problem was successfully created.'
39 flash[:notice] = 'Problem was successfully created.'
37 redirect_to action: :index
40 redirect_to action: :index
38 else
41 else
39 render :action => 'new'
42 render :action => 'new'
40 end
43 end
41 end
44 end
42
45
43 def quick_create
46 def quick_create
44 @problem = Problem.new(problem_params)
47 @problem = Problem.new(problem_params)
45 @problem.full_name = @problem.name if @problem.full_name == ''
48 @problem.full_name = @problem.name if @problem.full_name == ''
46 @problem.full_score = 100
49 @problem.full_score = 100
47 @problem.available = false
50 @problem.available = false
48 @problem.test_allowed = true
51 @problem.test_allowed = true
49 @problem.output_only = false
52 @problem.output_only = false
50 @problem.date_added = Time.new
53 @problem.date_added = Time.new
51 if @problem.save
54 if @problem.save
52 flash[:notice] = 'Problem was successfully created.'
55 flash[:notice] = 'Problem was successfully created.'
53 redirect_to action: :index
56 redirect_to action: :index
54 else
57 else
55 flash[:notice] = 'Error saving problem'
58 flash[:notice] = 'Error saving problem'
56 redirect_to action: :index
59 redirect_to action: :index
57 end
60 end
58 end
61 end
59
62
60 def edit
63 def edit
61 @problem = Problem.find(params[:id])
64 @problem = Problem.find(params[:id])
62 @description = @problem.description
65 @description = @problem.description
63 end
66 end
64
67
65 def update
68 def update
66 @problem = Problem.find(params[:id])
69 @problem = Problem.find(params[:id])
67 @description = @problem.description
70 @description = @problem.description
68 if @description.nil? and params[:description][:body]!=''
71 if @description.nil? and params[:description][:body]!=''
69 @description = Description.new(description_params)
72 @description = Description.new(description_params)
70 if !@description.save
73 if !@description.save
71 flash[:notice] = 'Error saving description'
74 flash[:notice] = 'Error saving description'
72 render :action => 'edit' and return
75 render :action => 'edit' and return
73 end
76 end
74 @problem.description = @description
77 @problem.description = @description
75 elsif @description
78 elsif @description
76 if !@description.update_attributes(description_params)
79 if !@description.update_attributes(description_params)
77 flash[:notice] = 'Error saving description'
80 flash[:notice] = 'Error saving description'
78 render :action => 'edit' and return
81 render :action => 'edit' and return
79 end
82 end
80 end
83 end
81 if params[:file] and params[:file].content_type != 'application/pdf'
84 if params[:file] and params[:file].content_type != 'application/pdf'
82 flash[:notice] = 'Error: Uploaded file is not PDF'
85 flash[:notice] = 'Error: Uploaded file is not PDF'
83 render :action => 'edit' and return
86 render :action => 'edit' and return
84 end
87 end
85 if @problem.update_attributes(problem_params)
88 if @problem.update_attributes(problem_params)
86 flash[:notice] = 'Problem was successfully updated.'
89 flash[:notice] = 'Problem was successfully updated.'
87 unless params[:file] == nil or params[:file] == ''
90 unless params[:file] == nil or params[:file] == ''
88 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
91 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
89 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
92 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
90 if not FileTest.exists? out_dirname
93 if not FileTest.exists? out_dirname
91 Dir.mkdir out_dirname
94 Dir.mkdir out_dirname
92 end
95 end
93
96
94 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
97 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
95 if FileTest.exists? out_filename
98 if FileTest.exists? out_filename
96 File.delete out_filename
99 File.delete out_filename
97 end
100 end
98
101
99 File.open(out_filename,"wb") do |file|
102 File.open(out_filename,"wb") do |file|
100 file.write(params[:file].read)
103 file.write(params[:file].read)
101 end
104 end
102 @problem.description_filename = "#{@problem.name}.pdf"
105 @problem.description_filename = "#{@problem.name}.pdf"
103 @problem.save
106 @problem.save
104 end
107 end
105 redirect_to :action => 'show', :id => @problem
108 redirect_to :action => 'show', :id => @problem
106 else
109 else
107 render :action => 'edit'
110 render :action => 'edit'
108 end
111 end
109 end
112 end
110
113
111 def destroy
114 def destroy
112 p = Problem.find(params[:id]).destroy
115 p = Problem.find(params[:id]).destroy
113 redirect_to action: :index
116 redirect_to action: :index
114 end
117 end
115
118
116 def toggle
119 def toggle
117 @problem = Problem.find(params[:id])
120 @problem = Problem.find(params[:id])
118 @problem.update_attributes(available: !(@problem.available) )
121 @problem.update_attributes(available: !(@problem.available) )
119 respond_to do |format|
122 respond_to do |format|
120 format.js { }
123 format.js { }
121 end
124 end
122 end
125 end
123
126
124 def toggle_test
127 def toggle_test
125 @problem = Problem.find(params[:id])
128 @problem = Problem.find(params[:id])
126 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
129 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
127 respond_to do |format|
130 respond_to do |format|
128 format.js { }
131 format.js { }
129 end
132 end
130 end
133 end
131
134
132 def toggle_view_testcase
135 def toggle_view_testcase
133 @problem = Problem.find(params[:id])
136 @problem = Problem.find(params[:id])
134 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
137 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
135 respond_to do |format|
138 respond_to do |format|
136 format.js { }
139 format.js { }
137 end
140 end
138 end
141 end
139
142
140 def turn_all_off
143 def turn_all_off
141 Problem.available.all.each do |problem|
144 Problem.available.all.each do |problem|
142 problem.available = false
145 problem.available = false
143 problem.save
146 problem.save
144 end
147 end
145 redirect_to action: :index
148 redirect_to action: :index
146 end
149 end
147
150
148 def turn_all_on
151 def turn_all_on
149 Problem.where.not(available: true).each do |problem|
152 Problem.where.not(available: true).each do |problem|
150 problem.available = true
153 problem.available = true
151 problem.save
154 problem.save
152 end
155 end
153 redirect_to action: :index
156 redirect_to action: :index
154 end
157 end
155
158
156 def stat
159 def stat
157 @problem = Problem.find(params[:id])
160 @problem = Problem.find(params[:id])
158 unless @problem.available or session[:admin]
161 unless @problem.available or session[:admin]
159 redirect_to :controller => 'main', :action => 'list'
162 redirect_to :controller => 'main', :action => 'list'
160 return
163 return
161 end
164 end
162 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
165 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
163
166
164 #stat summary
167 #stat summary
165 range =65
168 range =65
166 @histogram = { data: Array.new(range,0), summary: {} }
169 @histogram = { data: Array.new(range,0), summary: {} }
167 user = Hash.new(0)
170 user = Hash.new(0)
168 @submissions.find_each do |sub|
171 @submissions.find_each do |sub|
169 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
172 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
170 @histogram[:data][d.to_i] += 1 if d < range
173 @histogram[:data][d.to_i] += 1 if d < range
171 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
174 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
172 end
175 end
173 @histogram[:summary][:max] = [@histogram[:data].max,1].max
176 @histogram[:summary][:max] = [@histogram[:data].max,1].max
174
177
175 @summary = { attempt: user.count, solve: 0 }
178 @summary = { attempt: user.count, solve: 0 }
176 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
179 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
177 end
180 end
178
181
179 def manage
182 def manage
180 @problems = Problem.order(date_added: :desc)
183 @problems = Problem.order(date_added: :desc)
181 end
184 end
182
185
183 def do_manage
186 def do_manage
184 if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
187 if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
185 change_date_added
188 change_date_added
186 elsif params.has_key? 'add_to_contest'
189 elsif params.has_key? 'add_to_contest'
187 add_to_contest
190 add_to_contest
188 elsif params.has_key? 'enable_problem'
191 elsif params.has_key? 'enable_problem'
189 set_available(true)
192 set_available(true)
190 elsif params.has_key? 'disable_problem'
193 elsif params.has_key? 'disable_problem'
191 set_available(false)
194 set_available(false)
192 elsif params.has_key? 'add_group'
195 elsif params.has_key? 'add_group'
193 group = Group.find(params[:group_id])
196 group = Group.find(params[:group_id])
194 ok = []
197 ok = []
195 failed = []
198 failed = []
196 get_problems_from_params.each do |p|
199 get_problems_from_params.each do |p|
@@ -1,202 +1,202
1 require 'csv'
1 require 'csv'
2
2
3 class ReportController < ApplicationController
3 class ReportController < ApplicationController
4
4
5 - before_action :authenticate
5 + before_action :check_valid_login
6
6
7 before_action :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_action(only: [:problem_hof]) { |c|
9 before_action(only: [:problem_hof]) { |c|
10 - return false unless authenticate
10 + return false unless check_valid_login
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
@@ -1,115 +1,115
1 class SubmissionsController < ApplicationController
1 class SubmissionsController < ApplicationController
2 - before_action :authenticate
2 + before_action :check_valid_login
3 before_action :submission_authorization, only: [:show, :download, :edit]
3 before_action :submission_authorization, only: [:show, :download, :edit]
4 before_action :admin_authorization, only: [:rejudge]
4 before_action :admin_authorization, only: [:rejudge]
5
5
6 # GET /submissions
6 # GET /submissions
7 # GET /submissions.json
7 # GET /submissions.json
8 # Show problem selection and user's submission of that problem
8 # Show problem selection and user's submission of that problem
9 def index
9 def index
10 @user = @current_user
10 @user = @current_user
11 @problems = @user.available_problems
11 @problems = @user.available_problems
12
12
13 if params[:problem_id]==nil
13 if params[:problem_id]==nil
14 @problem = nil
14 @problem = nil
15 @submissions = nil
15 @submissions = nil
16 else
16 else
17 @problem = Problem.find_by_id(params[:problem_id])
17 @problem = Problem.find_by_id(params[:problem_id])
18 if (@problem == nil) or (not @problem.available)
18 if (@problem == nil) or (not @problem.available)
19 redirect_to main_list_path
19 redirect_to main_list_path
20 flash[:notice] = 'Error: submissions for that problem are not viewable.'
20 flash[:notice] = 'Error: submissions for that problem are not viewable.'
21 return
21 return
22 end
22 end
23 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
23 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
24 end
24 end
25 end
25 end
26
26
27 # GET /submissions/1
27 # GET /submissions/1
28 # GET /submissions/1.json
28 # GET /submissions/1.json
29 def show
29 def show
30 @submission = Submission.find(params[:id])
30 @submission = Submission.find(params[:id])
31
31
32 #log the viewing
32 #log the viewing
33 user = User.find(session[:user_id])
33 user = User.find(session[:user_id])
34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
35
35
36 @task = @submission.task
36 @task = @submission.task
37 end
37 end
38
38
39 def download
39 def download
40 @submission = Submission.find(params[:id])
40 @submission = Submission.find(params[:id])
41 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
41 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
42 end
42 end
43
43
44 def compiler_msg
44 def compiler_msg
45 @submission = Submission.find(params[:id])
45 @submission = Submission.find(params[:id])
46 respond_to do |format|
46 respond_to do |format|
47 format.js
47 format.js
48 end
48 end
49 end
49 end
50
50
51 #on-site new submission on specific problem
51 #on-site new submission on specific problem
52 def direct_edit_problem
52 def direct_edit_problem
53 @problem = Problem.find(params[:problem_id])
53 @problem = Problem.find(params[:problem_id])
54 unless @current_user.can_view_problem?(@problem)
54 unless @current_user.can_view_problem?(@problem)
55 unauthorized_redirect
55 unauthorized_redirect
56 return
56 return
57 end
57 end
58 @source = ''
58 @source = ''
59 if (params[:view_latest])
59 if (params[:view_latest])
60 sub = Submission.find_last_by_user_and_problem(@current_user.id,@problem.id)
60 sub = Submission.find_last_by_user_and_problem(@current_user.id,@problem.id)
61 @source = @submission.source.to_s if @submission and @submission.source
61 @source = @submission.source.to_s if @submission and @submission.source
62 end
62 end
63 render 'edit'
63 render 'edit'
64 end
64 end
65
65
66 # GET /submissions/1/edit
66 # GET /submissions/1/edit
67 def edit
67 def edit
68 @submission = Submission.find(params[:id])
68 @submission = Submission.find(params[:id])
69 @source = @submission.source.to_s
69 @source = @submission.source.to_s
70 @problem = @submission.problem
70 @problem = @submission.problem
71 @lang_id = @submission.language.id
71 @lang_id = @submission.language.id
72 end
72 end
73
73
74
74
75 def get_latest_submission_status
75 def get_latest_submission_status
76 @problem = Problem.find(params[:pid])
76 @problem = Problem.find(params[:pid])
77 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
77 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
78 puts User.find(params[:uid]).login
78 puts User.find(params[:uid]).login
79 puts Problem.find(params[:pid]).name
79 puts Problem.find(params[:pid]).name
80 puts 'nil' unless @submission
80 puts 'nil' unless @submission
81 respond_to do |format|
81 respond_to do |format|
82 format.js
82 format.js
83 end
83 end
84 end
84 end
85
85
86 # GET /submissions/:id/rejudge
86 # GET /submissions/:id/rejudge
87 def rejudge
87 def rejudge
88 @submission = Submission.find(params[:id])
88 @submission = Submission.find(params[:id])
89 @task = @submission.task
89 @task = @submission.task
90 @task.status_inqueue! if @task
90 @task.status_inqueue! if @task
91 respond_to do |format|
91 respond_to do |format|
92 format.js
92 format.js
93 end
93 end
94 end
94 end
95
95
96 protected
96 protected
97
97
98 def submission_authorization
98 def submission_authorization
99 #admin always has privileged
99 #admin always has privileged
100 if @current_user.admin?
100 if @current_user.admin?
101 return true
101 return true
102 end
102 end
103
103
104 sub = Submission.find(params[:id])
104 sub = Submission.find(params[:id])
105 if @current_user.available_problems.include? sub.problem
105 if @current_user.available_problems.include? sub.problem
106 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
106 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
107 end
107 end
108
108
109 #default to NO
109 #default to NO
110 unauthorized_redirect
110 unauthorized_redirect
111 return false
111 return false
112 end
112 end
113
113
114
114
115 end
115 end
@@ -1,60 +1,61
1 class TagsController < ApplicationController
1 class TagsController < ApplicationController
2 + before_action :admin_authorization
2 before_action :set_tag, only: [:show, :edit, :update, :destroy]
3 before_action :set_tag, only: [:show, :edit, :update, :destroy]
3
4
4 # GET /tags
5 # GET /tags
5 def index
6 def index
6 @tags = Tag.all
7 @tags = Tag.all
7 end
8 end
8
9
9 # GET /tags/1
10 # GET /tags/1
10 def show
11 def show
11 end
12 end
12
13
13 # GET /tags/new
14 # GET /tags/new
14 def new
15 def new
15 @tag = Tag.new
16 @tag = Tag.new
16 end
17 end
17
18
18 # GET /tags/1/edit
19 # GET /tags/1/edit
19 def edit
20 def edit
20 end
21 end
21
22
22 # POST /tags
23 # POST /tags
23 def create
24 def create
24 @tag = Tag.new(tag_params)
25 @tag = Tag.new(tag_params)
25
26
26 if @tag.save
27 if @tag.save
27 redirect_to @tag, notice: 'Tag was successfully created.'
28 redirect_to @tag, notice: 'Tag was successfully created.'
28 else
29 else
29 render :new
30 render :new
30 end
31 end
31 end
32 end
32
33
33 # PATCH/PUT /tags/1
34 # PATCH/PUT /tags/1
34 def update
35 def update
35 if @tag.update(tag_params)
36 if @tag.update(tag_params)
36 redirect_to @tag, notice: 'Tag was successfully updated.'
37 redirect_to @tag, notice: 'Tag was successfully updated.'
37 else
38 else
38 render :edit
39 render :edit
39 end
40 end
40 end
41 end
41
42
42 # DELETE /tags/1
43 # DELETE /tags/1
43 def destroy
44 def destroy
44 #remove any association
45 #remove any association
45 ProblemTag.where(tag_id: @tag.id).destroy_all
46 ProblemTag.where(tag_id: @tag.id).destroy_all
46 @tag.destroy
47 @tag.destroy
47 redirect_to tags_url, notice: 'Tag was successfully destroyed.'
48 redirect_to tags_url, notice: 'Tag was successfully destroyed.'
48 end
49 end
49
50
50 private
51 private
51 # Use callbacks to share common setup or constraints between actions.
52 # Use callbacks to share common setup or constraints between actions.
52 def set_tag
53 def set_tag
53 @tag = Tag.find(params[:id])
54 @tag = Tag.find(params[:id])
54 end
55 end
55
56
56 # Only allow a trusted parameter "white list" through.
57 # Only allow a trusted parameter "white list" through.
57 def tag_params
58 def tag_params
58 params.require(:tag).permit(:name, :description, :public)
59 params.require(:tag).permit(:name, :description, :public)
59 end
60 end
60 end
61 end
@@ -1,75 +1,75
1 class TasksController < ApplicationController
1 class TasksController < ApplicationController
2
2
3 - before_action :authenticate, :check_viewability
3 + before_action :check_valid_login, :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,111 +1,111
1 class TestController < ApplicationController
1 class TestController < ApplicationController
2
2
3 - before_action :authenticate, :check_viewability
3 + before_action :check_valid_login, :check_viewability
4
4
5
5
6 def index
6 def index
7 prepare_index_information
7 prepare_index_information
8 end
8 end
9
9
10 def submit
10 def submit
11 @user = User.find(session[:user_id])
11 @user = User.find(session[:user_id])
12
12
13 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
13 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
14
14
15 if ! @submitted_test_request.errors.empty?
15 if ! @submitted_test_request.errors.empty?
16 prepare_index_information
16 prepare_index_information
17 render :action => 'index' and return
17 render :action => 'index' and return
18 end
18 end
19
19
20 if GraderConfiguration.time_limit_mode?
20 if GraderConfiguration.time_limit_mode?
21 if @user.contest_finished?
21 if @user.contest_finished?
22 @submitted_test_request.errors.add(:base,'Contest is over.')
22 @submitted_test_request.errors.add(:base,'Contest is over.')
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.allow_test_request(@user)
27 if !GraderConfiguration.allow_test_request(@user)
28 prepare_index_information
28 prepare_index_information
29 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
29 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
30 redirect_to :action => 'index' and return
30 redirect_to :action => 'index' and return
31 end
31 end
32 end
32 end
33
33
34 if @submitted_test_request.save
34 if @submitted_test_request.save
35 redirect_to :action => 'index'
35 redirect_to :action => 'index'
36 else
36 else
37 prepare_index_information
37 prepare_index_information
38 render :action => 'index'
38 render :action => 'index'
39 end
39 end
40 end
40 end
41
41
42 def read
42 def read
43 user = User.find(session[:user_id])
43 user = User.find(session[:user_id])
44 begin
44 begin
45 test_request = TestRequest.find(params[:id])
45 test_request = TestRequest.find(params[:id])
46 rescue
46 rescue
47 test_request = nil
47 test_request = nil
48 end
48 end
49 if test_request==nil or test_request.user_id != user.id
49 if test_request==nil or test_request.user_id != user.id
50 flash[:notice] = 'Invalid output'
50 flash[:notice] = 'Invalid output'
51 redirect_to :action => 'index'
51 redirect_to :action => 'index'
52 return
52 return
53 end
53 end
54 if test_request.output_file_name!=nil
54 if test_request.output_file_name!=nil
55 data = File.open(test_request.output_file_name).read(2048)
55 data = File.open(test_request.output_file_name).read(2048)
56 if data==nil
56 if data==nil
57 data=""
57 data=""
58 end
58 end
59 send_data(data,
59 send_data(data,
60 {:filename => 'output.txt',
60 {:filename => 'output.txt',
61 :type => 'text/plain'})
61 :type => 'text/plain'})
62 return
62 return
63 end
63 end
64 redirect_to :action => 'index'
64 redirect_to :action => 'index'
65 end
65 end
66
66
67 def result
67 def result
68 @user = User.find(session[:user_id])
68 @user = User.find(session[:user_id])
69 begin
69 begin
70 @test_request = TestRequest.find(params[:id])
70 @test_request = TestRequest.find(params[:id])
71 rescue
71 rescue
72 @test_request = nil
72 @test_request = nil
73 end
73 end
74 if @test_request==nil or @test_request.user_id != @user.id
74 if @test_request==nil or @test_request.user_id != @user.id
75 flash[:notice] = 'Invalid request'
75 flash[:notice] = 'Invalid request'
76 redirect_to :action => 'index'
76 redirect_to :action => 'index'
77 return
77 return
78 end
78 end
79 end
79 end
80
80
81 protected
81 protected
82
82
83 def prepare_index_information
83 def prepare_index_information
84 @user = User.find(session[:user_id])
84 @user = User.find(session[:user_id])
85 @submissions = Submission.find_last_for_all_available_problems(@user.id)
85 @submissions = Submission.find_last_for_all_available_problems(@user.id)
86 all_problems = @submissions.collect { |submission| submission.problem }
86 all_problems = @submissions.collect { |submission| submission.problem }
87 @problems = []
87 @problems = []
88 all_problems.each do |problem|
88 all_problems.each do |problem|
89 if problem.test_allowed
89 if problem.test_allowed
90 @problems << problem
90 @problems << problem
91 end
91 end
92 end
92 end
93 @test_requests = []
93 @test_requests = []
94 @user.test_requests.each do |ts|
94 @user.test_requests.each do |ts|
95 if ts.problem and ts.problem.available
95 if ts.problem and ts.problem.available
96 @test_requests << ts
96 @test_requests << ts
97 end
97 end
98 end
98 end
99 end
99 end
100
100
101 def check_viewability
101 def check_viewability
102 user = User.find(session[:user_id])
102 user = User.find(session[:user_id])
103 if !GraderConfiguration.show_tasks_to?(user)
103 if !GraderConfiguration.show_tasks_to?(user)
104 redirect_to :controller => 'main', :action => 'list'
104 redirect_to :controller => 'main', :action => 'list'
105 end
105 end
106 if (!GraderConfiguration.show_submitbox_to?(user)) and (action_name=='submit')
106 if (!GraderConfiguration.show_submitbox_to?(user)) and (action_name=='submit')
107 redirect_to :controller => 'test', :action => 'index'
107 redirect_to :controller => 'test', :action => 'index'
108 end
108 end
109 end
109 end
110
110
111 end
111 end
@@ -1,209 +1,209
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_action :authenticate, :except => [:new,
7 + before_action :check_valid_login, :except => [:new,
8 :register,
8 :register,
9 :confirm,
9 :confirm,
10 :forget,
10 :forget,
11 :retrieve_password]
11 :retrieve_password]
12
12
13 before_action :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_action :authenticate, :profile_authorization, only: [:profile]
17 + before_action :check_valid_login, :profile_authorization, only: [:profile]
18
18
19 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
19 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
20
20
21
21
22 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
23 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
24
24
25 def index
25 def index
26 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
27 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
28 else
28 else
29 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
30 end
30 end
31 end
31 end
32
32
33 def chg_passwd
33 def chg_passwd
34 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
35 user.password = params[:passwd]
35 user.password = params[:passwd]
36 user.password_confirmation = params[:passwd_verify]
36 user.password_confirmation = params[:passwd_verify]
37 if user.save
37 if user.save
38 flash[:notice] = 'password changed'
38 flash[:notice] = 'password changed'
39 else
39 else
40 flash[:notice] = 'Error: password changing failed'
40 flash[:notice] = 'Error: password changing failed'
41 end
41 end
42 redirect_to :action => 'index'
42 redirect_to :action => 'index'
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 render :action => 'new', :layout => 'empty'
47 render :action => 'new', :layout => 'empty'
48 end
48 end
49
49
50 def register
50 def register
51 if(params[:cancel])
51 if(params[:cancel])
52 redirect_to :controller => 'main', :action => 'login'
52 redirect_to :controller => 'main', :action => 'login'
53 return
53 return
54 end
54 end
55 @user = User.new(user_params)
55 @user = User.new(user_params)
56 @user.password_confirmation = @user.password = User.random_password
56 @user.password_confirmation = @user.password = User.random_password
57 @user.activated = false
57 @user.activated = false
58 if (@user.valid?) and (@user.save)
58 if (@user.valid?) and (@user.save)
59 if send_confirmation_email(@user)
59 if send_confirmation_email(@user)
60 render :action => 'new_splash', :layout => 'empty'
60 render :action => 'new_splash', :layout => 'empty'
61 else
61 else
62 @admin_email = GraderConfiguration['system.admin_email']
62 @admin_email = GraderConfiguration['system.admin_email']
63 render :action => 'email_error', :layout => 'empty'
63 render :action => 'email_error', :layout => 'empty'
64 end
64 end
65 else
65 else
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 render :action => 'new', :layout => 'empty'
67 render :action => 'new', :layout => 'empty'
68 end
68 end
69 end
69 end
70
70
71 def confirm
71 def confirm
72 login = params[:login]
72 login = params[:login]
73 key = params[:activation]
73 key = params[:activation]
74 @user = User.find_by_login(login)
74 @user = User.find_by_login(login)
75 if (@user) and (@user.verify_activation_key(key))
75 if (@user) and (@user.verify_activation_key(key))
76 if @user.valid? # check uniquenss of email
76 if @user.valid? # check uniquenss of email
77 @user.activated = true
77 @user.activated = true
78 @user.save
78 @user.save
79 @result = :successful
79 @result = :successful
80 else
80 else
81 @result = :email_used
81 @result = :email_used
82 end
82 end
83 else
83 else
84 @result = :failed
84 @result = :failed
85 end
85 end
86 render :action => 'confirm', :layout => 'empty'
86 render :action => 'confirm', :layout => 'empty'
87 end
87 end
88
88
89 def forget
89 def forget
90 render :action => 'forget', :layout => 'empty'
90 render :action => 'forget', :layout => 'empty'
91 end
91 end
92
92
93 def retrieve_password
93 def retrieve_password
94 email = params[:email]
94 email = params[:email]
95 user = User.find_by_email(email)
95 user = User.find_by_email(email)
96 if user
96 if user
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 if last_updated_time > Time.now.gmtime - 5.minutes
98 if last_updated_time > Time.now.gmtime - 5.minutes
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 else
100 else
101 user.password = user.password_confirmation = User.random_password
101 user.password = user.password_confirmation = User.random_password
102 user.save
102 user.save
103 send_new_password_email(user)
103 send_new_password_email(user)
104 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
105 end
105 end
106 else
106 else
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 end
108 end
109 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
110 end
110 end
111
111
112 def stat
112 def stat
113 @user = User.find(params[:id])
113 @user = User.find(params[:id])
114 @submission = Submission.joins(:problem).where(user_id: params[:id])
114 @submission = Submission.joins(:problem).where(user_id: params[:id])
115 @submission = @submission.where('problems.available = true') unless current_user.admin?
115 @submission = @submission.where('problems.available = true') unless current_user.admin?
116
116
117 range = 120
117 range = 120
118 @histogram = { data: Array.new(range,0), summary: {} }
118 @histogram = { data: Array.new(range,0), summary: {} }
119 @summary = {count: 0, solve: 0, attempt: 0}
119 @summary = {count: 0, solve: 0, attempt: 0}
120 problem = Hash.new(0)
120 problem = Hash.new(0)
121
121
122 @submission.find_each do |sub|
122 @submission.find_each do |sub|
123 #histogram
123 #histogram
124 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
125 @histogram[:data][d.to_i] += 1 if d < range
125 @histogram[:data][d.to_i] += 1 if d < range
126
126
127 @summary[:count] += 1
127 @summary[:count] += 1
128 next unless sub.problem
128 next unless sub.problem
129 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
130 end
130 end
131
131
132 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @histogram[:summary][:max] = [@histogram[:data].max,1].max
133 @summary[:attempt] = problem.count
133 @summary[:attempt] = problem.count
134 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
135 end
135 end
136
136
137 def toggle_activate
137 def toggle_activate
138 @user = User.find(params[:id])
138 @user = User.find(params[:id])
139 @user.update_attributes( activated: !@user.activated? )
139 @user.update_attributes( activated: !@user.activated? )
140 respond_to do |format|
140 respond_to do |format|
141 format.js { render partial: 'toggle_button',
141 format.js { render partial: 'toggle_button',
142 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
143 end
143 end
144 end
144 end
145
145
146 def toggle_enable
146 def toggle_enable
147 @user = User.find(params[:id])
147 @user = User.find(params[:id])
148 @user.update_attributes( enabled: !@user.enabled? )
148 @user.update_attributes( enabled: !@user.enabled? )
149 respond_to do |format|
149 respond_to do |format|
150 format.js { render partial: 'toggle_button',
150 format.js { render partial: 'toggle_button',
151 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
152 end
152 end
153 end
153 end
154
154
155 protected
155 protected
156
156
157 def verify_online_registration
157 def verify_online_registration
158 if !GraderConfiguration['system.online_registration']
158 if !GraderConfiguration['system.online_registration']
159 redirect_to :controller => 'main', :action => 'login'
159 redirect_to :controller => 'main', :action => 'login'
160 end
160 end
161 end
161 end
162
162
163 def send_confirmation_email(user)
163 def send_confirmation_email(user)
164 contest_name = GraderConfiguration['contest.name']
164 contest_name = GraderConfiguration['contest.name']
165 activation_url = url_for(:action => 'confirm',
165 activation_url = url_for(:action => 'confirm',
166 :login => user.login,
166 :login => user.login,
167 :activation => user.activation_key)
167 :activation => user.activation_key)
168 home_url = url_for(:controller => 'main', :action => 'index')
168 home_url = url_for(:controller => 'main', :action => 'index')
169 mail_subject = "[#{contest_name}] Confirmation"
169 mail_subject = "[#{contest_name}] Confirmation"
170 mail_body = t('registration.email_body', {
170 mail_body = t('registration.email_body', {
171 :full_name => user.full_name,
171 :full_name => user.full_name,
172 :contest_name => contest_name,
172 :contest_name => contest_name,
173 :login => user.login,
173 :login => user.login,
174 :password => user.password,
174 :password => user.password,
175 :activation_url => activation_url,
175 :activation_url => activation_url,
176 :admin_email => GraderConfiguration['system.admin_email']
176 :admin_email => GraderConfiguration['system.admin_email']
177 })
177 })
178
178
179 logger.info mail_body
179 logger.info mail_body
180
180
181 send_mail(user.email, mail_subject, mail_body)
181 send_mail(user.email, mail_subject, mail_body)
182 end
182 end
183
183
184 def send_new_password_email(user)
184 def send_new_password_email(user)
185 contest_name = GraderConfiguration['contest.name']
185 contest_name = GraderConfiguration['contest.name']
186 mail_subject = "[#{contest_name}] Password recovery"
186 mail_subject = "[#{contest_name}] Password recovery"
187 mail_body = t('registration.password_retrieval.email_body', {
187 mail_body = t('registration.password_retrieval.email_body', {
188 :full_name => user.full_name,
188 :full_name => user.full_name,
189 :contest_name => contest_name,
189 :contest_name => contest_name,
190 :login => user.login,
190 :login => user.login,
191 :password => user.password,
191 :password => user.password,
192 :admin_email => GraderConfiguration['system.admin_email']
192 :admin_email => GraderConfiguration['system.admin_email']
193 })
193 })
194
194
195 logger.info mail_body
195 logger.info mail_body
196
196
197 send_mail(user.email, mail_subject, mail_body)
197 send_mail(user.email, mail_subject, mail_body)
198 end
198 end
199
199
200 # allow viewing of regular user profile only when options allow so
200 # allow viewing of regular user profile only when options allow so
201 # only admins can view admins profile
201 # only admins can view admins profile
202 def profile_authorization
202 def profile_authorization
203 #if view admins' profile, allow only admin
203 #if view admins' profile, allow only admin
204 return false unless(params[:id])
204 return false unless(params[:id])
205 user = User.find(params[:id])
205 user = User.find(params[:id])
206 return false unless user
206 return false unless user
207 return admin_authorization if user.admin?
207 return admin_authorization if user.admin?
208 return true if GraderConfiguration["right.user_view_submission"]
208 return true if GraderConfiguration["right.user_view_submission"]
209
209
@@ -1,102 +1,102
1 require "application_system_test_case"
1 require "application_system_test_case"
2
2
3 class UsersTest < ApplicationSystemTestCase
3 class UsersTest < ApplicationSystemTestCase
4 # test "visiting the index" do
4 # test "visiting the index" do
5 # visit users_url
5 # visit users_url
6 #
6 #
7 # assert_selector "h1", text: "User"
7 # assert_selector "h1", text: "User"
8 # end
8 # end
9
9
10 test "add new user and edit" do
10 test "add new user and edit" do
11 login('admin','admin')
11 login('admin','admin')
12 within 'header' do
12 within 'header' do
13 click_on 'Manage'
13 click_on 'Manage'
14 click_on 'Users', match: :first
14 click_on 'Users', match: :first
15 end
15 end
16
16
17 assert_text "Users"
17 assert_text "Users"
18 assert_text "New user"
18 assert_text "New user"
19
19
20 click_on "New user", match: :first
20 click_on "New user", match: :first
21 fill_in 'Login', with: 'test1'
21 fill_in 'Login', with: 'test1'
22 fill_in 'Full name', with: 'test1 McTestface'
22 fill_in 'Full name', with: 'test1 McTestface'
23 fill_in 'e-mail', with: 'a@a.com'
23 fill_in 'e-mail', with: 'a@a.com'
24 fill_in 'Password', with: 'abcdef'
24 fill_in 'Password', with: 'abcdef'
25 fill_in 'Password confirmation', with: 'abcdef'
25 fill_in 'Password confirmation', with: 'abcdef'
26
26
27 click_on 'Create'
27 click_on 'Create'
28
28
29 assert_text 'User was successfully created'
29 assert_text 'User was successfully created'
30 assert_text 'a@a.com'
30 assert_text 'a@a.com'
31 assert_text 'test1 McTestface'
31 assert_text 'test1 McTestface'
32
32
33 within('tr', text: 'McTestface') do
33 within('tr', text: 'McTestface') do
34 click_on 'Edit'
34 click_on 'Edit'
35 end
35 end
36
36
37 fill_in 'Alias', with: 'hahaha'
37 fill_in 'Alias', with: 'hahaha'
38 fill_in 'Remark', with: 'section 2'
38 fill_in 'Remark', with: 'section 2'
39 click_on 'Update User'
39 click_on 'Update User'
40
40
41 assert_text 'section 2'
41 assert_text 'section 2'
42 end
42 end
43
43
44 test "add multiple users" do
44 test "add multiple users" do
45 login 'admin', 'admin'
45 login 'admin', 'admin'
46 within 'header' do
46 within 'header' do
47 click_on 'Manage'
47 click_on 'Manage'
48 click_on 'Users', match: :first
48 click_on 'Users', match: :first
49 end
49 end
50
50
51 click_on 'New list of users', match: :first
51 click_on 'New list of users', match: :first
52 find(:css, 'textarea').fill_in with:"abc1,Boaty McBoatface,abcdef,alias1,remark1,\nabc2,Boaty2 McSecond,acbdef123,aias2,remark2"
52 find(:css, 'textarea').fill_in with:"abc1,Boaty McBoatface,abcdef,alias1,remark1,\nabc2,Boaty2 McSecond,acbdef123,aias2,remark2"
53 click_on 'create users'
53 click_on 'create users'
54
54
55 assert_text('remark1')
55 assert_text('remark1')
56 assert_text('remark2')
56 assert_text('remark2')
57 end
57 end
58
58
59 test "grant admin right" do
59 test "grant admin right" do
60 login 'admin', 'admin'
60 login 'admin', 'admin'
61 within 'header' do
61 within 'header' do
62 click_on 'Manage'
62 click_on 'Manage'
63 click_on 'Users', match: :first
63 click_on 'Users', match: :first
64 end
64 end
65
65
66 click_on "View administrator"
66 click_on "View administrator"
67 fill_in 'login', with: 'john'
67 fill_in 'login', with: 'john'
68 click_on "Grant"
68 click_on "Grant"
69
69
70 visit logout_main_path
70 visit logout_main_path
71 login 'john','hello'
71 login 'john','hello'
72 within 'header' do
72 within 'header' do
73 click_on 'Manage'
73 click_on 'Manage'
74 click_on 'Problem', match: :first
74 click_on 'Problem', match: :first
75 end
75 end
76 assert_text "Turn off all problems"
76 assert_text "Turn off all problems"
77 end
77 end
78
78
79 test "try using admin from normal user" do
79 test "try using admin from normal user" do
80 login 'admin','admin'
80 login 'admin','admin'
81 visit bulk_manage_user_admin_index_path
81 visit bulk_manage_user_admin_index_path
82 assert_current_path bulk_manage_user_admin_index_path
82 assert_current_path bulk_manage_user_admin_index_path
83 visit logout_main_path
83 visit logout_main_path
84
84
85 login 'jack','morning'
85 login 'jack','morning'
86 visit bulk_manage_user_admin_index_path
86 visit bulk_manage_user_admin_index_path
87 - assert_current_path root_path
88 assert_text 'You are not authorized'
87 assert_text 'You are not authorized'
88 + assert_current_path login_main_path
89
89
90 login 'james','morning'
90 login 'james','morning'
91 visit new_list_user_admin_index_path
91 visit new_list_user_admin_index_path
92 - assert_current_path root_path
93 assert_text 'You are not authorized'
92 assert_text 'You are not authorized'
93 + assert_current_path login_main_path
94 end
94 end
95
95
96 def login(username,password)
96 def login(username,password)
97 visit root_path
97 visit root_path
98 fill_in "Login", with: username
98 fill_in "Login", with: username
99 fill_in "Password", with: password
99 fill_in "Password", with: password
100 click_on "Login"
100 click_on "Login"
101 end
101 end
102 end
102 end
You need to be logged in to leave comments. Login now