Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Commit

Permalink
Add server rules (mastodon#15769)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gargron authored Feb 21, 2021
1 parent dcc7c68 commit 8331fdf
Show file tree
Hide file tree
Showing 21 changed files with 258 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/controllers/about_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def more

toc_generator = TOCGenerator.new(@instance_presenter.site_extended_description)

@rules = Rule.ordered
@contents = toc_generator.html
@table_of_contents = toc_generator.toc
@blocks = DomainBlock.with_user_facing_limitations.by_severity if display_blocks?
Expand Down
59 changes: 59 additions & 0 deletions app/controllers/admin/rules_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

module Admin
class RulesController < BaseController
before_action :set_rule, except: [:index, :create]

def index
authorize :rule, :index?

@rules = Rule.ordered
@rule = Rule.new
end

def create
authorize :rule, :create?

@rule = Rule.new(resource_params)

if @rule.save
redirect_to admin_rules_path
else
@rules = Rule.ordered
render :index
end
end

def edit
authorize @rule, :update?
end

def update
authorize @rule, :update?

if @rule.update(resource_params)
redirect_to admin_rules_path
else
render :edit
end
end

def destroy
authorize @rule, :destroy?

@rule.discard

redirect_to admin_rules_path
end

private

def set_rule
@rule = Rule.find(params[:id])
end

def resource_params
params.require(:rule).permit(:text, :priority)
end
end
end
17 changes: 17 additions & 0 deletions app/controllers/api/v1/instances/rules_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class Api::V1::Instances::RulesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?

before_action :set_rules

def index
render json: @rules, each_serializer: REST::RuleSerializer
end

private

def set_rules
@rules = Rule.ordered
end
end
21 changes: 21 additions & 0 deletions app/javascript/styles/mastodon/about.scss
Original file line number Diff line number Diff line change
Expand Up @@ -884,3 +884,24 @@ $small-breakpoint: 960px;
}
}

.rules-list {
background: darken($ui-base-color, 2%);
border: 1px solid darken($ui-base-color, 8%);
border-radius: 4px;
padding: 0.5em 2.5em !important;
margin-top: 1.85em !important;

li {
border-bottom: 1px solid lighten($ui-base-color, 4%);
color: $dark-text-color;
padding: 1em;

&:last-child {
border-bottom: 0;
}
}

&__text {
color: $primary-text-color;
}
}
22 changes: 22 additions & 0 deletions app/models/rule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

# == Schema Information
#
# Table name: rules
#
# id :bigint(8) not null, primary key
# priority :integer default(0), not null
# deleted_at :datetime
# text :text default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Rule < ApplicationRecord
include Discard::Model

self.discard_column = :deleted_at

validates :text, presence: true, length: { maximum: 300 }

scope :ordered, -> { kept.order(priority: :asc) }
end
19 changes: 19 additions & 0 deletions app/policies/rule_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class RulePolicy < ApplicationPolicy
def index?
staff?
end

def create?
admin?
end

def update?
admin?
end

def destroy?
admin?
end
end
4 changes: 4 additions & 0 deletions app/presenters/instance_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def contact_account
Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, ''))
end

def rules
Rule.ordered
end

def user_count
Rails.cache.fetch('user_count') { User.confirmed.joins(:account).merge(Account.without_suspended).count }
end
Expand Down
4 changes: 3 additions & 1 deletion app/serializers/rest/instance_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ class REST::InstanceSerializer < ActiveModel::Serializer

has_one :contact_account, serializer: REST::AccountSerializer

delegate :contact_account, to: :instance_presenter
has_many :rules, serializer: REST::RuleSerializer

delegate :contact_account, :rules, to: :instance_presenter

def uri
Rails.configuration.x.local_domain
Expand Down
9 changes: 9 additions & 0 deletions app/serializers/rest/rule_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class REST::RuleSerializer < ActiveModel::Serializer
attributes :id, :text

def id
object.id.to_s
end
end
13 changes: 13 additions & 0 deletions app/views/about/more.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@
- else
.box-widget
.rich-formatting
- unless @rules.empty?
%h2#rules= t('about.rules')

%p= t('about.rules_html')

%ol.rules-list
- @rules.each do |rule|
%li
.rules-list__text= rule.text

= @contents.html_safe

- if display_blocks? && [email protected]?
Expand All @@ -70,6 +80,9 @@

.column-4
%ul.table-of-contents
- unless @rules.empty?
%li= link_to t('about.rules'), '#rules'

- @table_of_contents.each do |item|
%li
= link_to item.title, "##{item.anchor}"
Expand Down
11 changes: 11 additions & 0 deletions app/views/admin/rules/_rule.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.announcements-list__item
= link_to edit_admin_rule_path(rule), class: 'announcements-list__item__title' do
= "#{rule_counter + 1}."
= truncate(rule.text)

.announcements-list__item__action-bar
.announcements-list__item__meta
= rule.text

