diff options
author | Timothy Andrew <mail@timothyandrew.net> | 2017-06-26 10:20:30 +0300 |
---|---|---|
committer | Timothy Andrew <mail@timothyandrew.net> | 2017-06-26 10:20:30 +0300 |
commit | 20f679d620380b5b5e662b790c76caf256867b01 (patch) | |
tree | 186b69dfdb75768e5dc75bf01cb3092e1c8b06b7 /lib/api/users.rb | |
parent | f0886918845f8292889db7e30033b7051147f3b0 (diff) |
Allow unauthenticated access to the `/api/v4/users` API.
- The issue filtering frontend code needs access to this API for non-logged-in
users + public projects. It uses the API to fetch information for a user by
username.
- We don't authenticate this API anymore, but instead - if the `current_user` is
not present:
- Verify that the `username` parameter has been passed. This disallows an
unauthenticated user from grabbing a list of all users on the instance. The
`UsersFinder` class performs an exact match on the `username`, so we are
guaranteed to get 0 or 1 users.
- Verify that the resulting user (if any) is accessible to be viewed publicly
by calling `can?(current_user, :read_user, user)`
Diffstat (limited to 'lib/api/users.rb')
-rw-r--r-- | lib/api/users.rb | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/api/users.rb b/lib/api/users.rb index c10e3364382..34619c90d8b 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -4,7 +4,7 @@ module API before do allow_access_with_scope :read_user if request.get? - authenticate! + authenticate! unless route_matches_description?("Get the list of users") end resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do @@ -51,15 +51,26 @@ module API use :pagination end get do - unless can?(current_user, :read_users_list) - render_api_error!("Not authorized.", 403) - end - authenticated_as_admin! if params[:external].present? || (params[:extern_uid].present? && params[:provider].present?) users = UsersFinder.new(current_user, params).execute - entity = current_user.admin? ? Entities::UserWithAdmin : Entities::UserBasic + authorized = + if current_user + can?(current_user, :read_users_list) + else + # When `current_user` is not present, require that the `username` + # parameter is passed, to prevent an unauthenticated user from accessing + # a list of all the users on the GitLab instance. `UsersFinder` performs + # an exact match on the `username` parameter, so we are guaranteed to + # get either 0 or 1 `users` here. + params[:username].present? && + users.all? { |user| can?(current_user, :read_user, user) } + end + + render_api_error!("Not authorized.", 403) unless authorized + + entity = current_user.try(:admin?) ? Entities::UserWithAdmin : Entities::UserBasic present paginate(users), with: entity end |