]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/util/UserMenu.java
Introduce workbench login
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / util / UserMenu.java
1 package org.argeo.cms.util;
2
3 import static org.argeo.cms.auth.AuthConstants.ACCESS_CONTROL_CONTEXT;
4 import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_ANONYMOUS;
5 import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_USER;
6
7 import java.io.IOException;
8 import java.security.AccessController;
9 import java.security.PrivilegedAction;
10
11 import javax.security.auth.Subject;
12 import javax.security.auth.callback.Callback;
13 import javax.security.auth.callback.CallbackHandler;
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 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpSession;
21
22 import org.argeo.cms.CmsException;
23 import org.argeo.cms.CmsMsg;
24 import org.argeo.cms.CmsStyles;
25 import org.argeo.cms.CmsView;
26 import org.argeo.cms.auth.AuthConstants;
27 import org.argeo.cms.auth.CurrentUser;
28 import org.eclipse.rap.rwt.RWT;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.MouseAdapter;
31 import org.eclipse.swt.events.MouseEvent;
32 import org.eclipse.swt.events.ShellAdapter;
33 import org.eclipse.swt.events.ShellEvent;
34 import org.eclipse.swt.events.TraverseEvent;
35 import org.eclipse.swt.events.TraverseListener;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.graphics.Rectangle;
38 import org.eclipse.swt.layout.GridData;
39 import org.eclipse.swt.layout.GridLayout;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.swt.widgets.Display;
43 import org.eclipse.swt.widgets.Label;
44 import org.eclipse.swt.widgets.Shell;
45 import org.eclipse.swt.widgets.Text;
46
47 /** The site-related user menu */
48 public class UserMenu implements CmsStyles, CallbackHandler {
49 private final CmsView cmsView;
50 private final Shell shell;
51
52 private Text username, password;
53
54 public UserMenu(Control source, boolean autoclose) {
55 shell = new Shell(source.getDisplay(), SWT.NO_TRIM | SWT.BORDER
56 | SWT.ON_TOP);
57 shell.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
58 // cmsView = (CmsView) shell.getDisplay().getData(CmsView.KEY);
59 cmsView = CmsUtils.getCmsView();
60
61 if (cmsView != null) {
62 String username = CurrentUser.getUsername(CmsUtils.getCmsView()
63 .getSubject());
64 if (username == null
65 || username.equalsIgnoreCase(AuthConstants.ROLE_ANONYMOUS)) {
66 username = null;
67 anonymousUi(shell);
68 } else {
69 userUi(shell);
70 }
71 } else {
72 anonymousUi(shell);
73 }
74
75 shell.pack();
76 shell.layout();
77 if (autoclose)// popup
78 shell.setLocation(source.toDisplay(
79 source.getSize().x - shell.getSize().x, source.getSize().y));
80 else // centered
81 {
82 Rectangle shellBounds = Display.getCurrent().getBounds();// RAP
83 Point dialogSize = shell.getSize();
84 int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
85 int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
86 shell.setLocation(x, y);
87
88 }
89 if (autoclose)
90 shell.addShellListener(new ShellAdapter() {
91 private static final long serialVersionUID = 5178980294808435833L;
92
93 @Override
94 public void shellDeactivated(ShellEvent e) {
95 closeShell();
96 }
97 });
98 shell.open();
99
100 }
101
102 protected void closeShell() {
103 shell.close();
104 shell.dispose();
105 }
106
107 protected void userUi(Composite parent) {
108 parent.setLayout(CmsUtils.noSpaceGridLayout());
109 Composite c = new Composite(parent, SWT.NONE);
110 c.setLayout(new GridLayout());
111 c.setLayoutData(CmsUtils.fillAll());
112
113 specificUserUi(c);
114
115 Label l = new Label(c, SWT.NONE);
116 l.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU_ITEM);
117 l.setText(CmsMsg.logout.lead());
118 GridData lData = CmsUtils.fillWidth();
119 lData.widthHint = 120;
120 l.setLayoutData(lData);
121
122 l.addMouseListener(new MouseAdapter() {
123 private static final long serialVersionUID = 6444395812777413116L;
124
125 public void mouseDown(MouseEvent e) {
126 logout();
127 }
128 });
129 }
130
131 /** To be overridden */
132 protected void specificUserUi(Composite parent) {
133
134 }
135
136 protected void anonymousUi(Composite parent) {
137 parent.setLayout(CmsUtils.noSpaceGridLayout());
138
139 // We need a composite for the traversal
140 Composite c = new Composite(parent, SWT.NONE);
141 c.setLayout(new GridLayout());
142 c.setLayoutData(CmsUtils.fillAll());
143
144 Integer textWidth = 120;
145 parent.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU);
146
147 // new Label(this, SWT.NONE).setText(CmsMsg.username.lead());
148 username = new Text(c, SWT.BORDER);
149 username.setMessage(CmsMsg.username.lead());
150 username.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_USERNAME);
151 GridData gd = CmsUtils.fillWidth();
152 gd.widthHint = textWidth;
153 username.setLayoutData(gd);
154
155 // new Label(this, SWT.NONE).setText(CmsMsg.password.lead());
156 password = new Text(c, SWT.BORDER | SWT.PASSWORD);
157 password.setMessage(CmsMsg.password.lead());
158 password.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_PASSWORD);
159 gd = CmsUtils.fillWidth();
160 gd.widthHint = textWidth;
161 password.setLayoutData(gd);
162
163 TraverseListener tl = new TraverseListener() {
164 private static final long serialVersionUID = -1158892811534971856L;
165
166 public void keyTraversed(TraverseEvent e) {
167 if (e.detail == SWT.TRAVERSE_RETURN)
168 login();
169 }
170 };
171 c.addTraverseListener(tl);
172 username.addTraverseListener(tl);
173 password.addTraverseListener(tl);
174 parent.setTabList(new Control[] { c });
175 c.setTabList(new Control[] { username, password });
176 c.setFocus();
177 }
178
179 protected void login() {
180 Subject subject = cmsView.getSubject();
181 try {
182 //
183 // LOGIN
184 //
185 new LoginContext(LOGIN_CONTEXT_ANONYMOUS, subject).logout();
186 LoginContext loginContext = new LoginContext(LOGIN_CONTEXT_USER,
187 subject, this);
188 loginContext.login();
189
190 // save context in session
191 final HttpSession httpSession = RWT.getRequest().getSession();
192 Subject.doAs(subject, new PrivilegedAction<Void>() {
193
194 @Override
195 public Void run() {
196 httpSession.setAttribute(ACCESS_CONTROL_CONTEXT,
197 AccessController.getContext());
198 return null;
199 }
200 });
201 } catch (LoginException e1) {
202 try {
203 new LoginContext(LOGIN_CONTEXT_ANONYMOUS, subject).login();
204 } catch (LoginException e) {
205 throw new CmsException("Cannot authenticate anonymous", e1);
206 }
207 throw new CmsException("Cannot authenticate", e1);
208 }
209 closeShell();
210 cmsView.authChange();
211 }
212
213 protected void logout() {
214 Subject subject = cmsView.getSubject();
215 try {
216 //
217 // LOGOUT
218 //
219 new LoginContext(LOGIN_CONTEXT_USER, subject).logout();
220 new LoginContext(LOGIN_CONTEXT_ANONYMOUS, subject).login();
221
222 HttpServletRequest httpRequest = RWT.getRequest();
223 HttpSession httpSession = httpRequest.getSession();
224 httpSession.setAttribute(ACCESS_CONTROL_CONTEXT, null);
225 } catch (LoginException e1) {
226 throw new CmsException("Cannot authenticate anonymous", e1);
227 }
228 closeShell();
229 cmsView.navigateTo("~");
230 cmsView.authChange();
231 }
232
233 @Override
234 public void handle(Callback[] callbacks) throws IOException,
235 UnsupportedCallbackException {
236 ((NameCallback) callbacks[0]).setName(username.getText());
237 ((PasswordCallback) callbacks[1]).setPassword(password.getTextChars());
238 }
239
240 public Shell getShell() {
241 return shell;
242 }
243
244 }