%div
= table_link_to 'trash', t('admin.rules.delete'), admin_rule_path(rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, rule)
11 changes: 11 additions & 0 deletions app/views/admin/rules/edit.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
- content_for :page_title do
= t('admin.rules.edit')

= simple_form_for @rule, url: admin_rule_path(@rule) do |f|
= render 'shared/error_messages', object: @rule

.fields-group
= f.input :text, wrapper: :with_block_label

.actions
= f.button :button, t('generic.save_changes'), type: :submit
24 changes: 24 additions & 0 deletions app/views/admin/rules/index.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
- content_for :page_title do
= t('admin.rules.title')

.simple_form
%p.hint= t('admin.rules.description')

- if can? :create, :rule
= simple_form_for @rule, url: admin_rules_path do |f|
= render 'shared/error_messages', object: @rule

.fields-group
= f.input :text, wrapper: :with_block_label

.actions
= f.button :button, t('admin.rules.add_new'), type: :submit

%hr.spacer/

- if @rules.empty?
%div.muted-hint.center-text
= t 'admin.rules.empty'
- else
.announcements-list
= render partial: 'rule', collection: @rules
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ en:
It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block.
learn_more: Learn more
privacy_policy: Privacy policy
rules: Server rules
rules_html: 'Below is a summary of rules you need to follow if you want to have an account on this server of Mastodon:'
see_whats_happening: See what's happening
server_stats: 'Server stats:'
source_code: Source code
Expand Down Expand Up @@ -542,6 +544,11 @@ en:
unassign: Unassign
unresolved: Unresolved
updated_at: Updated
rules:
add_new: Add rule
description: While most claim to have read and agree to the terms of service, usually people do not read through until after a problem arises. Make it easier to see your server's rules at a glance by providing them in a flat bullet point list. Try to keep individual rules short and simple, but try not to split them up into many separate items either.
edit: Edit rule
title: Server rules
settings:
activity_api_enabled:
desc_html: Counts of locally posted statuses, active users, and new registrations in weekly buckets
Expand Down
4 changes: 4 additions & 0 deletions config/locales/simple_form.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ en:
no_access: Block access to all resources
sign_up_requires_approval: New sign-ups will require your approval
severity: Choose what will happen with requests from this IP
rule:
text: Describe a rule or requirement for users on this server. Try to keep it short and simple
sessions:
otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:'
webauthn: If it's an USB key be sure to insert it and, if necessary, tap it.
Expand Down Expand Up @@ -197,6 +199,8 @@ en:
reblog: Someone boosted your status
report: New report is submitted
trending_tag: An unreviewed hashtag is trending
rule:
text: Rule
tag:
listable: Allow this hashtag to appear in searches and on the profile directory
name: Hashtag
Expand Down
1 change: 1 addition & 0 deletions config/navigation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
n.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_dashboard_url, if: proc { current_user.staff? } do |s|
s.item :dashboard, safe_join([fa_icon('tachometer fw'), t('admin.dashboard.title')]), admin_dashboard_url
s.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/settings}
s.item :rules, safe_join([fa_icon('gavel fw'), t('admin.rules.title')]), admin_rules_path, highlights_on: %r{/admin/rules}
s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements}
s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? && !whitelist_mode? }, highlights_on: %r{/admin/relays}
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@
end

resources :instances, only: [:index, :show], constraints: { id: /[^\/]+/ }
resources :rules

resources :reports, only: [:index, :show] do
member do
Expand Down Expand Up @@ -405,6 +406,7 @@
resource :instance, only: [:show] do
resources :peers, only: [:index], controller: 'instances/peers'
resource :activity, only: [:show], controller: 'instances/activity'
resources :rules, only: [:index], controller: 'instances/rules'
end

resource :domain_blocks, only: [:show, :create, :destroy]
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20210221045109_create_rules.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateRules < ActiveRecord::Migration[5.2]
def change
create_table :rules do |t|
t.integer :priority, null: false, default: 0
t.datetime :deleted_at
t.text :text, null: false, default: ''

t.timestamps
end
end
end
10 changes: 9 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_12_18_054746) do
ActiveRecord::Schema.define(version: 2021_02_21_045109) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -723,6 +723,14 @@
t.index ["target_account_id"], name: "index_reports_on_target_account_id"
end

create_table "rules", force: :cascade do |t|
t.integer "priority", default: 0, null: false
t.datetime "deleted_at"
t.text "text", default: "", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "scheduled_statuses", force: :cascade do |t|
t.bigint "account_id"
t.datetime "scheduled_at"
Expand Down
5 changes: 5 additions & 0 deletions spec/fabricators/rule_fabricator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Fabricator(:rule) do
priority ""
deleted_at "2021-02-21 05:51:09"
text "MyText"
end
5 changes: 5 additions & 0 deletions spec/models/rule_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Rule, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit 8331fdf

Please sign in to comment.