Merge branch 'instance_rules' into 'develop'
Instance rules See merge request pleroma/pleroma!3669
This commit is contained in:
commit
53ef576739
27 changed files with 758 additions and 14 deletions
|
|
@ -1260,6 +1260,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp restrict_quote_url(query, _), do: query
|
||||
|
||||
defp restrict_rule(query, %{rule_id: rule_id}) do
|
||||
from(
|
||||
activity in query,
|
||||
where: fragment("(?)->'rules' \\? (?)", activity.data, ^rule_id)
|
||||
)
|
||||
end
|
||||
|
||||
defp restrict_rule(query, _), do: query
|
||||
|
||||
defp exclude_poll_votes(query, %{include_poll_votes: true}), do: query
|
||||
|
||||
defp exclude_poll_votes(query, _) do
|
||||
|
|
@ -1422,6 +1431,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> restrict_instance(opts)
|
||||
|> restrict_announce_object_actor(opts)
|
||||
|> restrict_filtered(opts)
|
||||
|> restrict_rule(opts)
|
||||
|> restrict_quote_url(opts)
|
||||
|> maybe_restrict_deactivated_users(opts)
|
||||
|> exclude_poll_votes(opts)
|
||||
|
|
|
|||
|
|
@ -721,14 +721,18 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|
||||
#### Flag-related helpers
|
||||
@spec make_flag_data(map(), map()) :: map()
|
||||
def make_flag_data(%{actor: actor, context: context, content: content} = params, additional) do
|
||||
def make_flag_data(
|
||||
%{actor: actor, context: context, content: content} = params,
|
||||
additional
|
||||
) do
|
||||
%{
|
||||
"type" => "Flag",
|
||||
"actor" => actor.ap_id,
|
||||
"content" => content,
|
||||
"object" => build_flag_object(params),
|
||||
"context" => context,
|
||||
"state" => "open"
|
||||
"state" => "open",
|
||||
"rules" => Map.get(params, :rules, nil)
|
||||
}
|
||||
|> Map.merge(additional)
|
||||
end
|
||||
|
|
|
|||
62
lib/pleroma/web/admin_api/controllers/rule_controller.ex
Normal file
62
lib/pleroma/web/admin_api/controllers/rule_controller.ex
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.RuleController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Rule
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [
|
||||
json_response: 3
|
||||
]
|
||||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{scopes: ["admin:write"]}
|
||||
when action in [:create, :update, :delete]
|
||||
)
|
||||
|
||||
plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action == :index)
|
||||
|
||||
action_fallback(AdminAPI.FallbackController)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.RuleOperation
|
||||
|
||||
def index(conn, _) do
|
||||
rules =
|
||||
Rule.query()
|
||||
|> Repo.all()
|
||||
|
||||
render(conn, "index.json", rules: rules)
|
||||
end
|
||||
|
||||
def create(%{body_params: params} = conn, _) do
|
||||
rule =
|
||||
params
|
||||
|> Rule.create()
|
||||
|
||||
render(conn, "show.json", rule: rule)
|
||||
end
|
||||
|
||||
def update(%{body_params: params} = conn, %{id: id}) do
|
||||
rule =
|
||||
params
|
||||
|> Rule.update(id)
|
||||
|
||||
render(conn, "show.json", rule: rule)
|
||||
end
|
||||
|
||||
def delete(conn, %{id: id}) do
|
||||
with {:ok, _} <- Rule.delete(id) do
|
||||
json(conn, %{})
|
||||
else
|
||||
_ -> json_response(conn, :bad_request, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,9 +6,11 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
|
|||
use Pleroma.Web, :view
|
||||
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.Rule
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.AdminAPI.Report
|
||||
alias Pleroma.Web.AdminAPI.RuleView
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
|
|
@ -46,7 +48,8 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
|
|||
as: :activity
|
||||
}),
|
||||
state: report.data["state"],
|
||||
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes})
|
||||
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes}),
|
||||
rules: rules(Map.get(report.data, "rules", nil))
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -71,4 +74,16 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
|
|||
created_at: Utils.to_masto_date(inserted_at)
|
||||
}
|
||||
end
|
||||
|
||||
defp rules(nil) do
|
||||
[]
|
||||
end
|
||||
|
||||
defp rules(rule_ids) do
|
||||
rules =
|
||||
rule_ids
|
||||
|> Rule.get()
|
||||
|
||||
render(RuleView, "index.json", rules: rules)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
22
lib/pleroma/web/admin_api/views/rule_view.ex
Normal file
22
lib/pleroma/web/admin_api/views/rule_view.ex
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.RuleView do
|
||||
use Pleroma.Web, :view
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
def render("index.json", %{rules: rules} = _opts) do
|
||||
render_many(rules, __MODULE__, "show.json")
|
||||
end
|
||||
|
||||
def render("show.json", %{rule: rule} = _opts) do
|
||||
%{
|
||||
id: to_string(rule.id),
|
||||
priority: rule.priority,
|
||||
text: rule.text,
|
||||
hint: rule.hint
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -97,6 +97,7 @@ defmodule Pleroma.Web.ApiSpec do
|
|||
"Frontend management",
|
||||
"Instance configuration",
|
||||
"Instance documents",
|
||||
"Instance rule managment",
|
||||
"Invites",
|
||||
"MediaProxy cache",
|
||||
"OAuth application management",
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
|
|||
report_state(),
|
||||
"Filter by report state"
|
||||
),
|
||||
Operation.parameter(
|
||||
:rule_id,
|
||||
:query,
|
||||
%Schema{type: :string},
|
||||
"Filter by selected rule id"
|
||||
),
|
||||
Operation.parameter(
|
||||
:limit,
|
||||
:query,
|
||||
|
|
@ -169,6 +175,17 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
|
|||
inserted_at: %Schema{type: :string, format: :"date-time"}
|
||||
}
|
||||
}
|
||||
},
|
||||
rules: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
text: %Schema{type: :string},
|
||||
hint: %Schema{type: :string, nullable: true}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
115
lib/pleroma/web/api_spec/operations/admin/rule_operation.ex
Normal file
115
lib/pleroma/web/api_spec/operations/admin/rule_operation.ex
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.Admin.RuleOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Instance rule managment"],
|
||||
summary: "Retrieve list of instance rules",
|
||||
operationId: "AdminAPI.RuleController.index",
|
||||
security: [%{"oAuth" => ["admin:read"]}],
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Response", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: rule()
|
||||
}),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["Instance rule managment"],
|
||||
summary: "Create new rule",
|
||||
operationId: "AdminAPI.RuleController.create",
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: admin_api_params(),
|
||||
requestBody: request_body("Parameters", create_request(), required: true),
|
||||
responses: %{
|
||||
200 => Operation.response("Response", "application/json", rule()),
|
||||
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Instance rule managment"],
|
||||
summary: "Modify existing rule",
|
||||
operationId: "AdminAPI.RuleController.update",
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
parameters: [Operation.parameter(:id, :path, :string, "Rule ID")],
|
||||
requestBody: request_body("Parameters", update_request(), required: true),
|
||||
responses: %{
|
||||
200 => Operation.response("Response", "application/json", rule()),
|
||||
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Instance rule managment"],
|
||||
summary: "Delete rule",
|
||||
operationId: "AdminAPI.RuleController.delete",
|
||||
parameters: [Operation.parameter(:id, :path, :string, "Rule ID")],
|
||||
security: [%{"oAuth" => ["admin:write"]}],
|
||||
responses: %{
|
||||
200 => empty_object_response(),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp create_request do
|
||||
%Schema{
|
||||
type: :object,
|
||||
required: [:text],
|
||||
properties: %{
|
||||
priority: %Schema{type: :integer},
|
||||
text: %Schema{type: :string},
|
||||
hint: %Schema{type: :string}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_request do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
priority: %Schema{type: :integer},
|
||||
text: %Schema{type: :string},
|
||||
hint: %Schema{type: :string}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp rule do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
priority: %Schema{type: :integer},
|
||||
text: %Schema{type: :string},
|
||||
hint: %Schema{type: :string, nullable: true}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -46,6 +46,17 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
end
|
||||
|
||||
def rules_operation do
|
||||
%Operation{
|
||||
tags: ["Instance misc"],
|
||||
summary: "Retrieve list of instance rules",
|
||||
operationId: "InstanceController.rules",
|
||||
responses: %{
|
||||
200 => Operation.response("Array of domains", "application/json", array_of_rules())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp instance do
|
||||
%Schema{
|
||||
type: :object,
|
||||
|
|
@ -181,7 +192,8 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
"urls" => %{
|
||||
"streaming_api" => "wss://lain.com"
|
||||
},
|
||||
"version" => "2.7.2 (compatible; Pleroma 2.0.50-536-g25eec6d7-develop)"
|
||||
"version" => "2.7.2 (compatible; Pleroma 2.0.50-536-g25eec6d7-develop)",
|
||||
"rules" => array_of_rules()
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
@ -371,4 +383,18 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
example: ["pleroma.site", "lain.com", "bikeshed.party"]
|
||||
}
|
||||
end
|
||||
|
||||
defp array_of_rules do
|
||||
%Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
text: %Schema{type: :string},
|
||||
hint: %Schema{type: :string}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
|
|||
default: false,
|
||||
description:
|
||||
"If the account is remote, should the report be forwarded to the remote admin?"
|
||||
},
|
||||
rule_ids: %Schema{
|
||||
type: :array,
|
||||
nullable: true,
|
||||
items: %Schema{type: :string},
|
||||
description: "Array of rules"
|
||||
}
|
||||
},
|
||||
required: [:account_id],
|
||||
|
|
@ -60,7 +66,8 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
|
|||
"account_id" => "123",
|
||||
"status_ids" => ["1337"],
|
||||
"comment" => "bad status!",
|
||||
"forward" => "false"
|
||||
"forward" => "false",
|
||||
"rule_ids" => ["3"]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
alias Pleroma.Formatter
|
||||
alias Pleroma.ModerationLog
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Rule
|
||||
alias Pleroma.ThreadMute
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
|
|
@ -568,14 +569,16 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
def report(user, data) do
|
||||
with {:ok, account} <- get_reported_account(data.account_id),
|
||||
{:ok, {content_html, _, _}} <- make_report_content_html(data[:comment]),
|
||||
{:ok, statuses} <- get_report_statuses(account, data) do
|
||||
{:ok, statuses} <- get_report_statuses(account, data),
|
||||
rules <- get_report_rules(Map.get(data, :rule_ids, nil)) do
|
||||
ActivityPub.flag(%{
|
||||
context: Utils.generate_context_id(),
|
||||
actor: user,
|
||||
account: account,
|
||||
statuses: statuses,
|
||||
content: content_html,
|
||||
forward: Map.get(data, :forward, false)
|
||||
forward: Map.get(data, :forward, false),
|
||||
rules: rules
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -587,6 +590,15 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
end
|
||||
end
|
||||
|
||||
defp get_report_rules(nil) do
|
||||
nil
|
||||
end
|
||||
|
||||
defp get_report_rules(rule_ids) do
|
||||
rule_ids
|
||||
|> Enum.filter(&Rule.exists?/1)
|
||||
end
|
||||
|
||||
def update_report_state(activity_ids, state) when is_list(activity_ids) do
|
||||
case Utils.update_report_state(activity_ids, state) do
|
||||
:ok -> {:ok, activity_ids}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
def peers(conn, _params) do
|
||||
json(conn, Pleroma.Stats.get_peers())
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/instance/rules"
|
||||
def rules(conn, _params) do
|
||||
render(conn, "rules.json")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -76,12 +76,26 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
})
|
||||
end
|
||||
|
||||
def render("rules.json", _) do
|
||||
Pleroma.Rule.query()
|
||||
|> Pleroma.Repo.all()
|
||||
|> render_many(__MODULE__, "rule.json", as: :rule)
|
||||
end
|
||||
|
||||
def render("rule.json", %{rule: rule}) do
|
||||
%{
|
||||
id: to_string(rule.id),
|
||||
text: rule.text,
|
||||
hint: rule.hint || ""
|
||||
}
|
||||
end
|
||||
|
||||
defp common_information(instance) do
|
||||
%{
|
||||
title: Keyword.get(instance, :name),
|
||||
version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
|
||||
languages: Keyword.get(instance, :languages, ["en"]),
|
||||
rules: []
|
||||
rules: render(__MODULE__, "rules.json"),
|
||||
title: Keyword.get(instance, :name),
|
||||
version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})"
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,11 @@ defmodule Pleroma.Web.Router do
|
|||
post("/frontends/install", FrontendController, :install)
|
||||
|
||||
post("/backups", AdminAPIController, :create_backup)
|
||||
|
||||
get("/rules", RuleController, :index)
|
||||
post("/rules", RuleController, :create)
|
||||
patch("/rules/:id", RuleController, :update)
|
||||
delete("/rules/:id", RuleController, :delete)
|
||||
end
|
||||
|
||||
# AdminAPI: admins and mods (staff) can perform these actions (if privileged by role)
|
||||
|
|
@ -764,6 +769,7 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
get("/instance", InstanceController, :show)
|
||||
get("/instance/peers", InstanceController, :peers)
|
||||
get("/instance/rules", InstanceController, :rules)
|
||||
|
||||
get("/statuses", StatusController, :index)
|
||||
get("/statuses/:id", StatusController, :show)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue