Protected Branches API fails if adding user

Summary

Making API calls to protected branches will fail if you supply the same user in both the allowed_to_push and merge_access_level parameters.

https://docs.gitlab.com/ee/api/protected_branches.html#protect-repository-branches

What is the current bug behavior / reproduce?

Example Curl call:

curl --request POST --header $TOKEN http://$URI/api/v4/projects/70/protected_branches -H "Content-Type: application/json" -d '{"name":"stable", "allowed_to_merge": [{"user_id": 1}], "allowed_to_push": [{"user_id": 1}] }'

The result is a 422:

Cannot add users or groups unless they have access to the project 

What is the expected correct behavior?

Call should be successful and return and new access levels:

{"name":"stable","push_access_levels":[{"access_level":40,"access_level_description":"Administrator","user_id":1,"group_id":null}],"merge_access_levels":[{"access_level":40,"access_level_description":"Administrator","user_id":1,"group_id":null}]}

Reproduced on 10.6.2

Possible fixes

It looks like the validation/error is coming from the api_service.rb

def users_accessible?
  user_ids = @merge_params.user_ids + @push_params.user_ids 
  allowed_users = @project.team.users.where(id: user_ids)

  user_ids.count == allowed_users.count
end

Both merge_params and push_params will include the user id (as you want it on both). Therefore user_ids == [1,1] so the user_ids.count == allowed_users.count is actually [1,1].count == [1].count and failling the validation (I think this may effect the group as well).

Patched a test system and this seemed to work correctly:

def users_accessible?
  user_ids = @merge_params.user_ids + @push_params.user_ids 
  allowed_users = @project.team.users.where(id: user_ids)

  user_ids.uniq.count == allowed_users.count
end

Internal ZD: https://gitlab.zendesk.com/agent/tickets/93319

Edited by Davin Walker