diff --git a/app/controllers/user_admin_controller.rb b/app/controllers/user_admin_controller.rb --- a/app/controllers/user_admin_controller.rb +++ b/app/controllers/user_admin_controller.rb @@ -39,7 +39,7 @@ redirect_to :action => 'index' else render :action => 'new' - end + end end def clear_last_ip @@ -52,92 +52,23 @@ def create_from_list lines = params[:user_list] - note = [] - error_note = [] - error_msg = nil - ok_user = [] - - lines.split("\n").each do |line| - #split with large limit, this will cause consecutive ',' to be result in a blank - items = line.chomp.split(',',1000) - if items.length>=2 - login = items[0] - full_name = items[1] - remark ='' - user_alias = '' - - added_random_password = false - added_password = false - if items.length >= 3 - if items[2].chomp(" ").length > 0 - password = items[2].chomp(" ") - added_password = true - end - else - password = random_password - added_random_password=true; - end - - if items.length>= 4 and items[3].chomp(" ").length > 0; - user_alias = items[3].chomp(" ") - else - user_alias = login - end - - has_remark = false - if items.length>=5 - remark = items[4].strip; - has_remark = true - end + res = User.create_from_list(lines) + error_logins = res[:error_logins] + error_msg = res[:first_error] + ok_user = res[:created_users] - user = User.find_by_login(login) - if (user) - user.full_name = full_name - user.remark = remark if has_remark - user.password = password if added_password || added_random_password - else - #create a random password if none are given - password = random_password unless password - user = User.new({:login => login, - :full_name => full_name, - :password => password, - :password_confirmation => password, - :alias => user_alias, - :remark => remark}) - end - user.activated = true - - if user.save - if added_random_password - note << "'#{login}' (+)" - else - note << login - end - ok_user << user - else - error_note << "'#{login}'" - error_msg = user.errors.full_messages.to_sentence unless error_msg - end - - end - end #add to group if params[:add_to_group] - group = Group.where(id: params[:group_id]).first - if group - group.users << ok_user - end + group = Group.find_by(id: params[:group_id])&.add_users_skip_existing(ok_user) end # show flash - if note.size > 0 - flash[:success] = 'User(s) ' + note.join(', ') + - ' were successfully created. ' + - '( (+) - created with random passwords.)' + if ok_user.count > 0 + flash[:success] = "#{ok_user.count} user(s) was created or updated successfully" end - if error_note.size > 0 + if error_logins.size > 0 flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ') + ". The error of the first failed one are: " + error_msg; end redirect_to :action => 'index' @@ -401,7 +332,7 @@ flash[:notice] = 'You entered an empty mail subject.' redirect_to :action => 'mass_mailing' and return end - + mail_body = params[:email_body] if !mail_body or mail_body.blank? flash[:notice] = 'You entered an empty mail body.' @@ -417,7 +348,7 @@ note << user.login end end - + flash[:notice] = 'User(s) ' + note.join(', ') + ' were successfully modified. ' redirect_to :action => 'mass_mailing' @@ -426,9 +357,14 @@ #bulk manage def bulk_manage - begin - @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex] - @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised + begin + if params[:filter_group] + @users = Group.find_by(id: params[:filter_group_id]).users + else + @users = User.all + end + @users = @users.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) unless params[:regex].blank? + @users.count if @users #test the sql rescue Exception flash[:error] = 'Regular Expression is malformed' @users = nil diff --git a/app/models/group.rb b/app/models/group.rb --- a/app/models/group.rb +++ b/app/models/group.rb @@ -8,6 +8,13 @@ #has_and_belongs_to_many :problems #has_and_belongs_to_many :users + def add_users_skip_existing(users_list) + new_list = [] + users_list.each do |u| + new_list << u unless users.include? u + end + users << new_list + end end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -136,10 +136,6 @@ password end - def self.find_non_admin_with_prefix(prefix='') - users = User.all - return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 } - end # Contest information @@ -314,13 +310,91 @@ User.update_all(:last_ip => nil) end + #create multiple user, one per lines of input + def self.create_from_list(lines) + error_logins = [] + first_error = nil + created_users = [] + + lines.split("\n").each do |line| + #split with large limit, this will cause consecutive ',' to be result in a blank + items = line.chomp.split(',',1000) + if items.length>=2 + login = items[0] + full_name = items[1] + remark ='' + user_alias = '' + + added_random_password = false + added_password = false + + #given password? + if items.length >= 3 + if items[2].chomp(" ").length > 0 + password = items[2].chomp(" ") + added_password = true + end + else + password = random_password + added_random_password=true; + end + + #given alias? + if items.length>= 4 and items[3].chomp(" ").length > 0; + user_alias = items[3].chomp(" ") + else + user_alias = login + end + + #given remark? + has_remark = false + if items.length>=5 + remark = items[4].strip; + has_remark = true + end + + user = User.find_by_login(login) + if (user) + user.full_name = full_name + user.remark = remark if has_remark + user.password = password if added_password || added_random_password + else + #create a random password if none are given + password = random_password unless password + user = User.new({:login => login, + :full_name => full_name, + :password => password, + :password_confirmation => password, + :alias => user_alias, + :remark => remark}) + end + user.activated = true + + if user.save + created_users << user + else + error_logins << "'#{login}'" + first_error = user.errors.full_messages.to_sentence unless first_error + end + end + end + + return {error_logins: error_logins, first_error: first_error, created_users: created_users} + + end + + def self.find_non_admin_with_prefix(prefix='') + users = User.all + return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 } + end + protected def encrypt_new_password return if password.blank? self.salt = (10+rand(90)).to_s self.hashed_password = User.encrypt(self.password,self.salt) end - + def assign_default_site # have to catch error when migrating (because self.site is not available). begin diff --git a/app/views/user_admin/bulk_manage.html.haml b/app/views/user_admin/bulk_manage.html.haml --- a/app/views/user_admin/bulk_manage.html.haml +++ b/app/views/user_admin/bulk_manage.html.haml @@ -23,6 +23,12 @@ %li %code 21$ matches every user whose login ends with "21" + .form-group + .div.checkbox + %label + = check_box_tag :filter_group, 1, params[:filter_group] == '1' + Apply to this group only + = select_tag "filter_group_id", options_from_collection_for_select( Group.all, 'id','name',params[:filter_group_id]), id: 'group_name',class: 'select2' .col-md-6 .panel.panel-primary .panel-title.panel-heading diff --git a/db/migrate/20210809105935_add_index_to_task_status.rb b/db/migrate/20210809105935_add_index_to_task_status.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20210809105935_add_index_to_task_status.rb @@ -0,0 +1,5 @@ +class AddIndexToTaskStatus < ActiveRecord::Migration[5.2] + def change + add_index :tasks, :status + end +end