Allow users to update their Account in the API (#1179)
* Allow users to update their Account in the API It would be nice for API clients to be able to allow users to update their accounts without having to wrap Mastodon in a web view. This patch adds an API endpoint to let users submit a PATCH for their account. Signed-off-by: David Celis <me@davidcel.is> * Add /api/v1/accounts/update_credentials to the API docs Signed-off-by: David Celis <me@davidcel.is>
This commit is contained in:
parent
ea6c930c04
commit
d4fe6cd2bf
|
@ -1,10 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::AccountsController < ApiController
|
class Api::V1::AccountsController < ApiController
|
||||||
before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute, :update_credentials]
|
||||||
before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
|
||||||
|
before_action -> { doorkeeper_authorize! :write }, only: [:update_credentials]
|
||||||
before_action :require_user!, except: [:show, :following, :followers, :statuses]
|
before_action :require_user!, except: [:show, :following, :followers, :statuses]
|
||||||
before_action :set_account, except: [:verify_credentials, :suggestions, :search]
|
before_action :set_account, except: [:verify_credentials, :update_credentials, :suggestions, :search]
|
||||||
|
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
|
@ -15,6 +16,14 @@ class Api::V1::AccountsController < ApiController
|
||||||
render action: :show
|
render action: :show
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_credentials
|
||||||
|
@account = current_user.account
|
||||||
|
|
||||||
|
@account.update_attributes!(account_params)
|
||||||
|
|
||||||
|
render action: :show
|
||||||
|
end
|
||||||
|
|
||||||
def following
|
def following
|
||||||
results = Follow.where(account: @account).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
results = Follow.where(account: @account).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
||||||
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
||||||
|
@ -135,4 +144,8 @@ class Api::V1::AccountsController < ApiController
|
||||||
def statuses_pagination_params(core_params)
|
def statuses_pagination_params(core_params)
|
||||||
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def account_params
|
||||||
|
@account_params ||= params.permit(:display_name, :note, :avatar, :header)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -163,6 +163,7 @@ Rails.application.routes.draw do
|
||||||
collection do
|
collection do
|
||||||
get :relationships
|
get :relationships
|
||||||
get :verify_credentials
|
get :verify_credentials
|
||||||
|
patch :update_credentials
|
||||||
get :search
|
get :search
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,17 @@ Returns an [Account](#account).
|
||||||
|
|
||||||
Returns the authenticated user's [Account](#account).
|
Returns the authenticated user's [Account](#account).
|
||||||
|
|
||||||
|
#### Updating the current user:
|
||||||
|
|
||||||
|
PATCH /api/v1/accounts/update_credentials
|
||||||
|
|
||||||
|
Form data:
|
||||||
|
|
||||||
|
- `display_name`: The name to display in the user's profile
|
||||||
|
- `note`: A new biography for the user
|
||||||
|
- `avatar`: A base64 encoded image to display as the user's avatar (e.g. `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...`)
|
||||||
|
- `header`: A base64 encoded image to display as the user's header image (e.g. `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUoAAADrCAYAAAA...`)
|
||||||
|
|
||||||
#### Getting an account's followers:
|
#### Getting an account's followers:
|
||||||
|
|
||||||
GET /api/v1/accounts/:id/followers
|
GET /api/v1/accounts/:id/followers
|
||||||
|
|
|
@ -24,6 +24,39 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'PATCH #update_credentials' do
|
||||||
|
it 'returns http success' do
|
||||||
|
expect(user.account.avatar).not_to exist
|
||||||
|
expect(user.account.header).not_to exist
|
||||||
|
|
||||||
|
avatar = File.read(Rails.root.join('app', 'assets', 'images', 'logo.png'))
|
||||||
|
header = File.read(Rails.root.join('app', 'assets', 'images', 'mastodon-getting-started.png'))
|
||||||
|
params = {
|
||||||
|
display_name: "Alice Isn't Dead",
|
||||||
|
note: "Hi!\n\nToot toot!",
|
||||||
|
avatar: "data:image/png;base64,#{Base64.encode64(avatar)}",
|
||||||
|
header: "data:image/png;base64,#{Base64.encode64(header)}"
|
||||||
|
}
|
||||||
|
patch :update_credentials, params: params
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
|
||||||
|
expect(user.account.display_name).to eq("Alice Isn't Dead")
|
||||||
|
expect(user.account.note).to eq("Hi!\n\nToot toot!")
|
||||||
|
expect(user.account.avatar).to exist
|
||||||
|
expect(user.account.header).to exist
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'respects Account validations' do
|
||||||
|
note = "This is too long. " * 10
|
||||||
|
error = { error: 'The account could not be updated: Note is too long (maximum is 160 characters)' }.to_json
|
||||||
|
patch :update_credentials, params: { note: note }
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(response.body).to eq(error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET #statuses' do
|
describe 'GET #statuses' do
|
||||||
it 'returns http success' do
|
it 'returns http success' do
|
||||||
get :statuses, params: { id: user.account.id }
|
get :statuses, params: { id: user.account.id }
|
||||||
|
|
Reference in a new issue