Skip to content

Commit

Permalink
fix: login failed
Browse files Browse the repository at this point in the history
LeetCode do not allow third party login, retrieve LeetCode session from local
Chrome cookies. see: #46
  • Loading branch information
kaiwk committed Jan 1, 2020
1 parent 86e9e16 commit 28b78c4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 35 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2020-01-01 Wang Kai <kaiwkx@gmail.com>

* leetcode.el: leetcode.com don't allow third party login, so we retrieve LeetCode session from Chrome cookies

2019-10-11 Wang Kai <kaiwkx@gmail.com>

* leetcode.el (leetcode-try): When encounter syntax error, .expected_code_answer is null. Handle this situation depend on status_code.
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ LeetCode brings you offer, and now Emacs brings you LeetCode!

# Installation

You can `package-install` it from melpa directly.
- Vanilla Emacs: `package-install` it from melpa directly
- [Spacemacs](https://github.com/syl20bnr/spacemacs): [leetcode-emacs-layer](https://github.com/anmoljagetia/leetcode-emacs-layer)

LeetCode do not allow third party login, one workaround is restore LeetCode session from local Chrome cookies. To do this, you need to install a Python3 package called [my\_cookies](https://github.com/kaiwk/my_cookies): `pip3 install my_cookies`

## Manually

1. Clone this repository and install all dependencies
2. Move it to your load-path
3. Require it in your emacs config

If you use [spacemacs](https://github.com/syl20bnr/spacemacs), there is a [leetcode-emacs-layer](https://github.com/anmoljagetia/leetcode-emacs-layer). Thanks for [Anmol Jagetia](https://github.com/anmoljagetia)!

# Configuration

You can set your preferred LeetCode programming language and SQL by setting `leetcode-prefer-language` and `leetcode-prefer-sql`:
Expand All @@ -28,7 +29,7 @@ All supported languages can be found in variable `leetcode--prefer-language-suff

# Usage

1. Execute `leetcode` command, then Emacs will prompt you to input account and password. If login successful, Emacs will save it into a file. If you are interested in what happend here, you can check [auth-source.el](https://www.gnu.org/software/emacs/manual/html_mono/auth.html).
1. Execute `leetcode` command.

![leetcode](images/leetcode.png)

Expand Down
49 changes: 18 additions & 31 deletions leetcode.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
;; Keywords: extensions, tools
;; URL: https://github.com/kaiwk/leetcode.el
;; Package-Requires: ((emacs "26") (dash "2.16.0") (graphql "0.1.1") (spinner "1.7.3") (aio "1.0"))
;; Version: 0.1.9
;; Version: 0.1.10

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -188,38 +188,25 @@ VALUE should be the referer."
("filename" . "")
("content-type" . "")))

(aio-defun leetcode--login ()
(defun leetcode--login ()
"Send login request and return a deferred object.
When ACCOUNT or PASSWORD is empty string it will show a prompt."
(leetcode--loading-mode t)
(let* ((credentials (leetcode--credentials))
(account (nth 0 credentials))
(password (nth 1 credentials))
(save-func (nth 2 credentials))
(boundary (mml-compute-boundary '()))
(csrf-token (aio-await (leetcode--csrf-token)))
(url-request-method "POST")
(url-request-extra-headers
`(("Content-Type" . ,(concat "multipart/form-data; boundary=" boundary))
,leetcode--User-Agent
,leetcode--X-Requested-With
,(leetcode--referer leetcode--url-login)
,(cons leetcode--X-CSRFToken csrf-token)))
(url-request-data
(mm-url-encode-multipart-form-data
(list
(leetcode--multipart-form-data "csrfmiddlewaretoken" csrf-token)
(leetcode--multipart-form-data "login" account)
(leetcode--multipart-form-data "password" password))
boundary))
(result (aio-await (aio-url-retrieve leetcode--url-login))))
(if-let ((error-info (plist-get (car result) :error)))
(progn
(message "LeetCode login failed: %S" error-info)
(auth-source-forget+ :host leetcode--domain))
(when (functionp save-func)
(funcall save-func)))
(leetcode--loading-mode -1)))
(let ((my-cookies (executable-find "my_cookies")))
(set-process-filter
(start-process "my_cookies" nil "my_cookies")
(lambda (proc string)
(let* ((cookies-list (seq-filter
(lambda (s) (not (string-empty-p s)))
(split-string string "\n")))
(cookies-pairs (seq-map
(lambda (s) (split-string s))
cookies-list))
(leetcode-session (cadr (assoc "LEETCODE_SESSION" cookies-pairs)))
(leetcode-csrftoken (cadr (assoc "csrftoken" cookies-pairs))))
(url-cookie-store "LEETCODE_SESSION" leetcode-session nil leetcode--domain "/" t)
(url-cookie-store "csrftoken" leetcode-csrftoken nil leetcode--domain "/" t)))))
(leetcode--loading-mode -1))

(defun leetcode--login-p ()
"Whether user is login."
Expand Down Expand Up @@ -516,7 +503,7 @@ Return a list of rows, each row is a vector:
(if (get-buffer leetcode--buffer-name)
(switch-to-buffer leetcode--buffer-name)
(unless (leetcode--login-p)
(aio-await (leetcode--login)))
(leetcode--login))
(aio-await (leetcode-refresh-fetch))
(switch-to-buffer leetcode--buffer-name)))

Expand Down

0 comments on commit 28b78c4

Please sign in to comment.