Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using mattermost api via gitlab oauth as an end-user with username and password (no client_secret)

In our team we use gitlab (https://git.example) and the bundled mattermost chat (https://chat.example).

For mattermost we'd like to have a dedicated bot-user (the web hooks have limitations wrt. private channels etc.), which actually logs in exactly like a normal user.

We created that user in gitlab, and can log into our chat with it via chrome (chat login redir --> gitlab oauth, type in username and pw --> redir back to chat --> authed).

Now i searched for python libraries that can actually do this, but i can only find some which require a client_id and client_secret... From my understanding (please correct me if i'm wrong) this is not what we're searching for, as we don't want to create another application to auth via gitlab, but login to our chat (which already has an id (known) and a secret (unknown)) as a user via gitlab.

As we couldn't find such a lib, we also inspected the network requests in chrome and tried to re-create it in python via requests, but can't get it to work (needless to say it involves parsing html and csrf tokens)...

Taking yet another attempt and a lot of guesswork we tried to acquire an access_token manually via

client_id = 'the one of mattermost in our gitlab'
user = 'username'
pw = 'password'
r = requests.post(
    'https://git.example/oauth/token',
    data={
        "grant_type": "password",
        "username": user,
        "password": pw,
        "client_id": client_id,
    }
)
access_token = r.json()['access_token']

This seems to work (and the token looks good), but using it in the mattermost API only results in a 401:

ri = requests.get(
    'https://chat.example/api/v1/users/me',
    headers={'Authorization': 'Bearer ' + access_token}
)

ri.status_code, ri.json()
(401,
 {u'detailed_error': u'token=...xxx...',
  u'id': u'api.context.session_expired.app_error',
  u'is_oauth': False,
  u'message': u'Invalid or expired session, please login again.',
  u'request_id': u'...yyy...',
  u'status_code': 401})

Sadly http://docs.mattermost.com/developer/web-service.html#oauth2 currently doesn't shed more light into this, which is why I'm asking here. Did i maybe miss something obvious to "activate" that access_token in mattermost?

like image 680
Jörn Hees Avatar asked Apr 15 '16 14:04

Jörn Hees


1 Answers

Actually i finally got this running by imitating the browser's behavior as follows, but i'd still be interested in a more generic solution that doesn't involve parsing any of the gitlab server's html...:

import requests
from pyquery import PyQuery as pq

client_id = '...your_mattermost_client_id...'
user = '...username...'
pw = '...userpass...'

gitlab = 'https://git.example'
chat = 'https://chat.example'
team = '/your_team'

r = requests.get(
    chat + team + '/login/gitlab'
)
q = pq(r.content)
csrf_token = q('#new_ldap_user input[name="authenticity_token"]')[0].value  # watch out, several tokens for ldap vs. normal login, inspect the page to find correct one

r2 = requests.post(
    gitlab + '/users/auth/ldapmain/callback',  # or whatever the browser callback for your auth-method was
    cookies=r.cookies,
    data={
        'authenticity_token': csrf_token,
        'username': user,
        'password': pw,
    }
)

# print [h.url for h in r2.history] + [r2.url]  # to check the redirects

me = requests.get(
    chat + '/api/v1/users/me',
    cookies=r2.cookies,
)
print me.json()  # if everything went well you're now authorized

# remember to set cookies in the follow-up requests
like image 102
Jörn Hees Avatar answered Oct 17 '22 20:10

Jörn Hees