diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 675d0e067..29ee24a05 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -79,12 +79,12 @@ build-1.14.5-otp-25: script: - mix compile --force -build-1.17.1-otp-26: +build-1.18.3-otp-27: extends: - .build_changes_policy - .using-ci-base stage: build - image: git.pleroma.social:5050/pleroma/pleroma/ci-base:elixir-1.17.1-otp-26 + image: git.pleroma.social:5050/pleroma/pleroma/ci-base:elixir-1.18.3-otp-27 script: - mix compile --force @@ -142,12 +142,12 @@ unit-testing-1.14.5-otp-25: coverage_format: cobertura path: coverage.xml -unit-testing-1.17.1-otp-26: +unit-testing-1.18.3-otp-27: extends: - .build_changes_policy - .using-ci-base stage: test - image: git.pleroma.social:5050/pleroma/pleroma/ci-base:elixir-1.17.1-otp-26 + image: git.pleroma.social:5050/pleroma/pleroma/ci-base:elixir-1.18.3-otp-27 cache: *testing_cache_policy services: *testing_services script: *testing_script diff --git a/changelog.d/admin-api-docs-fix.skip b/changelog.d/admin-api-docs-fix.skip new file mode 100644 index 000000000..5c1c68ea0 --- /dev/null +++ b/changelog.d/admin-api-docs-fix.skip @@ -0,0 +1 @@ +Fix 'Create a user' description in admin api docs diff --git a/changelog.d/admin-api-log-fix.skip b/changelog.d/admin-api-log-fix.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/assign-app-user-oom.fix b/changelog.d/assign-app-user-oom.fix new file mode 100644 index 000000000..ac1de7159 --- /dev/null +++ b/changelog.d/assign-app-user-oom.fix @@ -0,0 +1 @@ +Fix AssignAppUser migration OOM diff --git a/changelog.d/doc-typo.skip b/changelog.d/doc-typo.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/elixir-1-18.fix b/changelog.d/elixir-1-18.fix new file mode 100644 index 000000000..d4d5a3493 --- /dev/null +++ b/changelog.d/elixir-1-18.fix @@ -0,0 +1 @@ +Elixir 1.18: Fixed warnings and new deprecations diff --git a/changelog.d/expiring-blocks.add b/changelog.d/expiring-blocks.add new file mode 100644 index 000000000..29989af15 --- /dev/null +++ b/changelog.d/expiring-blocks.add @@ -0,0 +1 @@ +Add `duration` to the block endpoint, which makes block expire \ No newline at end of file diff --git a/changelog.d/fixtests.skip b/changelog.d/fixtests.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/openbsd-docs-update.skip b/changelog.d/openbsd-docs-update.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/openbsd-update-httpd-relayd.change b/changelog.d/openbsd-update-httpd-relayd.change new file mode 100644 index 000000000..2ee85c2b0 --- /dev/null +++ b/changelog.d/openbsd-update-httpd-relayd.change @@ -0,0 +1 @@ +Updated relayd/httpd config files to be on par with nginx diff --git a/changelog.d/openbsd-update-rc.fix b/changelog.d/openbsd-update-rc.fix new file mode 100644 index 000000000..2d4263827 --- /dev/null +++ b/changelog.d/openbsd-update-rc.fix @@ -0,0 +1 @@ +replaced depracated flags and functions, renamed service to fit other service files diff --git a/changelog.d/private-functions.skip b/changelog.d/private-functions.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/remove-forgotten-OTPVersion-usage.skip b/changelog.d/remove-forgotten-OTPVersion-usage.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/webfinger.change b/changelog.d/webfinger.change new file mode 100644 index 000000000..353e65a89 --- /dev/null +++ b/changelog.d/webfinger.change @@ -0,0 +1 @@ +Don't require an Accept header for WebFinger queries and default to JSON. \ No newline at end of file diff --git a/ci/elixir-1.18.3-otp-27/Dockerfile b/ci/elixir-1.18.3-otp-27/Dockerfile new file mode 100644 index 000000000..2b42aa90d --- /dev/null +++ b/ci/elixir-1.18.3-otp-27/Dockerfile @@ -0,0 +1,8 @@ +FROM elixir:1.18.3-otp-27 + +# Single RUN statement, otherwise intermediate images are created +# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run +RUN apt-get update &&\ + apt-get install -y libmagic-dev cmake libimage-exiftool-perl ffmpeg &&\ + mix local.hex --force &&\ + mix local.rebar --force diff --git a/ci/elixir-1.18.3-otp-27/build_and_push.sh b/ci/elixir-1.18.3-otp-27/build_and_push.sh new file mode 100755 index 000000000..8a564fbf2 --- /dev/null +++ b/ci/elixir-1.18.3-otp-27/build_and_push.sh @@ -0,0 +1 @@ +docker buildx build --platform linux/amd64,linux/arm64 -t git.pleroma.social:5050/pleroma/pleroma/ci-base:elixir-1.18.3-otp-27 --push . diff --git a/docs/development/API/admin_api.md b/docs/development/API/admin_api.md index 409e78a1e..64c06ca2b 100644 --- a/docs/development/API/admin_api.md +++ b/docs/development/API/admin_api.md @@ -70,6 +70,8 @@ The `/api/v1/pleroma/admin/*` path is backwards compatible with `/api/pleroma/ad - `nicknames` - Response: Array of user nicknames +## `POST /api/v1/pleroma/admin/users` + ### Create a user - Method: `POST` @@ -81,7 +83,7 @@ The `/api/v1/pleroma/admin/*` path is backwards compatible with `/api/pleroma/ad `password` } ] -- Response: User’s nickname +- Response: Array of user objects ## `POST /api/v1/pleroma/admin/users/follow` diff --git a/docs/installation/generic_dependencies.include b/docs/installation/generic_dependencies.include index 9f07f62c6..769347a3c 100644 --- a/docs/installation/generic_dependencies.include +++ b/docs/installation/generic_dependencies.include @@ -1,8 +1,8 @@ ## Required dependencies * PostgreSQL >=11.0 -* Elixir >=1.14.0 <1.17 -* Erlang OTP >=23.0.0 (supported: <27) +* Elixir >=1.14.0 <1.19 +* Erlang OTP >=23.0.0 (supported: <28) * git * file / libmagic * gcc or clang diff --git a/docs/installation/openbsd_en.md b/docs/installation/openbsd_en.md index 78bbf399f..1de016cdd 100644 --- a/docs/installation/openbsd_en.md +++ b/docs/installation/openbsd_en.md @@ -1,25 +1,29 @@ # Installing on OpenBSD -This guide describes the installation and configuration of pleroma (and the required software to run it) on a single OpenBSD 6.6 server. +{! backend/installation/otp_vs_from_source_source.include !} + +This guide describes the installation and configuration of Pleroma (and the required software to run it) on a single OpenBSD 7.7 server. For any additional information regarding commands and configuration files mentioned here, check the man pages [online](https://man.openbsd.org/) or directly on your server with the man command. {! backend/installation/generic_dependencies.include !} +## Installation + ### Preparing the system #### Required software -To install them, run the following command (with doas or as root): +To install required packages, run the following command: ``` -pkg_add elixir gmake git postgresql-server postgresql-contrib cmake ffmpeg ImageMagick libvips +# pkg_add elixir gmake git postgresql-server postgresql-contrib cmake libmagic libvips ``` -Pleroma requires a reverse proxy, OpenBSD has relayd in base (and is used in this guide) and packages/ports are available for nginx (www/nginx) and apache (www/apache-httpd). Independently of the reverse proxy, [acme-client(1)](https://man.openbsd.org/acme-client) can be used to get a certificate from Let's Encrypt. +Pleroma requires a reverse proxy, OpenBSD has relayd in base (and is used in this guide) and packages/ports are available for nginx (www/nginx) and apache (www/apache-httpd). +Independently of the reverse proxy, [acme-client(1)](https://man.openbsd.org/acme-client) can be used to get a certificate from Let's Encrypt. #### Optional software -Per [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md): * ImageMagick * ffmpeg * exiftool @@ -27,234 +31,351 @@ Per [`docs/installation/optional/media_graphics_packages.md`](../installation/op To install the above: ``` -pkg_add ImageMagick ffmpeg p5-Image-ExifTool +# pkg_add ImageMagick ffmpeg p5-Image-ExifTool ``` -#### Creating the pleroma user -Pleroma will be run by a dedicated user, \_pleroma. Before creating it, insert the following lines in login.conf: +For more information read [`docs/installation/optional/media_graphics_packages.md`](../installation/optional/media_graphics_packages.md): + +### PostgreSQL + +Switch to the \_postgresql user and initialize PostgreSQL: + +``` +# su _postgresql +$ initdb -D /var/postgresql/data -U postgres --encoding=utf-8 --lc-collate=C +``` + +Running PostgreSQL in a different directory than `/var/postgresql/data` requires changing the `daemon_flags` variable in the `/etc/rc.d/postgresql` script. + +For security reasons it is recommended to change the authentication method for `local` and `host` connections with the localhost address to `scram-sha-256`.
+Do not forget to set a password for the `postgres` user before doing so, otherwise you won't be able to log back in unless you change the authentication method back to `trust`.
+Changing the password hashing algorithm is not needed.
+For more information [read](https://www.postgresql.org/docs/16/auth-pg-hba-conf.html) the PostgreSQL documentation. + +Enable and start the postgresql service: + +``` +# rcctl enable postgresql +# rcctl start postgresql +``` + +To check that PostgreSQL started properly and didn't fail right after starting, run `# rcctl check postgresql` which should return `postgresql(ok)`. + +### Configuring Pleroma + +Pleroma will be run by a dedicated \_pleroma user. Before creating it, insert the following lines in `/etc/login.conf`: + ``` pleroma:\ - :datasize-max=1536M:\ - :datasize-cur=1536M:\ - :openfiles-max=4096 + :datasize=1536M:\ + :openfiles-max=4096:\ + :openfiles-cur=1024:\ + :setenv=LC_ALL=en_US.UTF-8,VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS,MIX_ENV=prod:\ + :tc=daemon: ``` -This creates a "pleroma" login class and sets higher values than default for datasize and openfiles (see [login.conf(5)](https://man.openbsd.org/login.conf)), this is required to avoid having pleroma crash some time after starting. -Create the \_pleroma user, assign it the pleroma login class and create its home directory (/home/\_pleroma/): `useradd -m -L pleroma _pleroma` +This creates a "pleroma" login class and sets higher values than default for datasize and openfiles (see [login.conf(5)](https://man.openbsd.org/login.conf)), this is required to avoid having Pleroma crash some time after starting. -#### Clone pleroma's directory -Enter a shell as the \_pleroma user. As root, run `su _pleroma -;cd`. Then clone the repository with `git clone -b stable https://git.pleroma.social/pleroma/pleroma.git`. Pleroma is now installed in /home/\_pleroma/pleroma/, it will be configured and started at the end of this guide. - -#### PostgreSQL -Start a shell as the \_postgresql user (as root run `su _postgresql -` then run the `initdb` command to initialize postgresql: -You will need to specify pgdata directory to the default (/var/postgresql/data) with the `-D ` and set the user to postgres with the `-U ` flag. This can be done as follows: +Create the \_pleroma user, assign it the pleroma login class and create its home directory (/home/\_pleroma/): ``` -initdb -D /var/postgresql/data -U postgres +# useradd -m -L pleroma _pleroma ``` -If you are not using the default directory, you will have to update the `datadir` variable in the /etc/rc.d/postgresql script. -When this is done, enable postgresql so that it starts on boot and start it. As root, run: +Switch to the _pleroma user: + ``` -rcctl enable postgresql -rcctl start postgresql +# su -l _pleroma +``` + +Clone the Pleroma repository: + +``` +$ git clone -b stable https://git.pleroma.social/pleroma/pleroma.git +$ cd pleroma +``` + +Pleroma is now installed in /home/\_pleroma/pleroma/. To configure it run: + +``` +$ mix deps.get +$ MIX_ENV=prod mix pleroma.instance gen # You will be asked a few questions here. +$ cp config/generated_config.exs config/prod.secret.exs +``` + +Note: Answer yes when asked to install Hex and rebar3. This step might take some time as Pleroma gets compiled first. + +Create the Pleroma database: + +``` +$ psql -U postgres -f config/setup_db.psql +``` + +Apply database migrations: + +``` +$ MIX_ENV=prod mix ecto.migrate +``` + +Note: You will need to run this step again when updating your instance to a newer version with `git pull` or `git checkout tags/NEW_VERSION`. + +As \_pleroma in /home/\_pleroma/pleroma, you can now run `MIX_ENV=prod mix phx.server` to start your instance. +In another SSH session or a tmux window, check that it is working properly by running `ftp -MVo - http://127.0.0.1:4000/api/v1/instance`, you should get json output. +Double-check that the *uri* value near the bottom is your instance's domain name and the instance *title* are correct. + +### Configuring acme-client + +acme-client is used to get SSL/TLS certificates from Let's Encrypt. +Insert the following configuration in `/etc/acme-client.conf` and replace `example.tld` with your domain: + +``` +# +# $OpenBSD: acme-client.conf,v 1.5 2023/05/10 07:34:57 tb Exp $ +# + +authority letsencrypt { + api url "https://acme-v02.api.letsencrypt.org/directory" + account key "/etc/acme/letsencrypt-privkey.pem" +} + +domain example.tld { + # Adds alternative names to the certificate. Useful when serving media on another domain. Comma or space separated list. + # alternative names { } + + domain key "/etc/ssl/private/example.tld.key" + domain certificate "/etc/ssl/example.tld_cert-only.crt" + domain full chain certificate "/etc/ssl/example.tld.crt" + sign with letsencrypt +} +``` + +Check the configuration: + +``` +# acme-client -n +``` + +### Configuring the Web server + +Pleroma supports two Web servers: + + * nginx (recommended for most users) + * OpenBSD's httpd and relayd (ONLY for advanced users, media proxy cache is NOT supported and will NOT work properly) + +#### nginx + +Since nginx is not installed by default, install it by running: + +``` +# pkg_add nginx +``` + +Add the following to `/etc/nginx/nginx.conf`, within the `server {}` block listening on port 80 and change `server_name`, as follows: + +``` +http { + ... + + server { + ... + server_name localhost; # Replace with your domain + + location /.well-known/acme-challenge { + rewrite ^/\.well-known/acme-challenge/(.*) /$1 break; + root /var/www/acme; + } + } +} +``` + +Start the nginx service and acquire certificates: + +``` +# rcctl start nginx +# acme-client example.tld +``` + +Add certificate auto-renewal by adding acme-client to `/etc/weekly.local`, replace `example.tld` with your domain: + +``` +# echo "acme-client example.tld && rcctl reload nginx" >> /etc/weekly.local +``` + +OpenBSD's default nginx configuration does not contain an include directive, which is typically used for multiple sites. +Therefore, you will need to first create the required directory as follows: + +``` +# mkdir /etc/nginx/sites-available +# mkdir /etc/nginx/sites-enabled +``` + +Next add the `include` directive to `/etc/nginx/nginx.conf`, within the `http {}` block, as follows: + +``` +http { + ... + + server { + ... + } + + include /etc/nginx/sites-enabled/*; +} +``` + +As root, copy `/home/_pleroma/pleroma/installation/pleroma.nginx` to `/etc/nginx/sites-available/pleroma.nginx`. + +Edit default `/etc/nginx/sites-available/pleroma.nginx` settings and replace `example.tld` with your domain: + + * Uncomment the location block for `~ /\.well-known/acme-challenge` in the server block listening on port 80 + - add `rewrite ^/\.well-known/acme-challenge/(.*) /$1 break;` above the `root` location + - change the `root` location to `/var/www/acme;` + * Change `ssl_trusted_certificate` to `/etc/ssl/example.tld_cert-only.crt` + * Change `ssl_certificate` to `/etc/ssl/example.tld.crt` + * Change `ssl_certificate_key` to `/etc/ssl/private/example.tld.key` + +Remove the following `location {}` block from `/etc/nginx/nginx.conf`, that was previously added for acquiring certificates and change `server_name` back to `localhost`: + +``` +http { + ... + + server { + ... + server_name example.tld; # Change back to localhost + + # Delete this block + location /.well-known/acme-challenge { + rewrite ^/\.well-known/acme-challenge/(.*) /$1 break; + root /var/www/acme; + } + } +} +``` + +Symlink the Pleroma configuration to the enabled sites: + +``` +# ln -s /etc/nginx/sites-available/pleroma.nginx /etc/nginx/sites-enabled +``` + +Check nginx configuration syntax by running: + +``` +# nginx -t +``` + +Note: If the above command complains about a `conflicting server name`, check again that the `location {}` block for acquiring certificates has been removed from `/etc/nginx/nginx.conf` and that the `server_name` has been reverted back to `localhost`. +After doing so run `# nginx -t` again. + +If the configuration is correct, you can now enable and reload the nginx service: + +``` +# rcctl enable nginx +# rcctl reload nginx ``` -To check that it started properly and didn't fail right after starting, you can run `ps aux | grep postgres`, there should be multiple lines of output. #### httpd -httpd will have three functions: + +***Skip this section when using nginx*** + +httpd will have two functions: * redirect requests trying to reach the instance over http to the https URL - * serve a robots.txt file * get Let's Encrypt certificates, with acme-client -Insert the following config in httpd.conf: +As root, copy `/home/_pleroma/pleroma/installation/openbsd/httpd.conf` to `/etc/httpd.conf`, or modify the existing one. + +Edit `/etc/httpd.conf` settings and change: + + * `` with your instance's IPv4 address + * All occurrences of `example.tld` with your instance's domain name + * When using IPv6 also change: + - Uncomment the `ext_inet6=""` line near the beginning of the file and change `* to your server's address(es). If httpd should only listen on one protocol family, comment one of the two first *listen* options. - -Create the /var/www/htdocs/local/ folder and write the content of your robots.txt in /var/www/htdocs/local/robots.txt. -Check the configuration with `httpd -n`, if it is OK enable and start httpd (as root): -``` -rcctl enable httpd -rcctl start httpd +# httpd -n ``` -#### acme-client -acme-client is used to get SSL/TLS certificates from Let's Encrypt. -Insert the following configuration in /etc/acme-client.conf: -``` -# -# $OpenBSD: acme-client.conf,v 1.4 2017/03/22 11:14:14 benno Exp $ -# +If the configuration is correct, enable and start the `httpd` service: -authority letsencrypt- { - #agreement url "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf" - api url "https://acme-v02.api.letsencrypt.org/directory" - account key "/etc/acme/letsencrypt-privkey-.pem" -} +``` +# rcctl enable httpd +# rcctl start httpd +``` -domain { - domain key "/etc/ssl/private/.key" - domain certificate "/etc/ssl/.crt" - domain full chain certificate "/etc/ssl/.fullchain.pem" - sign with letsencrypt- - challengedir "/var/www/acme/" -} -``` -Replace ** by the domain name you'll use for your instance. As root, run `acme-client -n` to check the config, then `acme-client -ADv ` to create account and domain keys, and request a certificate for the first time. -Make acme-client run everyday by adding it in /etc/daily.local. As root, run the following command: `echo "acme-client " >> /etc/daily.local`. +Acquire certificate: -Relayd will look for certificates and keys based on the address it listens on (see next part), the easiest way to make them available to relayd is to create a link, as root run: ``` -ln -s /etc/ssl/.fullchain.pem /etc/ssl/.crt -ln -s /etc/ssl/private/.key /etc/ssl/private/.key +# acme-client example.tld ``` -This will have to be done for each IPv4 and IPv6 address relayd listens on. #### relayd + +***Skip this section when using nginx*** + relayd will be used as the reverse proxy sitting in front of pleroma. -Insert the following configuration in /etc/relayd.conf: + +As root, copy `/home/_pleroma/pleroma/installation/openbsd/relayd.conf` to `/etc/relayd.conf`, or modify the existing one. + +Edit `/etc/relayd.conf` settings and change: + + * `` with your instance's IPv4 address + * All occurrences of `example.tld` with your instance's domain name + * When using IPv6 also change: + - Uncomment the `ext_inet6=""` line near the beginning of the file and change `` to your instance's IPv6 address + - Uncomment the line starting with `listen on $ext_inet6` in the `relay wwwtls` block + +Check the configuration by running: ``` -# $OpenBSD: relayd.conf,v 1.4 2018/03/23 09:55:06 claudio Exp $ - -ext_inet="" -ext_inet6="" - -table { 127.0.0.1 } -table { 127.0.0.1 } - -http protocol plerup { # Protocol for upstream pleroma server - #tcp { nodelay, sack, socket buffer 65536, backlog 128 } # Uncomment and adjust as you see fit - tls ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305" - tls ecdhe secp384r1 - - # Forward some paths to the local server (as pleroma won't respond to them as you might want) - pass request quick path "/robots.txt" forward to - - # Append a bunch of headers - match request header append "X-Forwarded-For" value "$REMOTE_ADDR" # This two header and the next one are not strictly required by pleroma but adding them won't hurt - match request header append "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT" - - match response header append "X-XSS-Protection" value "1; mode=block" - match response header append "X-Permitted-Cross-Domain-Policies" value "none" - match response header append "X-Frame-Options" value "DENY" - match response header append "X-Content-Type-Options" value "nosniff" - match response header append "Referrer-Policy" value "same-origin" - match response header append "X-Download-Options" value "noopen" - match response header append "Content-Security-Policy" value "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://CHANGEME.tld; upgrade-insecure-requests;" # Modify "CHANGEME.tld" and set your instance's domain here - match request header append "Connection" value "upgrade" - #match response header append "Strict-Transport-Security" value "max-age=31536000; includeSubDomains" # Uncomment this only after you get HTTPS working. - - # If you do not want remote frontends to be able to access your Pleroma backend server, comment these lines - match response header append "Access-Control-Allow-Origin" value "*" - match response header append "Access-Control-Allow-Methods" value "POST, PUT, DELETE, GET, PATCH, OPTIONS" - match response header append "Access-Control-Allow-Headers" value "Authorization, Content-Type, Idempotency-Key" - match response header append "Access-Control-Expose-Headers" value "Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id" - # Stop commenting lines here -} - -relay wwwtls { - listen on $ext_inet port https tls # Comment to disable listening on IPv4 - listen on $ext_inet6 port https tls # Comment to disable listening on IPv6 - - protocol plerup - - forward to port 4000 check http "/" code 200 - forward to port 80 check http "/robots.txt" code 200 -} -``` -Again, change ** to your server's address(es) and comment one of the two *listen* options if needed. Also change *wss://CHANGEME.tld* to *wss://*. -Check the configuration with `relayd -n`, if it is OK enable and start relayd (as root): -``` -rcctl enable relayd -rcctl start relayd +# relayd -n ``` -##### (Strongly recommended) serve media on another domain +If the configuration is correct, enable and start the `relayd` service: + +``` +# rcctl enable relayd +# rcctl start relayd +``` + +Add certificate auto-renewal by adding acme-client to `/etc/weekly.local`, replace `example.tld` with your domain: + +``` +# echo "acme-client example.tld && rcctl reload relayd" >> /etc/weekly.local +``` + +#### (Strongly recommended) serve media on another domain Refer to the [Hardening your instance](../configuration/hardening.md) document on how to serve media on another domain. We STRONGLY RECOMMEND you to do this to minimize attack vectors. -#### pf -Enabling and configuring pf is highly recommended. -In /etc/pf.conf, insert the following configuration: +### Starting pleroma at boot + +Copy the startup script and make sure it's executable: + ``` -# Macros -if="" -authorized_ssh_clients="any" - -# Skip traffic on loopback interface -set skip on lo - -# Default behavior -set block-policy drop -block in log all -pass out quick - -# Security features -match in all scrub (no-df random-id) -block in log from urpf-failed - -# Rules -pass in quick on $if inet proto icmp to ($if) icmp-type { echoreq unreach paramprob trace } # ICMP -pass in quick on $if inet6 proto icmp6 to ($if) icmp6-type { echoreq unreach paramprob timex toobig } # ICMPv6 -pass in quick on $if proto tcp to ($if) port { http https } # relayd/httpd -pass in quick on $if proto tcp from $authorized_ssh_clients to ($if) port ssh -``` -Replace ** by your server's network interface name (which you can get with ifconfig). Consider replacing the content of the authorized\_ssh\_clients macro by, for example, your home IP address, to avoid SSH connection attempts from bots. - -Check pf's configuration by running `pfctl -nf /etc/pf.conf`, load it with `pfctl -f /etc/pf.conf` and enable pf at boot with `rcctl enable pf`. - -#### Configure and start pleroma -Enter a shell as \_pleroma (as root `su _pleroma -`) and enter pleroma's installation directory (`cd ~/pleroma/`). - -Then follow the main installation guide: - - * run `mix deps.get` - * run `MIX_ENV=prod mix pleroma.instance gen` and enter your instance's information when asked - * copy config/generated\_config.exs to config/prod.secret.exs. The default values should be sufficient but you should edit it and check that everything seems OK. - * exit your current shell back to a root one and run `psql -U postgres -f /home/_pleroma/pleroma/config/setup_db.psql` to setup the database. - * return to a \_pleroma shell into pleroma's installation directory (`su _pleroma -;cd ~/pleroma`) and run `MIX_ENV=prod mix ecto.migrate` - -As \_pleroma in /home/\_pleroma/pleroma, you can now run `LC_ALL=en_US.UTF-8 MIX_ENV=prod mix phx.server` to start your instance. -In another SSH session/tmux window, check that it is working properly by running `ftp -MVo - http://127.0.0.1:4000/api/v1/instance`, you should get json output. Double-check that *uri*'s value is your instance's domain name. - -##### Starting pleroma at boot -An rc script to automatically start pleroma at boot hasn't been written yet, it can be run in a tmux session (tmux is in base). - - -#### Create administrative user - -If your instance is up and running, you can create your first user with administrative rights with the following command as the \_pleroma user. -``` -LC_ALL=en_US.UTF-8 MIX_ENV=prod mix pleroma.user new --admin +# cp /home/_pleroma/pleroma/installation/openbsd/rc.d/pleroma /etc/rc.d/pleroma +# chmod 555 /etc/rc.d/pleroma ``` -#### Further reading +Enable and start the pleroma service: + +``` +# rcctl enable pleroma +# rcctl start pleroma +``` + +### Create administrative user + +If your instance is up and running, you can create your first user with administrative rights with the following commands as the \_pleroma user: + +``` +$ cd pleroma +$ MIX_ENV=prod mix pleroma.user new --admin +``` + +### Further reading {! backend/installation/further_reading.include !} diff --git a/docs/installation/openbsd_fi.md b/docs/installation/openbsd_fi.md index d7c94d8a0..858e64020 100644 --- a/docs/installation/openbsd_fi.md +++ b/docs/installation/openbsd_fi.md @@ -4,7 +4,7 @@ Note: This article is potentially outdated because at this time we may not have Tarvitset: * Oman domainin -* OpenBSD 6.3 -serverin +* OpenBSD 7.5 -serverin * Auttavan ymmärryksen unix-järjestelmistä Komennot, joiden edessä on '#', tulee ajaa käyttäjänä `root`. Tämä on @@ -18,7 +18,7 @@ Matrix-kanava #pleroma:libera.chat ovat hyviä paikkoja löytää apua Asenna tarvittava ohjelmisto: -`# pkg_add git elixir gmake postgresql-server-10.3 postgresql-contrib-10.3 cmake ffmpeg ImageMagick libvips` +`# pkg_add git elixir gmake postgresql-server postgresql-contrib cmake libmagic libvips` #### Optional software diff --git a/installation/openbsd/httpd.conf b/installation/openbsd/httpd.conf index 82f4803fd..f37325d91 100644 --- a/installation/openbsd/httpd.conf +++ b/installation/openbsd/httpd.conf @@ -2,20 +2,21 @@ # Default httpd.conf file for Pleroma on OpenBSD # Simple installation instructions # 1. Place file in /etc -# 2. Replace with your public IP address -# 3. If using IPv6, uncomment IPv6 lines and replace with your public IPv6 address -# 4. Check file using 'doas httpd -n' -# 5. Enable and start httpd: +# 2. Replace with your public IP address +# 3. If using IPv6, uncomment IPv6 lines and replace with your public IPv6 address +# 4. Replace all occurences of example.tld with your instance's domain name. +# 5. Check file using 'doas httpd -n' +# 6. Enable and start httpd: # # doas rcctl enable httpd # # doas rcctl start httpd # -ext_inet="" -#ext_inet6="" +ext_inet="" +#ext_inet6="" -server "default" { +server "example.tld" { listen on $ext_inet port 80 # Comment to disable listening on IPv4 -# listen on $ext_inet6 port 80 # Comment to disable listening on IPv6 + #listen on $ext_inet6 port 80 # Comment to disable listening on IPv6 listen on 127.0.0.1 port 80 # Do NOT comment this line log syslog @@ -26,10 +27,18 @@ server "default" { request strip 2 } - location "/robots.txt" { root "/htdocs/local/" } - location "/*" { block return 302 "https://$HTTP_HOST$REQUEST_URI" } + location "/*" { block return 301 "https://$HTTP_HOST$REQUEST_URI" } } +# Example of serving a basic static website besides Pleroma using the example configuration in relayd +#server "site.example.tld" { +# listen on 127.0.0.1 port 8080 +# +# location "/*" { +# root "/website" +# } +#} + types { include "/usr/share/misc/mime.types" } diff --git a/installation/openbsd/rc.d/pleromad b/installation/openbsd/rc.d/pleroma similarity index 63% rename from installation/openbsd/rc.d/pleromad rename to installation/openbsd/rc.d/pleroma index 19ac4bb51..6959c20b0 100755 --- a/installation/openbsd/rc.d/pleromad +++ b/installation/openbsd/rc.d/pleroma @@ -4,15 +4,16 @@ # # Simple installation instructions: # 1. Install Pleroma per wiki instructions -# 2. Place this pleromad file in /etc/rc.d +# 2. Place this pleroma file in /etc/rc.d # 3. Enable and start Pleroma -# # doas rcctl enable pleromad -# # doas rcctl start pleromad +# # doas rcctl enable pleroma +# # doas rcctl start pleroma # daemon="/usr/local/bin/elixir" -daemon_flags="--detached -S /usr/local/bin/mix phx.server" +daemon_flags="--erl \"-detached\" -S /usr/local/bin/mix phx.server" daemon_user="_pleroma" +daemon_execdir="/home/_pleroma/pleroma" . /etc/rc.d/rc.subr @@ -23,10 +24,6 @@ rc_check() { pgrep -q -U _pleroma -f "phx.server" } -rc_start() { - ${rcexec} "cd pleroma; ${daemon} ${daemon_flags}" -} - rc_stop() { pkill -q -U _pleroma -f "phx.server" } diff --git a/installation/openbsd/relayd.conf b/installation/openbsd/relayd.conf index 31c2c1129..8b7be4ca6 100644 --- a/installation/openbsd/relayd.conf +++ b/installation/openbsd/relayd.conf @@ -3,9 +3,10 @@ # Simple installation instructions: # 1. Place in /etc # 2. Replace with your public IPv4 address -# 3. If using IPv6i, uncomment IPv6 lines and replace with your public IPv6 address -# 4. Check file using 'doas relayd -n' -# 5. Reload/start relayd +# 3. If using IPv6, uncomment IPv6 lines and replace with your public IPv6 address +# 4. Replace all occurrences of example.tld with your instance's domain +# 5. Check file using 'doas relayd -n' +# 6. Reload/start relayd # # doas rcctl enable relayd # # doas rcctl start relayd # @@ -14,31 +15,54 @@ ext_inet="" #ext_inet6="" table { 127.0.0.1 } -table { 127.0.0.1 } -http protocol plerup { # Protocol for upstream pleroma server +# Uncomment when you want to serve other services than Pleroma. +# In this example tables are used only as way to differentiate between Pleroma and other services. +# Feel free to rename "httpd_server" everywhere to fit your setup. +#table { 127.0.0.1 } + +http protocol pleroma { # Protocol for upstream Pleroma server #tcp { nodelay, sack, socket buffer 65536, backlog 128 } # Uncomment and adjust as you see fit - tls ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA0-POLY1305" - tls ecdhe secp384r1 + tls ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4" + tls ecdhe "X25519,P-256,P-384,secp521r1" # relayd default+secp521r1 - # Forward some paths to the local server (as pleroma won't respond to them as you might want) - pass request quick path "/robots.txt" forward to + return error - # Append a bunch of headers - match request header append "X-Forwarded-For" value "$REMOTE_ADDR" # This two header and the next one are not strictl required by pleroma but adding them won't hurt - match request header append "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT" + # When serving multiple services with different certificates, specify multiple "tls keypair" keywords + # and add forwards to those services before the block keyword near the bottom of the protocol and relay configurations. + # The string in quotes must match the fullchain certificate file created by acme-client without the extension. + # For example: + # tls keypair "pleroma.example.tld" + # tls keypair "example.tld" + tls keypair "example.tld" + match request header append "X-Forwarded-For" value "$REMOTE_ADDR" match request header append "Connection" value "upgrade" + # When hosting Pleroma on a subdomain, replace example.tld accordingly (not the base domain). + # From the above example, "example.tld" should be replaced with "pleroma.example.tld" instead. + pass request quick header "Host" value "example.tld" forward to + + # Uncomment when serving media uploads on a different (sub)domain. + # Keep media proxy disabled, as it will NOT work under relayd/httpd. If you want to also setup media proxy, use nginx instead. + #pass request quick header "Host" value "media.example.tld" forward to + + # When serving multiple services, add the forwards here. + # Example: + #pass request quick header "Host" value "example.tld" forward to + + block } relay wwwtls { listen on $ext_inet port https tls # Comment to disable listening on IPv4 -# listen on $ext_inet6 port https tls # Comment to disable listening on IPv6 + #listen on $ext_inet6 port https tls # Comment to disable listening on IPv6 - protocol plerup + protocol pleroma - forward to port 4000 check http "/" code 200 - forward to port 80 check http "/robots.txt" code 200 + forward to port 4000 check tcp timeout 500 # Adjust timeout accordingly when relayd returns 502 while Pleroma is running without problems. + + # When serving multiple services, add the forwards here. + # Example: + #forward to port 8080 } - diff --git a/lib/mix/tasks/pleroma/test_runner.ex b/lib/mix/tasks/pleroma/test_runner.ex index 69fefb001..67820247e 100644 --- a/lib/mix/tasks/pleroma/test_runner.ex +++ b/lib/mix/tasks/pleroma/test_runner.ex @@ -4,7 +4,9 @@ defmodule Mix.Tasks.Pleroma.TestRunner do use Mix.Task def run(args \\ []) do - case System.cmd("mix", ["test"] ++ args, into: IO.stream(:stdio, :line)) do + case System.cmd("mix", ["test", "--warnings-as-errors"] ++ args, + into: IO.stream(:stdio, :line) + ) do {_, 0} -> :ok diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 497623ee1..8e1c5de0d 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -43,9 +43,6 @@ defmodule Pleroma.Application do # every time the application is restarted, so we disable module # conflicts at runtime Code.compiler_options(ignore_module_conflict: true) - # Disable warnings_as_errors at runtime, it breaks Phoenix live reload - # due to protocol consolidation warnings - Code.compiler_options(warnings_as_errors: false) Pleroma.Telemetry.Logger.attach() Config.Holder.save_default() Pleroma.HTML.compile_scrubbers() @@ -71,26 +68,11 @@ defmodule Pleroma.Application do Finch.start_link(name: MyFinch) end - if adapter == Tesla.Adapter.Gun do - if version = Pleroma.OTPVersion.version() do - [major, minor] = - version - |> String.split(".") - |> Enum.map(&String.to_integer/1) - |> Enum.take(2) - - if (major == 22 and minor < 2) or major < 22 do - raise " - !!!OTP VERSION WARNING!!! - You are using gun adapter with OTP version #{version}, which doesn't support correct handling of unordered certificates chains. Please update your Erlang/OTP to at least 22.2. - " - end - else - raise " - !!!OTP VERSION WARNING!!! - To support correct handling of unordered certificates chains - OTP version must be > 22.2. - " - end + # Disable warnings_as_errors at runtime, it breaks Phoenix live reload + # due to protocol consolidation warnings + # :warnings_as_errors is deprecated via Code.compiler_options/2 since 1.18 + if Version.compare(System.version(), "1.18.0") == :lt do + Code.compiler_options(warnings_as_errors: false) end # Define workers and child supervisors to be supervised diff --git a/lib/pleroma/config_db.ex b/lib/pleroma/config_db.ex index 89d3050d6..e9990fa35 100644 --- a/lib/pleroma/config_db.ex +++ b/lib/pleroma/config_db.ex @@ -302,7 +302,7 @@ defmodule Pleroma.ConfigDB do end def to_elixir_types(%{"tuple" => entity}) do - Enum.reduce(entity, {}, &Tuple.append(&2, to_elixir_types(&1))) + Enum.reduce(entity, {}, &Tuple.insert_at(&2, tuple_size(&2), to_elixir_types(&1))) end def to_elixir_types(entity) when is_map(entity) do diff --git a/lib/pleroma/language/language_detector.ex b/lib/pleroma/language/language_detector.ex index 16e2d4faa..68d243562 100644 --- a/lib/pleroma/language/language_detector.ex +++ b/lib/pleroma/language/language_detector.ex @@ -12,7 +12,7 @@ defmodule Pleroma.Language.LanguageDetector do def configured? do provider = get_provider() - !!provider and provider.configured? + !!provider and provider.configured?() end def missing_dependencies do @@ -41,7 +41,7 @@ defmodule Pleroma.Language.LanguageDetector do text = prepare_text(text) word_count = text |> String.split(~r/\s+/) |> Enum.count() - if word_count < @words_threshold or !provider or !provider.configured? do + if word_count < @words_threshold or !provider or !provider.configured?() do nil else with language <- provider.detect(text), diff --git a/lib/pleroma/language/translation.ex b/lib/pleroma/language/translation.ex index 3706e76eb..64f115ed8 100644 --- a/lib/pleroma/language/translation.ex +++ b/lib/pleroma/language/translation.ex @@ -8,7 +8,7 @@ defmodule Pleroma.Language.Translation do def configured? do provider = get_provider() - !!provider and provider.configured? + !!provider and provider.configured?() end def missing_dependencies do diff --git a/lib/pleroma/otp_version.ex b/lib/pleroma/otp_version.ex deleted file mode 100644 index 80b15275a..000000000 --- a/lib/pleroma/otp_version.ex +++ /dev/null @@ -1,28 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.OTPVersion do - @spec version() :: String.t() | nil - def version do - # OTP Version https://erlang.org/doc/system_principles/versions.html#otp-version - [ - Path.join(:code.root_dir(), "OTP_VERSION"), - Path.join([:code.root_dir(), "releases", :erlang.system_info(:otp_release), "OTP_VERSION"]) - ] - |> get_version_from_files() - end - - @spec get_version_from_files([Path.t()]) :: String.t() | nil - def get_version_from_files([]), do: nil - - def get_version_from_files([path | paths]) do - if File.exists?(path) do - path - |> File.read!() - |> String.replace(~r/\r|\n|\s/, "") - else - get_version_from_files(paths) - end - end -end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index d9da9ede1..427f7878d 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -308,7 +308,7 @@ defmodule Pleroma.User do def binary_id(%User{} = user), do: binary_id(user.id) - @doc "Returns status account" + @doc "Returns account status" @spec account_status(User.t()) :: account_status() def account_status(%User{is_active: false}), do: :deactivated def account_status(%User{password_reset_pending: true}), do: :password_reset_pending @@ -895,7 +895,7 @@ defmodule Pleroma.User do end) end - def validate_email_not_in_blacklisted_domain(changeset, field) do + defp validate_email_not_in_blacklisted_domain(changeset, field) do validate_change(changeset, field, fn _, value -> valid? = Config.get([User, :email_blacklist]) @@ -912,9 +912,9 @@ defmodule Pleroma.User do end) end - def maybe_validate_required_email(changeset, true), do: changeset + defp maybe_validate_required_email(changeset, true), do: changeset - def maybe_validate_required_email(changeset, _) do + defp maybe_validate_required_email(changeset, _) do if Config.get([:instance, :account_activation_required]) do validate_required(changeset, [:email]) else @@ -1109,15 +1109,15 @@ defmodule Pleroma.User do defp maybe_send_registration_email(_), do: {:ok, :noop} - def needs_update?(%User{local: true}), do: false + defp needs_update?(%User{local: true}), do: false - def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true + defp needs_update?(%User{local: false, last_refreshed_at: nil}), do: true - def needs_update?(%User{local: false} = user) do + defp needs_update?(%User{local: false} = user) do NaiveDateTime.diff(NaiveDateTime.utc_now(), user.last_refreshed_at) >= 86_400 end - def needs_update?(_), do: true + defp needs_update?(_), do: true @spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t(), User.t()} | {:error, String.t()} @@ -1708,7 +1708,9 @@ defmodule Pleroma.User do end end - def block(%User{} = blocker, %User{} = blocked) do + def block(blocker, blocked, params \\ %{}) + + def block(%User{} = blocker, %User{} = blocked, params) do # sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213) blocker = if following?(blocker, blocked) do @@ -1738,12 +1740,33 @@ defmodule Pleroma.User do {:ok, blocker} = update_follower_count(blocker) {:ok, blocker, _} = Participation.mark_all_as_read(blocker, blocked) - add_to_block(blocker, blocked) + + duration = Map.get(params, :duration, 0) + + expires_at = + if duration > 0 do + DateTime.utc_now() + |> DateTime.add(duration) + else + nil + end + + user_block = add_to_block(blocker, blocked, expires_at) + + if duration > 0 do + Pleroma.Workers.MuteExpireWorker.new( + %{"op" => "unblock_user", "blocker_id" => blocker.id, "blocked_id" => blocked.id}, + scheduled_at: expires_at + ) + |> Oban.insert() + end + + user_block end # helper to handle the block given only an actor's AP id - def block(%User{} = blocker, %{ap_id: ap_id}) do - block(blocker, get_cached_by_ap_id(ap_id)) + def block(%User{} = blocker, %{ap_id: ap_id}, params) do + block(blocker, get_cached_by_ap_id(ap_id), params) end def unblock(%User{} = blocker, %User{} = blocked) do @@ -1984,7 +2007,7 @@ defmodule Pleroma.User do end @spec purge_user_changeset(User.t()) :: Ecto.Changeset.t() - def purge_user_changeset(user) do + defp purge_user_changeset(user) do # "Right to be forgotten" # https://gdpr.eu/right-to-be-forgotten/ change(user, %{ @@ -2156,7 +2179,7 @@ defmodule Pleroma.User do Repo.all(query) end - def delete_notifications_from_user_activities(%User{ap_id: ap_id}) do + defp delete_notifications_from_user_activities(%User{ap_id: ap_id}) do Notification |> join(:inner, [n], activity in assoc(n, :activity)) |> where([n, a], fragment("? = ?", a.actor, ^ap_id)) @@ -2615,7 +2638,7 @@ defmodule Pleroma.User do end end - # Internal function; public one is `deactivate/2` + # Internal function; public one is `set_activation/2` defp set_activation_status(user, status) do user |> cast(%{is_active: status}, [:is_active]) @@ -2634,7 +2657,7 @@ defmodule Pleroma.User do |> update_and_set_cache() end - def validate_fields(changeset, remote? \\ false) do + defp validate_fields(changeset, remote?) do limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields limit = Config.get([:instance, limit_name], 0) @@ -2779,10 +2802,10 @@ defmodule Pleroma.User do set_domain_blocks(user, List.delete(user.domain_blocks, domain_blocked)) end - @spec add_to_block(User.t(), User.t()) :: + @spec add_to_block(User.t(), User.t(), integer() | nil) :: {:ok, UserRelationship.t()} | {:error, Ecto.Changeset.t()} - defp add_to_block(%User{} = user, %User{} = blocked) do - with {:ok, relationship} <- UserRelationship.create_block(user, blocked) do + defp add_to_block(%User{} = user, %User{} = blocked, expires_at) do + with {:ok, relationship} <- UserRelationship.create_block(user, blocked, expires_at) do @cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}") {:ok, relationship} end diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index 2a1e56278..046316024 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -327,8 +327,8 @@ defmodule Pleroma.Web.ActivityPub.Builder do }, []} end - @spec block(User.t(), User.t()) :: {:ok, map(), keyword()} - def block(blocker, blocked) do + @spec block(User.t(), User.t(), map()) :: {:ok, map(), keyword()} + def block(blocker, blocked, params \\ %{}) do {:ok, %{ "id" => Utils.generate_activity_id(), @@ -336,7 +336,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do "actor" => blocker.ap_id, "object" => blocked.ap_id, "to" => [blocked.ap_id] - }, []} + }, Keyword.new(params)} end @spec announce(User.t(), Object.t(), keyword()) :: {:ok, map(), keyword()} diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index ee12f3ebf..17652a0de 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -200,14 +200,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do end def validate(%{"type" => type} = object, meta) - when type in ~w[Accept Reject Follow Update Like EmojiReact Announce + when type in ~w[Accept Reject Follow Like EmojiReact Announce ChatMessage Answer] do validator = case type do "Accept" -> AcceptRejectValidator "Reject" -> AcceptRejectValidator "Follow" -> FollowValidator - "Update" -> UpdateValidator "Like" -> LikeValidator "EmojiReact" -> EmojiReactValidator "Announce" -> AnnounceValidator @@ -215,16 +214,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do "Answer" -> AnswerValidator end - cast_func = - if type == "Update" do - fn o -> validator.cast_and_validate(o, meta) end - else - fn o -> validator.cast_and_validate(o) end - end - with {:ok, object} <- object - |> cast_func.() + |> validator.cast_and_validate() + |> Ecto.Changeset.apply_action(:insert) do + object = stringify_keys(object) + {:ok, object, meta} + end + end + + def validate(%{"type" => type} = object, meta) when type == "Update" do + with {:ok, object} <- + object + |> UpdateValidator.cast_and_validate(meta) |> Ecto.Changeset.apply_action(:insert) do object = stringify_keys(object) {:ok, object, meta} diff --git a/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex b/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex index 47cf7b415..dc2770189 100644 --- a/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/tag_validator.ex @@ -50,13 +50,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do end def changeset(struct, %{"type" => "Hashtag", "name" => name} = data) do - name = - cond do - "#" <> name -> name - name -> name - end - |> String.downcase() - + name = String.downcase(name) data = Map.put(data, "name", name) struct diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index d6d403671..52cdc3c3f 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -145,7 +145,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do ) do with %User{} = blocker <- User.get_cached_by_ap_id(blocking_user), %User{} = blocked <- User.get_cached_by_ap_id(blocked_user) do - User.block(blocker, blocked) + User.block(blocker, blocked, Enum.into(meta, %{})) end {:ok, object, meta} diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex index 0f22dd538..b35f5cdcd 100644 --- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex @@ -335,13 +335,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do if params["password"] do User.force_password_reset_async(user) - end - ModerationLog.insert_log(%{ - actor: admin, - subject: [user], - action: "force_password_reset" - }) + ModerationLog.insert_log(%{ + actor: admin, + subject: [user], + action: "force_password_reset" + }) + end json(conn, %{status: "success"}) else diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 21a779dcb..d63e92d16 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -284,18 +284,6 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do :query, %Schema{allOf: [BooleanLike], default: true}, "Mute notifications in addition to statuses? Defaults to `true`." - ), - Operation.parameter( - :duration, - :query, - %Schema{type: :integer}, - "Expire the mute in `duration` seconds. Default 0 for infinity" - ), - Operation.parameter( - :expires_in, - :query, - %Schema{type: :integer, default: 0}, - "Deprecated, use `duration` instead" ) ], responses: %{ @@ -323,16 +311,37 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do tags: ["Account actions"], summary: "Block", operationId: "AccountController.block", + requestBody: request_body("Parameters", block_request()), security: [%{"oAuth" => ["follow", "write:blocks"]}], description: "Block the given account. Clients should filter statuses from this account if received (e.g. due to a boost in the Home timeline)", - parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}], + parameters: [ + %Reference{"$ref": "#/components/parameters/accountIdOrNickname"} + ], responses: %{ 200 => Operation.response("Relationship", "application/json", AccountRelationship) } } end + defp block_request do + %Schema{ + title: "AccountBlockRequest", + description: "POST body for blocking an account", + type: :object, + properties: %{ + duration: %Schema{ + type: :integer, + nullable: true, + description: "Expire the mute in `duration` seconds. Default 0 for infinity" + } + }, + example: %{ + "duration" => 86_400 + } + } + end + def unblock_operation do %Operation{ tags: ["Account actions"], diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index 1f73ef60c..19827e996 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -34,6 +34,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do id: FlakeID, locked: %Schema{type: :boolean}, mute_expires_at: %Schema{type: :string, format: "date-time", nullable: true}, + block_expires_at: %Schema{type: :string, format: "date-time", nullable: true}, note: %Schema{type: :string, format: :html}, statuses_count: %Schema{type: :integer}, url: %Schema{type: :string, format: :uri}, diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index 412424dae..ae554d0b9 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -27,9 +27,9 @@ defmodule Pleroma.Web.CommonAPI do require Logger @spec block(User.t(), User.t()) :: {:ok, Activity.t()} | Pipeline.errors() - def block(blocked, blocker) do - with {:ok, block_data, _} <- Builder.block(blocker, blocked), - {:ok, block, _} <- Pipeline.common_pipeline(block_data, local: true) do + def block(blocked, blocker, params \\ %{}) do + with {:ok, block_data, meta} <- Builder.block(blocker, blocked, params), + {:ok, block, _} <- Pipeline.common_pipeline(block_data, meta ++ [local: true]) do {:ok, block} end end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 68157b0c4..d374e8c01 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -501,8 +501,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do end @doc "POST /api/v1/accounts/:id/block" - def block(%{assigns: %{user: blocker, account: blocked}} = conn, _params) do - with {:ok, _activity} <- CommonAPI.block(blocked, blocker) do + def block( + %{ + assigns: %{user: blocker, account: blocked}, + private: %{open_api_spex: %{body_params: params}} + } = conn, + _params + ) do + with {:ok, _activity} <- CommonAPI.block(blocked, blocker, params) do render(conn, "relationship.json", user: blocker, target: blocked) else {:error, message} -> json_response(conn, :forbidden, %{error: message}) @@ -607,7 +613,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do users: users, for: user, as: :user, - embed_relationships: embed_relationships?(params) + embed_relationships: embed_relationships?(params), + blocks: true ) end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index f6727d29d..8d28dd69a 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -340,6 +340,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do |> maybe_put_unread_notification_count(user, opts[:for]) |> maybe_put_email_address(user, opts[:for]) |> maybe_put_mute_expires_at(user, opts[:for], opts) + |> maybe_put_block_expires_at(user, opts[:for], opts) |> maybe_show_birthday(user, opts[:for]) end @@ -476,6 +477,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do defp maybe_put_mute_expires_at(data, _, _, _), do: data + defp maybe_put_block_expires_at(data, %User{} = user, target, %{blocks: true}) do + Map.put( + data, + :block_expires_at, + UserRelationship.get_block_expire_date(target, user) + ) + end + + defp maybe_put_block_expires_at(data, _, _, _), do: data + defp maybe_show_birthday(data, %User{id: user_id} = user, %User{id: user_id}) do data |> Kernel.put_in([:pleroma, :birthday], user.birthday) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index fd72e2f91..5894c764b 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -157,7 +157,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do "pleroma:bookmark_folders", if Pleroma.Language.LanguageDetector.configured?() do "pleroma:language_detection" - end + end, + "pleroma:block_expiration" ] |> Enum.filter(& &1) end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index f2f9d7246..dfab1b216 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -189,7 +189,7 @@ defmodule Pleroma.Web.Router do end pipeline :well_known do - plug(:accepts, ["activity+json", "json", "jrd", "jrd+json", "xml", "xrd+xml"]) + plug(:accepts, ["activity+json", "json", "jrd", "jrd+json", "xml", "xrd+xml", "html"]) end pipeline :config do diff --git a/lib/pleroma/web/templates/email/digest.html.eex b/lib/pleroma/web/templates/email/digest.html.eex index 1efc76e1a..d2918bc6f 100644 --- a/lib/pleroma/web/templates/email/digest.html.eex +++ b/lib/pleroma/web/templates/email/digest.html.eex @@ -231,8 +231,8 @@ <%= for %{data: mention, object: object, from: from} <- @mentions do %> - <%# mention START %> - <%# user card START %> + <% # mention START %> + <% # user card START %>
@@ -291,7 +291,7 @@
- <%# user card END %> + <% # user card END %>
- <%# mention END %> + <% # mention END %> <% end %> <%= if @followers != [] do %> - <%# new followers header START %> + <% # new followers header START %>
@@ -397,10 +397,10 @@
- <%# new followers header END %> + <% # new followers header END %> <%= for %{data: follow, from: from} <- @followers do %> - <%# user card START %> + <% # user card START %>
@@ -459,13 +459,13 @@
- <%# user card END %> + <% # user card END %> <% end %> <% end %> - <%# divider start %> + <% # divider start %>
@@ -514,7 +514,7 @@
- <%# divider end %> + <% # divider end %>
diff --git a/lib/pleroma/web/templates/email/new_users_digest.html.eex b/lib/pleroma/web/templates/email/new_users_digest.html.eex index 40d9b8381..78b8ac4f9 100644 --- a/lib/pleroma/web/templates/email/new_users_digest.html.eex +++ b/lib/pleroma/web/templates/email/new_users_digest.html.eex @@ -1,5 +1,5 @@ <%= for {user, total_statuses, latest_status} <- @users_and_statuses do %> - <%# user card START %> + <% # user card START %>
@@ -60,7 +60,7 @@
- <%# user card END %> + <% # user card END %> <%= if latest_status do %>
@@ -104,7 +104,7 @@
<% end %> - <%# divider start %> + <% # divider start %>
@@ -153,6 +153,6 @@
- <%# divider end %> - <%# user card END %> + <% # divider end %> + <% # user card END %> <% end %> diff --git a/lib/pleroma/web/templates/layout/email_styled.html.eex b/lib/pleroma/web/templates/layout/email_styled.html.eex index 82cabd889..a1ed4ece3 100644 --- a/lib/pleroma/web/templates/layout/email_styled.html.eex +++ b/lib/pleroma/web/templates/layout/email_styled.html.eex @@ -111,7 +111,7 @@ - <%# header %> + <% # header %>
@@ -145,7 +145,7 @@
- <%# title %> + <% # title %> <%= if @title do %>
<%= for scope <- @available_scopes do %> - <%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> + <% # Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> <%= if scope in @scopes do %>
<%= checkbox @form, :"scope_#{scope}", value: scope in @scopes && scope, checked_value: scope, unchecked_value: "", name: "authorization[scope][]" %> diff --git a/lib/pleroma/web/web_finger/web_finger_controller.ex b/lib/pleroma/web/web_finger/web_finger_controller.ex index 021df9bc5..8a291e28e 100644 --- a/lib/pleroma/web/web_finger/web_finger_controller.ex +++ b/lib/pleroma/web/web_finger/web_finger_controller.ex @@ -41,5 +41,10 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do end end + # Default to JSON when no format is specified or format is not recognized + def webfinger(%{assigns: %{format: _format}} = conn, %{"resource" => _resource} = params) do + webfinger(put_in(conn.assigns.format, "json"), params) + end + def webfinger(conn, _params), do: send_resp(conn, 400, "Bad Request") end diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index 8356a775d..9a04fc486 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -5,9 +5,13 @@ defmodule Pleroma.Workers.MuteExpireWorker do use Oban.Worker, queue: :background + alias Pleroma.User + @impl true - def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do - Pleroma.User.unmute(muter_id, mutee_id) + def perform(%Job{ + args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id} + }) do + User.unmute(muter_id, mutee_id) :ok end @@ -18,6 +22,17 @@ defmodule Pleroma.Workers.MuteExpireWorker do :ok end + def perform(%Job{ + args: %{"op" => "unblock_user", "blocker_id" => blocker_id, "blocked_id" => blocked_id} + }) do + Pleroma.Web.CommonAPI.unblock( + User.get_cached_by_id(blocked_id), + User.get_cached_by_id(blocker_id) + ) + + :ok + end + @impl true def timeout(_job), do: :timer.seconds(5) end diff --git a/mix.exs b/mix.exs index 808a2b12c..971084f94 100644 --- a/mix.exs +++ b/mix.exs @@ -37,22 +37,13 @@ defmodule Pleroma.Mixfile do pleroma: [ include_executables_for: [:unix], applications: [ex_syslogger: :load, syslog: :load, eldap: :transient], - steps: [:assemble, &put_otp_version/1, ©_files/1, ©_nginx_config/1], + steps: [:assemble, ©_files/1, ©_nginx_config/1], config_providers: [{Pleroma.Config.ReleaseRuntimeProvider, []}] ] ] ] end - def put_otp_version(%{path: target_path} = release) do - File.write!( - Path.join([target_path, "OTP_VERSION"]), - Pleroma.OTPVersion.version() - ) - - release - end - def copy_files(%{path: target_path} = release) do File.cp_r!("./rel/files", target_path) release @@ -213,7 +204,7 @@ defmodule Pleroma.Mixfile do {:poison, "~> 3.0", only: :test}, {:ex_doc, "~> 0.22", only: :dev, runtime: false}, {:ex_machina, "~> 2.4", only: :test}, - {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, {:mock, "~> 0.3.5", only: :test}, {:covertool, "~> 2.0", only: :test}, {:hackney, "~> 1.18.0", override: true}, @@ -236,7 +227,7 @@ defmodule Pleroma.Mixfile do "ecto.rollback": ["pleroma.ecto.rollback"], "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], - test: ["ecto.create --quiet", "ecto.migrate", "test"], + test: ["ecto.create --quiet", "ecto.migrate", "test --warnings-as-errors"], docs: ["pleroma.docs", "docs"], analyze: ["credo --strict --only=warnings,todo,fixme,consistency,readability"], copyright: &add_copyright/1, diff --git a/mix.lock b/mix.lock index 9b53ede62..f7f37b7e1 100644 --- a/mix.lock +++ b/mix.lock @@ -23,7 +23,7 @@ "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, - "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, + "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, diff --git a/priv/repo/migrations/20240904142434_assign_app_user.exs b/priv/repo/migrations/20240904142434_assign_app_user.exs index 11bec529b..74740220d 100644 --- a/priv/repo/migrations/20240904142434_assign_app_user.exs +++ b/priv/repo/migrations/20240904142434_assign_app_user.exs @@ -1,20 +1,24 @@ defmodule Pleroma.Repo.Migrations.AssignAppUser do use Ecto.Migration + import Ecto.Query + alias Pleroma.Repo alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Token def up do - Repo.all(Token) - |> Enum.group_by(fn x -> Map.get(x, :app_id) end) - |> Enum.each(fn {_app_id, tokens} -> - token = - Enum.filter(tokens, fn x -> not is_nil(x.user_id) end) - |> List.first() - + Token + |> where([t], not is_nil(t.user_id)) + |> group_by([t], t.app_id) + |> select([t], %{app_id: t.app_id, id: min(t.id)}) + |> order_by(asc: :app_id) + |> Repo.stream() + |> Stream.each(fn %{id: id} -> + token = Token.Query.get_by_id(id) |> Repo.one() App.maybe_update_owner(token) end) + |> Stream.run() end def down, do: :ok diff --git a/test/fixtures/warnings/otp_version/21.1 b/test/fixtures/warnings/otp_version/21.1 deleted file mode 100644 index 90cd64c4f..000000000 --- a/test/fixtures/warnings/otp_version/21.1 +++ /dev/null @@ -1 +0,0 @@ -21.1 \ No newline at end of file diff --git a/test/fixtures/warnings/otp_version/22.1 b/test/fixtures/warnings/otp_version/22.1 deleted file mode 100644 index d9b314368..000000000 --- a/test/fixtures/warnings/otp_version/22.1 +++ /dev/null @@ -1 +0,0 @@ -22.1 \ No newline at end of file diff --git a/test/fixtures/warnings/otp_version/22.4 b/test/fixtures/warnings/otp_version/22.4 deleted file mode 100644 index 1da8ccd28..000000000 --- a/test/fixtures/warnings/otp_version/22.4 +++ /dev/null @@ -1 +0,0 @@ -22.4 \ No newline at end of file diff --git a/test/fixtures/warnings/otp_version/23.0 b/test/fixtures/warnings/otp_version/23.0 deleted file mode 100644 index 4266d8634..000000000 --- a/test/fixtures/warnings/otp_version/23.0 +++ /dev/null @@ -1 +0,0 @@ -23.0 \ No newline at end of file diff --git a/test/pleroma/otp_version_test.exs b/test/pleroma/otp_version_test.exs deleted file mode 100644 index 21701d5a8..000000000 --- a/test/pleroma/otp_version_test.exs +++ /dev/null @@ -1,42 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.OTPVersionTest do - use ExUnit.Case, async: true - - alias Pleroma.OTPVersion - - describe "check/1" do - test "22.4" do - assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/22.4"]) == - "22.4" - end - - test "22.1" do - assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/22.1"]) == - "22.1" - end - - test "21.1" do - assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/21.1"]) == - "21.1" - end - - test "23.0" do - assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/23.0"]) == - "23.0" - end - - test "with nonexistent file" do - assert OTPVersion.get_version_from_files([ - "test/fixtures/warnings/otp_version/non-exising", - "test/fixtures/warnings/otp_version/22.4" - ]) == "22.4" - end - - test "empty paths" do - assert OTPVersion.get_version_from_files([]) == nil - end - end -end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 176e70ef9..44e2d0d65 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -2669,8 +2669,12 @@ defmodule Pleroma.UserTest do assert {:ok, user} = User.update_last_active_at(user) - assert user.last_active_at >= test_started_at - assert user.last_active_at <= NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + assert NaiveDateTime.compare(user.last_active_at, test_started_at) in [:gt, :eq] + + assert NaiveDateTime.compare( + user.last_active_at, + NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + ) in [:lt, :eq] last_active_at = NaiveDateTime.utc_now() @@ -2682,10 +2686,15 @@ defmodule Pleroma.UserTest do |> cast(%{last_active_at: last_active_at}, [:last_active_at]) |> User.update_and_set_cache() - assert user.last_active_at == last_active_at + assert NaiveDateTime.compare(user.last_active_at, last_active_at) == :eq + assert {:ok, user} = User.update_last_active_at(user) - assert user.last_active_at >= test_started_at - assert user.last_active_at <= NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + assert NaiveDateTime.compare(user.last_active_at, test_started_at) in [:gt, :eq] + + assert NaiveDateTime.compare( + user.last_active_at, + NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + ) in [:lt, :eq] end test "active_user_count/1" do diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 73230a58c..6b5d31537 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -111,6 +111,17 @@ defmodule Pleroma.Web.CommonAPITest do end end + test "add expiring block", %{blocker: blocker, blocked: blocked} do + {:ok, _} = CommonAPI.block(blocked, blocker, %{expires_in: 60}) + assert User.blocks?(blocker, blocked) + + worker = Pleroma.Workers.MuteExpireWorker + args = %{"op" => "unblock_user", "blocker_id" => blocker.id, "blocked_id" => blocked.id} + + assert :ok = perform_job(worker, args) + refute User.blocks?(blocker, blocked) + end + test "it blocks and does not federate if outgoing blocks are disabled", %{ blocker: blocker, blocked: blocked diff --git a/test/pleroma/web/plugs/user_tracking_plug_test.exs b/test/pleroma/web/plugs/user_tracking_plug_test.exs index 742f04fea..cd9c66448 100644 --- a/test/pleroma/web/plugs/user_tracking_plug_test.exs +++ b/test/pleroma/web/plugs/user_tracking_plug_test.exs @@ -21,8 +21,12 @@ defmodule Pleroma.Web.Plugs.UserTrackingPlugTest do |> assign(:user, user) |> UserTrackingPlug.call(%{}) - assert user.last_active_at >= test_started_at - assert user.last_active_at <= NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + assert NaiveDateTime.compare(user.last_active_at, test_started_at) in [:gt, :eq] + + assert NaiveDateTime.compare( + user.last_active_at, + NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + ) in [:lt, :eq] end test "doesn't update last_active_at if it was updated recently", %{conn: conn} do @@ -38,7 +42,7 @@ defmodule Pleroma.Web.Plugs.UserTrackingPlugTest do |> assign(:user, user) |> UserTrackingPlug.call(%{}) - assert user.last_active_at == last_active_at + assert NaiveDateTime.compare(user.last_active_at, last_active_at) == :eq end test "skips updating last_active_at if user ID is nil", %{conn: conn} do diff --git a/test/pleroma/web/web_finger/web_finger_controller_test.exs b/test/pleroma/web/web_finger/web_finger_controller_test.exs index 80e072163..be44e3a8b 100644 --- a/test/pleroma/web/web_finger/web_finger_controller_test.exs +++ b/test/pleroma/web/web_finger/web_finger_controller_test.exs @@ -5,7 +5,6 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do use Pleroma.Web.ConnCase - import ExUnit.CaptureLog import Pleroma.Factory import Tesla.Mock @@ -55,6 +54,26 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do ] end + test "Webfinger defaults to JSON when no Accept header is provided" do + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda", + also_known_as: ["https://mushroom.kingdom/users/toad"] + ) + + response = + build_conn() + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> json_response(200) + + assert response["subject"] == "acct:#{user.nickname}@localhost" + + assert response["aliases"] == [ + "https://hyrule.world/users/zelda", + "https://mushroom.kingdom/users/toad" + ] + end + test "reach user on tld, while pleroma is running on subdomain" do clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com") @@ -109,16 +128,25 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do assert result == "Couldn't find user" end - test "Sends a 404 when invalid format" do - user = insert(:user) + test "Returns JSON when format is not supported" do + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda", + also_known_as: ["https://mushroom.kingdom/users/toad"] + ) - assert capture_log(fn -> - assert_raise Phoenix.NotAcceptableError, fn -> - build_conn() - |> put_req_header("accept", "text/html") - |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") - end - end) =~ "no supported media type in accept header" + response = + build_conn() + |> put_req_header("accept", "text/html") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> json_response(200) + + assert response["subject"] == "acct:#{user.nickname}@localhost" + + assert response["aliases"] == [ + "https://hyrule.world/users/zelda", + "https://mushroom.kingdom/users/toad" + ] end test "Sends a 400 when resource param is missing" do diff --git a/test/test_helper.exs b/test/test_helper.exs index 94661353b..dc6c05a74 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -2,8 +2,6 @@ # Copyright © 2017-2022 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only -Code.put_compiler_option(:warnings_as_errors, true) - ExUnit.configure(capture_log: true, max_cases: System.schedulers_online()) ExUnit.start(exclude: [:federated])