diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -39,13 +39,10 @@ def testcase_authorization #admin always has privileged - puts "haha" if @current_user.admin? return true end - puts "hehe" - puts GraderConfiguration["right.view_testcase"] unauthorized_redirect unless GraderConfiguration["right.view_testcase"] end @@ -61,27 +58,28 @@ return false end + # check if run in single user mode if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY] - user = User.find_by_id(session[:user_id]) - if user==nil or (not user.admin?) + if @current_user==nil or (not @current_user.admin?) flash[:notice] = 'You cannot log in at this time' redirect_to :controller => 'main', :action => 'login' return false end - unless user.enabled? - flash[:notice] = 'Your account is disabled' - redirect_to :controller => 'main', :action => 'login' - return false - end return true end + # check if the user is enabled + unless @current_user.enabled? or @current_user.admin? + flash[:notice] = 'Your account is disabled' + redirect_to :controller => 'main', :action => 'login' + return false + end + if GraderConfiguration.multicontests? - user = User.find(session[:user_id]) - return true if user.admin? + return true if @current_user.admin? begin - if user.contest_stat(true).forced_logout + if @current_user.contest_stat(true).forced_logout flash[:notice] = 'You have been automatically logged out.' redirect_to :controller => 'main', :action => 'index' end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb new file mode 100644 --- /dev/null +++ b/app/controllers/groups_controller.rb @@ -0,0 +1,86 @@ +class GroupsController < ApplicationController + before_action :set_group, only: [:show, :edit, :update, :destroy, + :add_user, :remove_user, + :add_problem, :remove_problem, + ] + before_action :authenticate, :admin_authorization + + # GET /groups + def index + @groups = Group.all + end + + # GET /groups/1 + def show + end + + # GET /groups/new + def new + @group = Group.new + end + + # GET /groups/1/edit + def edit + end + + # POST /groups + def create + @group = Group.new(group_params) + + if @group.save + redirect_to @group, notice: 'Group was successfully created.' + else + render :new + end + end + + # PATCH/PUT /groups/1 + def update + if @group.update(group_params) + redirect_to @group, notice: 'Group was successfully updated.' + else + render :edit + end + end + + # DELETE /groups/1 + def destroy + @group.destroy + redirect_to groups_url, notice: 'Group was successfully destroyed.' + end + + def remove_user + user = User.find(params[:user_id]) + @group.users.delete(user) + redirect_to group_path(@group), notice: "User #{user.login} was removed from the group #{@group.name}" + end + + def add_user + user = User.find(params[:user_id]) + @group.users << user + redirect_to group_path(@group), notice: "User #{user.login} was add to the group #{@group.name}" + end + + def remove_problem + problem = Problem.find(params[:problem_id]) + @group.problems.delete(problem) + redirect_to group_path(@group), notice: "Problem #{problem.name} was removed from the group #{@group.name}" + end + + def add_problem + problem = Problem.find(params[:problem_id]) + @group.problems << problem + redirect_to group_path(@group), notice: "Problem #{problem.name} was add to the group #{@group.name}" + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_group + @group = Group.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def group_params + params.require(:group).permit(:name, :description) + end +end diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -195,6 +195,11 @@ set_available(true) elsif params.has_key? 'disable_problem' set_available(false) + elsif params.has_key? 'add_group' + group = Group.find(params[:group_id]) + get_problems_from_params.each do |p| + group.problems << p + end end redirect_to :action => 'manage' end 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 @@ -228,6 +228,7 @@ end end + # contest management def contests @@ -423,6 +424,8 @@ @action[:set_enable] = params[:enabled] @action[:enabled] = params[:enable] == "1" @action[:gen_password] = params[:gen_password] + @action[:add_group] = params[:add_group] + @action[:group_name] = params[:group_name] end if params[:commit] == "Perform" @@ -437,6 +440,10 @@ u.save end end + if @action[:add_group] and @action[:group_name] + @group = Group.find(@action[:group_name]) + @users.each { |user| @group.users << user } + end end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb new file mode 100644 --- /dev/null +++ b/app/helpers/groups_helper.rb @@ -0,0 +1,2 @@ +module GroupsHelper +end diff --git a/app/models/grader_configuration.rb b/app/models/grader_configuration.rb --- a/app/models/grader_configuration.rb +++ b/app/models/grader_configuration.rb @@ -12,6 +12,7 @@ MULTIPLE_IP_LOGIN_KEY = 'right.multiple_ip_login' VIEW_TESTCASE = 'right.view_testcase' SINGLE_USER_KEY = 'system.single_user_mode' + SYSTEM_USE_PROBLEM_GROUP = 'system.use_problem_group' cattr_accessor :config_cache cattr_accessor :task_grading_info_cache @@ -119,6 +120,10 @@ def self.analysis_mode? return get(SYSTEM_MODE_CONF_KEY) == 'analysis' end + + def self.use_problem_group? + return get(SYSTEM_USE_PROBLEM_GROUP) + end def self.contest_time_limit contest_time_str = GraderConfiguration[CONTEST_TIME_LIMIT_KEY] diff --git a/app/models/group.rb b/app/models/group.rb new file mode 100644 --- /dev/null +++ b/app/models/group.rb @@ -0,0 +1,5 @@ +class Group < ActiveRecord::Base + has_and_belongs_to_many :problems + has_and_belongs_to_many :users +end + diff --git a/app/models/problem.rb b/app/models/problem.rb --- a/app/models/problem.rb +++ b/app/models/problem.rb @@ -2,6 +2,7 @@ belongs_to :description has_and_belongs_to_many :contests, :uniq => true + has_and_belongs_to_many :groups has_many :test_pairs, :dependent => :delete_all has_many :testcases, :dependent => :destroy diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,7 @@ class User < ActiveRecord::Base has_and_belongs_to_many :roles + has_and_belongs_to_many :groups has_many :test_requests, -> {order(submitted_at: DESC)} @@ -290,7 +291,11 @@ def available_problems if not GraderConfiguration.multicontests? - return Problem.available_problems + if GraderConfiguration.use_problem_group? + return available_problems_in_group + else + return Problem.available_problems + end else contest_problems = [] pin = {} @@ -307,6 +312,14 @@ end end + def available_problems_in_group + problem = [] + self.groups.each do |group| + group.problems.where(available: true).each { |p| problem << p } + end + return problem.uniq + end + def can_view_problem?(problem) if not GraderConfiguration.multicontests? return problem.available diff --git a/app/views/contests/edit.html.erb b/app/views/contests/edit.html.erb deleted file mode 100644 --- a/app/views/contests/edit.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -
<%= f.label :name %> | -<%= f.text_field :name %> | -
<%= f.label :title %> | -<%= f.text_field :title %> | -
- | - <%= f.check_box :enabled %> - <%= f.label :enabled %> - | -
- <%= f.submit 'Update' %> -
-<% end %> - -<%= link_to 'Show', @contest %> | -<%= link_to 'Back', contests_path %> diff --git a/app/views/contests/edit.html.haml b/app/views/contests/edit.html.haml new file mode 100644 --- /dev/null +++ b/app/views/contests/edit.html.haml @@ -0,0 +1,20 @@ +%h1 Editing contest += form_for(@contest) do |f| + = f.error_messages + %table + %tr + %td= f.label :name + %td= f.text_field :name + %tr + %td= f.label :title + %td= f.text_field :title + %tr + %td + %td + = f.check_box :enabled + = f.label :enabled + %p + = f.submit 'Update' += link_to 'Show', @contest +| += link_to 'Back', contests_path diff --git a/app/views/contests/index.html.erb b/app/views/contests/index.html.erb deleted file mode 100644 --- a/app/views/contests/index.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -Name | -Title | -Enabled | -|||
---|---|---|---|---|---|
<%= in_place_editor_field :contest, :name, {}, :rows => 1 %> | -<%= in_place_editor_field :contest, :title, {}, :rows => 1 %> | -<%= in_place_editor_field :contest, :enabled, {}, :rows => 1 %> | -<%= link_to 'Show', contest %> | -<%= link_to 'Edit', edit_contest_path(contest) %> | -<%= link_to 'Destroy', contest, :confirm => 'Are you sure?', :method => :delete %> | -
- <%= f.label :name %>
- <%= f.text_field :name %>
-
- <%= f.label :title %>
- <%= f.text_field :title %>
-
- <%= f.label :enabled %>
- <%= f.check_box :enabled %>
-
- <%= f.submit 'Create' %> -
-<% end %> - -<%= link_to 'Back', contests_path %> diff --git a/app/views/contests/new.html.haml b/app/views/contests/new.html.haml new file mode 100644 --- /dev/null +++ b/app/views/contests/new.html.haml @@ -0,0 +1,18 @@ +%h1 New contest += form_for(@contest) do |f| + = f.error_messages + %p + = f.label :name + %br/ + = f.text_field :name + %p + = f.label :title + %br/ + = f.text_field :title + %p + = f.label :enabled + %br/ + = f.check_box :enabled + %p + = f.submit 'Create' += link_to 'Back', contests_path diff --git a/app/views/contests/show.html.erb b/app/views/contests/show.html.erb deleted file mode 100644 --- a/app/views/contests/show.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -- Enabled: - <%=h @contest.enabled %> -
- - -<%= link_to 'Edit', edit_contest_path(@contest) %> | -<%= link_to 'Back', contests_path %> diff --git a/app/views/contests/show.html.haml b/app/views/contests/show.html.haml new file mode 100644 --- /dev/null +++ b/app/views/contests/show.html.haml @@ -0,0 +1,11 @@ +%h1 + Contest: #{h @contest.title} +.infobox + %b Go back to: + [#{link_to 'contest management', :controller => 'contest_management', :action => 'index'}] +%p + %b Enabled: + = h @contest.enabled += link_to 'Edit', edit_contest_path(@contest) +| += link_to 'Back', contests_path diff --git a/app/views/groups/_form.html.haml b/app/views/groups/_form.html.haml new file mode 100644 --- /dev/null +++ b/app/views/groups/_form.html.haml @@ -0,0 +1,16 @@ += form_for @group do |f| + - if @group.errors.any? + #error_explanation + %h2= "#{pluralize(@group.errors.count, "error")} prohibited this group from being saved:" + %ul + - @group.errors.full_messages.each do |msg| + %li= msg + + .form-group.field + = f.label :name + = f.text_field :name, class: 'form-control' + .form-group.field + = f.label :description + = f.text_field :description, class: 'form-control' + .form-group.actions + = f.submit 'Save', class: 'btn btn-primary' diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml new file mode 100644 --- /dev/null +++ b/app/views/groups/edit.html.haml @@ -0,0 +1,7 @@ +%h1 Editing group + += render 'form' + += link_to 'Show', @group +\| += link_to 'Back', groups_path diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml new file mode 100644 --- /dev/null +++ b/app/views/groups/index.html.haml @@ -0,0 +1,22 @@ +%h1 Groups + +%p + = link_to 'New Group', new_group_path, class: 'btn btn-primary' +%table.table.table-hover + %thead + %tr + %th Name + %th Description + %th + %th + + %tbody + - @groups.each do |group| + %tr + %td= group.name + %td= group.description + %td= link_to 'View', group, class: 'btn btn-default' + %td= link_to 'Destroy', group, :method => :delete, :data => { :confirm => 'Are you sure?' }, class: 'btn btn-danger' + +%br + diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml new file mode 100644 --- /dev/null +++ b/app/views/groups/new.html.haml @@ -0,0 +1,5 @@ +%h1 New group + += render 'form' + += link_to 'Back', groups_path diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml new file mode 100644 --- /dev/null +++ b/app/views/groups/show.html.haml @@ -0,0 +1,72 @@ +%p + %b Name: + = @group.name +%p + %b Description: + = @group.description + +%br += link_to 'Edit', edit_group_path(@group) +\| += link_to 'Back', groups_path + +.row + %h1 Group details +.row + .col-md-6 + .panel.panel-default + .panel-heading + .panel-title Users in this group + .panel-body + =form_tag add_user_group_path(@group), class: 'form-inline' do + .form-group + =label_tag :user_id, "User" + =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2' + =submit_tag "Add",class: 'btn btn-primary' + + + %table.table.table-hover + %thead + %tr + %th Login + %th Full name + %th Remark + %th + + %tbody + - @group.users.each do |user| + %tr + %td= user.login + %td= user.full_name + %td= user.remark + %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger' + .col-md-6 + .panel.panel-default + .panel-heading + .panel-title Problems + .panel-body + + =form_tag add_problem_group_path(@group), class: 'form-inline' do + .form-group + =label_tag :problem_id, "Problem" + =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2' + =submit_tag "Add",class: 'btn btn-primary' + + + %table.table.table-hover + %thead + %tr + %th name + %th Full name + %th Full score + %th + + %tbody + - @group.problems.each do |problem| + %tr + %td= problem.name + %td= problem.full_name + %td= problem.full_score + %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger' + + diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -47,6 +47,7 @@ = add_menu( 'Announcements', 'announcements', 'index') = add_menu( 'Problems', 'problems', 'index') = add_menu( 'Users', 'user_admin', 'index') + = add_menu( 'User Groups', 'groups', 'index') = add_menu( 'Graders', 'graders', 'list') = add_menu( 'Message ', 'messages', 'console') %li.divider{role: 'separator'} diff --git a/app/views/problems/manage.html.haml b/app/views/problems/manage.html.haml --- a/app/views/problems/manage.html.haml +++ b/app/views/problems/manage.html.haml @@ -39,7 +39,7 @@ %p= link_to '[Back to problem list]', :action => 'list' = form_tag :action=>'do_manage' do - .submitbox + .submitbox.panel What do you want to do to the selected problem? %br/ (You can shift-click to select a range of problems) @@ -59,8 +59,13 @@ Add to = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) = submit_tag 'Add', :name => 'add_to_contest' + %li + Add problems to group + = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' + = submit_tag 'Add', name: 'add_group' + - %table + %table.table.table-hover %tr{style: "text-align: left;"} %th= check_box_tag 'select_all' %th Name diff --git a/app/views/user_admin/_form.html.erb b/app/views/user_admin/_form.html.erb deleted file mode 100644 --- a/app/views/user_admin/_form.html.erb +++ /dev/null @@ -1,25 +0,0 @@ -<%= error_messages_for 'user' %> - - -
-<%= text_field 'user', 'login' %>
-<%= text_field 'user', 'full_name' %>
-<%= password_field 'user', 'password' %>
-<%= password_field 'user', 'password_confirmation' %>
-<%= email_field 'user', 'email' %>
-<%= text_field 'user', 'alias' %>
-<%= text_field 'user', 'remark' %>
- <%= column.human_name %>: <%=h @user.send(column.name) %> -
-<% end %> - -<%= link_to 'Edit', :action => 'edit', :id => @user %> | -<%= link_to 'Back', :action => 'list' %> diff --git a/app/views/user_admin/show.html.haml b/app/views/user_admin/show.html.haml new file mode 100644 --- /dev/null +++ b/app/views/user_admin/show.html.haml @@ -0,0 +1,14 @@ +%h1 User information +- for column in User.content_columns + %p + %b + = column.human_name + \: + = h @user.send(column.name) +%p + %strong Group + \: + = @user.groups.map{ |x| link_to(x.name,group_path(x)).html_safe}.join(', ').html_safe += link_to 'Edit', :action => 'edit', :id => @user +| += link_to 'Back', :action => 'index' diff --git a/config/routes.rb b/config/routes.rb --- a/config/routes.rb +++ b/config/routes.rb @@ -29,7 +29,15 @@ get 'import' get 'manage' end + end + resources :groups do + member do + post 'add_user', to: 'groups#add_user', as: 'add_user' + delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user' + post 'add_problem', to: 'groups#add_problem', as: 'add_problem' + delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem' + end end resources :testcases, only: [] do diff --git a/db/migrate/011_add_language_ext.rb b/db/migrate/011_add_language_ext.rb --- a/db/migrate/011_add_language_ext.rb +++ b/db/migrate/011_add_language_ext.rb @@ -3,7 +3,7 @@ add_column :languages, :ext, :string, :limit => 10 Language.reset_column_information - langs = Language.find(:all) + langs = Language.all langs.each do |l| l.ext = l.name l.save diff --git a/db/migrate/015_add_status_to_tasks.rb b/db/migrate/015_add_status_to_tasks.rb --- a/db/migrate/015_add_status_to_tasks.rb +++ b/db/migrate/015_add_status_to_tasks.rb @@ -4,7 +4,7 @@ add_column :tasks, :updated_at, :datetime Task.reset_column_information - Task.find(:all).each do |task| + Task.all.each do |task| task.status_complete task.save end diff --git a/db/migrate/018_add_number_to_submissions.rb b/db/migrate/018_add_number_to_submissions.rb --- a/db/migrate/018_add_number_to_submissions.rb +++ b/db/migrate/018_add_number_to_submissions.rb @@ -9,8 +9,7 @@ last_problem_id = nil current_number = 0 - Submission.find(:all, - :order => 'user_id, problem_id, submitted_at').each do |submission| + Submission.order('user_id, problem_id, submitted_at').each do |submission| if submission.user_id==last_user_id and submission.problem_id==last_problem_id current_number += 1 else diff --git a/db/migrate/025_add_site_to_user_and_add_default_site.rb b/db/migrate/025_add_site_to_user_and_add_default_site.rb --- a/db/migrate/025_add_site_to_user_and_add_default_site.rb +++ b/db/migrate/025_add_site_to_user_and_add_default_site.rb @@ -7,7 +7,7 @@ add_column :users, :site_id, :integer User.reset_column_information - User.find(:all).each do |user| + User.all.each do |user| class << user def valid? diff --git a/db/migrate/028_refactor_problem_body_to_description.rb b/db/migrate/028_refactor_problem_body_to_description.rb --- a/db/migrate/028_refactor_problem_body_to_description.rb +++ b/db/migrate/028_refactor_problem_body_to_description.rb @@ -3,7 +3,7 @@ add_column :problems, :description_id, :integer Problem.reset_column_information - Problem.find(:all).each do |problem| + Problem.all.each do |problem| if problem.body!=nil description = Description.new description.body = problem.body @@ -21,7 +21,7 @@ add_column :problems, :body, :text Problem.reset_column_information - Problem.find(:all).each do |problem| + Problem.all.each do |problem| if problem.description_id != nil problem.body = Description.find(problem.description_id).body problem.save diff --git a/db/migrate/029_add_test_allowed_to_problems.rb b/db/migrate/029_add_test_allowed_to_problems.rb --- a/db/migrate/029_add_test_allowed_to_problems.rb +++ b/db/migrate/029_add_test_allowed_to_problems.rb @@ -3,7 +3,7 @@ add_column :problems, :test_allowed, :boolean Problem.reset_column_information - Problem.find(:all).each do |problem| + Problem.all.each do |problem| problem.test_allowed = true problem.save end diff --git a/db/migrate/20081204122651_add_activated_to_users.rb b/db/migrate/20081204122651_add_activated_to_users.rb --- a/db/migrate/20081204122651_add_activated_to_users.rb +++ b/db/migrate/20081204122651_add_activated_to_users.rb @@ -4,7 +4,7 @@ User.reset_column_information - User.find(:all).each do |user| + User.all.each do |user| # disable validation class <