media_proxy_test.exs (6205B)
1 # Pleroma: A lightweight social networking server 2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> 3 # SPDX-License-Identifier: AGPL-3.0-only 4 5 defmodule Pleroma.MediaProxyTest do 6 use ExUnit.Case 7 import Pleroma.Web.MediaProxy 8 alias Pleroma.Web.MediaProxy.MediaProxyController 9 10 setup do 11 enabled = Pleroma.Config.get([:media_proxy, :enabled]) 12 on_exit(fn -> Pleroma.Config.put([:media_proxy, :enabled], enabled) end) 13 :ok 14 end 15 16 describe "when enabled" do 17 setup do 18 Pleroma.Config.put([:media_proxy, :enabled], true) 19 :ok 20 end 21 22 test "ignores invalid url" do 23 assert url(nil) == nil 24 assert url("") == nil 25 end 26 27 test "ignores relative url" do 28 assert url("/local") == "/local" 29 assert url("/") == "/" 30 end 31 32 test "ignores local url" do 33 local_url = Pleroma.Web.Endpoint.url() <> "/hello" 34 local_root = Pleroma.Web.Endpoint.url() 35 assert url(local_url) == local_url 36 assert url(local_root) == local_root 37 end 38 39 test "encodes and decodes URL" do 40 url = "https://pleroma.soykaf.com/static/logo.png" 41 encoded = url(url) 42 43 assert String.starts_with?( 44 encoded, 45 Pleroma.Config.get([:media_proxy, :base_url], Pleroma.Web.base_url()) 46 ) 47 48 assert String.ends_with?(encoded, "/logo.png") 49 50 assert decode_result(encoded) == url 51 end 52 53 test "encodes and decodes URL without a path" do 54 url = "https://pleroma.soykaf.com" 55 encoded = url(url) 56 assert decode_result(encoded) == url 57 end 58 59 test "encodes and decodes URL without an extension" do 60 url = "https://pleroma.soykaf.com/path/" 61 encoded = url(url) 62 assert String.ends_with?(encoded, "/path") 63 assert decode_result(encoded) == url 64 end 65 66 test "encodes and decodes URL and ignores query params for the path" do 67 url = "https://pleroma.soykaf.com/static/logo.png?93939393939&bunny=true" 68 encoded = url(url) 69 assert String.ends_with?(encoded, "/logo.png") 70 assert decode_result(encoded) == url 71 end 72 73 test "ensures urls are url-encoded" do 74 assert decode_result(url("https://pleroma.social/Hello world.jpg")) == 75 "https://pleroma.social/Hello%20world.jpg" 76 77 assert decode_result(url("https://pleroma.social/Hello%20world.jpg")) == 78 "https://pleroma.social/Hello%20world.jpg" 79 end 80 81 test "validates signature" do 82 secret_key_base = Pleroma.Config.get([Pleroma.Web.Endpoint, :secret_key_base]) 83 84 on_exit(fn -> 85 Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], secret_key_base) 86 end) 87 88 encoded = url("https://pleroma.social") 89 90 Pleroma.Config.put( 91 [Pleroma.Web.Endpoint, :secret_key_base], 92 "00000000000000000000000000000000000000000000000" 93 ) 94 95 [_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/") 96 assert decode_url(sig, base64) == {:error, :invalid_signature} 97 end 98 99 test "filename_matches matches url encoded paths" do 100 assert MediaProxyController.filename_matches( 101 true, 102 "/Hello%20world.jpg", 103 "http://pleroma.social/Hello world.jpg" 104 ) == :ok 105 106 assert MediaProxyController.filename_matches( 107 true, 108 "/Hello%20world.jpg", 109 "http://pleroma.social/Hello%20world.jpg" 110 ) == :ok 111 end 112 113 test "filename_matches matches non-url encoded paths" do 114 assert MediaProxyController.filename_matches( 115 true, 116 "/Hello world.jpg", 117 "http://pleroma.social/Hello%20world.jpg" 118 ) == :ok 119 120 assert MediaProxyController.filename_matches( 121 true, 122 "/Hello world.jpg", 123 "http://pleroma.social/Hello world.jpg" 124 ) == :ok 125 end 126 127 test "uses the configured base_url" do 128 base_url = Pleroma.Config.get([:media_proxy, :base_url]) 129 130 if base_url do 131 on_exit(fn -> 132 Pleroma.Config.put([:media_proxy, :base_url], base_url) 133 end) 134 end 135 136 Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social") 137 138 url = "https://pleroma.soykaf.com/static/logo.png" 139 encoded = url(url) 140 141 assert String.starts_with?(encoded, Pleroma.Config.get([:media_proxy, :base_url])) 142 end 143 144 # https://git.pleroma.social/pleroma/pleroma/issues/580 145 test "encoding S3 links (must preserve `%2F`)" do 146 url = 147 "https://s3.amazonaws.com/example/test.png?X-Amz-Credential=your-access-key-id%2F20130721%2Fus-east-1%2Fs3%2Faws4_request" 148 149 encoded = url(url) 150 assert decode_result(encoded) == url 151 end 152 153 test "does not change whitelisted urls" do 154 upload_config = Pleroma.Config.get([Pleroma.Upload]) 155 media_url = "https://media.pleroma.social" 156 Pleroma.Config.put([Pleroma.Upload, :base_url], media_url) 157 Pleroma.Config.put([:media_proxy, :whitelist], ["media.pleroma.social"]) 158 Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social") 159 160 url = "#{media_url}/static/logo.png" 161 encoded = url(url) 162 163 assert String.starts_with?(encoded, media_url) 164 165 Pleroma.Config.put([Pleroma.Upload], upload_config) 166 end 167 end 168 169 describe "when disabled" do 170 setup do 171 enabled = Pleroma.Config.get([:media_proxy, :enabled]) 172 173 if enabled do 174 Pleroma.Config.put([:media_proxy, :enabled], false) 175 176 on_exit(fn -> 177 Pleroma.Config.put([:media_proxy, :enabled], enabled) 178 :ok 179 end) 180 end 181 182 :ok 183 end 184 185 test "does not encode remote urls" do 186 assert url("https://google.fr") == "https://google.fr" 187 end 188 end 189 190 defp decode_result(encoded) do 191 [_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/") 192 {:ok, decoded} = decode_url(sig, base64) 193 decoded 194 end 195 196 test "mediaproxy whitelist" do 197 Pleroma.Config.put([:media_proxy, :enabled], true) 198 Pleroma.Config.put([:media_proxy, :whitelist], ["google.com", "feld.me"]) 199 url = "https://feld.me/foo.png" 200 201 unencoded = url(url) 202 assert unencoded == url 203 end 204 end