From be04d3528c765207c89e0c2d86f2733a05b284de Mon Sep 17 00:00:00 2001 From: Yuki Date: Thu, 23 Apr 2015 06:26:29 +0530 Subject: [PATCH] Support for ban reasons and ban times. Fixes Retrospring/bugs#26 and Retrospring/bugs#25 --- Rakefile | 63 ++++++++++++++++++- .../javascripts/application.js.erb.coffee | 3 +- .../javascripts/moderation.js.erb.coffee | 2 +- app/assets/javascripts/moderation/ban.coffee | 44 +++++++++++++ .../javascripts/moderation/privileges.coffee | 2 +- app/controllers/ajax/moderation_controller.rb | 44 ++++++++++++- app/controllers/application_controller.rb | 7 +++ app/models/user.rb | 17 +++++ app/views/ajax/moderation/ban.json.jbuilder | 1 + app/views/user/_actions.html.haml | 10 ++- app/views/user/_modal_ban.html.haml | 21 +++++++ app/views/user/_modal_privileges.html.haml | 2 - app/views/user/show.html.haml | 3 +- config/routes.rb | 1 + ...e_banned_to_permanently_banned_in_users.rb | 9 +++ ...dd_ban_reason_and_banned_until_to_users.rb | 6 ++ 16 files changed, 222 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/moderation/ban.coffee create mode 100644 app/views/ajax/moderation/ban.json.jbuilder create mode 100644 app/views/user/_modal_ban.html.haml create mode 100644 db/migrate/20150422224203_rename_banned_to_permanently_banned_in_users.rb create mode 100644 db/migrate/20150422224225_add_ban_reason_and_banned_until_to_users.rb diff --git a/Rakefile b/Rakefile index fba3b892..113524c5 100644 --- a/Rakefile +++ b/Rakefile @@ -94,11 +94,67 @@ namespace :justask do end desc "Hits an user with the banhammer." - task :ban, [:screen_name] => :environment do |t, args| + task :permanently_ban, [:screen_name, :reason] => :environment do |t, args| fail "screen name required" if args[:screen_name].nil? user = User.find_by_screen_name(args[:screen_name]) fail "user #{args[:screen_name]} not found" if user.nil? - user.banned = true + user.permanently_banned = true + user.ban_reason = args[:reason] + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Hits an user with the banhammer for one day." + task :ban, [:screen_name, :reason] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + user.permanently_banned = false + user.banned_until = DateTime.now + 1 + user.ban_reason = args[:reason] + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Hits an user with the banhammer for one week." + task :week_ban, [:screen_name, :reason] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + user.permanently_banned = false + user.banned_until = DateTime.now + 7 + user.ban_reason = args[:reason] + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Hits an user with the banhammer for one month." + task :month_ban, [:screen_name, :reason] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + user.permanently_banned = false + user.banned_until = DateTime.now + 30 + user.ban_reason = args[:reason] + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Hits an user with the banhammer for one year." + task :year_ban, [:screen_name, :reason] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + user.permanently_banned = false + user.banned_until = DateTime.now + 365 + user.ban_reason = args[:reason] + user.save! + puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" + end + + desc "Hits an user with the banhammer for one aeon." + task :aeon_ban, [:screen_name, :reason] => :environment do |t, args| + fail "screen name required" if args[:screen_name].nil? + user = User.find_by_screen_name(args[:screen_name]) + user.permanently_banned = false + user.banned_until = DateTime.now + 365_000_000_000 + user.ban_reason = args[:reason] user.save! puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!" end @@ -108,7 +164,8 @@ namespace :justask do fail "screen name required" if args[:screen_name].nil? user = User.find_by_screen_name(args[:screen_name]) fail "user #{args[:screen_name]} not found" if user.nil? - user.banned = false + user.permanently_banned = false + user.banned_until = DateTime.now - 0.00001 user.save! puts "#{user.screen_name} is no longer banned." end diff --git a/app/assets/javascripts/application.js.erb.coffee b/app/assets/javascripts/application.js.erb.coffee index 9d0839b2..5fe872f9 100644 --- a/app/assets/javascripts/application.js.erb.coffee +++ b/app/assets/javascripts/application.js.erb.coffee @@ -41,7 +41,8 @@ $(document).on "click", "button#create-account", -> Turbolinks.visit "/sign_up" _ready = -> - sweetAlertInitialize() + if typeof sweetAlertInitialize != "undefined" + sweetAlertInitialize() $(document).ready _ready $(document).on 'page:load', _ready diff --git a/app/assets/javascripts/moderation.js.erb.coffee b/app/assets/javascripts/moderation.js.erb.coffee index 5a8a1551..dd1af163 100644 --- a/app/assets/javascripts/moderation.js.erb.coffee +++ b/app/assets/javascripts/moderation.js.erb.coffee @@ -1 +1 @@ -#= require_tree ./moderation \ No newline at end of file +#= require_tree ./moderation diff --git a/app/assets/javascripts/moderation/ban.coffee b/app/assets/javascripts/moderation/ban.coffee new file mode 100644 index 00000000..30e0cd61 --- /dev/null +++ b/app/assets/javascripts/moderation/ban.coffee @@ -0,0 +1,44 @@ +$(document).on "DOMContentLoaded", -> + parent = $ "#ban-control-super" + parent.find('#_ban').on "change", (event) -> + $t = $ this + if $t.is(":checked") + $("#ban-controls").show() + else + $("#ban-controls").hide() + parent.find('#_permaban').on "change", (event) -> + $t = $ this + if $t.is(":checked") + $("#ban-controls-time").hide() + else + $("#ban-controls-time").show() + + parent.parent()[0].addEventListener "submit", (event) -> + event.preventDefault(); + + $("#modal-ban").modal "hide" + + checktostr = (selector) -> + if $(selector)[0].checked + "1" + else + "0" + + data = { + ban: checktostr "#_ban" + permaban: checktostr "#_permaban" + until: $("#until")[0].value + reason: $("#reason")[0].value + user: $("#_user")[0].value + } + + $.ajax + url: '/ajax/mod/ban' + type: 'POST' + data: data + success: (data, status, jqxhr) -> + showNotification data.message, data.success + error: (jqxhr, status, error) -> + console.log jqxhr, status, error + showNotification "An error occurred, a developer should check the console for details", false + complete: (jqxhr, status) -> diff --git a/app/assets/javascripts/moderation/privileges.coffee b/app/assets/javascripts/moderation/privileges.coffee index 6f676851..c64c4c38 100644 --- a/app/assets/javascripts/moderation/privileges.coffee +++ b/app/assets/javascripts/moderation/privileges.coffee @@ -21,4 +21,4 @@ console.log jqxhr, status, error showNotification "An error occurred, a developer should check the console for details", false complete: (jqxhr, status) -> - box.removeAttr "disabled" \ No newline at end of file + box.removeAttr "disabled" diff --git a/app/controllers/ajax/moderation_controller.rb b/app/controllers/ajax/moderation_controller.rb index 12580420..b6b5cb01 100644 --- a/app/controllers/ajax/moderation_controller.rb +++ b/app/controllers/ajax/moderation_controller.rb @@ -105,6 +105,45 @@ class Ajax::ModerationController < ApplicationController @success = true end + def ban + @status = :err + @message = "Weird..." + @success = false + + params.require :user + params.require :ban + params.require :permaban + + reason = params[:reason] + target = User.find_by_screen_name(params[:user]) + unban = params[:ban] == "0" + perma = params[:permaban] == "1" + + buntil = DateTime.strptime params[:until], "%Y-%m-%dT%H:%M" unless unban or perma + + if not unban and target.admin? + @status = :nopriv + @message = "You cannot ban an administrator!" + @success = false + end + + if unban + target.unban + @message = "Unbanned user." + @success = true + elsif perma + target.ban nil, reason + @message = "Permanently banned user." + else + target.ban buntil, reason + @message = "Banned user until #{buntil.to_s}" + end + target.save! + + @status = :okay + @success = target.banned? == !unban + end + def privilege @status = :err @success = false @@ -118,10 +157,9 @@ class Ajax::ModerationController < ApplicationController target_user = User.find_by_screen_name(params[:user]) @message = "nope!" - return unless %w(banned blogger supporter moderator admin contributor).include? params[:type].downcase + return unless %w(blogger supporter moderator admin contributor).include? params[:type].downcase - if (%w(supporter moderator admin).include?(params[:type].downcase) and !current_user.admin?) or - (params[:type].downcase == 'banned' and target_user.admin?) + if %w(supporter moderator admin).include?(params[:type].downcase) and !current_user.admin? @status = :nopriv @message = "You'd better check YOUR privileges first!" @success = false diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 42840939..e178da33 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,6 +12,13 @@ class ApplicationController < ActionController::Base name = current_user.screen_name # obligatory '2001: A Space Odyssey' reference flash[:notice] = "I'm sorry, #{name}, I'm afraid I can't do that." + if current_user.ban_reason.nil? + flash[:notice] += "\nBan reason: #{current_user.ban_reason}" + end + if not current_user.permanently_banned? + # TODO format banned_until + flash[:notice] += "\nBanned until: #{current_user.banned_until}" + end sign_out current_user redirect_to new_user_session_path end diff --git a/app/models/user.rb b/app/models/user.rb index d5b0cff1..9d4eaa2b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -196,4 +196,21 @@ class User < ActiveRecord::Base def cropping? !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank? end + + # forwards fill + def banned? + self.permanently_banned? or ((not self.banned_until.nil?) and self.banned_until > DateTime.now) + end + + def unban + self.update(permanently_banned: false, ban_reason: nil, banned_until: nil) + end + + def ban(buntil=nil, reason=nil) + if buntil == nil + self.update(permanently_banned: true, ban_reason: reason) + else + self.update(permanently_banned: false, banned_until: buntil, ban_reason: reason) + end + end end diff --git a/app/views/ajax/moderation/ban.json.jbuilder b/app/views/ajax/moderation/ban.json.jbuilder new file mode 100644 index 00000000..f98b3c38 --- /dev/null +++ b/app/views/ajax/moderation/ban.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'ajax/shared/status' diff --git a/app/views/user/_actions.html.haml b/app/views/user/_actions.html.haml index 6ed47740..d8678d62 100644 --- a/app/views/user/_actions.html.haml +++ b/app/views/user/_actions.html.haml @@ -35,4 +35,12 @@ Check = succeed "'s" do = user.screen_name - privileges \ No newline at end of file + privileges + %li + %a{href: '#', data: { target: "#modal-ban", toggle: :modal }} + %i.fa.fa-wrench + - if user.banned? + Unban or extend ban duration + - else + Ban + = user.screen_name diff --git a/app/views/user/_modal_ban.html.haml b/app/views/user/_modal_ban.html.haml new file mode 100644 index 00000000..50917c33 --- /dev/null +++ b/app/views/user/_modal_ban.html.haml @@ -0,0 +1,21 @@ +#modal-ban.modal.fade{"aria-hidden" => "true", "aria-labelledby" => "modal-ban-label", :role => "dialog", :tabindex => "-1"} + .modal-dialog + .modal-content + .modal-header + %button.close{"data-dismiss" => "modal", :type => "button"} + %span{"aria-hidden" => "true"} × + %span.sr-only Close + %h4#modal-ban-label.modal-title + Ban Control Center + = bootstrap_form_tag(url: '/mod/ban', html: { method: :post, novalidate: "novalidate" }) do |f| + = f.hidden_field :user, value: @user.screen_name + #ban-control-super.modal-body + = f.check_box :ban, label: "Ban?", checked: @user.banned? + #ban-controls{style: "#{"display: none" unless @user.banned?}"} + = f.check_box :permaban, label: "Permanently?", checked: @user.permanently_banned? + #ban-controls-time{style: "#{"display: none" unless not @user.permanently_banned?}"} + = f.datetime_local_field :until, label: "", required: true, value: (@user.banned_until || DateTime.now).strftime("%Y-%m-%dT%H:%M") + = f.text_field :reason, placeholder: "Reason", value: @user.ban_reason + .modal-footer + %button.btn.btn-default{name: 'stop-time', type: :button, data: { dismiss: :modal }} Close + = f.submit "Hammer Time", class: "btn btn-primary", name: 'hammer-time' diff --git a/app/views/user/_modal_privileges.html.haml b/app/views/user/_modal_privileges.html.haml index 3edbb981..265a3330 100644 --- a/app/views/user/_modal_privileges.html.haml +++ b/app/views/user/_modal_privileges.html.haml @@ -11,8 +11,6 @@ = @user.screen_name privileges %ul.list-group.groups--list - - unless @user.admin? - = render 'user/modal_privileges_item', privilege: 'banned', description: 'Hit the user with ye olde banhammer', user: @user = render 'user/modal_privileges_item', privilege: 'blogger', description: 'The user gets that privilege if they blogged something (nice) about Retrospring.', user: @user = render 'user/modal_privileges_item', privilege: 'contributor', description: "This user has contributed to justask#{" (the software behind #{APP_CONFIG['site_name']})" unless APP_CONFIG['site_name'] == 'justask'}.", user: @user - if current_user.admin? diff --git a/app/views/user/show.html.haml b/app/views/user/show.html.haml index 53401652..252fde35 100644 --- a/app/views/user/show.html.haml +++ b/app/views/user/show.html.haml @@ -18,4 +18,5 @@ - if user_signed_in? = render 'user/modal_group_memberships' - if current_user.mod? and @user != current_user - = render 'user/modal_privileges' \ No newline at end of file + = render 'user/modal_privileges' + = render 'user/modal_ban' diff --git a/config/routes.rb b/config/routes.rb index 475b516a..f267bd9f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,6 +21,7 @@ Rails.application.routes.draw do match '/mod/create_vote', to: 'moderation#vote', via: :post, as: :mod_create_vote match '/mod/destroy_vote', to: 'moderation#destroy_vote', via: :post, as: :mod_destroy_vote match '/mod/privilege', to: 'moderation#privilege', via: :post, as: :mod_privilege + match '/mod/ban', to: 'moderation#ban', via: :post, as: :mod_ban end end diff --git a/db/migrate/20150422224203_rename_banned_to_permanently_banned_in_users.rb b/db/migrate/20150422224203_rename_banned_to_permanently_banned_in_users.rb new file mode 100644 index 00000000..26d50c78 --- /dev/null +++ b/db/migrate/20150422224203_rename_banned_to_permanently_banned_in_users.rb @@ -0,0 +1,9 @@ +class RenameBannedToPermanentlyBannedInUsers < ActiveRecord::Migration + def up + rename_column :users, :banned, :permanently_banned + end + + def down + rename_column :users, :permanently_banned, :banned + end +end diff --git a/db/migrate/20150422224225_add_ban_reason_and_banned_until_to_users.rb b/db/migrate/20150422224225_add_ban_reason_and_banned_until_to_users.rb new file mode 100644 index 00000000..9e2ac7a4 --- /dev/null +++ b/db/migrate/20150422224225_add_ban_reason_and_banned_until_to_users.rb @@ -0,0 +1,6 @@ +class AddBanReasonAndBannedUntilToUsers < ActiveRecord::Migration + def change + add_column :users, :ban_reason, :string, default: nil + add_column :users, :banned_until, :datetime, default: nil + end +end