mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2024-12-23 00:26:30 +00:00
Add spec for AccountController.update_credentials
This commit is contained in:
parent
f80116125f
commit
260cbddc94
8 changed files with 229 additions and 16 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.ApiSpec.Helpers do
|
||||
def request_body(description, schema_ref, opts \\ []) do
|
||||
media_types = ["application/json", "multipart/form-data"]
|
||||
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]
|
||||
|
||||
content =
|
||||
media_types
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateRequest
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateResponse
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountUpdateCredentialsRequest
|
||||
|
||||
@spec open_api_operation(atom) :: Operation.t()
|
||||
def open_api_operation(action) do
|
||||
|
@ -44,7 +45,18 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
end
|
||||
|
||||
def update_credentials_operation do
|
||||
:ok
|
||||
%Operation{
|
||||
tags: ["accounts"],
|
||||
summary: "Update account credentials",
|
||||
description: "Update the user's display and preferences.",
|
||||
operationId: "AccountController.update_credentials",
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
requestBody:
|
||||
Helpers.request_body("Parameters", AccountUpdateCredentialsRequest, required: true),
|
||||
responses: %{
|
||||
200 => Operation.response("Account", "application/json", Account)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def relationships_operation do
|
||||
|
|
26
lib/pleroma/web/api_spec/schemas/account_field_attribute.ex
Normal file
26
lib/pleroma/web/api_spec/schemas/account_field_attribute.ex
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.Schemas.AccountAttributeField do
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "AccountAttributeField",
|
||||
description: "Request schema for account custom fields",
|
||||
type: :object,
|
||||
properties: %{
|
||||
name: %Schema{type: :string},
|
||||
value: %Schema{type: :string}
|
||||
},
|
||||
required: [:name, :value],
|
||||
example: %{
|
||||
"JSON" => %{
|
||||
"name" => "Website",
|
||||
"value" => "https://pleroma.com"
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
|
@ -0,0 +1,123 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.Schemas.AccountUpdateCredentialsRequest do
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountAttributeField
|
||||
require OpenApiSpex
|
||||
|
||||
OpenApiSpex.schema(%{
|
||||
title: "AccountUpdateCredentialsRequest",
|
||||
description: "POST body for creating an account",
|
||||
type: :object,
|
||||
properties: %{
|
||||
bot: %Schema{
|
||||
type: :boolean,
|
||||
description: "Whether the account has a bot flag."
|
||||
},
|
||||
display_name: %Schema{
|
||||
type: :string,
|
||||
description: "The display name to use for the profile."
|
||||
},
|
||||
note: %Schema{type: :string, description: "The account bio."},
|
||||
avatar: %Schema{
|
||||
type: :string,
|
||||
description: "Avatar image encoded using multipart/form-data",
|
||||
format: :binary
|
||||
},
|
||||
header: %Schema{
|
||||
type: :string,
|
||||
description: "Header image encoded using multipart/form-data",
|
||||
format: :binary
|
||||
},
|
||||
locked: %Schema{
|
||||
type: :boolean,
|
||||
description: "Whether manual approval of follow requests is required."
|
||||
},
|
||||
fields_attributes: %Schema{
|
||||
oneOf: [%Schema{type: :array, items: AccountAttributeField}, %Schema{type: :object}]
|
||||
},
|
||||
# NOTE: `source` field is not supported
|
||||
#
|
||||
# source: %Schema{
|
||||
# type: :object,
|
||||
# properties: %{
|
||||
# privacy: %Schema{type: :string},
|
||||
# sensitive: %Schema{type: :boolean},
|
||||
# language: %Schema{type: :string}
|
||||
# }
|
||||
# },
|
||||
|
||||
# Pleroma-specific fields
|
||||
no_rich_text: %Schema{
|
||||
type: :boolean,
|
||||
description: "html tags are stripped from all statuses requested from the API"
|
||||
},
|
||||
hide_followers: %Schema{type: :boolean, description: "user's followers will be hidden"},
|
||||
hide_follows: %Schema{type: :boolean, description: "user's follows will be hidden"},
|
||||
hide_followers_count: %Schema{
|
||||
type: :boolean,
|
||||
description: "user's follower count will be hidden"
|
||||
},
|
||||
hide_follows_count: %Schema{
|
||||
type: :boolean,
|
||||
description: "user's follow count will be hidden"
|
||||
},
|
||||
hide_favorites: %Schema{
|
||||
type: :boolean,
|
||||
description: "user's favorites timeline will be hidden"
|
||||
},
|
||||
show_role: %Schema{
|
||||
type: :boolean,
|
||||
description: "user's role (e.g admin, moderator) will be exposed to anyone in the
|
||||
API"
|
||||
},
|
||||
default_scope: %Schema{
|
||||
type: :string,
|
||||
description: "The scope returned under privacy key in Source subentity"
|
||||
},
|
||||
pleroma_settings_store: %Schema{
|
||||
type: :object,
|
||||
description: "Opaque user settings to be saved on the backend."
|
||||
},
|
||||
skip_thread_containment: %Schema{
|
||||
type: :boolean,
|
||||
description: "Skip filtering out broken threads"
|
||||
},
|
||||
allow_following_move: %Schema{
|
||||
type: :boolean,
|
||||
description: "Allows automatically follow moved following accounts"
|
||||
},
|
||||
pleroma_background_image: %Schema{
|
||||
type: :string,
|
||||
description: "Sets the background image of the user.",
|
||||
format: :binary
|
||||
},
|
||||
discoverable: %Schema{
|
||||
type: :boolean,
|
||||
description: "Discovery of this account in search results and other services is allowed."
|
||||
},
|
||||
actor_type: %Schema{type: :string, description: "the type of this account."}
|
||||
},
|
||||
example: %{
|
||||
bot: false,
|
||||
display_name: "cofe",
|
||||
note: "foobar",
|
||||
fields_attributes: [%{name: "foo", value: "bar"}],
|
||||
no_rich_text: false,
|
||||
hide_followers: true,
|
||||
hide_follows: false,
|
||||
hide_followers_count: false,
|
||||
hide_follows_count: false,
|
||||
hide_favorites: false,
|
||||
show_role: false,
|
||||
default_scope: "private",
|
||||
pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
|
||||
skip_thread_containment: false,
|
||||
allow_following_move: false,
|
||||
discoverable: false,
|
||||
actor_type: "Person"
|
||||
}
|
||||
})
|
||||
end
|
|
@ -82,7 +82,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
|
||||
plug(
|
||||
OpenApiSpex.Plug.CastAndValidate,
|
||||
[render_error: Pleroma.Web.ApiSpec.RenderError] when action == :create
|
||||
[render_error: Pleroma.Web.ApiSpec.RenderError]
|
||||
when action in [:create, :verify_credentials, :update_credentials]
|
||||
)
|
||||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
|
@ -152,9 +153,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
end
|
||||
|
||||
@doc "PATCH /api/v1/accounts/update_credentials"
|
||||
def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
||||
def update_credentials(%{assigns: %{user: original_user}, body_params: params} = conn, _params) do
|
||||
user = original_user
|
||||
|
||||
params =
|
||||
params
|
||||
|> Map.from_struct()
|
||||
|> Enum.filter(fn {_, value} -> not is_nil(value) end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
user_params =
|
||||
[
|
||||
:no_rich_text,
|
||||
|
@ -170,22 +177,22 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
:discoverable
|
||||
]
|
||||
|> Enum.reduce(%{}, fn key, acc ->
|
||||
add_if_present(acc, params, to_string(key), key, &{:ok, truthy_param?(&1)})
|
||||
add_if_present(acc, params, key, key, &{:ok, truthy_param?(&1)})
|
||||
end)
|
||||
|> add_if_present(params, "display_name", :name)
|
||||
|> add_if_present(params, "note", :bio)
|
||||
|> add_if_present(params, "avatar", :avatar)
|
||||
|> add_if_present(params, "header", :banner)
|
||||
|> add_if_present(params, "pleroma_background_image", :background)
|
||||
|> add_if_present(params, :display_name, :name)
|
||||
|> add_if_present(params, :note, :bio)
|
||||
|> add_if_present(params, :avatar, :avatar)
|
||||
|> add_if_present(params, :header, :banner)
|
||||
|> add_if_present(params, :pleroma_background_image, :background)
|
||||
|> add_if_present(
|
||||
params,
|
||||
"fields_attributes",
|
||||
:fields_attributes,
|
||||
:raw_fields,
|
||||
&{:ok, normalize_fields_attributes(&1)}
|
||||
)
|
||||
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store)
|
||||
|> add_if_present(params, "default_scope", :default_scope)
|
||||
|> add_if_present(params, "actor_type", :actor_type)
|
||||
|> add_if_present(params, :pleroma_settings_store, :pleroma_settings_store)
|
||||
|> add_if_present(params, :default_scope, :default_scope)
|
||||
|> add_if_present(params, :actor_type, :actor_type)
|
||||
|
||||
changeset = User.update_changeset(user, user_params)
|
||||
|
||||
|
@ -200,7 +207,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
|
||||
defp add_if_present(map, params, params_field, map_field, value_function \\ &{:ok, &1}) do
|
||||
with true <- Map.has_key?(params, params_field),
|
||||
{:ok, new_value} <- value_function.(params[params_field]) do
|
||||
{:ok, new_value} <- value_function.(Map.get(params, params_field)) do
|
||||
Map.put(map, map_field, new_value)
|
||||
else
|
||||
_ -> map
|
||||
|
@ -211,7 +218,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
if Enum.all?(fields, &is_tuple/1) do
|
||||
Enum.map(fields, fn {_, v} -> v end)
|
||||
else
|
||||
fields
|
||||
Enum.map(fields, fn
|
||||
%Pleroma.Web.ApiSpec.Schemas.AccountAttributeField{} = field ->
|
||||
%{"name" => field.name, "value" => field.value}
|
||||
|
||||
field ->
|
||||
field
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ defmodule Pleroma.Web.ConnCase do
|
|||
%{user: user, token: token, conn: conn}
|
||||
end
|
||||
|
||||
defp request_content_type(%{conn: conn}) do
|
||||
conn = put_req_header(conn, "content-type", "multipart/form-data")
|
||||
[conn: conn]
|
||||
end
|
||||
|
||||
defp ensure_federating_or_authenticated(conn, url, user) do
|
||||
initial_setting = Config.get([:instance, :federating])
|
||||
on_exit(fn -> Config.put([:instance, :federating], initial_setting) end)
|
||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperationTest do
|
|||
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateRequest
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountCreateResponse
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountUpdateCredentialsRequest
|
||||
|
||||
import OpenApiSpex.TestAssertions
|
||||
import Pleroma.Factory
|
||||
|
@ -31,6 +32,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperationTest do
|
|||
assert_schema(schema.example, "AccountCreateResponse", api_spec)
|
||||
end
|
||||
|
||||
test "AccountUpdateCredentialsRequest example matches schema" do
|
||||
api_spec = ApiSpec.spec()
|
||||
schema = AccountUpdateCredentialsRequest.schema()
|
||||
assert_schema(schema.example, "AccountUpdateCredentialsRequest", api_spec)
|
||||
end
|
||||
|
||||
test "AccountController produces a AccountCreateResponse", %{conn: conn} do
|
||||
api_spec = ApiSpec.spec()
|
||||
app_token = insert(:oauth_token, user: nil)
|
||||
|
@ -52,4 +59,29 @@ defmodule Pleroma.Web.ApiSpec.AccountOperationTest do
|
|||
|
||||
assert_schema(json, "AccountCreateResponse", api_spec)
|
||||
end
|
||||
|
||||
test "AccountUpdateCredentialsRequest produces an Account", %{conn: conn} do
|
||||
api_spec = ApiSpec.spec()
|
||||
token = insert(:oauth_token, scopes: ["read", "write"])
|
||||
|
||||
json =
|
||||
conn
|
||||
|> put_req_header("authorization", "Bearer " <> token.token)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch(
|
||||
"/api/v1/accounts/update_credentials",
|
||||
%{
|
||||
hide_followers_count: "true",
|
||||
hide_follows_count: "true",
|
||||
skip_thread_containment: "true",
|
||||
hide_follows: "true",
|
||||
pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
|
||||
note: "foobar",
|
||||
fields_attributes: [%{name: "foo", value: "bar"}]
|
||||
}
|
||||
)
|
||||
|> json_response(200)
|
||||
|
||||
assert_schema(json, "Account", api_spec)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
|
||||
describe "updating credentials" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
setup :request_content_type
|
||||
|
||||
test "sets user settings in a generic way", %{conn: conn} do
|
||||
res_conn =
|
||||
|
@ -237,6 +238,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
for token <- [token1, token2] do
|
||||
conn =
|
||||
build_conn()
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> put_req_header("authorization", "Bearer #{token.token}")
|
||||
|> patch("/api/v1/accounts/update_credentials", %{})
|
||||
|
||||
|
|
Loading…
Reference in a new issue