1 package com.github.celldynamics.quimp.registration;
2
3 import java.awt.BorderLayout;
4 import java.awt.Desktop;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
7 import java.awt.GridLayout;
8 import java.awt.Window;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import java.awt.event.MouseAdapter;
12 import java.awt.event.MouseEvent;
13 import java.io.IOException;
14 import java.net.URISyntaxException;
15 import java.nio.charset.StandardCharsets;
16 import java.security.MessageDigest;
17 import java.security.NoSuchAlgorithmException;
18 import java.util.List;
19
20 import javax.swing.JButton;
21 import javax.swing.JDialog;
22 import javax.swing.JEditorPane;
23 import javax.swing.JFrame;
24 import javax.swing.JLabel;
25 import javax.swing.JMenuItem;
26 import javax.swing.JOptionPane;
27 import javax.swing.JPanel;
28 import javax.swing.JPopupMenu;
29 import javax.swing.JScrollPane;
30 import javax.swing.JTextField;
31 import javax.swing.SwingWorker;
32 import javax.swing.event.HyperlinkEvent;
33 import javax.swing.event.HyperlinkListener;
34
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import com.github.celldynamics.quimp.PropertyReader;
39 import com.github.celldynamics.quimp.QuimP;
40
41 import ij.Prefs;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 public class Registration extends JDialog implements ActionListener {
150
151
152
153
154 static final Logger LOGGER = LoggerFactory.getLogger(Registration.class.getName());
155
156 private JButton bnOk;
157 private JButton bnCancel;
158
159
160
161 public boolean waited = false;
162
163
164
165 private final int secondsToWait = 5;
166 private JTextField tfEmail;
167 private JTextField tfKey;
168 private Window owner;
169
170 private JPopupMenu popup;
171 private JEditorPane helpArea;
172
173 private static final long serialVersionUID = -3889439366816085913L;
174
175
176
177
178
179
180
181 public Registration(Window owner, String title) {
182 super(owner, title, ModalityType.APPLICATION_MODAL);
183 this.owner = owner;
184
185 String skipReg = new PropertyReader().readProperty("quimpconfig.properties", "noRegWindow");
186 if (Boolean.parseBoolean(skipReg) == true) {
187 LOGGER.info("Skipping reg window. Hope ony for tests... ");
188 return;
189 }
190
191 if (checkRegistration() == false) {
192 build(title, true);
193 }
194 }
195
196
197
198
199
200
201
202
203 public Registration(Window owner) {
204 this.owner = owner;
205 }
206
207
208
209
210
211
212
213 public void build(String title, boolean show) {
214 buildMenu();
215 buildWindow();
216 setVisible(show);
217 }
218
219
220
221
222 private void buildMenu() {
223 popup = new JPopupMenu();
224
225 JMenuItem selectall = new JMenuItem("Select All");
226
227 JMenuItem copy = new JMenuItem("Copy");
228 selectall.addActionListener(this);
229 copy.addActionListener(this);
230 popup.add(selectall);
231 popup.add(copy);
232
233 }
234
235
236
237
238 private void buildWindow() {
239 JPanel wndpanel = new JPanel();
240 wndpanel.setLayout(new BorderLayout());
241
242
243 JPanel caButtons = new JPanel();
244 caButtons.setLayout(new FlowLayout(FlowLayout.CENTER));
245 bnOk = new JButton("Apply");
246 bnOk.addActionListener(this);
247 bnCancel = new JButton("Cancel");
248 bnCancel.addActionListener(this);
249 caButtons.add(bnOk);
250 caButtons.add(bnCancel);
251 wndpanel.add(caButtons, BorderLayout.SOUTH);
252
253 JPanel centerarea = new JPanel();
254 centerarea.setLayout(new BorderLayout());
255 wndpanel.add(centerarea, BorderLayout.CENTER);
256
257 try {
258 helpArea = new JEditorPane(getClass().getResource("reg.html").toURI().toURL());
259
260 helpArea.setContentType("text/html");
261 helpArea.setEditable(false);
262 JScrollPane helpPanel = new JScrollPane(helpArea);
263 helpPanel.setPreferredSize(new Dimension(500, 600));
264 centerarea.add(helpPanel, BorderLayout.CENTER);
265
266 helpArea.addMouseListener(new MouseAdapter() {
267 @Override
268 public void mousePressed(MouseEvent e) {
269 maybeShowPopup(e);
270 }
271
272 @Override
273 public void mouseReleased(MouseEvent e) {
274 maybeShowPopup(e);
275 }
276
277 private void maybeShowPopup(MouseEvent e) {
278 if (e.isPopupTrigger()) {
279 popup.show(e.getComponent(), e.getX(), e.getY());
280 }
281 }
282 });
283
284 helpArea.addHyperlinkListener(new HyperlinkListener() {
285 public void hyperlinkUpdate(HyperlinkEvent e) {
286 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
287 try {
288 Desktop.getDesktop().browse(e.getURL().toURI());
289 } catch (Exception e1) {
290 LOGGER.error("Can not start browser: " + e1.getMessage());
291 LOGGER.debug(e1.getMessage(), e1);
292 }
293 }
294 }
295 });
296 } catch (IOException | URISyntaxException e2) {
297 LOGGER.error("Can not read resource registration page: " + e2.getMessage());
298 LOGGER.debug(e2.getMessage(), e2);
299 }
300
301 JPanel regarea = new JPanel();
302
303 regarea.setLayout(new GridLayout(3, 2));
304 ((GridLayout) regarea.getLayout()).setHgap(10);
305 ((GridLayout) regarea.getLayout()).setVgap(2);
306 centerarea.add(regarea, BorderLayout.SOUTH);
307 tfEmail = new JTextField(16);
308 tfKey = new JTextField(16);
309 regarea.add(new JLabel(""));
310 regarea.add(new JLabel(""));
311
312 regarea.add(tfEmail);
313 regarea.add(new JLabel("Registration email"));
314
315 regarea.add(tfKey);
316 regarea.add(new JLabel("Your key"));
317
318 add(wndpanel);
319 if (owner != null) {
320 setLocation(owner.getLocation());
321 }
322 setAlwaysOnTop(true);
323 pack();
324 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
325 }
326
327
328
329
330
331
332 @Override
333 public void actionPerformed(ActionEvent e) {
334
335 if (e.getSource() == bnCancel && waited == false) {
336 bnOk.setEnabled(false);
337 bnCancel.setEnabled(false);
338 Worker w = new Worker(secondsToWait);
339 w.execute();
340 return;
341 }
342
343 if (e.getSource() == bnCancel && waited == true) {
344 dispose();
345 return;
346 }
347
348 if (e.getSource() == bnOk) {
349 boolean ret = validateRegInfo(tfEmail.getText(), tfKey.getText());
350 if (ret) {
351 waited = true;
352 registerUser(tfEmail.getText(), tfKey.getText());
353 JOptionPane.showMessageDialog(this, "Thank you for registering our product.", "OK!",
354 JOptionPane.INFORMATION_MESSAGE);
355 dispose();
356 } else {
357 JOptionPane.showMessageDialog(this, "The key you provided does not match to the email.",
358 "Error", JOptionPane.WARNING_MESSAGE);
359 }
360 return;
361 }
362
363 switch (e.getActionCommand()) {
364 case "Copy":
365 helpArea.copy();
366 break;
367 case "Select All":
368 helpArea.selectAll();
369 break;
370 default:
371 throw new IllegalArgumentException("Unknown action.");
372 }
373 }
374
375
376
377
378
379
380
381 private void registerUser(final String email, final String key) {
382 Prefs.set("registration" + QuimP.QUIMP_PREFS_SUFFIX + ".mail", email);
383 Prefs.set("registration" + QuimP.QUIMP_PREFS_SUFFIX + ".key", key);
384
385 }
386
387
388
389
390
391
392 public String[] readRegInfo() {
393 String[] ret = new String[2];
394 ret[0] = Prefs.get("registration" + QuimP.QUIMP_PREFS_SUFFIX + ".mail", "");
395 ret[1] = Prefs.get("registration" + QuimP.QUIMP_PREFS_SUFFIX + ".key", "");
396 return ret;
397 }
398
399
400
401
402 public void fillRegForm() {
403 String[] reg = readRegInfo();
404 tfEmail.setText(reg[0]);
405 tfKey.setText(reg[1]);
406 }
407
408
409
410
411
412
413 private boolean checkRegistration() {
414 String[] reginfo = readRegInfo();
415 boolean ret = validateRegInfo(reginfo[0], reginfo[1]);
416 return ret;
417 }
418
419
420
421
422
423
424
425
426 private boolean validateRegInfo(final String email, final String key) {
427 if (email == null || key == null) {
428 return false;
429 }
430 String emails = email.toLowerCase();
431 String keys = key.toLowerCase();
432
433 emails = emails.replaceAll("\\s+", "");
434 keys = keys.replaceAll("\\s+", "");
435 if (email.isEmpty() || key.isEmpty()) {
436 return false;
437 }
438
439 String salt = "secret";
440
441 emails = emails + salt;
442
443 try {
444 MessageDigest md = MessageDigest.getInstance("MD5");
445 md.update(emails.getBytes(StandardCharsets.UTF_8));
446 StringBuilder sb = new StringBuilder();
447 for (byte b : md.digest()) {
448
449 String ss = Integer.toHexString(0x100 | (b & 0xff)).substring(1);
450 sb.append(ss);
451 }
452 String digest = sb.toString().toLowerCase();
453 LOGGER.trace("email: " + email + " Digest: " + digest);
454 if (digest.equals(keys)) {
455 return true;
456 }
457 } catch (NoSuchAlgorithmException e) {
458 e.printStackTrace();
459 }
460 return false;
461 }
462
463
464
465
466
467
468
469
470 class Worker extends SwingWorker<String, String> {
471 private int wait;
472 private Dimension dc;
473
474
475
476
477
478
479 public Worker(int wait) {
480 this.wait = wait;
481 }
482
483
484
485
486
487
488 @Override
489 protected String doInBackground() throws Exception {
490 dc = bnCancel.getSize();
491
492 for (int i = 0; i < wait; i++) {
493
494 publish(String.valueOf(wait - i));
495 Thread.sleep(1000);
496 }
497
498 waited = true;
499 bnOk.setEnabled(true);
500 bnCancel.setEnabled(true);
501 bnCancel.setText("Cancel");
502 return null;
503 }
504
505
506
507
508
509
510 @Override
511 protected void process(List<String> item) {
512
513 bnCancel.setText(item.get(0));
514 bnCancel.setPreferredSize(dc);
515 }
516 }
517
518
519
520
521
522
523
524 class PopupListener extends MouseAdapter {
525
526
527
528
529
530
531 @Override
532 public void mousePressed(MouseEvent e) {
533 maybeShowPopup(e);
534 }
535
536
537
538
539
540
541 @Override
542 public void mouseReleased(MouseEvent e) {
543 maybeShowPopup(e);
544 }
545
546 private void maybeShowPopup(MouseEvent e) {
547 if (e.isPopupTrigger()) {
548 popup.show(e.getComponent(), e.getX(), e.getY());
549 }
550 }
551 }
552
553 }