]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java
Move Jetty factory to the servlet bundle
[lgpl/argeo-commons.git] / org.argeo.cms.swt / src / org / argeo / cms / swt / auth / CmsLogin.java
1 package org.argeo.cms.swt.auth;
2
3 import static org.argeo.cms.CmsMsg.password;
4 import static org.argeo.cms.CmsMsg.username;
5
6 import java.io.IOException;
7 import java.util.List;
8 import java.util.Locale;
9
10 import javax.security.auth.Subject;
11 import javax.security.auth.callback.Callback;
12 import javax.security.auth.callback.CallbackHandler;
13 import javax.security.auth.callback.LanguageCallback;
14 import javax.security.auth.callback.NameCallback;
15 import javax.security.auth.callback.PasswordCallback;
16 import javax.security.auth.callback.UnsupportedCallbackException;
17 import javax.security.auth.login.LoginContext;
18 import javax.security.auth.login.LoginException;
19
20 import org.argeo.api.cms.CmsAuth;
21 import org.argeo.api.cms.CmsContext;
22 import org.argeo.api.cms.CmsLog;
23 import org.argeo.api.cms.CmsView;
24 import org.argeo.cms.CmsMsg;
25 import org.argeo.cms.LocaleUtils;
26 import org.argeo.cms.auth.RemoteAuthCallback;
27 import org.argeo.cms.servlet.ServletHttpRequest;
28 import org.argeo.cms.servlet.ServletHttpResponse;
29 import org.argeo.cms.swt.CmsStyles;
30 import org.argeo.cms.swt.CmsSwtUtils;
31 import org.argeo.eclipse.ui.specific.UiContext;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.MouseAdapter;
34 import org.eclipse.swt.events.MouseEvent;
35 import org.eclipse.swt.events.SelectionAdapter;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.SelectionListener;
38 import org.eclipse.swt.events.TraverseEvent;
39 import org.eclipse.swt.events.TraverseListener;
40 import org.eclipse.swt.layout.GridData;
41 import org.eclipse.swt.layout.GridLayout;
42 import org.eclipse.swt.widgets.Button;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Control;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.Shell;
47 import org.eclipse.swt.widgets.Text;
48
49 public class CmsLogin implements CmsStyles, CallbackHandler {
50 private final static CmsLog log = CmsLog.getLog(CmsLogin.class);
51
52 private Composite parent;
53 private Text usernameT, passwordT;
54 private Composite credentialsBlock;
55 private final SelectionListener loginSelectionListener;
56
57 private final Locale defaultLocale;
58 private LocaleChoice localeChoice = null;
59
60 private final CmsView cmsView;
61
62 // optional subject to be set explicitly
63 private Subject subject = null;
64
65 public CmsLogin(CmsView cmsView) {
66 this.cmsView = cmsView;
67 CmsContext nodeState = null;// = Activator.getNodeState();
68 // FIXME reactivate locales
69 if (nodeState != null) {
70 defaultLocale = nodeState.getDefaultLocale();
71 List<Locale> locales = nodeState.getLocales();
72 if (locales != null)
73 localeChoice = new LocaleChoice(locales, defaultLocale);
74 } else {
75 defaultLocale = Locale.getDefault();
76 }
77 loginSelectionListener = new SelectionListener() {
78 private static final long serialVersionUID = -8832133363830973578L;
79
80 @Override
81 public void widgetSelected(SelectionEvent e) {
82 login();
83 }
84
85 @Override
86 public void widgetDefaultSelected(SelectionEvent e) {
87 }
88 };
89 }
90
91 protected boolean isAnonymous() {
92 return cmsView.isAnonymous();
93 }
94
95 public final void createUi(Composite parent) {
96 this.parent = parent;
97 createContents(parent);
98 }
99
100 protected void createContents(Composite parent) {
101 defaultCreateContents(parent);
102 }
103
104 public final void defaultCreateContents(Composite parent) {
105 parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
106 Composite credentialsBlock = createCredentialsBlock(parent);
107 if (parent instanceof Shell) {
108 credentialsBlock.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
109 }
110 }
111
112 public final Composite createCredentialsBlock(Composite parent) {
113 if (isAnonymous()) {
114 return anonymousUi(parent);
115 } else {
116 return userUi(parent);
117 }
118 }
119
120 public Composite getCredentialsBlock() {
121 return credentialsBlock;
122 }
123
124 protected Composite userUi(Composite parent) {
125 Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
126 credentialsBlock = new Composite(parent, SWT.NONE);
127 credentialsBlock.setLayout(new GridLayout());
128 // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
129
130 specificUserUi(credentialsBlock);
131
132 Label l = new Label(credentialsBlock, SWT.NONE);
133 CmsSwtUtils.style(l, CMS_USER_MENU_ITEM);
134 l.setText(CmsMsg.logout.lead(locale));
135 GridData lData = CmsSwtUtils.fillWidth();
136 lData.widthHint = 120;
137 l.setLayoutData(lData);
138
139 l.addMouseListener(new MouseAdapter() {
140 private static final long serialVersionUID = 6444395812777413116L;
141
142 public void mouseDown(MouseEvent e) {
143 logout();
144 }
145 });
146 return credentialsBlock;
147 }
148
149 /** To be overridden */
150 protected void specificUserUi(Composite parent) {
151
152 }
153
154 protected Composite anonymousUi(Composite parent) {
155 Locale locale = localeChoice == null ? this.defaultLocale : localeChoice.getSelectedLocale();
156 // We need a composite for the traversal
157 credentialsBlock = new Composite(parent, SWT.NONE);
158 credentialsBlock.setLayout(new GridLayout());
159 // credentialsBlock.setLayoutData(CmsUiUtils.fillAll());
160 CmsSwtUtils.style(credentialsBlock, CMS_LOGIN_DIALOG);
161
162 Integer textWidth = 120;
163 if (parent instanceof Shell)
164 CmsSwtUtils.style(parent, CMS_USER_MENU);
165 // new Label(this, SWT.NONE).setText(CmsMsg.username.lead());
166 usernameT = new Text(credentialsBlock, SWT.BORDER);
167 usernameT.setMessage(username.lead(locale));
168 CmsSwtUtils.style(usernameT, CMS_LOGIN_DIALOG_USERNAME);
169 GridData gd = CmsSwtUtils.fillWidth();
170 gd.widthHint = textWidth;
171 usernameT.setLayoutData(gd);
172
173 // new Label(this, SWT.NONE).setText(CmsMsg.password.lead());
174 passwordT = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD);
175 passwordT.setMessage(password.lead(locale));
176 CmsSwtUtils.style(passwordT, CMS_LOGIN_DIALOG_PASSWORD);
177 gd = CmsSwtUtils.fillWidth();
178 gd.widthHint = textWidth;
179 passwordT.setLayoutData(gd);
180
181 TraverseListener tl = new TraverseListener() {
182 private static final long serialVersionUID = -1158892811534971856L;
183
184 public void keyTraversed(TraverseEvent e) {
185 if (e.detail == SWT.TRAVERSE_RETURN)
186 login();
187 }
188 };
189 credentialsBlock.addTraverseListener(tl);
190 usernameT.addTraverseListener(tl);
191 passwordT.addTraverseListener(tl);
192 parent.setTabList(new Control[] { credentialsBlock });
193 credentialsBlock.setTabList(new Control[] { usernameT, passwordT });
194
195 // Button
196 Button loginButton = new Button(credentialsBlock, SWT.PUSH);
197 loginButton.setText(CmsMsg.login.lead(locale));
198 loginButton.setLayoutData(CmsSwtUtils.fillWidth());
199 loginButton.addSelectionListener(loginSelectionListener);
200
201 extendsCredentialsBlock(credentialsBlock, locale, loginSelectionListener);
202 if (localeChoice != null)
203 createLocalesBlock(credentialsBlock);
204 return credentialsBlock;
205 }
206
207 /**
208 * To be overridden in order to provide custom login button and other links.
209 */
210 protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
211 SelectionListener loginSelectionListener) {
212
213 }
214
215 protected void updateLocale(Locale selectedLocale) {
216 // save already entered values
217 String usernameStr = usernameT.getText();
218 char[] pwd = passwordT.getTextChars();
219
220 for (Control child : parent.getChildren())
221 child.dispose();
222 createContents(parent);
223 if (parent.getParent() != null)
224 parent.getParent().layout(true, true);
225 else
226 parent.layout();
227 usernameT.setText(usernameStr);
228 passwordT.setTextChars(pwd);
229 }
230
231 protected Composite createLocalesBlock(final Composite parent) {
232 Composite c = new Composite(parent, SWT.NONE);
233 CmsSwtUtils.style(c, CMS_USER_MENU_ITEM);
234 c.setLayout(CmsSwtUtils.noSpaceGridLayout());
235 c.setLayoutData(CmsSwtUtils.fillAll());
236
237 SelectionListener selectionListener = new SelectionAdapter() {
238 private static final long serialVersionUID = 4891637813567806762L;
239
240 public void widgetSelected(SelectionEvent event) {
241 Button button = (Button) event.widget;
242 if (button.getSelection()) {
243 localeChoice.setSelectedIndex((Integer) event.widget.getData());
244 updateLocale(localeChoice.getSelectedLocale());
245 }
246 };
247 };
248
249 List<Locale> locales = localeChoice.getLocales();
250 for (Integer i = 0; i < locales.size(); i++) {
251 Locale locale = locales.get(i);
252 Button button = new Button(c, SWT.RADIO);
253 CmsSwtUtils.style(button, CMS_USER_MENU_ITEM);
254 button.setData(i);
255 button.setText(LocaleUtils.toLead(locale.getDisplayName(locale), locale) + " (" + locale + ")");
256 // button.addListener(SWT.Selection, listener);
257 button.addSelectionListener(selectionListener);
258 if (i == localeChoice.getSelectedIndex())
259 button.setSelection(true);
260 }
261 return c;
262 }
263
264 protected boolean login() {
265 // TODO use CmsVie in order to retrieve subject?
266 // Subject subject = cmsView.getLoginContext().getSubject();
267 // LoginContext loginContext = cmsView.getLoginContext();
268 try {
269 //
270 // LOGIN
271 //
272 // loginContext.logout();
273 LoginContext loginContext;
274 if (subject == null)
275 loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, this);
276 else
277 loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, this);
278 loginContext.login();
279 cmsView.authChange(loginContext);
280 return true;
281 } catch (LoginException e) {
282 if (log.isTraceEnabled())
283 log.warn("Login failed: " + e.getMessage(), e);
284 else
285 log.warn("Login failed: " + e.getMessage());
286
287 try {
288 Thread.sleep(3000);
289 } catch (InterruptedException e2) {
290 // silent
291 }
292 // ErrorFeedback.show("Login failed", e);
293 return false;
294 }
295 // catch (LoginException e) {
296 // log.error("Cannot login", e);
297 // return false;
298 // }
299 }
300
301 protected void logout() {
302 cmsView.logout();
303 cmsView.navigateTo("~");
304 }
305
306 @Override
307 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
308 for (Callback callback : callbacks) {
309 if (callback instanceof NameCallback && usernameT != null)
310 ((NameCallback) callback).setName(usernameT.getText());
311 else if (callback instanceof PasswordCallback && passwordT != null)
312 ((PasswordCallback) callback).setPassword(passwordT.getTextChars());
313 else if (callback instanceof RemoteAuthCallback) {
314 ((RemoteAuthCallback) callback).setRequest(new ServletHttpRequest(UiContext.getHttpRequest()));
315 ((RemoteAuthCallback) callback).setResponse(new ServletHttpResponse(UiContext.getHttpResponse()));
316 } else if (callback instanceof LanguageCallback) {
317 Locale toUse = null;
318 if (localeChoice != null)
319 toUse = localeChoice.getSelectedLocale();
320 else if (defaultLocale != null)
321 toUse = defaultLocale;
322
323 if (toUse != null) {
324 ((LanguageCallback) callback).setLocale(toUse);
325 UiContext.setLocale(toUse);
326 }
327
328 }
329 }
330 }
331
332 public void setSubject(Subject subject) {
333 this.subject = subject;
334 }
335
336 }