Visitar URL original
Credential-based login is broken after removal of /session endpoint · Issue #380 · python-gitlab/python-gitlab · GitHub
Skip to content

Credential-based login is broken after removal of /session endpoint #380

Description

@GhostLyrics

Remove Session API now that private tokens are removed from user API endpoints.

/api/v4/session has been removed and it is currently not possible to log in via email/password combination. [Deprecation notice, Changelog]

I use this to completely automate testing (e.g. create a GitLab instance, set a password for root, run some tests, tear everything down).

wget http://gitlab/api/v4/session
--2017-11-23 23:06:57--  http://gitlab/api/v4/session
Resolving gitlab (gitlab)... 192.168.34.151, 192.168.34.151
Connecting to gitlab (gitlab)|192.168.34.151|:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2017-11-23 23:06:57 ERROR 404: Not Found.
import gitlab
s = gitlab.Gitlab('http://localhost',email='root',password='some_test_password',api_version=4)
s.auth()

Traceback (most recent call last):
  File "<input>", line 1, in <module>
    s.auth()
  File "/Users/ghostlyrics/.pyenv/versions/3.5.3/lib/python3.5/site-packages/gitlab/__init__
.py", line 197, in auth
    self._credentials_auth()
  File "/Users/ghostlyrics/.pyenv/versions/3.5.3/lib/python3.5/site-packages/gitlab/__init__
.py", line 216, in _credentials_auth
    r = self.http_post('/session', data)
  File "/Users/ghostlyrics/.pyenv/versions/3.5.3/lib/python3.5/site-packages/gitlab/__init__
.py", line 806, in http_post
    post_data=post_data, files=files, **kwargs)
  File "/Users/ghostlyrics/.pyenv/versions/3.5.3/lib/python3.5/site-packages/gitlab/__init__
.py", line 713, in http_request
    response_body=result.content)
gitlab.exceptions.GitlabHttpError: 404: b'{"error":"404 Not Found"}'

self = <gitlab.Gitlab object at 0x7f28dfd66da0>, verb = 'post', path = '/session', query_data = {'email': 'root', 'password': 'some_test_password'}, post_data = {}, streamed = False
files = None, kwargs = {}, sanitized_url = <function Gitlab.http_request.<locals>.sanitized_url at 0x7f28e17879d8>, url = 'http://localhost/api/v4/session'
params = {'email': 'root', 'password': 'some_test_password'}, opts = {'auth': None, 'headers': {'Content-type': 'application/json'}}, verify = True, timeout = None, req = <Request [post]>

    def http_request(self, verb, path, query_data={}, post_data={},
                     streamed=False, files=None, **kwargs):
        """Make an HTTP request to the Gitlab server.

            Args:
                verb (str): The HTTP method to call ('get', 'post', 'put',
                            'delete')
                path (str): Path or full URL to query ('/projects' or
                            'http://whatever/v4/api/projecs')
                query_data (dict): Data to send as query parameters
                post_data (dict): Data to send in the body (will be converted to
                                  json)
                streamed (bool): Whether the data should be streamed
                **kwargs: Extra data to make the query (e.g. sudo, per_page, page)

            Returns:
                A requests result object.

            Raises:
                GitlabHttpError: When the return code is not 2xx
            """

        def sanitized_url(url):
            parsed = six.moves.urllib.parse.urlparse(url)
            new_path = parsed.path.replace('.', '%2E')
            return parsed._replace(path=new_path).geturl()

        url = self._build_url(path)
        params = query_data.copy()
        params.update(kwargs)
        opts = self._get_session_opts(content_type='application/json')

        # don't set the content-type header when uploading files
        if files is not None:
            del opts["headers"]["Content-type"]

        verify = opts.pop('verify')
        timeout = opts.pop('timeout')

        # Requests assumes that `.` should not be encoded as %2E and will make
        # changes to urls using this encoding. Using a prepped request we can
        # get the desired behavior.
        # The Requests behavior is right but it seems that web servers don't
        # always agree with this decision (this is the case with a default
        # gitlab installation)
        req = requests.Request(verb, url, json=post_data, params=params,
                               files=files, **opts)
        prepped = self.session.prepare_request(req)
        prepped.url = sanitized_url(prepped.url)
        result = self.session.send(prepped, stream=streamed, verify=verify,
                                   timeout=timeout)

        if 200 <= result.status_code < 300:
            return result

        try:
            error_message = result.json()['message']
        except (KeyError, ValueError, TypeError):
            error_message = result.content

        if result.status_code == 401:
            raise GitlabAuthenticationError(response_code=result.status_code,
                                            error_message=error_message,
                                            response_body=result.content)

        raise GitlabHttpError(response_code=result.status_code,
                              error_message=error_message,
>                             response_body=result.content)
E       gitlab.exceptions.GitlabHttpError: 404: b'{"error":"404 Not Found"}'

