Merge develop to bump elixir version in the CI so I don't get failing formatting

This commit is contained in:
rinpatch 2019-03-14 22:33:20 +03:00
commit cbdd11c381
131 changed files with 865 additions and 506 deletions

View file

@ -69,8 +69,8 @@
# You can also customize the exit_status of each check. # You can also customize the exit_status of each check.
# If you don't want TODO comments to cause `mix credo` to fail, just # If you don't want TODO comments to cause `mix credo` to fail, just
# set this value to 0 (zero). # set this value to 0 (zero).
{Credo.Check.Design.TagTODO, exit_status: 2}, {Credo.Check.Design.TagTODO, exit_status: 0},
{Credo.Check.Design.TagFIXME}, {Credo.Check.Design.TagFIXME, exit_status: 0},
{Credo.Check.Readability.FunctionNames}, {Credo.Check.Readability.FunctionNames},
{Credo.Check.Readability.LargeNumbers}, {Credo.Check.Readability.LargeNumbers},
@ -81,7 +81,9 @@
{Credo.Check.Readability.ParenthesesOnZeroArityDefs}, {Credo.Check.Readability.ParenthesesOnZeroArityDefs},
{Credo.Check.Readability.ParenthesesInCondition}, {Credo.Check.Readability.ParenthesesInCondition},
{Credo.Check.Readability.PredicateFunctionNames}, {Credo.Check.Readability.PredicateFunctionNames},
{Credo.Check.Readability.PreferImplicitTry}, # lanodan: I think PreferImplicitTry should be consistency, and the behaviour seems
# inconsistent, see: https://github.com/rrrene/credo/issues/224
{Credo.Check.Readability.PreferImplicitTry, false},
{Credo.Check.Readability.RedundantBlankLines}, {Credo.Check.Readability.RedundantBlankLines},
{Credo.Check.Readability.StringSigils}, {Credo.Check.Readability.StringSigils},
{Credo.Check.Readability.TrailingBlankLine}, {Credo.Check.Readability.TrailingBlankLine},
@ -126,10 +128,6 @@
# Deprecated checks (these will be deleted after a grace period) # Deprecated checks (these will be deleted after a grace period)
{Credo.Check.Readability.Specs, false}, {Credo.Check.Readability.Specs, false},
{Credo.Check.Warning.NameRedeclarationByAssignment, false},
{Credo.Check.Warning.NameRedeclarationByCase, false},
{Credo.Check.Warning.NameRedeclarationByDef, false},
{Credo.Check.Warning.NameRedeclarationByFn, false},
# Custom checks can be created using `mix credo.gen.check`. # Custom checks can be created using `mix credo.gen.check`.
# #

View file

@ -1,4 +1,4 @@
image: elixir:1.7.2 image: elixir:1.8.1
services: services:
- name: postgres:9.6.2 - name: postgres:9.6.2
@ -19,6 +19,7 @@ cache:
stages: stages:
- lint - lint
- test - test
- analysis
before_script: before_script:
- mix local.hex --force - mix local.hex --force
@ -37,3 +38,8 @@ unit-testing:
stage: test stage: test
script: script:
- mix test --trace --preload-modules - mix test --trace --preload-modules
analysis:
stage: analysis
script:
- mix credo --strict --only=warnings,todo,fixme,consistency,readability

View file

@ -4,8 +4,8 @@ Feel free to contact us to be added to this list!
## Desktop ## Desktop
### Roma for Desktop ### Roma for Desktop
- Homepage: <http://www.pleroma.com/desktop-app/> - Homepage: <https://www.pleroma.com/#desktopApp>
- Source Code: ??? - Source Code: <https://github.com/roma-apps/roma-desktop>
- Platforms: Windows, Mac, (Linux?) - Platforms: Windows, Mac, (Linux?)
- Features: Streaming Ready - Features: Streaming Ready
@ -44,8 +44,8 @@ Feel free to contact us to be added to this list!
- Features: Streaming Ready - Features: Streaming Ready
### Roma ### Roma
- Homepage: <http://www.pleroma.com/> - Homepage: <https://www.pleroma.com/#mobileApps>
- Source Code: ??? - Source Code: [iOS](https://github.com/roma-apps/roma-ios), [Android](https://github.com/roma-apps/roma-android)
- Platforms: iOS, Android - Platforms: iOS, Android
- Features: No Streaming - Features: No Streaming

View file

@ -13,3 +13,13 @@ Some apps operate under the assumption that no more than 4 attachments can be re
## Timelines ## Timelines
Adding the parameter `with_muted=true` to the timeline queries will also return activities by muted (not by blocked!) users. Adding the parameter `with_muted=true` to the timeline queries will also return activities by muted (not by blocked!) users.
## Statuses
Has these additional fields under the `pleroma` object:
- `local`: true if the post was made on the local instance.
## Accounts
- `/api/v1/accounts/:id`: The `id` parameter can also be the `nickname` of the user. This only works in this endpoint, not the deeper nested ones for following etc.

View file

@ -4,8 +4,8 @@
defmodule Mix.Tasks.Pleroma.Relay do defmodule Mix.Tasks.Pleroma.Relay do
use Mix.Task use Mix.Task
alias Pleroma.Web.ActivityPub.Relay
alias Mix.Tasks.Pleroma.Common alias Mix.Tasks.Pleroma.Common
alias Pleroma.Web.ActivityPub.Relay
@shortdoc "Manages remote relays" @shortdoc "Manages remote relays"
@moduledoc """ @moduledoc """

View file

@ -4,9 +4,9 @@
defmodule Mix.Tasks.Pleroma.Uploads do defmodule Mix.Tasks.Pleroma.Uploads do
use Mix.Task use Mix.Task
alias Mix.Tasks.Pleroma.Common
alias Pleroma.Upload alias Pleroma.Upload
alias Pleroma.Uploaders.Local alias Pleroma.Uploaders.Local
alias Mix.Tasks.Pleroma.Common
require Logger require Logger
@log_every 50 @log_every 50
@ -20,7 +20,6 @@ defmodule Mix.Tasks.Pleroma.Uploads do
Options: Options:
- `--delete` - delete local uploads after migrating them to the target uploader - `--delete` - delete local uploads after migrating them to the target uploader
A list of available uploaders can be seen in config.exs A list of available uploaders can be seen in config.exs
""" """
def run(["migrate_local", target_uploader | args]) do def run(["migrate_local", target_uploader | args]) do

View file

@ -5,9 +5,9 @@
defmodule Mix.Tasks.Pleroma.User do defmodule Mix.Tasks.Pleroma.User do
use Mix.Task use Mix.Task
import Ecto.Changeset import Ecto.Changeset
alias Mix.Tasks.Pleroma.Common
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Mix.Tasks.Pleroma.Common
@shortdoc "Manages Pleroma users" @shortdoc "Manages Pleroma users"
@moduledoc """ @moduledoc """

View file

@ -7,9 +7,9 @@ defmodule Pleroma.PasswordResetToken do
import Ecto.Changeset import Ecto.Changeset
alias Pleroma.User
alias Pleroma.Repo
alias Pleroma.PasswordResetToken alias Pleroma.PasswordResetToken
alias Pleroma.Repo
alias Pleroma.User
schema "password_reset_tokens" do schema "password_reset_tokens" do
belongs_to(:user, User, type: Pleroma.FlakeId) belongs_to(:user, User, type: Pleroma.FlakeId)

View file

@ -5,9 +5,9 @@
defmodule Pleroma.Activity do defmodule Pleroma.Activity do
use Ecto.Schema use Ecto.Schema
alias Pleroma.Repo
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Repo
import Ecto.Query import Ecto.Query
@ -107,6 +107,18 @@ def get_in_reply_to_activity(%Activity{data: %{"object" => %{"inReplyTo" => ap_i
def get_in_reply_to_activity(_), do: nil def get_in_reply_to_activity(_), do: nil
def delete_by_ap_id(id) when is_binary(id) do
by_object_ap_id(id)
|> Repo.delete_all(returning: true)
|> elem(1)
|> Enum.find(fn
%{data: %{"type" => "Create", "object" => %{"id" => ap_id}}} -> ap_id == id
_ -> nil
end)
end
def delete_by_ap_id(_), do: nil
for {ap_type, type} <- @mastodon_notification_types do for {ap_type, type} <- @mastodon_notification_types do
def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}), def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}),
do: unquote(type) do: unquote(type)

View file

@ -11,10 +11,10 @@ defmodule Pleroma.Application do
@repository Mix.Project.config()[:source_url] @repository Mix.Project.config()[:source_url]
def name, do: @name def name, do: @name
def version, do: @version def version, do: @version
def named_version(), do: @name <> " " <> @version def named_version, do: @name <> " " <> @version
def repository, do: @repository def repository, do: @repository
def user_agent() do def user_agent do
info = "#{Pleroma.Web.base_url()} <#{Pleroma.Config.get([:instance, :email], "")}>" info = "#{Pleroma.Web.base_url()} <#{Pleroma.Config.get([:instance, :email], "")}>"
named_version() <> "; " <> info named_version() <> "; " <> info
end end
@ -48,7 +48,7 @@ def start(_type, _args) do
[ [
:user_cache, :user_cache,
[ [
default_ttl: 25000, default_ttl: 25_000,
ttl_interval: 1000, ttl_interval: 1000,
limit: 2500 limit: 2500
] ]
@ -60,7 +60,7 @@ def start(_type, _args) do
[ [
:object_cache, :object_cache,
[ [
default_ttl: 25000, default_ttl: 25_000,
ttl_interval: 1000, ttl_interval: 1000,
limit: 2500 limit: 2500
] ]
@ -127,7 +127,7 @@ def start(_type, _args) do
Supervisor.start_link(children, opts) Supervisor.start_link(children, opts)
end end
def enabled_hackney_pools() do def enabled_hackney_pools do
[:media] ++ [:media] ++
if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do
[:federation] [:federation]
@ -142,14 +142,14 @@ def enabled_hackney_pools() do
end end
if Mix.env() == :test do if Mix.env() == :test do
defp streamer_child(), do: [] defp streamer_child, do: []
defp chat_child(), do: [] defp chat_child, do: []
else else
defp streamer_child() do defp streamer_child do
[worker(Pleroma.Web.Streamer, [])] [worker(Pleroma.Web.Streamer, [])]
end end
defp chat_child() do defp chat_child do
if Pleroma.Config.get([:chat, :enabled]) do if Pleroma.Config.get([:chat, :enabled]) do
[worker(Pleroma.Web.ChatChannel.ChatChannelState, [])] [worker(Pleroma.Web.ChatChannel.ChatChannelState, [])]
else else
@ -158,7 +158,7 @@ defp chat_child() do
end end
end end
defp hackney_pool_children() do defp hackney_pool_children do
for pool <- enabled_hackney_pools() do for pool <- enabled_hackney_pools() do
options = Pleroma.Config.get([:hackney_pools, pool]) options = Pleroma.Config.get([:hackney_pools, pool])
:hackney_pool.child_spec(pool, options) :hackney_pool.child_spec(pool, options)

View file

@ -10,7 +10,7 @@ defmodule Pleroma.Captcha do
use GenServer use GenServer
@doc false @doc false
def start_link() do def start_link do
GenServer.start_link(__MODULE__, [], name: __MODULE__) GenServer.start_link(__MODULE__, [], name: __MODULE__)
end end
@ -22,7 +22,7 @@ def init(_) do
@doc """ @doc """
Ask the configured captcha service for a new captcha Ask the configured captcha service for a new captcha
""" """
def new() do def new do
GenServer.call(__MODULE__, :new) GenServer.call(__MODULE__, :new)
end end
@ -73,7 +73,7 @@ def handle_call({:validate, token, captcha, answer_data}, _from, state) do
secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt") secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt")
sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign") sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign")
# If the time found is less than (current_time - seconds_valid), then the time has already passed. # If the time found is less than (current_time-seconds_valid) then the time has already passed
# Later we check that the time found is more than the presumed invalidatation time, that means # Later we check that the time found is more than the presumed invalidatation time, that means
# that the data is still valid and the captcha can be checked # that the data is still valid and the captcha can be checked
seconds_valid = Pleroma.Config.get!([Pleroma.Captcha, :seconds_valid]) seconds_valid = Pleroma.Config.get!([Pleroma.Captcha, :seconds_valid])

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Captcha.Kocaptcha do
@behaviour Service @behaviour Service
@impl Service @impl Service
def new() do def new do
endpoint = Pleroma.Config.get!([__MODULE__, :endpoint]) endpoint = Pleroma.Config.get!([__MODULE__, :endpoint])
case Tesla.get(endpoint <> "/new") do case Tesla.get(endpoint <> "/new") do

View file

@ -7,13 +7,13 @@ defmodule Pleroma.Clippy do
# No software is complete until they have a Clippy implementation. # No software is complete until they have a Clippy implementation.
# A ballmer peak _may_ be required to change this module. # A ballmer peak _may_ be required to change this module.
def tip() do def tip do
tips() tips()
|> Enum.random() |> Enum.random()
|> puts() |> puts()
end end
def tips() do def tips do
host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
[ [
@ -92,8 +92,8 @@ def puts(text_or_lines) do
# surrond one/five line clippy with blank lines around to not fuck up the layout # surrond one/five line clippy with blank lines around to not fuck up the layout
# #
# yes this fix sucks but it's good enough, have you ever seen a release of windows wihtout some butched # yes this fix sucks but it's good enough, have you ever seen a release of windows
# features anyway? # without some butched features anyway?
lines = lines =
if length(lines) == 1 or length(lines) == 5 do if length(lines) == 1 or length(lines) == 5 do
[""] ++ lines ++ [""] [""] ++ lines ++ [""]

View file

@ -5,7 +5,7 @@
defmodule Pleroma.Config.DeprecationWarnings do defmodule Pleroma.Config.DeprecationWarnings do
require Logger require Logger
def check_frontend_config_mechanism() do def check_frontend_config_mechanism do
if Pleroma.Config.get(:fe) do if Pleroma.Config.get(:fe) do
Logger.warn(""" Logger.warn("""
!!!DEPRECATION WARNING!!! !!!DEPRECATION WARNING!!!

View file

@ -17,13 +17,13 @@ defmodule Pleroma.Emoji do
@ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}] @ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}]
@doc false @doc false
def start_link() do def start_link do
GenServer.start_link(__MODULE__, [], name: __MODULE__) GenServer.start_link(__MODULE__, [], name: __MODULE__)
end end
@doc "Reloads the emojis from disk." @doc "Reloads the emojis from disk."
@spec reload() :: :ok @spec reload() :: :ok
def reload() do def reload do
GenServer.call(__MODULE__, :reload) GenServer.call(__MODULE__, :reload)
end end
@ -38,7 +38,7 @@ def get(name) do
@doc "Returns all the emojos!!" @doc "Returns all the emojos!!"
@spec get_all() :: [{String.t(), String.t()}, ...] @spec get_all() :: [{String.t(), String.t()}, ...]
def get_all() do def get_all do
:ets.tab2list(@ets) :ets.tab2list(@ets)
end end
@ -72,7 +72,7 @@ def code_change(_old_vsn, state, _extra) do
{:ok, state} {:ok, state}
end end
defp load() do defp load do
emojis = emojis =
(load_finmoji(Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)) ++ (load_finmoji(Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)) ++
load_from_file("config/emoji.txt") ++ load_from_file("config/emoji.txt") ++

View file

@ -8,8 +8,8 @@ defmodule Pleroma.Filter do
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
schema "filters" do schema "filters" do
belongs_to(:user, User, type: Pleroma.FlakeId) belongs_to(:user, User, type: Pleroma.FlakeId)

View file

@ -85,7 +85,7 @@ def dump(value) do
{:ok, FlakeId.from_string(value)} {:ok, FlakeId.from_string(value)}
end end
def autogenerate(), do: get() def autogenerate, do: get()
# -- GenServer API # -- GenServer API
def start_link do def start_link do
@ -165,7 +165,7 @@ defp time do
1_000_000_000 * mega_seconds + seconds * 1000 + :erlang.trunc(micro_seconds / 1000) 1_000_000_000 * mega_seconds + seconds * 1000 + :erlang.trunc(micro_seconds / 1000)
end end
defp worker_id() do defp worker_id do
<<worker::integer-size(48)>> = :crypto.strong_rand_bytes(6) <<worker::integer-size(48)>> = :crypto.strong_rand_bytes(6)
worker worker
end end

View file

@ -10,6 +10,7 @@ defmodule Pleroma.Formatter do
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
@link_regex ~r{((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+}ui @link_regex ~r{((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+}ui
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
@auto_linker_config hashtag: true, @auto_linker_config hashtag: true,
hashtag_handler: &Pleroma.Formatter.hashtag_handler/4, hashtag_handler: &Pleroma.Formatter.hashtag_handler/4,

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Gopher.Server do
use GenServer use GenServer
require Logger require Logger
def start_link() do def start_link do
config = Pleroma.Config.get(:gopher, []) config = Pleroma.Config.get(:gopher, [])
ip = Keyword.get(config, :ip, {0, 0, 0, 0}) ip = Keyword.get(config, :ip, {0, 0, 0, 0})
port = Keyword.get(config, :port, 1234) port = Keyword.get(config, :port, 1234)
@ -36,12 +36,12 @@ def init([ip, port]) do
end end
defmodule Pleroma.Gopher.Server.ProtocolHandler do defmodule Pleroma.Gopher.Server.ProtocolHandler do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
def start_link(ref, socket, transport, opts) do def start_link(ref, socket, transport, opts) do
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts]) pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])

View file

@ -9,7 +9,7 @@ defp get_scrubbers(scrubber) when is_atom(scrubber), do: [scrubber]
defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers
defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default] defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default]
def get_scrubbers() do def get_scrubbers do
Pleroma.Config.get([:markup, :scrub_policy]) Pleroma.Config.get([:markup, :scrub_policy])
|> get_scrubbers |> get_scrubbers
end end

