Allow admin to configure bucket ACL settings #600

Open
darkkirb wants to merge 1 commit from darkkirb/akkoma:add-s3-acl-option into develop
4 changed files with 21 additions and 4 deletions

View file

@ -70,6 +70,7 @@
config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads" config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads"
config :pleroma, Pleroma.Uploaders.S3, config :pleroma, Pleroma.Uploaders.S3,
acl: :public_read,
bucket: nil, bucket: nil,
bucket_namespace: nil, bucket_namespace: nil,
truncated_namespace: nil, truncated_namespace: nil,

View file

@ -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_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. * `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. * `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. 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. * `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). * `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) 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!

can you also document the old standard value of public_read?

used if you point media directly at the bucket

can you also document the old standard value of `public_read`? used if you point media directly at the bucket
* `bucket`: S3 bucket name. * `bucket`: S3 bucket name.
* `bucket_namespace`: S3 bucket namespace. * `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. * `truncated_namespace`: If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or "" etc.

View file

@ -25,6 +25,7 @@ def put_file(%Pleroma.Upload{} = upload) do
config = Config.get([__MODULE__]) config = Config.get([__MODULE__])
bucket = Keyword.get(config, :bucket) bucket = Keyword.get(config, :bucket)
streaming = Keyword.get(config, :streaming_enabled) streaming = Keyword.get(config, :streaming_enabled)
acl = Keyword.get(config, :acl)

keyboard
keyboard

muscle memory fun

keyboard keyboard muscle memory fun
s3_name = strict_encode(upload.path) s3_name = strict_encode(upload.path)
@ -33,14 +34,14 @@ def put_file(%Pleroma.Upload{} = upload) do
upload.tempfile upload.tempfile
|> ExAws.S3.Upload.stream_file() |> ExAws.S3.Upload.stream_file()
|> ExAws.S3.upload(bucket, s3_name, [ |> ExAws.S3.upload(bucket, s3_name, [
{:acl, :public_read}, {:acl, acl},
{:content_type, upload.content_type} {:content_type, upload.content_type}
]) ])
else else
{:ok, file_data} = File.read(upload.tempfile) {:ok, file_data} = File.read(upload.tempfile)
ExAws.S3.put_object(bucket, s3_name, file_data, [ ExAws.S3.put_object(bucket, s3_name, file_data, [
{:acl, :public_read}, {:acl, acl},
{:content_type, upload.content_type} {:content_type, upload.content_type}
]) ])
end end

View file

@ -66,7 +66,11 @@ test "it returns path with bucket namespace when namespace is set" do
end end
test "save file", %{file_upload: file_upload} do 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
Review

op is not defined

op is not defined
{:ok, :ok}
end)
do
assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}} assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}}
end end
end end
@ -78,6 +82,16 @@ test "returns error", %{file_upload: file_upload} do
end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}" end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}"
end end
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 end
describe "delete_file/1" do describe "delete_file/1" do