]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/dialogs/AbstractLoginDialog.java
Make security UI more robust
[lgpl/argeo-commons.git] / security / eclipse / plugins / org.argeo.security.ui / src / main / java / org / argeo / security / ui / dialogs / AbstractLoginDialog.java
1 package org.argeo.security.ui.dialogs;
2
3 import java.io.IOException;
4
5 import javax.security.auth.callback.Callback;
6 import javax.security.auth.callback.CallbackHandler;
7 import javax.security.auth.callback.NameCallback;
8 import javax.security.auth.callback.PasswordCallback;
9
10 import org.eclipse.core.runtime.IProgressMonitor;
11 import org.eclipse.core.runtime.NullProgressMonitor;
12 import org.eclipse.jface.dialogs.IDialogConstants;
13 import org.eclipse.jface.dialogs.TitleAreaDialog;
14 import org.eclipse.jface.operation.IRunnableWithProgress;
15 import org.eclipse.jface.operation.ModalContext;
16 import org.eclipse.swt.events.SelectionEvent;
17 import org.eclipse.swt.events.SelectionListener;
18 import org.eclipse.swt.widgets.Button;
19 import org.eclipse.swt.widgets.Display;
20 import org.eclipse.swt.widgets.Shell;
21
22 public abstract class AbstractLoginDialog extends TitleAreaDialog implements
23 CallbackHandler {
24
25 boolean processCallbacks = false;
26 boolean isCancelled = false;
27 Callback[] callbackArray;
28
29 protected final Callback[] getCallbacks() {
30 return this.callbackArray;
31 }
32
33 public abstract void internalHandle();
34
35 public boolean isCancelled() {
36 return isCancelled;
37 }
38
39 protected AbstractLoginDialog(Shell parentShell) {
40 super(parentShell);
41 }
42
43 /*
44 * (non-Javadoc)
45 *
46 * @see
47 * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
48 * .callback.Callback[])
49 */
50 public void handle(final Callback[] callbacks) throws IOException {
51 this.callbackArray = callbacks;
52 final Display display = Display.getDefault();
53 display.syncExec(new Runnable() {
54
55 public void run() {
56 isCancelled = false;
57 setBlockOnOpen(false);
58 open();
59 final Button okButton = getButton(IDialogConstants.OK_ID);
60 okButton.setText("Login");
61 okButton.addSelectionListener(new SelectionListener() {
62
63 public void widgetSelected(final SelectionEvent event) {
64 processCallbacks = true;
65 }
66
67 public void widgetDefaultSelected(final SelectionEvent event) {
68 // nothing to do
69 }
70 });
71 final Button cancel = getButton(IDialogConstants.CANCEL_ID);
72 cancel.addSelectionListener(new SelectionListener() {
73
74 public void widgetSelected(final SelectionEvent event) {
75 isCancelled = true;
76 processCallbacks = true;
77 }
78
79 public void widgetDefaultSelected(final SelectionEvent event) {
80 // nothing to do
81 }
82 });
83 }
84 });
85 try {
86 ModalContext.setAllowReadAndDispatch(true); // Works for now.
87 ModalContext.run(new IRunnableWithProgress() {
88
89 public void run(final IProgressMonitor monitor) {
90 // Wait here until OK or cancel is pressed, then let it rip.
91 // The event
92 // listener
93 // is responsible for closing the dialog (in the
94 // loginSucceeded
95 // event).
96 while (!processCallbacks) {
97 try {
98 Thread.sleep(100);
99 } catch (final Exception e) {
100 // do nothing
101 }
102 }
103 processCallbacks = false;
104 // Call the adapter to handle the callbacks
105 if (!isCancelled())
106 internalHandle();
107 else
108 // clear callbacks are when cancelling
109 for (Callback callback : callbacks)
110 if (callback instanceof PasswordCallback)
111 ((PasswordCallback) callback).setPassword(null);
112 else if (callback instanceof NameCallback)
113 ((NameCallback) callback).setName(null);
114 }
115 }, true, new NullProgressMonitor(), Display.getDefault());
116 } catch (final Exception e) {
117 final IOException ioe = new IOException();
118 ioe.initCause(e);
119 throw ioe;
120 }
121 }
122
123 protected void configureShell(Shell shell) {
124 super.configureShell(shell);
125 shell.setText("Login");
126 }
127 }