View file

@ -2,8 +2,8 @@ defmodule Pleroma.Instances.Instance do
@moduledoc "Instance." @moduledoc "Instance."
alias Pleroma.Instances alias Pleroma.Instances
alias Pleroma.Repo
alias Pleroma.Instances.Instance alias Pleroma.Instances.Instance
alias Pleroma.Repo
use Ecto.Schema use Ecto.Schema

View file

@ -5,12 +5,12 @@
defmodule Pleroma.Notification do defmodule Pleroma.Notification do
use Ecto.Schema use Ecto.Schema
alias Pleroma.User
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.User
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
import Ecto.Query import Ecto.Query

View file

@ -5,11 +5,11 @@
defmodule Pleroma.Object do defmodule Pleroma.Object do
use Ecto.Schema use Ecto.Schema
alias Pleroma.Repo
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.ObjectTombstone alias Pleroma.ObjectTombstone
alias Pleroma.Repo
alias Pleroma.User
import Ecto.Query import Ecto.Query
import Ecto.Changeset import Ecto.Changeset
@ -86,9 +86,9 @@ def swap_object_with_tombstone(object) do
def delete(%Object{data: %{"id" => id}} = object) do def delete(%Object{data: %{"id" => id}} = object) do
with {:ok, _obj} = swap_object_with_tombstone(object), with {:ok, _obj} = swap_object_with_tombstone(object),
Repo.delete_all(Activity.by_object_ap_id(id)), deleted_activity = Activity.delete_by_ap_id(id),
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do
{:ok, object} {:ok, object, deleted_activity}
end end
end end

View file

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
alias Pleroma.Web.HTTPSignatures
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.HTTPSignatures
import Plug.Conn import Plug.Conn
require Logger require Logger

View file

@ -6,8 +6,8 @@ defmodule Pleroma.Plugs.OAuthPlug do
import Plug.Conn import Plug.Conn
import Ecto.Query import Ecto.Query
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
@realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i") @realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i")
@ -38,6 +38,7 @@ defp fetch_user_and_token(token) do
preload: [user: user] preload: [user: user]
) )
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
with %Token{user: %{info: %{deactivated: false} = _} = user} = token_record <- Repo.one(query) do with %Token{user: %{info: %{deactivated: false} = _} = user} = token_record <- Repo.one(query) do
{:ok, user, token_record} {:ok, user, token_record}
end end

View file

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UserFetcherPlug do defmodule Pleroma.Plugs.UserFetcherPlug do
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
import Plug.Conn import Plug.Conn

View file

@ -3,10 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReverseProxy do defmodule Pleroma.ReverseProxy do
@keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since if-none-match if-range range) @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since) ++
~w(if-unmodified-since if-none-match if-range range)
@resp_cache_headers ~w(etag date last-modified cache-control) @resp_cache_headers ~w(etag date last-modified cache-control)
@keep_resp_headers @resp_cache_headers ++ @keep_resp_headers @resp_cache_headers ++
~w(content-type content-disposition content-encoding content-range accept-ranges vary) ~w(content-type content-disposition content-encoding content-range) ++
~w(accept-ranges vary)
@default_cache_control_header "public, max-age=1209600" @default_cache_control_header "public, max-age=1209600"
@valid_resp_codes [200, 206, 304] @valid_resp_codes [200, 206, 304]
@max_read_duration :timer.seconds(30) @max_read_duration :timer.seconds(30)
@ -282,8 +284,8 @@ defp build_resp_cache_headers(headers, _opts) do
headers headers
has_cache? -> has_cache? ->
# There's caching header present but no cache-control -- we need to explicitely override it to public # There's caching header present but no cache-control -- we need to explicitely override it
# as Plug defaults to "max-age=0, private, must-revalidate" # to public as Plug defaults to "max-age=0, private, must-revalidate"
List.keystore(headers, "cache-control", 0, {"cache-control", "public"}) List.keystore(headers, "cache-control", 0, {"cache-control", "public"})
true -> true ->