Activity

  1. sslaven3 commented on Nov 27, 2017

    @sslaven3

    I'm experiencing this as well. Our GitLab CE was just updated to 10.2.1 this last weekend and now gl.auth throws a 404. I'm using the latest version of python-gitlab.

  2. gpocentek commented on Nov 28, 2017

    @gpocentek
    Contributor

    Without the /session endpoint python-gitlab cannot do password authentication.

    One possible solution is to use cookie authentication:

    1. use python-requests to authenticate on the web UI (POST on /users/sign_in)
    2. get the cookie from the answer
    3. create a requests.Session object and setup the cookies
    4. use the session object to create a Gitlab connexion
    5. create/get a token from the API
    6. create a new gitlab object with token authentication

    I have not tested this solution but according to Gitlab docs cookie authentication is supposed to work.

  3. ViachaslauKabak commented on Nov 29, 2017

    @ViachaslauKabak

    Experiencing this too as soon as upgraded to 10.2

  4. melissaulaval commented on Dec 3, 2017

    @melissaulaval

    I am experiencing the same problem even I didn't upgrade gitlab. It seems the commands:

    s = gitlab.Gitlab('https://gitlab.com',email='my_username',password='my_password')
    s.auth()

    not working.

    Thank you for the response!

  5. ahsobhi commented on Dec 12, 2017

    @ahsobhi

    im experiencing the same issue with our updated Gitlab instance to 10.2

  6. gpocentek commented on Dec 12, 2017

    @gpocentek
    Contributor

    GitLab has decided to remove the /session endpoint so there is nothing much I can do.

    I've successfully used cookie authentication on gitlab.com with the following code: https://gist.github.com/gpocentek/bd4c3fbf8a6ce226ebddc4aad6b46c0a

    I'll add some documentation to python-gitlab.

  7. ViachaslauKabak commented on Dec 12, 2017

    @ViachaslauKabak

    @gpocentek , do you mean that there will be only token authentication since GL10.2?

  8. ViachaslauKabak commented on Dec 12, 2017

    @ViachaslauKabak

    found in GL changelog 10.2
    Remove Session API now that private tokens are removed from user API endpoints.

  9. GhostLyrics commented on Dec 12, 2017

    @GhostLyrics
    ContributorAuthor

    @gpocentek Do you plan on integrating this workaround into python-gitlab?

  10. gpocentek commented on Dec 13, 2017

    @gpocentek
    Contributor

    @GhostLyrics I'm afraid not, because there are multiple ways to authenticate using the web UI (LDAP and DB authentication use different endpoints for instance), and I'm not really sure that things will not change and break.

    GitLab devs clearly want to make personal token authentication the default. This makes full automation more complicated (functional testing for python-gitlab needs to be updated as well), but it also makes sense.

    My plan to resolve this issue is to update the documentation with code examples, to make initial setup of tokens easier.

  11. ahsobhi commented on Dec 13, 2017

    @ahsobhi

    @gpocentek Thank you for your efforts and the code sample, it works like a charm, now i do agree with you that things might change and break, GitLab undergoes major changes every few months, adding new features and functionality, we've been using it since it was v4 and it has come a long long way

  12. sslaven3 commented on Dec 13, 2017

    @sslaven3

    @gpocentek - Thanks for the update Gauvain. I see now that it's just a change in GitLab's code, and nothing you can do about it. The module is great though, and I appreciate your work. I've converted to using a private token, which I programmatically pull from a password management system using my credentials. For others, if you don't have a secure password system, you can use a token of an account with less privileges on your GitLab projects, and generate a token for that account to pull code. It's not perfect, but it's an option.

  13. slonopotamus commented on Dec 19, 2017

    @slonopotamus

    Hi! We've also hit this problem in git-as-svn/git-as-svn#154. Did anyone try to file a bugreport to GitLab so they would consider returning back password-based authentication API? I'm also interested in GitLab ticket that triggered removal of /session API.

  14. slonopotamus commented on Dec 19, 2017

    @slonopotamus

    Okay, it is possible to perform login/password -> token authentication even with GitLab 10.2: https://docs.gitlab.com/ce/api/oauth2.html#resource-owner-password-credentials

    That's how it was done in git-as-svn (Java): slonopotamus/git-as-svn@8a4d067

    So I think you should reopen this issue and reimplement login/password authentication via OAuth2 too.

  15. locked as resolved and limited conversation to collaborators on Nov 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions