total rebase
[anni] / lib / pleroma / web / api_spec / scopes / compiler.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ApiSpec.Scopes.Compiler do
6   defmacro __before_compile__(_env) do
7     strings = __MODULE__.extract_all_scopes()
8
9     quote do
10       def placeholder do
11         unquote do
12           Enum.map(
13             strings,
14             fn string ->
15               quote do
16                 Pleroma.Web.Gettext.dgettext_noop(
17                   "oauth_scopes",
18                   unquote(string)
19                 )
20               end
21             end
22           )
23         end
24       end
25     end
26   end
27
28   def extract_all_scopes do
29     extract_all_scopes_from(Pleroma.Web.ApiSpec.spec())
30   end
31
32   def extract_all_scopes_from(specs) do
33     specs.paths
34     |> Enum.reduce([], fn
35       {_path, %{} = path_item}, acc ->
36         extract_routes(path_item)
37         |> Enum.flat_map(fn operation -> process_operation(operation) end)
38         |> Kernel.++(acc)
39
40       {_, _}, acc ->
41         acc
42     end)
43     |> Enum.uniq()
44   end
45
46   defp extract_routes(path_item) do
47     path_item
48     |> Map.from_struct()
49     |> Enum.map(fn {_method, path_item} -> path_item end)
50     |> Enum.filter(fn
51       %OpenApiSpex.Operation{} = _operation -> true
52       _ -> false
53     end)
54   end
55
56   defp process_operation(operation) do
57     operation.security
58     |> Kernel.||([])
59     |> Enum.flat_map(fn
60       %{"oAuth" => scopes} -> process_scopes(scopes)
61       _ -> []
62     end)
63   end
64
65   defp process_scopes(scopes) do
66     scopes
67     |> Enum.flat_map(fn scope ->
68       process_scope(scope)
69     end)
70   end
71
72   def process_scope(scope) do
73     hierarchy = String.split(scope, ":")
74
75     {_, list} =
76       Enum.reduce(hierarchy, {"", []}, fn comp, {cur, list} ->
77         {cur <> comp <> ":", [cur <> comp | list]}
78       end)
79
80     list
81   end
82 end