Skip to content

Commit 411bff5

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 df7accc commit 411bff5

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
@@ -170,26 +170,17 @@
170170
(cl-defstruct (gptel--gh (:include gptel-openai)
171171
(:copier nil)
172172
(:constructor gptel--make-gh))
173-
token github-token sessionid machineid)
174-
175-
(defcustom gptel-gh-github-token-file (expand-file-name ".cache/copilot-chat/github-token"
176-
user-emacs-directory)
177-
"File where the GitHub token is stored."
178-
:type 'string
179-
:group 'gptel)
180-
181-
(defcustom gptel-gh-token-file (expand-file-name ".cache/copilot-chat/token"
182-
user-emacs-directory)
183-
"File where the chat token is cached."
184-
:type 'string
185-
:group 'gptel)
173+
sessionid machineid)
186174

187175
(defconst gptel--gh-auth-common-headers
188176
`(("editor-plugin-version" . "gptel/*")
189177
("editor-version" . ,(concat "emacs/" emacs-version))))
190178

191179
(defconst gptel--gh-client-id "Iv1.b507a08c87ecfe98")
192180

181+
(defvar gptel--gh-token nil)
182+
(defvar gptel--gh-github-token nil)
183+
193184
;; https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
194185
(defun gptel--gh-uuid ()
195186
"Generate a UUID v4-1."
@@ -209,26 +200,10 @@
209200
(setq hex (nconc hex (list (aref hex-chars (random 16))))))
210201
(apply #'string hex)))
211202

212-
(defun gptel--gh-restore (file)
213-
"Restore saved object from FILE."
214-
(when (file-exists-p file)
215-
;; We set the coding system to `utf-8-auto-dos' when reading so that
216-
;; files with CR EOL can still be read properly
217-
(let ((coding-system-for-read 'utf-8-auto-dos))
218-
(with-temp-buffer
219-
(set-buffer-multibyte nil)
220-
(insert-file-contents-literally file)
221-
(goto-char (point-min))
222-
(read (current-buffer))))))
223-
224-
(defun gptel--gh-save (file obj)
203+
(defun gptel--gh-save (obj)
225204
"Save OBJ to FILE."
226-
(let ((print-length nil)
227-
(print-level nil)
228-
(coding-system-for-write 'utf-8-unix))
229-
(make-directory (file-name-directory file) t)
230-
(write-region (prin1-to-string obj) nil file nil :silent)
231-
obj))
205+
(message "New GitHub token: %s" (prin1-to-string obj))
206+
(setq gptel--gh-github-token obj))
232207

233208
(defun gptel-gh-login ()
234209
"Login to GitHub Copilot API.
@@ -260,13 +235,11 @@ If your browser does not open automatically, browse to %s."
260235
:device_code ,device_code
261236
:grant_type "urn:ietf:params:oauth:grant-type:device_code"))
262237
:access_token)
263-
(gptel--gh-save gptel-gh-github-token-file)
264-
(setf (gptel--gh-github-token gptel-backend))))
265-
(if (and (gptel--gh-github-token gptel-backend)
266-
(not (string-empty-p
267-
(gptel--gh-github-token gptel-backend))))
268-
(message "Successfully logged in to GitHub Copilot")
269-
(user-error "Error: You might not have access to GitHub Copilot Chat!")))
238+
(gptel--gh-save))
239+
(if (and gptel--gh-github-token
240+
(not (string-empty-p gptel--gh-github-token)))
241+
(message "Successfully logged in to GitHub Copilot")
242+
(user-error "Error: You might not have access to GitHub Copilot Chat!"))))
270243

271244
(defun gptel--gh-renew-token ()
272245
"Renew session token."
@@ -275,34 +248,22 @@ If your browser does not open automatically, browse to %s."
275248
"https://api.github.com/copilot_internal/v2/token"
276249
:method 'get
277250
:headers `(("authorization"
278-
. ,(format "token %s" (gptel--gh-github-token gptel-backend)))
251+
. ,(format "token %s" gptel--gh-github-token))
279252
,@gptel--gh-auth-common-headers))))
280253
(if (not (plist-get token :token))
281-
(progn
282-
(setf (gptel--gh-github-token gptel-backend) nil)
283-
(user-error "Error: You might not have access to GitHub Copilot Chat!"))
284-
(thread-last
285-
(gptel--gh-save gptel-gh-token-file token)
286-
(setf (gptel--gh-token gptel-backend))))))
254+
(user-error "Error: You might not have access to GitHub Copilot Chat!")
255+
(setq gptel--gh-token token))))
287256

288257
(defun gptel--gh-auth ()
289258
"Authenticate with GitHub Copilot API.
290259
291260
We first need github authorization (github token).
292261
Then we need a session token."
293-
(unless (gptel--gh-github-token gptel-backend)
294-
(let ((token (gptel--gh-restore gptel-gh-github-token-file)))
295-
(if token
296-
(setf (gptel--gh-github-token gptel-backend) token)
297-
(gptel-gh-login))))
298-
299-
(when (null (gptel--gh-token gptel-backend))
300-
;; try to load token from `gptel-gh-token-file'
301-
(setf (gptel--gh-token gptel-backend)
302-
(gptel--gh-restore gptel-gh-token-file)))
262+
(unless gptel--gh-github-token
263+
(gptel-gh-login))
303264

304265
(pcase-let (((map :token :expires_at)
305-
(gptel--gh-token gptel-backend)))
266+
gptel--gh-token))
306267
(when (or (null token)
307268
(and expires_at
308269
(> (round (float-time (current-time)))
@@ -315,8 +276,7 @@ Then we need a session token."
315276
(header (lambda ()
316277
(gptel--gh-auth)
317278
`(("openai-intent" . "conversation-panel")
318-
("authorization" . ,(concat "Bearer "
319-
(plist-get (gptel--gh-token gptel-backend) :token)))
279+
("authorization" . ,(concat "Bearer " (plist-get gptel--gh-token :token)))
320280
("x-request-id" . ,(gptel--gh-uuid))
321281
("vscode-sessionid" . ,(or (gptel--gh-sessionid gptel-backend) ""))
322282
("vscode-machineid" . ,(or (gptel--gh-machineid gptel-backend) ""))
@@ -328,7 +288,8 @@ Then we need a session token."
328288
(protocol "https")
329289
(endpoint "/chat/completions")
330290
(stream t)
331-
(models gptel--gh-models))
291+
(models gptel--gh-models)
292+
(github-token-init nil))
332293
"Register a Github Copilot chat backend for gptel with NAME.
333294
334295
Keyword arguments:
@@ -380,6 +341,9 @@ parameters (as plist keys) and values supported by the API. Use
380341
these to set parameters that gptel does not provide user options
381342
for."
382343
(declare (indent 1))
344+
(if (and (not gptel--gh-github-token)
345+
github-token-init)
346+
(gptel--gh-save (funcall github-token-init)))
383347
(let ((backend (gptel--make-gh
384348
:name name
385349
:host host

0 commit comments

Comments
 (0)