From f446744a6a72d707504c2ba20ea2326f956b5097 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Wed, 26 Feb 2020 20:13:53 +0400 Subject: [PATCH 1/9] Allow account registration without an email --- CHANGELOG.md | 1 + lib/pleroma/user.ex | 11 +++- .../controllers/account_controller.ex | 16 ++++-- test/user_test.exs | 21 +++++++- .../controllers/account_controller_test.exs | 52 ++++++++++++++++++- 5 files changed, 92 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08bb7e1c7..a924d4083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Rate limiter is now disabled for localhost/socket (unless remoteip plug is enabled) - Logger: default log level changed from `warn` to `info`. - Config mix task `migrate_to_db` truncates `config` table before migrating the config file. +- Allow account registration without an email
API Changes diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 56e599ecc..5271d8dbe 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.User do @@ -530,7 +530,14 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do end def maybe_validate_required_email(changeset, true), do: changeset - def maybe_validate_required_email(changeset, _), do: validate_required(changeset, [:email]) + + def maybe_validate_required_email(changeset, _) do + if Pleroma.Config.get([:instance, :account_activation_required]) do + validate_required(changeset, [:email]) + else + changeset + end + end defp put_ap_id(changeset) do ap_id = ap_id(%User{nickname: get_field(changeset, :nickname)}) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 38d14256f..88c997b9f 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AccountController do @@ -76,7 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do @doc "POST /api/v1/accounts" def create( %{assigns: %{app: app}} = conn, - %{"username" => nickname, "email" => _, "password" => _, "agreement" => true} = params + %{"username" => nickname, "password" => _, "agreement" => true} = params ) do params = params @@ -93,7 +93,8 @@ def create( |> Map.put("bio", params["bio"] || "") |> Map.put("confirm", params["password"]) - with {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), + with :ok <- validate_email_param(params), + {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do json(conn, %{ token_type: "Bearer", @@ -114,6 +115,15 @@ def create(conn, _) do render_error(conn, :forbidden, "Invalid credentials") end + defp validate_email_param(%{"email" => _}), do: :ok + + defp validate_email_param(_) do + case Pleroma.Config.get([:instance, :account_activation_required]) do + true -> {:error, %{"error" => "Missing parameters"}} + _ -> :ok + end + end + @doc "GET /api/v1/accounts/verify_credentials" def verify_credentials(%{assigns: %{user: user}} = conn, _) do chat_token = Phoenix.Token.sign(conn, "user socket", user.id) diff --git a/test/user_test.exs b/test/user_test.exs index 2fc42a90d..b07fed42b 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.UserTest do @@ -412,7 +412,11 @@ test "it sends a welcome message if it is set" do assert activity.actor == welcome_user.ap_id end - test "it requires an email, name, nickname and password, bio is optional" do + clear_config([:instance, :account_activation_required]) + + test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do + Pleroma.Config.put([:instance, :account_activation_required], true) + @full_user_data |> Map.keys() |> Enum.each(fn key -> @@ -423,6 +427,19 @@ test "it requires an email, name, nickname and password, bio is optional" do end) end + test "it requires an name, nickname and password, bio and email are optional when account_activation_required is disabled" do + Pleroma.Config.put([:instance, :account_activation_required], false) + + @full_user_data + |> Map.keys() + |> Enum.each(fn key -> + params = Map.delete(@full_user_data, key) + changeset = User.register_changeset(%User{}, params) + + assert if key in [:bio, :email], do: changeset.valid?, else: not changeset.valid? + end) + end + test "it restricts certain nicknames" do [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames]) diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 8625bb9cf..ff7cb88d1 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do @@ -601,6 +601,8 @@ test "blocking / unblocking a user" do [valid_params: valid_params] end + clear_config([:instance, :account_activation_required]) + test "Account registration via Application", %{conn: conn} do conn = post(conn, "/api/v1/apps", %{ @@ -731,7 +733,7 @@ test "returns bad_request if missing required params", %{ assert json_response(res, 200) [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}] - |> Stream.zip(valid_params) + |> Stream.zip(Map.delete(valid_params, :email)) |> Enum.each(fn {ip, {attr, _}} -> res = conn @@ -743,6 +745,52 @@ test "returns bad_request if missing required params", %{ end) end + test "returns bad_request if missing email params when :account_activation_required is enabled", + %{conn: conn, valid_params: valid_params} do + Pleroma.Config.put([:instance, :account_activation_required], true) + + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 5}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response(res, 400) == %{"error" => "Missing parameters"} + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 6}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response(res, 400) == %{"error" => "{\"email\":[\"can't be blank\"]}"} + end + + test "allow registration without an email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 7}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response(res, 200) + end + + test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 8}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response(res, 200) + end + test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token") From cc98d010edc444e260c81ac9f264a27d9afd5daf Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Tue, 25 Feb 2020 16:21:48 +0300 Subject: [PATCH 2/9] relay list shows hosts without accepted follow --- lib/mix/tasks/pleroma/relay.ex | 2 +- lib/pleroma/activity.ex | 7 ++++ lib/pleroma/web/activity_pub/relay.ex | 19 ++++++++-- test/fixtures/relay/accept-follow.json | 15 ++++++++ test/fixtures/relay/relay.json | 20 ++++++++++ test/support/http_request_mock.ex | 8 ++++ test/tasks/relay_test.exs | 3 ++ .../activity_pub_controller_test.exs | 38 +++++++++++++++++++ 8 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/relay/accept-follow.json create mode 100644 test/fixtures/relay/relay.json diff --git a/lib/mix/tasks/pleroma/relay.ex b/lib/mix/tasks/pleroma/relay.ex index 7ef5f9678..b0fadeae9 100644 --- a/lib/mix/tasks/pleroma/relay.ex +++ b/lib/mix/tasks/pleroma/relay.ex @@ -35,7 +35,7 @@ def run(["unfollow", target]) do def run(["list"]) do start_pleroma() - with {:ok, list} <- Relay.list() do + with {:ok, list} <- Relay.list(true) do list |> Enum.each(&shell_info(&1)) else {:error, e} -> shell_error("Error while fetching relay subscription list: #{inspect(e)}") diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 397eb6e3f..6ca05f74e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -308,6 +308,13 @@ def follow_requests_for_actor(%Pleroma.User{ap_id: ap_id}) do |> where([a], fragment("? ->> 'state' = 'pending'", a.data)) end + def following_requests_for_actor(%Pleroma.User{ap_id: ap_id}) do + Queries.by_type("Follow") + |> where([a], fragment("?->>'state' = 'pending'", a.data)) + |> where([a], a.actor == ^ap_id) + |> Repo.all() + end + def restrict_deactivated_users(query) do deactivated_users = from(u in User.Query.build(%{deactivated: true}), select: u.ap_id) diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index bb5542c89..729c23af7 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -60,15 +60,28 @@ def publish(%Activity{data: %{"type" => "Create"}} = activity) do def publish(_), do: {:error, "Not implemented"} - @spec list() :: {:ok, [String.t()]} | {:error, any()} - def list do + @spec list(boolean()) :: {:ok, [String.t()]} | {:error, any()} + def list(with_not_accepted \\ false) do with %User{} = user <- get_actor() do - list = + accepted = user |> User.following() |> Enum.map(fn entry -> URI.parse(entry).host end) |> Enum.uniq() + list = + if with_not_accepted do + without_accept = + user + |> Pleroma.Activity.following_requests_for_actor() + |> Enum.map(fn a -> URI.parse(a.data["object"]).host <> " (no Accept received)" end) + |> Enum.uniq() + + accepted ++ without_accept + else + accepted + end + {:ok, list} else error -> format_error(error) diff --git a/test/fixtures/relay/accept-follow.json b/test/fixtures/relay/accept-follow.json new file mode 100644 index 000000000..1b166f2da --- /dev/null +++ b/test/fixtures/relay/accept-follow.json @@ -0,0 +1,15 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "actor": "https://relay.mastodon.host/actor", + "id": "https://relay.mastodon.host/activities/ec477b69-db26-4019-923e-cf809de516ab", + "object": { + "actor": "{{ap_id}}", + "id": "{{activity_id}}", + "object": "https://relay.mastodon.host/actor", + "type": "Follow" + }, + "to": [ + "{{ap_id}}" + ], + "type": "Accept" +} \ No newline at end of file diff --git a/test/fixtures/relay/relay.json b/test/fixtures/relay/relay.json new file mode 100644 index 000000000..77ae7f06c --- /dev/null +++ b/test/fixtures/relay/relay.json @@ -0,0 +1,20 @@ +{ + "@context": "https://www.w3.org/ns/activitystreams", + "endpoints": { + "sharedInbox": "https://relay.mastodon.host/inbox" + }, + "followers": "https://relay.mastodon.host/followers", + "following": "https://relay.mastodon.host/following", + "inbox": "https://relay.mastodon.host/inbox", + "name": "ActivityRelay", + "type": "Application", + "id": "https://relay.mastodon.host/actor", + "publicKey": { + "id": "https://relay.mastodon.host/actor#main-key", + "owner": "https://relay.mastodon.host/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuNYHNYETdsZFsdcTTEQo\nlsTP9yz4ZjOGrQ1EjoBA7NkjBUxxUAPxZbBjWPT9F+L3IbCX1IwI2OrBM/KwDlug\nV41xnjNmxSCUNpxX5IMZtFaAz9/hWu6xkRTs9Bh6XWZxi+db905aOqszb9Mo3H2g\nQJiAYemXwTh2kBO7XlBDbsMhO11Tu8FxcWTMdR54vlGv4RoiVh8dJRa06yyiTs+m\njbj/OJwR06mHHwlKYTVT/587NUb+e9QtCK6t/dqpyZ1o7vKSK5PSldZVjwHt292E\nXVxFOQVXi7JazTwpdPww79ECSe8ThCykOYCNkm3RjsKuLuokp7Vzq1hXIoeBJ7z2\ndU8vbgg/JyazsOsTxkVs2nd2i9/QW2SH+sX9X3357+XLSCh/A8p8fv/GeoN7UCXe\n4DWHFJZDlItNFfymiPbQH+omuju8qrfW9ngk1gFeI2mahXFQVu7x0qsaZYioCIrZ\nwq0zPnUGl9u0tLUXQz+ZkInRrEz+JepDVauy5/3QdzMLG420zCj/ygDrFzpBQIrc\n62Z6URueUBJox0UK71K+usxqOrepgw8haFGMvg3STFo34pNYjoK4oKO+h5qZEDFD\nb1n57t6JWUaBocZbJns9RGASq5gih+iMk2+zPLWp1x64yvuLsYVLPLBHxjCxS6lA\ndWcopZHi7R/OsRz+vTT7420CAwEAAQ==\n-----END PUBLIC KEY-----" + }, + "summary": "ActivityRelay bot", + "preferredUsername": "relay", + "url": "https://relay.mastodon.host/actor" +} \ No newline at end of file diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index d46887865..e72638814 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -1277,6 +1277,10 @@ def get("http://example.com/rel_me/error", _, _, _) do {:ok, %Tesla.Env{status: 404, body: ""}} end + def get("https://relay.mastodon.host/actor", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}} + end + def get(url, query, body, headers) do {:error, "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ @@ -1289,6 +1293,10 @@ def get(url, query, body, headers) do def post(url, query \\ [], body \\ [], headers \\ []) + def post("https://relay.mastodon.host/inbox", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: ""}} + end + def post("http://example.org/needs_refresh", _, _, _) do {:ok, %Tesla.Env{ diff --git a/test/tasks/relay_test.exs b/test/tasks/relay_test.exs index 04a1e45d7..43565b7c7 100644 --- a/test/tasks/relay_test.exs +++ b/test/tasks/relay_test.exs @@ -38,6 +38,9 @@ test "relay is followed" do assert activity.data["type"] == "Follow" assert activity.data["actor"] == local_user.ap_id assert activity.data["object"] == target_user.ap_id + + :ok = Mix.Tasks.Pleroma.Relay.run(["list"]) + assert_receive {:mix_shell, :info, ["mastodon.example.org (no Accept received)"]} end end diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index ba2ce1dd9..0c80e2434 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -341,6 +341,44 @@ test "it clears `unreachable` federation status of the sender", %{conn: conn} do assert "ok" == json_response(conn, 200) assert Instances.reachable?(sender_url) end + + test "accept follow activity", %{conn: conn} do + Pleroma.Config.put([:instance, :federating], true) + relay = Relay.get_actor() + + assert {:ok, %Activity{} = activity} = Relay.follow("https://relay.mastodon.host/actor") + + followed_relay = Pleroma.User.get_by_ap_id("https://relay.mastodon.host/actor") + relay = refresh_record(relay) + + accept = + File.read!("test/fixtures/relay/accept-follow.json") + |> String.replace("{{ap_id}}", relay.ap_id) + |> String.replace("{{activity_id}}", activity.data["id"]) + + assert "ok" == + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/inbox", accept) + |> json_response(200) + + ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) + + assert Pleroma.FollowingRelationship.following?( + relay, + followed_relay + ) + + Mix.shell(Mix.Shell.Process) + + on_exit(fn -> + Mix.shell(Mix.Shell.IO) + end) + + :ok = Mix.Tasks.Pleroma.Relay.run(["list"]) + assert_receive {:mix_shell, :info, ["relay.mastodon.host"]} + end end describe "/users/:nickname/inbox" do From d9134d4430d4592030af12354aa2231e7c260140 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 10 Mar 2020 11:49:02 +0100 Subject: [PATCH 3/9] installation/otp_en.md: Fix pleroma.nginx target [deb] Needs to be backported to stable. Related: https://git.pleroma.social/pleroma/pleroma-support/issues/29 --- docs/installation/otp_en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation/otp_en.md b/docs/installation/otp_en.md index 32551f7b6..fb99af699 100644 --- a/docs/installation/otp_en.md +++ b/docs/installation/otp_en.md @@ -156,8 +156,8 @@ cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/conf.d/pleroma.conf ``` ```sh tab="Debian/Ubuntu" -cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.nginx -ln -s /etc/nginx/sites-available/pleroma.nginx /etc/nginx/sites-enabled/pleroma.nginx +cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.conf +ln -s /etc/nginx/sites-available/pleroma.conf /etc/nginx/sites-enabled/pleroma.conf ``` If your distro does not have either of those you can append `include /etc/nginx/pleroma.conf` to the end of the http section in /etc/nginx/nginx.conf and From a747eb6df9c554c9b17de03f2c1332f6fb9ba164 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 11 Mar 2020 06:35:18 +0100 Subject: [PATCH 4/9] static-fe.css: Restore from before a65ee8ea Related: https://git.pleroma.social/pleroma/pleroma/issues/1616 --- priv/static/static/static-fe.css | 176 +++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 priv/static/static/static-fe.css diff --git a/priv/static/static/static-fe.css b/priv/static/static/static-fe.css new file mode 100644 index 000000000..19c56387b --- /dev/null +++ b/priv/static/static/static-fe.css @@ -0,0 +1,176 @@ +body { + background-color: #282c37; + font-family: sans-serif; + color: white; +} + +main { + margin: 50px auto; + max-width: 960px; + padding: 40px; + background-color: #313543; + border-radius: 4px; +} + +header { + margin: 50px auto; + max-width: 960px; + padding: 40px; + background-color: #313543; + border-radius: 4px; +} + +.activity { + border-radius: 4px; + padding: 1em; + padding-bottom: 2em; + margin-bottom: 1em; +} + +.avatar { + cursor: pointer; +} + +.avatar img { + float: left; + border-radius: 4px; + margin-right: 4px; +} + +.activity-content img, video, audio { + padding: 1em; + max-width: 800px; + max-height: 800px; +} + +#selected { + background-color: #1b2735; +} + +.counts dt, .counts dd { + float: left; + margin-left: 1em; +} + +a { + color: white; +} + +.h-card { + min-height: 48px; + margin-bottom: 8px; +} + +header a, .h-card a { + text-decoration: none; +} + +header a:hover, .h-card a:hover { + text-decoration: underline; +} + +.display-name { + padding-top: 4px; + display: block; + text-overflow: ellipsis; + overflow: hidden; + color: white; +} + +/* keep emoji from being hilariously huge */ +.display-name img { + max-height: 1em; +} + +.display-name .nickname { + padding-top: 4px; + display: block; +} + +.nickname:hover { + text-decoration: none; +} + +.pull-right { + float: right; +} + +.collapse { + margin: 0; + width: auto; +} + +h1 { + margin: 0; +} + +h2 { + color: #9baec8; + font-weight: normal; + font-size: 20px; + margin-bottom: 40px; +} + +form { + width: 100%; +} + +input { + box-sizing: border-box; + width: 100%; + padding: 10px; + margin-top: 20px; + background-color: rgba(0,0,0,.1); + color: white; + border: 0; + border-bottom: 2px solid #9baec8; + font-size: 14px; +} + +input:focus { + border-bottom: 2px solid #4b8ed8; +} + +input[type="checkbox"] { + width: auto; +} + +button { + box-sizing: border-box; + width: 100%; + color: white; + background-color: #419bdd; + border-radius: 4px; + border: none; + padding: 10px; + margin-top: 30px; + text-transform: uppercase; + font-weight: 500; + font-size: 16px; +} + +.alert-danger { + box-sizing: border-box; + width: 100%; + color: #D8000C; + background-color: #FFD2D2; + border-radius: 4px; + border: none; + padding: 10px; + margin-top: 20px; + font-weight: 500; + font-size: 16px; +} + +.alert-info { + box-sizing: border-box; + width: 100%; + color: #00529B; + background-color: #BDE5F8; + border-radius: 4px; + border: none; + padding: 10px; + margin-top: 20px; + font-weight: 500; + font-size: 16px; +} From a06104b9d59f93d3275dff30854543c2e705b4fe Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 11 Mar 2020 08:35:46 +0100 Subject: [PATCH 5/9] CLI_tasks/user.md: Fix `pleroma.user new` documentation Closes: https://git.pleroma.social/pleroma/pleroma/issues/1621 [ci skip] --- docs/administration/CLI_tasks/user.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/administration/CLI_tasks/user.md b/docs/administration/CLI_tasks/user.md index da8363131..64385ad28 100644 --- a/docs/administration/CLI_tasks/user.md +++ b/docs/administration/CLI_tasks/user.md @@ -5,11 +5,11 @@ ## Create a user ```sh tab="OTP" -./bin/pleroma_ctl user new [] +./bin/pleroma_ctl user new [] ``` ```sh tab="From Source" -mix pleroma.user new [] +mix pleroma.user new [] ``` From 6316726a5fe9d65ee865d281efc2d2652001eb8c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 11 Mar 2020 08:46:57 +0100 Subject: [PATCH 6/9] CLI_tasks: Use manpage formatting conventions - [] for options - <> for mandatory arguments - foo ... when foo can be repeated [ci skip] --- docs/administration/CLI_tasks/database.md | 8 ++++---- docs/administration/CLI_tasks/digest.md | 4 ++-- docs/administration/CLI_tasks/emoji.md | 8 ++++---- docs/administration/CLI_tasks/instance.md | 4 ++-- docs/administration/CLI_tasks/uploads.md | 4 ++-- docs/administration/CLI_tasks/user.md | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/administration/CLI_tasks/database.md b/docs/administration/CLI_tasks/database.md index 51c7484ba..ff400c8ed 100644 --- a/docs/administration/CLI_tasks/database.md +++ b/docs/administration/CLI_tasks/database.md @@ -10,11 +10,11 @@ Replaces embedded objects with references to them in the `objects` table. Only needs to be ran once if the instance was created before Pleroma 1.0.5. The reason why this is not a migration is because it could significantly increase the database size after being ran, however after this `VACUUM FULL` will be able to reclaim about 20% (really depends on what is in the database, your mileage may vary) of the db size before the migration. ```sh tab="OTP" -./bin/pleroma_ctl database remove_embedded_objects [] +./bin/pleroma_ctl database remove_embedded_objects [option ...] ``` ```sh tab="From Source" -mix pleroma.database remove_embedded_objects [] +mix pleroma.database remove_embedded_objects [option ...] ``` ### Options @@ -28,11 +28,11 @@ This will prune remote posts older than 90 days (configurable with [`config :ple The disk space will only be reclaimed after `VACUUM FULL`. You may run out of disk space during the execution of the task or vacuuming if you don't have about 1/3rds of the database size free. ```sh tab="OTP" -./bin/pleroma_ctl database prune_objects [] +./bin/pleroma_ctl database prune_objects [option ...] ``` ```sh tab="From Source" -mix pleroma.database prune_objects [] +mix pleroma.database prune_objects [option ...] ``` ### Options diff --git a/docs/administration/CLI_tasks/digest.md b/docs/administration/CLI_tasks/digest.md index 1badda8c3..2eb31379e 100644 --- a/docs/administration/CLI_tasks/digest.md +++ b/docs/administration/CLI_tasks/digest.md @@ -5,11 +5,11 @@ ## Send digest email since given date (user registration date by default) ignoring user activity status. ```sh tab="OTP" - ./bin/pleroma_ctl digest test [] + ./bin/pleroma_ctl digest test [since_date] ``` ```sh tab="From Source" -mix pleroma.digest test [] +mix pleroma.digest test [since_date] ``` diff --git a/docs/administration/CLI_tasks/emoji.md b/docs/administration/CLI_tasks/emoji.md index a3207bc6c..efec8222c 100644 --- a/docs/administration/CLI_tasks/emoji.md +++ b/docs/administration/CLI_tasks/emoji.md @@ -5,11 +5,11 @@ ## Lists emoji packs and metadata specified in the manifest ```sh tab="OTP" -./bin/pleroma_ctl emoji ls-packs [] +./bin/pleroma_ctl emoji ls-packs [option ...] ``` ```sh tab="From Source" -mix pleroma.emoji ls-packs [] +mix pleroma.emoji ls-packs [option ...] ``` @@ -19,11 +19,11 @@ mix pleroma.emoji ls-packs [] ## Fetch, verify and install the specified packs from the manifest into `STATIC-DIR/emoji/PACK-NAME` ```sh tab="OTP" -./bin/pleroma_ctl emoji get-packs [] +./bin/pleroma_ctl emoji get-packs [option ...] ``` ```sh tab="From Source" -mix pleroma.emoji get-packs [] +mix pleroma.emoji get-packs [option ...] ``` ### Options diff --git a/docs/administration/CLI_tasks/instance.md b/docs/administration/CLI_tasks/instance.md index 1a3b268be..52e264bb1 100644 --- a/docs/administration/CLI_tasks/instance.md +++ b/docs/administration/CLI_tasks/instance.md @@ -4,11 +4,11 @@ ## Generate a new configuration file ```sh tab="OTP" - ./bin/pleroma_ctl instance gen [] + ./bin/pleroma_ctl instance gen [option ...] ``` ```sh tab="From Source" -mix pleroma.instance gen [] +mix pleroma.instance gen [option ...] ``` diff --git a/docs/administration/CLI_tasks/uploads.md b/docs/administration/CLI_tasks/uploads.md index e36c94c38..6a15d22f6 100644 --- a/docs/administration/CLI_tasks/uploads.md +++ b/docs/administration/CLI_tasks/uploads.md @@ -4,11 +4,11 @@ ## Migrate uploads from local to remote storage ```sh tab="OTP" - ./bin/pleroma_ctl uploads migrate_local [] + ./bin/pleroma_ctl uploads migrate_local [option ...] ``` ```sh tab="From Source" -mix pleroma.uploads migrate_local [] +mix pleroma.uploads migrate_local [option ...] ``` ### Options diff --git a/docs/administration/CLI_tasks/user.md b/docs/administration/CLI_tasks/user.md index 64385ad28..f535dad82 100644 --- a/docs/administration/CLI_tasks/user.md +++ b/docs/administration/CLI_tasks/user.md @@ -5,11 +5,11 @@ ## Create a user ```sh tab="OTP" -./bin/pleroma_ctl user new [] +./bin/pleroma_ctl user new [option ...] ``` ```sh tab="From Source" -mix pleroma.user new [] +mix pleroma.user new [option ...] ``` @@ -33,11 +33,11 @@ mix pleroma.user list ## Generate an invite link ```sh tab="OTP" - ./bin/pleroma_ctl user invite [] + ./bin/pleroma_ctl user invite [option ...] ``` ```sh tab="From Source" -mix pleroma.user invite [] +mix pleroma.user invite [option ...] ``` @@ -137,11 +137,11 @@ mix pleroma.user reset_password ## Set the value of the given user's settings ```sh tab="OTP" - ./bin/pleroma_ctl user set [] + ./bin/pleroma_ctl user set [option ...] ``` ```sh tab="From Source" -mix pleroma.user set [] +mix pleroma.user set [option ...] ``` ### Options From 282a93554fbf919ff553d839eeea98abe1f861d4 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 11 Mar 2020 16:25:53 +0300 Subject: [PATCH 7/9] merging release default config on app start --- lib/mix/tasks/pleroma/docs.ex | 2 +- lib/pleroma/application.ex | 1 + lib/pleroma/config/holder.ex | 38 +++++++++++++++---- lib/pleroma/config/loader.ex | 32 ++++++---------- lib/pleroma/config/transfer_task.ex | 2 +- lib/pleroma/docs/json.ex | 2 +- .../web/admin_api/admin_api_controller.ex | 2 +- test/config/holder_test.exs | 16 ++++---- test/config/loader_test.exs | 19 +--------- test/config/transfer_task_test.exs | 2 +- 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/lib/mix/tasks/pleroma/docs.ex b/lib/mix/tasks/pleroma/docs.ex index 3c870f876..6088fc71d 100644 --- a/lib/mix/tasks/pleroma/docs.ex +++ b/lib/mix/tasks/pleroma/docs.ex @@ -28,7 +28,7 @@ def run(_) do defp do_run(implementation) do start_pleroma() - with descriptions <- Pleroma.Config.Loader.load("config/description.exs"), + with descriptions <- Pleroma.Config.Loader.read("config/description.exs"), {:ok, file_path} <- Pleroma.Docs.Generator.process( implementation, diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 18854b850..c5b9a98fd 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -31,6 +31,7 @@ def user_agent do # See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do + Pleroma.Config.Holder.to_ets() Pleroma.HTML.compile_scrubbers() Pleroma.Config.DeprecationWarnings.warn() Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled() diff --git a/lib/pleroma/config/holder.ex b/lib/pleroma/config/holder.ex index f1a339703..88e1db313 100644 --- a/lib/pleroma/config/holder.ex +++ b/lib/pleroma/config/holder.ex @@ -3,14 +3,38 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Config.Holder do - @config Pleroma.Config.Loader.load_and_merge() + @config Pleroma.Config.Loader.default_config() - @spec config() :: keyword() - def config, do: @config + @spec to_ets() :: true + def to_ets do + :ets.new(:default_config, [:named_table, :protected]) - @spec config(atom()) :: any() - def config(group), do: @config[group] + default_config = + if System.get_env("RELEASE_NAME") do + release_config = + [:code.root_dir(), "releases", System.get_env("RELEASE_VSN"), "releases.exs"] + |> Path.join() + |> Pleroma.Config.Loader.read() - @spec config(atom(), atom()) :: any() - def config(group, key), do: @config[group][key] + Pleroma.Config.Loader.merge(@config, release_config) + else + @config + end + + :ets.insert(:default_config, {:config, default_config}) + end + + @spec default_config() :: keyword() + def default_config, do: from_ets() + + @spec default_config(atom()) :: keyword() + def default_config(group), do: Keyword.get(from_ets(), group) + + @spec default_config(atom(), atom()) :: keyword() + def default_config(group, key), do: get_in(from_ets(), [group, key]) + + defp from_ets do + [{:config, default_config}] = :ets.lookup(:default_config, :config) + default_config + end end diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index df2d18725..b2cb34129 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -13,32 +13,22 @@ defmodule Pleroma.Config.Loader do ] if Code.ensure_loaded?(Config.Reader) do - @spec load(Path.t()) :: keyword() - def load(path), do: Config.Reader.read!(path) - - defp do_merge(conf1, conf2), do: Config.Reader.merge(conf1, conf2) + @reader Config.Reader else # support for Elixir less than 1.9 - @spec load(Path.t()) :: keyword() - def load(path) do - path - |> Mix.Config.eval!() - |> elem(0) - end - - defp do_merge(conf1, conf2), do: Mix.Config.merge(conf1, conf2) + @reader Mix.Config end - @spec load_and_merge() :: keyword() - def load_and_merge do - all_paths = - if Pleroma.Config.get(:release), - do: ["config/config.exs", "config/releases.exs"], - else: ["config/config.exs"] + @spec read(Path.t()) :: keyword() + def read(path), do: @reader.read!(path) - all_paths - |> Enum.map(&load(&1)) - |> Enum.reduce([], &do_merge(&2, &1)) + @spec merge(keyword(), keyword()) :: keyword() + def merge(c1, c2), do: @reader.merge(c1, c2) + + @spec default_config() :: keyword() + def default_config do + "config/config.exs" + |> read() |> filter() end diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index 435fc7450..7c3449b5e 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -83,7 +83,7 @@ defp merge_and_update(setting) do key = ConfigDB.from_string(setting.key) group = ConfigDB.from_string(setting.group) - default = Pleroma.Config.Holder.config(group, key) + default = Pleroma.Config.Holder.default_config(group, key) value = ConfigDB.from_binary(setting.value) merged_value = diff --git a/lib/pleroma/docs/json.ex b/lib/pleroma/docs/json.ex index 6508a7bdb..74f8b2615 100644 --- a/lib/pleroma/docs/json.ex +++ b/lib/pleroma/docs/json.ex @@ -15,7 +15,7 @@ def process(descriptions) do end def compile do - with config <- Pleroma.Config.Loader.load("config/description.exs") do + with config <- Pleroma.Config.Loader.read("config/description.exs") do config[:pleroma][:config_description] |> Pleroma.Docs.Generator.convert_to_strings() |> Jason.encode!() diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index de0755ee5..47b7d2da3 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -834,7 +834,7 @@ def config_show(conn, _params) do configs = ConfigDB.get_all_as_keyword() merged = - Config.Holder.config() + Config.Holder.default_config() |> ConfigDB.merge(configs) |> Enum.map(fn {group, values} -> Enum.map(values, fn {key, value} -> diff --git a/test/config/holder_test.exs b/test/config/holder_test.exs index 2368d4856..15d48b5c7 100644 --- a/test/config/holder_test.exs +++ b/test/config/holder_test.exs @@ -7,8 +7,8 @@ defmodule Pleroma.Config.HolderTest do alias Pleroma.Config.Holder - test "config/0" do - config = Holder.config() + test "default_config/0" do + config = Holder.default_config() assert config[:pleroma][Pleroma.Uploaders.Local][:uploads] == "test/uploads" assert config[:tesla][:adapter] == Tesla.Mock @@ -20,15 +20,15 @@ test "config/0" do refute config[:phoenix][:serve_endpoints] end - test "config/1" do - pleroma_config = Holder.config(:pleroma) + test "default_config/1" do + pleroma_config = Holder.default_config(:pleroma) assert pleroma_config[Pleroma.Uploaders.Local][:uploads] == "test/uploads" - tesla_config = Holder.config(:tesla) + tesla_config = Holder.default_config(:tesla) assert tesla_config[:adapter] == Tesla.Mock end - test "config/2" do - assert Holder.config(:pleroma, Pleroma.Uploaders.Local) == [uploads: "test/uploads"] - assert Holder.config(:tesla, :adapter) == Tesla.Mock + test "default_config/2" do + assert Holder.default_config(:pleroma, Pleroma.Uploaders.Local) == [uploads: "test/uploads"] + assert Holder.default_config(:tesla, :adapter) == Tesla.Mock end end diff --git a/test/config/loader_test.exs b/test/config/loader_test.exs index 4c93e5d4d..607572f4e 100644 --- a/test/config/loader_test.exs +++ b/test/config/loader_test.exs @@ -7,28 +7,13 @@ defmodule Pleroma.Config.LoaderTest do alias Pleroma.Config.Loader - test "load/1" do - config = Loader.load("test/fixtures/config/temp.secret.exs") + test "read/1" do + config = Loader.read("test/fixtures/config/temp.secret.exs") assert config[:pleroma][:first_setting][:key] == "value" assert config[:pleroma][:first_setting][:key2] == [Pleroma.Repo] assert config[:quack][:level] == :info end - test "load_and_merge/0" do - config = Loader.load_and_merge() - - refute config[:pleroma][Pleroma.Repo] - refute config[:pleroma][Pleroma.Web.Endpoint] - refute config[:pleroma][:env] - refute config[:pleroma][:configurable_from_database] - refute config[:pleroma][:database] - refute config[:phoenix][:serve_endpoints] - - assert config[:pleroma][:ecto_repos] == [Pleroma.Repo] - assert config[:pleroma][Pleroma.Uploaders.Local][:uploads] == "test/uploads" - assert config[:tesla][:adapter] == Tesla.Mock - end - test "filter_group/2" do assert Loader.filter_group(:pleroma, pleroma: [ diff --git a/test/config/transfer_task_test.exs b/test/config/transfer_task_test.exs index ce31d1e87..01d04761d 100644 --- a/test/config/transfer_task_test.exs +++ b/test/config/transfer_task_test.exs @@ -70,7 +70,7 @@ test "transfer config values for 1 group and some keys" do assert Application.get_env(:quack, :level) == :info assert Application.get_env(:quack, :meta) == [:none] - default = Pleroma.Config.Holder.config(:quack, :webhook_url) + default = Pleroma.Config.Holder.default_config(:quack, :webhook_url) assert Application.get_env(:quack, :webhook_url) == default on_exit(fn -> From 193d67cde590efd9a75ac11da76657151f58afdd Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 11 Mar 2020 16:43:58 +0300 Subject: [PATCH 8/9] compile fix --- lib/pleroma/config/loader.ex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index b2cb34129..6ca6550bd 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -14,13 +14,19 @@ defmodule Pleroma.Config.Loader do if Code.ensure_loaded?(Config.Reader) do @reader Config.Reader + + def read(path), do: @reader.read!(path) else # support for Elixir less than 1.9 @reader Mix.Config + def read(path) do + path + |> @reader.eval!() + |> elem(0) + end end @spec read(Path.t()) :: keyword() - def read(path), do: @reader.read!(path) @spec merge(keyword(), keyword()) :: keyword() def merge(c1, c2), do: @reader.merge(c1, c2) From fce090c1de543f0bcebf47cfc2a32f99f8ef401f Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 11 Mar 2020 17:22:50 +0300 Subject: [PATCH 9/9] using Pleroma.Config instead of ets --- lib/pleroma/application.ex | 2 +- lib/pleroma/config/holder.ex | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index c5b9a98fd..33f1705df 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -31,7 +31,7 @@ def user_agent do # See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do - Pleroma.Config.Holder.to_ets() + Pleroma.Config.Holder.save_default() Pleroma.HTML.compile_scrubbers() Pleroma.Config.DeprecationWarnings.warn() Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled() diff --git a/lib/pleroma/config/holder.ex b/lib/pleroma/config/holder.ex index 88e1db313..f037d5d48 100644 --- a/lib/pleroma/config/holder.ex +++ b/lib/pleroma/config/holder.ex @@ -5,10 +5,8 @@ defmodule Pleroma.Config.Holder do @config Pleroma.Config.Loader.default_config() - @spec to_ets() :: true - def to_ets do - :ets.new(:default_config, [:named_table, :protected]) - + @spec save_default() :: :ok + def save_default do default_config = if System.get_env("RELEASE_NAME") do release_config = @@ -21,20 +19,17 @@ def to_ets do @config end - :ets.insert(:default_config, {:config, default_config}) + Pleroma.Config.put(:default_config, default_config) end @spec default_config() :: keyword() - def default_config, do: from_ets() + def default_config, do: get_default() @spec default_config(atom()) :: keyword() - def default_config(group), do: Keyword.get(from_ets(), group) + def default_config(group), do: Keyword.get(get_default(), group) @spec default_config(atom(), atom()) :: keyword() - def default_config(group, key), do: get_in(from_ets(), [group, key]) + def default_config(group, key), do: get_in(get_default(), [group, key]) - defp from_ets do - [{:config, default_config}] = :ets.lookup(:default_config, :config) - default_config - end + defp get_default, do: Pleroma.Config.get(:default_config) end