diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/mix/tasks/pleroma/app.ex | 49 | ||||
| -rw-r--r-- | lib/pleroma/web/admin_api/admin_api_controller.ex | 79 | ||||
| -rw-r--r-- | lib/pleroma/web/mastodon_api/controllers/account_controller.ex | 1 | ||||
| -rw-r--r-- | lib/pleroma/web/mastodon_api/views/app_view.ex | 15 | ||||
| -rw-r--r-- | lib/pleroma/web/oauth/app.ex | 82 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 5 | ||||
| -rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 3 | 
7 files changed, 232 insertions, 2 deletions
| diff --git a/lib/mix/tasks/pleroma/app.ex b/lib/mix/tasks/pleroma/app.ex new file mode 100644 index 000000000..463e2449f --- /dev/null +++ b/lib/mix/tasks/pleroma/app.ex @@ -0,0 +1,49 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Mix.Tasks.Pleroma.App do +  @moduledoc File.read!("docs/administration/CLI_tasks/oauth_app.md") +  use Mix.Task + +  import Mix.Pleroma + +  @shortdoc "Creates trusted OAuth App" + +  def run(["create" | options]) do +    start_pleroma() + +    {opts, _} = +      OptionParser.parse!(options, +        strict: [name: :string, redirect_uri: :string, scopes: :string], +        aliases: [n: :name, r: :redirect_uri, s: :scopes] +      ) + +    scopes = +      if opts[:scopes] do +        String.split(opts[:scopes], ",") +      else +        ["read", "write", "follow", "push"] +      end + +    params = %{ +      client_name: opts[:name], +      redirect_uris: opts[:redirect_uri], +      trusted: true, +      scopes: scopes +    } + +    with {:ok, app} <- Pleroma.Web.OAuth.App.create(params) do +      shell_info("#{app.client_name} successfully created:") +      shell_info("App client_id: " <> app.client_id) +      shell_info("App client_secret: " <> app.client_secret) +    else +      {:error, changeset} -> +        shell_error("Creating failed:") + +        Enum.each(Pleroma.Web.OAuth.App.errors(changeset), fn {key, error} -> +          shell_error("#{key}: #{error}") +        end) +    end +  end +end diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 175260bc2..b03fa7169 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -27,7 +27,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    alias Pleroma.Web.AdminAPI.Search    alias Pleroma.Web.CommonAPI    alias Pleroma.Web.Endpoint +  alias Pleroma.Web.MastodonAPI.AppView    alias Pleroma.Web.MastodonAPI.StatusView +  alias Pleroma.Web.OAuth.App    alias Pleroma.Web.Router    require Logger @@ -978,6 +980,83 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do      conn |> json("")    end +  def oauth_app_create(conn, params) do +    params = +      if params["name"] do +        Map.put(params, "client_name", params["name"]) +      else +        params +      end + +    result = +      case App.create(params) do +        {:ok, app} -> +          AppView.render("show.json", %{app: app, admin: true}) + +        {:error, changeset} -> +          App.errors(changeset) +      end + +    json(conn, result) +  end + +  def oauth_app_update(conn, params) do +    params = +      if params["name"] do +        Map.put(params, "client_name", params["name"]) +      else +        params +      end + +    with {:ok, app} <- App.update(params) do +      json(conn, AppView.render("show.json", %{app: app, admin: true})) +    else +      {:error, changeset} -> +        json(conn, App.errors(changeset)) + +      nil -> +        json_response(conn, :bad_request, "") +    end +  end + +  def oauth_app_list(conn, params) do +    {page, page_size} = page_params(params) + +    search_params = %{ +      client_name: params["name"], +      client_id: params["client_id"], +      page: page, +      page_size: page_size +    } + +    search_params = +      if Map.has_key?(params, "trusted") do +        Map.put(search_params, :trusted, params["trusted"]) +      else +        search_params +      end + +    with {:ok, apps, count} <- App.search(search_params) do +      json( +        conn, +        AppView.render("index.json", +          apps: apps, +          count: count, +          page_size: page_size, +          admin: true +        ) +      ) +    end +  end + +  def oauth_app_delete(conn, params) do +    with {:ok, _app} <- App.destroy(params["id"]) do +      json_response(conn, :no_content, "") +    else +      _ -> json_response(conn, :bad_request, "") +    end +  end +    def stats(conn, _) do      count = Stats.get_status_visibility_count() diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 6dbf11ac9..5f8aa2e3e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -92,6 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do        |> Map.put("fullname", params["fullname"] || nickname)        |> Map.put("bio", params["bio"] || "")        |> Map.put("confirm", params["password"]) +      |> Map.put("trusted_app", app.trusted)      with :ok <- validate_email_param(params),           {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), diff --git a/lib/pleroma/web/mastodon_api/views/app_view.ex b/lib/pleroma/web/mastodon_api/views/app_view.ex index d934e2107..36071cd25 100644 --- a/lib/pleroma/web/mastodon_api/views/app_view.ex +++ b/lib/pleroma/web/mastodon_api/views/app_view.ex @@ -7,6 +7,21 @@ defmodule Pleroma.Web.MastodonAPI.AppView do    alias Pleroma.Web.OAuth.App +  def render("index.json", %{apps: apps, count: count, page_size: page_size, admin: true}) do +    %{ +      apps: render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json", %{admin: true}), +      count: count, +      page_size: page_size +    } +  end + +  def render("show.json", %{admin: true, app: %App{} = app} = assigns) do +    "show.json" +    |> render(Map.delete(assigns, :admin)) +    |> Map.put(:trusted, app.trusted) +    |> Map.put(:id, app.id) +  end +    def render("show.json", %{app: %App{} = app}) do      %{        id: app.id |> to_string, diff --git a/lib/pleroma/web/oauth/app.ex b/lib/pleroma/web/oauth/app.ex index 01ed326f4..6a6d5f2e2 100644 --- a/lib/pleroma/web/oauth/app.ex +++ b/lib/pleroma/web/oauth/app.ex @@ -5,6 +5,7 @@  defmodule Pleroma.Web.OAuth.App do    use Ecto.Schema    import Ecto.Changeset +  import Ecto.Query    alias Pleroma.Repo    @type t :: %__MODULE__{} @@ -16,14 +17,24 @@ defmodule Pleroma.Web.OAuth.App do      field(:website, :string)      field(:client_id, :string)      field(:client_secret, :string) +    field(:trusted, :boolean, default: false) + +    has_many(:oauth_authorizations, Pleroma.Web.OAuth.Authorization, on_delete: :delete_all) +    has_many(:oauth_tokens, Pleroma.Web.OAuth.Token, on_delete: :delete_all)      timestamps()    end +  @spec changeset(App.t(), map()) :: Ecto.Changeset.t() +  def changeset(struct, params) do +    cast(struct, params, [:client_name, :redirect_uris, :scopes, :website, :trusted]) +  end + +  @spec register_changeset(App.t(), map()) :: Ecto.Changeset.t()    def register_changeset(struct, params \\ %{}) do      changeset =        struct -      |> cast(params, [:client_name, :redirect_uris, :scopes, :website]) +      |> changeset(params)        |> validate_required([:client_name, :redirect_uris, :scopes])      if changeset.valid? do @@ -41,6 +52,21 @@ defmodule Pleroma.Web.OAuth.App do      end    end +  @spec create(map()) :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} +  def create(params) do +    with changeset <- __MODULE__.register_changeset(%__MODULE__{}, params) do +      Repo.insert(changeset) +    end +  end + +  @spec update(map()) :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} +  def update(params) do +    with %__MODULE__{} = app <- Repo.get(__MODULE__, params["id"]), +         changeset <- changeset(app, params) do +      Repo.update(changeset) +    end +  end +    @doc """    Gets app by attrs or create new  with attrs.    And updates the scopes if need. @@ -65,4 +91,58 @@ defmodule Pleroma.Web.OAuth.App do      |> change(%{scopes: scopes})      |> Repo.update()    end + +  @spec search(map()) :: {:ok, [App.t()], non_neg_integer()} +  def search(params) do +    query = from(a in __MODULE__) + +    query = +      if params[:client_name] do +        from(a in query, where: a.client_name == ^params[:client_name]) +      else +        query +      end + +    query = +      if params[:client_id] do +        from(a in query, where: a.client_id == ^params[:client_id]) +      else +        query +      end + +    query = +      if Map.has_key?(params, :trusted) do +        from(a in query, where: a.trusted == ^params[:trusted]) +      else +        query +      end + +    query = +      from(u in query, +        limit: ^params[:page_size], +        offset: ^((params[:page] - 1) * params[:page_size]) +      ) + +    count = Repo.aggregate(__MODULE__, :count, :id) + +    {:ok, Repo.all(query), count} +  end + +  @spec destroy(pos_integer()) :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} +  def destroy(id) do +    with %__MODULE__{} = app <- Repo.get(__MODULE__, id) do +      Repo.delete(app) +    end +  end + +  @spec errors(Ecto.Changeset.t()) :: map() +  def errors(changeset) do +    Enum.reduce(changeset.errors, %{}, fn +      {:client_name, {error, _}}, acc -> +        Map.put(acc, :name, error) + +      {key, {error, _}}, acc -> +        Map.put(acc, key, error) +    end) +  end  end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 3f36f6c1a..c37ef59a0 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -203,6 +203,11 @@ defmodule Pleroma.Web.Router do      post("/reload_emoji", AdminAPIController, :reload_emoji)      get("/stats", AdminAPIController, :stats) + +    get("/oauth_app", AdminAPIController, :oauth_app_list) +    post("/oauth_app", AdminAPIController, :oauth_app_create) +    patch("/oauth_app/:id", AdminAPIController, :oauth_app_update) +    delete("/oauth_app/:id", AdminAPIController, :oauth_app_delete)    end    scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index f9c0994da..7a1ba6936 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do    def register_user(params, opts \\ []) do      token = params["token"] +    trusted_app? = params["trusted_app"]      params = %{        nickname: params["nickname"], @@ -29,7 +30,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do      captcha_enabled = Pleroma.Config.get([Pleroma.Captcha, :enabled])      # true if captcha is disabled or enabled and valid, false otherwise      captcha_ok = -      if not captcha_enabled do +      if trusted_app? || not captcha_enabled do          :ok        else          Pleroma.Captcha.validate( | 
