GET /api/v1/apps endpoint
authorSean King <seanking2919@protonmail.com>
Thu, 26 Aug 2021 03:01:04 +0000 (21:01 -0600)
committerSean King <seanking2919@protonmail.com>
Thu, 26 Aug 2021 03:01:04 +0000 (21:01 -0600)
lib/pleroma/web/api_spec/operations/app_operation.ex
lib/pleroma/web/mastodon_api/controllers/app_controller.ex
lib/pleroma/web/mastodon_api/views/app_view.ex
lib/pleroma/web/o_auth/app.ex
lib/pleroma/web/router.ex
priv/repo/migrations/20210818023112_add_user_id_to_apps.exs [new file with mode: 0644]

index dfb1c71706c4c4ed6b6be97f986f1c6af97aa81d..72032a4e05cc9d62dc47521ba5960f49f342a754 100644 (file)
@@ -13,6 +13,19 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
     apply(__MODULE__, operation, [])
   end
 
+  @spec index_operation() :: Operation.t()
+  def index_operation do
+    %Operation{
+      tags: ["Applications"],
+      summary: "List applications",
+      description: "List the OAuth applications for the current user",
+      operationId: "AppController.index",
+      responses: %{
+        200 => Operation.response("App", "application/json", index_response()),
+      }
+    }
+  end
+
   @spec create_operation() :: Operation.t()
   def create_operation do
     %Operation{
@@ -145,4 +158,30 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
       }
     }
   end
+
+  defp index_response do
+    %Schema{
+      title: "AppIndexResponse",
+      description: "Response schema for GET /api/v1/apps",
+      type: :object,
+      properties: [%{
+        id: %Schema{type: :string},
+        name: %Schema{type: :string},
+        client_id: %Schema{type: :string},
+        client_secret: %Schema{type: :string},
+        redirect_uri: %Schema{type: :string},
+        vapid_key: %Schema{type: :string},
+        website: %Schema{type: :string, nullable: true}
+      }],
+      example: [%{
+        "id" => "123",
+        "name" => "My App",
+        "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM",
+        "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw",
+        "vapid_key" =>
+          "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=",
+        "website" => "https://myapp.com/"
+      }]
+    }
+  end
 end
index a95cc52fda151536ee6b4be6258cc5c5ceaa73d2..38073c29aad8d9ccb0da52195d0b8f3e59f6c2ea 100644 (file)
@@ -14,17 +14,27 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
   alias Pleroma.Web.OAuth.App
   alias Pleroma.Web.OAuth.Scopes
   alias Pleroma.Web.OAuth.Token
+  alias Pleroma.Web.Plugs.OAuthScopesPlug
 
   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 
   plug(:skip_auth when action in [:create, :verify_credentials])
 
+  plug(:skip_plug, OAuthScopesPlug when action in [:index])
+
   plug(Pleroma.Web.ApiSpec.CastAndValidate)
 
   @local_mastodon_name "Mastodon-Local"
 
   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation
 
+  @doc "GET /api/v1/apps"
+  def index(%{assigns: %{user: user}} = conn, _params) do
+    with apps <- App.get_user_apps(user) do
+      render(conn, "index.json", %{apps: apps})
+    end
+  end
+
   @doc "POST /api/v1/apps"
   def create(%{body_params: params} = conn, _params) do
     scopes = Scopes.fetch_scopes(params, ["read"])
index c406b5a27f939a32d1a877182ed38f86a6d2d66e..450943aee18862bd6c25c9cf45c541216393ee2c 100644 (file)
@@ -15,6 +15,10 @@ defmodule Pleroma.Web.MastodonAPI.AppView do
     }
   end
 
+  def render("index.json", %{apps: apps}) do
+    render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json")
+  end
+
   def render("show.json", %{admin: true, app: %App{} = app} = assigns) do
     "show.json"
     |> render(Map.delete(assigns, :admin))
index 38275001036177a142cb0f2d436242bd2cc9063a..94b0e41f05eee009ccb3edebf0eb6541740b67d3 100644 (file)
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.OAuth.App do
   import Ecto.Changeset
   import Ecto.Query
   alias Pleroma.Repo
+  alias Pleroma.User
 
   @type t :: %__MODULE__{}
 
@@ -19,6 +20,8 @@ defmodule Pleroma.Web.OAuth.App do
     field(:client_secret, :string)
     field(:trusted, :boolean, default: false)
 
+    belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
+
     has_many(:oauth_authorizations, Pleroma.Web.OAuth.Authorization, on_delete: :delete_all)
     has_many(:oauth_tokens, Pleroma.Web.OAuth.Token, on_delete: :delete_all)
 
@@ -129,6 +132,12 @@ defmodule Pleroma.Web.OAuth.App do
     {:ok, Repo.all(query), count}
   end
 
+  @spec get_user_apps(User.t()) :: {:ok, [t()], non_neg_integer()}
+  def get_user_apps(%User{id: user_id}) do
+    from(a in __MODULE__, where: a.user_id == ^user_id)
+    |> Repo.all()
+  end
+
   @spec destroy(pos_integer()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
   def destroy(id) do
     with %__MODULE__{} = app <- Repo.get(__MODULE__, id) do
index 74ee23c06c17d4108e1330de1b81fe9f56ca02ca..90443956408dc48bdbb70081a8a5525c27e09fb0 100644 (file)
@@ -444,6 +444,8 @@ defmodule Pleroma.Web.Router do
   scope "/api/v1", Pleroma.Web.MastodonAPI do
     pipe_through(:authenticated_api)
 
+    get("/apps", AppController, :index)
+
     get("/accounts/verify_credentials", AccountController, :verify_credentials)
     patch("/accounts/update_credentials", AccountController, :update_credentials)
 
diff --git a/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs b/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs
new file mode 100644 (file)
index 0000000..39e7fbe
--- /dev/null
@@ -0,0 +1,9 @@
+defmodule Pleroma.Repo.Migrations.AddUserIdToApps do
+  use Ecto.Migration
+
+  def change do
+    alter table(:apps) do
+      add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
+    end
+  end
+end