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:
commit
f4b03f0992
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
|
||||
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
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
|
|
@ -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
|
||||
|
|
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