View file

@ -4,8 +4,8 @@
defmodule Pleroma.Stats do defmodule Pleroma.Stats do
import Ecto.Query import Ecto.Query
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
def start_link do def start_link do
agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__) agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__)

View file

@ -4,7 +4,11 @@
defmodule Pleroma.ThreadMute do defmodule Pleroma.ThreadMute do
use Ecto.Schema use Ecto.Schema
alias Pleroma.{Repo, User, ThreadMute}
alias Pleroma.Repo
alias Pleroma.ThreadMute
alias Pleroma.User
require Ecto.Query require Ecto.Query
schema "thread_mutes" do schema "thread_mutes" do

View file

@ -6,7 +6,8 @@ defmodule Pleroma.Uploaders.S3 do
@behaviour Pleroma.Uploaders.Uploader @behaviour Pleroma.Uploaders.Uploader
require Logger require Logger
# The file name is re-encoded with S3's constraints here to comply with previous links with less strict filenames # The file name is re-encoded with S3's constraints here to comply with previous
# links with less strict filenames
def get_file(file) do def get_file(file) do
config = Pleroma.Config.get([__MODULE__]) config = Pleroma.Config.get([__MODULE__])
bucket = Keyword.fetch!(config, :bucket) bucket = Keyword.fetch!(config, :bucket)

View file

@ -17,7 +17,7 @@ def process_response_body(body) do
|> Poison.decode!() |> Poison.decode!()
end end
def get_token() do def get_token do
settings = Pleroma.Config.get(Pleroma.Uploaders.Swift) settings = Pleroma.Config.get(Pleroma.Uploaders.Swift)
username = Keyword.fetch!(settings, :username) username = Keyword.fetch!(settings, :username)
password = Keyword.fetch!(settings, :password) password = Keyword.fetch!(settings, :password)

View file

@ -29,7 +29,6 @@ defmodule Pleroma.Uploaders.Uploader do
* `{:error, String.t}` error information if the file failed to be saved to the backend. * `{:error, String.t}` error information if the file failed to be saved to the backend.
* `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method. * `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method.
""" """
@type file_spec :: {:file | :url, String.t()} @type file_spec :: {:file | :url, String.t()}
@callback put_file(Pleroma.Upload.t()) :: @callback put_file(Pleroma.Upload.t()) ::

View file

@ -8,21 +8,21 @@ defmodule Pleroma.User do
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
alias Comeonin.Pbkdf2
alias Pleroma.Activity
alias Pleroma.Formatter
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Object
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Activity
alias Pleroma.Notification
alias Comeonin.Pbkdf2
alias Pleroma.Formatter
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
alias Pleroma.Web.OStatus
alias Pleroma.Web.Websub
alias Pleroma.Web.OAuth
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
alias Pleroma.Web.OAuth
alias Pleroma.Web.OStatus
alias Pleroma.Web.RelMe alias Pleroma.Web.RelMe
alias Pleroma.Web.Websub
require Logger require Logger
@ -30,6 +30,7 @@ defmodule Pleroma.User do
@primary_key {:id, Pleroma.FlakeId, autogenerate: true} @primary_key {:id, Pleroma.FlakeId, autogenerate: true}
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
@strict_local_nickname_regex ~r/^[a-zA-Z\d]+$/ @strict_local_nickname_regex ~r/^[a-zA-Z\d]+$/
@ -285,7 +286,7 @@ def needs_update?(%User{local: true}), do: false
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
def needs_update?(%User{local: false} = user) do def needs_update?(%User{local: false} = user) do
NaiveDateTime.diff(NaiveDateTime.utc_now(), user.last_refreshed_at) >= 86400 NaiveDateTime.diff(NaiveDateTime.utc_now(), user.last_refreshed_at) >= 86_400
end end
def needs_update?(_), do: true def needs_update?(_), do: true
@ -435,7 +436,8 @@ def get_by_ap_id(ap_id) do
Repo.get_by(User, ap_id: ap_id) Repo.get_by(User, ap_id: ap_id)
end end
# This is mostly an SPC migration fix. This guesses the user nickname (by taking the last part of the ap_id and the domain) and tries to get that user # This is mostly an SPC migration fix. This guesses the user nickname by taking the last part
# of the ap_id and the domain and tries to get that user
def get_by_guessed_nickname(ap_id) do def get_by_guessed_nickname(ap_id) do
domain = URI.parse(ap_id).host domain = URI.parse(ap_id).host
name = List.last(String.split(ap_id, "/")) name = List.last(String.split(ap_id, "/"))
@ -1340,7 +1342,7 @@ defp normalize_tags(tags) do
|> Enum.map(&String.downcase(&1)) |> Enum.map(&String.downcase(&1))
end end
defp local_nickname_regex() do defp local_nickname_regex do
if Pleroma.Config.get([:instance, :extended_nickname_format]) do if Pleroma.Config.get([:instance, :extended_nickname_format]) do
@extended_local_nickname_regex @extended_local_nickname_regex
else else

View file

@ -6,6 +6,8 @@ defmodule Pleroma.User.Info do
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Pleroma.User.Info
embedded_schema do embedded_schema do
field(:banner, :map, default: %{}) field(:banner, :map, default: %{})
field(:background, :map, default: %{}) field(:background, :map, default: %{})
@ -250,4 +252,11 @@ def remove_pinnned_activity(info, %Pleroma.Activity{id: id}) do
cast(info, params, [:pinned_activities]) cast(info, params, [:pinned_activities])
end end
def roles(%Info{is_moderator: is_moderator, is_admin: is_admin}) do
%{
admin: is_admin,
moderator: is_moderator
}
end
end end

View file

@ -14,7 +14,7 @@ def post_welcome_message_to_user(user) do
end end
end end
defp welcome_user() do defp welcome_user do
with nickname when is_binary(nickname) <- with nickname when is_binary(nickname) <-
Pleroma.Config.get([:instance, :welcome_user_nickname]), Pleroma.Config.get([:instance, :welcome_user_nickname]),
%User{local: true} = user <- User.get_cached_by_nickname(nickname) do %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
@ -24,7 +24,7 @@ defp welcome_user() do
end end
end end
defp welcome_message() do defp welcome_message do
Pleroma.Config.get([:instance, :welcome_message]) Pleroma.Config.get([:instance, :welcome_message])
end end
end end

View file

@ -7,8 +7,8 @@ defmodule Pleroma.UserInviteToken do
import Ecto.Changeset import Ecto.Changeset
alias Pleroma.UserInviteToken
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.UserInviteToken
schema "user_invite_tokens" do schema "user_invite_tokens" do
field(:token, :string) field(:token, :string)

View file

@ -4,17 +4,17 @@
defmodule Pleroma.Web.ActivityPub.ActivityPub do defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Repo alias Pleroma.Instances
alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Upload alias Pleroma.Upload
alias Pleroma.User alias Pleroma.User
alias Pleroma.Notification
alias Pleroma.Instances
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.WebFinger alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.Federator alias Pleroma.Web.Federator
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.WebFinger
import Ecto.Query import Ecto.Query
import Pleroma.Web.ActivityPub.Utils import Pleroma.Web.ActivityPub.Utils
@ -170,7 +170,8 @@ def create(%{to: to, actor: actor, context: context, object: object} = params) d
additional additional
), ),
{:ok, activity} <- insert(create_data, local), {:ok, activity} <- insert(create_data, local),
# Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info # Changing note count prior to enqueuing federation task in order to avoid
# race conditions on updating user.info
{:ok, _actor} <- increase_note_count_if_public(actor, activity), {:ok, _actor} <- increase_note_count_if_public(actor, activity),
:ok <- maybe_federate(activity) do :ok <- maybe_federate(activity) do
{:ok, activity} {:ok, activity}
@ -309,18 +310,19 @@ def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do
user = User.get_cached_by_ap_id(actor) user = User.get_cached_by_ap_id(actor)
to = object.data["to"] || [] ++ object.data["cc"] || [] to = (object.data["to"] || []) ++ (object.data["cc"] || [])
data = %{ with {:ok, object, activity} <- Object.delete(object),
data <- %{
"type" => "Delete", "type" => "Delete",
"actor" => actor, "actor" => actor,
"object" => id, "object" => id,
"to" => to "to" => to,
} "deleted_activity_id" => activity && activity.id
},
with {:ok, _} <- Object.delete(object),
{:ok, activity} <- insert(data, local), {:ok, activity} <- insert(data, local),
# Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info # Changing note count prior to enqueuing federation task in order to avoid
# race conditions on updating user.info
{:ok, _actor} <- decrease_note_count_if_public(user, object), {:ok, _actor} <- decrease_note_count_if_public(user, object),
:ok <- maybe_federate(activity) do :ok <- maybe_federate(activity) do
{:ok, activity} {:ok, activity}
@ -502,7 +504,7 @@ defp restrict_tag_reject(query, %{"tag_reject" => tag_reject})
when is_list(tag_reject) and tag_reject != [] do when is_list(tag_reject) and tag_reject != [] do
from( from(
activity in query, activity in query,
where: fragment("(not (? #> '{\"object\",\"tag\"}') \\?| ?)", activity.data, ^tag_reject) where: fragment(~s(\(not \(? #> '{"object","tag"}'\) \\?| ?\)), activity.data, ^tag_reject)
) )
end end
@ -512,7 +514,7 @@ defp restrict_tag_all(query, %{"tag_all" => tag_all})
when is_list(tag_all) and tag_all != [] do when is_list(tag_all) and tag_all != [] do
from( from(
activity in query, activity in query,
where: fragment("(? #> '{\"object\",\"tag\"}') \\?& ?", activity.data, ^tag_all) where: fragment(~s(\(? #> '{"object","tag"}'\) \\?& ?), activity.data, ^tag_all)
) )
end end
@ -521,14 +523,14 @@ defp restrict_tag_all(query, _), do: query
defp restrict_tag(query, %{"tag" => tag}) when is_list(tag) do defp restrict_tag(query, %{"tag" => tag}) when is_list(tag) do
from( from(
activity in query, activity in query,
where: fragment("(? #> '{\"object\",\"tag\"}') \\?| ?", activity.data, ^tag) where: fragment(~s(\(? #> '{"object","tag"}'\) \\?| ?), activity.data, ^tag)
) )
end end
defp restrict_tag(query, %{"tag" => tag}) when is_binary(tag) do defp restrict_tag(query, %{"tag" => tag}) when is_binary(tag) do
from( from(
activity in query, activity in query,
where: fragment("? <@ (? #> '{\"object\",\"tag\"}')", ^tag, activity.data) where: fragment(~s(? <@ (? #> '{"object","tag"}'\)), ^tag, activity.data)
) )
end end
@ -601,7 +603,7 @@ defp restrict_type(query, _), do: query
defp restrict_favorited_by(query, %{"favorited_by" => ap_id}) do defp restrict_favorited_by(query, %{"favorited_by" => ap_id}) do
from( from(
activity in query, activity in query,
where: fragment("? <@ (? #> '{\"object\",\"likes\"}')", ^ap_id, activity.data) where: fragment(~s(? <@ (? #> '{"object","likes"}'\)), ^ap_id, activity.data)
) )
end end
@ -610,7 +612,7 @@ defp restrict_favorited_by(query, _), do: query
defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do
from( from(
activity in query, activity in query,
where: fragment("not (? #> '{\"object\",\"attachment\"}' = ?)", activity.data, ^[]) where: fragment(~s(not (? #> '{"object","attachment"}' = ?\)), activity.data, ^[])
) )
end end

View file

@ -6,15 +6,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.User
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Federator alias Pleroma.Web.Federator
require Logger require Logger

View file

@ -16,7 +16,7 @@ def filter(object) do
end) end)
end end
def get_policies() do def get_policies do
Application.get_env(:pleroma, :instance, []) Application.get_env(:pleroma, :instance, [])
|> Keyword.get(:rewrite_policy, []) |> Keyword.get(:rewrite_policy, [])
|> get_policies() |> get_policies()

View file

@ -45,13 +45,14 @@ defp check_ftl_removal(
defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do
{content, summary} = {content, summary} =
Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), {content, summary}, fn {pattern, Enum.reduce(
replacement}, Pleroma.Config.get([:mrf_keyword, :replace]),
{content_acc, {content, summary},
summary_acc} -> fn {pattern, replacement}, {content_acc, summary_acc} ->
{String.replace(content_acc, pattern, replacement), {String.replace(content_acc, pattern, replacement),
String.replace(summary_acc, pattern, replacement)} String.replace(summary_acc, pattern, replacement)}
end) end
)
{:ok, {:ok,
message message

View file

@ -3,9 +3,9 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Relay do defmodule Pleroma.Web.ActivityPub.Relay do
alias Pleroma.User
alias Pleroma.Object
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
require Logger require Logger

View file

@ -7,9 +7,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
A module to handle coding from internal to wire ActivityPub and back. A module to handle coding from internal to wire ActivityPub and back.
""" """
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
@ -650,10 +650,10 @@ def get_obj_helper(id) do
if object = Object.normalize(id), do: {:ok, object}, else: nil if object = Object.normalize(id), do: {:ok, object}, else: nil
end end
def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) when is_binary(inReplyTo) do def set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_reply_to) do
with false <- String.starts_with?(inReplyTo, "http"), with false <- String.starts_with?(in_reply_to, "http"),
{:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do {:ok, %{data: replied_to_object}} <- get_obj_helper(in_reply_to) do
Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo) Map.put(object, "inReplyTo", replied_to_object["external_url"] || in_reply_to)
else else
_e -> object _e -> object
end end
@ -736,6 +736,7 @@ def prepare_outgoing(%{"type" => "Reject"} = data) do
def prepare_outgoing(%{"type" => _type} = data) do def prepare_outgoing(%{"type" => _type} = data) do
data = data =
data data
|> strip_internal_fields
|> maybe_fix_object_url |> maybe_fix_object_url
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
@ -829,10 +830,10 @@ def set_sensitive(object) do
end end
def add_attributed_to(object) do def add_attributed_to(object) do
attributedTo = object["attributedTo"] || object["actor"] attributed_to = object["attributedTo"] || object["actor"]
object object
|> Map.put("attributedTo", attributedTo) |> Map.put("attributedTo", attributed_to)
end end
def add_likes(%{"id" => id, "like_count" => likes} = object) do def add_likes(%{"id" => id, "like_count" => likes} = object) do
@ -870,7 +871,8 @@ defp strip_internal_fields(object) do
"announcements", "announcements",
"announcement_count", "announcement_count",
"emoji", "emoji",
"context_id" "context_id",
"deleted_activity_id"
]) ])
end end

View file

@ -3,17 +3,17 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Utils do defmodule Pleroma.Web.ActivityPub.Utils do
alias Pleroma.Repo
alias Pleroma.Web
alias Pleroma.Object
alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.User
alias Pleroma.Notification
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Endpoint
alias Ecto.Changeset alias Ecto.Changeset
alias Ecto.UUID alias Ecto.UUID
alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Endpoint
alias Pleroma.Web.Router.Helpers
import Ecto.Query import Ecto.Query

View file

@ -5,15 +5,15 @@
defmodule Pleroma.Web.ActivityPub.UserView do defmodule Pleroma.Web.ActivityPub.UserView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.Web.WebFinger
alias Pleroma.Web.Salmon
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Salmon
alias Pleroma.Web.WebFinger
import Ecto.Query import Ecto.Query

View file

@ -8,7 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.MastodonAPI.Admin.AccountView alias Pleroma.Web.AdminAPI.AccountView
import Pleroma.Web.ControllerHelper, only: [json_response: 3] import Pleroma.Web.ControllerHelper, only: [json_response: 3]

View file

@ -2,10 +2,11 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.Admin.AccountView do defmodule Pleroma.Web.AdminAPI.AccountView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.Web.MastodonAPI.Admin.AccountView alias Pleroma.User.Info
alias Pleroma.Web.AdminAPI.AccountView
def render("index.json", %{users: users, count: count, page_size: page_size}) do def render("index.json", %{users: users, count: count, page_size: page_size}) do
%{ %{
@ -19,7 +20,10 @@ def render("show.json", %{user: user}) do
%{ %{
"id" => user.id, "id" => user.id,
"nickname" => user.nickname, "nickname" => user.nickname,
"deactivated" => user.info.deactivated "deactivated" => user.info.deactivated,
"local" => user.local,
"roles" => Info.roles(user.info),
"tags" => user.tags || []
} }
end end
end end

View file

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.PleromaAuthenticator do defmodule Pleroma.Web.Auth.PleromaAuthenticator do
alias Pleroma.User
alias Comeonin.Pbkdf2 alias Comeonin.Pbkdf2
alias Pleroma.User
@behaviour Pleroma.Web.Auth.Authenticator @behaviour Pleroma.Web.Auth.Authenticator

View file

@ -23,7 +23,7 @@ defmodule Pleroma.Web.UserSocket do
# performing token verification on connect. # performing token verification on connect.
def connect(%{"token" => token}, socket) do def connect(%{"token" => token}, socket) do
with true <- Pleroma.Config.get([:chat, :enabled]), with true <- Pleroma.Config.get([:chat, :enabled]),
{:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84600), {:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600),
%User{} = user <- Pleroma.Repo.get(User, user_id) do %User{} = user <- Pleroma.Repo.get(User, user_id) do
{:ok, assign(socket, :user_name, user.nickname)} {:ok, assign(socket, :user_name, user.nickname)}
else else

View file

@ -4,8 +4,8 @@
defmodule Pleroma.Web.ChatChannel do defmodule Pleroma.Web.ChatChannel do
use Phoenix.Channel use Phoenix.Channel
alias Pleroma.Web.ChatChannel.ChatChannelState
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ChatChannel.ChatChannelState
def join("chat:public", _message, socket) do def join("chat:public", _message, socket) do
send(self(), :after_join) send(self(), :after_join)
@ -48,7 +48,7 @@ def add_message(message) do
end) end)
end end
def messages() do def messages do
Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse() end) Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse() end)
end end
end end

View file

@ -3,14 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPI do defmodule Pleroma.Web.CommonAPI do
alias Pleroma.User
alias Pleroma.Repo
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Formatter
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.ThreadMute alias Pleroma.ThreadMute
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Formatter
import Pleroma.Web.CommonAPI.Utils import Pleroma.Web.CommonAPI.Utils
@ -27,6 +27,42 @@ def follow(follower, followed) do
end end
end end
def unfollow(follower, unfollowed) do
with {:ok, follower, _follow_activity} <- User.unfollow(follower, unfollowed),
{:ok, _activity} <- ActivityPub.unfollow(follower, unfollowed) do
{:ok, follower}
end
end
def accept_follow_request(follower, followed) do
with {:ok, follower} <- User.maybe_follow(follower, followed),
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"),
{:ok, _activity} <-
ActivityPub.accept(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Accept"
}) do
{:ok, follower}
end
end
def reject_follow_request(follower, followed) do
with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"),
{:ok, _activity} <-
ActivityPub.reject(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Reject"
}) do
{:ok, follower}
end
end
def delete(activity_id, user) do def delete(activity_id, user) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
%Object{} = object <- Object.normalize(object_id), %Object{} = object <- Object.normalize(object_id),
@ -88,8 +124,8 @@ def get_visibility(%{"in_reply_to_status_id" => status_id}) when not is_nil(stat
nil -> nil ->
"public" "public"
inReplyTo -> in_reply_to ->
Pleroma.Web.MastodonAPI.StatusView.get_visibility(inReplyTo.data["object"]) Pleroma.Web.MastodonAPI.StatusView.get_visibility(in_reply_to.data["object"])
end end
end end
@ -101,15 +137,15 @@ def post(user, %{"status" => status} = data) do
with status <- String.trim(status), with status <- String.trim(status),
attachments <- attachments_from_ids(data), attachments <- attachments_from_ids(data),
inReplyTo <- get_replied_to_activity(data["in_reply_to_status_id"]), in_reply_to <- get_replied_to_activity(data["in_reply_to_status_id"]),
{content_html, mentions, tags} <- {content_html, mentions, tags} <-
make_content_html( make_content_html(
status, status,
attachments, attachments,
data data
), ),
{to, cc} <- to_for_user_and_mentions(user, mentions, inReplyTo, visibility), {to, cc} <- to_for_user_and_mentions(user, mentions, in_reply_to, visibility),
context <- make_context(inReplyTo), context <- make_context(in_reply_to),
cw <- data["spoiler_text"], cw <- data["spoiler_text"],
full_payload <- String.trim(status <> (data["spoiler_text"] || "")), full_payload <- String.trim(status <> (data["spoiler_text"] || "")),
length when length in 1..limit <- String.length(full_payload), length when length in 1..limit <- String.length(full_payload),
@ -120,7 +156,7 @@ def post(user, %{"status" => status} = data) do
context, context,
content_html, content_html,
attachments, attachments,
inReplyTo, in_reply_to,
tags, tags,
cw, cw,
cc cc

View file

@ -6,14 +6,14 @@ defmodule Pleroma.Web.CommonAPI.Utils do
alias Calendar.Strftime alias Calendar.Strftime
alias Comeonin.Pbkdf2 alias Comeonin.Pbkdf2
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Formatter alias Pleroma.Formatter
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Config alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
alias Pleroma.Web.ActivityPub.Utils
# This is a hack for twidere. # This is a hack for twidere.
def get_by_id_or_ap_id(id) do def get_by_id_or_ap_id(id) do

View file

@ -6,7 +6,8 @@ defmodule Pleroma.Web.ControllerHelper do
use Pleroma.Web, :controller use Pleroma.Web, :controller
def oauth_scopes(params, default) do def oauth_scopes(params, default) do
# Note: `scopes` is used by Mastodon — supporting it but sticking to OAuth's standard `scope` wherever we control it # Note: `scopes` is used by Mastodon — supporting it but sticking to
# OAuth's standard `scope` wherever we control it
Pleroma.Web.OAuth.parse_scopes(params["scope"] || params["scopes"], default) Pleroma.Web.OAuth.parse_scopes(params["scope"] || params["scopes"], default)
end end

View file

@ -26,6 +26,7 @@ defmodule Pleroma.Web.Endpoint do
from: :pleroma, from: :pleroma,
only: only:
~w(index.html static finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc) ~w(index.html static finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc)
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
) )
# Code reloading can be explicitly enabled under the # Code reloading can be explicitly enabled under the

View file

@ -4,27 +4,27 @@
defmodule Pleroma.Web.Federator do defmodule Pleroma.Web.Federator do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Jobs
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.WebFinger
alias Pleroma.Web.Websub
alias Pleroma.Web.Salmon
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.Federator.RetryQueue alias Pleroma.Web.Federator.RetryQueue
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Jobs alias Pleroma.Web.Salmon
alias Pleroma.Web.WebFinger
alias Pleroma.Web.Websub
require Logger require Logger
@websub Application.get_env(:pleroma, :websub) @websub Application.get_env(:pleroma, :websub)
@ostatus Application.get_env(:pleroma, :ostatus) @ostatus Application.get_env(:pleroma, :ostatus)
def init() do def init do
# 1 minute # 1 minute
Process.sleep(1000 * 60 * 1) Process.sleep(1000 * 60)
refresh_subscriptions() refresh_subscriptions()
end end
@ -58,7 +58,7 @@ def request_subscription(sub) do
Jobs.enqueue(:federator_outgoing, __MODULE__, [:request_subscription, sub]) Jobs.enqueue(:federator_outgoing, __MODULE__, [:request_subscription, sub])
end end
def refresh_subscriptions() do def refresh_subscriptions do
Jobs.enqueue(:federator_outgoing, __MODULE__, [:refresh_subscriptions]) Jobs.enqueue(:federator_outgoing, __MODULE__, [:refresh_subscriptions])
end end

View file

@ -13,7 +13,7 @@ def init(args) do
{:ok, %{args | queue_table: queue_table, running_jobs: :sets.new()}} {:ok, %{args | queue_table: queue_table, running_jobs: :sets.new()}}
end end
def start_link() do def start_link do
enabled = enabled =
if Mix.env() == :test, do: true, else: Pleroma.Config.get([__MODULE__, :enabled], false) if Mix.env() == :test, do: true, else: Pleroma.Config.get([__MODULE__, :enabled], false)
@ -39,11 +39,11 @@ def enqueue(data, transport, retries \\ 0) do
GenServer.cast(__MODULE__, {:maybe_enqueue, data, transport, retries + 1}) GenServer.cast(__MODULE__, {:maybe_enqueue, data, transport, retries + 1})
end end
def get_stats() do def get_stats do
GenServer.call(__MODULE__, :get_stats) GenServer.call(__MODULE__, :get_stats)
end end
def reset_stats() do def reset_stats do
GenServer.call(__MODULE__, :reset_stats) GenServer.call(__MODULE__, :reset_stats)
end end
@ -55,7 +55,7 @@ def get_retry_params(retries) do
end end
end end
def get_retry_timer_interval() do def get_retry_timer_interval do
Pleroma.Config.get([:retry_queue, :interval], 1000) Pleroma.Config.get([:retry_queue, :interval], 1000)
end end
@ -231,7 +231,7 @@ defp growth_function(retries) do
end end
end end
defp maybe_kickoff_timer() do defp maybe_kickoff_timer do
GenServer.cast(__MODULE__, :kickoff_timer) GenServer.cast(__MODULE__, :kickoff_timer)
end end
end end

View file

@ -1 +1,63 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
import Ecto.Query
import Ecto.Changeset
alias Pleroma.Repo
alias Pleroma.User
@default_limit 20
def get_followers(user, params \\ %{}) do
user
|> User.get_followers_query()
|> paginate(params)
|> Repo.all()
end
def get_friends(user, params \\ %{}) do
user
|> User.get_friends_query()
|> paginate(params)
|> Repo.all()
end
def paginate(query, params \\ %{}) do
options = cast_params(params)
query
|> restrict(:max_id, options)
|> restrict(:since_id, options)
|> restrict(:limit, options)
|> order_by([u], fragment("? desc nulls last", u.id))
end
def cast_params(params) do
param_types = %{
max_id: :string,
since_id: :string,
limit: :integer
}
changeset = cast({%{}, param_types}, params, Map.keys(param_types))
changeset.changes
end
defp restrict(query, :max_id, %{max_id: max_id}) do
query
|> where([q], q.id < ^max_id)
end
defp restrict(query, :since_id, %{since_id: since_id}) do
query
|> where([q], q.id > ^since_id)
end
defp restrict(query, :limit, options) do
limit = Map.get(options, :limit, @default_limit)
query
|> limit(^limit)
end
defp restrict(query, _, _), do: query
end

View file

@ -4,6 +4,7 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Filter alias Pleroma.Filter
@ -13,18 +14,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Stats alias Pleroma.Stats
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MediaProxy
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.FilterView alias Pleroma.Web.MastodonAPI.FilterView
alias Pleroma.Web.MastodonAPI.ListView alias Pleroma.Web.MastodonAPI.ListView
alias Pleroma.Web.MastodonAPI.MastodonAPI
alias Pleroma.Web.MastodonAPI.MastodonView alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MastodonAPI.ReportView alias Pleroma.Web.MastodonAPI.ReportView
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.MediaProxy
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
@ -131,8 +131,8 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _) do
json(conn, account) json(conn, account)
end end
def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do def user(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
with %User{} = user <- Repo.get(User, id), with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id),
true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
account = AccountView.render("account.json", %{user: user, for: for_user}) account = AccountView.render("account.json", %{user: user, for: for_user})
json(conn, account) json(conn, account)
@ -652,9 +652,9 @@ def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", %{activities: activities, for: user, as: :activity}) |> render("index.json", %{activities: activities, for: user, as: :activity})
end end
def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
with %User{} = user <- Repo.get(User, id), with %User{} = user <- Repo.get(User, id),
{:ok, followers} <- User.get_followers(user) do followers <- MastodonAPI.get_followers(user, params) do
followers = followers =
cond do cond do
for_user && user.id == for_user.id -> followers for_user && user.id == for_user.id -> followers
@ -663,14 +663,15 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
end end
conn conn
|> add_link_headers(:followers, followers, user)
|> put_view(AccountView) |> put_view(AccountView)
|> render("accounts.json", %{users: followers, as: :user}) |> render("accounts.json", %{users: followers, as: :user})
end end
end end
def following(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do def following(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
with %User{} = user <- Repo.get(User, id), with %User{} = user <- Repo.get(User, id),
{:ok, followers} <- User.get_friends(user) do followers <- MastodonAPI.get_friends(user, params) do
followers = followers =
cond do cond do
for_user && user.id == for_user.id -> followers for_user && user.id == for_user.id -> followers
@ -679,6 +680,7 @@ def following(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
end end
conn conn
|> add_link_headers(:following, followers, user)
|> put_view(AccountView) |> put_view(AccountView)
|> render("accounts.json", %{users: followers, as: :user}) |> render("accounts.json", %{users: followers, as: :user})
end end
@ -694,16 +696,7 @@ def follow_requests(%{assigns: %{user: followed}} = conn, _params) do
def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
with %User{} = follower <- Repo.get(User, id), with %User{} = follower <- Repo.get(User, id),
{:ok, follower} <- User.maybe_follow(follower, followed), {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"),
{:ok, _activity} <-
ActivityPub.accept(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Accept"
}) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("relationship.json", %{user: followed, target: follower}) |> render("relationship.json", %{user: followed, target: follower})
@ -717,15 +710,7 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}
def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
with %User{} = follower <- Repo.get(User, id), with %User{} = follower <- Repo.get(User, id),
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"),
{:ok, _activity} <-
ActivityPub.reject(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Reject"
}) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("relationship.json", %{user: followed, target: follower}) |> render("relationship.json", %{user: followed, target: follower})
@ -767,8 +752,7 @@ def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
with %User{} = followed <- Repo.get(User, id), with %User{} = followed <- Repo.get(User, id),
{:ok, _activity} <- ActivityPub.unfollow(follower, followed), {:ok, follower} <- CommonAPI.unfollow(follower, followed) do
{:ok, follower, _} <- User.unfollow(follower, followed) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("relationship.json", %{user: follower, target: followed}) |> render("relationship.json", %{user: follower, target: followed})
@ -1126,7 +1110,8 @@ def index(%{assigns: %{user: user}} = conn, _params) do
compose: %{ compose: %{
me: "#{user.id}", me: "#{user.id}",
default_privacy: user.info.default_scope, default_privacy: user.info.default_scope,
default_sensitive: false default_sensitive: false,
allow_content_types: Config.get([:instance, :allowed_post_formats])
}, },
media_attachments: %{ media_attachments: %{
accept_content_types: [ accept_content_types: [
@ -1271,7 +1256,7 @@ def login(conn, _) do
end end
end end
defp get_or_make_app() do defp get_or_make_app do
find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."} find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."}
scopes = ["read", "write", "follow", "push"] scopes = ["read", "write", "follow", "push"]

View file

@ -102,7 +102,10 @@ def render(
website: nil website: nil
}, },
language: nil, language: nil,
emojis: [] emojis: [],
pleroma: %{
local: activity.local
}
} }
end end
@ -181,7 +184,10 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
website: nil website: nil
}, },
language: nil, language: nil,
emojis: build_emojis(activity.data["object"]["emoji"]) emojis: build_emojis(activity.data["object"]["emoji"]),
pleroma: %{
local: activity.local
}
} }
end end

View file

@ -5,9 +5,9 @@
defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
require Logger require Logger
alias Pleroma.Web.OAuth.Token
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.OAuth.Token
@behaviour :cowboy_websocket @behaviour :cowboy_websocket

View file

@ -19,7 +19,8 @@ def url(url) do
else else
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base] secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
# Must preserve `%2F` for compatibility with S3 (https://git.pleroma.social/pleroma/pleroma/issues/580) # Must preserve `%2F` for compatibility with S3
# https://git.pleroma.social/pleroma/pleroma/issues/580
replacement = get_replacement(url, ":2F:") replacement = get_replacement(url, ":2F:")
# The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice. # The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice.

View file

@ -88,7 +88,7 @@ defp build_attachments(%{data: %{"attachment" => attachments}}) do
# TODO: Add additional properties to objects when we have the data available. # TODO: Add additional properties to objects when we have the data available.
# Also, Whatsapp only wants JPEG or PNGs. It seems that if we add a second og:image # Also, Whatsapp only wants JPEG or PNGs. It seems that if we add a second og:image
# object when a Video or GIF is attached it will display that in the Whatsapp Rich Preview. # object when a Video or GIF is attached it will display that in Whatsapp Rich Preview.
case media_type do case media_type do
"audio" -> "audio" ->
[ [

View file

@ -97,7 +97,8 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
| acc | acc
] ]
# TODO: Need the true width and height values here or Twitter renders an iFrame with a bad aspect ratio # TODO: Need the true width and height values here or Twitter renders an iFrame with
# a bad aspect ratio
"video" -> "video" ->
[ [
{:meta, [property: "twitter:card", content: "player"], []}, {:meta, [property: "twitter:card", content: "player"], []},

View file

@ -1,10 +1,10 @@
# Pleroma: A lightweight social networking server # Pleroma: A lightweight social networking server
# Copyright \xc2\xa9 2017-2019 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Utils do defmodule Pleroma.Web.Metadata.Utils do
alias Pleroma.HTML
alias Pleroma.Formatter alias Pleroma.Formatter
alias Pleroma.HTML
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do

View file

@ -1 +0,0 @@

View file

@ -5,10 +5,10 @@
defmodule Pleroma.Web.OAuth.Authorization do defmodule Pleroma.Web.OAuth.Authorization do
use Ecto.Schema use Ecto.Schema
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Web.OAuth.Authorization alias Pleroma.User
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query

View file

@ -5,13 +5,13 @@
defmodule Pleroma.Web.OAuth.OAuthController do defmodule Pleroma.Web.OAuth.OAuthController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Web.Auth.Authenticator alias Comeonin.Pbkdf2
alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.OAuth.App
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Comeonin.Pbkdf2 alias Pleroma.Web.Auth.Authenticator
alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token
import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2] import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2]

View file

@ -7,11 +7,11 @@ defmodule Pleroma.Web.OAuth.Token do
import Ecto.Query import Ecto.Query
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Web.OAuth.Token alias Pleroma.User
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token
schema "oauth_tokens" do schema "oauth_tokens" do
field(:token, :string) field(:token, :string)

View file

@ -4,8 +4,8 @@
defmodule Pleroma.Web.OStatus.ActivityRepresenter do defmodule Pleroma.Web.OStatus.ActivityRepresenter do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.OStatus.UserRepresenter alias Pleroma.Web.OStatus.UserRepresenter
require Logger require Logger

View file

@ -4,8 +4,8 @@
defmodule Pleroma.Web.OStatus.FeedRepresenter do defmodule Pleroma.Web.OStatus.FeedRepresenter do
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.OStatus
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
alias Pleroma.Web.OStatus
alias Pleroma.Web.OStatus.ActivityRepresenter alias Pleroma.Web.OStatus.ActivityRepresenter
alias Pleroma.Web.OStatus.UserRepresenter alias Pleroma.Web.OStatus.UserRepresenter

View file

@ -4,9 +4,9 @@
defmodule Pleroma.Web.OStatus.DeleteHandler do defmodule Pleroma.Web.OStatus.DeleteHandler do
require Logger require Logger
alias Pleroma.Web.XML
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.XML
def handle_delete(entry, _doc \\ nil) do def handle_delete(entry, _doc \\ nil) do
with id <- XML.string_from_xpath("//id", entry), with id <- XML.string_from_xpath("//id", entry),

View file

@ -3,10 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OStatus.FollowHandler do defmodule Pleroma.Web.OStatus.FollowHandler do
alias Pleroma.Web.XML
alias Pleroma.Web.OStatus
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
def handle(entry, doc) do def handle(entry, doc) do
with {:ok, actor} <- OStatus.find_make_or_update_user(doc), with {:ok, actor} <- OStatus.find_make_or_update_user(doc),

View file

@ -4,13 +4,14 @@
defmodule Pleroma.Web.OStatus.NoteHandler do defmodule Pleroma.Web.OStatus.NoteHandler do
require Logger require Logger
alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
@doc """ @doc """
Get the context for this note. Uses this: Get the context for this note. Uses this:
@ -18,13 +19,13 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
2. The conversation reference in the ostatus xml 2. The conversation reference in the ostatus xml
3. A newly generated context id. 3. A newly generated context id.
""" """
def get_context(entry, inReplyTo) do def get_context(entry, in_reply_to) do
context = context =
(XML.string_from_xpath("//ostatus:conversation[1]", entry) || (XML.string_from_xpath("//ostatus:conversation[1]", entry) ||
XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry) || "") XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry) || "")
|> String.trim() |> String.trim()
with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(inReplyTo) do with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(in_reply_to) do
context context
else else
_e -> _e ->
@ -87,14 +88,14 @@ def add_external_url(note, entry) do
Map.put(note, "external_url", url) Map.put(note, "external_url", url)
end end
def fetch_replied_to_activity(entry, inReplyTo) do def fetch_replied_to_activity(entry, in_reply_to) do
with %Activity{} = activity <- Activity.get_create_by_object_ap_id(inReplyTo) do with %Activity{} = activity <- Activity.get_create_by_object_ap_id(in_reply_to) do
activity activity
else else
_e -> _e ->
with inReplyToHref when not is_nil(inReplyToHref) <- with in_reply_to_href when not is_nil(in_reply_to_href) <-
XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry), XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry),
{:ok, [activity | _]} <- OStatus.fetch_activity_from_url(inReplyToHref) do {:ok, [activity | _]} <- OStatus.fetch_activity_from_url(in_reply_to_href) do
activity activity
else else
_e -> nil _e -> nil
@ -110,11 +111,12 @@ def handle_note(entry, doc \\ nil) do
{:ok, actor} <- OStatus.find_make_or_update_user(author), {:ok, actor} <- OStatus.find_make_or_update_user(author),
content_html <- OStatus.get_content(entry), content_html <- OStatus.get_content(entry),
cw <- OStatus.get_cw(entry), cw <- OStatus.get_cw(entry),
inReplyTo <- XML.string_from_xpath("//thr:in-reply-to[1]/@ref", entry), in_reply_to <- XML.string_from_xpath("//thr:in-reply-to[1]/@ref", entry),
inReplyToActivity <- fetch_replied_to_activity(entry, inReplyTo), in_reply_to_activity <- fetch_replied_to_activity(entry, in_reply_to),
inReplyTo <- (inReplyToActivity && inReplyToActivity.data["object"]["id"]) || inReplyTo, in_reply_to <-
(in_reply_to_activity && in_reply_to_activity.data["object"]["id"]) || in_reply_to,
attachments <- OStatus.get_attachments(entry), attachments <- OStatus.get_attachments(entry),
context <- get_context(entry, inReplyTo), context <- get_context(entry, in_reply_to),
tags <- OStatus.get_tags(entry), tags <- OStatus.get_tags(entry),
mentions <- get_mentions(entry), mentions <- get_mentions(entry),
to <- make_to_list(actor, mentions), to <- make_to_list(actor, mentions),
@ -128,7 +130,7 @@ def handle_note(entry, doc \\ nil) do
context, context,
content_html, content_html,
attachments, attachments,
inReplyToActivity, in_reply_to_activity,
[], [],
cw cw
), ),
@ -140,8 +142,8 @@ def handle_note(entry, doc \\ nil) do
# TODO: Handle this case in make_note_data # TODO: Handle this case in make_note_data
note <- note <-
if( if(
inReplyTo && !inReplyToActivity, in_reply_to && !in_reply_to_activity,
do: note |> Map.put("inReplyTo", inReplyTo), do: note |> Map.put("inReplyTo", in_reply_to),
else: note else: note
) do ) do
ActivityPub.create(%{ ActivityPub.create(%{

View file

@ -3,10 +3,10 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OStatus.UnfollowHandler do defmodule Pleroma.Web.OStatus.UnfollowHandler do
alias Pleroma.Web.XML
alias Pleroma.Web.OStatus
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
def handle(entry, doc) do def handle(entry, doc) do
with {:ok, actor} <- OStatus.find_make_or_update_user(doc), with {:ok, actor} <- OStatus.find_make_or_update_user(doc),

View file

@ -9,19 +9,19 @@ defmodule Pleroma.Web.OStatus do
import Pleroma.Web.XML import Pleroma.Web.XML
require Logger require Logger
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Object
alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.OStatus.DeleteHandler
alias Pleroma.Web.OStatus.FollowHandler
alias Pleroma.Web.OStatus.NoteHandler
alias Pleroma.Web.OStatus.UnfollowHandler
alias Pleroma.Web.WebFinger alias Pleroma.Web.WebFinger
alias Pleroma.Web.Websub alias Pleroma.Web.Websub
alias Pleroma.Web.OStatus.FollowHandler
alias Pleroma.Web.OStatus.UnfollowHandler
alias Pleroma.Web.OStatus.NoteHandler
alias Pleroma.Web.OStatus.DeleteHandler
def is_representable?(%Activity{data: data}) do def is_representable?(%Activity{data: data}) do
object = Object.normalize(data["object"]) object = Object.normalize(data["object"])

View file

@ -9,13 +9,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.ActivityPub.ActivityPubController alias Pleroma.Web.ActivityPub.ActivityPubController
alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.OStatus.ActivityRepresenter alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Web.Federator alias Pleroma.Web.Federator
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.OStatus.ActivityRepresenter
alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Web.XML alias Pleroma.Web.XML
plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming]) plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming])

