Vaelor/python-mattermost-driver

Cannot authenticate when running on localhost.

Closed this issue · 8 comments

I am getting the following error when running on a mattermost server run in docker.

requests.exceptions.ConnectionError: HTTPConnectionPool(host='http', port=80): Max retries exceeded with url: //localhost:8065/test-team/:8065/api/v4/users/me (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x03E884D8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'))

My mattermost server is up and running and I can access it fine in a browser window. I am using a token to authenticate(as it is a bot account).

@asdmenon
faced the same problem yesterday, solved but don't remember exactly how (used errbot with mattermostdriver and mattermost ``backend) :)
A couple of notes:

  1. That extra :8065 in url looks weird.
  2. I debugged using postman (GET request in case of bot) and double checked using simple requests.get()
  3. If you use bot, don't include login/password creds in BOT_IDENTITY, only token
  4. Switch bot role -> system admin. Member role didn't work for me for some reason
  5. localhost uses http scheme, but Driver has default value 'scheme': 'https',

Hello @maxeval , here's my code that causes the error

from mattermostdriver import Driver

access_token = '<access token here>'
server_url = 'http://localhost:8065'

def main():
    driv = Driver({'token': access_token, 'url': server_url, 'scheme':'http'})
    driv.login()

Despite the scheme being set to http, the error is still being thrown. Things i've tried

  1. Remove the port number from server_url so it is just `http://localhost' . Same error without the extra 8065 in the error string.
  2. The bot being a system admin or a member has no effect on the API call as using a curl command to login and do stuff with the generated token works fine when using curl in terminal or requests in python against the desired endpoints.
  3. Force setting the port flag to 8065 in conjunction with 1.

I have tested my token and server url in a separate script that uses requests instead of the library and it works fine. Not sure what I am doing wrong here.

@asdmenon just did the same thing (except my mattermost is spinning on remote):
>>> d = Driver({"url": "server.name", "port": 443, "token": "piof89gkjdkjiefykxf3epoi98522dfd"}) >>> d.login() >>> {'id': '1kyr6umxgfn1idys7876m8owe', 'create_at': 1684329199976, 'update_at': 1684331505513, 'delete_at': 0, 'username': 'errbot_test', 'auth_data': '', 'auth_service': '', 'email': 'errbot_test@localhost', 'nickname': '', 'first_name': 'errbot', 'last_name': '', 'position': '', 'roles': 'system_user system_admin', 'notify_props': {'channel': 'true', 'comments': 'never', 'desktop': 'mention', 'desktop_sound': 'true', 'desktop_threads': 'all', 'email': 'true', 'email_threads': 'all', 'first_name': 'false', 'mention_keys': '', 'push': 'mention', 'push_status': 'away', 'push_threads': 'all'}, 'last_password_update': 1684329199976, 'locale': 'en', 'timezone': {'automaticTimezone': '', 'manualTimezone': '', 'useAutomaticTimezone': 'true'}, 'is_bot': True, 'disable_welcome_email': False}`

works fine. Here is another trick: make sure you input token value, (not token_id). It can be seen once you create it and then disappears.
image

@maxeval The thing is I am not using user tokens to access the API. I am using a bots access token instead. So when I run the curl to authorize I get the following response

curl -i -H 'authorization: Bearer xkxf3em8xfgopyknqefqxsxm7c' http://localhost:8065/api/v4/users/me

HTTP/1.1 200 OK
Content-Type: application/json
Etag: 7.5.0.3npzo9apr389xqettytigjc3ba.1684396490018..0.true.true.0
Expires: 0
Vary: Accept-Encoding
X-Request-Id: mu6qr6qbujf77bf7wtpzzm4yxh
X-Version-Id: 7.5.0.7.5.0.81377f0a1aa54d8bdc686497662704cf.false
Date: Sun, 21 May 2023 09:38:06 GMT
Content-Length: 759

{"id":"3npzo9apr389xqettytigjc3ba","create_at":1684231863585,"update_at":1684396490018,"delete_at":0,"username":"mrbot","auth_data":"","auth_service":"","email":"mrbot@localhost","nickname":"","first_name":"MrGoodBot","last_name":"","position":"","roles":"system_user system_admin","notify_props":{"channel":"true","comments":"never","desktop":"mention","desktop_sound":"true","desktop_threads":"all","email":"true","email_threads":"all","first_name":"false","mention_keys":"","push":"mention","push_status":"away","push_threads":"all"},"last_password_update":1684231863585,"locale":"en","timezone":{"automaticTimezone":"","manualTimezone":"","useAutomaticTimezone":"true"},"is_bot":true,"bot_description":"A Very good bot boy","disable_welcome_email":false}

@asdmenon in my example above I used that token as bot access token: 'is_bot': True.
Just followed this instuctions to create one

I think something weird is happening when I try to connect to localhost as the url is very weird in the error log.
If I pass "url" as "http://localhost" this is the error snippet

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='http', port=443): Max retries exceeded with url: //localhost:8065/api/v4/users/me (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x016A6550>: Failed to establish a new connection: 
[Errno 11001] getaddrinfo failed'))

If I pass url as "http://localhost:8065" it goes to this instead

 File "<string>", line 3, in raise_from
urllib3.exceptions.LocationParseError: Failed to parse: //localhost:8065:8065/api/v4/users/me

Passing the port number in the Driver constructor's dict, it still gives the first error.

Try:

server_url = 'localhost'
def main():
    driv = Driver({'token': access_token, 'url': server_url, 'scheme':'http', 'port': 8065})
    driv.login()

Try:

server_url = 'localhost'
def main():
    driv = Driver({'token': access_token, 'url': server_url, 'scheme':'http', 'port': 8065})
    driv.login()

This worked. Thank you!