Merge branch '45821-avatar_api' into 'master'

Add Avatar API

Closes #45821

See merge request gitlab-org/gitlab-ce!19121
This commit is contained in:
Rémy Coutable 2018-06-06 10:50:34 +00:00
commit f4b03f0992
6 changed files with 172 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
title: Add Avatar API
merge_request: 19121
author: Imre Farkas
type: added

33
doc/api/avatar.md Normal file
View 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

View file

@ -83,6 +83,7 @@ module API
# Keep in alphabetical order
mount ::API::AccessRequests
mount ::API::Applications
mount ::API::Avatar
mount ::API::AwardEmoji
mount ::API::Badges
mount ::API::Boards

21
lib/api/avatar.rb Normal file
View 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

View file

@ -694,6 +694,12 @@ module API
expose :notes, using: Entities::Note
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
expose :id
expose :name

View 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