From 8a010425a2dcb0c28e4114e170b26ded0cfefef5 Mon Sep 17 00:00:00 2001 From: sesheikholeslam Date: Fri, 17 Jul 2020 16:37:09 -0400 Subject: [PATCH 01/12] Adds Survey to Rate Challenges After Correct Flag Submission --- app/assets/javascripts/application.js | 1 + app/assets/javascripts/surveys.js | 6 +++ app/assets/stylesheets/surveys.scss | 56 +++++++++++++++++++++ app/controllers/challenges_controller.rb | 7 ++- app/controllers/surveys_controller.rb | 55 ++++++++++++++++++++ app/helpers/surveys_helper.rb | 4 ++ app/models/submitted_flag.rb | 1 + app/models/survey.rb | 5 ++ app/views/challenges/show.html.haml | 9 +++- app/views/surveys/_form.html.haml | 56 +++++++++++++++++++++ app/views/surveys/_star_rating.html.haml | 13 +++++ app/views/surveys/edit.html.haml | 7 +++ app/views/surveys/index.html.haml | 27 ++++++++++ app/views/surveys/new.html.haml | 5 ++ app/views/surveys/show.html.haml | 21 ++++++++ config/initializers/rails_admin.rb | 4 +- config/locales/en.yml | 5 ++ config/routes.rb | 1 + db/migrate/20200710145833_create_surveys.rb | 13 +++++ db/schema.rb | 13 ++++- test/controllers/surveys_controller_test.rb | 5 ++ test/factories/surveys.rb | 9 ++++ test/models/survey_test.rb | 7 +++ test/system/surveys_test.rb | 51 +++++++++++++++++++ 24 files changed, 374 insertions(+), 7 deletions(-) create mode 100644 app/assets/javascripts/surveys.js create mode 100644 app/assets/stylesheets/surveys.scss create mode 100644 app/controllers/surveys_controller.rb create mode 100644 app/helpers/surveys_helper.rb create mode 100644 app/models/survey.rb create mode 100644 app/views/surveys/_form.html.haml create mode 100644 app/views/surveys/_star_rating.html.haml create mode 100644 app/views/surveys/edit.html.haml create mode 100644 app/views/surveys/index.html.haml create mode 100644 app/views/surveys/new.html.haml create mode 100644 app/views/surveys/show.html.haml create mode 100644 db/migrate/20200710145833_create_surveys.rb create mode 100644 test/controllers/surveys_controller_test.rb create mode 100644 test/factories/surveys.rb create mode 100644 test/models/survey_test.rb create mode 100644 test/system/surveys_test.rb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 7b704463..de856e9b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -11,6 +11,7 @@ // GO AFTER THE REQUIRES BELOW. // //= require jquery +//= require jquery_ujs //= require_tree . //= require jquery.nested-fields // Loads all Bootstrap javascripts diff --git a/app/assets/javascripts/surveys.js b/app/assets/javascripts/surveys.js new file mode 100644 index 00000000..b2ce9100 --- /dev/null +++ b/app/assets/javascripts/surveys.js @@ -0,0 +1,6 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. + +function setRating(id, rating) { + document.getElementById(id).value = rating; +}; diff --git a/app/assets/stylesheets/surveys.scss b/app/assets/stylesheets/surveys.scss new file mode 100644 index 00000000..9bb58850 --- /dev/null +++ b/app/assets/stylesheets/surveys.scss @@ -0,0 +1,56 @@ +// Place all the styles related to the Surveys controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: https://sass-lang.com/ + +.star-cb-group { + /* remove inline-block whitespace */ + font-size: 0; + /* flip the order so we can use the + and ~ combinators */ + unicode-bidi: bidi-override; + direction: rtl; + /* the hidden clearer */ +} +.star-cb-group * { + font-size: 1rem; +} +.star-cb-group > input { + display: none; +} +.star-cb-group > input + label { + /* only enough room for the star */ + display: inline-block; + overflow: hidden; + text-indent: 9999px; + width: 1em; + white-space: nowrap; + cursor: pointer; +} +.star-cb-group > input + label:before { + display: inline-block; + text-indent: -9999px; + content: "☆"; + color: #888; +} +.star-cb-group > input:checked ~ label:before, .star-cb-group > input + label:hover ~ label:before, .star-cb-group > input + label:hover:before { + content: "★"; + color: rgb(238, 206, 24); + text-shadow: 0 0 1px #333; +} +.star-cb-group > .star-cb-clear + label { + text-indent: -9999px; + width: .5em; + margin-left: -.5em; +} +.star-cb-group > .star-cb-clear + label:before { + width: .5em; +} +.star-cb-group:hover > input + label:before { + content: "☆"; + color: #888; + text-shadow: none; +} +.star-cb-group:hover > input + label:hover ~ label:before, .star-cb-group:hover > input + label:hover:before { + content: "★"; + color: rgb(238, 206, 24); + text-shadow: 0 0 1px #333; +} diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 49671fcc..535ad15c 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -21,10 +21,11 @@ def update @solved_challenge = @flag_found.save_solved_challenge(current_user) @solved_video_url = @flag_found.video_url flash.now[:notice] = I18n.t('flag.accepted') + @survey = Survey.new + @survey.submitted_flag_id = @submitted_flag.id else flash.now[:alert] = wrong_flag_messages.sample end - @solvable = @challenge.can_be_solved_by(current_user.team) render :show end @@ -51,7 +52,9 @@ def find_and_log_flag flag = params[:challenge]&.[](:submitted_flag) # Safe navigation on a hash return if flag.nil? - SubmittedFlag.create(user: current_user, challenge: @challenge, text: flag) unless current_user.admin? + unless current_user.admin? + @submitted_flag = SubmittedFlag.create(user: current_user, challenge: @challenge, text: flag) + end @flag_found = @challenge.find_flag(flag) end diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb new file mode 100644 index 00000000..3e31a388 --- /dev/null +++ b/app/controllers/surveys_controller.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +class SurveysController < ApplicationController + before_action :set_survey, only: %i[show edit update destroy] + + # GET /surveys + def index + @surveys = Survey.all + end + + # GET /surveys/1 + def show; end + + # GET /surveys/new + def new + @survey = Survey.new + end + + # GET /surveys/1/edit + def edit; end + + # POST /surveys + def create + @survey = Survey.new(survey_params) + + redirect_to '/game', notice: I18n.t('surveys.submitted') if @survey.save + end + + # PATCH/PUT /surveys/1 + def update + if @survey.update(survey_params) + redirect_to @survey, notice: 'Survey was successfully updated.' + else + render :edit + end + end + + # DELETE /surveys/1 + def destroy + @survey.destroy + redirect_to surveys_url, notice: 'Survey was successfully destroyed.' + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_survey + @survey = Survey.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def survey_params + params.require(:survey).permit(:difficulty, :realism, :interest, :comment, :submitted_flag_id) + end +end diff --git a/app/helpers/surveys_helper.rb b/app/helpers/surveys_helper.rb new file mode 100644 index 00000000..10efc10c --- /dev/null +++ b/app/helpers/surveys_helper.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module SurveysHelper +end diff --git a/app/models/submitted_flag.rb b/app/models/submitted_flag.rb index 83c07ef2..be62bac3 100644 --- a/app/models/submitted_flag.rb +++ b/app/models/submitted_flag.rb @@ -3,6 +3,7 @@ class SubmittedFlag < ApplicationRecord belongs_to :user belongs_to :challenge + has_many :surveys, dependent: :destroy validates :text, presence: true diff --git a/app/models/survey.rb b/app/models/survey.rb new file mode 100644 index 00000000..47174ec4 --- /dev/null +++ b/app/models/survey.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Survey < ApplicationRecord + belongs_to :submitted_flag +end diff --git a/app/views/challenges/show.html.haml b/app/views/challenges/show.html.haml index c7b3391b..a5472690 100644 --- a/app/views/challenges/show.html.haml +++ b/app/views/challenges/show.html.haml @@ -1,5 +1,5 @@ -# For PentestGames, @challenge here can actually be a flag object since Pentest challenges belong to teams + challenges and are linked by a flag object. --# +-# - content_for :admin_menu do %li= link_to t('challenges.admin_edit_challenge', challengename: @challenge.name), admin_edit_url(@challenge) @@ -28,7 +28,7 @@ = sanitize(Kramdown::Document.new(@challenge.sponsor_description).to_html) - if @solvable - = form_for :challenge, url: submit_url(@defense_team, @challenge), method: "put", html: { class: "well", style: "margin-bottom:40px;" } do |f| + = form_for :challenge, url: submit_url(@defense_team, @challenge), method: "put", html: { class: "well form-inline", style: "margin-bottom:40px;" } do |f| .control-group %p = t('challenges.submit_flag') @@ -38,6 +38,11 @@ .control-group = invisible_recaptcha_tags text: 'Submit', :class => "btn btn-primary" +- if @flag_found + %hr/ + = render partial: "surveys/form" + %hr/ + - if @solved_by.length > 0 %table.table.table-bordered.table-striped %thead diff --git a/app/views/surveys/_form.html.haml b/app/views/surveys/_form.html.haml new file mode 100644 index 00000000..bbf8f4d6 --- /dev/null +++ b/app/views/surveys/_form.html.haml @@ -0,0 +1,56 @@ += form_for @survey, html: { class: "well form-inline", style: "margin-bottom:40px;" } do |f| + - if @survey.errors.any? + #error_explanation + %h2= "#{pluralize(@survey.errors.count, "error")} prohibited this survey from being saved:" + %ul + - @survey.errors.full_messages.each do |message| + %li= message + + %h3= t('surveys.new.header') + + .field + = f.label :difficulty + = render partial: "surveys/star_rating", locals: { | + star_5: "rating_difficulty_5", | + star_4: "rating_difficulty_4", | + star_3: "rating_difficulty_3", | + star_2: "rating_difficulty_2", | + star_1: "rating_difficulty_1", | + star_0: "rating_difficulty_0", | + category: :difficulty, | + f: f | + } | + = f.hidden_field :difficulty + .field + = f.label :realism + = render partial: "surveys/star_rating", locals: { | + star_5: "rating_realism_5", | + star_4: "rating_realism_4", | + star_3: "rating_realism_3", | + star_2: "rating_realism_2", | + star_1: "rating_realism_1", | + star_0: "rating_realism_0", | + category: :realism, | + f: f | + } | + = f.hidden_field :realism + .field + = f.label :interest + = render partial: "surveys/star_rating", locals: { | + star_5: "rating_interest_5", | + star_4: "rating_interest_4", | + star_3: "rating_interest_3", | + star_2: "rating_interest_2", | + star_1: "rating_interest_1", | + star_0: "rating_interest_0", | + category: :interest, | + f: f | + } | + = f.hidden_field :interest + .field + = f.label :comment + = f.text_area :comment + .field + = f.hidden_field :submitted_flag_id + .field + = f.submit t('surveys.new.submit_btn'), class: "btn btn-primary" diff --git a/app/views/surveys/_star_rating.html.haml b/app/views/surveys/_star_rating.html.haml new file mode 100644 index 00000000..ff2aa75d --- /dev/null +++ b/app/views/surveys/_star_rating.html.haml @@ -0,0 +1,13 @@ +%span.star-cb-group + = f.radio_button category, 5, { :name => "#{category}", :id => "#{star_5}", :onclick => "setRating('survey_#{category}', '5')" } + %label{:for => "#{star_5}"} 5 + = f.radio_button category, 4, { :name => "#{category}", :id => "#{star_4}", :onclick => "setRating('survey_#{category}', '4')" } + %label{:for => "#{star_4}"} 4 + = f.radio_button category, 3, { :name => "#{category}", :id => "#{star_3}", :onclick => "setRating('survey_#{category}', '3')" } + %label{:for => "#{star_3}"} 3 + = f.radio_button category, 2, { :name => "#{category}", :id => "#{star_2}", :onclick => "setRating('survey_#{category}', '2')" } + %label{:for => "#{star_2}"} 2 + = f.radio_button category, 1, { :name => "#{category}", :id => "#{star_1}", :onclick => "setRating('survey_#{category}', '1')" } + %label{:for => "#{star_1}"} 1 + = f.radio_button category, 0, { :name => "#{category}", :id => "#{star_0}", :class => "star-cb-clear", :onclick => "setRating('survey_#{category}', '0')", :checked => true } + %label{:for => "#{star_0}"} 0 diff --git a/app/views/surveys/edit.html.haml b/app/views/surveys/edit.html.haml new file mode 100644 index 00000000..b5487e1d --- /dev/null +++ b/app/views/surveys/edit.html.haml @@ -0,0 +1,7 @@ +%h1 Editing survey + += render 'form' + += link_to 'Show', @survey +\| += link_to 'Back', surveys_path diff --git a/app/views/surveys/index.html.haml b/app/views/surveys/index.html.haml new file mode 100644 index 00000000..90f84adc --- /dev/null +++ b/app/views/surveys/index.html.haml @@ -0,0 +1,27 @@ +%h1 Listing surveys + +%table.table.table-bordered.table-striped + %thead + %tr + %th Difficulty + %th Realism + %th Interest + %th Comment + %th Submitted flag + + + %tbody + - @surveys.each do |survey| + %tr + %td= survey.difficulty + %td= survey.realism + %td= survey.interest + %td= survey.comment + %td= survey.submitted_flag_id + %td= link_to 'Show', survey + %td= link_to 'Edit', edit_survey_path(survey) + %td= link_to 'Destroy', survey, method: :delete, data: { confirm: 'Are you sure?' } + +%br + += link_to 'New Survey', new_survey_path diff --git a/app/views/surveys/new.html.haml b/app/views/surveys/new.html.haml new file mode 100644 index 00000000..2a68300f --- /dev/null +++ b/app/views/surveys/new.html.haml @@ -0,0 +1,5 @@ +%h1 New survey + += render 'form' + += link_to 'Back', surveys_path diff --git a/app/views/surveys/show.html.haml b/app/views/surveys/show.html.haml new file mode 100644 index 00000000..1111e95b --- /dev/null +++ b/app/views/surveys/show.html.haml @@ -0,0 +1,21 @@ +%p#notice= notice + +%p + %b Difficulty: + = @survey.difficulty +%p + %b Realism: + = @survey.realism +%p + %b Interest: + = @survey.interest +%p + %b Comment: + = @survey.comment +%p + %b Submitted flag: + = @survey.submitted_flag_id + += link_to 'Edit', edit_survey_path(@survey) +\| += link_to 'Back', surveys_path diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb index f2054fb0..f4d297c4 100644 --- a/config/initializers/rails_admin.rb +++ b/config/initializers/rails_admin.rb @@ -19,7 +19,7 @@ config.actions do # root actions dashboard # mandatory - # collection actions + # collection actions index # mandatory new do except ['Challenge', 'FeedItem', 'SolvedChallenge', 'Flag'] # Block users from adding items from their parent classes instead of their own classes @@ -472,7 +472,7 @@ list do field :team_name field :affiliation - field :team_captian + field :team_captain field :division end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9e7f63b3..4121f3b4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -407,3 +407,8 @@ en: unlock_line_1: 'Your account has been locked due to an excessive amount of unsuccessful sign in attempts.' unlock_line_2: 'Click the link below to unlock your account:' unlock_account_link: 'Unlock my account' + surveys: + submitted: 'Survey Submitted!' + new: + header: 'Review Solved Challenge' + submit_btn: 'Submit Survey' diff --git a/config/routes.rb b/config/routes.rb index fe11ffa9..3db74b84 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ # rubocop:disable Metrics/BlockLength Rails.application.routes.draw do + resources :surveys mount RailsAdmin::Engine => '/admin', :as => 'rails_admin' get 'home/index' diff --git a/db/migrate/20200710145833_create_surveys.rb b/db/migrate/20200710145833_create_surveys.rb new file mode 100644 index 00000000..d252e51c --- /dev/null +++ b/db/migrate/20200710145833_create_surveys.rb @@ -0,0 +1,13 @@ +class CreateSurveys < ActiveRecord::Migration[6.0] + def change + create_table :surveys do |t| + t.integer :difficulty, default: 0, null: false + t.integer :realism, default: 0, null: false + t.integer :interest, default: 0, null: false + t.text :comment, default: "", null: true + t.integer :submitted_flag_id, null: false + t.timestamps + end + add_foreign_key "surveys", "submitted_flags" + end +end diff --git a/db/schema.rb b/db/schema.rb index 77cec4b9..37eb707a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_06_23_173255) do +ActiveRecord::Schema.define(version: 2020_07_10_145833) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -178,6 +178,16 @@ t.index ["flag_id"], name: "index_submitted_flags_on_flag_id" end + create_table "surveys", force: :cascade do |t| + t.integer "difficulty", default: 0, null: false + t.integer "realism", default: 0, null: false + t.integer "interest", default: 0, null: false + t.text "comment", default: "" + t.integer "submitted_flag_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + create_table "teams", id: :serial, force: :cascade do |t| t.string "team_name" t.datetime "created_at" @@ -281,5 +291,6 @@ add_foreign_key "challenges", "games" add_foreign_key "flags", "teams" add_foreign_key "submitted_flags", "flags" + add_foreign_key "surveys", "submitted_flags" add_foreign_key "teams", "divisions" end diff --git a/test/controllers/surveys_controller_test.rb b/test/controllers/surveys_controller_test.rb new file mode 100644 index 00000000..161cbb8f --- /dev/null +++ b/test/controllers/surveys_controller_test.rb @@ -0,0 +1,5 @@ +require 'test_helper' + +class SurveysControllerTest < ActionDispatch::IntegrationTest + +end diff --git a/test/factories/surveys.rb b/test/factories/surveys.rb new file mode 100644 index 00000000..cf4bacd7 --- /dev/null +++ b/test/factories/surveys.rb @@ -0,0 +1,9 @@ +FactoryBot.define do + factory :survey do + difficulty { 1 } + realism { 1 } + interest { 1 } + comment { "MyText" } + submitted_flag_id { 1 } + end +end diff --git a/test/models/survey_test.rb b/test/models/survey_test.rb new file mode 100644 index 00000000..c4960fc5 --- /dev/null +++ b/test/models/survey_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class SurveyTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/surveys_test.rb b/test/system/surveys_test.rb new file mode 100644 index 00000000..a538a01a --- /dev/null +++ b/test/system/surveys_test.rb @@ -0,0 +1,51 @@ +require "application_system_test_case" + +class SurveysTest < ApplicationSystemTestCase + setup do + @survey = surveys(:one) + end + + test "visiting the index" do + visit surveys_url + assert_selector "h1", text: "Surveys" + end + + test "creating a Survey" do + visit surveys_url + click_on "New Survey" + + fill_in "Comment", with: @survey.comment + fill_in "Difficulty", with: @survey.difficulty + fill_in "Interest", with: @survey.interest + fill_in "Realism", with: @survey.realism + fill_in "Submitted flag", with: @survey.submitted_flag_id + click_on "Create Survey" + + assert_text "Survey was successfully created" + click_on "Back" + end + + test "updating a Survey" do + visit surveys_url + click_on "Edit", match: :first + + fill_in "Comment", with: @survey.comment + fill_in "Difficulty", with: @survey.difficulty + fill_in "Interest", with: @survey.interest + fill_in "Realism", with: @survey.realism + fill_in "Submitted flag", with: @survey.submitted_flag_id + click_on "Update Survey" + + assert_text "Survey was successfully updated" + click_on "Back" + end + + test "destroying a Survey" do + visit surveys_url + page.accept_confirm do + click_on "Destroy", match: :first + end + + assert_text "Survey was successfully destroyed" + end +end From 36165612db7b8e3ede891d53c76d7a751079a4b0 Mon Sep 17 00:00:00 2001 From: sesheikholeslam Date: Fri, 17 Jul 2020 16:50:22 -0400 Subject: [PATCH 02/12] Fix Unscoped Find Call --- app/models/survey.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/survey.rb b/app/models/survey.rb index 47174ec4..5879a38f 100644 --- a/app/models/survey.rb +++ b/app/models/survey.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Survey < ApplicationRecord - belongs_to :submitted_flag + belongs_to :submitted_flag, optional: true end From b28d472bf190685e8077a2d51aed0c4356705d20 Mon Sep 17 00:00:00 2001 From: sesheikholeslam Date: Fri, 17 Jul 2020 16:57:34 -0400 Subject: [PATCH 03/12] Removed Redundent Semicolon --- app/assets/javascripts/surveys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/surveys.js b/app/assets/javascripts/surveys.js index b2ce9100..89940ab9 100644 --- a/app/assets/javascripts/surveys.js +++ b/app/assets/javascripts/surveys.js @@ -3,4 +3,4 @@ function setRating(id, rating) { document.getElementById(id).value = rating; -}; +} From 33193ec1fbf76267bf9aa898858097c2d7321841 Mon Sep 17 00:00:00 2001 From: sesheikholeslam Date: Wed, 22 Jul 2020 08:41:11 -0400 Subject: [PATCH 04/12] Adds Coverage Tests and Cleanup --- app/controllers/surveys_controller.rb | 40 ---------- app/views/surveys/edit.html.haml | 7 -- app/views/surveys/index.html.haml | 27 ------- app/views/surveys/new.html.haml | 5 -- app/views/surveys/show.html.haml | 21 ----- config/routes.rb | 5 +- .../controllers/challenges_controller_test.rb | 79 +++++++++++++++++++ test/controllers/surveys_controller_test.rb | 21 ++++- 8 files changed, 102 insertions(+), 103 deletions(-) delete mode 100644 app/views/surveys/edit.html.haml delete mode 100644 app/views/surveys/index.html.haml delete mode 100644 app/views/surveys/new.html.haml delete mode 100644 app/views/surveys/show.html.haml diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index 3e31a388..351c2126 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -1,54 +1,14 @@ # frozen_string_literal: true class SurveysController < ApplicationController - before_action :set_survey, only: %i[show edit update destroy] - - # GET /surveys - def index - @surveys = Survey.all - end - - # GET /surveys/1 - def show; end - - # GET /surveys/new - def new - @survey = Survey.new - end - - # GET /surveys/1/edit - def edit; end - - # POST /surveys def create @survey = Survey.new(survey_params) redirect_to '/game', notice: I18n.t('surveys.submitted') if @survey.save end - # PATCH/PUT /surveys/1 - def update - if @survey.update(survey_params) - redirect_to @survey, notice: 'Survey was successfully updated.' - else - render :edit - end - end - - # DELETE /surveys/1 - def destroy - @survey.destroy - redirect_to surveys_url, notice: 'Survey was successfully destroyed.' - end - private - # Use callbacks to share common setup or constraints between actions. - def set_survey - @survey = Survey.find(params[:id]) - end - - # Only allow a trusted parameter "white list" through. def survey_params params.require(:survey).permit(:difficulty, :realism, :interest, :comment, :submitted_flag_id) end diff --git a/app/views/surveys/edit.html.haml b/app/views/surveys/edit.html.haml deleted file mode 100644 index b5487e1d..00000000 --- a/app/views/surveys/edit.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%h1 Editing survey - -= render 'form' - -= link_to 'Show', @survey -\| -= link_to 'Back', surveys_path diff --git a/app/views/surveys/index.html.haml b/app/views/surveys/index.html.haml deleted file mode 100644 index 90f84adc..00000000 --- a/app/views/surveys/index.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -%h1 Listing surveys - -%table.table.table-bordered.table-striped - %thead - %tr - %th Difficulty - %th Realism - %th Interest - %th Comment - %th Submitted flag - - - %tbody - - @surveys.each do |survey| - %tr - %td= survey.difficulty - %td= survey.realism - %td= survey.interest - %td= survey.comment - %td= survey.submitted_flag_id - %td= link_to 'Show', survey - %td= link_to 'Edit', edit_survey_path(survey) - %td= link_to 'Destroy', survey, method: :delete, data: { confirm: 'Are you sure?' } - -%br - -= link_to 'New Survey', new_survey_path diff --git a/app/views/surveys/new.html.haml b/app/views/surveys/new.html.haml deleted file mode 100644 index 2a68300f..00000000 --- a/app/views/surveys/new.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%h1 New survey - -= render 'form' - -= link_to 'Back', surveys_path diff --git a/app/views/surveys/show.html.haml b/app/views/surveys/show.html.haml deleted file mode 100644 index 1111e95b..00000000 --- a/app/views/surveys/show.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -%p#notice= notice - -%p - %b Difficulty: - = @survey.difficulty -%p - %b Realism: - = @survey.realism -%p - %b Interest: - = @survey.interest -%p - %b Comment: - = @survey.comment -%p - %b Submitted flag: - = @survey.submitted_flag_id - -= link_to 'Edit', edit_survey_path(@survey) -\| -= link_to 'Back', surveys_path diff --git a/config/routes.rb b/config/routes.rb index 3db74b84..e4a7a6e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,6 @@ # rubocop:disable Metrics/BlockLength Rails.application.routes.draw do - resources :surveys mount RailsAdmin::Engine => '/admin', :as => 'rails_admin' get 'home/index' @@ -59,6 +58,10 @@ end end + resource :surveys, only: %i[create] do + post :create + end + get '/game/summary' => 'games#summary' get '/game/teams' => 'games#teams' diff --git a/test/controllers/challenges_controller_test.rb b/test/controllers/challenges_controller_test.rb index a5ecd93c..1f5e10a4 100644 --- a/test/controllers/challenges_controller_test.rb +++ b/test/controllers/challenges_controller_test.rb @@ -131,6 +131,32 @@ def setup assert_equal I18n.t('flag.accepted'), flash[:notice] end + test 'solved challenge survey shows for pentest challenge when submitted flag is accepted' do + create(:pentest_solved_challenge, team: @team1, challenge: @pentest_challenge, flag: @team2.defense_flags.first) + sign_in @team1.team_captain + get :show, params: { id: @pentest_challenge, team_id: @team2 } + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end + test 'flag accepted shows on page reload for standard challenge' do create(:standard_solved_challenge, challenge: @standard_challenge, team: @team1) sign_in @team1.team_captain @@ -139,6 +165,32 @@ def setup assert_equal I18n.t('flag.accepted'), flash[:notice] end + test 'solved challenge survey shows for standard challenge when submitted flag is accepted' do + create(:standard_solved_challenge, challenge: @standard_challenge, team: @team1) + sign_in @team1.team_captain + get :show, params: { id: @standard_challenge } + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end + test 'flag accepted shows on page reload for share challenge' do share_chal = create(:share_challenge) create(:standard_solved_challenge, challenge: share_chal, team: @team1) @@ -147,4 +199,31 @@ def setup assert_response :success assert_equal I18n.t('flag.accepted'), flash[:notice] end + + test 'solved challenge survey shows for share challenge when submitted flag is accepted' do + share_chal = create(:share_challenge) + create(:standard_solved_challenge, challenge: share_chal, team: @team1) + sign_in @team1.team_captain + get :show, params: { id: share_chal } + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end end diff --git a/test/controllers/surveys_controller_test.rb b/test/controllers/surveys_controller_test.rb index 161cbb8f..0689ad86 100644 --- a/test/controllers/surveys_controller_test.rb +++ b/test/controllers/surveys_controller_test.rb @@ -1,5 +1,22 @@ require 'test_helper' -class SurveysControllerTest < ActionDispatch::IntegrationTest - +class SurveysControllerTest < ActionController::TestCase + + def setup + create(:active_game) + @team1 = create(:team) + @team2 = create(:team) + @standard_challenge = create(:standard_challenge, flag_count: 3) + @pentest_challenge = create(:pentest_challenge_with_flags) + end + + test 'create new survey' do + team_user = create(:user_with_team) + standard_challenge = create(:standard_challenge) + sign_in team_user + submitted_flag = create(:submitted_flag, user: team_user, challenge: standard_challenge) + post :create, params: { survey: { difficulty: 5, realism: 5, interest: 5, comment: "MyText", submitted_flag_id: submitted_flag.id } } + assert_redirected_to game_path + assert_match I18n.t('surveys.submitted'), flash[:notice] + end end From c136e77a4849e5e07e80a9d19427c327ab413019 Mon Sep 17 00:00:00 2001 From: sesheikholeslam Date: Fri, 24 Jul 2020 12:21:15 -0400 Subject: [PATCH 05/12] Enhancements and Integration Test --- app/helpers/surveys_helper.rb | 4 - app/models/submitted_flag.rb | 2 +- app/views/surveys/_form.html.haml | 33 +------ app/views/surveys/_star_rating.html.haml | 17 +--- .../controllers/challenges_controller_test.rb | 79 ---------------- ...bmitted_flags_survey_display_modes_test.rb | 93 +++++++++++++++++++ 6 files changed, 102 insertions(+), 126 deletions(-) delete mode 100644 app/helpers/surveys_helper.rb create mode 100644 test/integration/submitted_flags_survey_display_modes_test.rb diff --git a/app/helpers/surveys_helper.rb b/app/helpers/surveys_helper.rb deleted file mode 100644 index 10efc10c..00000000 --- a/app/helpers/surveys_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -module SurveysHelper -end diff --git a/app/models/submitted_flag.rb b/app/models/submitted_flag.rb index be62bac3..f5bc435c 100644 --- a/app/models/submitted_flag.rb +++ b/app/models/submitted_flag.rb @@ -3,7 +3,7 @@ class SubmittedFlag < ApplicationRecord belongs_to :user belongs_to :challenge - has_many :surveys, dependent: :destroy + has_one :survey, dependent: :destroy validates :text, presence: true diff --git a/app/views/surveys/_form.html.haml b/app/views/surveys/_form.html.haml index bbf8f4d6..203e9ac5 100644 --- a/app/views/surveys/_form.html.haml +++ b/app/views/surveys/_form.html.haml @@ -10,42 +10,15 @@ .field = f.label :difficulty - = render partial: "surveys/star_rating", locals: { | - star_5: "rating_difficulty_5", | - star_4: "rating_difficulty_4", | - star_3: "rating_difficulty_3", | - star_2: "rating_difficulty_2", | - star_1: "rating_difficulty_1", | - star_0: "rating_difficulty_0", | - category: :difficulty, | - f: f | - } | + = render partial: "surveys/star_rating", locals: { category: :difficulty, f: f } = f.hidden_field :difficulty .field = f.label :realism - = render partial: "surveys/star_rating", locals: { | - star_5: "rating_realism_5", | - star_4: "rating_realism_4", | - star_3: "rating_realism_3", | - star_2: "rating_realism_2", | - star_1: "rating_realism_1", | - star_0: "rating_realism_0", | - category: :realism, | - f: f | - } | + = render partial: "surveys/star_rating", locals: { category: :realism, f: f } = f.hidden_field :realism .field = f.label :interest - = render partial: "surveys/star_rating", locals: { | - star_5: "rating_interest_5", | - star_4: "rating_interest_4", | - star_3: "rating_interest_3", | - star_2: "rating_interest_2", | - star_1: "rating_interest_1", | - star_0: "rating_interest_0", | - category: :interest, | - f: f | - } | + = render partial: "surveys/star_rating", locals: { category: :interest, f: f } = f.hidden_field :interest .field = f.label :comment diff --git a/app/views/surveys/_star_rating.html.haml b/app/views/surveys/_star_rating.html.haml index ff2aa75d..e875146d 100644 --- a/app/views/surveys/_star_rating.html.haml +++ b/app/views/surveys/_star_rating.html.haml @@ -1,13 +1,6 @@ %span.star-cb-group - = f.radio_button category, 5, { :name => "#{category}", :id => "#{star_5}", :onclick => "setRating('survey_#{category}', '5')" } - %label{:for => "#{star_5}"} 5 - = f.radio_button category, 4, { :name => "#{category}", :id => "#{star_4}", :onclick => "setRating('survey_#{category}', '4')" } - %label{:for => "#{star_4}"} 4 - = f.radio_button category, 3, { :name => "#{category}", :id => "#{star_3}", :onclick => "setRating('survey_#{category}', '3')" } - %label{:for => "#{star_3}"} 3 - = f.radio_button category, 2, { :name => "#{category}", :id => "#{star_2}", :onclick => "setRating('survey_#{category}', '2')" } - %label{:for => "#{star_2}"} 2 - = f.radio_button category, 1, { :name => "#{category}", :id => "#{star_1}", :onclick => "setRating('survey_#{category}', '1')" } - %label{:for => "#{star_1}"} 1 - = f.radio_button category, 0, { :name => "#{category}", :id => "#{star_0}", :class => "star-cb-clear", :onclick => "setRating('survey_#{category}', '0')", :checked => true } - %label{:for => "#{star_0}"} 0 + - [5, 4, 3, 2, 1].each do |rating| + = f.radio_button category, rating, { :name => "#{category}", :id => "#{category}_#{rating}", :onclick => "setRating('survey_#{category}', '#{rating}')" } + %label{:for => "#{category}_#{rating}"} + = f.radio_button category, 0, { :name => "#{category}", :id => "#{category}_0", :class => "star-cb-clear", :onclick => "setRating('survey_#{category}', '0')", :checked => true } + %label{:for => "#{category}_0"} 0 diff --git a/test/controllers/challenges_controller_test.rb b/test/controllers/challenges_controller_test.rb index 1f5e10a4..a5ecd93c 100644 --- a/test/controllers/challenges_controller_test.rb +++ b/test/controllers/challenges_controller_test.rb @@ -131,32 +131,6 @@ def setup assert_equal I18n.t('flag.accepted'), flash[:notice] end - test 'solved challenge survey shows for pentest challenge when submitted flag is accepted' do - create(:pentest_solved_challenge, team: @team1, challenge: @pentest_challenge, flag: @team2.defense_flags.first) - sign_in @team1.team_captain - get :show, params: { id: @pentest_challenge, team_id: @team2 } - assert_response :success - if @flag_found - assert_select 'form.well.form-inline' do - assert_select 'h3', I18n.t('surveys.new.header') - assert_select 'div.field', {:count => 3} do - assert_select 'label' - assert_select 'span.star-cb-group' - end - assert_select 'div.field' do - assert_select 'label' - assert_select 'textarea#survey_comment' - end - assert_select 'div.field' do - assert_select 'input#survey_submitted_flag_id' - end - assert_select 'div.field' do - assert_select 'input.btn.btn-primary[type=submit]' - end - end - end - end - test 'flag accepted shows on page reload for standard challenge' do create(:standard_solved_challenge, challenge: @standard_challenge, team: @team1) sign_in @team1.team_captain @@ -165,32 +139,6 @@ def setup assert_equal I18n.t('flag.accepted'), flash[:notice] end - test 'solved challenge survey shows for standard challenge when submitted flag is accepted' do - create(:standard_solved_challenge, challenge: @standard_challenge, team: @team1) - sign_in @team1.team_captain - get :show, params: { id: @standard_challenge } - assert_response :success - if @flag_found - assert_select 'form.well.form-inline' do - assert_select 'h3', I18n.t('surveys.new.header') - assert_select 'div.field', {:count => 3} do - assert_select 'label' - assert_select 'span.star-cb-group' - end - assert_select 'div.field' do - assert_select 'label' - assert_select 'textarea#survey_comment' - end - assert_select 'div.field' do - assert_select 'input#survey_submitted_flag_id' - end - assert_select 'div.field' do - assert_select 'input.btn.btn-primary[type=submit]' - end - end - end - end - test 'flag accepted shows on page reload for share challenge' do share_chal = create(:share_challenge) create(:standard_solved_challenge, challenge: share_chal, team: @team1) @@ -199,31 +147,4 @@ def setup assert_response :success assert_equal I18n.t('flag.accepted'), flash[:notice] end - - test 'solved challenge survey shows for share challenge when submitted flag is accepted' do - share_chal = create(:share_challenge) - create(:standard_solved_challenge, challenge: share_chal, team: @team1) - sign_in @team1.team_captain - get :show, params: { id: share_chal } - assert_response :success - if @flag_found - assert_select 'form.well.form-inline' do - assert_select 'h3', I18n.t('surveys.new.header') - assert_select 'div.field', {:count => 3} do - assert_select 'label' - assert_select 'span.star-cb-group' - end - assert_select 'div.field' do - assert_select 'label' - assert_select 'textarea#survey_comment' - end - assert_select 'div.field' do - assert_select 'input#survey_submitted_flag_id' - end - assert_select 'div.field' do - assert_select 'input.btn.btn-primary[type=submit]' - end - end - end - end end diff --git a/test/integration/submitted_flags_survey_display_modes_test.rb b/test/integration/submitted_flags_survey_display_modes_test.rb new file mode 100644 index 00000000..8d180618 --- /dev/null +++ b/test/integration/submitted_flags_survey_display_modes_test.rb @@ -0,0 +1,93 @@ +require 'test_helper' + +class SubmittedFlagsSurveyDisplayModesTest < ActionDispatch::IntegrationTest + include TeamsHelper + include Devise::Test::IntegrationHelpers + + def setup + create(:active_game) + @team1 = create(:team) + @team2 = create(:team) + @standard_challenge = create(:standard_challenge, flag_count: 3) + @pentest_challenge = create(:pentest_challenge_with_flags) + end + + test 'solved challenge survey shows for pentest challenge when submitted flag is accepted' do + create(:pentest_solved_challenge, team: @team1, challenge: @pentest_challenge, flag: @team2.defense_flags.first) + sign_in @team1.team_captain + get game_team_challenge_path(@team2, @pentest_challenge) + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end + + test 'solved challenge survey shows for standard challenge when submitted flag is accepted' do + create(:standard_solved_challenge, challenge: @standard_challenge, team: @team1) + sign_in @team1.team_captain + get game_challenge_path(@standard_challenge) + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end + + test 'solved challenge survey shows for share challenge when submitted flag is accepted' do + share_chal = create(:share_challenge) + create(:standard_solved_challenge, challenge: share_chal, team: @team1) + sign_in @team1.team_captain + get game_challenge_path(share_chal) + assert_response :success + if @flag_found + assert_select 'form.well.form-inline' do + assert_select 'h3', I18n.t('surveys.new.header') + assert_select 'div.field', {:count => 3} do + assert_select 'label' + assert_select 'span.star-cb-group' + end + assert_select 'div.field' do + assert_select 'label' + assert_select 'textarea#survey_comment' + end + assert_select 'div.field' do + assert_select 'input#survey_submitted_flag_id' + end + assert_select 'div.field' do + assert_select 'input.btn.btn-primary[type=submit]' + end + end + end + end +end From fd5c689227226863eebecd4c6ec52e74ff23f137 Mon Sep 17 00:00:00 2001 From: camdenmoors <66680985+camdenmoors@users.noreply.github.com> Date: Mon, 10 Aug 2020 10:08:32 -0500 Subject: [PATCH 06/12] Removing JavaScript dependency Removing JavaScript dependency manually from within Github, as the desktop client doesn't want to commit directly to this PR. --- app/views/surveys/_form.html.haml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/app/views/surveys/_form.html.haml b/app/views/surveys/_form.html.haml index 203e9ac5..af967b6b 100644 --- a/app/views/surveys/_form.html.haml +++ b/app/views/surveys/_form.html.haml @@ -7,22 +7,19 @@ %li= message %h3= t('surveys.new.header') - - .field - = f.label :difficulty - = render partial: "surveys/star_rating", locals: { category: :difficulty, f: f } - = f.hidden_field :difficulty - .field - = f.label :realism - = render partial: "surveys/star_rating", locals: { category: :realism, f: f } - = f.hidden_field :realism - .field - = f.label :interest - = render partial: "surveys/star_rating", locals: { category: :interest, f: f } - = f.hidden_field :interest - .field - = f.label :comment - = f.text_area :comment + .rating + .field + = f.label :difficulty + = render partial: "surveys/star_rating", locals: { category: :difficulty, f: f } + .field + = f.label :realism + = render partial: "surveys/star_rating", locals: { category: :realism, f: f } + .field + = f.label :interest + = render partial: "surveys/star_rating", locals: { category: :interest, f: f } + .field + = f.label :comment + = f.text_area :comment .field = f.hidden_field :submitted_flag_id .field From 8d54afb51399844516e99089bd238eeff7bf8585 Mon Sep 17 00:00:00 2001 From: camdenmoors <66680985+camdenmoors@users.noreply.github.com> Date: Mon, 10 Aug 2020 10:09:47 -0500 Subject: [PATCH 07/12] Removing JavaScript dependency Removing JavaScript dependency manually from within Github, as the desktop client doesn't want to commit directly to this PR. --- app/views/surveys/_star_rating.html.haml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/views/surveys/_star_rating.html.haml b/app/views/surveys/_star_rating.html.haml index e875146d..2b8a61e2 100644 --- a/app/views/surveys/_star_rating.html.haml +++ b/app/views/surveys/_star_rating.html.haml @@ -1,6 +1,5 @@ -%span.star-cb-group - - [5, 4, 3, 2, 1].each do |rating| - = f.radio_button category, rating, { :name => "#{category}", :id => "#{category}_#{rating}", :onclick => "setRating('survey_#{category}', '#{rating}')" } - %label{:for => "#{category}_#{rating}"} - = f.radio_button category, 0, { :name => "#{category}", :id => "#{category}_0", :class => "star-cb-clear", :onclick => "setRating('survey_#{category}', '0')", :checked => true } - %label{:for => "#{category}_0"} 0 +.rating + %span.star-cb-group + - [5, 4, 3, 2, 1].each do |rating| + = f.radio_button category, rating, { :name => "survey[#{category}]", :id => "#{category}_#{rating}", :value => rating } + %label{:for => "#{category}_#{rating}"} From 22e3c7fa6d5a047588d3ba22556659d8a6dc408f Mon Sep 17 00:00:00 2001 From: camdenmoors <66680985+camdenmoors@users.noreply.github.com> Date: Mon, 10 Aug 2020 10:10:15 -0500 Subject: [PATCH 08/12] Removing JavaScript dependency Removing JavaScript dependency manually from within Github, as the desktop client doesn't want to commit directly to this PR. --- app/assets/javascripts/surveys.js | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 app/assets/javascripts/surveys.js diff --git a/app/assets/javascripts/surveys.js b/app/assets/javascripts/surveys.js deleted file mode 100644 index 89940ab9..00000000 --- a/app/assets/javascripts/surveys.js +++ /dev/null @@ -1,6 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. - -function setRating(id, rating) { - document.getElementById(id).value = rating; -} From 5e2a68782e838c56ed1bdad78430c749458df53d Mon Sep 17 00:00:00 2001 From: Camden Moors Date: Tue, 11 Aug 2020 07:40:56 -0400 Subject: [PATCH 09/12] Use faker for survey factories --- test/controllers/surveys_controller_test.rb | 7 ++++--- test/factories/surveys.rb | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/test/controllers/surveys_controller_test.rb b/test/controllers/surveys_controller_test.rb index 0689ad86..e21c1845 100644 --- a/test/controllers/surveys_controller_test.rb +++ b/test/controllers/surveys_controller_test.rb @@ -12,10 +12,11 @@ def setup test 'create new survey' do team_user = create(:user_with_team) - standard_challenge = create(:standard_challenge) sign_in team_user - submitted_flag = create(:submitted_flag, user: team_user, challenge: standard_challenge) - post :create, params: { survey: { difficulty: 5, realism: 5, interest: 5, comment: "MyText", submitted_flag_id: submitted_flag.id } } + submitted_flag = create(:submitted_flag, user: team_user, challenge: @standard_challenge) + assert_difference 'Survey.count', +1 do + post :create, params: { survey: { difficulty: 5, realism: 5, interest: 5, comment: "MyText", submitted_flag_id: submitted_flag.id } } + end assert_redirected_to game_path assert_match I18n.t('surveys.submitted'), flash[:notice] end diff --git a/test/factories/surveys.rb b/test/factories/surveys.rb index cf4bacd7..6adc3234 100644 --- a/test/factories/surveys.rb +++ b/test/factories/surveys.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + FactoryBot.define do factory :survey do - difficulty { 1 } - realism { 1 } - interest { 1 } + difficulty { Faker::Number.between(from:1, to:5) } + realism { Faker::Number.between(from:1, to:5) } + interest { Faker::Number.between(from:1, to:5) } comment { "MyText" } submitted_flag_id { 1 } end From 93e72187fec5d0ea37d41757997d0290f00ab2c3 Mon Sep 17 00:00:00 2001 From: Camden Moors Date: Tue, 11 Aug 2020 09:29:25 -0400 Subject: [PATCH 10/12] Disable Cop AbcSize on challenge update Using another method here wouldn't make sense, becuase it would still have to check if @flag_found was valid being just as complex. --- app/controllers/challenges_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 535ad15c..2de95514 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -16,6 +16,7 @@ def show flash.now[:notice] = I18n.t('flag.accepted') if @solved_challenge end + # rubocop:disable Metrics/AbcSize def update if @flag_found @solved_challenge = @flag_found.save_solved_challenge(current_user) @@ -29,6 +30,7 @@ def update render :show end + # rubocop:enable Metrics/AbcSize private From 5ec3bc029b2f2cf2fb935bea363e24e56cb6d2a8 Mon Sep 17 00:00:00 2001 From: Camden Moors Date: Thu, 13 Aug 2020 13:54:38 -0400 Subject: [PATCH 11/12] Sync progress to transfer --- Gemfile | 2 ++ Gemfile.lock | 2 ++ app/controllers/challenges_controller.rb | 6 ++++-- app/controllers/surveys_controller.rb | 9 ++++++--- app/models/survey.rb | 1 + app/models/team.rb | 2 +- app/views/challenges/show.html.haml | 2 +- app/views/surveys/_form.html.haml | 2 ++ config/locales/en.yml | 1 + config/routes.rb | 4 +--- db/migrate/20200710145833_create_surveys.rb | 1 + db/schema.rb | 3 +++ 12 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index 01138ed8..c3d02712 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ gem 'awesome_nested_fields' gem 'bootsnap', '>= 1.1.0', require: false gem 'bootstrap-kaminari-views' gem 'bootstrap-sass', '~> 2.3.2.2' +gem 'byebug' gem 'carrierwave-postgresql', '< 0.3.0' # Can be upgraded once https://github.com/diogob/carrierwave-postgresql/issues/33 gem 'chartkick' gem 'delayed_job' @@ -48,6 +49,7 @@ end group :test do gem 'brakeman', require: false gem 'bundler-audit', require: false + gem 'byebug' gem 'ffi-hunspell' gem 'rails-controller-testing' gem 'rubocop', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 31fd9db9..99e6ff0e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,6 +80,7 @@ GEM bundler-audit (0.7.0.1) bundler (>= 1.2.0, < 3) thor (>= 0.18, < 2) + byebug (11.1.3) carrierwave (0.10.0) activemodel (>= 3.2.0) activesupport (>= 3.2.0) @@ -372,6 +373,7 @@ DEPENDENCIES bootstrap-sass (~> 2.3.2.2) brakeman bundler-audit + byebug carrierwave-postgresql (< 0.3.0) chartkick coffee-rails diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 2de95514..84087338 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -14,6 +14,9 @@ def show @solvable = @challenge.can_be_solved_by(current_user.team) @solved_video_url = @solved_challenge.flag.video_url if @solved_challenge flash.now[:notice] = I18n.t('flag.accepted') if @solved_challenge + if @solved_challenge + @survey = Survey.find_by(team: current_user.team.id) + end end # rubocop:disable Metrics/AbcSize @@ -22,8 +25,7 @@ def update @solved_challenge = @flag_found.save_solved_challenge(current_user) @solved_video_url = @flag_found.video_url flash.now[:notice] = I18n.t('flag.accepted') - @survey = Survey.new - @survey.submitted_flag_id = @submitted_flag.id + @survey = Survey.create(submitted_flag_id: @submitted_flag.id, team_id: current_user.team.id) else flash.now[:alert] = wrong_flag_messages.sample end diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index 351c2126..f3906dfd 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -3,13 +3,16 @@ class SurveysController < ApplicationController def create @survey = Survey.new(survey_params) - - redirect_to '/game', notice: I18n.t('surveys.submitted') if @survey.save + if(@survey.save) + return redirect_to '/game', notice: I18n.t('surveys.submitted') + else + return redirect_to '/game', notice: @survey.errors.full_messages + end end private def survey_params - params.require(:survey).permit(:difficulty, :realism, :interest, :comment, :submitted_flag_id) + params.require(:survey).permit(:difficulty, :realism, :interest, :comment, :submitted_flag_id, :team_id) end end diff --git a/app/models/survey.rb b/app/models/survey.rb index 5879a38f..81d4605e 100644 --- a/app/models/survey.rb +++ b/app/models/survey.rb @@ -2,4 +2,5 @@ class Survey < ApplicationRecord belongs_to :submitted_flag, optional: true + belongs_to :team end diff --git a/app/models/team.rb b/app/models/team.rb index e7fed599..f083275c 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -14,7 +14,7 @@ class Team < ApplicationRecord # Current_score is so we don't have to have any logic to handle # which class we are rendering in the game summary view. attr_accessor :rank, :current_score - + has_many :surveys # This has_many is only applicable to Pentest Challenges has_many :defense_flags, dependent: :destroy has_many :feed_items, dependent: :destroy diff --git a/app/views/challenges/show.html.haml b/app/views/challenges/show.html.haml index a5472690..2869e839 100644 --- a/app/views/challenges/show.html.haml +++ b/app/views/challenges/show.html.haml @@ -38,7 +38,7 @@ .control-group = invisible_recaptcha_tags text: 'Submit', :class => "btn btn-primary" -- if @flag_found +- if @solved_challenge %hr/ = render partial: "surveys/form" %hr/ diff --git a/app/views/surveys/_form.html.haml b/app/views/surveys/_form.html.haml index af967b6b..e284145a 100644 --- a/app/views/surveys/_form.html.haml +++ b/app/views/surveys/_form.html.haml @@ -22,5 +22,7 @@ = f.text_area :comment .field = f.hidden_field :submitted_flag_id + .field + = f.hidden_field :team_id .field = f.submit t('surveys.new.submit_btn'), class: "btn btn-primary" diff --git a/config/locales/en.yml b/config/locales/en.yml index 7a9a5f99..4e6c9194 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -436,6 +436,7 @@ en: unlock_account_link: 'Unlock my account' surveys: submitted: 'Survey Submitted!' + invalid: 'Invalid survey submitted.' new: header: 'Review Solved Challenge' submit_btn: 'Submit Survey' diff --git a/config/routes.rb b/config/routes.rb index e4a7a6e2..4640b631 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,9 +58,7 @@ end end - resource :surveys, only: %i[create] do - post :create - end + resource :surveys, only: %i[create update] get '/game/summary' => 'games#summary' get '/game/teams' => 'games#teams' diff --git a/db/migrate/20200710145833_create_surveys.rb b/db/migrate/20200710145833_create_surveys.rb index d252e51c..ca6847d3 100644 --- a/db/migrate/20200710145833_create_surveys.rb +++ b/db/migrate/20200710145833_create_surveys.rb @@ -6,6 +6,7 @@ def change t.integer :interest, default: 0, null: false t.text :comment, default: "", null: true t.integer :submitted_flag_id, null: false + t.references :team, foreign_key: true t.timestamps end add_foreign_key "surveys", "submitted_flags" diff --git a/db/schema.rb b/db/schema.rb index 37eb707a..c2da4786 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -184,8 +184,10 @@ t.integer "interest", default: 0, null: false t.text "comment", default: "" t.integer "submitted_flag_id", null: false + t.bigint "team_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.index ["team_id"], name: "index_surveys_on_team_id" end create_table "teams", id: :serial, force: :cascade do |t| @@ -292,5 +294,6 @@ add_foreign_key "flags", "teams" add_foreign_key "submitted_flags", "flags" add_foreign_key "surveys", "submitted_flags" + add_foreign_key "surveys", "teams" add_foreign_key "teams", "divisions" end From 54cef79dd4595cc774f43841a164c62918ce159b Mon Sep 17 00:00:00 2001 From: Camden Moors Date: Mon, 17 Aug 2020 11:47:02 -0400 Subject: [PATCH 12/12] Show flag submission box on update when incorrect --- app/controllers/challenges_controller.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 84087338..58c0823d 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -14,25 +14,21 @@ def show @solvable = @challenge.can_be_solved_by(current_user.team) @solved_video_url = @solved_challenge.flag.video_url if @solved_challenge flash.now[:notice] = I18n.t('flag.accepted') if @solved_challenge - if @solved_challenge - @survey = Survey.find_by(team: current_user.team.id) - end end - # rubocop:disable Metrics/AbcSize def update if @flag_found @solved_challenge = @flag_found.save_solved_challenge(current_user) @solved_video_url = @flag_found.video_url flash.now[:notice] = I18n.t('flag.accepted') - @survey = Survey.create(submitted_flag_id: @submitted_flag.id, team_id: current_user.team.id) + @survey = Survey.new(submitted_flag_id: @submitted_flag.id) else flash.now[:alert] = wrong_flag_messages.sample + @solvable = @challenge.can_be_solved_by(current_user.team) end render :show end - # rubocop:enable Metrics/AbcSize private