From d87785652731c4e5b350465d80e606557231fa6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charlotte=20=F0=9F=A6=9D=20Delenk?= Date: Sun, 23 Jul 2023 08:11:47 +0100 Subject: [PATCH] Allow admin to configure bucket ACL settings To upload to Backblaze B2, the ACL needs to match bucket settings, and if you have a CDN in front of your media server you may want to restrict public access to the bucket to avoid expensive non-cdn transfers and bucket enumeration. --- config/config.exs | 1 + docs/docs/configuration/cheatsheet.md | 3 ++- lib/pleroma/uploaders/s3.ex | 5 +++-- test/pleroma/uploaders/s3_test.exs | 16 +++++++++++++++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/config/config.exs b/config/config.exs index 3430ee4d7..ae2c6f2e0 100644 --- a/config/config.exs +++ b/config/config.exs @@ -70,6 +70,7 @@ config :pleroma, Pleroma.Upload, config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads" config :pleroma, Pleroma.Uploaders.S3, + acl: :public_read, bucket: nil, bucket_namespace: nil, truncated_namespace: nil, diff --git a/docs/docs/configuration/cheatsheet.md b/docs/docs/configuration/cheatsheet.md index 73fdf9eea..8afc33018 100644 --- a/docs/docs/configuration/cheatsheet.md +++ b/docs/docs/configuration/cheatsheet.md @@ -33,7 +33,7 @@ To add configuration to your config file, you can copy it from the base config. * `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes. * `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it. * `allow_relay`: Permits remote instances to subscribe to all public posts of your instance. This may increase the visibility of your instance. -* `public`: Allows unauthenticated access to public resources on your instance. This is essentially used as the default value for `:restrict_unauthenticated`. +* `public`: Allows unauthenticated access to public resources on your instance. This is essentially used as the default value for `:restrict_unauthenticated`. See `restrict_unauthenticated` for more details. * `quarantined_instances`: *DEPRECATED* ActivityPub instances where activities will not be sent. They can still reach there via other means, we just won't send them. * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML). @@ -576,6 +576,7 @@ the source code is here: [kocaptcha](https://github.com/koto-bank/kocaptcha). Th Don't forget to configure [Ex AWS S3](#ex-aws-s3-settings) +* `acl`: The ACL the uploaded media will have. By default media will be `:public_read`, and thus directly accessible from the bucket. Set this to `:private` if you have a CDN in front of your media proxy which sends authenticated requests to your S3 provider. On some providers, like Backblaze B2, this needs to match bucket settings! * `bucket`: S3 bucket name. * `bucket_namespace`: S3 bucket namespace. * `truncated_namespace`: If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or "" etc. diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex index 481153fe8..7d517df5b 100644 --- a/lib/pleroma/uploaders/s3.ex +++ b/lib/pleroma/uploaders/s3.ex @@ -25,6 +25,7 @@ defmodule Pleroma.Uploaders.S3 do config = Config.get([__MODULE__]) bucket = Keyword.get(config, :bucket) streaming = Keyword.get(config, :streaming_enabled) + acl = Keyword.get(config, :acl) s3_name = strict_encode(upload.path) @@ -33,14 +34,14 @@ defmodule Pleroma.Uploaders.S3 do upload.tempfile |> ExAws.S3.Upload.stream_file() |> ExAws.S3.upload(bucket, s3_name, [ - {:acl, :public_read}, + {:acl, acl}, {:content_type, upload.content_type} ]) else {:ok, file_data} = File.read(upload.tempfile) ExAws.S3.put_object(bucket, s3_name, file_data, [ - {:acl, :public_read}, + {:acl, acl}, {:content_type, upload.content_type} ]) end diff --git a/test/pleroma/uploaders/s3_test.exs b/test/pleroma/uploaders/s3_test.exs index 2711e2c8d..0f5d0b00e 100644 --- a/test/pleroma/uploaders/s3_test.exs +++ b/test/pleroma/uploaders/s3_test.exs @@ -66,7 +66,11 @@ defmodule Pleroma.Uploaders.S3Test do end test "save file", %{file_upload: file_upload} do - with_mock ExAws, request: fn _ -> {:ok, :ok} end do + with_mock ExAws, request: (fn _ -> + assert op.opts[:acl] == :public_read + {:ok, :ok} + end) + do assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}} end end @@ -78,6 +82,16 @@ defmodule Pleroma.Uploaders.S3Test do end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}" end end + + test "respects acl setting", %{file_upload: file_upload} do + clear_config([Pleroma.Uploaders.S3, :acl], :private) + with_mock ExAws, request: (fn(op) -> + assert op.opts[:acl] == :private + {:ok, :ok} + end) do + assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}} + end + end end describe "delete_file/1" do -- 2.34.1