Add Avatar API
This commit is contained in:
parent
fe0ebf76c4
commit
c8f0e4b5da
6 changed files with 172 additions and 0 deletions
5
changelogs/unreleased/45821-avatar_api.yml
Normal file
5
changelogs/unreleased/45821-avatar_api.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add Avatar API
|
||||||
|
merge_request: 19121
|
||||||
|
author: Imre Farkas
|
||||||
|
type: added
|
33
doc/api/avatar.md
Normal file
33
doc/api/avatar.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Avatar API
|
||||||
|
|
||||||
|
> [Introduced][ce-19121] in GitLab 11.0
|
||||||
|
|
||||||
|
## Get a single avatar URL
|
||||||
|
|
||||||
|
Get a single avatar URL for a given email addres. If user with matching public
|
||||||
|
email address is not found, results from external avatar services are returned.
|
||||||
|
This endpoint can be accessed without authentication. In case public visibility
|
||||||
|
is restricted, response will be `403 Forbidden` when unauthenticated.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /avatar?email=admin@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | ------- | -------- | --------------------- |
|
||||||
|
| `email` | string | yes | Public email address of the user |
|
||||||
|
| `size` | integer | no | Single pixel dimension (since images are squares). Only used for avatar lookups at `Gravatar` or at the configured `Libravatar` server |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://gitlab.example.com/api/v4/avatar?email=admin@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[ce-19121]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19121
|
|
@ -83,6 +83,7 @@ module API
|
||||||
# Keep in alphabetical order
|
# Keep in alphabetical order
|
||||||
mount ::API::AccessRequests
|
mount ::API::AccessRequests
|
||||||
mount ::API::Applications
|
mount ::API::Applications
|
||||||
|
mount ::API::Avatar
|
||||||
mount ::API::AwardEmoji
|
mount ::API::AwardEmoji
|
||||||
mount ::API::Badges
|
mount ::API::Badges
|
||||||
mount ::API::Boards
|
mount ::API::Boards
|
||||||
|
|
21
lib/api/avatar.rb
Normal file
21
lib/api/avatar.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
module API
|
||||||
|
class Avatar < Grape::API
|
||||||
|
resource :avatar do
|
||||||
|
desc 'Return avatar url for a user' do
|
||||||
|
success Entities::Avatar
|
||||||
|
end
|
||||||
|
params do
|
||||||
|
requires :email, type: String, desc: 'Public email address of the user'
|
||||||
|
optional :size, type: Integer, desc: 'Single pixel dimension for Gravatar images'
|
||||||
|
end
|
||||||
|
get do
|
||||||
|
forbidden!('Unauthorized access') unless can?(current_user, :read_users_list)
|
||||||
|
|
||||||
|
user = User.find_by_public_email(params[:email])
|
||||||
|
user ||= User.new(email: params[:email])
|
||||||
|
|
||||||
|
present user, with: Entities::Avatar, size: params[:size]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -692,6 +692,12 @@ module API
|
||||||
expose :notes, using: Entities::Note
|
expose :notes, using: Entities::Note
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Avatar < Grape::Entity
|
||||||
|
expose :avatar_url do |avatarable, options|
|
||||||
|
avatarable.avatar_url(only_path: false, size: options[:size])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class AwardEmoji < Grape::Entity
|
class AwardEmoji < Grape::Entity
|
||||||
expose :id
|
expose :id
|
||||||
expose :name
|
expose :name
|
||||||
|
|
106
spec/requests/api/avatar_spec.rb
Normal file
106
spec/requests/api/avatar_spec.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe API::Avatar do
|
||||||
|
let(:gravatar_service) { double('GravatarService') }
|
||||||
|
|
||||||
|
describe 'GET /avatar' do
|
||||||
|
context 'avatar uploaded to GitLab' do
|
||||||
|
context 'user with matching public email address' do
|
||||||
|
let(:user) { create(:user, :with_avatar, email: 'public@example.com', public_email: 'public@example.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the avatar url' do
|
||||||
|
get api('/avatar'), { email: 'public@example.com' }
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'no user with matching public email address' do
|
||||||
|
before do
|
||||||
|
expect(GravatarService).to receive(:new).and_return(gravatar_service)
|
||||||
|
expect(gravatar_service).to(
|
||||||
|
receive(:execute)
|
||||||
|
.with('private@example.com', nil, 2, { username: nil })
|
||||||
|
.and_return('https://gravatar'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the avatar url from Gravatar' do
|
||||||
|
get api('/avatar'), { email: 'private@example.com' }
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(json_response['avatar_url']).to eq('https://gravatar')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'avatar uploaded to Gravatar' do
|
||||||
|
context 'user with matching public email address' do
|
||||||
|
let(:user) { create(:user, email: 'public@example.com', public_email: 'public@example.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user
|
||||||
|
|
||||||
|
expect(GravatarService).to receive(:new).and_return(gravatar_service)
|
||||||
|
expect(gravatar_service).to(
|
||||||
|
receive(:execute)
|
||||||
|
.with('public@example.com', nil, 2, { username: user.username })
|
||||||
|
.and_return('https://gravatar'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the avatar url from Gravatar' do
|
||||||
|
get api('/avatar'), { email: 'public@example.com' }
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(json_response['avatar_url']).to eq('https://gravatar')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'no user with matching public email address' do
|
||||||
|
before do
|
||||||
|
expect(GravatarService).to receive(:new).and_return(gravatar_service)
|
||||||
|
expect(gravatar_service).to(
|
||||||
|
receive(:execute)
|
||||||
|
.with('private@example.com', nil, 2, { username: nil })
|
||||||
|
.and_return('https://gravatar'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the avatar url from Gravatar' do
|
||||||
|
get api('/avatar'), { email: 'private@example.com' }
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(json_response['avatar_url']).to eq('https://gravatar')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'public visibility level restricted' do
|
||||||
|
let(:user) { create(:user, :with_avatar, email: 'public@example.com', public_email: 'public@example.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user
|
||||||
|
|
||||||
|
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when authenticated' do
|
||||||
|
it 'returns the avatar url' do
|
||||||
|
get api('/avatar', user), { email: 'public@example.com' }
|
||||||
|
|
||||||
|
expect(response.status).to eq 200
|
||||||
|
expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when unauthenticated' do
|
||||||
|
it_behaves_like '403 response' do
|
||||||
|
let(:request) { get api('/avatar'), { email: 'public@example.com' } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue