python-gitlab / python-gitlab

A python wrapper for the GitLab API.

Home Page:https://python-gitlab.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Basic Authentication via .netrc does not work

trivialkettle opened this issue · comments

Description of the problem, including code/CLI snippet

I try to authenticate via .netrc over API / CLI

Expected Behavior

Authentication should work

Actual Behavior

I get only 401 errors.
Debug output from python API:

>>> client = gitlab.Gitlab(url="gitlab.company.com")
>>> client.auth()
DEBUG:http.client:send: b'GET /api/v4/user HTTP/1.1\r\nHost: gitlab.company.com\r\nUser-Agent: python-gitlab/4.4.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-type: application/json\r\nAuthorization: Basic <base64>\r\n\r\n'

The base64 encoded string equals to <login>:<password> from ~.netrc.
The same Token works in this request:

curl --header "PRIVATE-TOKEN: <token>" "https://gitlab.company.com/api/v4/projects"

Specifications

  • python-gitlab version: 4.4.0
  • API version you are using (v3/v4): v4
  • Gitlab server version (or gitlab.com): v16.8.0

@trivialkettle I think GitLab no longer supports basic authentication for normal API usage, only specific endpoints like some types of packages.

Are you able to use basic authentication with curl for the endpoint you show above?

@nejch

curl -vv --header "Authorization: Basic <base64>" "https://gitlab.company.com/api/v4/user"

Returns 401

Though

curl -vv --header "Authorization: Basic <base64>" "https://gitlab.company.com/api/v4/projects"

returns 200 and an empty list.

@trivialkettle is this then consistent with the behavior you see in python-gitlab? i.e. if you skip gl.auth() which calls the user endpoint, do you get an empty response as well?

@nejch
Yes this is consistent.

>>> client = gitlab.Gitlab(url="gitlab.company.com")
>>> client.projects.list()
[]

Thanks @trivialkettle in that case I think there's not much we can do here, maybe we can document the upstream limitation, but I see they have a lot of other similar issues related to inconsistencies in auth and endpoints (see e.g. https://gitlab.com/gitlab-org/gitlab/-/issues/296041). If you like you could also file an issue upstream to see if this is intentional 🙇

@nejch
A workaround could be to avoid basic auth from requests and use e.g. Authentication: Bearer <token> as shown in https://docs.gitlab.com/ee/api/rest/#authentication

Hmm, technically we could do this but IMO it deviates from the requests behavior in https://requests.readthedocs.io/en/latest/user/authentication/#netrc-authentication (as well as others supporting netrc such as httpx & co.), and I feel like we might be relying on undocumented GitLab behavior as well.

Would https://docs.python.org/3/library/netrc.html be an alternative maybe?

Authentication: Bearer <token> is documented: https://docs.gitlab.com/ee/api/rest/#personalprojectgroup-access-tokens

curl --header "Authorization: Bearer <your_access_token>" "https://gitlab.example.com/api/v4/projects"

So I don't see how we could rely on undocumented behavior.

deviates from the requests behavior

Yes, thats why I would not so happy with that.

Would https://docs.python.org/3/library/netrc.html be an alternative maybe?

For API usage yes, but I would like to use the CLI with .netrc support.

@nejch Yes this is consistent.

>>> client = gitlab.Gitlab(url="gitlab.company.com")
>>> client.projects.list()
[]

To be clear, the behavior is consistent, but the result is wrong. With Authentication: Bearer <token> I get all my projects,

@nejch Yes this is consistent.

>>> client = gitlab.Gitlab(url="gitlab.company.com")
>>> client.projects.list()
[]

To be clear, the behavior is consistent, but the result is wrong. With Authentication: Bearer <token> I get all my projects,

@trivialkettle I would consider this an upstream issue (/user accepts bearer token auth but not basic auth, whereas other endpoints do, but return different results -EDIT seems like /projects actually works without authentication, so maybe it's not really accepted anyway).We just want to avoid making workarounds in the client for bugs in the API itself, would be best to fix it upstream instead.

But I see what you mean with the CLI, if we're forcing unwanted API calls then that's wrong, but I need to check if that's always the behavior.