~tardypad/wee-most-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH] Add support for personal access tokens

Details
Message ID
<20220828133703.2045-1-fkfd@fkfd.me>
DKIM signature
missing
Download raw message
Patch: +28 -12
Also mention access token in README
---
 README.md          |  2 +-
 wee_most/config.py |  6 ++++++
 wee_most/server.py | 32 +++++++++++++++++++++-----------
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index d3fcaaa..67e51fe 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ $ make install # WEECHAT_DATA_DIR=~/.weechat
/mattermost server add a_banal_server
```

You should then edit its configuration such as URL, username, password, 2FA command,...
You should then edit its configuration such as URL, username, password, 2FA command, access token...
To store the password safely, you can make use of WeeChat [secured data storage](https://weechat.org/files/doc/stable/weechat_user.en.html#secured_data)

```
diff --git a/wee_most/config.py b/wee_most/config.py
index 18fc0d6..041b95d 100644
--- a/wee_most/config.py
+++ b/wee_most/config.py
@@ -164,6 +164,12 @@ class PluginConfig:
            description = "Username for authentication to {} server",
            type = "string",
        ),
        Setting(
            name = "access_token",
            default = "",
            description = "Personal access token to {} server",
            type = "string",
        ),
    ]

    def __getattr__(self, key):
diff --git a/wee_most/server.py b/wee_most/server.py
index fdc02d7..bbe433f 100644
--- a/wee_most/server.py
+++ b/wee_most/server.py
@@ -34,12 +34,12 @@ class Server:
        self.url = config.get_server_config(id, "url").strip("/")
        self.username = config.get_server_config(id, "username")
        self.password = config.get_server_config(id, "password")
        self.token = config.get_server_config(id, "access_token")
        self.command_2fa = config.get_server_config(id, "command_2fa")

        if not self.url or not self.username or not self.password:
        if not self.url or not self.username or not (self.password or self.token):
            raise ValueError("Server " + id + " is not fully configured")

        self.token = ""
        self.me = None
        self.highlight_words = []
        self.users = {}
@@ -316,14 +316,16 @@ def connect_server_cb(server_id, command, rc, out, err):
        weechat.prnt("", "An error occurred while connecting")
        return weechat.WEECHAT_RC_ERROR

    token_search = re.search("[tT]oken: (\w*)", out)

    out = out.splitlines()[-1] # we remove the headers line
    server = servers[server_id]
    out = out.splitlines()[-1] # we remove the status line
    response = json.loads(out)

    server = servers[server_id]
    if not server.token:
        # user authenticates with password
        # server supplies a "Token" header
        token_search = re.search("[tT]oken: (\w*)", out)
        server.token = token_search.group(1)

    server.token = token_search.group(1)
    server.init_me(**response)

    try:
@@ -372,10 +374,18 @@ def connect_server(server_id):

    servers[server_id] = server

    wee_most.http.enqueue_request(
        "run_user_login",
        server, "connect_server_cb", server.id
    )
    if server.token:
        # skip login if user authenticates with personal access token
        # instead directly GET /api/v4/users/me
        wee_most.http.enqueue_request(
            "run_get_user",
            server, "me", "connect_server_cb", server.id
        )
    else:
        wee_most.http.enqueue_request(
            "run_user_login",
            server, "connect_server_cb", server.id
        )

    return weechat.WEECHAT_RC_OK

-- 
2.37.2
Details
Message ID
<CMHPMVWYCBRH.1TORS842H7KHM@bandito>
In-Reply-To
<20220828133703.2045-1-fkfd@fkfd.me> (view parent)
DKIM signature
missing
Download raw message
This patch adds support for Personal Access Tokens[1] by calling
/api/v4/users/me in lieu of /api/v4/users/login. The user can now specify an
access token in their configuration option access_token.

However, as I don't have access to a password-authenticated MM server, I cannot
test whether this patch broke anything relevant. I did not test with 2FA
enabled either.

Thanks for reviewing.

[1] https://docs.mattermost.com/developer/personal-access-tokens.html
Details
Message ID
<CNEW4BP9GWG3.3DSAXVUVIY83V@coconut>
In-Reply-To
<20220828133703.2045-1-fkfd@fkfd.me> (view parent)
DKIM signature
missing
Download raw message
Hi,

I've tested your patch but unfortunately it breaks the password login.
Please find below a few comments.

> -    out = out.splitlines()[-1] # we remove the headers line
> +    server = servers[server_id]
> +    out = out.splitlines()[-1] # we remove the status line

From what I see the comment was correct. It splits the response on the
empty line between the headers and the body, and returns only the body.

> +    if not server.token:
> +        # user authenticates with password
> +        # server supplies a "Token" header
> +        token_search = re.search("[tT]oken: (\w*)", out)

This search needs to be done before the splitlines happens because the
token is part of the response headers which it discards.

Regards,

--
Damien Tardy-Panis
Details
Message ID
<CNEX0PSPXJTJ.3BTW4NJ1P6038@coconut>
In-Reply-To
<CMHPMVWYCBRH.1TORS842H7KHM@bandito> (view parent)
DKIM signature
missing
Download raw message
Hi

> I did not test with 2FA enabled either.

I was checking a bit the Mattermost documentation but it seems that it's
not possible to have 2FA when using a personal access token (I guess
that's why my company doesn't allow those). The 2FA value is used only
during a login call.

Overall, this make sense as that personal token is used in the same way
as a session token retrieved from the login call, there's no
intermediate step.

So there's no 2FA specific thing to test with this change, the 2FA code
can stay only in the login call.

Regards,

--
Damien Tardy-Panis
Reply to thread Export thread (mbox)