Skip to content

Commit

Permalink
Merge branch 'xoauth2'
Browse files Browse the repository at this point in the history
  • Loading branch information
kazu-yamamoto committed Apr 29, 2024
2 parents 82c531e + 0d3bcff commit e16e133
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 106 deletions.
72 changes: 0 additions & 72 deletions elisp/mew-auth.el
Original file line number Diff line number Diff line change
Expand Up @@ -67,78 +67,6 @@
(defun mew-keyed-md5 (key passwd)
(mew-md5 (concat key passwd)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; XOAUTH2

(defun mew-auth-xoauth2-auth-string (user token)
;; base64(user=user@example.com^Aauth=Bearer ya29vF9dft4...^A^A)
(base64-encode-string (format "user=%s\1auth=Bearer %s\1\1" user token) t))

(defun mew-auth-xoauth2-json-status (status-string)
;; https://developers.google.com/gmail/imap/xoauth2-protocol#error_response_2
(require 'json)
(let ((json-status
(ignore-errors
(json-read-from-string
(base64-decode-string status-string)))))
(if json-status
(if (string-match "^2" (cdr (assoc 'status json-status)))
"OK" ;; 2XX
"NO") ;; XXX: Anyway NO?
"OK"))) ;; XXX: Maybe OK if not JSON.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; OAuth2

(defvar mew-auth-oauth2-client-id
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com")

(defvar mew-auth-oauth2-client-secret
"xxxxxxxxxxxxxxxxxxxxxxxx")

(defvar mew-auth-oauth2-auth-url "https://accounts.google.com/o/oauth2/auth"
"OAuth2 auth server URL.")

(defvar mew-auth-oauth2-token-url "https://accounts.google.com/o/oauth2/token"
"OAuth2 token server URL.")

(defvar mew-auth-oauth2-resource-url "https://mail.google.com/"
"URL used to request access to Mail Resources.")

(defvar mew-auth-oauth2-redirect-url nil
"URL used to OAuth redirect url.")

(declare-function oauth2-auth-and-store "oauth2")
(declare-function oauth2-refresh-access "oauth2")
(declare-function oauth2-token-access-token "oauth2")

(defun mew-auth-oauth2-auth-and-store
(resource-url client-id client-secret &optional redirect-url)
"Request access to a mail resource and store it using `auth-source'."
(require 'oauth2)
(oauth2-auth-and-store
mew-auth-oauth2-auth-url
mew-auth-oauth2-token-url
resource-url
client-id
client-secret
redirect-url))

(defun mew-auth-oauth2-token ()
"Get OAuth token for Mew to access mail service."
(require 'oauth2)
(let ((token (mew-auth-oauth2-auth-and-store
mew-auth-oauth2-resource-url
mew-auth-oauth2-client-id
mew-auth-oauth2-client-secret
mew-auth-oauth2-redirect-url)))
(oauth2-refresh-access token)
token))

(defun mew-auth-oauth2-token-access-token ()
(require 'oauth2)
(ignore-errors (oauth2-token-access-token (mew-auth-oauth2-token))))

(provide 'mew-auth)

;;; Copyright Notice:
Expand Down
27 changes: 3 additions & 24 deletions elisp/mew-imap.el
Original file line number Diff line number Diff line change
Expand Up @@ -1015,39 +1015,18 @@
;; XOAUTH2

(defun mew-imap-command-auth-xoauth2 (pro pnm)
(let* ((user (mew-imap-get-user pnm))
(token (mew-auth-oauth2-token-access-token))
(auth-string (mew-auth-xoauth2-auth-string user token)))
;; XXX: need to reset satus if token is nil.
(let* ((tag (mew-imap-passtag pnm))
(auth-string (mew-xoauth2-auth-string tag)))
(mew-imap-process-send-string pro pnm (format "AUTHENTICATE XOAUTH2 %s" auth-string))
(mew-imap-set-status pnm "auth-xoauth2")))

;; XXX: defalias does not work!
;; (defalias 'mew-imap2-command-auth-xoauth2 'mew-imap-command-auth-xoauth2)
(defun mew-imap2-command-auth-xoauth2 (pro pnm)
(let* ((user (mew-imap2-get-user pnm))
(token (mew-auth-oauth2-token-access-token))
(auth-string (mew-auth-xoauth2-auth-string user token)))
;; XXX: need to reset satus if token is nil.
(mew-imap2-process-send-string pro pnm (format "AUTHENTICATE XOAUTH2 %s" auth-string))
(mew-imap2-set-status pnm "auth-xoauth2")))

(defun mew-imap-command-xoauth2-wpwd (pro pnm)
(mew-imap-set-done pnm t)
(mew-passwd-set-passwd (mew-imap-passtag pnm) nil)
(delete-process pro)
;; XXX: Should be cared more! Clear process and filter without sending LOGOUT.
(error "IMAP XOAUTH2 token is wrong!"))

;; XXX: defalias does not work!
;; (defalias 'mew-imap2-command-xoauth2-wpwd 'mew-imap-command-xoauth2-wpwd)
(defun mew-imap2-command-xoauth2-wpwd (pro pnm)
(mew-imap2-set-done pnm t)
(mew-passwd-set-passwd (mew-imap2-passtag pnm) nil)
(delete-process pro)
;; XXX: Should be cared more! Clear process and filter without sending LOGOUT.
(error "IMAP XOAUTH2 token is wrong!"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Sub functions
Expand Down Expand Up @@ -1551,7 +1530,7 @@
(setq next (mew-imap-fsm-next
status
(if (string= status "auth-xoauth2")
(mew-auth-xoauth2-json-status (mew-match-string 1))
(mew-xoauth2-json-status (mew-match-string 1))
"OK"))))
((and (goto-char (point-max)) (= (forward-line -1) 0) (looking-at eos))
(mew-imap-set-tag pnm nil)
Expand Down
20 changes: 19 additions & 1 deletion elisp/mew-imap2.el
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,23 @@
(epasswd (mew-base64-encode-string passwd)))
(mew-imap2-process-send-string2 pro epasswd)))

;;;;;;;;;;;;;;;;
;; XOAUTH2

(defun mew-imap2-command-auth-xoauth2 (pro pnm)
(let* ((tag (mew-imap2-passtag pnm))
(auth-string (mew-xoauth2-auth-string tag)))
;; XXX: need to reset satus if token is nil.
(mew-imap2-process-send-string pro pnm (format "AUTHENTICATE XOAUTH2 %s" auth-string))
(mew-imap2-set-status pnm "auth-xoauth2")))

(defun mew-imap2-command-xoauth2-wpwd (pro pnm)
(mew-imap2-set-done pnm t)
(mew-passwd-set-passwd (mew-imap2-passtag pnm) nil)
(delete-process pro)
;; XXX: Should be cared more! Clear process and filter without sending LOGOUT.
(error "IMAP XOAUTH2 token is wrong!"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Sub functions
Expand Down Expand Up @@ -581,7 +598,8 @@ with '*' in the region are handled."
(setq next (mew-imap2-fsm-next
status
(if (string= status "auth-xoauth2")
(mew-auth-xoauth2-json-status (mew-match-string 1))
(mew-xoauth2-json-status (mew-match-string 1))
"OK"
"OK"))))
((string-match eos str)
(mew-imap2-set-tag pnm nil)
Expand Down
Loading

0 comments on commit e16e133

Please sign in to comment.