Mattermost, Inc.

Launch queries on the Mattermost API, having Gitlab as authentication provider

Hello,

I have Gitlab on one side, which serves me as an authentication provider.
I have Mattermost on the other side, with which I would use the API, to automatically save commands.
Finally, I have a Flask server (python) which is used to execute commands.

To save a single command, I go through the Mattermost interface, manually configuring the command.
Only, I will have several orders in the near future, and I would like to save them automatically. I already know what queries I have to perform for this (https://github.com/mattermost/platform/blob/master/api/command.go#L47).

What I have trouble with is the authentication of the Flask server in Mattermost.
If I understood everything, I must have a user token in Gitlab. I created it via Profile Settings> Access Tokens.

Only, when I run my queries on the Mattermost API with this token, Mattermost does not recognize it.

For example :

`` `

It works, I get list of all gitlab projects

Curl - header “PRIVATE-TOKEN: myTokenABCD” “https://gitlab.mydomain.com/api/v3/projects

I have a message that my session is invalid or expired

Curl - header “Authorization: Bearer myTokenABCD” “https://mattermost.mydomain.com/api/v3/users/me
`` `

So I do not understand how to properly authenticate to Mattermost via a gitlab token. And so I can not continue my program further.

Thank you all for reading!

1 Like

Hi @serge

Let me start by saying that the private token that gitlab returns its not the same one as Mattermost, you need to authenticate the user against Mattermost and then use the Token returned (can be found in the header).

For more info on how to make Authorized request to the Mattermost API please see the API documentation

@serge or @elias
I’m not sure if this is applicable to my use-case, but I have set up mattermost within gitlab (ie. the omnibus edition, I believe), as per this demo.

In this instance, Gitlab is used for authentication when entering the Mattermost GUI. While that still creates a ‘user’ (corresponding to the Gitlab user) in the mattermost database, it doesn’t appear to assign a password … and so running this login in order to get a session token returned in the header is no longer working.

curl -X POST -H "Content-Type: application/json" -d '{"login_id": "username", "password": "gitlab_password"}' "https://mattermost.mydomain.com/api/v3/users/login"

Instead, it’s returning with this error, eventhough the user does exist:

{
  "id": "store.sql_user.get_for_login.app_error",
  "message": "We couldn't find an existing account matching your credentials. This team may require an invite from the team owner to join.",
  "detailed_error": "",
  "request_id": "f7i8ffgc8tyaf8pc9q1j4oixey",
  "status_code": 400
}

I was wondering if either you you were able to resolve this, since I would like to be able to use the mattermost API as I had before, when I was running Mattermost on a stand-alone basis.

Thanks.

Hi @mccoole,

The thing is that when you use gitlab as a SSO you won’t have a password assigned as the only way to authenticate the user is by using gitlab.

So as a workaround maybe you will want to enable the OAuth provider built-in Mattermost and have the user authenticate using OAuth which in turn will ask you to authenticate against gitlab, but then you’ll be provided with an access_token that you can use to make further API calls.

let me know if this helps.

Cheers

@elias,
Thanks for the suggestion. I suppose I’m not completely clear on how to implement what you suggest.

As part of the gitlab set-up that I’m working with, I believe the following (documented at the link below) has already been implemented.
https://docs.mattermost.com/deployment/sso-gitlab.html

That therefore provides a ‘login with gitlab’ option on the mattermost homepage. But, as you pointed out above, that results in no password getting assigned to my user in mattermost and therefore no ability to access the mattermost API.

I think you were suggesting to follow these docs (link below) to set up Gitlab separately as an oauth2 provider, which I followed, setting up as Trusted: Yes and using https://gitlab.mydomain.com as the homepage url … and http://gitlab.mydomain.com/users/auth/gitlab/callback as the callback URL.

https://docs.mattermost.com/developer/oauth-2-0-applications.html

According the link above:

Once you have created an OAuth 2.0 application, all users on the Mattermost server are automatically given access to it.

However, if I go back to the mattermost main menu > account-settings > security … and look under OAuth2 applications, I just see ‘No OAuth 2.0 Applications are authorized.’ Does Mattermost therefore require a restart for newly added OAuth2 applications to show up?

Also, back in Gitlab, presumably I need to set up a new application (separate to the Gitlab Mattermost that has already been set up) … and use the client ID and client secret that were part of my OAuth2 set-up above?

I’m wondering will this then result in two separate login choices for gitlab on the mattermost home page?

@mccoole

Once you setup for Mattermost as an OAuth 2.0 provider you’ll need to initiate the auth flow from your app to Mattermost in order to authorize and authenticate the user with the OAuth 2.0 app that you created, after that the app will be listed in the OAuth 2.0 apps in Account Settings. Note that giving access is the ability to authorize and authenticate with that app while OAuth 2.0 Authorized Apps refer to those that are being used by the user.

That being said, If you set the OAuth app as Trusted then you’ll skip the page to authorize the app (that page is very much like the authorization page that GitLab presents when the user first login with the GitLab auth method).

The callback of the registered OAuth 2.0 app must be controlled by your app and that endpoint will receive the access_token that you can later use to make further Mattermost API calls.

So the flow should be something like this:

  1. User goes to your app
  2. User clicks on Login to Mattermost -> this will initiate the OAuth 2.0 flow with mattermost
  3. user is redirected to /api/v3/oauth/authorize (this is the part where you need to use the client secret and client id)
    -> in case the user is logged in this will present the authorization page unless you marked the app as trusted, but if the user is not logged into Mattermost yet, they will get a login page, in that page they will be able to choose GitLab as the login method
  4. user gets redirected to your app with an access granted or denied, in the event of the access granted you’ll receive a code per OAuth 2.0 specs
  5. with the code received in the previous step user will be redirected to /api/v3/oauth/access_token following the OAuth 2.0 flow
  6. finally user is redirected to the callback URI registered in the OAuth 2.0 app that you created in Mattermost and that endpoint will receive the access_token
  7. Add the access_token to the Authorization header as Authorization Bearer <access_token> to any of the Mattermost apis

Does this help?

Ok, if i got this right. I am using the exact same setup as mccoole.
Omnibus gitlab with mattermost, and gitlab as oauth2 provider connected to our ldap server.

You describe the way the zapier uses the api, as an oauth2 app, like described in the docs.
The question is how to authenticate via the api to mattermost,
when there is no “valid credentials” in mattermost itself. Not as a trusted app or something.
Just by using the
curl -i -d '{"login_id":"username","password":"mysecret"}' https://example.com/api/v3/users/login
part.

Could we use the gitlab api, to generate a token to access the mattermost api somehow.

Greetings Nev

@nev sadly there is no way to use the gitlab access token to issue calls to the Mattermost API.

So how can we use this part of the api.
Or are we stuck to oauth2 app way, like zapier.

As of now that would be the only way

@elias @mccoole

Hello everyone,

I have failed to industrialize authentication via oauth2 on mattermost.
I’m dropping this system (temporarily maybe?).

I recall my problem: to be able to launch calls on the mattermost api using exclusively gitlab authentication.

So I chose to emulate the “real” stream that we follow as user.
It forces me to parse the html code of the authentication form on gitlab.
And for a reason that escapes me, I am forced to add a Header to pass my queries as Ajax when I query on the mattermost api.
But it works.

The code (python):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
DOC
"""
# Import from stdlib
from urllib.parse import urlparse

# Imports from external libraries
from lxml import html as ehtml
from path import Path
import requests



config = {
    'gitlab': {
        'username': 'my-username',
        'password': 'my-password',
    },
    'mattermost': {
        'api-url': Path('https://mattermost.domain.ext/api/v3'),
        'team-id': 'my-team-id',
    }
}



# Create session for keep cookies (auth with mattermost)
session = requests.Session()

# Request on gitlab oauth
r1 = session.get(config['mattermost']['api-url'] / 'oauth/gitlab/login')

# Parse html for retrieve data in prevision of auth in gitlab
gitlab_domain = Path('{uri.scheme}://{uri.netloc}/'.format(uri=urlparse(r1.url)))
html = ehtml.fromstring(r1.text)
form = html.xpath('//form[@id="new_ldap_user"]')[0]
data = {e.get('name'): e.get('value', None) for e in form.xpath('.//input')}
data['username'] = config['gitlab']['username']
data['password'] = config['gitlab']['password']

# Auth in gitlab
r2 = session.post(gitlab_domain / form.get('action').strip('/'), data=data)

# Now we have cookie in session for requests in API
# Next line is required for accepting requests in mattermost api, I don't know why
session.headers.update({
    'X-Requested-With': 'XMLHttpRequest',
})
# Profit !
r3 = session.get(config['mattermost']['api-url'] / 'teams' / config['mattermost']['team-id'] / 'channels/')
print(r3.json())

@serge
Thanks for posting that. You got further than I did!
I had been trying to engage with the gitlab developers to find a solution here … but they suggested going back to mattermost developers … which I tried here (on the forum) and on the developer channel …

While gitlab/mattermost integration works nicely for many things … being able to access the mattermost API when authenticating with gitlab is a non-runner, unless you somehow backward-engineer things … which is certainly frustrating.

I would love if there was some renewed focus placed on solving this.