forked from AkkomaGang/akkoma
Merge branch 'develop' into fix/signup-without-email
This commit is contained in:
commit
4a45b96a91
1657 changed files with 5508 additions and 4756 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -47,3 +47,5 @@ docs/generated_config.md
|
||||||
.idea
|
.idea
|
||||||
pleroma.iml
|
pleroma.iml
|
||||||
|
|
||||||
|
# asdf
|
||||||
|
.tool-versions
|
||||||
|
|
|
@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Security
|
||||||
|
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- **Breaking**: Removed 1.0+ deprecated configurations `Pleroma.Upload, :strip_exif` and `:instance, :dedupe_media`
|
- **Breaking**: Removed 1.0+ deprecated configurations `Pleroma.Upload, :strip_exif` and `:instance, :dedupe_media`
|
||||||
- **Breaking**: OStatus protocol support
|
- **Breaking**: OStatus protocol support
|
||||||
|
@ -57,6 +60,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Admin API: Render whole status in grouped reports
|
- Admin API: Render whole status in grouped reports
|
||||||
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
||||||
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
||||||
|
- Mastodon API: Limit timeline requests to 3 per timeline per 500ms per user/ip by default.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -105,6 +109,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Configuration: `feed` option for user atom feed.
|
- Configuration: `feed` option for user atom feed.
|
||||||
- Pleroma API: Add Emoji reactions
|
- Pleroma API: Add Emoji reactions
|
||||||
- Admin API: Add `/api/pleroma/admin/instances/:instance/statuses` - lists all statuses from a given instance
|
- Admin API: Add `/api/pleroma/admin/instances/:instance/statuses` - lists all statuses from a given instance
|
||||||
|
- Admin API: Add `/api/pleroma/admin/users/:nickname/statuses` - lists all statuses from a given user
|
||||||
- Admin API: `PATCH /api/pleroma/users/confirm_email` to confirm email for multiple users, `PATCH /api/pleroma/users/resend_confirmation_email` to resend confirmation email for multiple users
|
- Admin API: `PATCH /api/pleroma/users/confirm_email` to confirm email for multiple users, `PATCH /api/pleroma/users/resend_confirmation_email` to resend confirmation email for multiple users
|
||||||
- ActivityPub: Configurable `type` field of the actors.
|
- ActivityPub: Configurable `type` field of the actors.
|
||||||
- Mastodon API: `/api/v1/accounts/:id` has `source/pleroma/actor_type` field.
|
- Mastodon API: `/api/v1/accounts/:id` has `source/pleroma/actor_type` field.
|
||||||
|
@ -122,6 +127,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Pleroma API: Add reactions for a single emoji.
|
- Pleroma API: Add reactions for a single emoji.
|
||||||
- ActivityPub: `[:activitypub, :note_replies_output_limit]` setting sets the number of note self-replies to output on outgoing federation.
|
- ActivityPub: `[:activitypub, :note_replies_output_limit]` setting sets the number of note self-replies to output on outgoing federation.
|
||||||
- Admin API: `GET /api/pleroma/admin/stats` to get status count by visibility scope
|
- Admin API: `GET /api/pleroma/admin/stats` to get status count by visibility scope
|
||||||
|
- Admin API: `GET /api/pleroma/admin/statuses` - list all statuses (accepts `godmode` and `local_only`)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -402,6 +402,8 @@
|
||||||
|
|
||||||
config :phoenix, :json_library, Jason
|
config :phoenix, :json_library, Jason
|
||||||
|
|
||||||
|
config :phoenix, :filter_parameters, ["password", "confirm"]
|
||||||
|
|
||||||
config :pleroma, :gopher,
|
config :pleroma, :gopher,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
ip: {0, 0, 0, 0},
|
ip: {0, 0, 0, 0},
|
||||||
|
@ -597,6 +599,7 @@
|
||||||
|
|
||||||
config :pleroma, :rate_limit,
|
config :pleroma, :rate_limit,
|
||||||
authentication: {60_000, 15},
|
authentication: {60_000, 15},
|
||||||
|
timeline: {500, 3},
|
||||||
search: [{1000, 10}, {1000, 30}],
|
search: [{1000, 10}, {1000, 30}],
|
||||||
app_account_creation: {1_800_000, 25},
|
app_account_creation: {1_800_000, 25},
|
||||||
relations_actions: {10_000, 10},
|
relations_actions: {10_000, 10},
|
||||||
|
|
|
@ -1615,160 +1615,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: Pleroma.Web.Endpoint,
|
|
||||||
type: :group,
|
|
||||||
description: "Phoenix endpoint configuration",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :http,
|
|
||||||
label: "HTTP",
|
|
||||||
type: {:keyword, :integer, :tuple},
|
|
||||||
description: "http protocol configuration",
|
|
||||||
suggestions: [
|
|
||||||
port: 8080,
|
|
||||||
ip: {127, 0, 0, 1}
|
|
||||||
],
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :dispatch,
|
|
||||||
type: {:list, :tuple},
|
|
||||||
description: "dispatch settings",
|
|
||||||
suggestions: [
|
|
||||||
{:_,
|
|
||||||
[
|
|
||||||
{"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
|
|
||||||
{"/websocket", Phoenix.Endpoint.CowboyWebSocket,
|
|
||||||
{Phoenix.Transports.WebSocket,
|
|
||||||
{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}},
|
|
||||||
{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
|
|
||||||
]}
|
|
||||||
# end copied from config.exs
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :ip,
|
|
||||||
label: "IP",
|
|
||||||
type: :tuple,
|
|
||||||
description: "ip",
|
|
||||||
suggestions: [
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :port,
|
|
||||||
type: :integer,
|
|
||||||
description: "port",
|
|
||||||
suggestions: [
|
|
||||||
2020
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :url,
|
|
||||||
label: "URL",
|
|
||||||
type: {:keyword, :string, :integer},
|
|
||||||
description: "configuration for generating urls",
|
|
||||||
suggestions: [
|
|
||||||
host: "example.com",
|
|
||||||
port: 2020,
|
|
||||||
scheme: "https"
|
|
||||||
],
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :host,
|
|
||||||
type: :string,
|
|
||||||
description: "Host",
|
|
||||||
suggestions: [
|
|
||||||
"example.com"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :port,
|
|
||||||
type: :integer,
|
|
||||||
description: "port",
|
|
||||||
suggestions: [
|
|
||||||
2020
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :scheme,
|
|
||||||
type: :string,
|
|
||||||
description: "Scheme",
|
|
||||||
suggestions: [
|
|
||||||
"https",
|
|
||||||
"https"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :instrumenters,
|
|
||||||
type: {:list, :module},
|
|
||||||
suggestions: [Pleroma.Web.Endpoint.Instrumenter]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :protocol,
|
|
||||||
type: :string,
|
|
||||||
suggestions: ["https"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :secret_key_base,
|
|
||||||
type: :string,
|
|
||||||
suggestions: ["aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :signing_salt,
|
|
||||||
type: :string,
|
|
||||||
suggestions: ["CqaoopA2"]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :render_errors,
|
|
||||||
type: :keyword,
|
|
||||||
suggestions: [view: Pleroma.Web.ErrorView, accepts: ~w(json)],
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :view,
|
|
||||||
type: :module,
|
|
||||||
suggestions: [Pleroma.Web.ErrorView]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :accepts,
|
|
||||||
type: {:list, :string},
|
|
||||||
suggestions: ["json"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :pubsub,
|
|
||||||
type: :keyword,
|
|
||||||
suggestions: [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2],
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :name,
|
|
||||||
type: :module,
|
|
||||||
suggestions: [Pleroma.PubSub]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :adapter,
|
|
||||||
type: :module,
|
|
||||||
suggestions: [Phoenix.PubSub.PG2]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :secure_cookie_flag,
|
|
||||||
type: :boolean
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
key: :extra_cookie_attrs,
|
|
||||||
type: {:list, :string},
|
|
||||||
suggestions: ["SameSite=Lax"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :activitypub,
|
key: :activitypub,
|
||||||
|
@ -2057,6 +1903,18 @@
|
||||||
suggestions: [50]
|
suggestions: [50]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :crontab,
|
||||||
|
type: {:list, :tuple},
|
||||||
|
description: "Settings for cron background jobs",
|
||||||
|
suggestions: [
|
||||||
|
{"0 0 * * *", Pleroma.Workers.Cron.ClearOauthTokenWorker},
|
||||||
|
{"0 * * * *", Pleroma.Workers.Cron.StatsWorker},
|
||||||
|
{"* * * * *", Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker},
|
||||||
|
{"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker},
|
||||||
|
{"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -2594,19 +2452,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :pleroma,
|
|
||||||
key: :database,
|
|
||||||
type: :group,
|
|
||||||
description: "Database related settings",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :rum_enabled,
|
|
||||||
type: :boolean,
|
|
||||||
description: "If RUM indexes should be used. Default: disabled"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :rate_limit,
|
key: :rate_limit,
|
||||||
|
@ -2620,6 +2465,12 @@
|
||||||
description: "For the search requests (account & status search etc.)",
|
description: "For the search requests (account & status search etc.)",
|
||||||
suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
|
suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
|
||||||
},
|
},
|
||||||
|
%{
|
||||||
|
key: :timeline,
|
||||||
|
type: [:tuple, {:list, :tuple}],
|
||||||
|
description: "For requests to timelines (each timeline has it's own limiter)",
|
||||||
|
suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
|
||||||
|
},
|
||||||
%{
|
%{
|
||||||
key: :app_account_creation,
|
key: :app_account_creation,
|
||||||
type: [:tuple, {:list, :tuple}],
|
type: [:tuple, {:list, :tuple}],
|
||||||
|
@ -2770,20 +2621,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
%{
|
|
||||||
group: :prometheus,
|
|
||||||
key: Pleroma.Web.Endpoint.MetricsExporter,
|
|
||||||
type: :group,
|
|
||||||
description: "Prometheus settings",
|
|
||||||
children: [
|
|
||||||
%{
|
|
||||||
key: :path,
|
|
||||||
type: :string,
|
|
||||||
description: "API endpoint with metrics",
|
|
||||||
suggestions: ["/api/pleroma/app_metrics"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
group: :http_signatures,
|
group: :http_signatures,
|
||||||
type: :group,
|
type: :group,
|
||||||
|
@ -3051,7 +2888,7 @@
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :feed,
|
key: :feed,
|
||||||
type: :group,
|
type: :group,
|
||||||
description: "Configure feed rendering.",
|
description: "Configure feed rendering",
|
||||||
children: [
|
children: [
|
||||||
%{
|
%{
|
||||||
key: :post_title,
|
key: :post_title,
|
||||||
|
@ -3101,7 +2938,7 @@
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
key: :modules,
|
key: :modules,
|
||||||
type: :group,
|
type: :group,
|
||||||
description: "Custom Runtime Modules.",
|
description: "Custom Runtime Modules",
|
||||||
children: [
|
children: [
|
||||||
%{
|
%{
|
||||||
key: :runtime_dir,
|
key: :runtime_dir,
|
||||||
|
@ -3112,14 +2949,21 @@
|
||||||
},
|
},
|
||||||
%{
|
%{
|
||||||
group: :pleroma,
|
group: :pleroma,
|
||||||
|
key: :streamer,
|
||||||
type: :group,
|
type: :group,
|
||||||
description: "Allow instance configuration from database.",
|
description: "Settings for notifications streamer",
|
||||||
children: [
|
children: [
|
||||||
%{
|
%{
|
||||||
key: :configurable_from_database,
|
key: :workers,
|
||||||
type: :boolean,
|
type: :integer,
|
||||||
description:
|
description: "Number of workers to send notifications.",
|
||||||
"Allow transferring configuration to DB with the subsequent customization from Admin api. Default: disabled"
|
suggestions: [3]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :overflow_workers,
|
||||||
|
type: :integer,
|
||||||
|
description: "Maximum number of workers created if pool is empty.",
|
||||||
|
suggestions: [2]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,11 +74,7 @@
|
||||||
total_user_limit: 3,
|
total_user_limit: 3,
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
config :pleroma, :rate_limit,
|
config :pleroma, :rate_limit, %{}
|
||||||
search: [{1000, 30}, {1000, 30}],
|
|
||||||
app_account_creation: {10_000, 5},
|
|
||||||
password_reset: {1000, 30},
|
|
||||||
ap_routes: nil
|
|
||||||
|
|
||||||
config :pleroma, :http_security, report_uri: "https://endpoint.com"
|
config :pleroma, :http_security, report_uri: "https://endpoint.com"
|
||||||
|
|
||||||
|
|
|
@ -260,10 +260,24 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
||||||
- `nickname` or `id`
|
- `nickname` or `id`
|
||||||
- *optional* `page_size`: number of statuses to return (default is `20`)
|
- *optional* `page_size`: number of statuses to return (default is `20`)
|
||||||
- *optional* `godmode`: `true`/`false` – allows to see private statuses
|
- *optional* `godmode`: `true`/`false` – allows to see private statuses
|
||||||
|
- *optional* `with_reblogs`: `true`/`false` – allows to see reblogs (default is false)
|
||||||
- Response:
|
- Response:
|
||||||
- On failure: `Not found`
|
- On failure: `Not found`
|
||||||
- On success: JSON array of user's latest statuses
|
- On success: JSON array of user's latest statuses
|
||||||
|
|
||||||
|
## `GET /api/pleroma/admin/instances/:instance/statuses`
|
||||||
|
|
||||||
|
### Retrive instance's latest statuses
|
||||||
|
|
||||||
|
- Params:
|
||||||
|
- `instance`: instance name
|
||||||
|
- *optional* `page_size`: number of statuses to return (default is `20`)
|
||||||
|
- *optional* `godmode`: `true`/`false` – allows to see private statuses
|
||||||
|
- *optional* `with_reblogs`: `true`/`false` – allows to see reblogs (default is false)
|
||||||
|
- Response:
|
||||||
|
- On failure: `Not found`
|
||||||
|
- On success: JSON array of instance's latest statuses
|
||||||
|
|
||||||
## `POST /api/pleroma/admin/relay`
|
## `POST /api/pleroma/admin/relay`
|
||||||
|
|
||||||
### Follow a Relay
|
### Follow a Relay
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
This is a cheat sheet for Pleroma configuration file, any setting possible to configure should be listed here.
|
This is a cheat sheet for Pleroma configuration file, any setting possible to configure should be listed here.
|
||||||
|
|
||||||
Pleroma configuration works by first importing the base config (`config/config.exs` on source installs, compiled-in on OTP releases), then overriding it by the environment config (`config/$MIX_ENV.exs` on source installs, N/A to OTP releases) and then overriding it by user config (`config/$MIX_ENV.secret.exs` on source installs, typically `/etc/pleroma/config.exs` on OTP releases).
|
For OTP installations the configuration is typically stored in `/etc/pleroma/config.exs`.
|
||||||
|
|
||||||
You shouldn't edit the base config directly to avoid breakages and merge conflicts, but it can be used as a reference if you don't understand how an option is supposed to be formatted, the latest version of it can be viewed [here](https://git.pleroma.social/pleroma/pleroma/blob/develop/config/config.exs).
|
For from source installations Pleroma configuration works by first importing the base config `config/config.exs`, then overriding it by the environment config `config/$MIX_ENV.exs` and then overriding it by user config `config/$MIX_ENV.secret.exs`. In from source installations you should always make the changes to the user config and NEVER to the base config to avoid breakages and merge conflicts. So for production you change/add configuration to `config/prod.secret.exs`.
|
||||||
|
|
||||||
|
To add configuration to your config file, you can copy it from the base config. The latest version of it can be viewed [here](https://git.pleroma.social/pleroma/pleroma/blob/develop/config/config.exs). You can also use this file if you don't know how an option is supposed to be formatted.
|
||||||
|
|
||||||
## :instance
|
## :instance
|
||||||
* `name`: The instance’s name.
|
* `name`: The instance’s name.
|
||||||
|
@ -150,8 +152,12 @@ config :pleroma, :mrf_user_allowlist,
|
||||||
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
|
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
|
||||||
|
|
||||||
### :fetch_initial_posts
|
### :fetch_initial_posts
|
||||||
* `enabled`: if enabled, when a new user is federated with, fetch some of their latest posts
|
|
||||||
* `pages`: the amount of pages to fetch
|
!!! warning
|
||||||
|
Be careful with this setting, fetching posts may lead to new users being discovered whose posts will then also be fetched. This can lead to serious load on your instance and database.
|
||||||
|
|
||||||
|
* `enabled`: If enabled, when a new user is discovered by your instance, fetch some of their latest posts.
|
||||||
|
* `pages`: The amount of pages to fetch
|
||||||
|
|
||||||
## Pleroma.ScheduledActivity
|
## Pleroma.ScheduledActivity
|
||||||
|
|
||||||
|
@ -343,6 +349,7 @@ Means that:
|
||||||
Supported rate limiters:
|
Supported rate limiters:
|
||||||
|
|
||||||
* `:search` - Account/Status search.
|
* `:search` - Account/Status search.
|
||||||
|
* `:timeline` - Timeline requests (each timeline has it's own limiter).
|
||||||
* `:app_account_creation` - Account registration from the API.
|
* `:app_account_creation` - Account registration from the API.
|
||||||
* `:relations_actions` - Following/Unfollowing in general.
|
* `:relations_actions` - Following/Unfollowing in general.
|
||||||
* `:relation_id_action` - Following/Unfollowing for a specific user.
|
* `:relation_id_action` - Following/Unfollowing for a specific user.
|
||||||
|
|
|
@ -123,7 +123,7 @@ In addition to that, replace the existing nginx config's contents with the examp
|
||||||
|
|
||||||
If not an I2P-only instance, add the nginx config below to your existing config at `/etc/nginx/sites-enabled/pleroma.nginx`.
|
If not an I2P-only instance, add the nginx config below to your existing config at `/etc/nginx/sites-enabled/pleroma.nginx`.
|
||||||
|
|
||||||
And for both cases, disable CSP in Pleroma's config (STS is disabled by default) so you can define those yourself seperately from the clearnet (if your instance is also on the clearnet).
|
And for both cases, disable CSP in Pleroma's config (STS is disabled by default) so you can define those yourself separately from the clearnet (if your instance is also on the clearnet).
|
||||||
Copy the following into the `config/prod.secret.exs` in your Pleroma folder (/home/pleroma/pleroma/):
|
Copy the following into the `config/prod.secret.exs` in your Pleroma folder (/home/pleroma/pleroma/):
|
||||||
```
|
```
|
||||||
config :pleroma, :http_security,
|
config :pleroma, :http_security,
|
||||||
|
|
|
@ -75,7 +75,7 @@ If not a Tor-only instance,
|
||||||
add the nginx config below to your existing config at `/etc/nginx/sites-enabled/pleroma.nginx`.
|
add the nginx config below to your existing config at `/etc/nginx/sites-enabled/pleroma.nginx`.
|
||||||
|
|
||||||
---
|
---
|
||||||
For both cases, disable CSP in Pleroma's config (STS is disabled by default) so you can define those yourself seperately from the clearnet (if your instance is also on the clearnet).
|
For both cases, disable CSP in Pleroma's config (STS is disabled by default) so you can define those yourself separately from the clearnet (if your instance is also on the clearnet).
|
||||||
Copy the following into the `config/prod.secret.exs` in your Pleroma folder (/home/pleroma/pleroma/):
|
Copy the following into the `config/prod.secret.exs` in your Pleroma folder (/home/pleroma/pleroma/):
|
||||||
```
|
```
|
||||||
config :pleroma, :http_security,
|
config :pleroma, :http_security,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.Config do
|
defmodule Mix.Tasks.Pleroma.Config do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.Emoji do
|
defmodule Mix.Tasks.Pleroma.Emoji do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.Instance do
|
defmodule Mix.Tasks.Pleroma.Instance do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
|
defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.RobotsTxt do
|
defmodule Mix.Tasks.Pleroma.RobotsTxt do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.User do
|
defmodule Mix.Tasks.Pleroma.User do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Activity do
|
defmodule Pleroma.Activity do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Activity.Queries do
|
defmodule Pleroma.Activity.Queries do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Activity.Search do
|
defmodule Pleroma.Activity.Search do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.ActivityExpiration do
|
defmodule Pleroma.ActivityExpiration do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Application do
|
defmodule Pleroma.Application do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Captcha.Native do
|
defmodule Pleroma.Captcha.Native do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.ConfigDB do
|
defmodule Pleroma.ConfigDB do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Config.Holder do
|
defmodule Pleroma.Config.Holder do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Config.Loader do
|
defmodule Pleroma.Config.Loader do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Config.TransferTask do
|
defmodule Pleroma.Config.TransferTask do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Conversation.Participation do
|
defmodule Pleroma.Conversation.Participation do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.CounterCache do
|
defmodule Pleroma.CounterCache do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Emails.AdminEmail do
|
defmodule Pleroma.Emails.AdminEmail do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.FollowingRelationship do
|
defmodule Pleroma.FollowingRelationship do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Formatter do
|
defmodule Pleroma.Formatter do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.HTML do
|
defmodule Pleroma.HTML do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.MIME do
|
defmodule Pleroma.MIME do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Notification do
|
defmodule Pleroma.Notification do
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Object do
|
defmodule Pleroma.Object do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
|
import Ecto.Query
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Object.Fetcher
|
alias Pleroma.Object.Fetcher
|
||||||
|
@ -12,9 +15,6 @@ defmodule Pleroma.Object do
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
import Ecto.Query
|
|
||||||
import Ecto.Changeset
|
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@type t() :: %__MODULE__{}
|
@type t() :: %__MODULE__{}
|
||||||
|
@ -145,18 +145,18 @@ def authorize_mutation(%Object{data: %{"actor" => actor}}, %User{ap_id: ap_id}),
|
||||||
# Legacy objects can be mutated by anybody
|
# Legacy objects can be mutated by anybody
|
||||||
def authorize_mutation(%Object{}, %User{}), do: true
|
def authorize_mutation(%Object{}, %User{}), do: true
|
||||||
|
|
||||||
|
@spec get_cached_by_ap_id(String.t()) :: Object.t() | nil
|
||||||
def get_cached_by_ap_id(ap_id) do
|
def get_cached_by_ap_id(ap_id) do
|
||||||
key = "object:#{ap_id}"
|
key = "object:#{ap_id}"
|
||||||
|
|
||||||
Cachex.fetch!(:object_cache, key, fn _ ->
|
with {:ok, nil} <- Cachex.get(:object_cache, key),
|
||||||
object = get_by_ap_id(ap_id)
|
object when not is_nil(object) <- get_by_ap_id(ap_id),
|
||||||
|
{:ok, true} <- Cachex.put(:object_cache, key, object) do
|
||||||
if object do
|
object
|
||||||
{:commit, object}
|
else
|
||||||
else
|
{:ok, object} -> object
|
||||||
{:ignore, object}
|
nil -> nil
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def context_mapping(context) do
|
def context_mapping(context) do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Object.Containment do
|
defmodule Pleroma.Object.Containment do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Object.Fetcher do
|
defmodule Pleroma.Object.Fetcher do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Pagination do
|
defmodule Pleroma.Pagination do
|
||||||
|
@ -12,11 +12,15 @@ defmodule Pleroma.Pagination do
|
||||||
|
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
|
|
||||||
|
@type type :: :keyset | :offset
|
||||||
|
|
||||||
@default_limit 20
|
@default_limit 20
|
||||||
|
@max_limit 40
|
||||||
@page_keys ["max_id", "min_id", "limit", "since_id", "order"]
|
@page_keys ["max_id", "min_id", "limit", "since_id", "order"]
|
||||||
|
|
||||||
def page_keys, do: @page_keys
|
def page_keys, do: @page_keys
|
||||||
|
|
||||||
|
@spec fetch_paginated(Ecto.Query.t(), map(), type(), atom() | nil) :: [Ecto.Schema.t()]
|
||||||
def fetch_paginated(query, params, type \\ :keyset, table_binding \\ nil)
|
def fetch_paginated(query, params, type \\ :keyset, table_binding \\ nil)
|
||||||
|
|
||||||
def fetch_paginated(query, %{"total" => true} = params, :keyset, table_binding) do
|
def fetch_paginated(query, %{"total" => true} = params, :keyset, table_binding) do
|
||||||
|
@ -57,6 +61,7 @@ def fetch_paginated(query, params, :offset, table_binding) do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec paginate(Ecto.Query.t(), map(), type(), atom() | nil) :: [Ecto.Schema.t()]
|
||||||
def paginate(query, options, method \\ :keyset, table_binding \\ nil)
|
def paginate(query, options, method \\ :keyset, table_binding \\ nil)
|
||||||
|
|
||||||
def paginate(query, options, :keyset, table_binding) do
|
def paginate(query, options, :keyset, table_binding) do
|
||||||
|
@ -130,7 +135,11 @@ defp restrict(query, :offset, %{offset: offset}, _table_binding) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, :limit, options, _table_binding) do
|
defp restrict(query, :limit, options, _table_binding) do
|
||||||
limit = Map.get(options, :limit, @default_limit)
|
limit =
|
||||||
|
case Map.get(options, :limit, @default_limit) do
|
||||||
|
limit when limit < @max_limit -> limit
|
||||||
|
_ -> @max_limit
|
||||||
|
end
|
||||||
|
|
||||||
query
|
query
|
||||||
|> limit(^limit)
|
|> limit(^limit)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.HTTPSecurityPlug do
|
defmodule Pleroma.Plugs.HTTPSecurityPlug do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# 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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.OAuthScopesPlug do
|
defmodule Pleroma.Plugs.OAuthScopesPlug do
|
||||||
|
|
|
@ -7,8 +7,8 @@ def start_link(init_arg) do
|
||||||
DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
|
DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_limiter(limiter_name, expiration) do
|
def add_or_return_limiter(limiter_name, expiration) do
|
||||||
{:ok, _pid} =
|
result =
|
||||||
DynamicSupervisor.start_child(
|
DynamicSupervisor.start_child(
|
||||||
__MODULE__,
|
__MODULE__,
|
||||||
%{
|
%{
|
||||||
|
@ -28,6 +28,12 @@ def add_limiter(limiter_name, expiration) do
|
||||||
]}
|
]}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
case result do
|
||||||
|
{:ok, _pid} = result -> result
|
||||||
|
{:error, {:already_started, pid}} -> {:ok, pid}
|
||||||
|
_ -> result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.RateLimiter do
|
defmodule Pleroma.Plugs.RateLimiter do
|
||||||
|
@ -7,12 +7,14 @@ defmodule Pleroma.Plugs.RateLimiter do
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
A keyword list of rate limiters where a key is a limiter name and value is the limiter configuration. The basic configuration is a tuple where:
|
A keyword list of rate limiters where a key is a limiter name and value is the limiter configuration.
|
||||||
|
The basic configuration is a tuple where:
|
||||||
|
|
||||||
* The first element: `scale` (Integer). The time scale in milliseconds.
|
* The first element: `scale` (Integer). The time scale in milliseconds.
|
||||||
* The second element: `limit` (Integer). How many requests to limit in the time scale provided.
|
* The second element: `limit` (Integer). How many requests to limit in the time scale provided.
|
||||||
|
|
||||||
It is also possible to have different limits for unauthenticated and authenticated users: the keyword value must be a list of two tuples where the first one is a config for unauthenticated users and the second one is for authenticated.
|
It is also possible to have different limits for unauthenticated and authenticated users: the keyword value must be a
|
||||||
|
list of two tuples where the first one is a config for unauthenticated users and the second one is for authenticated.
|
||||||
|
|
||||||
To disable a limiter set its value to `nil`.
|
To disable a limiter set its value to `nil`.
|
||||||
|
|
||||||
|
@ -64,91 +66,102 @@ defmodule Pleroma.Plugs.RateLimiter do
|
||||||
import Pleroma.Web.TranslationHelpers
|
import Pleroma.Web.TranslationHelpers
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
|
alias Pleroma.Config
|
||||||
alias Pleroma.Plugs.RateLimiter.LimiterSupervisor
|
alias Pleroma.Plugs.RateLimiter.LimiterSupervisor
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def init(opts) do
|
@doc false
|
||||||
limiter_name = Keyword.get(opts, :name)
|
def init(plug_opts) do
|
||||||
|
plug_opts
|
||||||
|
end
|
||||||
|
|
||||||
case Pleroma.Config.get([:rate_limit, limiter_name]) do
|
def call(conn, plug_opts) do
|
||||||
nil ->
|
if disabled?() do
|
||||||
nil
|
handle_disabled(conn)
|
||||||
|
else
|
||||||
config ->
|
action_settings = action_settings(plug_opts)
|
||||||
name_root = Keyword.get(opts, :bucket_name, limiter_name)
|
handle(conn, action_settings)
|
||||||
|
|
||||||
%{
|
|
||||||
name: name_root,
|
|
||||||
limits: config,
|
|
||||||
opts: opts
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Do not limit if there is no limiter configuration
|
defp handle_disabled(conn) do
|
||||||
def call(conn, nil), do: conn
|
if Config.get(:env) == :prod do
|
||||||
|
Logger.warn("Rate limiter is disabled for localhost/socket")
|
||||||
|
end
|
||||||
|
|
||||||
def call(conn, settings) do
|
conn
|
||||||
case disabled?() do
|
end
|
||||||
true ->
|
|
||||||
if Pleroma.Config.get(:env) == :prod,
|
|
||||||
do: Logger.warn("Rate limiter is disabled for localhost/socket")
|
|
||||||
|
|
||||||
|
defp handle(conn, nil), do: conn
|
||||||
|
|
||||||
|
defp handle(conn, action_settings) do
|
||||||
|
action_settings
|
||||||
|
|> incorporate_conn_info(conn)
|
||||||
|
|> check_rate()
|
||||||
|
|> case do
|
||||||
|
{:ok, _count} ->
|
||||||
conn
|
conn
|
||||||
|
|
||||||
false ->
|
{:error, _count} ->
|
||||||
settings
|
render_throttled_error(conn)
|
||||||
|> incorporate_conn_info(conn)
|
|
||||||
|> check_rate()
|
|
||||||
|> case do
|
|
||||||
{:ok, _count} ->
|
|
||||||
conn
|
|
||||||
|
|
||||||
{:error, _count} ->
|
|
||||||
render_throttled_error(conn)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def disabled? do
|
def disabled? do
|
||||||
localhost_or_socket =
|
localhost_or_socket =
|
||||||
Pleroma.Config.get([Pleroma.Web.Endpoint, :http, :ip])
|
Config.get([Pleroma.Web.Endpoint, :http, :ip])
|
||||||
|> Tuple.to_list()
|
|> Tuple.to_list()
|
||||||
|> Enum.join(".")
|
|> Enum.join(".")
|
||||||
|> String.match?(~r/^local|^127.0.0.1/)
|
|> String.match?(~r/^local|^127.0.0.1/)
|
||||||
|
|
||||||
remote_ip_disabled = not Pleroma.Config.get([Pleroma.Plugs.RemoteIp, :enabled])
|
remote_ip_disabled = not Config.get([Pleroma.Plugs.RemoteIp, :enabled])
|
||||||
|
|
||||||
localhost_or_socket and remote_ip_disabled
|
localhost_or_socket and remote_ip_disabled
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect_bucket(conn, name_root, settings) do
|
@inspect_bucket_not_found {:error, :not_found}
|
||||||
settings =
|
|
||||||
settings
|
|
||||||
|> incorporate_conn_info(conn)
|
|
||||||
|
|
||||||
bucket_name = make_bucket_name(%{settings | name: name_root})
|
def inspect_bucket(conn, bucket_name_root, plug_opts) do
|
||||||
key_name = make_key_name(settings)
|
with %{name: _} = action_settings <- action_settings(plug_opts) do
|
||||||
limit = get_limits(settings)
|
action_settings = incorporate_conn_info(action_settings, conn)
|
||||||
|
bucket_name = make_bucket_name(%{action_settings | name: bucket_name_root})
|
||||||
|
key_name = make_key_name(action_settings)
|
||||||
|
limit = get_limits(action_settings)
|
||||||
|
|
||||||
case Cachex.get(bucket_name, key_name) do
|
case Cachex.get(bucket_name, key_name) do
|
||||||
{:error, :no_cache} ->
|
{:error, :no_cache} ->
|
||||||
{:err, :not_found}
|
@inspect_bucket_not_found
|
||||||
|
|
||||||
{:ok, nil} ->
|
{:ok, nil} ->
|
||||||
{0, limit}
|
{0, limit}
|
||||||
|
|
||||||
{:ok, value} ->
|
{:ok, value} ->
|
||||||
{value, limit - value}
|
{value, limit - value}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
_ -> @inspect_bucket_not_found
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_rate(settings) do
|
def action_settings(plug_opts) do
|
||||||
bucket_name = make_bucket_name(settings)
|
with limiter_name when is_atom(limiter_name) <- plug_opts[:name],
|
||||||
key_name = make_key_name(settings)
|
limits when not is_nil(limits) <- Config.get([:rate_limit, limiter_name]) do
|
||||||
limit = get_limits(settings)
|
bucket_name_root = Keyword.get(plug_opts, :bucket_name, limiter_name)
|
||||||
|
|
||||||
|
%{
|
||||||
|
name: bucket_name_root,
|
||||||
|
limits: limits,
|
||||||
|
opts: plug_opts
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp check_rate(action_settings) do
|
||||||
|
bucket_name = make_bucket_name(action_settings)
|
||||||
|
key_name = make_key_name(action_settings)
|
||||||
|
limit = get_limits(action_settings)
|
||||||
|
|
||||||
case Cachex.get_and_update(bucket_name, key_name, &increment_value(&1, limit)) do
|
case Cachex.get_and_update(bucket_name, key_name, &increment_value(&1, limit)) do
|
||||||
{:commit, value} ->
|
{:commit, value} ->
|
||||||
|
@ -158,8 +171,8 @@ defp check_rate(settings) do
|
||||||
{:error, value}
|
{:error, value}
|
||||||
|
|
||||||
{:error, :no_cache} ->
|
{:error, :no_cache} ->
|
||||||
initialize_buckets(settings)
|
initialize_buckets!(action_settings)
|
||||||
check_rate(settings)
|
check_rate(action_settings)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,16 +182,19 @@ defp increment_value(val, limit) when val >= limit, do: {:ignore, val}
|
||||||
|
|
||||||
defp increment_value(val, _limit), do: {:commit, val + 1}
|
defp increment_value(val, _limit), do: {:commit, val + 1}
|
||||||
|
|
||||||
defp incorporate_conn_info(settings, %{assigns: %{user: %User{id: user_id}}, params: params}) do
|
defp incorporate_conn_info(action_settings, %{
|
||||||
Map.merge(settings, %{
|
assigns: %{user: %User{id: user_id}},
|
||||||
|
params: params
|
||||||
|
}) do
|
||||||
|
Map.merge(action_settings, %{
|
||||||
mode: :user,
|
mode: :user,
|
||||||
conn_params: params,
|
conn_params: params,
|
||||||
conn_info: "#{user_id}"
|
conn_info: "#{user_id}"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp incorporate_conn_info(settings, %{params: params} = conn) do
|
defp incorporate_conn_info(action_settings, %{params: params} = conn) do
|
||||||
Map.merge(settings, %{
|
Map.merge(action_settings, %{
|
||||||
mode: :anon,
|
mode: :anon,
|
||||||
conn_params: params,
|
conn_params: params,
|
||||||
conn_info: "#{ip(conn)}"
|
conn_info: "#{ip(conn)}"
|
||||||
|
@ -197,10 +213,10 @@ defp render_throttled_error(conn) do
|
||||||
|> halt()
|
|> halt()
|
||||||
end
|
end
|
||||||
|
|
||||||
defp make_key_name(settings) do
|
defp make_key_name(action_settings) do
|
||||||
""
|
""
|
||||||
|> attach_params(settings)
|
|> attach_selected_params(action_settings)
|
||||||
|> attach_identity(settings)
|
|> attach_identity(action_settings)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_scale(_, {scale, _}), do: scale
|
defp get_scale(_, {scale, _}), do: scale
|
||||||
|
@ -215,28 +231,35 @@ defp get_limits(%{mode: :user, limits: [_, {_, limit}]}), do: limit
|
||||||
|
|
||||||
defp get_limits(%{limits: [{_, limit}, _]}), do: limit
|
defp get_limits(%{limits: [{_, limit}, _]}), do: limit
|
||||||
|
|
||||||
defp make_bucket_name(%{mode: :user, name: name_root}),
|
defp make_bucket_name(%{mode: :user, name: bucket_name_root}),
|
||||||
do: user_bucket_name(name_root)
|
do: user_bucket_name(bucket_name_root)
|
||||||
|
|
||||||
defp make_bucket_name(%{mode: :anon, name: name_root}),
|
defp make_bucket_name(%{mode: :anon, name: bucket_name_root}),
|
||||||
do: anon_bucket_name(name_root)
|
do: anon_bucket_name(bucket_name_root)
|
||||||
|
|
||||||
defp attach_params(input, %{conn_params: conn_params, opts: opts}) do
|
defp attach_selected_params(input, %{conn_params: conn_params, opts: plug_opts}) do
|
||||||
param_string =
|
params_string =
|
||||||
opts
|
plug_opts
|
||||||
|> Keyword.get(:params, [])
|
|> Keyword.get(:params, [])
|
||||||
|> Enum.sort()
|
|> Enum.sort()
|
||||||
|> Enum.map(&Map.get(conn_params, &1, ""))
|
|> Enum.map(&Map.get(conn_params, &1, ""))
|
||||||
|> Enum.join(":")
|
|> Enum.join(":")
|
||||||
|
|
||||||
"#{input}#{param_string}"
|
[input, params_string]
|
||||||
|
|> Enum.join(":")
|
||||||
|
|> String.replace_leading(":", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
defp initialize_buckets(%{name: _name, limits: nil}), do: :ok
|
defp initialize_buckets!(%{name: _name, limits: nil}), do: :ok
|
||||||
|
|
||||||
defp initialize_buckets(%{name: name, limits: limits}) do
|
defp initialize_buckets!(%{name: name, limits: limits}) do
|
||||||
LimiterSupervisor.add_limiter(anon_bucket_name(name), get_scale(:anon, limits))
|
{:ok, _pid} =
|
||||||
LimiterSupervisor.add_limiter(user_bucket_name(name), get_scale(:user, limits))
|
LimiterSupervisor.add_or_return_limiter(anon_bucket_name(name), get_scale(:anon, limits))
|
||||||
|
|
||||||
|
{:ok, _pid} =
|
||||||
|
LimiterSupervisor.add_or_return_limiter(user_bucket_name(name), get_scale(:user, limits))
|
||||||
|
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
defp attach_identity(base, %{mode: :user, conn_info: conn_info}),
|
defp attach_identity(base, %{mode: :user, conn_info: conn_info}),
|
||||||
|
@ -245,6 +268,6 @@ defp attach_identity(base, %{mode: :user, conn_info: conn_info}),
|
||||||
defp attach_identity(base, %{mode: :anon, conn_info: conn_info}),
|
defp attach_identity(base, %{mode: :anon, conn_info: conn_info}),
|
||||||
do: "ip:#{base}:#{conn_info}"
|
do: "ip:#{base}:#{conn_info}"
|
||||||
|
|
||||||
defp user_bucket_name(name_root), do: "user:#{name_root}" |> String.to_atom()
|
defp user_bucket_name(bucket_name_root), do: "user:#{bucket_name_root}" |> String.to_atom()
|
||||||
defp anon_bucket_name(name_root), do: "anon:#{name_root}" |> String.to_atom()
|
defp anon_bucket_name(bucket_name_root), do: "anon:#{bucket_name_root}" |> String.to_atom()
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.RemoteIp do
|
defmodule Pleroma.Plugs.RemoteIp do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.UserEnabledPlug do
|
defmodule Pleroma.Plugs.UserEnabledPlug do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.UserIsAdminPlug do
|
defmodule Pleroma.Plugs.UserIsAdminPlug do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Repo do
|
defmodule Pleroma.Repo do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.ScheduledActivity do
|
defmodule Pleroma.ScheduledActivity do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Stats do
|
defmodule Pleroma.Stats do
|
||||||
|
|
|
@ -37,6 +37,7 @@ defmodule Pleroma.Upload do
|
||||||
Plug.Upload.t()
|
Plug.Upload.t()
|
||||||
| (data_uri_string :: String.t())
|
| (data_uri_string :: String.t())
|
||||||
| {:from_local, name :: String.t(), id :: String.t(), path :: String.t()}
|
| {:from_local, name :: String.t(), id :: String.t(), path :: String.t()}
|
||||||
|
| map()
|
||||||
|
|
||||||
@type option ::
|
@type option ::
|
||||||
{:type, :avatar | :banner | :background}
|
{:type, :avatar | :banner | :background}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Uploaders.Local do
|
defmodule Pleroma.Uploaders.Local do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Uploaders.S3 do
|
defmodule Pleroma.Uploaders.S3 do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Uploaders.Uploader do
|
defmodule Pleroma.Uploaders.Uploader do
|
||||||
|
|
|
@ -756,9 +756,18 @@ def invalidate_cache(user) do
|
||||||
Cachex.del(:user_cache, "nickname:#{user.nickname}")
|
Cachex.del(:user_cache, "nickname:#{user.nickname}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_cached_by_ap_id(String.t()) :: User.t() | nil
|
||||||
def get_cached_by_ap_id(ap_id) do
|
def get_cached_by_ap_id(ap_id) do
|
||||||
key = "ap_id:#{ap_id}"
|
key = "ap_id:#{ap_id}"
|
||||||
Cachex.fetch!(:user_cache, key, fn _ -> get_by_ap_id(ap_id) end)
|
|
||||||
|
with {:ok, nil} <- Cachex.get(:user_cache, key),
|
||||||
|
user when not is_nil(user) <- get_by_ap_id(ap_id),
|
||||||
|
{:ok, true} <- Cachex.put(:user_cache, key, user) do
|
||||||
|
user
|
||||||
|
else
|
||||||
|
{:ok, user} -> user
|
||||||
|
nil -> nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_cached_by_id(id) do
|
def get_cached_by_id(id) do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.User.Query do
|
defmodule Pleroma.User.Query do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.User.Search do
|
defmodule Pleroma.User.Search do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.UserRelationship do
|
defmodule Pleroma.UserRelationship do
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Activity.Ir.Topics
|
alias Pleroma.Activity.Ir.Topics
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Constants
|
||||||
alias Pleroma.Conversation
|
alias Pleroma.Conversation
|
||||||
alias Pleroma.Conversation.Participation
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
|
@ -124,6 +125,7 @@ def increase_poll_votes_if_vote(%{
|
||||||
|
|
||||||
def increase_poll_votes_if_vote(_create_data), do: :noop
|
def increase_poll_votes_if_vote(_create_data), do: :noop
|
||||||
|
|
||||||
|
@spec insert(map(), boolean(), boolean(), boolean()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def insert(map, local \\ true, fake \\ false, bypass_actor_check \\ false) when is_map(map) do
|
def insert(map, local \\ true, fake \\ false, bypass_actor_check \\ false) when is_map(map) do
|
||||||
with nil <- Activity.normalize(map),
|
with nil <- Activity.normalize(map),
|
||||||
map <- lazy_put_activity_defaults(map, fake),
|
map <- lazy_put_activity_defaults(map, fake),
|
||||||
|
@ -231,12 +233,19 @@ def stream_out(_activity) do
|
||||||
:noop
|
:noop
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do
|
@spec create(map(), boolean()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
|
def create(params, fake \\ false) do
|
||||||
|
with {:ok, result} <- Repo.transaction(fn -> do_create(params, fake) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_create(%{to: to, actor: actor, context: context, object: object} = params, fake) do
|
||||||
additional = params[:additional] || %{}
|
additional = params[:additional] || %{}
|
||||||
# only accept false as false value
|
# only accept false as false value
|
||||||
local = !(params[:local] == false)
|
local = !(params[:local] == false)
|
||||||
published = params[:published]
|
published = params[:published]
|
||||||
quick_insert? = Pleroma.Config.get([:env]) == :benchmark
|
quick_insert? = Config.get([:env]) == :benchmark
|
||||||
|
|
||||||
with create_data <-
|
with create_data <-
|
||||||
make_create_data(
|
make_create_data(
|
||||||
|
@ -259,10 +268,11 @@ def create(%{to: to, actor: actor, context: context, object: object} = params, f
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
|
||||||
{:error, message} ->
|
{:error, message} ->
|
||||||
{:error, message}
|
Repo.rollback(message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec listen(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
|
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
|
||||||
additional = params[:additional] || %{}
|
additional = params[:additional] || %{}
|
||||||
# only accept false as false value
|
# only accept false as false value
|
||||||
|
@ -277,20 +287,20 @@ def listen(%{to: to, actor: actor, context: context, object: object} = params) d
|
||||||
{:ok, activity} <- insert(listen_data, local),
|
{:ok, activity} <- insert(listen_data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
|
||||||
{:error, message} ->
|
|
||||||
{:error, message}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec accept(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def accept(params) do
|
def accept(params) do
|
||||||
accept_or_reject("Accept", params)
|
accept_or_reject("Accept", params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec reject(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def reject(params) do
|
def reject(params) do
|
||||||
accept_or_reject("Reject", params)
|
accept_or_reject("Reject", params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec accept_or_reject(String.t(), map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def accept_or_reject(type, %{to: to, actor: actor, object: object} = params) do
|
def accept_or_reject(type, %{to: to, actor: actor, object: object} = params) do
|
||||||
local = Map.get(params, :local, true)
|
local = Map.get(params, :local, true)
|
||||||
activity_id = Map.get(params, :activity_id, nil)
|
activity_id = Map.get(params, :activity_id, nil)
|
||||||
|
@ -304,6 +314,7 @@ def accept_or_reject(type, %{to: to, actor: actor, object: object} = params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec update(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
|
def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
|
||||||
local = !(params[:local] == false)
|
local = !(params[:local] == false)
|
||||||
activity_id = params[:activity_id]
|
activity_id = params[:activity_id]
|
||||||
|
@ -322,7 +333,16 @@ def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec react_with_emoji(User.t(), Object.t(), String.t(), keyword()) ::
|
||||||
|
{:ok, Activity.t(), Object.t()} | {:error, any()}
|
||||||
def react_with_emoji(user, object, emoji, options \\ []) do
|
def react_with_emoji(user, object, emoji, options \\ []) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_react_with_emoji(user, object, emoji, options) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_react_with_emoji(user, object, emoji, options) do
|
||||||
with local <- Keyword.get(options, :local, true),
|
with local <- Keyword.get(options, :local, true),
|
||||||
activity_id <- Keyword.get(options, :activity_id, nil),
|
activity_id <- Keyword.get(options, :activity_id, nil),
|
||||||
true <- Pleroma.Emoji.is_unicode_emoji?(emoji),
|
true <- Pleroma.Emoji.is_unicode_emoji?(emoji),
|
||||||
|
@ -332,11 +352,21 @@ def react_with_emoji(user, object, emoji, options \\ []) do
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity, object}
|
{:ok, activity, object}
|
||||||
else
|
else
|
||||||
e -> {:error, e}
|
false -> {:error, false}
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unreact_with_emoji(User.t(), String.t(), keyword()) ::
|
||||||
|
{:ok, Activity.t(), Object.t()} | {:error, any()}
|
||||||
def unreact_with_emoji(user, reaction_id, options \\ []) do
|
def unreact_with_emoji(user, reaction_id, options \\ []) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_unreact_with_emoji(user, reaction_id, options) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_unreact_with_emoji(user, reaction_id, options) do
|
||||||
with local <- Keyword.get(options, :local, true),
|
with local <- Keyword.get(options, :local, true),
|
||||||
activity_id <- Keyword.get(options, :activity_id, nil),
|
activity_id <- Keyword.get(options, :activity_id, nil),
|
||||||
user_ap_id <- user.ap_id,
|
user_ap_id <- user.ap_id,
|
||||||
|
@ -348,17 +378,25 @@ def unreact_with_emoji(user, reaction_id, options \\ []) do
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity, object}
|
{:ok, activity, object}
|
||||||
else
|
else
|
||||||
e -> {:error, e}
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: This is weird, maybe we shouldn't check here if we can make the activity.
|
# TODO: This is weird, maybe we shouldn't check here if we can make the activity.
|
||||||
def like(
|
@spec like(User.t(), Object.t(), String.t() | nil, boolean()) ::
|
||||||
%User{ap_id: ap_id} = user,
|
{:ok, Activity.t(), Object.t()} | {:error, any()}
|
||||||
%Object{data: %{"id" => _}} = object,
|
def like(user, object, activity_id \\ nil, local \\ true) do
|
||||||
activity_id \\ nil,
|
with {:ok, result} <- Repo.transaction(fn -> do_like(user, object, activity_id, local) end) do
|
||||||
local \\ true
|
result
|
||||||
) do
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_like(
|
||||||
|
%User{ap_id: ap_id} = user,
|
||||||
|
%Object{data: %{"id" => _}} = object,
|
||||||
|
activity_id,
|
||||||
|
local
|
||||||
|
) do
|
||||||
with nil <- get_existing_like(ap_id, object),
|
with nil <- get_existing_like(ap_id, object),
|
||||||
like_data <- make_like_data(user, object, activity_id),
|
like_data <- make_like_data(user, object, activity_id),
|
||||||
{:ok, activity} <- insert(like_data, local),
|
{:ok, activity} <- insert(like_data, local),
|
||||||
|
@ -366,12 +404,24 @@ def like(
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity, object}
|
{:ok, activity, object}
|
||||||
else
|
else
|
||||||
%Activity{} = activity -> {:ok, activity, object}
|
%Activity{} = activity ->
|
||||||
error -> {:error, error}
|
{:ok, activity, object}
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unlike(User.t(), Object.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t(), Activity.t(), Object.t()} | {:ok, Object.t()} | {:error, any()}
|
||||||
def unlike(%User{} = actor, %Object{} = object, activity_id \\ nil, local \\ true) do
|
def unlike(%User{} = actor, %Object{} = object, activity_id \\ nil, local \\ true) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_unlike(actor, object, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_unlike(actor, object, activity_id, local) do
|
||||||
with %Activity{} = like_activity <- get_existing_like(actor.ap_id, object),
|
with %Activity{} = like_activity <- get_existing_like(actor.ap_id, object),
|
||||||
unlike_data <- make_unlike_data(actor, like_activity, activity_id),
|
unlike_data <- make_unlike_data(actor, like_activity, activity_id),
|
||||||
{:ok, unlike_activity} <- insert(unlike_data, local),
|
{:ok, unlike_activity} <- insert(unlike_data, local),
|
||||||
|
@ -380,10 +430,13 @@ def unlike(%User{} = actor, %Object{} = object, activity_id \\ nil, local \\ tru
|
||||||
:ok <- maybe_federate(unlike_activity) do
|
:ok <- maybe_federate(unlike_activity) do
|
||||||
{:ok, unlike_activity, like_activity, object}
|
{:ok, unlike_activity, like_activity, object}
|
||||||
else
|
else
|
||||||
_e -> {:ok, object}
|
nil -> {:ok, object}
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec announce(User.t(), Object.t(), String.t() | nil, boolean(), boolean()) ::
|
||||||
|
{:ok, Activity.t(), Object.t()} | {:error, any()}
|
||||||
def announce(
|
def announce(
|
||||||
%User{ap_id: _} = user,
|
%User{ap_id: _} = user,
|
||||||
%Object{data: %{"id" => _}} = object,
|
%Object{data: %{"id" => _}} = object,
|
||||||
|
@ -391,6 +444,13 @@ def announce(
|
||||||
local \\ true,
|
local \\ true,
|
||||||
public \\ true
|
public \\ true
|
||||||
) do
|
) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_announce(user, object, activity_id, local, public) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_announce(user, object, activity_id, local, public) do
|
||||||
with true <- is_announceable?(object, user, public),
|
with true <- is_announceable?(object, user, public),
|
||||||
announce_data <- make_announce_data(user, object, activity_id, public),
|
announce_data <- make_announce_data(user, object, activity_id, public),
|
||||||
{:ok, activity} <- insert(announce_data, local),
|
{:ok, activity} <- insert(announce_data, local),
|
||||||
|
@ -398,16 +458,26 @@ def announce(
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity, object}
|
{:ok, activity, object}
|
||||||
else
|
else
|
||||||
error -> {:error, error}
|
false -> {:error, false}
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unannounce(User.t(), Object.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t(), Object.t()} | {:ok, Object.t()} | {:error, any()}
|
||||||
def unannounce(
|
def unannounce(
|
||||||
%User{} = actor,
|
%User{} = actor,
|
||||||
%Object{} = object,
|
%Object{} = object,
|
||||||
activity_id \\ nil,
|
activity_id \\ nil,
|
||||||
local \\ true
|
local \\ true
|
||||||
) do
|
) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_unannounce(actor, object, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_unannounce(actor, object, activity_id, local) do
|
||||||
with %Activity{} = announce_activity <- get_existing_announce(actor.ap_id, object),
|
with %Activity{} = announce_activity <- get_existing_announce(actor.ap_id, object),
|
||||||
unannounce_data <- make_unannounce_data(actor, announce_activity, activity_id),
|
unannounce_data <- make_unannounce_data(actor, announce_activity, activity_id),
|
||||||
{:ok, unannounce_activity} <- insert(unannounce_data, local),
|
{:ok, unannounce_activity} <- insert(unannounce_data, local),
|
||||||
|
@ -416,30 +486,61 @@ def unannounce(
|
||||||
{:ok, object} <- remove_announce_from_object(announce_activity, object) do
|
{:ok, object} <- remove_announce_from_object(announce_activity, object) do
|
||||||
{:ok, unannounce_activity, object}
|
{:ok, unannounce_activity, object}
|
||||||
else
|
else
|
||||||
_e -> {:ok, object}
|
nil -> {:ok, object}
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec follow(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t()} | {:error, any()}
|
||||||
def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_follow(follower, followed, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_follow(follower, followed, activity_id, local) do
|
||||||
with data <- make_follow_data(follower, followed, activity_id),
|
with data <- make_follow_data(follower, followed, activity_id),
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity),
|
:ok <- maybe_federate(activity),
|
||||||
_ <- User.set_follow_state_cache(follower.ap_id, followed.ap_id, activity.data["state"]) do
|
_ <- User.set_follow_state_cache(follower.ap_id, followed.ap_id, activity.data["state"]) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unfollow(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t()} | nil | {:error, any()}
|
||||||
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_unfollow(follower, followed, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_unfollow(follower, followed, activity_id, local) do
|
||||||
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
|
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
|
||||||
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
|
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
|
||||||
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
|
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
|
||||||
{:ok, activity} <- insert(unfollow_data, local),
|
{:ok, activity} <- insert(unfollow_data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
nil -> nil
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(%User{ap_id: ap_id, follower_address: follower_address} = user) do
|
@spec delete(User.t() | Object.t(), keyword()) :: {:ok, User.t() | Object.t()} | {:error, any()}
|
||||||
|
def delete(entity, options \\ []) do
|
||||||
|
with {:ok, result} <- Repo.transaction(fn -> do_delete(entity, options) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_delete(%User{ap_id: ap_id, follower_address: follower_address} = user, _) do
|
||||||
with data <- %{
|
with data <- %{
|
||||||
"to" => [follower_address],
|
"to" => [follower_address],
|
||||||
"type" => "Delete",
|
"type" => "Delete",
|
||||||
|
@ -452,7 +553,7 @@ def delete(%User{ap_id: ap_id, follower_address: follower_address} = user) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options \\ []) do
|
defp do_delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options) do
|
||||||
local = Keyword.get(options, :local, true)
|
local = Keyword.get(options, :local, true)
|
||||||
activity_id = Keyword.get(options, :activity_id, nil)
|
activity_id = Keyword.get(options, :activity_id, nil)
|
||||||
actor = Keyword.get(options, :actor, actor)
|
actor = Keyword.get(options, :actor, actor)
|
||||||
|
@ -477,11 +578,22 @@ def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options \\ [
|
||||||
{: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}
|
||||||
|
else
|
||||||
|
{:error, error} ->
|
||||||
|
Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec block(User.t(), User.t(), String.t() | nil, boolean) :: {:ok, Activity.t() | nil}
|
@spec block(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t()} | {:error, any()}
|
||||||
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_block(blocker, blocked, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_block(blocker, blocked, activity_id, local) do
|
||||||
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
||||||
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
||||||
|
|
||||||
|
@ -496,20 +608,32 @@ def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
_e -> {:ok, nil}
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unblock(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||||
|
{:ok, Activity.t()} | {:error, any()} | nil
|
||||||
def unblock(blocker, blocked, activity_id \\ nil, local \\ true) do
|
def unblock(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
|
with {:ok, result} <-
|
||||||
|
Repo.transaction(fn -> do_unblock(blocker, blocked, activity_id, local) end) do
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_unblock(blocker, blocked, activity_id, local) do
|
||||||
with %Activity{} = block_activity <- fetch_latest_block(blocker, blocked),
|
with %Activity{} = block_activity <- fetch_latest_block(blocker, blocked),
|
||||||
unblock_data <- make_unblock_data(blocker, blocked, block_activity, activity_id),
|
unblock_data <- make_unblock_data(blocker, blocked, block_activity, activity_id),
|
||||||
{:ok, activity} <- insert(unblock_data, local),
|
{:ok, activity} <- insert(unblock_data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
nil -> nil
|
||||||
|
{:error, error} -> Repo.rollback(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec flag(map()) :: {:ok, Activity.t()} | any
|
@spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def flag(
|
def flag(
|
||||||
%{
|
%{
|
||||||
actor: actor,
|
actor: actor,
|
||||||
|
@ -546,6 +670,7 @@ def flag(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec move(User.t(), User.t(), boolean()) :: {:ok, Activity.t()} | {:error, any()}
|
||||||
def move(%User{} = origin, %User{} = target, local \\ true) do
|
def move(%User{} = origin, %User{} = target, local \\ true) do
|
||||||
params = %{
|
params = %{
|
||||||
"type" => "Move",
|
"type" => "Move",
|
||||||
|
@ -571,7 +696,7 @@ def move(%User{} = origin, %User{} = target, local \\ true) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fetch_activities_for_context_query(context, opts) do
|
defp fetch_activities_for_context_query(context, opts) do
|
||||||
public = [Pleroma.Constants.as_public()]
|
public = [Constants.as_public()]
|
||||||
|
|
||||||
recipients =
|
recipients =
|
||||||
if opts["user"],
|
if opts["user"],
|
||||||
|
@ -616,10 +741,11 @@ def fetch_latest_activity_id_for_context(context, opts \\ %{}) do
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
|
||||||
def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
|
def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
|
||||||
opts = Map.drop(opts, ["user"])
|
opts = Map.drop(opts, ["user"])
|
||||||
|
|
||||||
[Pleroma.Constants.as_public()]
|
[Constants.as_public()]
|
||||||
|> fetch_activities_query(opts)
|
|> fetch_activities_query(opts)
|
||||||
|> restrict_unlisted()
|
|> restrict_unlisted()
|
||||||
|> Pagination.fetch_paginated(opts, pagination)
|
|> Pagination.fetch_paginated(opts, pagination)
|
||||||
|
@ -770,13 +896,18 @@ def fetch_user_activities(user, reading_user, params \\ %{}) do
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_instance_activities(params) do
|
def fetch_statuses(reading_user, params) do
|
||||||
params =
|
params =
|
||||||
params
|
params
|
||||||
|> Map.put("type", ["Create", "Announce"])
|
|> Map.put("type", ["Create", "Announce"])
|
||||||
|> Map.put("instance", params["instance"])
|
|
||||||
|
|
||||||
fetch_activities([Pleroma.Constants.as_public()], params, :offset)
|
recipients =
|
||||||
|
user_activities_recipients(%{
|
||||||
|
"godmode" => params["godmode"],
|
||||||
|
"reading_user" => reading_user
|
||||||
|
})
|
||||||
|
|
||||||
|
fetch_activities(recipients, params, :offset)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -786,9 +917,9 @@ defp user_activities_recipients(%{"godmode" => true}) do
|
||||||
|
|
||||||
defp user_activities_recipients(%{"reading_user" => reading_user}) do
|
defp user_activities_recipients(%{"reading_user" => reading_user}) do
|
||||||
if reading_user do
|
if reading_user do
|
||||||
[Pleroma.Constants.as_public()] ++ [reading_user.ap_id | User.following(reading_user)]
|
[Constants.as_public()] ++ [reading_user.ap_id | User.following(reading_user)]
|
||||||
else
|
else
|
||||||
[Pleroma.Constants.as_public()]
|
[Constants.as_public()]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -995,7 +1126,7 @@ defp restrict_unlisted(query) do
|
||||||
fragment(
|
fragment(
|
||||||
"not (coalesce(?->'cc', '{}'::jsonb) \\?| ?)",
|
"not (coalesce(?->'cc', '{}'::jsonb) \\?| ?)",
|
||||||
activity.data,
|
activity.data,
|
||||||
^[Pleroma.Constants.as_public()]
|
^[Constants.as_public()]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -1169,7 +1300,7 @@ def fetch_activities(recipients, opts \\ %{}, pagination \\ :keyset) do
|
||||||
@doc """
|
@doc """
|
||||||
Fetch favorites activities of user with order by sort adds to favorites
|
Fetch favorites activities of user with order by sort adds to favorites
|
||||||
"""
|
"""
|
||||||
@spec fetch_favourites(User.t(), map(), atom()) :: list(Activity.t())
|
@spec fetch_favourites(User.t(), map(), Pagination.type()) :: list(Activity.t())
|
||||||
def fetch_favourites(user, params \\ %{}, pagination \\ :keyset) do
|
def fetch_favourites(user, params \\ %{}, pagination \\ :keyset) do
|
||||||
user.ap_id
|
user.ap_id
|
||||||
|> Activity.Queries.by_actor()
|
|> Activity.Queries.by_actor()
|
||||||
|
@ -1207,7 +1338,7 @@ def fetch_activities_bounded_query(query, recipients, recipients_with_public) do
|
||||||
where:
|
where:
|
||||||
fragment("? && ?", activity.recipients, ^recipients) or
|
fragment("? && ?", activity.recipients, ^recipients) or
|
||||||
(fragment("? && ?", activity.recipients, ^recipients_with_public) and
|
(fragment("? && ?", activity.recipients, ^recipients_with_public) and
|
||||||
^Pleroma.Constants.as_public() in activity.recipients)
|
^Constants.as_public() in activity.recipients)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1223,6 +1354,7 @@ def fetch_activities_bounded(
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec upload(Upload.source(), keyword()) :: {:ok, Object.t()} | {:error, any()}
|
||||||
def upload(file, opts \\ []) do
|
def upload(file, opts \\ []) do
|
||||||
with {:ok, data} <- Upload.store(file, opts) do
|
with {:ok, data} <- Upload.store(file, opts) do
|
||||||
obj_data =
|
obj_data =
|
||||||
|
@ -1320,8 +1452,7 @@ defp normalize_counter(counter) when is_integer(counter), do: counter
|
||||||
defp normalize_counter(_), do: 0
|
defp normalize_counter(_), do: 0
|
||||||
|
|
||||||
defp maybe_update_follow_information(data) do
|
defp maybe_update_follow_information(data) do
|
||||||
with {:enabled, true} <-
|
with {:enabled, true} <- {:enabled, Config.get([:instance, :external_user_synchronization])},
|
||||||
{:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])},
|
|
||||||
{:ok, info} <- fetch_follow_information_for_user(data) do
|
{:ok, info} <- fetch_follow_information_for_user(data) do
|
||||||
info = Map.merge(data[:info] || %{}, info)
|
info = Map.merge(data[:info] || %{}, info)
|
||||||
Map.put(data, :info, info)
|
Map.put(data, :info, info)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.NoOpPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.NoOpPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
|
defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.Publisher do
|
defmodule Pleroma.Web.ActivityPub.Publisher do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# 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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# 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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
@ -244,13 +244,15 @@ def user_show(conn, %{"nickname" => nickname}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
||||||
|
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||||
{page, page_size} = page_params(params)
|
{page, page_size} = page_params(params)
|
||||||
|
|
||||||
activities =
|
activities =
|
||||||
ActivityPub.fetch_instance_activities(%{
|
ActivityPub.fetch_statuses(nil, %{
|
||||||
"instance" => instance,
|
"instance" => instance,
|
||||||
"limit" => page_size,
|
"limit" => page_size,
|
||||||
"offset" => (page - 1) * page_size
|
"offset" => (page - 1) * page_size,
|
||||||
|
"exclude_reblogs" => !with_reblogs && "true"
|
||||||
})
|
})
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -259,6 +261,7 @@ def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_user_statuses(conn, %{"nickname" => nickname} = params) do
|
def list_user_statuses(conn, %{"nickname" => nickname} = params) do
|
||||||
|
with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
|
||||||
godmode = params["godmode"] == "true" || params["godmode"] == true
|
godmode = params["godmode"] == "true" || params["godmode"] == true
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
|
||||||
|
@ -267,7 +270,8 @@ def list_user_statuses(conn, %{"nickname" => nickname} = params) do
|
||||||
activities =
|
activities =
|
||||||
ActivityPub.fetch_user_activities(user, nil, %{
|
ActivityPub.fetch_user_activities(user, nil, %{
|
||||||
"limit" => page_size,
|
"limit" => page_size,
|
||||||
"godmode" => godmode
|
"godmode" => godmode,
|
||||||
|
"exclude_reblogs" => !with_reblogs && "true"
|
||||||
})
|
})
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -741,6 +745,24 @@ def report_notes_delete(%{assigns: %{user: user}} = conn, %{
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def list_statuses(%{assigns: %{user: admin}} = conn, params) do
|
||||||
|
godmode = params["godmode"] == "true" || params["godmode"] == true
|
||||||
|
local_only = params["local_only"] == "true" || params["local_only"] == true
|
||||||
|
{page, page_size} = page_params(params)
|
||||||
|
|
||||||
|
activities =
|
||||||
|
ActivityPub.fetch_statuses(admin, %{
|
||||||
|
"godmode" => godmode,
|
||||||
|
"local_only" => local_only,
|
||||||
|
"limit" => page_size,
|
||||||
|
"offset" => (page - 1) * page_size
|
||||||
|
})
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_view(Pleroma.Web.AdminAPI.StatusView)
|
||||||
|
|> render("index.json", %{activities: activities, as: :activity})
|
||||||
|
end
|
||||||
|
|
||||||
def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
|
def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
|
||||||
with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
|
with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
|
||||||
{:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
|
{:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.AdminAPI.Search do
|
defmodule Pleroma.Web.AdminAPI.Search do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.AdminAPI.ConfigView do
|
defmodule Pleroma.Web.AdminAPI.ConfigView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.AdminAPI.StatusView do
|
defmodule Pleroma.Web.AdminAPI.StatusView do
|
||||||
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
def render("index.json", opts) do
|
def render("index.json", opts) do
|
||||||
render_many(opts.activities, __MODULE__, "show.json", opts)
|
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
|
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.CommonAPI do
|
defmodule Pleroma.Web.CommonAPI do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.CommonAPI.Utils do
|
defmodule Pleroma.Web.CommonAPI.Utils do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ControllerHelper do
|
defmodule Pleroma.Web.ControllerHelper do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Endpoint do
|
defmodule Pleroma.Web.Endpoint do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Federator do
|
defmodule Pleroma.Web.Federator do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Feed.FeedView do
|
defmodule Pleroma.Web.Feed.FeedView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Feed.TagController do
|
defmodule Pleroma.Web.Feed.TagController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Feed.UserController do
|
defmodule Pleroma.Web.Feed.UserController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastoFEController do
|
defmodule Pleroma.Web.MastoFEController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.NotificationController do
|
defmodule Pleroma.Web.MastodonAPI.NotificationController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.StatusController do
|
defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.SubscriptionController do
|
defmodule Pleroma.Web.MastodonAPI.SubscriptionController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.SuggestionController do
|
defmodule Pleroma.Web.MastodonAPI.SuggestionController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
|
@ -10,9 +10,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
|
|
||||||
alias Pleroma.Pagination
|
alias Pleroma.Pagination
|
||||||
alias Pleroma.Plugs.OAuthScopesPlug
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
|
alias Pleroma.Plugs.RateLimiter
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
|
||||||
|
# TODO: Replace with a macro when there is a Phoenix release with
|
||||||
|
# https://github.com/phoenixframework/phoenix/commit/2e8c63c01fec4dde5467dbbbf9705ff9e780735e
|
||||||
|
# in it
|
||||||
|
|
||||||
|
plug(RateLimiter, [name: :timeline, bucket_name: :direct_timeline] when action == :direct)
|
||||||
|
plug(RateLimiter, [name: :timeline, bucket_name: :public_timeline] when action == :public)
|
||||||
|
plug(RateLimiter, [name: :timeline, bucket_name: :home_timeline] when action == :home)
|
||||||
|
plug(RateLimiter, [name: :timeline, bucket_name: :hashtag_timeline] when action == :hashtag)
|
||||||
|
plug(RateLimiter, [name: :timeline, bucket_name: :list_timeline] when action == :list)
|
||||||
|
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|
defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.AccountView do
|
defmodule Pleroma.Web.MastodonAPI.AccountView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.AppView do
|
defmodule Pleroma.Web.MastodonAPI.AppView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.NotificationView do
|
defmodule Pleroma.Web.MastodonAPI.NotificationView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.PollView do
|
defmodule Pleroma.Web.MastodonAPI.PollView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.StatusView do
|
defmodule Pleroma.Web.MastodonAPI.StatusView do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Metadata.Providers.Feed do
|
defmodule Pleroma.Web.Metadata.Providers.Feed do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Metadata.Providers.RelMe do
|
defmodule Pleroma.Web.Metadata.Providers.RelMe do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OAuth.OAuthController do
|
defmodule Pleroma.Web.OAuth.OAuthController do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OAuth.Scopes do
|
defmodule Pleroma.Web.OAuth.Scopes do
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue