From 6dc0328f6d948186a51c5605a2c07cdbc2f7af0c Mon Sep 17 00:00:00 2001
From: shuzijun
Date: Wed, 9 Sep 2020 14:05:13 +0800
Subject: [PATCH] Fix compatibility
---
doc/LoginHelp.md | 5 +-
doc/LoginHelp_ZH.md | 7 +-
.../plugin/actions/toolbar/LoginAction.java | 27 +-
.../leetcode/plugin/setting/SettingUI.java | 13 +-
.../leetcode/plugin/window/CookieLogin.java | 131 +++++++
.../leetcode/plugin/window/HttpLogin.java | 158 +++++++++
.../leetcode/plugin/window/JcefLogin.java | 126 +++++++
.../leetcode/plugin/window/LoginFrame.java | 334 +-----------------
8 files changed, 437 insertions(+), 364 deletions(-)
create mode 100644 src/main/java/com/shuzijun/leetcode/plugin/window/CookieLogin.java
create mode 100644 src/main/java/com/shuzijun/leetcode/plugin/window/HttpLogin.java
create mode 100644 src/main/java/com/shuzijun/leetcode/plugin/window/JcefLogin.java
diff --git a/doc/LoginHelp.md b/doc/LoginHelp.md
index 9523247a..76f00078 100644
--- a/doc/LoginHelp.md
+++ b/doc/LoginHelp.md
@@ -14,5 +14,6 @@
## browser login
- This login requires additional download of dependent files. Download the compressed package with the version number ** jcef ** at the [releases](https://github.com/shuzijun/leetcode-editor/releases) address. After downloading, decompress it to the path of JCEFFilePath shown on the configuration page.
- If there is a resource file in the path, this login method will be used first, but this method is not compatible. If it cannot be loaded normally, you need to delete the contents of the folder and log in using other methods.
+ ~~This login requires additional download of dependent files. Download the compressed package with the version number ** jcef ** at the [releases](https://github.com/shuzijun/leetcode-editor/releases) address. After downloading, decompress it to the path of JCEFFilePath shown on the configuration page.~~
+ ~~If there is a resource file in the path, this login method will be used first, but this method is not compatible. If it cannot be loaded normally, you need to delete the contents of the folder and log in using other methods.~~
+ Starting from version 6.8, external mounting of JCEF is no longer supported. Instead, JCEF provided by JetBrains is used. The supported version is 2020.2+. If you meet the conditions of use, you can check JCEF in the configuration item.
\ No newline at end of file
diff --git a/doc/LoginHelp_ZH.md b/doc/LoginHelp_ZH.md
index 5946f70e..d57dfa75 100644
--- a/doc/LoginHelp_ZH.md
+++ b/doc/LoginHelp_ZH.md
@@ -14,6 +14,7 @@
## 浏览器登录
- 此登录需要额外下载依赖文件,在地址[releases](https://github.com/shuzijun/leetcode-editor/releases)下载版号带有**jcef**的压缩包,
- 下载后,解压到配置页展示的JCEFFilePath的路径中。
- 如路径中存在资源文件,将首先使用此登录方式,但此方式兼容性差,如不能正常加载,需删除文件夹下内容,使用其他方式登录。
+ ~~此登录需要额外下载依赖文件,在地址[releases](https://github.com/shuzijun/leetcode-editor/releases)下载版号带有**jcef**的压缩包,~~
+ ~~下载后,解压到配置页展示的JCEFFilePath的路径中。 ~~
+ ~~如路径中存在资源文件,将首先使用此登录方式,但此方式兼容性差,如不能正常加载,需删除文件夹下内容,使用其他方式登录。~~
+ 从版本6.8开始,不再支持外部挂载JCEF,改用JetBrains提供的JCEF,支持版本为2020.2+,如果满足使用条件,可以在配置项中勾选JCEF
\ No newline at end of file
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
index 1ce520a9..17fcdfc4 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
@@ -7,8 +7,7 @@
import com.shuzijun.leetcode.plugin.model.Config;
import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
import com.shuzijun.leetcode.plugin.utils.*;
-import com.shuzijun.leetcode.plugin.window.LoginFrame;
-import com.shuzijun.leetcode.plugin.window.WindowFactory;
+import com.shuzijun.leetcode.plugin.window.*;
import org.apache.commons.lang.StringUtils;
import javax.swing.*;
@@ -20,8 +19,8 @@
*/
public class LoginAction extends AbstractAction {
- @Override
- public void actionPerformed(AnActionEvent anActionEvent, Config config) {
+ @Override
+ public void actionPerformed(AnActionEvent anActionEvent, Config config) {
JTree tree = WindowFactory.getDataContext(anActionEvent.getProject()).getData(DataKeys.LEETCODE_PROJECTS_TREE);
@@ -61,22 +60,16 @@ public void actionPerformed(AnActionEvent anActionEvent, Config config) {
}
}
-
- if (URLUtils.leetcodecn.equals(URLUtils.getLeetcodeHost())) {
- if (!LoginFrame.httpLogin.ajaxLogin(config, tree, anActionEvent.getProject())) {
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
- @Override
- public void run() {
- LoginFrame loginFrame = new LoginFrame(anActionEvent.getProject(), tree);
- loginFrame.loadComponent();
- }
- });
- }
- } else {
+ if (!HttpLogin.ajaxLogin(config, tree, anActionEvent.getProject())) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
- LoginFrame loginFrame = new LoginFrame(anActionEvent.getProject(), tree);
+ LoginFrame loginFrame;
+ if (HttpLogin.isSupportedJcef()) {
+ loginFrame = new JcefLogin(anActionEvent.getProject(), tree);
+ } else {
+ loginFrame = new CookieLogin(anActionEvent.getProject(), tree);
+ }
loginFrame.loadComponent();
}
});
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java b/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
index e1d0ff84..6d736344 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
@@ -13,7 +13,6 @@
import com.intellij.ui.components.JBPasswordField;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBTextField;
-import com.intellij.ui.jcef.JBCefApp;
import com.intellij.util.net.HttpConfigurable;
import com.shuzijun.leetcode.plugin.listener.ColorListener;
import com.shuzijun.leetcode.plugin.listener.DonateListener;
@@ -25,6 +24,7 @@
import com.shuzijun.leetcode.plugin.utils.MTAUtils;
import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
import com.shuzijun.leetcode.plugin.utils.URLUtils;
+import com.shuzijun.leetcode.plugin.window.HttpLogin;
import org.apache.commons.lang.StringUtils;
import javax.swing.*;
@@ -92,15 +92,8 @@ public void mouseClicked(MouseEvent e) {
}
}
});
- Boolean jcefSupported;
- try {
- jcefSupported = JBCefApp.isSupported();
- }catch (Throwable e){
- jcefSupported = false;
- }
- if(!jcefSupported){
- proxyCheckBox.setEnabled(true);
- }
+
+ jcefCheckBox.setEnabled(!HttpLogin.isSupportedJcef());
templateConfigHelp.addMouseListener(new MouseAdapter() {
@Override
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/CookieLogin.java b/src/main/java/com/shuzijun/leetcode/plugin/window/CookieLogin.java
new file mode 100644
index 00000000..bbc731f6
--- /dev/null
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/CookieLogin.java
@@ -0,0 +1,131 @@
+package com.shuzijun.leetcode.plugin.window;
+
+import com.intellij.ide.BrowserUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.ui.components.JBPanel;
+import com.intellij.ui.components.JBScrollPane;
+import com.shuzijun.leetcode.plugin.utils.HttpRequestUtils;
+import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
+import com.shuzijun.leetcode.plugin.utils.URLUtils;
+import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.net.HttpCookie;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author shuzijun
+ */
+public class CookieLogin implements LoginFrame {
+ private JTree tree;
+ private Project project;
+
+
+ public CookieLogin(Project project, JTree tree) {
+ this.tree = tree;
+ this.project = project;
+ }
+
+ @Override
+ public void loadComponent() {
+ CookiePanel cookiePanel = new CookiePanel(project);
+ if (cookiePanel.showAndGet()) {
+ String cookiesString = cookiePanel.cookieText();
+ if (StringUtils.isBlank(cookiesString)) {
+ JOptionPane.showMessageDialog(null, "cookie is null");
+ return;
+ }
+ final List cookieList = new ArrayList<>();
+ String[] cookies = cookiesString.split(";");
+ for (String cookieString : cookies) {
+ String[] cookie = cookieString.trim().split("=");
+ if (cookie.length >= 2) {
+ try {
+ HttpCookie basicClientCookie = new HttpCookie(cookie[0], cookie[1]);
+ basicClientCookie.setDomain("." + URLUtils.getLeetcodeHost());
+ basicClientCookie.setPath("/");
+ cookieList.add(basicClientCookie);
+ } catch (IllegalArgumentException ignore) {
+
+ }
+ }
+ }
+ HttpRequestUtils.setCookie(cookieList);
+
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, "leetcode.loginSuccess", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator progressIndicator) {
+ if (HttpRequestUtils.isLogin()) {
+ HttpLogin.loginSuccess(tree, project, cookieList);
+ } else {
+ JOptionPane.showMessageDialog(null, PropertiesUtils.getInfo("login.failed"));
+ }
+
+ }
+ });
+ }
+ }
+
+ class CookiePanel extends DialogWrapper {
+
+ private JPanel jpanel;
+ private JTextArea caseText;
+
+ public CookiePanel(Project project) {
+ super(project, Boolean.TRUE);
+
+ jpanel = new JBPanel();
+ jpanel.setLayout(new BorderLayout());
+ caseText = new JTextArea();
+ caseText.setLineWrap(true);
+ caseText.setMinimumSize(new Dimension(400, 200));
+ caseText.setPreferredSize(new Dimension(400, 200));
+ jpanel.add(new JBScrollPane(caseText, JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JBScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
+ setModal(true);
+ init();
+ setTitle("Cookie login");
+ }
+
+ @NotNull
+ @Override
+ protected Action getOKAction() {
+ Action action = super.getOKAction();
+ action.putValue(Action.NAME, "login");
+ return action;
+ }
+
+ @NotNull
+ @Override
+ protected Action[] createActions() {
+ Action helpAction = new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ BrowserUtil.browse("https://github.com/shuzijun/leetcode-editor/blob/master/doc/LoginHelp.md");
+ }
+
+ };
+ helpAction.putValue(Action.NAME, "help");
+ Action[] actions = new Action[]{helpAction, this.getOKAction(), this.getCancelAction()};
+ return actions;
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return jpanel;
+ }
+
+ public String cookieText() {
+ return caseText.getText();
+ }
+ }
+}
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/HttpLogin.java b/src/main/java/com/shuzijun/leetcode/plugin/window/HttpLogin.java
new file mode 100644
index 00000000..70d54748
--- /dev/null
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/HttpLogin.java
@@ -0,0 +1,158 @@
+package com.shuzijun.leetcode.plugin.window;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.shuzijun.leetcode.plugin.manager.ViewManager;
+import com.shuzijun.leetcode.plugin.model.Config;
+import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
+import com.shuzijun.leetcode.plugin.utils.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.lang.reflect.Method;
+import java.net.HttpCookie;
+import java.util.List;
+
+/**
+ * @author shuzijun
+ */
+public class HttpLogin {
+ public static boolean ajaxLogin(Config config, JTree tree, Project project) {
+
+ if (URLUtils.leetcode.equals(URLUtils.getLeetcodeHost())) {
+ return Boolean.FALSE;
+ }
+
+ if (StringUtils.isBlank(PersistentConfig.getInstance().getPassword())) {
+ return Boolean.FALSE;
+ }
+
+ try {
+ HttpEntity ent = MultipartEntityBuilder.create()
+ .addTextBody("csrfmiddlewaretoken", HttpRequestUtils.getToken())
+ .addTextBody("login", config.getLoginName())
+ .addTextBody("password", PersistentConfig.getInstance().getPassword())
+ .addTextBody("next", "/problems")
+ .build();
+ HttpRequest httpRequest = HttpRequest.post(URLUtils.getLeetcodeLogin(), ent.getContentType().getValue());
+ httpRequest.setBody(IOUtils.toString(ent.getContent(), "UTF-8"));
+ httpRequest.addHeader("x-requested-with", "XMLHttpRequest");
+ httpRequest.addHeader("accept", "*/*");
+ HttpResponse response = HttpRequestUtils.executePost(httpRequest);
+
+ if (response == null) {
+ MessageUtils.getInstance(project).showWarnMsg("warning", PropertiesUtils.getInfo("request.failed"));
+ return Boolean.FALSE;
+ }
+
+ String body = response.getBody();
+
+ if ((response.getStatusCode() == 200 || response.getStatusCode() == 302)) {
+ if (StringUtils.isNotBlank(body) && body.startsWith("{")) {
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ JSONArray jsonArray = jsonObject.getJSONObject("form").getJSONArray("errors");
+ if (jsonArray.isEmpty()) {
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
+ examineEmail(project);
+ ViewManager.loadServiceData(tree, project);
+ return Boolean.TRUE;
+ } else {
+ MessageUtils.getInstance(project).showInfoMsg("info", StringUtils.join(jsonArray, ","));
+ return Boolean.FALSE;
+ }
+ } else if (StringUtils.isBlank(body)) {
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
+ examineEmail(project);
+ ViewManager.loadServiceData(tree, project);
+ return Boolean.TRUE;
+ } else {
+ HttpRequestUtils.resetHttpclient();
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.unknown"));
+ SentryUtils.submitErrorReport(null, String.format("login.unknown:\nStatusCode:%s\nbody:%s", response.getStatusCode(), body));
+ return Boolean.FALSE;
+ }
+ } else if (response.getStatusCode() == 400) {
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ MessageUtils.getInstance(project).showInfoMsg("info", StringUtils.join(jsonObject.getJSONObject("form").getJSONArray("errors"), ","));
+ return Boolean.FALSE;
+ } else {
+ HttpRequestUtils.resetHttpclient();
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.unknown"));
+ SentryUtils.submitErrorReport(null, String.format("login.unknown:\nStatusCode:%s\nbody:%s", response.getStatusCode(), body));
+ return Boolean.FALSE;
+ }
+ } catch (Exception e) {
+ LogUtils.LOG.error("登陆错误", e);
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.failed"));
+ return Boolean.FALSE;
+ }
+ }
+
+ public static void examineEmail(Project project) {
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ HttpRequest httpRequest = HttpRequest.post(URLUtils.getLeetcodeGraphql(), "application/json");
+ try {
+ httpRequest.setBody("{\"operationName\":\"user\",\"variables\":{},\"query\":\"query user {\\n user {\\n socialAccounts\\n username\\n emails {\\n email\\n primary\\n verified\\n __typename\\n }\\n phone\\n profile {\\n rewardStats\\n __typename\\n }\\n __typename\\n }\\n}\\n\"}");
+ httpRequest.addHeader("Accept", "application/json");
+ HttpResponse response = HttpRequestUtils.executePost(httpRequest);
+ if (response != null && response.getStatusCode() == 200) {
+
+ String body = response.getBody();
+
+ JSONArray jsonArray = JSONObject.parseObject(body).getJSONObject("data").getJSONObject("user").getJSONArray("emails");
+ if (jsonArray != null && jsonArray.size() > 0) {
+ for (int i = 0; i < jsonArray.size(); i++) {
+ JSONObject object = jsonArray.getJSONObject(i);
+ if (object.getBoolean("verified")) {
+ return;
+ }
+ }
+
+ }
+ MessageUtils.getInstance(project).showWarnMsg("info", PropertiesUtils.getInfo("user.email"));
+ }
+ } catch (Exception i) {
+ LogUtils.LOG.error("验证邮箱错误");
+ }
+ }
+ });
+ }
+
+ public static void loginSuccess(JTree tree, Project project, List cookieList) {
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, "leetcode.loginSuccess", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator progressIndicator) {
+ Config config = PersistentConfig.getInstance().getInitConfig();
+ config.addCookie(config.getUrl() + config.getLoginName(), CookieUtils.httpCookieToJSONString(cookieList));
+ PersistentConfig.getInstance().setInitConfig(config);
+ MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
+ ViewManager.loadServiceData(tree, project);
+ examineEmail(project);
+ }
+ });
+ }
+
+ public static boolean isSupportedJcef() {
+ try {
+ Class> JBCefAppClass = Class.forName("com.intellij.ui.jcef.JBCefApp");
+ Method method = JBCefAppClass.getMethod("isSupported");
+ boolean supported = (boolean) method.invoke(null);
+
+ Config config = PersistentConfig.getInstance().getInitConfig();
+ return config.getJcef() && supported;
+ } catch (Throwable e) {
+ return Boolean.FALSE;
+ }
+ }
+
+}
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/JcefLogin.java b/src/main/java/com/shuzijun/leetcode/plugin/window/JcefLogin.java
new file mode 100644
index 00000000..a5dbf0b3
--- /dev/null
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/JcefLogin.java
@@ -0,0 +1,126 @@
+package com.shuzijun.leetcode.plugin.window;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.wm.impl.IdeFrameImpl;
+import com.intellij.ui.jcef.JBCefBrowser;
+import com.shuzijun.leetcode.plugin.utils.HttpRequestUtils;
+import com.shuzijun.leetcode.plugin.utils.LogUtils;
+import com.shuzijun.leetcode.plugin.utils.URLUtils;
+import org.cef.browser.CefBrowser;
+import org.cef.browser.CefFrame;
+import org.cef.callback.CefCookieVisitor;
+import org.cef.handler.CefLoadHandler;
+import org.cef.handler.CefLoadHandlerAdapter;
+import org.cef.misc.BoolRef;
+import org.cef.network.CefCookie;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.net.HttpCookie;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author shuzijun
+ */
+public class JcefLogin implements LoginFrame {
+
+ private JTree tree;
+ private Project project;
+
+
+ public JcefLogin(Project project, JTree tree) {
+ this.tree = tree;
+ this.project = project;
+ }
+
+ @Override
+ public void loadComponent() {
+ Window activeFrame = IdeFrameImpl.getActiveFrame();
+ if (activeFrame == null) {
+ return;
+ }
+ Rectangle bounds = activeFrame.getGraphicsConfiguration().getBounds();
+ final JFrame frame = new IdeFrameImpl();
+ frame.setTitle("JCEF login");
+ frame.setAlwaysOnTop(true);
+ frame.setDefaultCloseOperation(2);
+ frame.setBounds(bounds.width / 4, bounds.height / 4, bounds.width / 2, bounds.height / 2);
+ frame.setLayout(new BorderLayout());
+
+ loadJCEFComponent(frame);
+
+ frame.setVisible(true);
+
+ }
+
+ private void loadJCEFComponent(JFrame frame) {
+ final JBCefBrowser jbCefBrowser = new JBCefBrowser(URLUtils.getLeetcodeLogin());
+
+ frame.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosed(WindowEvent e) {
+ jbCefBrowser.getJBCefCookieManager().deleteCookies(URLUtils.leetcode, false);
+ jbCefBrowser.getJBCefCookieManager().deleteCookies(URLUtils.leetcodecn, false);
+ Disposer.dispose(jbCefBrowser);
+ }
+ });
+
+
+ jbCefBrowser.getJBCefClient().addLoadHandler(new CefLoadHandlerAdapter() {
+
+ boolean successDispose = false;
+
+ @Override
+ public void onLoadError(CefBrowser browser, CefFrame frame, CefLoadHandler.ErrorCode errorCode, String errorText, String failedUrl) {
+ if (!successDispose) {
+ browser.executeJavaScript("alert('The page failed to load, please check the network and open it again')", "leetcode-editor", 0);
+ }
+ }
+
+ @Override
+ public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) {
+
+ jbCefBrowser.getJBCefCookieManager().getCefCookieManager().visitAllCookies(new CefCookieVisitor() {
+
+ private List cookieList = new ArrayList<>();
+
+ @Override
+ public boolean visit(CefCookie cefCookie, int count, int total, BoolRef boolRef) {
+
+ boolean isSession = Boolean.FALSE;
+ if (cefCookie.domain.contains("leetcode")) {
+ HttpCookie cookie = new HttpCookie(cefCookie.name, cefCookie.value);
+ cookie.setDomain(cefCookie.domain);
+ cookie.setPath(cefCookie.path);
+ cookieList.add(cookie);
+ if ("LEETCODE_SESSION".equals(cefCookie.name)) {
+ isSession = Boolean.TRUE;
+ }
+ }
+ if (count == total - 1 && isSession) {
+ HttpRequestUtils.setCookie(cookieList);
+ if (HttpRequestUtils.isLogin()) {
+ HttpLogin.loginSuccess(tree, project, cookieList);
+ //browser.executeJavaScript("alert('Login is successful. close the window')", "leetcode-editor", 0);
+ successDispose = true;
+ frame.dispose();
+ } else {
+ cookieList.clear();
+ LogUtils.LOG.info("login failure");
+ }
+ }
+ return true;
+ }
+ });
+ }
+ }, jbCefBrowser.getCefBrowser());
+
+ frame.add(jbCefBrowser.getComponent(), BorderLayout.CENTER);
+
+ }
+
+}
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/LoginFrame.java b/src/main/java/com/shuzijun/leetcode/plugin/window/LoginFrame.java
index 820a09a4..59afdc9e 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/LoginFrame.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/LoginFrame.java
@@ -1,340 +1,10 @@
package com.shuzijun.leetcode.plugin.window;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.intellij.ide.BrowserUtil;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.Task;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.wm.impl.IdeFrameImpl;
-import com.intellij.ui.jcef.JBCefApp;
-import com.intellij.ui.jcef.JBCefBrowser;
-import com.shuzijun.leetcode.plugin.manager.ViewManager;
-import com.shuzijun.leetcode.plugin.model.Config;
-import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
-import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.cef.browser.CefBrowser;
-import org.cef.browser.CefFrame;
-import org.cef.callback.CefCookieVisitor;
-import org.cef.handler.CefLoadHandlerAdapter;
-import org.cef.misc.BoolRef;
-import org.cef.network.CefCookie;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* @author shuzijun
*/
-public class LoginFrame {
-
- private JTree tree;
- private Project project;
-
-
- public LoginFrame(Project project, JTree tree) {
- this.tree = tree;
- this.project = project;
- }
-
- public void loadComponent() {
- Window activeFrame = IdeFrameImpl.getActiveFrame();
- if (activeFrame == null) {
- return;
- }
- Rectangle bounds = activeFrame.getGraphicsConfiguration().getBounds();
- final JFrame frame = new IdeFrameImpl();
- frame.setDefaultCloseOperation(2);
- frame.setBounds(bounds.width / 4, bounds.height / 4, bounds.width / 2, bounds.height / 2);
- frame.setLayout(new BorderLayout());
-
- if (classLoader()) {
- loadJCEFComponent(frame);
- } else {
- loadCookieComponent(frame);
- }
- frame.setVisible(true);
-
- }
-
- private void loadJCEFComponent(JFrame frame) {
- final JBCefBrowser jbCefBrowser = new JBCefBrowser(URLUtils.getLeetcodeLogin());
-
- frame.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosed(WindowEvent e) {
- jbCefBrowser.getJBCefCookieManager().deleteCookies(URLUtils.leetcode, false);
- jbCefBrowser.getJBCefCookieManager().deleteCookies(URLUtils.leetcodecn, false);
- Disposer.dispose(jbCefBrowser);
- }
- });
-
-
- jbCefBrowser.getJBCefClient().addLoadHandler(new CefLoadHandlerAdapter() {
-
- boolean successDispose = false;
-
- @Override
- public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode, String errorText, String failedUrl) {
- if(!successDispose) {
- browser.executeJavaScript("alert('The page failed to load, please check the network and open it again')", "leetcode-editor", 0);
- }
- }
-
- @Override
- public void onLoadingStateChange(CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) {
-
- jbCefBrowser.getJBCefCookieManager().getCefCookieManager().visitAllCookies(new CefCookieVisitor() {
-
- private List cookieList = new ArrayList<>();
- @Override
- public boolean visit(CefCookie cefCookie, int count, int total, BoolRef boolRef) {
-
- boolean isSession = Boolean.FALSE;
- if (cefCookie.domain.contains("leetcode")) {
- HttpCookie cookie = new HttpCookie(cefCookie.name, cefCookie.value);
- cookie.setDomain(cefCookie.domain);
- cookie.setPath(cefCookie.path);
- cookieList.add(cookie);
- if ("LEETCODE_SESSION".equals(cefCookie.name)) {
- isSession = Boolean.TRUE;
- }
- }
- if (count == total - 1 && isSession) {
- HttpRequestUtils.setCookie(cookieList);
- if (HttpRequestUtils.isLogin()) {
- loginSuccess(tree, project, cookieList);
- //browser.executeJavaScript("alert('Login is successful. close the window')", "leetcode-editor", 0);
- successDispose = true;
- frame.dispose();
- } else {
- cookieList.clear();
- LogUtils.LOG.info("login failure");
- }
- }
- return true;
- }
- });
- }
- }, jbCefBrowser.getCefBrowser());
-
- frame.add(jbCefBrowser.getComponent(), BorderLayout.CENTER);
-
- }
-
- private void loadCookieComponent(JFrame frame) {
-
- JTextArea cookieText = new JTextArea();
- cookieText.setLineWrap(true);
- cookieText.setMinimumSize(new Dimension(400, 200));
- cookieText.setPreferredSize(new Dimension(400, 200));
-
- frame.add(cookieText, BorderLayout.CENTER);
-
- JPanel buttonPanel = new JPanel();
- JButton cookieHelp = new JButton("help");
- cookieHelp.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- BrowserUtil.browse("https://github.com/shuzijun/leetcode-editor/blob/master/doc/LoginHelp.md");
- }
- });
-
- JButton loginButton = new JButton("login");
- loginButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- String cookiesString = cookieText.getText();
- if (StringUtils.isBlank(cookiesString)) {
- JOptionPane.showMessageDialog(null, "cookie is null");
- return;
- }
-
- final List cookieList = new ArrayList<>();
- String[] cookies = cookiesString.split(";");
- for (String cookieString : cookies) {
- String[] cookie = cookieString.trim().split("=");
- if (cookie.length >= 2) {
- try {
- HttpCookie basicClientCookie = new HttpCookie(cookie[0], cookie[1]);
- basicClientCookie.setDomain("." + URLUtils.getLeetcodeHost());
- basicClientCookie.setPath("/");
- cookieList.add(basicClientCookie);
- } catch (IllegalArgumentException ignore) {
-
- }
- }
- }
- HttpRequestUtils.setCookie(cookieList);
-
- ProgressManager.getInstance().run(new Task.Backgroundable(project, "leetcode.editor.login", false) {
- @Override
- public void run(@NotNull ProgressIndicator progressIndicator) {
- if (HttpRequestUtils.isLogin()) {
- loginSuccess(tree, project, cookieList);
- return;
- } else {
- JOptionPane.showMessageDialog(null, PropertiesUtils.getInfo("login.failed"));
- return;
- }
- }
- });
- frame.dispose();
- }
- });
-
- JButton closeButton = new JButton("close");
- closeButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- frame.dispose();
- }
- });
-
- buttonPanel.add(loginButton);
- buttonPanel.add(cookieHelp);
- buttonPanel.add(closeButton);
- frame.add(buttonPanel, BorderLayout.SOUTH);
-
- }
-
- private boolean classLoader() {
- synchronized (this) {
- try {
- Config config = PersistentConfig.getInstance().getInitConfig();
- return config.getJcef() && JBCefApp.isSupported();
- } catch (Throwable e) {
- return Boolean.FALSE;
- }
-
- }
- }
-
- private void loginSuccess(JTree tree, Project project, List cookieList) {
- ProgressManager.getInstance().run(new Task.Backgroundable(project, "leetcode.loginSuccess", false) {
- @Override
- public void run(@NotNull ProgressIndicator progressIndicator) {
- Config config = PersistentConfig.getInstance().getInitConfig();
- config.addCookie(config.getUrl() + config.getLoginName(), CookieUtils.httpCookieToJSONString(cookieList));
- PersistentConfig.getInstance().setInitConfig(config);
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
- ViewManager.loadServiceData(tree, project);
- httpLogin.examineEmail(project);
- }
- });
- }
-
- public static class httpLogin {
- public static boolean ajaxLogin(Config config, JTree tree, Project project) {
- if (StringUtils.isBlank(PersistentConfig.getInstance().getPassword())) {
- return Boolean.FALSE;
- }
-
- try {
- HttpEntity ent = MultipartEntityBuilder.create()
- .addTextBody("csrfmiddlewaretoken", HttpRequestUtils.getToken())
- .addTextBody("login", config.getLoginName())
- .addTextBody("password", PersistentConfig.getInstance().getPassword())
- .addTextBody("next", "/problems")
- .build();
- HttpRequest httpRequest = HttpRequest.post(URLUtils.getLeetcodeLogin(), ent.getContentType().getValue());
- httpRequest.setBody(IOUtils.toString(ent.getContent(), "UTF-8"));
- httpRequest.addHeader("x-requested-with", "XMLHttpRequest");
- httpRequest.addHeader("accept", "*/*");
- HttpResponse response = HttpRequestUtils.executePost(httpRequest);
-
- if (response == null) {
- MessageUtils.getInstance(project).showWarnMsg("warning", PropertiesUtils.getInfo("request.failed"));
- return Boolean.FALSE;
- }
-
- String body = response.getBody();
-
- if ((response.getStatusCode() == 200 || response.getStatusCode() == 302)) {
- if (StringUtils.isNotBlank(body) && body.startsWith("{")) {
- JSONObject jsonObject = JSONObject.parseObject(body);
- JSONArray jsonArray = jsonObject.getJSONObject("form").getJSONArray("errors");
- if (jsonArray.isEmpty()) {
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
- examineEmail(project);
- ViewManager.loadServiceData(tree, project);
- return Boolean.TRUE;
- } else {
- MessageUtils.getInstance(project).showInfoMsg("info", StringUtils.join(jsonArray, ","));
- return Boolean.FALSE;
- }
- } else if (StringUtils.isBlank(body)) {
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.success"));
- examineEmail(project);
- ViewManager.loadServiceData(tree, project);
- return Boolean.TRUE;
- } else {
- HttpRequestUtils.resetHttpclient();
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.unknown"));
- SentryUtils.submitErrorReport(null, String.format("login.unknown:\nStatusCode:%s\nbody:%s", response.getStatusCode(), body));
- return Boolean.FALSE;
- }
- } else if (response.getStatusCode() == 400) {
- JSONObject jsonObject = JSONObject.parseObject(body);
- MessageUtils.getInstance(project).showInfoMsg("info", StringUtils.join(jsonObject.getJSONObject("form").getJSONArray("errors"), ","));
- return Boolean.FALSE;
- } else {
- HttpRequestUtils.resetHttpclient();
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.unknown"));
- SentryUtils.submitErrorReport(null, String.format("login.unknown:\nStatusCode:%s\nbody:%s", response.getStatusCode(), body));
- return Boolean.FALSE;
- }
- } catch (Exception e) {
- LogUtils.LOG.error("登陆错误", e);
- MessageUtils.getInstance(project).showInfoMsg("info", PropertiesUtils.getInfo("login.failed"));
- return Boolean.FALSE;
- }
- }
-
- public static void examineEmail(Project project) {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- HttpRequest httpRequest = HttpRequest.post(URLUtils.getLeetcodeGraphql(), "application/json");
- try {
- httpRequest.setBody("{\"operationName\":\"user\",\"variables\":{},\"query\":\"query user {\\n user {\\n socialAccounts\\n username\\n emails {\\n email\\n primary\\n verified\\n __typename\\n }\\n phone\\n profile {\\n rewardStats\\n __typename\\n }\\n __typename\\n }\\n}\\n\"}");
- httpRequest.addHeader("Accept", "application/json");
- HttpResponse response = HttpRequestUtils.executePost(httpRequest);
- if (response != null && response.getStatusCode() == 200) {
-
- String body = response.getBody();
+public interface LoginFrame {
- JSONArray jsonArray = JSONObject.parseObject(body).getJSONObject("data").getJSONObject("user").getJSONArray("emails");
- if (jsonArray != null && jsonArray.size() > 0) {
- for (int i = 0; i < jsonArray.size(); i++) {
- JSONObject object = jsonArray.getJSONObject(i);
- if (object.getBoolean("verified")) {
- return;
- }
- }
+ public void loadComponent();
- }
- MessageUtils.getInstance(project).showWarnMsg("info", PropertiesUtils.getInfo("user.email"));
- }
- } catch (Exception i) {
- LogUtils.LOG.error("验证邮箱错误");
- }
- }
- });
- }
- }
}