Skip to content

Commit d6395d4

Browse files
gptel-gh: Change how tokens are managed
Removed the file based persistent storage of the tokens, as they were stored in clear text. They will only be stored in variables. The initial value of the github-token can now be set by providing a function that provides it. This enables this token to be securely stored outside of Emacs.
1 parent 0c32dbd commit d6395d4

File tree

1 file changed

+24
-60
lines changed

1 file changed

+24
-60
lines changed

gptel-gh.el

Lines changed: 24 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -186,26 +186,17 @@
186186
(cl-defstruct (gptel--gh (:include gptel-openai)
187187
(:copier nil)
188188
(:constructor gptel--make-gh))
189-
token github-token sessionid machineid)
190-
191-
(defcustom gptel-gh-github-token-file (expand-file-name ".cache/copilot-chat/github-token"
192-
user-emacs-directory)
193-
"File where the GitHub token is stored."
194-
:type 'string
195-
:group 'gptel)
196-
197-
(defcustom gptel-gh-token-file (expand-file-name ".cache/copilot-chat/token"
198-
user-emacs-directory)
199-
"File where the chat token is cached."
200-
:type 'string
201-
:group 'gptel)
189+
sessionid machineid)
202190

203191
(defconst gptel--gh-auth-common-headers
204192
`(("editor-plugin-version" . "gptel/*")
205193
("editor-version" . ,(concat "emacs/" emacs-version))))
206194

207195
(defconst gptel--gh-client-id "Iv1.b507a08c87ecfe98")
208196

197+
(defvar gptel--gh-token nil)
198+
(defvar gptel--gh-github-token nil)
199+
209200
;; https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
210201
(defun gptel--gh-uuid ()
211202
"Generate a UUID v4-1."
@@ -225,26 +216,10 @@
225216
(setq hex (nconc hex (list (aref hex-chars (random 16))))))
226217
(apply #'string hex)))
227218

228-
(defun gptel--gh-restore (file)
229-
"Restore saved object from FILE."
230-
(when (file-exists-p file)
231-
;; We set the coding system to `utf-8-auto-dos' when reading so that
232-
;; files with CR EOL can still be read properly
233-
(let ((coding-system-for-read 'utf-8-auto-dos))
234-
(with-temp-buffer
235-
(set-buffer-multibyte nil)
236-
(insert-file-contents-literally file)
237-
(goto-char (point-min))
238-
(read (current-buffer))))))
239-
240-
(defun gptel--gh-save (file obj)
219+
(defun gptel--gh-save (obj)
241220
"Save OBJ to FILE."
242-
(let ((print-length nil)
243-
(print-level nil)
244-
(coding-system-for-write 'utf-8-unix))
245-
(make-directory (file-name-directory file) t)
246-
(write-region (prin1-to-string obj) nil file nil :silent)
247-
obj))
221+
(message "New GitHub token: %s" (prin1-to-string obj))
222+
(setq gptel--gh-github-token obj))
248223

249224
(defun gptel-gh-login ()
250225
"Login to GitHub Copilot API.
@@ -276,13 +251,11 @@ If your browser does not open automatically, browse to %s."
276251
:device_code ,device_code
277252
:grant_type "urn:ietf:params:oauth:grant-type:device_code"))
278253
:access_token)
279-
(gptel--gh-save gptel-gh-github-token-file)
280-
(setf (gptel--gh-github-token gptel-backend))))
281-
(if (and (gptel--gh-github-token gptel-backend)
282-
(not (string-empty-p
283-
(gptel--gh-github-token gptel-backend))))
284-
(message "Successfully logged in to GitHub Copilot")
285-
(user-error "Error: You might not have access to GitHub Copilot Chat!")))
254+
(gptel--gh-save))
255+
(if (and gptel--gh-github-token
256+
(not (string-empty-p gptel--gh-github-token)))
257+
(message "Successfully logged in to GitHub Copilot")
258+
(user-error "Error: You might not have access to GitHub Copilot Chat!"))))
286259

287260
(defun gptel--gh-renew-token ()
288261
"Renew session token."
@@ -291,34 +264,22 @@ If your browser does not open automatically, browse to %s."
291264
"https://api.github.com/copilot_internal/v2/token"
292265
:method 'get
293266
:headers `(("authorization"
294-
. ,(format "token %s" (gptel--gh-github-token gptel-backend)))
267+
. ,(format "token %s" gptel--gh-github-token))
295268
,@gptel--gh-auth-common-headers))))
296269
(if (not (plist-get token :token))
297-
(progn
298-
(setf (gptel--gh-github-token gptel-backend) nil)
299-
(user-error "Error: You might not have access to GitHub Copilot Chat!"))
300-
(thread-last
301-
(gptel--gh-save gptel-gh-token-file token)
302-
(setf (gptel--gh-token gptel-backend))))))
270+
(user-error "Error: You might not have access to GitHub Copilot Chat!")
271+
(setq gptel--gh-token token))))
303272

304273
(defun gptel--gh-auth ()
305274
"Authenticate with GitHub Copilot API.
306275

307276
We first need github authorization (github token).
308277
Then we need a session token."
309-
(unless (gptel--gh-github-token gptel-backend)
310-
(let ((token (gptel--gh-restore gptel-gh-github-token-file)))
311-
(if token
312-
(setf (gptel--gh-github-token gptel-backend) token)
313-
(gptel-gh-login))))
314-
315-
(when (null (gptel--gh-token gptel-backend))
316-
;; try to load token from `gptel-gh-token-file'
317-
(setf (gptel--gh-token gptel-backend)
318-
(gptel--gh-restore gptel-gh-token-file)))
278+
(unless gptel--gh-github-token
279+
(gptel-gh-login))
319280

320281
(pcase-let (((map :token :expires_at)
321-
(gptel--gh-token gptel-backend)))
282+
gptel--gh-token))
322283
(when (or (null token)
323284
(and expires_at
324285
(> (round (float-time (current-time)))
@@ -331,8 +292,7 @@ Then we need a session token."
331292
(header (lambda ()
332293
(gptel--gh-auth)
333294
`(("openai-intent" . "conversation-panel")
334-
("authorization" . ,(concat "Bearer "
335-
(plist-get (gptel--gh-token gptel-backend) :token)))
295+
("authorization" . ,(concat "Bearer " (plist-get gptel--gh-token :token)))
336296
("x-request-id" . ,(gptel--gh-uuid))
337297
("vscode-sessionid" . ,(or (gptel--gh-sessionid gptel-backend) ""))
338298
("vscode-machineid" . ,(or (gptel--gh-machineid gptel-backend) ""))
@@ -344,7 +304,8 @@ Then we need a session token."
344304
(protocol "https")
345305
(endpoint "/chat/completions")
346306
(stream t)
347-
(models gptel--gh-models))
307+
(models gptel--gh-models)
308+
(github-token-init nil))
348309
"Register a Github Copilot chat backend for gptel with NAME.
349310

350311
Keyword arguments:
@@ -396,6 +357,9 @@ parameters (as plist keys) and values supported by the API. Use
396357
these to set parameters that gptel does not provide user options
397358
for."
398359
(declare (indent 1))
360+
(if (and (not gptel--gh-github-token)
361+
github-token-init)
362+
(gptel--gh-save (funcall github-token-init)))
399363
(let ((backend (gptel--make-gh
400364
:name name
401365
:host host

0 commit comments

Comments
 (0)