Skip to content

Commit

Permalink
Allow users to update their Account in the API (mastodon#1179)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
davidcelis authored and Gargron committed Apr 9, 2017
1 parent ea6c930 commit d4fe6cd
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
17 changes: 15 additions & 2 deletions app/controllers/api/v1/accounts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# frozen_string_literal: true

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! :write }, only: [:update_credentials]
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

Expand All @@ -15,6 +16,14 @@ def verify_credentials
render action: :show
end

def update_credentials
@account = current_user.account

@account.update_attributes!(account_params)

render action: :show
end

def following
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
Expand Down Expand Up @@ -135,4 +144,8 @@ def pagination_params(core_params)
def statuses_pagination_params(core_params)
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
end

def account_params
@account_params ||= params.permit(:display_name, :note, :avatar, :header)
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
collection do
get :relationships
get :verify_credentials
patch :update_credentials
get :search
end

Expand Down
11 changes: 11 additions & 0 deletions docs/Using-the-API/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ Returns an [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:

GET /api/v1/accounts/:id/followers
Expand Down
33 changes: 33 additions & 0 deletions spec/controllers/api/v1/accounts_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,39 @@
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
it 'returns http success' do
get :statuses, params: { id: user.account.id }
Expand Down

0 comments on commit d4fe6cd

Please sign in to comment.