From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Philip Kaludercic Newsgroups: gmane.emacs.bugs Subject: bug#72992: 29.4; towards xoauth2 support in Emacs Date: Tue, 17 Sep 2024 19:12:57 +0000 Message-ID: <87r09i14cm.fsf@posteo.net> References: <87h6ayfo87.fsf_-_@debian-hx90.lan> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7050"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 72992@debbugs.gnu.org To: Xiyue Deng Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Sep 17 21:13:58 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sqdeA-0001eD-Br for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 17 Sep 2024 21:13:58 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sqde0-0000SR-S3; Tue, 17 Sep 2024 15:13:49 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sqddz-0000Rz-CC for bug-gnu-emacs@gnu.org; Tue, 17 Sep 2024 15:13:47 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sqddz-0002XV-3Z for bug-gnu-emacs@gnu.org; Tue, 17 Sep 2024 15:13:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:References:In-Reply-To:From:To:Subject; bh=66fpSe3e8+zM8Jg/Tb8Q4aQ177wg+Vg/cUPHmk4DIcA=; b=Rj+eK3FlSqel0RdIvIp1cXAQk7mJH5bnW7FwhbbbrZm/aFhmdIVet29j0byOApHc5bk+GxOElX6IT7na9tplb3d5cSxsiLeouL73g4KSmJomFL49Lab62bukNwdS6jBm4hogftqiRrH52IpwlPkm6yFZJx0Yq7EYUgX96AHseQ9Ksy+FexmcRNcfMX4xsCrwBJrDtE5w7x7UU1HnJfXqqU5JMlivG9tDIPDauZ/DP8+uRlFeh0P3cIX3DLeq3npQSf3bXgAtISDcCv/oulp2aF6V9H/3/OwTwEL7XqH3nt1tpbeixo1lRJ+htfleHjBvomjp+O/Fb1VbZYAWaMEs1w==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1sqdeE-0007Qm-1m for bug-gnu-emacs@gnu.org; Tue, 17 Sep 2024 15:14:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 17 Sep 2024 19:14:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 72992 X-GNU-PR-Package: emacs Original-Received: via spool by 72992-submit@debbugs.gnu.org id=B72992.172660040228507 (code B ref 72992); Tue, 17 Sep 2024 19:14:02 +0000 Original-Received: (at 72992) by debbugs.gnu.org; 17 Sep 2024 19:13:22 +0000 Original-Received: from localhost ([127.0.0.1]:55992 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sqdda-0007Pi-4S for submit@debbugs.gnu.org; Tue, 17 Sep 2024 15:13:22 -0400 Original-Received: from mout01.posteo.de ([185.67.36.65]:38845) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1sqddX-0007PO-Ix for 72992@debbugs.gnu.org; Tue, 17 Sep 2024 15:13:20 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 0198D240027 for <72992@debbugs.gnu.org>; Tue, 17 Sep 2024 21:12:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1726600379; bh=qqj8rvL3l52lNBlB5JnB0r03+++ehKbkBnaVNV2s9lM=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=Vp/rgWmPwnuhI7SQ917lFf1+Kvsr6BZLwOcV64LWbMPkvrggDQ+j3D6Q+zf2eCk00 5+JIx3Eclu7hqtD7DYRXcXoFXkgiaQVAtA3RglGNqZgQqbC5jiBh2FtQqkVQqFfXra njZTKj+LVDJ8jL4niGpkJV44Sm3K0UNpOI/Kh5sFxYPjMvHQPc4t4uLlox2uO4CvMu FrwH9EHHywtqoSFFokOm/rNxzNIsYDE9iFa6lbPqtbIBuaNgTqmr9UHN79NX5G7nY8 O7ENqbEzPT0UZJLL5K1Btg5BOL3ZgUFw1MWOMuao48cc88xrIpYn6Vp5ytPQ/Whpy4 eu6aXSoPDxJNA== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4X7WdQ3Mpbz9rxD; Tue, 17 Sep 2024 21:12:58 +0200 (CEST) In-Reply-To: <87h6ayfo87.fsf_-_@debian-hx90.lan> (Xiyue Deng's message of "Mon, 02 Sep 2024 01:34:32 -0700") Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=philipk@posteo.net; url="https://keys.openpgp.org/vks/v1/by-email/philipk@posteo.net"; preference=signencrypt X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:291965 Archived-At: Xiyue Deng writes: > Now that bug#72358 is done, as promised, I'm posting my plugin for > auth-sources that enables oauth2 handling which you can find on > Gitlab[1] (also attached). Once again I just want to be sure: When you say "plugin", you mean package, right? You are proposing to add this to GNU ELPA? [...] > > Thanks for reading, and any comments are appreciated. I'll be honest, I have no idea about OAuth, so my comments are just related to Elisp for now. Hope that's OK! > [1] https://gitlab.com/xiyueden/auth-source-xoauth2-plugin > ;; Copyright (C) 2024 Xiyue Deng > > ;; Author: Xiyue Deng > ;; Version: 0.1-git > ;; Package-Requires: ((emacs "28.1") (oauth2 "0.17")) > > ;; This file is not part of GNU Emacs. > > ;; GNU Emacs is free software: you can redistribute it and/or modify > ;; it under the terms of the GNU General Public License as published by > ;; the Free Software Foundation, either version 3 of the License, or > ;; (at your option) any later version. > > ;; GNU Emacs is distributed in the hope that it will be useful, > ;; but WITHOUT ANY WARRANTY; without even the implied warranty of > ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > ;; GNU General Public License for more details. > > ;; You should have received a copy of the GNU General Public License > ;; along with GNU Emacs. If not, see . > > ;;; Commentary: > > ;; This package enables support for xoauth2 authentication with > ;; auth-source. To set up, please put this file in the `load-path' of > ;; Emacs, and add the following lines in your Emacs configuration: > > ;; (require 'auth-source-xoauth2-plugin) > ;; (auth-source-xoauth2-plugin-enable) > > ;; or with use-package: > > ;; (use-package auth-source-xoauth2-plugin > ;; :config > ;; (auth-source-xoauth2-plugin-enable)) > > ;; After enabling, smtpmail should be supported. To enable this in Gnus > ;; nnimap, you should also set `(nnimap-authenticator xoauth2)' in the > ;; corresponding account settings in `gnus-secondary-select-methods' > > ;; auth-source uses the `secret' field in auth-source file as password > ;; for authentication, including xoauth2. To decide which > ;; authentication method to use (e.g. plain password vs xoauth2), it > ;; inspects the `auth' field from the auth-source entry, and if the > ;; value is `xaouth2', it will try to gather data and get the access > ;; token for use of xoauth2 authentication; otherwise, it will fallback > ;; to the default authentication method. > > ;; When xoauth2 authentication is enabled, it will try to get the > ;; following data from the auth-source entry: `auth-url', `token-url', > ;; `scope', `client-id', `client-secret', `redirect-uri', and optionally > ;; `state'. These information will be used by oauth2 to retrieve the > ;; access-token. This package uses an advice to switch the auth-source > ;; search result from the `password' to the `access-token' it got, which > ;; in turn will be used to construct the xoauth2 authentication string, > ;; currently in nnimap-login and smtpmail-try-auth-method. To really > ;; enable xoauth2 in smtpmail, it will add 'xoauth2 to > ;; 'smtpmail-auth-supported (if it is not already in the list) using > ;; `add-to-list' so that xoauth2 is tried first. > > ;; Note that currently the auth-source requires the searched entry must > ;; have `secret' field set in the entry, which is not necessary when > ;; using xoauth2. Therefore in the advice it temporarily disables > ;; checking for `:secret' if set and perform the search, and check the > ;; result before returning. > > ;;; Code: > > (require 'auth-source) > (require 'cl-lib) > (require 'oauth2) > (require 'smtpmail) > > (defun auth-source-xoauth2-plugin--search-backends (orig-fun &rest args) > "Perform auth-source-search and set password as access-token when reque= sted. > The substitution only happens if one sets `auth' to `xoauth2' in > your auth-source-entry. It is expected that `token_url', > `client_id', `client_secret', and `refresh_token' are properly > set along `host', `user', and `port' (note the snake_case)." > (auth-source-do-trivia "Advising auth-source-search") > (let (check-secret) > (when (memq :secret (nth 5 args)) > (auth-source-do-trivia > "Required fields include :secret. As we are requesting access tok= en to replace the secret, we'll temporary remove :secret from the require l= ist and check that it's properly set to a valid access token later.") > (setf (nth 5 args) (remove :secret (nth 5 args))) > (setq check-secret t)) > (let ((orig-res (apply orig-fun args)) > res) > (dolist (auth-data orig-res) > (auth-source-do-trivia "Matched auth data: %s" (pp-to-string auth= -data)) Is "trivia" the right debug level for all the messages in this function? I feel like some of them should at least be "debug". > (let ((auth (plist-get auth-data :auth))) > (when (and auth > (stringp auth) > (string=3D auth "xoauth2")) You can simplify the check by just doing (equal auth "xoauth2"), as this implies all of the above (if it is `equal' to a string, it must be a string and hence also non-nil). > (auth-source-do-debug > ":auth set to `xoauth2'. Will get access token.") > (let ((auth-url (plist-get auth-data :auth-url)) > (token-url (plist-get auth-data :token-url)) > (scope (plist-get auth-data :scope)) > (client-id (plist-get auth-data :client-id)) > (client-secret (plist-get auth-data :client-secret)) > (redirect-uri (plist-get auth-data :redirect-uri)) > (state (plist-get auth-data :state))) I feel like this could be simplified with a map-let expression.=20=20 (map-let (:auth-url :token-url ...) auth-data ...) =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 You should be able to require 'map at compile time, so that the expansions don't occur an overhead during run-time. > (auth-source-do-trivia "Using oauth2 to auth and store toke= n...") > (let ((token (oauth2-auth-and-store > auth-url token-url scope client-id client-sec= ret > redirect-uri state))) > (auth-source-do-trivia "oauth2 token: %s" (pp-to-string t= oken)) > (auth-source-do-trivia "Refreshing token...") > (oauth2-refresh-access token) > (auth-source-do-trivia "oauth2 token after refresh: %s" > (pp-to-string token)) > (let ((access-token (oauth2-token-access-token token))) > (auth-source-do-trivia > "Updating :secret with access-token: %s" access-token) > (plist-put auth-data :secret access-token)))))) The documentation for plist-put warns: The new plist is returned; use =E2=80=98(setq x (plist-put x prop val))=E2=80=99 to be sure to use t= he new value. The PLIST is modified by side effects. Alternatively, you should also be able to do: (setf (plist-get auth-data :secret) access-token) > > (unless (and check-secret > (not (plist-get auth-data :secret))) > (auth-source-do-trivia "Updating auth-source-search results.") > (add-to-list 'res auth-data t))) This should definitely be a `push', as `res' is lexically scoped (see docstring for `add-to-list'). > res))) > > ;;;###autoload > (defun auth-source-xoauth2-plugin-enable () > "Enable auth-source-xoauth2-plugin." > (unless (memq 'xoauth2 smtpmail-auth-supported) > (add-to-list 'smtpmail-auth-supported 'xoauth2)) In functions, it would be more conventional to use push. Especially because `add-to-list' checks for duplicates, which you have already done. > > (advice-add 'auth-source-search-backends :around There's no reason not to sharp-quote the function here as well? > #'auth-source-xoauth2-plugin--search-backends)) I would recommend turning this into a global minor mode instead, so that it is easy to disable, if a user just wants to try it out. > > (provide 'auth-source-xoauth2-plugin) > > ;;; auth-source-xoauth2-plugin.el ends here --=20 Philip Kaludercic on siskin