-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSO Support (also needed for ElementOne) #24
Comments
Hi, I don't use SSO, so I don't plan to implement it myself (unless someone wanted to sponsor it in some way). But, patches welcome, and I'll be glad to help integrate it. :) |
After talking to alphapapa in matrix I wrote the following which could be a helpful jumping off point for integrating sso. According to https://matrix.org/docs/guides/sso-for-client-developers the server should support m.login.sso and m.login.token. (defun necronian-ement-sso-api (data)
(let* ((id (cdr (assq 'user_id data)))
(username (save-match-data
(string-match "@\\(.*\\):.*" id)
(match-string 1 id)))
(server (cdr (assq 'home_server data)))
(uri-prefix (cdr (assq 'base_url
(cdr (assq 'm\.homeserver
(cdr (assq 'well_known data)))))))
(token (cdr (assq 'access_token data))))
(ement-connect
:session (make-ement-session
:user (make-ement-user :id id :username username)
:server (make-ement-server :name server
:uri-prefix uri-prefix)
:token token
:events (make-hash-table :test #'equal)
:transaction-id 0))))
(defun sso-login (uri-prefix proc msg)
(let* ((token (save-match-data
(string-match "GET /\\?loginToken=\\(.*\\)\s.*" msg)
(match-string 1 msg)))
(login-data (ement-alist "type" "m.login.token"
"token" token)))
(ement-api (make-ement-session
:server (make-ement-server :uri-prefix uri-prefix))
"login"
:then #'necronian-ement-sso-api
:method 'post
:data (json-encode login-data))
(delete-process "ement-sso")))
(defun necronian-ement-sso (uri-prefix &optional local-port)
(make-network-process
:name "ement-sso"
:family 'ipv4
:host "localhost"
:service (or local-port 4567)
:filter (apply-partially #'sso-login uri-prefix)
:server t)
(browse-url (concat uri-prefix
"/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:"
(number-to-string (or local-port 4567))))) Calling |
Thanks, that is very helpful. |
This looks great! Does it have a chance of working through pantalaimon? My understanding is pantalaimon handles the login when I use it, as I don't inform ement of the home server pantalaimon is proxying to. |
I have no idea, since I don't use Pantalaimon myself. If you could find out and report back, that would be helpful. :) |
Trying this with and after sign-in into browser, emacs fails with:
can you point me how to debug this error? |
Honestly, my elisp is not very good so I'm not sure if I can help. To start this code will always be brittle since ement doesn't really have an interface for users to create/initialize a new session. We create the session struct ourselves and need to make sure we initialize it correctly with the information ement is expecting. That has changed slightly since my last post. This is what I'm using now, which I know fixes some issues. (defun necronian-ement-sso-api (data)
(let* ((id (cdr (assq 'user_id data)))
(username (save-match-data
(string-match "@\\(.*\\):.*" id)
(match-string 1 id)))
(server (cdr (assq 'home_server data)))
(uri-prefix (cdr (assq 'base_url
(cdr (assq 'm\.homeserver
(cdr (assq 'well_known data)))))))
(token (cdr (assq 'access_token data))))
(ement-connect
:session (make-ement-session
:user (make-ement-user :id id
:username username
:room-display-names (make-hash-table))
:server (make-ement-server :name server
:uri-prefix uri-prefix)
:token token
:events (make-hash-table :test #'equal)
:transaction-id (ement--initial-transaction-id)))))
(defun sso-login (uri-prefix proc msg)
(let* ((token (save-match-data
(string-match "GET /\\?loginToken=\\(.*\\)\s.*" msg)
(match-string 1 msg)))
(login-data (ement-alist "type" "m.login.token"
"token" token)))
(ement-api (make-ement-session
:server (make-ement-server :uri-prefix uri-prefix))
"login"
:then #'necronian-ement-sso-api
:method 'post
:data (json-encode login-data))
(delete-process "ement-sso")))
(defun necronian-ement-sso (uri-prefix &optional local-port)
(make-network-process
:name "ement-sso"
:family 'ipv4
:host "localhost"
:service (or local-port 4567)
:filter (apply-partially #'sso-login uri-prefix)
:server t)
(browse-url (concat uri-prefix
"/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:"
(number-to-string (or local-port 4567))))) |
Thank you so much for your fast reply. Sadly your updated SSO code is not working for me neither. At least I expect to revive this thread and some elisp expert could help in the future. I'll keep trying. |
Juanjo, please be specific about what you did and what happened. Just
saying that it didn't work isn't helpful.
…On Sun, Apr 17, 2022, 14:25 Juanjo Presa ***@***.***> wrote:
Thank you so much for your fast reply. Sadly your updated SSO code is not
working for me neither. At least I expect to revive this thread and some
elisp expert could help in the future. I'll keep trying.
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAES2FK3JH3VX2FG3PZGNLDVFRQTVANCNFSM5CCSEWJQ>
.
You are receiving this because you were assigned.Message ID:
***@***.***>
|
Sure, I run
By the way I'll be happy to help debugging this in-depth. |
If you're going to evaluate that expression directly, you will need to
`(require 'ement)` first, otherwise the other libraries will not get loaded
automatically.
…On Tue, Apr 19, 2022, 05:42 Juanjo Presa ***@***.***> wrote:
Sure, I run (necronian-ement-sso "https://one.element.io") again with new
excerpt of code shared by @Necronian <https://github.com/Necronian> and
after login in browser I get same message error than before:
error in process sentinel: run-hook-with-args: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: HTTP error [30 times]
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAES2FMVDU4XZGQSWYTRY63VF2EZVANCNFSM5CCSEWJQ>
.
You are receiving this because you were assigned.Message ID:
***@***.***>
|
OK, I will try to be more clear. Reproducing the problem in a pristine emacs environment (add-to-list 'load-path "/home/user/.emacs.d/contrib-lisp/ement")
(add-to-list 'load-path "/home/user/.emacs.d/contrib-lisp/plz")
(require 'ement)
(defun necronian-ement-sso-api (data)
(let* ((id (cdr (assq 'user_id data)))
(username (save-match-data
(string-match "@\\(.*\\):.*" id)
(match-string 1 id)))
(server (cdr (assq 'home_server data)))
(uri-prefix (cdr (assq 'base_url
(cdr (assq 'm\.homeserver
(cdr (assq 'well_known data)))))))
(token (cdr (assq 'access_token data))))
(ement-connect
:session (make-ement-session
:user (make-ement-user :id id
:username username
:room-display-names (make-hash-table))
:server (make-ement-server :name server
:uri-prefix uri-prefix)
:token token
:events (make-hash-table :test #'equal)
:transaction-id (ement--initial-transaction-id)))))
(defun sso-login (uri-prefix proc msg)
(let* ((token (save-match-data
(string-match "GET /\\?loginToken=\\(.*\\)\s.*" msg)
(match-string 1 msg)))
(login-data (ement-alist "type" "m.login.token"
"token" token)))
(ement-api (make-ement-session
:server (make-ement-server :uri-prefix uri-prefix))
"login"
:then #'necronian-ement-sso-api
:method 'post
:data (json-encode login-data))
(delete-process "ement-sso")))
(defun necronian-ement-sso (uri-prefix &optional local-port)
(make-network-process
:name "ement-sso"
:family 'ipv4
:host "localhost"
:service (or local-port 4567)
:filter (apply-partially #'sso-login uri-prefix)
:server t)
(browse-url (concat uri-prefix
"/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:"
(number-to-string (or local-port 4567))))) being Then i run
I'm running "GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30, cairo version 1.16.0)" |
Please install plz and ement according to the instructions in the readme.
…On Tue, Apr 19, 2022, 15:57 Juanjo Presa ***@***.***> wrote:
OK, I will try to be more clear. Also going to reproduce the problem in a
pristine emacs environment, so i run emacs -Q then evaluate this code:
(add-to-list 'load-path "/home/user/.emacs.d/contrib-lisp/ement")
(add-to-list 'load-path "/home/user/.emacs.d/contrib-lisp/plz")
(require 'ement)
(defun necronian-ement-sso-api (data)
(let* ((id (cdr (assq 'user_id data)))
(username (save-match-data
(string-match "@\\(.*\\):.*" id)
(match-string 1 id)))
(server (cdr (assq 'home_server data)))
(uri-prefix (cdr (assq 'base_url
(cdr (assq 'm\.homeserver
(cdr (assq 'well_known data)))))))
(token (cdr (assq 'access_token data))))
(ement-connect
:session (make-ement-session
:user (make-ement-user :id id
:username username
:room-display-names (make-hash-table))
:server (make-ement-server :name server
:uri-prefix uri-prefix)
:token token
:events (make-hash-table :test #'equal)
:transaction-id (ement--initial-transaction-id)))))
(defun sso-login (uri-prefix proc msg)
(let* ((token (save-match-data
(string-match "GET /\\?loginToken=\\(.*\\)\s.*" msg)
(match-string 1 msg)))
(login-data (ement-alist "type" "m.login.token"
"token" token)))
(ement-api (make-ement-session
:server (make-ement-server :uri-prefix uri-prefix))
"login"
:then #'necronian-ement-sso-api
:method 'post
:data (json-encode login-data))
(delete-process "ement-sso")))
(defun necronian-ement-sso (uri-prefix &optional local-port)
(make-network-process
:name "ement-sso"
:family 'ipv4
:host "localhost"
:service (or local-port 4567)
:filter (apply-partially #'sso-login uri-prefix)
:server t)
(browse-url (concat uri-prefix
"/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:"
(number-to-string (or local-port 4567)))))
being ~/.emacs.d/contrib-lisp/ement and ~/.emacs.d/contrib-lisp/plz the
place where i download git third party packages.
Then i run (necronian-ement-sso "https://one.element.io"), firefox new
tab opens and I login in ElementOne site authorizing localhost. Browser
hangs and Emacs Messages buffers respond:
#<process firefox https://one.element.io/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:4567>
Ement: Sync request sent, waiting for response...
Ement: Response arrived after 11.87 seconds. Reading 2.6M JSON response...
Ement: Reading JSON took 0.84 seconds
Ement: Reading events...62%
Ement: Sync request sent, waiting for response...
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error
error in process sentinel: let: HTTP error
error in process sentinel: HTTP error [57 times]
Ement: Response arrived after 30.27 seconds. Reading 751 JSON response...
Ement: Reading JSON took 0.00 seconds
Ement: Reading events...
Ement: Sync request sent, waiting for response...
error in process sentinel: run-hook-with-args: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: HTTP error [60 times]
Ement: Response arrived after 30.41 seconds. Reading 751 JSON response...
Ement: Reading JSON took 0.00 seconds
Ement: Reading events...
Ement: Sync request sent, waiting for response...
error in process sentinel: run-hook-with-args: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: HTTP error [4 times]
error in process sentinel: Quit [8 times]
error in process sentinel: HTTP error [4 times]
error in process sentinel: Quit [2 times]
error in process sentinel: HTTP error [6 times]
error in process sentinel: Symbol’s function definition is void: ement-room-list-auto-update [2 times]
Ement: Response arrived after 30.21 seconds. Reading 751 JSON response...
Ement: Reading JSON took 0.00 seconds
Ement: Reading events...
Ement: Sync request sent, waiting for response...
error in process sentinel: run-hook-with-args: Symbol’s function definition is void: ement-room-list-auto-update
error in process sentinel: Symbol’s function definition is void: ement-room-list-auto-update
I'm running "GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.30, cairo version 1.16.0)"
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAES2FJZQ6BEZXKPSD4OIJTVF4M25ANCNFSM5CCSEWJQ>
.
You are receiving this because you were assigned.Message ID:
***@***.***>
|
Ok, I evaluate this now and its working well: (unless (package-installed-p 'quelpa)
(with-temp-buffer
(url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el")
(eval-buffer)
(quelpa-self-upgrade)))
(quelpa
'(quelpa-use-package
:fetcher git
\ :url "https://github.com/quelpa/quelpa-use-package.git"))
(require 'quelpa-use-package)
;; Install `plz' HTTP library (not on MELPA yet).
(use-package plz
:quelpa (plz :fetcher github :repo "alphapapa/plz.el"))
;; Install Ement.
(use-package ement
:quelpa (ement :fetcher github :repo "alphapapa/ement.el"))
(require 'ement)
(defun necronian-ement-sso-api (data)
(let* ((id (cdr (assq 'user_id data)))
(username (save-match-data
(string-match "@\\(.*\\):.*" id)
(match-string 1 id)))
(server (cdr (assq 'home_server data)))
(uri-prefix (cdr (assq 'base_url
(cdr (assq 'm\.homeserver
(cdr (assq 'well_known data)))))))
(token (cdr (assq 'access_token data))))
(ement-connect
:session (make-ement-session
:user (make-ement-user :id id
:username username
:room-display-names (make-hash-table))
:server (make-ement-server :name server
:uri-prefix uri-prefix)
:token token
:events (make-hash-table :test #'equal)
:transaction-id (ement--initial-transaction-id)))))
(defun sso-login (uri-prefix proc msg)
(let* ((token (save-match-data
(string-match "GET /\\?loginToken=\\(.*\\)\s.*" msg)
(match-string 1 msg)))
(login-data (ement-alist "type" "m.login.token"
"token" token)))
(ement-api (make-ement-session
:server (make-ement-server :uri-prefix uri-prefix))
"login"
:then #'necronian-ement-sso-api
:method 'post
:data (json-encode login-data))
(delete-process "ement-sso")))
(defun necronian-ement-sso (uri-prefix &optional local-port)
(make-network-process
:name "ement-sso"
:family 'ipv4
:host "localhost"
:service (or local-port 4567)
:filter (apply-partially #'sso-login uri-prefix)
:server t)
(browse-url (concat uri-prefix
"/_matrix/client/r0/login/sso/redirect?redirectUrl=http://localhost:"
(number-to-string (or local-port 4567))))) Thanks everyone for your effort. |
@uningan Thanks, that's great. @Necronian It looks like your code works. I'd guess it's sufficiently trivial (i.e. there's no other obvious way to implement it) that copyright could hardly be an issue, but on the other hand, the FSF's policies are what they are (i.e. no more than 15 lines of changes without copyright assignment. Since I'm planning to submit Ement to GNU ELPA, which requires FSF CA, are you willing to pursue that, so this code could be accepted as-is in a patch? |
I'll try to get a FSF CA. Honestly it feels a bit silly for something so trivial, but sure. I've always wanted to eventually integrate it into ement-connect. Possibly when a blank password is entered and m.login.sso is supported start the sso process. What I have now has been working so I just haven't felt a huge need. |
Thanks. I'm trying to go by the book here so that there won't be any troubles in the future (which are always much harder to resolve after the fact).
Probably we'll need to check the server's supported methods and prompt the user for the one to use. |
Not working for me again, any hints?
stil ok on you @Necronian ? |
That code does not exist in Ement.el anymore. You need to remove the setting of the |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Mozilla offers a free Matrix server that requires SSO - you can find more information at https://chat.mozilla.org . |
See <#24>. Co-developed-by: Jeffrey Stoffers <[email protected]>
@ceearrbee Thanks, that helped a lot. @phil-s and anyone else who's interested: the |
Closes <#24>. Co-developed-by: Jeffrey Stoffers <[email protected]>
I went ahead and merged to master. Testing would be appreciated. Maybe a v0.10 release with this feature can be tagged in time for TWIM on Friday; but if not, maybe next week. |
Great, that's now mostly working! After entering my username I do still get the It's no longer requesting a password, so I go straight to URL entry and select
I'm running Ubuntu 22.04 with curl 7.81.0 and the new plz commit a0a6d623352aa1caee722c16649190611a253cbc "Fix: (plz--sentinel) Skip HTTP redirect headers".
I'll have to ask other people about that, but I'm happy to test anything you can think of. Tracing
If I stop plz from from killing the
|
Ah, The plz buffer starts out like this when that's being processed:
(but with carriage returns after each header line; github is stripping those.) |
Thanks to Phil Sainty's (@phil-s) comment: <alphapapa/ement.el#24 (comment)>.
@phil-s Another silly mistake by me, sorry. I was thinking that
I don't think that will be necessary anymore. This should fix it... |
That issue looks sorted now, thanks. I'm afraid I'm now getting a new problem -- a subsequent
I see I can confirm that swapping between the current and previous revision of I haven't checked, but perhaps it's assuming that if it gets any |
Correction... I'd been guessing (wrongly) that The JSON data does not include the URL which I was previously being prompted to enter manually, though. I don't know whether the JSON is supposed to include that, or if it should be inferred from the URL that This issue aside, I'm entirely unfamiliar with any |
It looks to me like it's a valid scenario. https://spec.matrix.org/latest/client-server-api/#well-known-uri says:
|
By comparison, I see that {
"m.homeserver": {
"base_url": "https://mozilla.modular.im"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
} I'll have to raise an internal request to do similarly for the server I'm using; but that can wait until after things are working here without it :) |
@phil-s Thanks again for the detailed investigation. I'm sorry but I'm not sure I fully understand: are you saying that the JSON returned for the request to If it doesn't, then the homeserver is not configured correctly--a not-uncommon problem, judging from the reports I've heard from other users about using other homeservers. Then, are you saying that Ement should be able to cope with that? Well, yes, it should "fail prompt," but apparently, yes, it's assuming that if So, that problem isn't directly related to SSO support, but I'm glad you found it. I'll push a fix probably tomorrow. Thanks. |
Yes, all correct. The entirety of the JSON I get is shown in #24 (comment) and does not include "m.homeserver".
I'm happy to be providing lots of edge-cases prior to the feature being merged :)
Excellent, thank you. I'll re-test after that (and then see if I can get someone at my end to fix that JSON!) |
See <#24 (comment)>. Thanks to Phil Sainty (@phil-s).
@phil-s Ok, it should be working now (with the current master versions of Note to self: I should probably make v0.10 of Ement depend on v0.6 of plz. |
Thank you, that is now working nicely for me! Should
But (on account of that less-than-ideal local JSON response from my Matrix server) I still have to interactively enter
I note that if I enable session saving, then |
The only other question I have left is wrt one of my earlier notes:
The issue being that (very much by design) that error screen looks like the opposite of success. (I was going to include a small screenshot but github doesn't like the png for some reason; but it's a browser-generated error screen, so you'll see your version just by visiting I figure that ideally ement would be sending the web browser something here to make it happier, but I don't know how much additional effort that would entail. It can be confusing the first time though -- in my case my window manager switches me to another workspace to get to Firefox, so I no longer have visibility on Emacs when I'm dealing with the SSO form; and consequently the first time I saw that submission error message in Firefox I assumed that the authentication process had failed. Conversely when signing in via SSO with the standalone Element client I get automatically switched back to the original workspace after submitting the browser form, and there is no error message in the browser; so the experience is nicer there. That said, the browser doesn't actually display any confirmation message (it's still showing the form with the submit button I'd just clicked); and with Element I see that the browser form refers to I don't know what the options are for improving this, and it's not really a big deal (users will undoubtedly notice before long that the authentication process worked, and once you know, you know); but it would be a "nice-to-have" if Ement could cause the web browser to appear less like something had gone wrong. |
Great, thanks.
Hm, I'm not sure. I don't think it's intended that the user call Something that might be helpful would be to interactively prompt the user to choose to save the session if the option isn't yet enabled, because many, if not most, users won't know that such an option exists or needs to be set in order to save the token and not have to enter credentials each time. What do you think? |
Yes, that should be improved. Probably we do need to send the browser an HTTP response with at least a plain HTML page that says that authentication succeeded and the tab can be closed and the user should switch back to Emacs. Like you said, I don't think we can automate that, especially with all the sandboxing browsers do, but we can at least make it less confusing. Thanks very much for your help with this feature. I think it will benefit many users to come. |
Ah, fair enough.
Yes, that sounds useful. Perhaps
Differentiating "this server" from "all servers" may be overkill, but I think "never save a session for this server (ask for others)" is the only response that isn't facilitated by the combination of the user option value and the known list of saved sessions (as it would require an additional list of blacklisted servers to be maintained; maybe this could be integrated into the session file, though?). Or you could simply omit this from the set of valid responses to avoid the complication. I suspect the other responses might all be fairly straightforward. |
Use the secondary browser to browse the URL, because typically JavaScript is required, which EWW doesn't support; and if the page is opened in EWW first, it may break the process, because the server may not allow that URL to be loaded multiple times. See #24.
I'm not sure how I feel about those ideas. It seems a bit complicated to me, but some of them could be good. I'll defer those ideas to the future. For now, I'll consider this feature to have been implemented in v0.11. Thanks. |
SSO as the login method for servers is becoming popular - such as with Mozilla's, is there any likelihood of this being implemented anytime soon?
The text was updated successfully, but these errors were encountered: