Commit f4b03f09 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch '45821-avatar_api' into 'master'

Add Avatar API

Closes #45821

See merge request gitlab-org/gitlab-ce!19121
parents 71242199 c8f0e4b5
---
title: Add Avatar API
merge_request: 19121
author: Imre Farkas
type: added
# 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 ...@@ -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
......
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
...@@ -694,6 +694,12 @@ module API ...@@ -694,6 +694,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
......
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment