mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
added stepic.org authorization
This commit is contained in:
+67
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.learning.ui.StudyNewProjectPanel">
|
||||
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
@@ -67,6 +67,72 @@
|
||||
<verticalTextPosition value="1"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="f583f" binding="myHideablePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="b4a52" binding="myLoginPanel" layout-manager="GridBagLayout">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f0dd0" class="javax.swing.JPasswordField" binding="myPasswordField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
<gridbag weightx="1.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="8d976" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Password:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="56bf1" class="javax.swing.JTextField" binding="myLoginField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
<gridbag weightx="1.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="fb0e2" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="E-mail:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5f574" class="javax.swing.JButton" binding="myLogInButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Log in"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<vspacer id="9a0a">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+42
-16
@@ -3,10 +3,12 @@ package com.jetbrains.edu.learning.ui;
|
||||
import com.intellij.facet.ui.FacetValidatorsManager;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ui.HideableDecorator;
|
||||
import com.jetbrains.edu.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.stepic.CourseInfo;
|
||||
import com.jetbrains.edu.stepic.EduStepicConnector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -20,6 +22,7 @@ import java.util.List;
|
||||
* data: 7/31/14.
|
||||
*/
|
||||
public class StudyNewProjectPanel{
|
||||
private final HideableDecorator myDecorator;
|
||||
private List<CourseInfo> myAvailableCourses = new ArrayList<CourseInfo>();
|
||||
private JComboBox myCoursesComboBox;
|
||||
private JButton myRefreshButton;
|
||||
@@ -28,6 +31,11 @@ public class StudyNewProjectPanel{
|
||||
private JLabel myDescriptionLabel;
|
||||
private JLabel myLabel;
|
||||
private JPanel myInfoPanel;
|
||||
private JPanel myHideablePanel;
|
||||
private JPanel myLoginPanel;
|
||||
private JPasswordField myPasswordField;
|
||||
private JTextField myLoginField;
|
||||
private JButton myLogInButton;
|
||||
private final StudyProjectGenerator myGenerator;
|
||||
private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
|
||||
private static final String INVALID_COURSE = "Selected course is invalid";
|
||||
@@ -54,12 +62,26 @@ public class StudyNewProjectPanel{
|
||||
myRefreshButton.setIcon(AllIcons.Actions.Refresh);
|
||||
|
||||
myLabel.setPreferredSize(new JLabel("Project name").getPreferredSize());
|
||||
myDecorator = new HideableDecorator(myHideablePanel, "Credentials", false);
|
||||
myDecorator.setOn(false);
|
||||
myDecorator.setContentComponent(myLoginPanel);
|
||||
|
||||
}
|
||||
|
||||
private void initListeners() {
|
||||
|
||||
myRefreshButton.addActionListener(new RefreshActionListener());
|
||||
myCoursesComboBox.addActionListener(new CourseSelectedListener());
|
||||
myLogInButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final boolean isSuccess = EduStepicConnector.login(myLoginField.getText(), String.valueOf(myPasswordField.getPassword()));
|
||||
if (!isSuccess) {
|
||||
setError("Failed to log in");
|
||||
return;
|
||||
}
|
||||
refreshCoursesList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setError(@NotNull final String errorMessage) {
|
||||
@@ -93,24 +115,28 @@ public class StudyNewProjectPanel{
|
||||
private class RefreshActionListener implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final List<CourseInfo> courses = myGenerator.getCourses(true);
|
||||
if (courses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
return;
|
||||
}
|
||||
myCoursesComboBox.removeAllItems();
|
||||
|
||||
for (CourseInfo courseInfo : courses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
myGenerator.setSelectedCourse(StudyUtils.getFirst(courses));
|
||||
|
||||
myGenerator.setCourses(courses);
|
||||
myAvailableCourses = courses;
|
||||
myGenerator.flushCache();
|
||||
refreshCoursesList();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCoursesList() {
|
||||
final List<CourseInfo> courses = myGenerator.getCourses(true);
|
||||
if (courses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
return;
|
||||
}
|
||||
myCoursesComboBox.removeAllItems();
|
||||
|
||||
for (CourseInfo courseInfo : courses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
myGenerator.setSelectedCourse(StudyUtils.getFirst(courses));
|
||||
|
||||
myGenerator.setCourses(courses);
|
||||
myAvailableCourses = courses;
|
||||
myGenerator.flushCache();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles selecting course in combo box
|
||||
|
||||
@@ -10,69 +10,139 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.io.HttpRequests;
|
||||
import com.intellij.util.net.ssl.CertificateManager;
|
||||
import com.jetbrains.edu.EduUtils;
|
||||
import com.jetbrains.edu.courseFormat.Course;
|
||||
import com.jetbrains.edu.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.courseFormat.Task;
|
||||
import com.jetbrains.edu.courseFormat.TaskFile;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
public class EduStepicConnector {
|
||||
private static final String stepicApiUrl = "https://stepic.org/api/";
|
||||
private static final String stepicUrl = "https://stepic.org/";
|
||||
private static final String stepicApiUrl = stepicUrl + "api/";
|
||||
private static final Logger LOG = Logger.getInstance(EduStepicConnector.class.getName());
|
||||
private static final String ourDomain = "stepic.org";
|
||||
private static String ourSessionId = "524iethiwju2tjywaqmf7tbwx0p0jk1b";
|
||||
private static String ourCSRFToken = "LJ9n6OyLVA7hxU94dlYWUu65MF51Nx37";
|
||||
private static String ourCSRFToken = "";
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
||||
//this prefix indicates that course can be opened by educational plugin
|
||||
public static final String PYCHARM_PREFIX = "pycharm";
|
||||
private static BasicCookieStore ourCookieStore;
|
||||
|
||||
private EduStepicConnector() {
|
||||
}
|
||||
|
||||
private static <T> T getFromStepic(String link, final Class<T> container) throws IOException {
|
||||
return HttpRequests.request(stepicApiUrl + link).connect(new HttpRequests.RequestProcessor<T>() {
|
||||
@Override
|
||||
public T process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
final BufferedReader reader = request.getReader();
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(reader, container);
|
||||
public static boolean login(@NotNull final String user, @NotNull final String password) {
|
||||
if (ourClient == null || ourCookieStore == null)
|
||||
initializeClient();
|
||||
return postCredentials(user, password);
|
||||
}
|
||||
|
||||
private static void initializeClient() {
|
||||
final HttpGet request = new HttpGet(stepicUrl);
|
||||
request.addHeader(new BasicHeader("referer", "https://stepic.org"));
|
||||
request.addHeader(new BasicHeader("content-type", "application/json"));
|
||||
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext()).setMaxConnPerRoute(100);
|
||||
ourCookieStore = new BasicCookieStore();
|
||||
ourClient = builder.setDefaultCookieStore(ourCookieStore).build();
|
||||
|
||||
try {
|
||||
ourClient.execute(request);
|
||||
saveCSRFToken();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveCSRFToken() {
|
||||
if (ourCookieStore == null) return;
|
||||
final List<Cookie> cookies = ourCookieStore.getCookies();
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("csrftoken")) {
|
||||
ourCSRFToken = cookie.getValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean postCredentials(String user, String password) {
|
||||
String url = stepicUrl + "accounts/login/";
|
||||
final HttpPost request = new HttpPost(url);
|
||||
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
|
||||
nvps.add(new BasicNameValuePair("csrfmiddlewaretoken", ourCSRFToken));
|
||||
nvps.add(new BasicNameValuePair("login", user));
|
||||
nvps.add(new BasicNameValuePair("next", "/"));
|
||||
nvps.add(new BasicNameValuePair("password", password));
|
||||
nvps.add(new BasicNameValuePair("remember", "on"));
|
||||
|
||||
try {
|
||||
request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
setHeaders(request, "application/x-www-form-urlencoded");
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
saveCSRFToken();
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 302) {
|
||||
LOG.error("Failed to login " + EntityUtils.toString(response.getEntity()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static <T> T getFromStepic(String link, final Class<T> container) throws IOException {
|
||||
final HttpGet request = new HttpGet(stepicApiUrl + link);
|
||||
if (ourClient == null) {
|
||||
initializeClient();
|
||||
}
|
||||
setHeaders(request, "application/json");
|
||||
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final String responseString = EntityUtils.toString(response.getEntity());
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(responseString, container);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<CourseInfo> getCourses() {
|
||||
try {
|
||||
List<CourseInfo> result = new ArrayList<CourseInfo>();
|
||||
final List<CourseInfo> courseInfos =
|
||||
HttpRequests.request(stepicApiUrl + "courses").connect(new HttpRequests.RequestProcessor<List<CourseInfo>>() {
|
||||
|
||||
@Override
|
||||
public List<CourseInfo> process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
final BufferedReader reader = request.getReader();
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(reader, CoursesContainer.class).courses;
|
||||
}
|
||||
});
|
||||
final List<CourseInfo> courseInfos = getFromStepic("courses", CoursesContainer.class).courses;
|
||||
for (CourseInfo info : courseInfos) {
|
||||
final String courseType = info.getType();
|
||||
if (StringUtil.isEmptyOrSpaces(courseType)) continue;
|
||||
@@ -153,23 +223,29 @@ public class EduStepicConnector {
|
||||
}
|
||||
|
||||
|
||||
public static boolean postLesson(Project project, @NotNull final Lesson lesson) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "lessons");
|
||||
final ArrayList<Header> headers = getHeaders(request);
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext());
|
||||
final BasicCookieStore cookieStore = getCookies();
|
||||
final CloseableHttpClient client = builder.setDefaultHeaders(headers).setDefaultCookieStore(cookieStore).build();
|
||||
public static void showLoginDialog() {
|
||||
final LoginDialog dialog = new LoginDialog();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
public static void postLesson(Project project, @NotNull final Lesson lesson) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "lessons");
|
||||
if (ourClient == null) {
|
||||
showLoginDialog();
|
||||
}
|
||||
|
||||
setHeaders(request, "application/json");
|
||||
String requestBody = new Gson().toJson(new LessonWrapper(lesson));
|
||||
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = client.execute(request);
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final String responseString = EntityUtils.toString(response.getEntity());
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 201) {
|
||||
LOG.error("Failed to push " + EntityUtils.toString(response.getEntity()));
|
||||
return false;
|
||||
LOG.error("Failed to push " + responseString);
|
||||
return;
|
||||
}
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, Course.class).getLessons().get(0);
|
||||
for (Task task : lesson.getTaskList()) {
|
||||
@@ -179,56 +255,31 @@ public class EduStepicConnector {
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean postTask(Project project, @NotNull final Task task, int id) {
|
||||
public static void postTask(Project project, @NotNull final Task task, int id) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "step-sources");
|
||||
final ArrayList<Header> headers = getHeaders(request);
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext());
|
||||
final BasicCookieStore cookieStore = getCookies();
|
||||
final CloseableHttpClient client = builder.setDefaultHeaders(headers).setDefaultCookieStore(cookieStore).build();
|
||||
setHeaders(request, "application/json");
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
|
||||
String requestBody = gson.toJson(new StepSourceWrapper(project, task, id));
|
||||
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = client.execute(request);
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 201) {
|
||||
LOG.error("Failed to push " + EntityUtils.toString(response.getEntity()));
|
||||
}
|
||||
return line.getStatusCode() == 201;
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static BasicCookieStore getCookies() {
|
||||
final BasicCookieStore cookieStore = new BasicCookieStore();
|
||||
final BasicClientCookie sessionid = new BasicClientCookie("sessionid", ourSessionId);
|
||||
sessionid.setDomain(ourDomain);
|
||||
sessionid.setPath("/");
|
||||
|
||||
cookieStore.addCookie(sessionid);
|
||||
final BasicClientCookie csrfToken = new BasicClientCookie("csrftoken", ourCSRFToken);
|
||||
csrfToken.setDomain(ourDomain);
|
||||
csrfToken.setPath("/");
|
||||
|
||||
cookieStore.addCookie(csrfToken);
|
||||
return cookieStore;
|
||||
}
|
||||
|
||||
private static ArrayList<Header> getHeaders(HttpPost request) {
|
||||
final ArrayList<Header> headers = new ArrayList<Header>();
|
||||
headers.add(new BasicHeader("referer", "https://stepic.org"));
|
||||
headers.add(new BasicHeader("X-CSRFToken", ourCSRFToken));
|
||||
headers.add(new BasicHeader("content-type", "application/json"));
|
||||
request.setHeaders(headers.toArray(new Header[headers.size()]));
|
||||
return headers;
|
||||
private static void setHeaders(@NotNull final HttpRequestBase request, String contentType) {
|
||||
request.addHeader(new BasicHeader("referer", stepicUrl));
|
||||
request.addHeader(new BasicHeader("X-CSRFToken", ourCSRFToken));
|
||||
request.addHeader(new BasicHeader("content-type", contentType));
|
||||
}
|
||||
|
||||
private static class StepContainer {
|
||||
@@ -267,6 +318,7 @@ public class EduStepicConnector {
|
||||
@Override
|
||||
public void run() {
|
||||
final VirtualFile taskDir = task.getTaskDir(project);
|
||||
assert taskDir != null;
|
||||
EduUtils.createStudentFileFromAnswer(project, taskDir, taskDir, entry);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.jetbrains.edu.stepic;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LoginDialog extends DialogWrapper {
|
||||
private final LoginPanel myLoginPanel;
|
||||
|
||||
public LoginDialog() {
|
||||
super(false);
|
||||
myLoginPanel = new LoginPanel(this);
|
||||
setTitle("Login to Stepic");
|
||||
setOKButtonText("Login");
|
||||
init();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction(), getCancelAction()};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myLoginPanel.getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHelpId() {
|
||||
return "login_to_stepic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myLoginPanel.getPreferableFocusComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
AuthDataHolder authData = myLoginPanel.getAuthData();
|
||||
final boolean success = EduStepicConnector.login(authData.email, authData.password);
|
||||
if (!success) {
|
||||
setErrorText("Log in failed");
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
public void clearErrors() {
|
||||
setErrorText(null);
|
||||
}
|
||||
|
||||
public static class AuthDataHolder {
|
||||
String email;
|
||||
String password;
|
||||
|
||||
public AuthDataHolder(String login, String password) {
|
||||
email = login;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.stepic.LoginPanel">
|
||||
<grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="174"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusable value="false"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="9b306">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="9edbd" class="javax.swing.JPasswordField" binding="myPasswordField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="300" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="fe9db" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Password:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="c0234" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="E-mail:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.edu.stepic;
|
||||
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
public class LoginPanel {
|
||||
private JPanel myPane;
|
||||
private JTextField myLoginTextField;
|
||||
private JPasswordField myPasswordField;
|
||||
|
||||
public LoginPanel(final LoginDialog dialog) {
|
||||
DocumentListener listener = new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
dialog.clearErrors();
|
||||
}
|
||||
};
|
||||
myLoginTextField.getDocument().addDocumentListener(listener);
|
||||
myPasswordField.getDocument().addDocumentListener(listener);
|
||||
}
|
||||
|
||||
public JComponent getPanel() {
|
||||
return myPane;
|
||||
}
|
||||
|
||||
public void setLogin(@Nullable String login) {
|
||||
myLoginTextField.setText(login);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLogin() {
|
||||
return myLoginTextField.getText().trim();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getPassword() {
|
||||
return String.valueOf(myPasswordField.getPassword());
|
||||
}
|
||||
|
||||
public JComponent getPreferableFocusComponent() {
|
||||
return myLoginTextField.isVisible() ? myLoginTextField : myPasswordField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LoginDialog.AuthDataHolder getAuthData() {
|
||||
return new LoginDialog.AuthDataHolder(getLogin(), getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user