Number-only usernames are not recognized by API properly

Summary

I found that number-only usernames (like 100001, 100002) are not recognized by GitLab API properly, as API assumes number-only argument as user id (assigned orderly at signup), not username.

The reason I have number-only usernames is that my organization uses LDAP authentication for GitLab signup, which imports numeric usernames into GitLab.

Steps to reproduce

Call API with numeric SUDO argument (i.e. 100001, 100002) which is used as a username

curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --header "SUDO: 100001" "https://gitlab.example.com/api/v4/projects"

What is the current bug behavior?

Returns No user id or username for 100001.

What is the expected correct behavior?

List of projects of user 100001 (username)

Relevant logs and/or screenshots

N/A

Output of checks

N/A

Results of GitLab environment info

System information
System:
Current User:   git
Using RVM:      no
Ruby Version:   2.3.3p222
Gem Version:    2.6.6
Bundler Version:1.13.7
Rake Version:   10.5.0
Redis Version:  3.2.5
Sidekiq Version:4.2.7

GitLab information
Version:        8.17.4
Revision:       3d2890c
Directory:      /opt/gitlab/embedded/service/gitlab-rails
DB Adapter:     postgresql
URL:            https://gitlab
HTTP Clone URL: https://gitlab/some-group/some-project.git
SSH Clone URL:  git@gitlab:some-group/some-project.git
Using LDAP:     yes
Using Omniauth: no

GitLab Shell
Version:        4.1.1
Repository storage paths:
- default:      /var/opt/gitlab/git-data/repositories
Hooks:          /opt/gitlab/embedded/service/gitlab-shell/hooks/
Git:            /opt/gitlab/embedded/bin/git

Results of GitLab application Check

N/A

Possible fixes

(If you can, link to the line of code that might be responsible for the problem)

Here are relevant functions I found.

find_user from /lib/api/helpers.rb

    def find_user(id)
      if id =~ /^\d+$/
        User.find_by(id: id)
      else
        User.find_by(username: id)
      end
    end

find_project from /lib/api/helpers.rb

    def find_project(id)
      if id =~ /^\d+$/
        Project.find_by(id: id)
      else
        Project.find_by_full_path(id)
      end
    end

sudo from /lib/api/helpers.rb

    def sudo!
      return unless sudo_identifier
      return unless initial_current_user
      unless initial_current_user.is_admin?
        forbidden!('Must be admin to use sudo')
      end
      # Only private tokens should be used for the SUDO feature
      unless private_token == initial_current_user.private_token
        forbidden!('Private token must be specified in order to use sudo')
      end
      sudoed_user = find_user(sudo_identifier)
      if sudoed_user
        @current_user = sudoed_user
      else
        not_found!("No user id or username for: #{sudo_identifier}")
      end
    end

As you see the functions assumes a numeric argument as a user id. It would be possible to add some additional arguments to specify the given number is weather user id or username I think.

Assignee Loading
Time tracking Loading