View file

@ -5,13 +5,13 @@
defmodule Pleroma.Web.Push.Impl do defmodule Pleroma.Web.Push.Impl do
@moduledoc "The module represents implementation push web notification" @moduledoc "The module represents implementation push web notification"
alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Web.Push.Subscription
alias Pleroma.Web.Metadata.Utils alias Pleroma.Web.Metadata.Utils
alias Pleroma.Notification alias Pleroma.Web.Push.Subscription
require Logger require Logger
import Ecto.Query import Ecto.Query
@ -20,7 +20,10 @@ defmodule Pleroma.Web.Push.Impl do
@doc "Performs sending notifications for user subscriptions" @doc "Performs sending notifications for user subscriptions"
@spec perform_send(Notification.t()) :: list(any) @spec perform_send(Notification.t()) :: list(any)
def perform_send(%{activity: %{data: %{"type" => activity_type}}, user_id: user_id} = notif) def perform_send(
%{activity: %{data: %{"type" => activity_type}, id: activity_id}, user_id: user_id} =
notif
)
when activity_type in @types do when activity_type in @types do
actor = User.get_cached_by_ap_id(notif.activity.data["actor"]) actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
@ -37,7 +40,10 @@ def perform_send(%{activity: %{data: %{"type" => activity_type}}, user_id: user_
notification_id: notif.id, notification_id: notif.id,
notification_type: type, notification_type: type,
icon: avatar_url, icon: avatar_url,
preferred_locale: "en" preferred_locale: "en",
pleroma: %{
activity_id: activity_id
}
} }
|> Jason.encode!() |> Jason.encode!()
|> push_message(build_sub(subscription), gcm_api_key, subscription) |> push_message(build_sub(subscription), gcm_api_key, subscription)

