1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.argeo.cms.ui.widgets.auth;
17
18 import java.io.IOException;
19 import java.util.Arrays;
20
21 import javax.security.auth.callback.Callback;
22 import javax.security.auth.callback.CallbackHandler;
23 import javax.security.auth.callback.NameCallback;
24 import javax.security.auth.callback.PasswordCallback;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.eclipse.core.runtime.IProgressMonitor;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30 import org.eclipse.jface.dialogs.IDialogConstants;
31 import org.eclipse.jface.dialogs.TrayDialog;
32 import org.eclipse.jface.operation.IRunnableWithProgress;
33 import org.eclipse.jface.operation.ModalContext;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.events.SelectionListener;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Display;
38 import org.eclipse.swt.widgets.Shell;
39 import org.osgi.framework.FrameworkUtil;
40
41
42 public abstract class AbstractLoginDialog extends TrayDialog implements CallbackHandler {
43 private static final long serialVersionUID = -8046708963512717709L;
44
45 private final static Log log = LogFactory.getLog(AbstractLoginDialog.class);
46
47 private Thread modalContextThread = null;
48 boolean processCallbacks = false;
49 boolean isCancelled = false;
50 Callback[] callbackArray;
51
52 protected final Callback[] getCallbacks() {
53 return this.callbackArray;
54 }
55
56 public abstract void internalHandle();
57
58 public boolean isCancelled() {
59 return isCancelled;
60 }
61
62 protected AbstractLoginDialog(Shell parentShell) {
63 super(parentShell);
64 }
65
66
67
68
69
70
71
72
73 public void handle(final Callback[] callbacks) throws IOException {
74
75 if (processCallbacks) {
76
77 processCallbacks = false;
78 }
79
80 if (modalContextThread != null) {
81 try {
82 modalContextThread.join(1000);
83 } catch (InterruptedException e) {
84
85 }
86 modalContextThread = null;
87 }
88
89
90 this.callbackArray = callbacks;
91 final Display display = Display.getDefault();
92 display.syncExec(new Runnable() {
93
94 public void run() {
95 isCancelled = false;
96 setBlockOnOpen(false);
97 open();
98
99 final Button okButton = getButton(IDialogConstants.OK_ID);
100 okButton.setText("Login");
101 okButton.addSelectionListener(new SelectionListener() {
102 private static final long serialVersionUID = -200281625679096775L;
103
104 public void widgetSelected(final SelectionEvent event) {
105 processCallbacks = true;
106 }
107
108 public void widgetDefaultSelected(final SelectionEvent event) {
109
110 }
111 });
112 final Button cancel = getButton(IDialogConstants.CANCEL_ID);
113 cancel.addSelectionListener(new SelectionListener() {
114 private static final long serialVersionUID = -3826030278084915815L;
115
116 public void widgetSelected(final SelectionEvent event) {
117 isCancelled = true;
118 processCallbacks = true;
119 }
120
121 public void widgetDefaultSelected(final SelectionEvent event) {
122
123 }
124 });
125 }
126 });
127 try {
128 ModalContext.setAllowReadAndDispatch(true);
129 ModalContext.run(new IRunnableWithProgress() {
130
131 public void run(final IProgressMonitor monitor) {
132 modalContextThread = Thread.currentThread();
133
134
135
136
137
138
139 while (!processCallbacks && (modalContextThread != null)
140 && (modalContextThread == Thread.currentThread())
141 && FrameworkUtil.getBundle(AbstractLoginDialog.class).getBundleContext() != null) {
142
143
144 try {
145 Thread.sleep(100);
146
147
148
149
150
151 } catch (final Exception e) {
152
153 }
154 }
155 processCallbacks = false;
156
157 if (!isCancelled())
158 internalHandle();
159 else
160
161 for (Callback callback : callbacks)
162 if (callback instanceof PasswordCallback) {
163 char[] arr = ((PasswordCallback) callback).getPassword();
164 if (arr != null) {
165 Arrays.fill(arr, '*');
166 ((PasswordCallback) callback).setPassword(null);
167 }
168 } else if (callback instanceof NameCallback)
169 ((NameCallback) callback).setName(null);
170 }
171 }, true, new NullProgressMonitor(), Display.getDefault());
172 } catch (ThreadDeath e) {
173 isCancelled = true;
174 log.debug("Thread " + Thread.currentThread().getId() + " died");
175 throw e;
176 } catch (Exception e) {
177 isCancelled = true;
178 IOException ioe = new IOException("Unexpected issue in login dialog, see root cause for more details");
179 ioe.initCause(e);
180 throw ioe;
181 } finally {
182
183 processCallbacks = true;
184
185
186
187
188
189
190 modalContextThread = null;
191 }
192 }
193
194 protected void configureShell(Shell shell) {
195 super.configureShell(shell);
196 shell.setText("Authentication");
197 }
198 }