Skip to content

Commit 28c5998

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 a24173f commit 28c5998

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
@@ -164,26 +164,17 @@
164164
(cl-defstruct (gptel--gh (:include gptel-openai)
165165
(:copier nil)
166166
(:constructor gptel--make-gh))
167-
token github-token sessionid machineid)
168-
169-
(defcustom gptel-gh-github-token-file (expand-file-name ".cache/copilot-chat/github-token"
170-
user-emacs-directory)
171-
"File where the GitHub token is stored."
172-
:type 'string
173-
:group 'gptel)
174-
175-
(defcustom gptel-gh-token-file (expand-file-name ".cache/copilot-chat/token"
176-
user-emacs-directory)
177-
"File where the chat token is cached."
178-
:type 'string
179-
:group 'gptel)
167+
sessionid machineid)
180168

181169
(defconst gptel--gh-auth-common-headers
182170
`(("editor-plugin-version" . "gptel/*")
183171
("editor-version" . ,(concat "emacs/" emacs-version))))
184172

185173
(defconst gptel--gh-client-id "Iv1.b507a08c87ecfe98")
186174

175+
(defvar gptel--gh-token nil)
176+
(defvar gptel--gh-github-token nil)
177+
187178
;; https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
188179
(defun gptel--gh-uuid ()
189180
"Generate a UUID v4-1."
@@ -203,26 +194,10 @@
203194
(setq hex (nconc hex (list (aref hex-chars (random 16))))))
204195
(apply #'string hex)))
205196

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

227202
(defun gptel-gh-login ()
228203
"Login to GitHub Copilot API.
@@ -254,13 +229,11 @@ If your browser does not open automatically, browse to %s."
254229
:device_code ,device_code
255230
:grant_type "urn:ietf:params:oauth:grant-type:device_code"))
256231
:access_token)
257-
(gptel--gh-save gptel-gh-github-token-file)
258-
(setf (gptel--gh-github-token gptel-backend))))
259-
(if (and (gptel--gh-github-token gptel-backend)
260-
(not (string-empty-p
261-
(gptel--gh-github-token gptel-backend))))
262-
(message "Successfully logged in to GitHub Copilot")
263-
(user-error "Error: You might not have access to GitHub Copilot Chat!")))
232+
(gptel--gh-save))
233+
(if (and gptel--gh-github-token
234+
(not (string-empty-p gptel--gh-github-token)))
235+
(message "Successfully logged in to GitHub Copilot")
236+
(user-error "Error: You might not have access to GitHub Copilot Chat!"))))
264237

265238
(defun gptel--gh-renew-token ()
266239
"Renew session token."
@@ -269,34 +242,22 @@ If your browser does not open automatically, browse to %s."
269242
"https://api.github.com/copilot_internal/v2/token"
270243
:method 'get
271244
:headers `(("authorization"
272-
. ,(format "token %s" (gptel--gh-github-token gptel-backend)))
245+
. ,(format "token %s" gptel--gh-github-token))
273246
,@gptel--gh-auth-common-headers))))
274247
(if (not (plist-get token :token))
275-
(progn
276-
(setf (gptel--gh-github-token gptel-backend) nil)
277-
(user-error "Error: You might not have access to GitHub Copilot Chat!"))
278-
(thread-last
279-
(gptel--gh-save gptel-gh-token-file token)
280-
(setf (gptel--gh-token gptel-backend))))))
248+
(user-error "Error: You might not have access to GitHub Copilot Chat!")
249+
(setq gptel--gh-token token))))
281250

282251
(defun gptel--gh-auth ()
283252
"Authenticate with GitHub Copilot API.
284253
285254
We first need github authorization (github token).
286255
Then we need a session token."
287-
(unless (gptel--gh-github-token gptel-backend)
288-
(let ((token (gptel--gh-restore gptel-gh-github-token-file)))
289-
(if token
290-
(setf (gptel--gh-github-token gptel-backend) token)
291-
(gptel-gh-login))))
292-
293-
(when (null (gptel--gh-token gptel-backend))
294-
;; try to load token from `gptel-gh-token-file'
295-
(setf (gptel--gh-token gptel-backend)
296-
(gptel--gh-restore gptel-gh-token-file)))
256+
(unless gptel--gh-github-token
257+
(gptel-gh-login))
297258

298259
(pcase-let (((map :token :expires_at)
299-
(gptel--gh-token gptel-backend)))
260+
gptel--gh-token))
300261
(when (or (null token)
301262
(and expires_at
302263
(> (round (float-time (current-time)))
@@ -309,8 +270,7 @@ Then we need a session token."
309270
(header (lambda ()
310271
(gptel--gh-auth)
311272
`(("openai-intent" . "conversation-panel")
312-
("authorization" . ,(concat "Bearer "
313-
(plist-get (gptel--gh-token gptel-backend) :token)))
273+
("authorization" . ,(concat "Bearer " (plist-get gptel--gh-token :token)))
314274
("x-request-id" . ,(gptel--gh-uuid))
315275
("vscode-sessionid" . ,(or (gptel--gh-sessionid gptel-backend) ""))
316276
("vscode-machineid" . ,(or (gptel--gh-machineid gptel-backend) ""))
@@ -322,7 +282,8 @@ Then we need a session token."
322282
(protocol "https")
323283
(endpoint "/chat/completions")
324284
(stream t)
325-
(models gptel--gh-models))
285+
(models gptel--gh-models)
286+
(github-token-init nil))
326287
"Register a Github Copilot chat backend for gptel with NAME.
327288
328289
Keyword arguments:
@@ -374,6 +335,9 @@ parameters (as plist keys) and values supported by the API. Use
374335
these to set parameters that gptel does not provide user options
375336
for."
376337
(declare (indent 1))
338+
(if (and (not gptel--gh-github-token)
339+
github-token-init)
340+
(gptel--gh-save (funcall github-token-init)))
377341
(let ((backend (gptel--make-gh
378342
:name name
379343
:host host

0 commit comments

Comments
 (0)