View file

@ -13,15 +13,15 @@ defmodule Pleroma.Web.Push do
# Client API # # Client API #
############## ##############
def start_link() do def start_link do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__) GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end end
def vapid_config() do def vapid_config do
Application.get_env(:web_push_encryption, :vapid_details, []) Application.get_env(:web_push_encryption, :vapid_details, [])
end end
def enabled() do def enabled do
case vapid_config() do case vapid_config() do
[] -> false [] -> false
list when is_list(list) -> true list when is_list(list) -> true

View file

@ -82,8 +82,8 @@ def delete_if_exists(user, token) do
end end
# Some webpush clients (e.g. iOS Toot!) use an non urlsafe base64 as an encoding for the key. # Some webpush clients (e.g. iOS Toot!) use an non urlsafe base64 as an encoding for the key.
# However, the web push rfs specify to use base64 urlsafe, and the `web_push_encryption` library we use # However, the web push rfs specify to use base64 urlsafe, and the `web_push_encryption` library
# requires the key to be properly encoded. So we just convert base64 to urlsafe base64. # we use requires the key to be properly encoded. So we just convert base64 to urlsafe base64.
defp ensure_base64_urlsafe(string) do defp ensure_base64_urlsafe(string) do
string string
|> String.replace("+", "-") |> String.replace("+", "-")

