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

时间:2016-04-15 14:52:28

标签: python oauth authorization gitlab mattermost

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?

1 个答案:

答案 0 :(得分:9)

实际上,我终于通过模仿浏览器的行为来实现这一目标,但我仍然对一个更通用的解决方案感兴趣,它不涉及解析任何gitlab服务器&#39 ; 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