First
[anni] / lib / pleroma / web / rich_media / parser / ttl / aws_signed_url.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl do
6   @behaviour Pleroma.Web.RichMedia.Parser.TTL
7
8   @impl true
9   def ttl(data, _url) do
10     image = Map.get(data, :image)
11
12     if is_aws_signed_url(image) do
13       image
14       |> parse_query_params()
15       |> format_query_params()
16       |> get_expiration_timestamp()
17     else
18       {:error, "Not aws signed url #{inspect(image)}"}
19     end
20   end
21
22   defp is_aws_signed_url(image) when is_binary(image) and image != "" do
23     %URI{host: host, query: query} = URI.parse(image)
24
25     String.contains?(host, "amazonaws.com") and String.contains?(query, "X-Amz-Expires")
26   end
27
28   defp is_aws_signed_url(_), do: nil
29
30   defp parse_query_params(image) do
31     %URI{query: query} = URI.parse(image)
32     query
33   end
34
35   defp format_query_params(query) do
36     query
37     |> String.split(~r/&|=/)
38     |> Enum.chunk_every(2)
39     |> Map.new(fn [k, v] -> {k, v} end)
40   end
41
42   defp get_expiration_timestamp(params) when is_map(params) do
43     {:ok, date} =
44       params
45       |> Map.get("X-Amz-Date")
46       |> Timex.parse("{ISO:Basic:Z}")
47
48     {:ok, Timex.to_unix(date) + String.to_integer(Map.get(params, "X-Amz-Expires"))}
49   end
50 end