View file

@ -4,8 +4,8 @@
defmodule Pleroma.Web.RichMedia.Helpers do defmodule Pleroma.Web.RichMedia.Helpers do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Object
alias Pleroma.Web.RichMedia.Parser alias Pleroma.Web.RichMedia.Parser
defp validate_page_url(page_url) when is_binary(page_url) do defp validate_page_url(page_url) when is_binary(page_url) do

View file

@ -631,8 +631,8 @@ defmodule Pleroma.Web.Router do
defmodule Fallback.RedirectController do defmodule Fallback.RedirectController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Web.Metadata
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.Metadata
def redirector(conn, _params, code \\ 200) do def redirector(conn, _params, code \\ 200) do
conn conn

View file

@ -9,8 +9,8 @@ defmodule Pleroma.Web.Salmon do
alias Pleroma.Instances alias Pleroma.Instances
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.XML
alias Pleroma.Web.OStatus.ActivityRepresenter alias Pleroma.Web.OStatus.ActivityRepresenter
alias Pleroma.Web.XML
require Logger require Logger
@ -86,10 +86,10 @@ def encode_key({:RSAPublicKey, modulus, exponent}) do
# Native generation of RSA keys is only available since OTP 20+ and in default build conditions # Native generation of RSA keys is only available since OTP 20+ and in default build conditions
# We try at compile time to generate natively an RSA key otherwise we fallback on the old way. # We try at compile time to generate natively an RSA key otherwise we fallback on the old way.
try do try do
_ = :public_key.generate_key({:rsa, 2048, 65537}) _ = :public_key.generate_key({:rsa, 2048, 65_537})
def generate_rsa_pem do def generate_rsa_pem do
key = :public_key.generate_key({:rsa, 2048, 65537}) key = :public_key.generate_key({:rsa, 2048, 65_537})
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key) entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
pem = :public_key.pem_encode([entry]) |> String.trim_trailing() pem = :public_key.pem_encode([entry]) |> String.trim_trailing()
{:ok, pem} {:ok, pem}

View file

