diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/activity.ex | 4 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 10 | ||||
| -rw-r--r-- | lib/pleroma/web/common_api/utils.ex | 11 | ||||
| -rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 17 | ||||
| -rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 46 | ||||
| -rw-r--r-- | lib/pleroma/web/ostatus/ostatus_controller.ex | 109 | ||||
| -rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 6 | ||||
| -rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api_controller.ex | 23 | 
8 files changed, 154 insertions, 72 deletions
| diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c7502981e..dd6805125 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -72,8 +72,10 @@ defmodule Pleroma.Activity do      )    end -  def get_create_activity_by_object_ap_id(ap_id) do +  def get_create_activity_by_object_ap_id(ap_id) when is_binary(ap_id) do      create_activity_by_object_id_query([ap_id])      |> Repo.one()    end + +  def get_create_activity_by_object_ap_id(_), do: nil  end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index a6a9b99ef..ee5d319a7 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -27,9 +27,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do        |> json(ObjectView.render("object.json", %{object: object}))      else        {:public?, false} -> -        conn -        |> put_status(404) -        |> json("Not found") +        {:error, :not_found}      end    end @@ -107,6 +105,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do      json(conn, "ok")    end +  def errors(conn, {:error, :not_found}) do +    conn +    |> put_status(404) +    |> json("Not found") +  end +    def errors(conn, _e) do      conn      |> put_status(500) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 9c9951371..30089f553 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -9,11 +9,12 @@ defmodule Pleroma.Web.CommonAPI.Utils do    def get_by_id_or_ap_id(id) do      activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) -    if activity.data["type"] == "Create" do -      activity -    else -      Activity.get_create_activity_by_object_ap_id(activity.data["object"]) -    end +    activity && +      if activity.data["type"] == "Create" do +        activity +      else +        Activity.get_create_activity_by_object_ap_id(activity.data["object"]) +      end    end    def get_replied_to_activity(id) when not is_nil(id) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5fb51e8fa..4252ac2fe 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -10,6 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    import Ecto.Query    require Logger +  action_fallback(:errors) +    def create_app(conn, params) do      with cs <- App.register_changeset(%App{}, params) |> IO.inspect(),           {:ok, app} <- Repo.insert(cs) |> IO.inspect() do @@ -134,6 +136,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do        %{          "shortcode" => shortcode,          "static_url" => url, +        "visible_in_picker" => true,          "url" => url        }      end) @@ -327,27 +330,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do -    with {:ok, announce, _activity} = CommonAPI.repeat(ap_id_or_id, user) do +    with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user) do        render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity})      end    end    def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do -    with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unrepeat(ap_id_or_id, user), +    with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})      end    end    def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do -    with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user), +    with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})      end    end    def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do -    with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user), +    with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})      end @@ -919,4 +922,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do          nil      end    end + +  def errors(conn, _) do +    conn +    |> put_status(500) +    |> json("Something went wrong") +  end  end diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 11dc1806f..3dd87d0ab 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -56,12 +56,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do    # TODO    # - proper scope handling    def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do -    with %App{} = app <- -           Repo.get_by( -             App, -             client_id: params["client_id"], -             client_secret: params["client_secret"] -           ), +    with %App{} = app <- get_app_from_request(conn, params),           fixed_token = fix_padding(params["code"]),           %Authorization{} = auth <-             Repo.get_by(Authorization, token: fixed_token, app_id: app.id), @@ -76,7 +71,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do        json(conn, response)      else -      _error -> json(conn, %{error: "Invalid credentials"}) +      _error -> +        put_status(conn, 400) +        |> json(%{error: "Invalid credentials"})      end    end @@ -86,12 +83,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do          conn,          %{"grant_type" => "password", "name" => name, "password" => password} = params        ) do -    with %App{} = app <- -           Repo.get_by( -             App, -             client_id: params["client_id"], -             client_secret: params["client_secret"] -           ), +    with %App{} = app <- get_app_from_request(conn, params),           %User{} = user <- User.get_cached_by_nickname(name),           true <- Pbkdf2.checkpw(password, user.password_hash),           {:ok, auth} <- Authorization.create_authorization(app, user), @@ -106,7 +98,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do        json(conn, response)      else -      _error -> json(conn, %{error: "Invalid credentials"}) +      _error -> +        put_status(conn, 400) +        |> json(%{error: "Invalid credentials"})      end    end @@ -115,4 +109,28 @@ defmodule Pleroma.Web.OAuth.OAuthController do      |> Base.url_decode64!(padding: false)      |> Base.url_encode64()    end + +  defp get_app_from_request(conn, params) do +    # Per RFC 6749, HTTP Basic is preferred to body params +    {client_id, client_secret} = +      with ["Basic " <> encoded] <- get_req_header(conn, "authorization"), +           {:ok, decoded} <- Base.decode64(encoded), +           [id, secret] <- +             String.split(decoded, ":") +             |> Enum.map(fn s -> URI.decode_www_form(s) end) do +        {id, secret} +      else +        _ -> {params["client_id"], params["client_secret"]} +      end + +    if client_id && client_secret do +      Repo.get_by( +        App, +        client_id: client_id, +        client_secret: client_secret +      ) +    else +      nil +    end +  end  end diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 53278431e..f346cc9af 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -9,36 +9,42 @@ defmodule Pleroma.Web.OStatus.OStatusController do    alias Pleroma.Web.ActivityPub.ActivityPubController    alias Pleroma.Web.ActivityPub.ActivityPub -  def feed_redirect(conn, %{"nickname" => nickname} = params) do -    user = User.get_cached_by_nickname(nickname) +  action_fallback(:errors) -    case get_format(conn) do -      "html" -> Fallback.RedirectController.redirector(conn, nil) -      "activity+json" -> ActivityPubController.user(conn, params) -      _ -> redirect(conn, external: OStatus.feed_path(user)) +  def feed_redirect(conn, %{"nickname" => nickname}) do +    with {_, %User{} = user} <- {:user, User.get_cached_by_nickname(nickname)} do +      case get_format(conn) do +        "html" -> Fallback.RedirectController.redirector(conn, nil) +        "activity+json" -> ActivityPubController.call(conn, :user) +        _ -> redirect(conn, external: OStatus.feed_path(user)) +      end +    else +      {:user, nil} -> {:error, :not_found}      end    end    def feed(conn, %{"nickname" => nickname} = params) do -    user = User.get_cached_by_nickname(nickname) - -    query_params = -      Map.take(params, ["max_id"]) -      |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) - -    activities = -      ActivityPub.fetch_public_activities(query_params) -      |> Enum.reverse() - -    response = -      user -      |> FeedRepresenter.to_simple_form(activities, [user]) -      |> :xmerl.export_simple(:xmerl_xml) -      |> to_string - -    conn -    |> put_resp_content_type("application/atom+xml") -    |> send_resp(200, response) +    with {_, %User{} = user} <- {:user, User.get_cached_by_nickname(nickname)} do +      query_params = +        Map.take(params, ["max_id"]) +        |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) + +      activities = +        ActivityPub.fetch_public_activities(query_params) +        |> Enum.reverse() + +      response = +        user +        |> FeedRepresenter.to_simple_form(activities, [user]) +        |> :xmerl.export_simple(:xmerl_xml) +        |> to_string + +      conn +      |> put_resp_content_type("application/atom+xml") +      |> send_resp(200, response) +    else +      {:user, nil} -> {:error, :not_found} +    end    end    defp decode_or_retry(body) do @@ -68,12 +74,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do      |> send_resp(200, "")    end -  def object(conn, %{"uuid" => uuid} = params) do +  def object(conn, %{"uuid" => uuid}) do      if get_format(conn) == "activity+json" do -      ActivityPubController.object(conn, params) +      ActivityPubController.call(conn, :object)      else        with id <- o_status_url(conn, :object, uuid), -           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id), +           {_, %Activity{} = activity} <- +             {:activity, Activity.get_create_activity_by_object_ap_id(id)},             {_, true} <- {:public?, ActivityPub.is_public?(activity)},             %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do          case get_format(conn) do @@ -82,16 +89,20 @@ defmodule Pleroma.Web.OStatus.OStatusController do          end        else          {:public?, false} -> -          conn -          |> put_status(404) -          |> json("Not found") +          {:error, :not_found} + +        {:activity, nil} -> +          {:error, :not_found} + +        e -> +          e        end      end    end    def activity(conn, %{"uuid" => uuid}) do      with id <- o_status_url(conn, :activity, uuid), -         %Activity{} = activity <- Activity.get_by_ap_id(id), +         {_, %Activity{} = activity} <- {:activity, Activity.get_by_ap_id(id)},           {_, true} <- {:public?, ActivityPub.is_public?(activity)},           %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do        case get_format(conn) do @@ -100,14 +111,18 @@ defmodule Pleroma.Web.OStatus.OStatusController do        end      else        {:public?, false} -> -        conn -        |> put_status(404) -        |> json("Not found") +        {:error, :not_found} + +      {:activity, nil} -> +        {:error, :not_found} + +      e -> +        e      end    end    def notice(conn, %{"id" => id}) do -    with %Activity{} = activity <- Repo.get(Activity, id), +    with {_, %Activity{} = activity} <- {:activity, Repo.get(Activity, id)},           {_, true} <- {:public?, ActivityPub.is_public?(activity)},           %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do        case get_format(conn) do @@ -121,9 +136,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do        end      else        {:public?, false} -> -        conn -        |> put_status(404) -        |> json("Not found") +        {:error, :not_found} + +      {:activity, nil} -> +        {:error, :not_found} + +      e -> +        e      end    end @@ -139,4 +158,16 @@ defmodule Pleroma.Web.OStatus.OStatusController do      |> put_resp_content_type("application/atom+xml")      |> send_resp(200, response)    end + +  def errors(conn, {:error, :not_found}) do +    conn +    |> put_status(404) +    |> text("Not found") +  end + +  def errors(conn, _) do +    conn +    |> put_status(500) +    |> text("Something went wrong") +  end  end diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 331efa90b..ccc6fe8e7 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -64,7 +64,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do    end    def repeat(%User{} = user, ap_id_or_id) do -    with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(ap_id_or_id, user), +    with {:ok, _announce, %{data: %{"id" => id}}} <- CommonAPI.repeat(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        {:ok, activity}      end @@ -77,14 +77,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do    end    def fav(%User{} = user, ap_id_or_id) do -    with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user), +    with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        {:ok, activity}      end    end    def unfav(%User{} = user, ap_id_or_id) do -    with {:ok, _unfav, _fav, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user), +    with {:ok, _unfav, _fav, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user),           %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do        {:ok, activity}      end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 320f2fcf4..d53dd0c44 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -8,6 +8,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    require Logger +  action_fallback(:errors) +    def verify_credentials(%{assigns: %{user: user}} = conn, _params) do      token = Phoenix.Token.sign(conn, "user socket", user.id)      render(conn, UserView, "show.json", %{user: user, token: token}) @@ -218,19 +220,22 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    end    def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do -    with {:ok, activity} <- TwitterAPI.fav(user, id) do +    with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, +         {:ok, activity} <- TwitterAPI.fav(user, id) do        render(conn, ActivityView, "activity.json", %{activity: activity, for: user})      end    end    def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do -    with {:ok, activity} <- TwitterAPI.unfav(user, id) do +    with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, +         {:ok, activity} <- TwitterAPI.unfav(user, id) do        render(conn, ActivityView, "activity.json", %{activity: activity, for: user})      end    end    def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do -    with {:ok, activity} <- TwitterAPI.repeat(user, id) do +    with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, +         {:ok, activity} <- TwitterAPI.repeat(user, id) do        render(conn, ActivityView, "activity.json", %{activity: activity, for: user})      end    end @@ -389,4 +394,16 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    defp error_json(conn, error_message) do      %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!()    end + +  def errors(conn, {:param_cast, _}) do +    conn +    |> put_status(400) +    |> json("Invalid parameters") +  end + +  def errors(conn, _) do +    conn +    |> put_status(500) +    |> json("Something went wrong") +  end  end | 
