Page MenuHomePhorge

No OneTemporary

Size
33 KB
Referenced Files
None
Subscribers
None
diff --git a/docs/api/admin_api.md b/docs/api/admin_api.md
index c05a353d7..4be0ab0f8 100644
--- a/docs/api/admin_api.md
+++ b/docs/api/admin_api.md
@@ -1,648 +1,648 @@
# Admin API
Authentication is required and the user must be an admin.
## `/api/pleroma/admin/users`
### List users
- Method `GET`
- Query Params:
- *optional* `query`: **string** search term (e.g. nickname, domain, nickname@domain)
- *optional* `filters`: **string** comma-separated string of filters:
- `local`: only local users
- `external`: only external users
- `active`: only active users
- `deactivated`: only deactivated users
- `is_admin`: users with admin role
- `is_moderator`: users with moderator role
- *optional* `page`: **integer** page number
- *optional* `page_size`: **integer** number of users per page (default is `50`)
- *optional* `tags`: **[string]** tags list
- *optional* `name`: **string** user display name
- *optional* `email`: **string** user email
- Example: `https://mypleroma.org/api/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10&tags[]=some_tag&tags[]=another_tag&name=display_name&email=email@example.com`
- Response:
```json
{
"page_size": integer,
"count": integer,
"users": [
{
"deactivated": bool,
"id": integer,
"nickname": string,
"roles": {
"admin": bool,
"moderator": bool
},
"local": bool,
"tags": array
},
...
]
}
```
## `/api/pleroma/admin/users`
### Remove a user
- Method `DELETE`
- Params:
- `nickname`
- Response: User’s nickname
### Create a user
- Method: `POST`
- Params:
- `nickname`
- `email`
- `password`
- Response: User’s nickname
## `/api/pleroma/admin/users/follow`
### Make a user follow another user
- Methods: `POST`
- Params:
- `follower`: The nickname of the follower
- `followed`: The nickname of the followed
- Response:
- "ok"
## `/api/pleroma/admin/users/unfollow`
### Make a user unfollow another user
- Methods: `POST`
- Params:
- `follower`: The nickname of the follower
- `followed`: The nickname of the followed
- Response:
- "ok"
## `/api/pleroma/admin/users/:nickname/toggle_activation`
### Toggle user activation
- Method: `PATCH`
- Params:
- `nickname`
- Response: User’s object
```json
{
"deactivated": bool,
"id": integer,
"nickname": string
}
```
## `/api/pleroma/admin/users/tag`
### Tag a list of users
- Method: `PUT`
- Params:
- `nicknames` (array)
- `tags` (array)
### Untag a list of users
- Method: `DELETE`
- Params:
- `nicknames` (array)
- `tags` (array)
## `/api/pleroma/admin/users/:nickname/permission_group`
### Get user user permission groups membership
- Method: `GET`
- Params: none
- Response:
```json
{
"is_moderator": bool,
"is_admin": bool
}
```
## `/api/pleroma/admin/users/:nickname/permission_group/:permission_group`
Note: Available `:permission_group` is currently moderator and admin. 404 is returned when the permission group doesn’t exist.
### Get user user permission groups membership per permission group
- Method: `GET`
- Params: none
- Response:
```json
{
"is_moderator": bool,
"is_admin": bool
}
```
### Add user in permission group
- Method: `POST`
- Params: none
- Response:
- On failure: `{"error": "…"}`
- On success: JSON of the `user.info`
### Remove user from permission group
- Method: `DELETE`
- Params: none
- Response:
- On failure: `{"error": "…"}`
- On success: JSON of the `user.info`
- Note: An admin cannot revoke their own admin status.
## `/api/pleroma/admin/users/:nickname/activation_status`
### Active or deactivate a user
- Method: `PUT`
- Params:
- `nickname`
- `status` BOOLEAN field, false value means deactivation.
## `/api/pleroma/admin/users/:nickname`
### Retrive the details of a user
- Method: `GET`
- Params:
- `nickname`
- Response:
- On failure: `Not found`
- On success: JSON of the user
## `/api/pleroma/admin/relay`
### Follow a Relay
- Methods: `POST`
- Params:
- `relay_url`
- Response:
- On success: URL of the followed relay
### Unfollow a Relay
- Methods: `DELETE`
- Params:
- `relay_url`
- Response:
- On success: URL of the unfollowed relay
## `/api/pleroma/admin/users/invite_token`
### Get an account registration invite token
- Methods: `GET`
- Params:
- *optional* `invite` => [
- *optional* `max_use` (integer)
- *optional* `expires_at` (date string e.g. "2019-04-07")
]
- Response: invite token (base64 string)
## `/api/pleroma/admin/users/invites`
### Get a list of generated invites
- Methods: `GET`
- Params: none
- Response:
```json
{
"invites": [
{
"id": integer,
"token": string,
"used": boolean,
"expires_at": date,
"uses": integer,
"max_use": integer,
"invite_type": string (possible values: `one_time`, `reusable`, `date_limited`, `reusable_date_limited`)
},
...
]
}
```
## `/api/pleroma/admin/users/revoke_invite`
### Revoke invite by token
- Methods: `POST`
- Params:
- `token`
- Response:
```json
{
"id": integer,
"token": string,
"used": boolean,
"expires_at": date,
"uses": integer,
"max_use": integer,
"invite_type": string (possible values: `one_time`, `reusable`, `date_limited`, `reusable_date_limited`)
}
```
## `/api/pleroma/admin/users/email_invite`
### Sends registration invite via email
- Methods: `POST`
- Params:
- `email`
- `name`, optional
## `/api/pleroma/admin/users/:nickname/password_reset`
### Get a password reset token for a given nickname
- Methods: `GET`
- Params: none
- Response: password reset token (base64 string)
## `/api/pleroma/admin/reports`
### Get a list of reports
- Method `GET`
- Params:
- `state`: optional, the state of reports. Valid values are `open`, `closed` and `resolved`
- `limit`: optional, the number of records to retrieve
- `since_id`: optional, returns results that are more recent than the specified id
- `max_id`: optional, returns results that are older than the specified id
- Response:
- On failure: 403 Forbidden error `{"error": "error_msg"}` when requested by anonymous or non-admin
- On success: JSON, returns a list of reports, where:
- `account`: the user who has been reported
- `actor`: the user who has sent the report
- `statuses`: list of statuses that have been included to the report
```json
{
"reports": [
{
"account": {
"acct": "user",
"avatar": "https://pleroma.example.org/images/avi.png",
"avatar_static": "https://pleroma.example.org/images/avi.png",
"bot": false,
"created_at": "2019-04-23T17:32:04.000Z",
"display_name": "User",
"emojis": [],
"fields": [],
"followers_count": 1,
"following_count": 1,
"header": "https://pleroma.example.org/images/banner.png",
"header_static": "https://pleroma.example.org/images/banner.png",
"id": "9i6dAJqSGSKMzLG2Lo",
"locked": false,
"note": "",
"pleroma": {
"confirmation_pending": false,
"hide_favorites": true,
"hide_followers": false,
"hide_follows": false,
"is_admin": false,
"is_moderator": false,
"relationship": {},
"tags": []
},
"source": {
"note": "",
"pleroma": {},
"sensitive": false
},
"statuses_count": 3,
"url": "https://pleroma.example.org/users/user",
"username": "user"
},
"actor": {
"acct": "lain",
"avatar": "https://pleroma.example.org/images/avi.png",
"avatar_static": "https://pleroma.example.org/images/avi.png",
"bot": false,
"created_at": "2019-03-28T17:36:03.000Z",
"display_name": "Roger Braun",
"emojis": [],
"fields": [],
"followers_count": 1,
"following_count": 1,
"header": "https://pleroma.example.org/images/banner.png",
"header_static": "https://pleroma.example.org/images/banner.png",
"id": "9hEkA5JsvAdlSrocam",
"locked": false,
"note": "",
"pleroma": {
"confirmation_pending": false,
"hide_favorites": false,
"hide_followers": false,
"hide_follows": false,
"is_admin": false,
"is_moderator": false,
"relationship": {},
"tags": []
},
"source": {
"note": "",
"pleroma": {},
"sensitive": false
},
"statuses_count": 1,
"url": "https://pleroma.example.org/users/lain",
"username": "lain"
},
"content": "Please delete it",
"created_at": "2019-04-29T19:48:15.000Z",
"id": "9iJGOv1j8hxuw19bcm",
"state": "open",
"statuses": [
{
"account": { ... },
"application": {
"name": "Web",
"website": null
},
"bookmarked": false,
"card": null,
"content": "<span class=\"h-card\"><a data-user=\"9hEkA5JsvAdlSrocam\" class=\"u-url mention\" href=\"https://pleroma.example.org/users/lain\">@<span>lain</span></a></span> click on my link <a href=\"https://www.google.com/\">https://www.google.com/</a>",
"created_at": "2019-04-23T19:15:47.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 0,
"id": "9i6mQ9uVrrOmOime8m",
"in_reply_to_account_id": null,
"in_reply_to_id": null,
"language": null,
"media_attachments": [],
"mentions": [
{
"acct": "lain",
"id": "9hEkA5JsvAdlSrocam",
"url": "https://pleroma.example.org/users/lain",
"username": "lain"
},
{
"acct": "user",
"id": "9i6dAJqSGSKMzLG2Lo",
"url": "https://pleroma.example.org/users/user",
"username": "user"
}
],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "@lain click on my link https://www.google.com/"
},
"conversation_id": 28,
"in_reply_to_account_acct": null,
"local": true,
"spoiler_text": {
"text/plain": ""
}
},
"reblog": null,
"reblogged": false,
"reblogs_count": 0,
"replies_count": 0,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"uri": "https://pleroma.example.org/objects/8717b90f-8e09-4b58-97b0-e3305472b396",
"url": "https://pleroma.example.org/notice/9i6mQ9uVrrOmOime8m",
"visibility": "direct"
}
]
}
]
}
```
## `/api/pleroma/admin/reports/:id`
### Get an individual report
- Method `GET`
- Params:
- `id`
- Response:
- On failure:
- 403 Forbidden `{"error": "error_msg"}`
- 404 Not Found `"Not found"`
- On success: JSON, Report object (see above)
## `/api/pleroma/admin/reports/:id`
### Change the state of the report
- Method `PUT`
- Params:
- `id`
- `state`: required, the new state. Valid values are `open`, `closed` and `resolved`
- Response:
- On failure:
- 400 Bad Request `"Unsupported state"`
- 403 Forbidden `{"error": "error_msg"}`
- 404 Not Found `"Not found"`
- On success: JSON, Report object (see above)
## `/api/pleroma/admin/reports/:id/respond`
### Respond to a report
- Method `POST`
- Params:
- `id`
- `status`: required, the message
- Response:
- On failure:
- 400 Bad Request `"Invalid parameters"` when `status` is missing
- 403 Forbidden `{"error": "error_msg"}`
- 404 Not Found `"Not found"`
- On success: JSON, created Mastodon Status entity
```json
{
"account": { ... },
"application": {
"name": "Web",
"website": null
},
"bookmarked": false,
"card": null,
"content": "Your claim is going to be closed",
"created_at": "2019-05-11T17:13:03.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 0,
"id": "9ihuiSL1405I65TmEq",
"in_reply_to_account_id": null,
"in_reply_to_id": null,
"language": null,
"media_attachments": [],
"mentions": [
{
"acct": "user",
"id": "9i6dAJqSGSKMzLG2Lo",
"url": "https://pleroma.example.org/users/user",
"username": "user"
},
{
"acct": "admin",
"id": "9hEkA5JsvAdlSrocam",
"url": "https://pleroma.example.org/users/admin",
"username": "admin"
}
],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "Your claim is going to be closed"
},
"conversation_id": 35,
"in_reply_to_account_acct": null,
"local": true,
"spoiler_text": {
"text/plain": ""
}
},
"reblog": null,
"reblogged": false,
"reblogs_count": 0,
"replies_count": 0,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"uri": "https://pleroma.example.org/objects/cab0836d-9814-46cd-a0ea-529da9db5fcb",
"url": "https://pleroma.example.org/notice/9ihuiSL1405I65TmEq",
"visibility": "direct"
}
```
## `/api/pleroma/admin/statuses/:id`
### Change the scope of an individual reported status
- Method `PUT`
- Params:
- `id`
- `sensitive`: optional, valid values are `true` or `false`
- `visibility`: optional, valid values are `public`, `private` and `unlisted`
- Response:
- On failure:
- 400 Bad Request `"Unsupported visibility"`
- 403 Forbidden `{"error": "error_msg"}`
- 404 Not Found `"Not found"`
- On success: JSON, Mastodon Status entity
## `/api/pleroma/admin/statuses/:id`
### Delete an individual reported status
- Method `DELETE`
- Params:
- `id`
- Response:
- On failure:
- 403 Forbidden `{"error": "error_msg"}`
- 404 Not Found `"Not found"`
- On success: 200 OK `{}`
## `/api/pleroma/admin/config`
### List config settings
- Method `GET`
- Params: none
- Response:
```json
{
configs: [
{
"group": string,
"key": string,
"value": string or {} or [] or {"tuple": []}
}
]
}
```
## `/api/pleroma/admin/config`
### Update config settings
Module name can be passed as string, which starts with `Pleroma`, e.g. `"Pleroma.Upload"`.
-Atom or boolean value can be passed with `:` in the beginning, e.g. `":true"`, `":upload"`.
+Atom or boolean value can be passed with `:` in the beginning, e.g. `":true"`, `":upload"`. For keys it is not needed.
Integer with `i:`, e.g. `"i:150"`.
Tuple with more than 2 values with `{"tuple": ["first_val", Pleroma.Module, []]}`.
`{"tuple": ["some_string", "Pleroma.Some.Module", []]}` will be converted to `{"some_string", Pleroma.Some.Module, []}`.
Compile time settings (need instance reboot):
- all settings by this keys:
- `:hackney_pools`
- `:chat`
- `Pleroma.Web.Endpoint`
- `Pleroma.Repo`
- part settings:
- `Pleroma.Captcha` -> `:seconds_valid`
- `Pleroma.Upload` -> `:proxy_remote`
- `:instance` -> `:upload_limit`
- Method `POST`
- Params:
- `configs` => [
- `group` (string)
- `key` (string)
- `value` (string, [], {} or {"tuple": []})
- `delete` = true (optional, if parameter must be deleted)
]
- Request (example):
```json
{
configs: [
{
"group": "pleroma",
"key": "Pleroma.Upload",
"value": {
"uploader": "Pleroma.Uploaders.Local",
"filters": ["Pleroma.Upload.Filter.Dedupe"],
"link_name": ":true",
"proxy_remote": ":false",
"proxy_opts": {
"redirect_on_failure": ":false",
"max_body_length": "i:1048576",
"http": {
"follow_redirect": ":true",
"pool": ":upload"
}
},
"dispatch": {
"tuple": ["/api/v1/streaming", "Pleroma.Web.MastodonAPI.WebsocketHandler", []]
}
}
}
]
}
- Response:
```json
{
configs: [
{
"group": string,
"key": string,
"value": string or {} or [] or {"tuple": []}
}
]
}
```
diff --git a/lib/mix/tasks/pleroma/config.ex b/lib/mix/tasks/pleroma/config.ex
index 4ed2c9789..faa605d9b 100644
--- a/lib/mix/tasks/pleroma/config.ex
+++ b/lib/mix/tasks/pleroma/config.ex
@@ -1,71 +1,79 @@
defmodule Mix.Tasks.Pleroma.Config do
use Mix.Task
import Mix.Pleroma
alias Pleroma.Repo
alias Pleroma.Web.AdminAPI.Config
@shortdoc "Manages the location of the config"
@moduledoc """
Manages the location of the config.
## Transfers config from file to DB.
mix pleroma.config migrate_to_db
## Transfers config from DB to file.
mix pleroma.config migrate_from_db ENV
"""
def run(["migrate_to_db"]) do
start_pleroma()
if Pleroma.Config.get([:instance, :dynamic_configuration]) do
Application.get_all_env(:pleroma)
|> Enum.reject(fn {k, _v} -> k in [Pleroma.Repo, :env] end)
|> Enum.each(fn {k, v} ->
key = to_string(k) |> String.replace("Elixir.", "")
{:ok, _} = Config.update_or_create(%{group: "pleroma", key: key, value: v})
Mix.shell().info("#{key} is migrated.")
end)
Mix.shell().info("Settings migrated.")
else
Mix.shell().info(
"Migration is not allowed by config. You can change this behavior in instance settings."
)
end
end
- def run(["migrate_from_db", env]) do
+ def run(["migrate_from_db", env, delete?]) do
start_pleroma()
+ delete? = if delete? == "true", do: true, else: false
+
if Pleroma.Config.get([:instance, :dynamic_configuration]) do
config_path = "config/#{env}.exported_from_db.secret.exs"
{:ok, file} = File.open(config_path, [:write])
IO.write(file, "use Mix.Config\r\n")
Repo.all(Config)
|> Enum.each(fn config ->
- mark = if String.starts_with?(config.key, "Pleroma."), do: ",", else: ":"
+ mark =
+ if String.starts_with?(config.key, "Pleroma.") or
+ String.starts_with?(config.key, "Ueberauth"),
+ do: ",",
+ else: ":"
IO.write(
file,
"config :#{config.group}, #{config.key}#{mark} #{
inspect(Config.from_binary(config.value))
}\r\n"
)
- {:ok, _} = Repo.delete(config)
- Mix.shell().info("#{config.key} deleted from DB.")
+ if delete? do
+ {:ok, _} = Repo.delete(config)
+ Mix.shell().info("#{config.key} deleted from DB.")
+ end
end)
File.close(file)
System.cmd("mix", ["format", config_path])
else
Mix.shell().info(
"Migration is not allowed by config. You can change this behavior in instance settings."
)
end
end
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 953a22ea0..498beb56a 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -1,447 +1,447 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
use Pleroma.Web, :controller
alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.AdminAPI.Config
alias Pleroma.Web.AdminAPI.ConfigView
alias Pleroma.Web.AdminAPI.ReportView
alias Pleroma.Web.AdminAPI.Search
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.StatusView
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
require Logger
@users_page_size 50
action_fallback(:errors)
def user_delete(conn, %{"nickname" => nickname}) do
User.get_cached_by_nickname(nickname)
|> User.delete()
conn
|> json(nickname)
end
def user_follow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
%User{} = followed <- User.get_cached_by_nickname(followed_nick) do
User.follow(follower, followed)
end
conn
|> json("ok")
end
def user_unfollow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
%User{} = followed <- User.get_cached_by_nickname(followed_nick) do
User.unfollow(follower, followed)
end
conn
|> json("ok")
end
def user_create(
conn,
%{"nickname" => nickname, "email" => email, "password" => password}
) do
user_data = %{
nickname: nickname,
name: nickname,
email: email,
password: password,
password_confirmation: password,
bio: "."
}
changeset = User.register_changeset(%User{}, user_data, need_confirmation: false)
{:ok, user} = User.register(changeset)
conn
|> json(user.nickname)
end
def user_show(conn, %{"nickname" => nickname}) do
with %User{} = user <- User.get_cached_by_nickname(nickname) do
conn
|> json(AccountView.render("show.json", %{user: user}))
else
_ -> {:error, :not_found}
end
end
def user_toggle_activation(conn, %{"nickname" => nickname}) do
user = User.get_cached_by_nickname(nickname)
{:ok, updated_user} = User.deactivate(user, !user.info.deactivated)
conn
|> json(AccountView.render("show.json", %{user: updated_user}))
end
def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
with {:ok, _} <- User.tag(nicknames, tags),
do: json_response(conn, :no_content, "")
end
def untag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
with {:ok, _} <- User.untag(nicknames, tags),
do: json_response(conn, :no_content, "")
end
def list_users(conn, params) do
{page, page_size} = page_params(params)
filters = maybe_parse_filters(params["filters"])
search_params = %{
query: params["query"],
page: page,
page_size: page_size,
tags: params["tags"],
name: params["name"],
email: params["email"]
}
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
do:
conn
|> json(
AccountView.render("index.json",
users: users,
count: count,
page_size: page_size
)
)
end
@filters ~w(local external active deactivated is_admin is_moderator)
@spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
defp maybe_parse_filters(filters) do
filters
|> String.split(",")
|> Enum.filter(&Enum.member?(@filters, &1))
|> Enum.map(&String.to_atom(&1))
|> Enum.into(%{}, &{&1, true})
end
def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})
when permission_group in ["moderator", "admin"] do
user = User.get_cached_by_nickname(nickname)
info =
%{}
|> Map.put("is_" <> permission_group, true)
info_cng = User.Info.admin_api_update(user.info, info)
cng =
user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_cng)
{:ok, _user} = User.update_and_set_cache(cng)
json(conn, info)
end
def right_add(conn, _) do
conn
|> put_status(404)
|> json(%{error: "No such permission_group"})
end
def right_get(conn, %{"nickname" => nickname}) do
user = User.get_cached_by_nickname(nickname)
conn
|> json(%{
is_moderator: user.info.is_moderator,
is_admin: user.info.is_admin
})
end
def right_delete(
%{assigns: %{user: %User{:nickname => admin_nickname}}} = conn,
%{
"permission_group" => permission_group,
"nickname" => nickname
}
)
when permission_group in ["moderator", "admin"] do
if admin_nickname == nickname do
conn
|> put_status(403)
|> json(%{error: "You can't revoke your own admin status."})
else
user = User.get_cached_by_nickname(nickname)
info =
%{}
|> Map.put("is_" <> permission_group, false)
info_cng = User.Info.admin_api_update(user.info, info)
cng =
Ecto.Changeset.change(user)
|> Ecto.Changeset.put_embed(:info, info_cng)
{:ok, _user} = User.update_and_set_cache(cng)
json(conn, info)
end
end
def right_delete(conn, _) do
conn
|> put_status(404)
|> json(%{error: "No such permission_group"})
end
def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do
with {:ok, status} <- Ecto.Type.cast(:boolean, status),
%User{} = user <- User.get_cached_by_nickname(nickname),
{:ok, _} <- User.deactivate(user, !status),
do: json_response(conn, :no_content, "")
end
def relay_follow(conn, %{"relay_url" => target}) do
with {:ok, _message} <- Relay.follow(target) do
json(conn, target)
else
_ ->
conn
|> put_status(500)
|> json(target)
end
end
def relay_unfollow(conn, %{"relay_url" => target}) do
with {:ok, _message} <- Relay.unfollow(target) do
json(conn, target)
else
_ ->
conn
|> put_status(500)
|> json(target)
end
end
@doc "Sends registration invite via email"
def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
with true <-
Pleroma.Config.get([:instance, :invites_enabled]) &&
!Pleroma.Config.get([:instance, :registrations_open]),
{:ok, invite_token} <- UserInviteToken.create_invite(),
email <-
Pleroma.Emails.UserEmail.user_invitation_email(
user,
invite_token,
email,
params["name"]
),
{:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
json_response(conn, :no_content, "")
end
end
@doc "Get a account registeration invite token (base64 string)"
def get_invite_token(conn, params) do
options = params["invite"] || %{}
{:ok, invite} = UserInviteToken.create_invite(options)
conn
|> json(invite.token)
end
@doc "Get list of created invites"
def invites(conn, _params) do
invites = UserInviteToken.list_invites()
conn
|> json(AccountView.render("invites.json", %{invites: invites}))
end
@doc "Revokes invite by token"
def revoke_invite(conn, %{"token" => token}) do
invite = UserInviteToken.find_by_token!(token)
{:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true})
conn
|> json(AccountView.render("invite.json", %{invite: updated_invite}))
end
@doc "Get a password reset token (base64 string) for given nickname"
def get_password_reset(conn, %{"nickname" => nickname}) do
(%User{local: true} = user) = User.get_cached_by_nickname(nickname)
{:ok, token} = Pleroma.PasswordResetToken.create_token(user)
conn
|> json(token.token)
end
def list_reports(conn, params) do
params =
params
|> Map.put("type", "Flag")
|> Map.put("skip_preload", true)
reports =
[]
|> ActivityPub.fetch_activities(params)
|> Enum.reverse()
conn
|> put_view(ReportView)
|> render("index.json", %{reports: reports})
end
def report_show(conn, %{"id" => id}) do
with %Activity{} = report <- Activity.get_by_id(id) do
conn
|> put_view(ReportView)
|> render("show.json", %{report: report})
else
_ -> {:error, :not_found}
end
end
def report_update_state(conn, %{"id" => id, "state" => state}) do
with {:ok, report} <- CommonAPI.update_report_state(id, state) do
conn
|> put_view(ReportView)
|> render("show.json", %{report: report})
end
end
def report_respond(%{assigns: %{user: user}} = conn, %{"id" => id} = params) do
with false <- is_nil(params["status"]),
%Activity{} <- Activity.get_by_id(id) do
params =
params
|> Map.put("in_reply_to_status_id", id)
|> Map.put("visibility", "direct")
{:ok, activity} = CommonAPI.post(user, params)
conn
|> put_view(StatusView)
|> render("status.json", %{activity: activity})
else
true ->
{:param_cast, nil}
nil ->
{:error, :not_found}
end
end
def status_update(conn, %{"id" => id} = params) do
with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
conn
|> put_view(StatusView)
|> render("status.json", %{activity: activity})
end
end
def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
json(conn, %{})
end
end
def config_show(conn, _params) do
configs = Pleroma.Repo.all(Config)
conn
|> put_view(ConfigView)
|> render("index.json", %{configs: configs})
end
def config_update(conn, %{"configs" => configs}) do
updated =
if Pleroma.Config.get([:instance, :dynamic_configuration]) do
updated =
Enum.map(configs, fn
%{"group" => group, "key" => key, "value" => value} ->
{:ok, config} = Config.update_or_create(%{group: group, key: key, value: value})
config
%{"group" => group, "key" => key, "delete" => "true"} ->
{:ok, _} = Config.delete(%{group: group, key: key})
nil
end)
|> Enum.reject(&is_nil(&1))
Pleroma.Config.TransferTask.load_and_update_env()
- Mix.Tasks.Pleroma.Config.run(["migrate_from_db", Pleroma.Config.get(:env)])
+ Mix.Tasks.Pleroma.Config.run(["migrate_from_db", Pleroma.Config.get(:env), "false"])
updated
else
[]
end
conn
|> put_view(ConfigView)
|> render("index.json", %{configs: updated})
end
def errors(conn, {:error, :not_found}) do
conn
|> put_status(404)
|> json("Not found")
end
def errors(conn, {:error, reason}) do
conn
|> put_status(400)
|> json(reason)
end
def errors(conn, {:param_cast, _}) do
conn
|> put_status(400)
|> json("Invalid parameters")
end
def errors(conn, _) do
conn
|> put_status(500)
|> json("Something went wrong")
end
defp page_params(params) do
{get_page(params["page"]), get_page_size(params["page_size"])}
end
defp get_page(page_string) when is_nil(page_string), do: 1
defp get_page(page_string) do
case Integer.parse(page_string) do
{page, _} -> page
:error -> 1
end
end
defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
defp get_page_size(page_size_string) do
case Integer.parse(page_size_string) do
{page_size, _} -> page_size
:error -> @users_page_size
end
end
end
diff --git a/test/tasks/config_test.exs b/test/tasks/config_test.exs
index 9c9a31bf4..83a363356 100644
--- a/test/tasks/config_test.exs
+++ b/test/tasks/config_test.exs
@@ -1,63 +1,63 @@
defmodule Mix.Tasks.Pleroma.ConfigTest do
use Pleroma.DataCase
alias Pleroma.Repo
alias Pleroma.Web.AdminAPI.Config
setup_all do
Mix.shell(Mix.Shell.Process)
temp_file = "config/temp.exported_from_db.secret.exs"
dynamic = Pleroma.Config.get([:instance, :dynamic_configuration])
Pleroma.Config.put([:instance, :dynamic_configuration], true)
on_exit(fn ->
Mix.shell(Mix.Shell.IO)
Application.delete_env(:pleroma, :first_setting)
Application.delete_env(:pleroma, :second_setting)
Pleroma.Config.put([:instance, :dynamic_configuration], dynamic)
:ok = File.rm(temp_file)
end)
{:ok, temp_file: temp_file}
end
test "settings are migrated to db" do
assert Repo.all(Config) == []
Application.put_env(:pleroma, :first_setting, key: "value", key2: [Pleroma.Repo])
Application.put_env(:pleroma, :second_setting, key: "value2", key2: [Pleroma.Activity])
Mix.Tasks.Pleroma.Config.run(["migrate_to_db"])
first_db = Config.get_by_params(%{group: "pleroma", key: "first_setting"})
second_db = Config.get_by_params(%{group: "pleroma", key: "second_setting"})
refute Config.get_by_params(%{group: "pleroma", key: "Pleroma.Repo"})
assert Config.from_binary(first_db.value) == [key: "value", key2: [Pleroma.Repo]]
assert Config.from_binary(second_db.value) == [key: "value2", key2: [Pleroma.Activity]]
end
test "settings are migrated to file and deleted from db", %{temp_file: temp_file} do
Config.create(%{
group: "pleroma",
key: "setting_first",
value: [key: "value", key2: [Pleroma.Activity]]
})
Config.create(%{
group: "pleroma",
key: "setting_second",
value: [key: "valu2", key2: [Pleroma.Repo]]
})
- Mix.Tasks.Pleroma.Config.run(["migrate_from_db", "temp"])
+ Mix.Tasks.Pleroma.Config.run(["migrate_from_db", "temp", "true"])
assert Repo.all(Config) == []
assert File.exists?(temp_file)
{:ok, file} = File.read(temp_file)
assert file =~ "config :pleroma, setting_first:"
assert file =~ "config :pleroma, setting_second:"
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 10, 9:34 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785465
Default Alt Text
(33 KB)

Event Timeline