Description:
fix bug with duplicate logins are given also increase dropdown size on group view
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r809:e8c8ed4696af - - 3 files changed: 7 inserted, 3 deleted

@@ -1,20 +1,20
1 class Group < ActiveRecord::Base
1 class Group < ActiveRecord::Base
2 has_many :groups_problems, class_name: 'GroupProblem'
2 has_many :groups_problems, class_name: 'GroupProblem'
3 has_many :problems, :through => :groups_problems
3 has_many :problems, :through => :groups_problems
4
4
5 has_many :groups_users, class_name: 'GroupUser'
5 has_many :groups_users, class_name: 'GroupUser'
6 has_many :users, :through => :groups_users
6 has_many :users, :through => :groups_users
7
7
8 #has_and_belongs_to_many :problems
8 #has_and_belongs_to_many :problems
9 #has_and_belongs_to_many :users
9 #has_and_belongs_to_many :users
10
10
11 def add_users_skip_existing(users_list)
11 def add_users_skip_existing(users_list)
12 new_list = []
12 new_list = []
13 - users_list.each do |u|
13 + users_list.uniq.each do |u|
14 new_list << u unless users.include? u
14 new_list << u unless users.include? u
15 end
15 end
16 users << new_list
16 users << new_list
17 end
17 end
18
18
19 end
19 end
20
20
@@ -1,180 +1,184
1 require 'digest/sha1'
1 require 'digest/sha1'
2 require 'net/pop'
2 require 'net/pop'
3 require 'net/https'
3 require 'net/https'
4 require 'net/http'
4 require 'net/http'
5 require 'json'
5 require 'json'
6
6
7 class User < ActiveRecord::Base
7 class User < ActiveRecord::Base
8
8
9 has_and_belongs_to_many :roles
9 has_and_belongs_to_many :roles
10
10
11 #has_and_belongs_to_many :groups
11 #has_and_belongs_to_many :groups
12 has_many :groups_users, class_name: 'GroupUser'
12 has_many :groups_users, class_name: 'GroupUser'
13 has_many :groups, :through => :groups_users
13 has_many :groups, :through => :groups_users
14
14
15 has_many :test_requests, -> {order(submitted_at: :desc)}
15 has_many :test_requests, -> {order(submitted_at: :desc)}
16
16
17 has_many :messages, -> { order(created_at: :desc) },
17 has_many :messages, -> { order(created_at: :desc) },
18 :class_name => "Message",
18 :class_name => "Message",
19 :foreign_key => "sender_id"
19 :foreign_key => "sender_id"
20
20
21 has_many :replied_messages, -> { order(created_at: :desc) },
21 has_many :replied_messages, -> { order(created_at: :desc) },
22 :class_name => "Message",
22 :class_name => "Message",
23 :foreign_key => "receiver_id"
23 :foreign_key => "receiver_id"
24
24
25 has_many :logins
25 has_many :logins
26
26
27 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
27 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
28
28
29 belongs_to :site
29 belongs_to :site
30 belongs_to :country
30 belongs_to :country
31
31
32 has_and_belongs_to_many :contests, -> { order(:name)}
32 has_and_belongs_to_many :contests, -> { order(:name)}
33
33
34 scope :activated_users, -> {where activated: true}
34 scope :activated_users, -> {where activated: true}
35
35
36 validates_presence_of :login
36 validates_presence_of :login
37 validates_uniqueness_of :login
37 validates_uniqueness_of :login
38 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
38 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
39 validates_length_of :login, :within => 3..30
39 validates_length_of :login, :within => 3..30
40
40
41 validates_presence_of :full_name
41 validates_presence_of :full_name
42 validates_length_of :full_name, :minimum => 1
42 validates_length_of :full_name, :minimum => 1
43
43
44 validates_presence_of :password, :if => :password_required?
44 validates_presence_of :password, :if => :password_required?
45 validates_length_of :password, :within => 4..50, :if => :password_required?
45 validates_length_of :password, :within => 4..50, :if => :password_required?
46 validates_confirmation_of :password, :if => :password_required?
46 validates_confirmation_of :password, :if => :password_required?
47
47
48 validates_format_of :email,
48 validates_format_of :email,
49 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
49 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
50 :if => :email_validation?
50 :if => :email_validation?
51 validate :uniqueness_of_email_from_activated_users,
51 validate :uniqueness_of_email_from_activated_users,
52 :if => :email_validation?
52 :if => :email_validation?
53 validate :enough_time_interval_between_same_email_registrations,
53 validate :enough_time_interval_between_same_email_registrations,
54 :if => :email_validation?
54 :if => :email_validation?
55
55
56 # these are for ytopc
56 # these are for ytopc
57 # disable for now
57 # disable for now
58 #validates_presence_of :province
58 #validates_presence_of :province
59
59
60 attr_accessor :password
60 attr_accessor :password
61
61
62 before_save :encrypt_new_password
62 before_save :encrypt_new_password
63 before_save :assign_default_site
63 before_save :assign_default_site
64 before_save :assign_default_contest
64 before_save :assign_default_contest
65
65
66 # this is for will_paginate
66 # this is for will_paginate
67 cattr_reader :per_page
67 cattr_reader :per_page
68 @@per_page = 50
68 @@per_page = 50
69
69
70 def self.authenticate(login, password)
70 def self.authenticate(login, password)
71 user = find_by_login(login)
71 user = find_by_login(login)
72 if user
72 if user
73 return user if user.authenticated?(password)
73 return user if user.authenticated?(password)
74 end
74 end
75 end
75 end
76
76
77 def authenticated?(password)
77 def authenticated?(password)
78 if self.activated
78 if self.activated
79 hashed_password == User.encrypt(password,self.salt)
79 hashed_password == User.encrypt(password,self.salt)
80 else
80 else
81 false
81 false
82 end
82 end
83 end
83 end
84
84
85 + def login_with_name
86 + "[#{login}] #{full_name}"
87 + end
88 +
85 def admin?
89 def admin?
86 has_role?('admin')
90 has_role?('admin')
87 end
91 end
88
92
89 def has_role?(role)
93 def has_role?(role)
90 self.roles.where(name: role).count > 0
94 self.roles.where(name: role).count > 0
91 end
95 end
92
96
93 def email_for_editing
97 def email_for_editing
94 if self.email==nil
98 if self.email==nil
95 "(unknown)"
99 "(unknown)"
96 elsif self.email==''
100 elsif self.email==''
97 "(blank)"
101 "(blank)"
98 else
102 else
99 self.email
103 self.email
100 end
104 end
101 end
105 end
102
106
103 def email_for_editing=(e)
107 def email_for_editing=(e)
104 self.email=e
108 self.email=e
105 end
109 end
106
110
107 def alias_for_editing
111 def alias_for_editing
108 if self.alias==nil
112 if self.alias==nil
109 "(unknown)"
113 "(unknown)"
110 elsif self.alias==''
114 elsif self.alias==''
111 "(blank)"
115 "(blank)"
112 else
116 else
113 self.alias
117 self.alias
114 end
118 end
115 end
119 end
116
120
117 def alias_for_editing=(e)
121 def alias_for_editing=(e)
118 self.alias=e
122 self.alias=e
119 end
123 end
120
124
121 def activation_key
125 def activation_key
122 if self.hashed_password==nil
126 if self.hashed_password==nil
123 encrypt_new_password
127 encrypt_new_password
124 end
128 end
125 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
129 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
126 end
130 end
127
131
128 def verify_activation_key(key)
132 def verify_activation_key(key)
129 key == activation_key
133 key == activation_key
130 end
134 end
131
135
132 def self.random_password(length=5)
136 def self.random_password(length=5)
133 chars = 'abcdefghjkmnopqrstuvwxyz'
137 chars = 'abcdefghjkmnopqrstuvwxyz'
134 password = ''
138 password = ''
135 length.times { password << chars[rand(chars.length - 1)] }
139 length.times { password << chars[rand(chars.length - 1)] }
136 password
140 password
137 end
141 end
138
142
139
143
140 # Contest information
144 # Contest information
141
145
142 def self.find_users_with_no_contest()
146 def self.find_users_with_no_contest()
143 users = User.all
147 users = User.all
144 return users.find_all { |u| u.contests.length == 0 }
148 return users.find_all { |u| u.contests.length == 0 }
145 end
149 end
146
150
147
151
148 def contest_time_left
152 def contest_time_left
149 if GraderConfiguration.contest_mode?
153 if GraderConfiguration.contest_mode?
150 return nil if site==nil
154 return nil if site==nil
151 return site.time_left
155 return site.time_left
152 elsif GraderConfiguration.indv_contest_mode?
156 elsif GraderConfiguration.indv_contest_mode?
153 time_limit = GraderConfiguration.contest_time_limit
157 time_limit = GraderConfiguration.contest_time_limit
154 if time_limit == nil
158 if time_limit == nil
155 return nil
159 return nil
156 end
160 end
157 if contest_stat==nil or contest_stat.started_at==nil
161 if contest_stat==nil or contest_stat.started_at==nil
158 return (Time.now.gmtime + time_limit) - Time.now.gmtime
162 return (Time.now.gmtime + time_limit) - Time.now.gmtime
159 else
163 else
160 finish_time = contest_stat.started_at + time_limit
164 finish_time = contest_stat.started_at + time_limit
161 current_time = Time.now.gmtime
165 current_time = Time.now.gmtime
162 if current_time > finish_time
166 if current_time > finish_time
163 return 0
167 return 0
164 else
168 else
165 return finish_time - current_time
169 return finish_time - current_time
166 end
170 end
167 end
171 end
168 else
172 else
169 return nil
173 return nil
170 end
174 end
171 end
175 end
172
176
173 def contest_finished?
177 def contest_finished?
174 if GraderConfiguration.contest_mode?
178 if GraderConfiguration.contest_mode?
175 return false if site==nil
179 return false if site==nil
176 return site.finished?
180 return site.finished?
177 elsif GraderConfiguration.indv_contest_mode?
181 elsif GraderConfiguration.indv_contest_mode?
178 return false if self.contest_stat==nil
182 return false if self.contest_stat==nil
179 return contest_time_left == 0
183 return contest_time_left == 0
180 else
184 else
@@ -1,82 +1,82
1 .container-fluid
1 .container-fluid
2 .row
2 .row
3 .col-md-6
3 .col-md-6
4 %h1 Group #{@group.name}
4 %h1 Group #{@group.name}
5 .row
5 .row
6 .col-md-6
6 .col-md-6
7 %b Description:
7 %b Description:
8 = @group.description
8 = @group.description
9 %br
9 %br
10 = link_to 'Edit', edit_group_path(@group), class: 'btn btn-primary'
10 = link_to 'Edit', edit_group_path(@group), class: 'btn btn-primary'
11 .row
11 .row
12 .col-md-12
12 .col-md-12
13 %h1 Group details
13 %h1 Group details
14 .row
14 .row
15 .col-md-6
15 .col-md-6
16 .panel.panel-default
16 .panel.panel-default
17 .panel-heading
17 .panel-heading
18 .panel-title Users in this group
18 .panel-title Users in this group
19 .panel-body
19 .panel-body
20 %ul
20 %ul
21 %li
21 %li
22 If you want to add several users to a group, it may be easier to just re-import those users in
22 If you want to add several users to a group, it may be easier to just re-import those users in
23 = link_to 'New list of users', new_list_user_admin_index_path
23 = link_to 'New list of users', new_list_user_admin_index_path
24 page. You can also use
24 page. You can also use
25 = link_to 'Bulk Manage User', bulk_manage_user_admin_index_path
25 = link_to 'Bulk Manage User', bulk_manage_user_admin_index_path
26 page.
26 page.
27 =form_tag add_user_group_path(@group), class: 'form-inline' do
27 =form_tag add_user_group_path(@group), class: 'form-inline' do
28 .form-group
28 .form-group
29 =label_tag :user_id, "User"
29 =label_tag :user_id, "User"
30 - =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2', style: 'width: 10em';
30 + =select_tag :user_id, options_from_collection_for_select(User.all,'id','login_with_name'), class: 'select2', style: 'width: 25em';
31 =submit_tag "Add",class: 'btn btn-primary'
31 =submit_tag "Add",class: 'btn btn-primary'
32
32
33
33
34 %table.table.table-hover
34 %table.table.table-hover
35 %thead
35 %thead
36 %tr
36 %tr
37 %th Login
37 %th Login
38 %th Full name
38 %th Full name
39 %th Remark
39 %th Remark
40 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
40 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
41
41
42 %tbody
42 %tbody
43 - @group.users.each do |user|
43 - @group.users.each do |user|
44 %tr
44 %tr
45 %td= user.login
45 %td= user.login
46 %td= user.full_name
46 %td= user.full_name
47 %td= user.remark
47 %td= user.remark
48 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
48 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
49 .col-md-6
49 .col-md-6
50 .panel.panel-default
50 .panel.panel-default
51 .panel-heading
51 .panel-heading
52 .panel-title Problems
52 .panel-title Problems
53 .panel-body
53 .panel-body
54 %ul
54 %ul
55 %li
55 %li
56 If you want to add several problem to a group, it may be easier to bulk manage them in the
56 If you want to add several problem to a group, it may be easier to bulk manage them in the
57 = link_to 'Bulk Manage Problems', manage_problems_path
57 = link_to 'Bulk Manage Problems', manage_problems_path
58 page
58 page
59 =form_tag add_problem_group_path(@group), class: 'form-inline' do
59 =form_tag add_problem_group_path(@group), class: 'form-inline' do
60 .form-group
60 .form-group
61 =label_tag :problem_id, "Problem"
61 =label_tag :problem_id, "Problem"
62 - =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2', style: 'width: 10em';
62 + =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','long_name'), class: 'select2', style: 'width: 25em';
63 =submit_tag "Add",class: 'btn btn-primary'
63 =submit_tag "Add",class: 'btn btn-primary'
64
64
65
65
66 %table.table.table-hover
66 %table.table.table-hover
67 %thead
67 %thead
68 %tr
68 %tr
69 %th name
69 %th name
70 %th Full name
70 %th Full name
71 %th Full score
71 %th Full score
72 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
72 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
73
73
74 %tbody
74 %tbody
75 - @group.problems.each do |problem|
75 - @group.problems.each do |problem|
76 %tr
76 %tr
77 %td= problem.name
77 %td= problem.name
78 %td= problem.full_name
78 %td= problem.full_name
79 %td= problem.full_score
79 %td= problem.full_score
80 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
80 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
81
81
82
82
You need to be logged in to leave comments. Login now