Description:
fix user profile, add test
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r759:6c24fe0db627 - - 7 files changed: 64 inserted, 43 deleted

@@ -1,219 +1,226
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 :check_valid_login, :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 :check_valid_login, :profile_authorization, only: [:profile]
18
17
19 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
18 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
20
19
21
20
22 #in_place_edit_for :user, :alias_for_editing
21 #in_place_edit_for :user, :alias_for_editing
23 #in_place_edit_for :user, :email_for_editing
22 #in_place_edit_for :user, :email_for_editing
24
23
25 def index
24 def index
26 if !GraderConfiguration['system.user_setting_enabled']
25 if !GraderConfiguration['system.user_setting_enabled']
27 redirect_to :controller => 'main', :action => 'list'
26 redirect_to :controller => 'main', :action => 'list'
28 else
27 else
29 @user = User.find(session[:user_id])
28 @user = User.find(session[:user_id])
30 end
29 end
31 end
30 end
32
31
32 + # edit logged in user profile
33 + def profile
34 + if !GraderConfiguration['system.user_setting_enabled']
35 + redirect_to :controller => 'main', :action => 'list'
36 + else
37 + @user = current_user;
38 + end
39 + end
40 +
33 def chg_passwd
41 def chg_passwd
34 user = User.find(session[:user_id])
42 user = User.find(session[:user_id])
35 - user.password = params[:passwd]
43 + user.password = params[:password]
36 - user.password_confirmation = params[:passwd_verify]
44 + user.password_confirmation = params[:password_confirmation]
37 if user.save
45 if user.save
38 flash[:notice] = 'password changed'
46 flash[:notice] = 'password changed'
39 else
47 else
40 flash[:notice] = 'Error: password changing failed'
48 flash[:notice] = 'Error: password changing failed'
41 end
49 end
42 - redirect_to :action => 'index'
50 + redirect_to :action => 'profile'
43 end
51 end
44
52
45 def new
53 def new
46 @user = User.new
54 @user = User.new
47 render :action => 'new', :layout => 'empty'
55 render :action => 'new', :layout => 'empty'
48 end
56 end
49
57
50 def register
58 def register
51 if(params[:cancel])
59 if(params[:cancel])
52 redirect_to :controller => 'main', :action => 'login'
60 redirect_to :controller => 'main', :action => 'login'
53 return
61 return
54 end
62 end
55 @user = User.new(user_params)
63 @user = User.new(user_params)
56 @user.password_confirmation = @user.password = User.random_password
64 @user.password_confirmation = @user.password = User.random_password
57 @user.activated = false
65 @user.activated = false
58 if (@user.valid?) and (@user.save)
66 if (@user.valid?) and (@user.save)
59 if send_confirmation_email(@user)
67 if send_confirmation_email(@user)
60 render :action => 'new_splash', :layout => 'empty'
68 render :action => 'new_splash', :layout => 'empty'
61 else
69 else
62 @admin_email = GraderConfiguration['system.admin_email']
70 @admin_email = GraderConfiguration['system.admin_email']
63 render :action => 'email_error', :layout => 'empty'
71 render :action => 'email_error', :layout => 'empty'
64 end
72 end
65 else
73 else
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
74 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 render :action => 'new', :layout => 'empty'
75 render :action => 'new', :layout => 'empty'
68 end
76 end
69 end
77 end
70
78
71 def confirm
79 def confirm
72 login = params[:login]
80 login = params[:login]
73 key = params[:activation]
81 key = params[:activation]
74 @user = User.find_by_login(login)
82 @user = User.find_by_login(login)
75 if (@user) and (@user.verify_activation_key(key))
83 if (@user) and (@user.verify_activation_key(key))
76 if @user.valid? # check uniquenss of email
84 if @user.valid? # check uniquenss of email
77 @user.activated = true
85 @user.activated = true
78 @user.save
86 @user.save
79 @result = :successful
87 @result = :successful
80 else
88 else
81 @result = :email_used
89 @result = :email_used
82 end
90 end
83 else
91 else
84 @result = :failed
92 @result = :failed
85 end
93 end
86 render :action => 'confirm', :layout => 'empty'
94 render :action => 'confirm', :layout => 'empty'
87 end
95 end
88
96
89 def forget
97 def forget
90 render :action => 'forget', :layout => 'empty'
98 render :action => 'forget', :layout => 'empty'
91 end
99 end
92
100
93 def retrieve_password
101 def retrieve_password
94 email = params[:email]
102 email = params[:email]
95 user = User.find_by_email(email)
103 user = User.find_by_email(email)
96 if user
104 if user
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
105 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 if last_updated_time > Time.now.gmtime - 5.minutes
106 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'
107 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 else
108 else
101 user.password = user.password_confirmation = User.random_password
109 user.password = user.password_confirmation = User.random_password
102 user.save
110 user.save
103 send_new_password_email(user)
111 send_new_password_email(user)
104 flash[:notice] = 'New password has been mailed to you.'
112 flash[:notice] = 'New password has been mailed to you.'
105 end
113 end
106 else
114 else
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
115 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 end
116 end
109 redirect_to :action => 'forget'
117 redirect_to :action => 'forget'
110 end
118 end
111
119
112 def stat
120 def stat
113 @user = User.find(params[:id])
121 @user = User.find(params[:id])
114 @submission = Submission.joins(:problem).where(user_id: params[:id])
122 @submission = Submission.joins(:problem).where(user_id: params[:id])
115 @submission = @submission.where('problems.available = true') unless current_user.admin?
123 @submission = @submission.where('problems.available = true') unless current_user.admin?
116
124
117 range = 120
125 range = 120
118 @histogram = { data: Array.new(range,0), summary: {} }
126 @histogram = { data: Array.new(range,0), summary: {} }
119 @summary = {count: 0, solve: 0, attempt: 0}
127 @summary = {count: 0, solve: 0, attempt: 0}
120 problem = Hash.new(0)
128 problem = Hash.new(0)
121
129
122 @submission.find_each do |sub|
130 @submission.find_each do |sub|
123 #histogram
131 #histogram
124 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
132 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
125 @histogram[:data][d.to_i] += 1 if d < range
133 @histogram[:data][d.to_i] += 1 if d < range
126
134
127 @summary[:count] += 1
135 @summary[:count] += 1
128 next unless sub.problem
136 next unless sub.problem
129 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
137 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
130 end
138 end
131
139
132 @histogram[:summary][:max] = [@histogram[:data].max,1].max
140 @histogram[:summary][:max] = [@histogram[:data].max,1].max
133 @summary[:attempt] = problem.count
141 @summary[:attempt] = problem.count
134 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
142 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
135 end
143 end
136
144
137 def toggle_activate
145 def toggle_activate
138 @user = User.find(params[:id])
146 @user = User.find(params[:id])
139 @user.update_attributes( activated: !@user.activated? )
147 @user.update_attributes( activated: !@user.activated? )
140 respond_to do |format|
148 respond_to do |format|
141 format.js { render partial: 'toggle_button',
149 format.js { render partial: 'toggle_button',
142 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
150 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
143 end
151 end
144 end
152 end
145
153
146 def toggle_enable
154 def toggle_enable
147 @user = User.find(params[:id])
155 @user = User.find(params[:id])
148 @user.update_attributes( enabled: !@user.enabled? )
156 @user.update_attributes( enabled: !@user.enabled? )
149 respond_to do |format|
157 respond_to do |format|
150 format.js { render partial: 'toggle_button',
158 format.js { render partial: 'toggle_button',
151 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
159 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
152 end
160 end
153 end
161 end
154
162
155 protected
163 protected
156
164
157 def verify_online_registration
165 def verify_online_registration
158 if !GraderConfiguration['system.online_registration']
166 if !GraderConfiguration['system.online_registration']
159 redirect_to :controller => 'main', :action => 'login'
167 redirect_to :controller => 'main', :action => 'login'
160 end
168 end
161 end
169 end
162
170
163 def send_confirmation_email(user)
171 def send_confirmation_email(user)
164 contest_name = GraderConfiguration['contest.name']
172 contest_name = GraderConfiguration['contest.name']
165 activation_url = url_for(:action => 'confirm',
173 activation_url = url_for(:action => 'confirm',
166 :login => user.login,
174 :login => user.login,
167 :activation => user.activation_key)
175 :activation => user.activation_key)
168 home_url = url_for(:controller => 'main', :action => 'index')
176 home_url = url_for(:controller => 'main', :action => 'index')
169 mail_subject = "[#{contest_name}] Confirmation"
177 mail_subject = "[#{contest_name}] Confirmation"
170 mail_body = t('registration.email_body', {
178 mail_body = t('registration.email_body', {
171 :full_name => user.full_name,
179 :full_name => user.full_name,
172 :contest_name => contest_name,
180 :contest_name => contest_name,
173 :login => user.login,
181 :login => user.login,
174 :password => user.password,
182 :password => user.password,
175 :activation_url => activation_url,
183 :activation_url => activation_url,
176 :admin_email => GraderConfiguration['system.admin_email']
184 :admin_email => GraderConfiguration['system.admin_email']
177 })
185 })
178
186
179 logger.info mail_body
187 logger.info mail_body
180
188
181 send_mail(user.email, mail_subject, mail_body)
189 send_mail(user.email, mail_subject, mail_body)
182 end
190 end
183
191
184 def send_new_password_email(user)
192 def send_new_password_email(user)
185 contest_name = GraderConfiguration['contest.name']
193 contest_name = GraderConfiguration['contest.name']
186 mail_subject = "[#{contest_name}] Password recovery"
194 mail_subject = "[#{contest_name}] Password recovery"
187 mail_body = t('registration.password_retrieval.email_body', {
195 mail_body = t('registration.password_retrieval.email_body', {
188 :full_name => user.full_name,
196 :full_name => user.full_name,
189 :contest_name => contest_name,
197 :contest_name => contest_name,
190 :login => user.login,
198 :login => user.login,
191 :password => user.password,
199 :password => user.password,
192 :admin_email => GraderConfiguration['system.admin_email']
200 :admin_email => GraderConfiguration['system.admin_email']
193 })
201 })
194
202
195 logger.info mail_body
203 logger.info mail_body
196
204
197 send_mail(user.email, mail_subject, mail_body)
205 send_mail(user.email, mail_subject, mail_body)
198 end
206 end
199
207
200 # allow viewing of regular user profile only when options allow so
208 # allow viewing of regular user profile only when options allow so
201 # only admins can view admins profile
209 # only admins can view admins profile
202 def profile_authorization
210 def profile_authorization
203 #if view admins' profile, allow only admin
211 #if view admins' profile, allow only admin
204 return false unless(params[:id])
212 return false unless(params[:id])
205 user = User.find(params[:id])
213 user = User.find(params[:id])
206 return false unless user
214 return false unless user
207 return admin_authorization if user.admin?
215 return admin_authorization if user.admin?
208 return true if GraderConfiguration["right.user_view_submission"]
216 return true if GraderConfiguration["right.user_view_submission"]
209
217
210 #finally, we allow only admin
218 #finally, we allow only admin
211 admin_authorization
219 admin_authorization
212 end
220 end
213
221
214 private
222 private
215 def user_params
223 def user_params
216 params.require(:user).permit(:login, :full_name, :email)
224 params.require(:user).permit(:login, :full_name, :email)
217 end
225 end
218 -
219 end
226 end
@@ -1,95 +1,95
1 %header.navbar.navbar-default.navbar-fixed-top
1 %header.navbar.navbar-default.navbar-fixed-top
2 %nav
2 %nav
3 .container-fluid
3 .container-fluid
4 .navbar-header
4 .navbar-header
5 %button.navbar-toggle.collapsed{ data: {toggle: 'collapse', target: '#navbar-collapse'} }
5 %button.navbar-toggle.collapsed{ data: {toggle: 'collapse', target: '#navbar-collapse'} }
6 %span.sr-only Togggle Navigation
6 %span.sr-only Togggle Navigation
7 %span.icon-bar
7 %span.icon-bar
8 %span.icon-bar
8 %span.icon-bar
9 %span.icon-bar
9 %span.icon-bar
10 %a.navbar-brand{href: list_main_path}
10 %a.navbar-brand{href: list_main_path}
11 %span.glyphicon.glyphicon-home
11 %span.glyphicon.glyphicon-home
12 MAIN
12 MAIN
13 .collapse.navbar-collapse#navbar-collapse
13 .collapse.navbar-collapse#navbar-collapse
14 %ul.nav.navbar-nav
14 %ul.nav.navbar-nav
15 / submission
15 / submission
16 - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
16 - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
17 %li.dropdown
17 %li.dropdown
18 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
18 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
19 = "#{I18n.t 'menu.submissions'}"
19 = "#{I18n.t 'menu.submissions'}"
20 %span.caret
20 %span.caret
21 %ul.dropdown-menu
21 %ul.dropdown-menu
22 = add_menu("View", 'submissions', 'index')
22 = add_menu("View", 'submissions', 'index')
23 = add_menu("Self Test", 'test', 'index')
23 = add_menu("Self Test", 'test', 'index')
24 / hall of fame
24 / hall of fame
25 - if GraderConfiguration['right.user_hall_of_fame']
25 - if GraderConfiguration['right.user_hall_of_fame']
26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
27 / display MODE button (with countdown in contest mode)
27 / display MODE button (with countdown in contest mode)
28 - if GraderConfiguration.analysis_mode?
28 - if GraderConfiguration.analysis_mode?
29 %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
29 %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
30 - elsif GraderConfiguration.time_limit_mode?
30 - elsif GraderConfiguration.time_limit_mode?
31 - if @current_user.contest_finished?
31 - if @current_user.contest_finished?
32 %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
32 %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
33 - elsif !@current_user.contest_started?
33 - elsif !@current_user.contest_started?
34 %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
34 %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
35 - else
35 - else
36 %div.navbar-btn.btn.btn-primary#countdown asdf
36 %div.navbar-btn.btn.btn-primary#countdown asdf
37 :javascript
37 :javascript
38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
39 / admin section
39 / admin section
40 - if (@current_user!=nil) and (session[:admin])
40 - if (@current_user!=nil) and (session[:admin])
41 / management
41 / management
42 %li.dropdown
42 %li.dropdown
43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
44 Manage
44 Manage
45 %span.caret
45 %span.caret
46 %ul.dropdown-menu
46 %ul.dropdown-menu
47 = add_menu( 'Announcements', 'announcements', 'index')
47 = add_menu( 'Announcements', 'announcements', 'index')
48 = add_menu( 'Problems', 'problems', 'index')
48 = add_menu( 'Problems', 'problems', 'index')
49 = add_menu( 'Tags', 'tags', 'index')
49 = add_menu( 'Tags', 'tags', 'index')
50 = add_menu( 'Users', 'user_admin', 'index')
50 = add_menu( 'Users', 'user_admin', 'index')
51 = add_menu( 'User Groups', 'groups', 'index')
51 = add_menu( 'User Groups', 'groups', 'index')
52 = add_menu( 'Graders', 'graders', 'list')
52 = add_menu( 'Graders', 'graders', 'list')
53 = add_menu( 'Message ', 'messages', 'console')
53 = add_menu( 'Message ', 'messages', 'console')
54 %li.divider{role: 'separator'}
54 %li.divider{role: 'separator'}
55 = add_menu( 'System config', 'configurations', 'index')
55 = add_menu( 'System config', 'configurations', 'index')
56 %li.divider{role: 'separator'}
56 %li.divider{role: 'separator'}
57 = add_menu( 'Sites', 'sites', 'index')
57 = add_menu( 'Sites', 'sites', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
59 / report
59 / report
60 %li.dropdown
60 %li.dropdown
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
62 Report
62 Report
63 %span.caret
63 %span.caret
64 %ul.dropdown-menu
64 %ul.dropdown-menu
65 = add_menu( 'Current Score', 'report', 'current_score')
65 = add_menu( 'Current Score', 'report', 'current_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
67 = add_menu( 'Report', 'report', 'multiple_login')
67 = add_menu( 'Report', 'report', 'multiple_login')
68 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
68 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
69 =link_to "#{ungraded} backlogs!",
69 =link_to "#{ungraded} backlogs!",
70 grader_list_path,
70 grader_list_path,
71 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
71 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
72
72
73 %ul.nav.navbar-nav.navbar-right
73 %ul.nav.navbar-nav.navbar-right
74 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
74 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
76 - if GraderConfiguration['system.user_setting_enabled']
76 - if GraderConfiguration['system.user_setting_enabled']
77 - = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
77 + = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog', id: 'user_profile')}".html_safe, 'users', 'profile', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
79
79
80 /
80 /
81 - if (@current_user!=nil) and (session[:admin])
81 - if (@current_user!=nil) and (session[:admin])
82 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
82 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
83 .container-fluid
83 .container-fluid
84 .collapse.navbar-collapse
84 .collapse.navbar-collapse
85 %ul.nav.navbar-nav
85 %ul.nav.navbar-nav
86 = add_menu( '[Announcements]', 'announcements', 'index')
86 = add_menu( '[Announcements]', 'announcements', 'index')
87 = add_menu( '[Msg console]', 'messages', 'console')
87 = add_menu( '[Msg console]', 'messages', 'console')
88 = add_menu( '[Problems]', 'problems', 'index')
88 = add_menu( '[Problems]', 'problems', 'index')
89 = add_menu( '[Users]', 'user_admin', 'index')
89 = add_menu( '[Users]', 'user_admin', 'index')
90 = add_menu( '[Results]', 'user_admin', 'user_stat')
90 = add_menu( '[Results]', 'user_admin', 'user_stat')
91 = add_menu( '[Report]', 'report', 'multiple_login')
91 = add_menu( '[Report]', 'report', 'multiple_login')
92 = add_menu( '[Graders]', 'graders', 'list')
92 = add_menu( '[Graders]', 'graders', 'list')
93 = add_menu( '[Contests]', 'contest_management', 'index')
93 = add_menu( '[Contests]', 'contest_management', 'index')
94 = add_menu( '[Sites]', 'sites', 'index')
94 = add_menu( '[Sites]', 'sites', 'index')
95 = add_menu( '[System config]', 'configurations', 'index')
95 = add_menu( '[System config]', 'configurations', 'index')
@@ -1,14 +1,12
1 = simple_form_for(@user) do |f|
1 = simple_form_for(@user) do |f|
2 = f.error_notification
2 = f.error_notification
3 - .row
4 - .col-md-6.col-md-offset-2
5 = f.input :login, label: 'Login'
3 = f.input :login, label: 'Login'
6 = f.input :full_name, label: 'Full name'
4 = f.input :full_name, label: 'Full name'
7 = f.input :password
5 = f.input :password
8 = f.input :password_confirmation
6 = f.input :password_confirmation
9 = f.input :email
7 = f.input :email
10 = f.input :alias
8 = f.input :alias
11 = f.input :remark
9 = f.input :remark
12 - = f.button :submit, class: 'btn btn-success'
10 + = f.button :submit, class: 'btn btn-primary'
13 = link_to 'Cancel', :back, class: 'btn btn-default'
11 = link_to 'Cancel', :back, class: 'btn btn-default'
14
12
@@ -1,4 +1,9
1 + .container-fluid
2 + .row
3 + .col-md-6
1 %h1 Editing user
4 %h1 Editing user
5 + .row
6 + .col-md-6
2 = simple_form_for @user, url: user_admin_path(@user) do |f|
7 = simple_form_for @user, url: user_admin_path(@user) do |f|
3 = render partial: 'form', local: f
8 = render partial: 'form', local: f
4
9
@@ -1,36 +1,24
1 - = user_title_bar(@user)
2 -
3 - %h1 Your account settings
4 -
5 - -#%p
6 - -#You can edit your alias and e-mails. Just click on the text and edit it.
7
1
8 - %table.table.table-bordered{:style => "width:30%"}
2 + .container-fluid
9 - %tr
10 - %th Login
11 - %td= @user.login
12 - %tr
13 - %th Full name
14 - %td= @user.full_name
15 - -#%tr
16 - -#%th.uinfo Alias
17 - -#%td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
18 - -#%tr
19 - -#%th.uinfo E-mail
20 - -#%td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
21 - %tr
22 - %th Password
23 - %td
24 = form_tag :action => 'chg_passwd', :method => 'post' do
3 = form_tag :action => 'chg_passwd', :method => 'post' do
25 - %table
4 + .row
26 - %tr
5 + .col-md-6
27 - %td
6 + %h1 Your account settings
28 - %input{:type => "password", :class => "form-control", :name => "passwd", :id => "passwd"}
7 + .form-group
29 - %td (new)
8 + %label{:for => "login"} Login
30 - %tr
9 + =@user.login
31 - %td
10 + .form-group
32 - %input{:type => "password", :class => "form-control", :name => "passwd_verify", :id => "passwd_verify"}
11 + %label{:for => "full_name"} Full name
33 - %td (verify)
12 + =@user.full_name
34 - %tr
13 + .form-group
35 - %td{:colspan => "2"}
14 + %label{:for => "password"} Password
36 - %input{:type => "button", :class => "btn btn-default", :name => "commit", :value => "Change Password"}
15 + =password_field_tag :password, nil, class: 'form-control'
16 + .form-group
17 + %label{:for => "password_confirmation"} Password confirmation
18 + =password_field_tag :password_confirmation, nil, class: 'form-control'
19 + .row
20 + .col-md-6
21 + =submit_tag 'Edit', class: 'btn btn-primary'
22 +
23 +
24 +
@@ -1,170 +1,174
1 Rails.application.routes.draw do
1 Rails.application.routes.draw do
2 resources :tags
2 resources :tags
3 get "sources/direct_edit"
3 get "sources/direct_edit"
4
4
5 root :to => 'main#login'
5 root :to => 'main#login'
6
6
7 #logins
7 #logins
8 match 'login/login', to: 'login#login', via: [:get,:post]
8 match 'login/login', to: 'login#login', via: [:get,:post]
9
9
10 resources :contests
10 resources :contests
11 resources :sites
11 resources :sites
12 resources :test
12 resources :test
13
13
14 resources :messages do
14 resources :messages do
15 collection do
15 collection do
16 get 'console'
16 get 'console'
17 end
17 end
18 end
18 end
19
19
20 resources :announcements do
20 resources :announcements do
21 member do
21 member do
22 get 'toggle','toggle_front'
22 get 'toggle','toggle_front'
23 end
23 end
24 end
24 end
25
25
26 resources :problems do
26 resources :problems do
27 member do
27 member do
28 get 'toggle'
28 get 'toggle'
29 get 'toggle_test'
29 get 'toggle_test'
30 get 'toggle_view_testcase'
30 get 'toggle_view_testcase'
31 get 'stat'
31 get 'stat'
32 end
32 end
33 collection do
33 collection do
34 get 'turn_all_off'
34 get 'turn_all_off'
35 get 'turn_all_on'
35 get 'turn_all_on'
36 get 'import'
36 get 'import'
37 get 'manage'
37 get 'manage'
38 get 'quick_create'
38 get 'quick_create'
39 post 'do_manage'
39 post 'do_manage'
40 post 'do_import'
40 post 'do_import'
41 end
41 end
42 end
42 end
43
43
44 resources :groups do
44 resources :groups do
45 member do
45 member do
46 post 'add_user', to: 'groups#add_user', as: 'add_user'
46 post 'add_user', to: 'groups#add_user', as: 'add_user'
47 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
47 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
48 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
48 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
49 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
49 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
50 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
50 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
51 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
51 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
52 end
52 end
53 collection do
53 collection do
54
54
55 end
55 end
56 end
56 end
57
57
58 resources :testcases, only: [] do
58 resources :testcases, only: [] do
59 member do
59 member do
60 get 'download_input'
60 get 'download_input'
61 get 'download_sol'
61 get 'download_sol'
62 end
62 end
63 collection do
63 collection do
64 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
64 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
65 end
65 end
66 end
66 end
67
67
68 resources :grader_configuration, controller: 'configurations'
68 resources :grader_configuration, controller: 'configurations'
69
69
70 resources :users do
70 resources :users do
71 member do
71 member do
72 get 'toggle_activate', 'toggle_enable'
72 get 'toggle_activate', 'toggle_enable'
73 get 'stat'
73 get 'stat'
74 end
74 end
75 + collection do
76 + get 'profile'
77 + post 'chg_passwd'
78 + end
75 end
79 end
76
80
77 resources :submissions do
81 resources :submissions do
78 member do
82 member do
79 get 'download'
83 get 'download'
80 get 'compiler_msg'
84 get 'compiler_msg'
81 get 'rejudge'
85 get 'rejudge'
82 get 'source'
86 get 'source'
83 end
87 end
84 collection do
88 collection do
85 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
89 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
86 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
90 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
87 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
91 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
88 end
92 end
89 end
93 end
90
94
91
95
92 #user admin
96 #user admin
93 resources :user_admin do
97 resources :user_admin do
94 collection do
98 collection do
95 match 'bulk_manage', via: [:get, :post]
99 match 'bulk_manage', via: [:get, :post]
96 get 'bulk_mail'
100 get 'bulk_mail'
97 get 'user_stat'
101 get 'user_stat'
98 get 'import'
102 get 'import'
99 get 'new_list'
103 get 'new_list'
100 get 'admin'
104 get 'admin'
101 get 'active'
105 get 'active'
102 get 'mass_mailing'
106 get 'mass_mailing'
103 get 'revoke_admin'
107 get 'revoke_admin'
104 post 'grant_admin'
108 post 'grant_admin'
105 match 'create_from_list', via: [:get, :post]
109 match 'create_from_list', via: [:get, :post]
106 match 'random_all_passwords', via: [:get, :post]
110 match 'random_all_passwords', via: [:get, :post]
107 end
111 end
108 member do
112 member do
109 get 'clear_last_ip'
113 get 'clear_last_ip'
110 end
114 end
111 end
115 end
112
116
113 resources :contest_management, only: [:index] do
117 resources :contest_management, only: [:index] do
114 collection do
118 collection do
115 get 'user_stat'
119 get 'user_stat'
116 get 'clear_stat'
120 get 'clear_stat'
117 get 'clear_all_stat'
121 get 'clear_all_stat'
118 get 'change_contest_mode'
122 get 'change_contest_mode'
119 end
123 end
120 end
124 end
121
125
122 #get 'user_admin', to: 'user_admin#index'
126 #get 'user_admin', to: 'user_admin#index'
123 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
127 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
124 #post 'user_admin', to: 'user_admin#create'
128 #post 'user_admin', to: 'user_admin#create'
125 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
129 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
126
130
127 #singular resource
131 #singular resource
128 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
132 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
129 #report
133 #report
130 resource :report, only: [], controller: 'report' do
134 resource :report, only: [], controller: 'report' do
131 get 'login'
135 get 'login'
132 get 'multiple_login'
136 get 'multiple_login'
133 get 'problem_hof/:id', action: 'problem_hof'
137 get 'problem_hof/:id', action: 'problem_hof'
134 get 'current_score'
138 get 'current_score'
135 get 'max_score'
139 get 'max_score'
136 post 'show_max_score'
140 post 'show_max_score'
137 end
141 end
138 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
142 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
139 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
143 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
140 #get "report/login"
144 #get "report/login"
141 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
145 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
142 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
146 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
143
147
144 resource :main, only: [], controller: 'main' do
148 resource :main, only: [], controller: 'main' do
145 get 'login'
149 get 'login'
146 get 'logout'
150 get 'logout'
147 get 'list'
151 get 'list'
148 get 'submission(/:id)', action: 'submission', as: 'main_submission'
152 get 'submission(/:id)', action: 'submission', as: 'main_submission'
149 get 'announcements'
153 get 'announcements'
150 get 'help'
154 get 'help'
151 post 'submit'
155 post 'submit'
152 end
156 end
153 #main
157 #main
154 #get "main/list"
158 #get "main/list"
155 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
159 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
156 #post 'main/submit', to: 'main#submit'
160 #post 'main/submit', to: 'main#submit'
157 #get 'main/announcements', to: 'main#announcements'
161 #get 'main/announcements', to: 'main#announcements'
158
162
159
163
160 #
164 #
161 get 'tasks/view/:file.:ext' => 'tasks#view'
165 get 'tasks/view/:file.:ext' => 'tasks#view'
162 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
166 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
163 get 'heartbeat/:id/edit' => 'heartbeat#edit'
167 get 'heartbeat/:id/edit' => 'heartbeat#edit'
164
168
165 #grader
169 #grader
166 get 'graders/list', to: 'graders#list', as: 'grader_list'
170 get 'graders/list', to: 'graders#list', as: 'grader_list'
167
171
168
172
169 # See how all your routes lay out with "rake routes"
173 # See how all your routes lay out with "rake routes"
170
174
@@ -1,102 +1,121
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_text 'You are not authorized'
87 assert_text 'You are not authorized'
88 assert_current_path login_main_path
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_text 'You are not authorized'
92 assert_text 'You are not authorized'
93 assert_current_path login_main_path
93 assert_current_path login_main_path
94 end
94 end
95
95
96 + test "login then change password" do
97 + newpassword = '1234asdf'
98 + login 'john', 'hello'
99 + visit profile_users_path
100 +
101 + fill_in 'password', with: newpassword
102 + fill_in 'password_confirmation', with: newpassword
103 +
104 + click_on 'Edit'
105 +
106 + visit logout_main_path
107 + login 'john', 'hello'
108 + assert_text 'Wrong password'
109 +
110 + login 'john', newpassword
111 + assert_text "MAIN"
112 + assert_text "Submission"
113 + end
114 +
96 def login(username,password)
115 def login(username,password)
97 visit root_path
116 visit root_path
98 fill_in "Login", with: username
117 fill_in "Login", with: username
99 fill_in "Password", with: password
118 fill_in "Password", with: password
100 click_on "Login"
119 click_on "Login"
101 end
120 end
102 end
121 end
You need to be logged in to leave comments. Login now