@ -5,11 +5,11 @@
defmodule Pleroma.Web.Streamer do defmodule Pleroma.Web.Streamer do
use GenServer use GenServer
require Logger require Logger
alias Pleroma.User
alias Pleroma.Notification
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
@keepalive_interval :timer.seconds(30) @keepalive_interval :timer.seconds(30)
@ -211,15 +211,19 @@ def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = ite
end) end)
end end
def push_to_socket(topics, topic, %Activity{id: id, data: %{"type" => "Delete"}}) do def push_to_socket(topics, topic, %Activity{
data: %{"type" => "Delete", "deleted_activity_id" => deleted_activity_id}
}) do
Enum.each(topics[topic] || [], fn socket -> Enum.each(topics[topic] || [], fn socket ->
send( send(
socket.transport_pid, socket.transport_pid,
{:text, %{event: "delete", payload: to_string(id)} |> Jason.encode!()} {:text, %{event: "delete", payload: to_string(deleted_activity_id)} |> Jason.encode!()}
) )
end) end)
end end
def push_to_socket(_topics, _topic, %Activity{data: %{"type" => "Delete"}}), do: :noop
def push_to_socket(topics, topic, item) do def push_to_socket(topics, topic, item) do
Enum.each(topics[topic] || [], fn socket -> Enum.each(topics[topic] || [], fn socket ->
# Get the current user so we have up-to-date blocks etc. # Get the current user so we have up-to-date blocks etc.

View file

@ -8,75 +8,145 @@
</title> </title>
<style> <style>
body { body {
background-color: #282c37; background-color: #121a24;
font-family: sans-serif; font-family: sans-serif;
color:white; color: #b9b9ba;
text-align: center; text-align: center;
} }
.container { .container {
margin: 50px auto; max-width: 420px;
max-width: 320px; padding: 20px;
padding: 0; background-color: #182230;
padding: 40px 40px 40px 40px;
background-color: #313543;
border-radius: 4px; border-radius: 4px;
margin: auto;
margin-top: 10vh;
box-shadow: 0 1px 4px 0px rgba(0, 0, 0, 0.5);
} }
h1 { h1 {
margin: 0; margin: 0;
font-size: 24px;
} }
h2 { h2 {
color: #9baec8; color: #b9b9ba;
font-weight: normal; font-weight: normal;
font-size: 20px; font-size: 18px;
margin-bottom: 40px; margin-bottom: 20px;
} }
form { form {
width: 100%; width: 100%;
} }
.input {
text-align: left;
color: #89898a;
display: flex;
flex-direction: column;
}
input { input {
box-sizing: border-box; box-sizing: content-box;
width: 100%;
padding: 10px; padding: 10px;
margin-top: 20px; margin-top: 5px;
background-color: rgba(0,0,0,.1); margin-bottom: 10px;
color: white; background-color: #121a24;
color: #b9b9ba;
border: 0; border: 0;
border-bottom: 2px solid #9baec8; transition-property: border-bottom;
transition-duration: 0.35s;
border-bottom: 2px solid #2a384a;
font-size: 14px; font-size: 14px;
} }
input:focus { .scopes-input {
border-bottom: 2px solid #4b8ed8; display: flex;
margin-top: 1em;
text-align: left;
color: #89898a;
} }
input[type="checkbox"] { .scopes-input label:first-child {
width: auto; flex-basis: 40%;
}
.scopes {
display: flex;
flex-wrap: wrap;
text-align: left;
color: #b9b9ba;
}
.scope {
flex-basis: 100%;
display: flex;
height: 2em;
align-items: center;
}
[type="checkbox"] + label {
margin: 0.5em;
}
[type="checkbox"] {
display: none;
}
[type="checkbox"] + label:before {
display: inline-block;
color: white;
background-color: #121a24;
border: 4px solid #121a24;
box-sizing: border-box;
width: 1.2em;
height: 1.2em;
margin-right: 1.0em;
content: "";
transition-property: background-color;
transition-duration: 0.35s;
color: #121a24;
margin-bottom: -0.2em;
border-radius: 2px;
}
[type="checkbox"]:checked + label:before {
background-color: #d8a070;
}
input:focus {
outline: none;
border-bottom: 2px solid #d8a070;
} }
button { button {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
color: white; background-color: #1c2a3a;
background-color: #419bdd; color: #b9b9ba;
border-radius: 4px; border-radius: 4px;
border: none; border: none;
padding: 10px; padding: 10px;
margin-top: 30px; margin-top: 30px;
text-transform: uppercase; text-transform: uppercase;
font-weight: 500;
font-size: 16px; font-size: 16px;
box-shadow: 0px 0px 2px 0px black,
0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset,
0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
}
button:hover {
cursor: pointer;
box-shadow: 0px 0px 0px 1px #d8a070,
0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset,
0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
} }
.alert-danger { .alert-danger {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
color: #D8000C; background-color: #931014;
background-color: #FFD2D2;
border-radius: 4px; border-radius: 4px;
border: none; border: none;
padding: 10px; padding: 10px;
@ -88,20 +158,32 @@
.alert-info { .alert-info {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
color: #00529B;
background-color: #BDE5F8;
border-radius: 4px; border-radius: 4px;
border: none; border: 1px solid #7d796a;
padding: 10px; padding: 10px;
margin-top: 20px; margin-top: 20px;
font-weight: 500; font-weight: 500;
font-size: 16px; font-size: 16px;
} }
@media all and (max-width: 440px) {
.container {
margin-top: 0
}
.scopes-input {
flex-direction: column;
}
.scope {
flex-basis: 50%;
}
}
</style> </style>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1>Pleroma</h1> <h1><%= Application.get_env(:pleroma, :instance)[:name] %></h1>
<%= render @view_module, @view_template, assigns %> <%= render @view_module, @view_template, assigns %>
</div> </div>
</body> </body>

View file

@ -6,23 +6,26 @@
<% end %> <% end %>
<h2>OAuth Authorization</h2> <h2>OAuth Authorization</h2>
<%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %> <%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %>
<%= label f, :name, "Name or email" %> <div class="input">
<%= text_input f, :name %> <%= label f, :name, "Name or email" %>
<br> <%= text_input f, :name %>
<br> </div>
<%= label f, :password, "Password" %> <div class="input">
<%= password_input f, :password %> <%= label f, :password, "Password" %>
<br> <%= password_input f, :password %>
<br> </div>
<div class="scopes-input">
<%= label f, :scope, "Permissions" %> <%= label f, :scope, "Permissions" %>
<br> <div class="scopes">
<%= for scope <- @available_scopes do %> <%= for scope <- @available_scopes do %>
<%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> <%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %>
<div class="scope">
<%= checkbox f, :"scope_#{scope}", value: scope in @scopes && scope, checked_value: scope, unchecked_value: "", name: "authorization[scope][]" %> <%= checkbox f, :"scope_#{scope}", value: scope in @scopes && scope, checked_value: scope, unchecked_value: "", name: "authorization[scope][]" %>
<%= label f, :"scope_#{scope}", String.capitalize(scope) %> <%= label f, :"scope_#{scope}", String.capitalize(scope) %>
<br> </div>
<% end %> <% end %>
</div>
</div>
<%= hidden_input f, :client_id, value: @client_id %> <%= hidden_input f, :client_id, value: @client_id %>
<%= hidden_input f, :response_type, value: @response_type %> <%= hidden_input f, :response_type, value: @response_type %>

View file

@ -10,13 +10,13 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Comeonin.Pbkdf2 alias Comeonin.Pbkdf2
alias Pleroma.Emoji alias Pleroma.Emoji
alias Pleroma.PasswordResetToken alias Pleroma.PasswordResetToken
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.WebFinger alias Pleroma.Web.WebFinger
alias Pleroma.Web.ActivityPub.ActivityPub
def show_password_reset(conn, %{"token" => token}) do def show_password_reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),

View file

@ -3,16 +3,16 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.UserInviteToken
alias Pleroma.User
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Repo
alias Pleroma.Object
alias Pleroma.UserEmail
alias Pleroma.Mailer alias Pleroma.Mailer
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.UserEmail
alias Pleroma.UserInviteToken
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.TwitterAPI.UserView
import Ecto.Query import Ecto.Query
@ -35,11 +35,8 @@ def follow(%User{} = follower, params) do
def unfollow(%User{} = follower, params) do def unfollow(%User{} = follower, params) do
with {:ok, %User{} = unfollowed} <- get_user(params), with {:ok, %User{} = unfollowed} <- get_user(params),
{:ok, follower, _follow_activity} <- User.unfollow(follower, unfollowed), {:ok, follower} <- CommonAPI.unfollow(follower, unfollowed) do
{:ok, _activity} <- ActivityPub.unfollow(follower, unfollowed) do
{:ok, follower, unfollowed} {:ok, follower, unfollowed}
else
err -> err
end end
end end
@ -133,7 +130,7 @@ def upload(%Plug.Upload{} = file, %User{} = user, format \\ "xml") do
end end
def register_user(params) do def register_user(params) do
tokenString = params["token"] token_string = params["token"]
params = %{ params = %{
nickname: params["nickname"], nickname: params["nickname"],
@ -170,8 +167,8 @@ def register_user(params) do
# no need to query DB if registration is open # no need to query DB if registration is open
token = token =
unless registrations_open || is_nil(tokenString) do unless registrations_open || is_nil(token_string) do
Repo.get_by(UserInviteToken, %{token: tokenString}) Repo.get_by(UserInviteToken, %{token: token_string})
end end
cond do cond do

View file

@ -8,23 +8,20 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
import Pleroma.Web.ControllerHelper, only: [json_response: 3] import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Ecto.Changeset alias Ecto.Changeset
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView, NotificationView, TokenView}
alias Pleroma.Web.CommonAPI
alias Pleroma.{Repo, Activity, Object, User, Notification}
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.NotificationView
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.NotificationView
alias Pleroma.Web.TwitterAPI.TokenView
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView
require Logger require Logger
@ -590,16 +587,7 @@ def friend_requests(conn, params) do
def approve_friend_request(conn, %{"user_id" => uid} = _params) do def approve_friend_request(conn, %{"user_id" => uid} = _params) do
with followed <- conn.assigns[:user], with followed <- conn.assigns[:user],
%User{} = follower <- Repo.get(User, uid), %User{} = follower <- Repo.get(User, uid),
{:ok, follower} <- User.maybe_follow(follower, followed), {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"),
{:ok, _activity} <-
ActivityPub.accept(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Accept"
}) do
conn conn
|> put_view(UserView) |> put_view(UserView)
|> render("show.json", %{user: follower, for: followed}) |> render("show.json", %{user: follower, for: followed})
@ -611,15 +599,7 @@ def approve_friend_request(conn, %{"user_id" => uid} = _params) do
def deny_friend_request(conn, %{"user_id" => uid} = _params) do def deny_friend_request(conn, %{"user_id" => uid} = _params) do
with followed <- conn.assigns[:user], with followed <- conn.assigns[:user],
%User{} = follower <- Repo.get(User, uid), %User{} = follower <- Repo.get(User, uid),
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do
{:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"),
{:ok, _activity} <-
ActivityPub.reject(%{
to: [follower.ap_id],
actor: followed,
object: follow_activity.data["id"],
type: "Reject"
}) do
conn conn
|> put_view(UserView) |> put_view(UserView)
|> render("show.json", %{user: follower, for: followed}) |> render("show.json", %{user: follower, for: followed})

View file

@ -14,9 +14,9 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.TwitterAPI.ActivityView alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
import Ecto.Query import Ecto.Query
require Logger require Logger

View file

@ -6,11 +6,11 @@ defmodule Pleroma.Web.WebFinger do
@httpoison Application.get_env(:pleroma, :httpoison) @httpoison Application.get_env(:pleroma, :httpoison)
alias Pleroma.User alias Pleroma.User
alias Pleroma.XmlBuilder
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.XML
alias Pleroma.Web.Salmon
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.Salmon
alias Pleroma.Web.XML
alias Pleroma.XmlBuilder
require Jason require Jason
require Logger require Logger

View file

@ -6,14 +6,14 @@ defmodule Pleroma.Web.Websub do
alias Ecto.Changeset alias Ecto.Changeset
alias Pleroma.Instances alias Pleroma.Instances
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Web.Websub.WebsubServerSubscription
alias Pleroma.Web.Websub.WebsubClientSubscription
alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Web.XML
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.OStatus
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Federator alias Pleroma.Web.Federator
alias Pleroma.Web.OStatus
alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Websub.WebsubClientSubscription
alias Pleroma.Web.Websub.WebsubServerSubscription
alias Pleroma.Web.XML
require Logger require Logger
import Ecto.Query import Ecto.Query
@ -200,8 +200,8 @@ def gather_feed_data(topic, getter \\ &@httpoison.get/1) do
uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc), uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc),
hub when not is_nil(hub) <- XML.string_from_xpath(~S{/feed/link[@rel="hub"]/@href}, doc) do hub when not is_nil(hub) <- XML.string_from_xpath(~S{/feed/link[@rel="hub"]/@href}, doc) do
name = XML.string_from_xpath("/feed/author[1]/name", doc) name = XML.string_from_xpath("/feed/author[1]/name", doc)
preferredUsername = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc) preferred_username = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc)
displayName = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc) display_name = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc)
avatar = OStatus.make_avatar_object(doc) avatar = OStatus.make_avatar_object(doc)
bio = XML.string_from_xpath("/feed/author[1]/summary", doc) bio = XML.string_from_xpath("/feed/author[1]/summary", doc)
@ -209,8 +209,8 @@ def gather_feed_data(topic, getter \\ &@httpoison.get/1) do
%{ %{
"uri" => uri, "uri" => uri,
"hub" => hub, "hub" => hub,
"nickname" => preferredUsername || name, "nickname" => preferred_username || name,
"name" => displayName || name, "name" => display_name || name,
"host" => URI.parse(uri).host, "host" => URI.parse(uri).host,
"avatar" => avatar, "avatar" => avatar,
"bio" => bio "bio" => bio

View file

@ -7,8 +7,8 @@ defmodule Pleroma.Web.Websub.WebsubController do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.Websub
alias Pleroma.Web.Federator alias Pleroma.Web.Federator
alias Pleroma.Web.Websub
alias Pleroma.Web.Websub.WebsubClientSubscription alias Pleroma.Web.Websub.WebsubClientSubscription
require Logger require Logger

View file

@ -7,9 +7,9 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Integration.WebsocketClient
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth alias Pleroma.Web.OAuth
alias Pleroma.Integration.WebsocketClient
alias Pleroma.Web.Streamer alias Pleroma.Web.Streamer
@path Pleroma.Web.Endpoint.url() @path Pleroma.Web.Endpoint.url()

View file

@ -5,8 +5,8 @@
defmodule Pleroma.JobsTest do defmodule Pleroma.JobsTest do
use ExUnit.Case, async: true use ExUnit.Case, async: true
alias Pleroma.Jobs
alias Jobs.WorkerMock alias Jobs.WorkerMock
alias Pleroma.Jobs
setup do setup do
state = %{ state = %{

View file

@ -4,11 +4,11 @@
defmodule Pleroma.NotificationTest do defmodule Pleroma.NotificationTest do
use Pleroma.DataCase use Pleroma.DataCase
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.CommonAPI
alias Pleroma.User
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.TwitterAPI.TwitterAPI
import Pleroma.Factory import Pleroma.Factory
describe "create_notifications" do describe "create_notifications" do

View file

@ -5,8 +5,8 @@
defmodule Pleroma.ObjectTest do defmodule Pleroma.ObjectTest do
use Pleroma.DataCase use Pleroma.DataCase
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Repo
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
test "returns an object by it's AP id" do test "returns an object by it's AP id" do
object = insert(:note) object = insert(:note)

View file

@ -1,6 +1,6 @@
defmodule Pleroma.Builders.UserBuilder do defmodule Pleroma.Builders.UserBuilder do
alias Pleroma.User
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
def build(data \\ %{}) do def build(data \\ %{}) do
user = %User{ user = %User{

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Captcha.Mock do
@behaviour Service @behaviour Service
@impl Service @impl Service
def new(), do: %{type: :mock} def new, do: %{type: :mock}
@impl Service @impl Service
def validate(_token, _captcha, _data), do: :ok def validate(_token, _captcha, _data), do: :ok

View file

@ -4,10 +4,10 @@
defmodule Mix.Tasks.Pleroma.RelayTest do defmodule Mix.Tasks.Pleroma.RelayTest do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Utils
use Pleroma.DataCase use Pleroma.DataCase
setup_all do setup_all do

View file

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserTest do defmodule Pleroma.UserTest do
alias Pleroma.Builders.UserBuilder
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Builders.UserBuilder
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI

View file

@ -5,13 +5,13 @@
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Web.ActivityPub.UserView alias Pleroma.Activity
alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.Instances
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Activity
alias Pleroma.User alias Pleroma.User
alias Pleroma.Instances alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.UserView
setup_all do setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)

Some files were not shown because too many files have changed in this diff Show more