]> git.argeo.org Git - lgpl/argeo-commons.git/blob - Users.java
2637ed4d9afeeb923af00e3a6bb3a829805c0071
[lgpl/argeo-commons.git] / Users.java
1 package org.argeo.cms.users;
2
3 import java.util.Iterator;
4 import java.util.Map;
5 import java.util.TreeMap;
6
7 import javax.jcr.Node;
8 import javax.jcr.RepositoryException;
9 import javax.jcr.Session;
10 import javax.jcr.security.AccessControlManager;
11 import javax.jcr.security.Privilege;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.ArgeoException;
16 import org.argeo.cms.CmsUiProvider;
17 import org.argeo.cms.maintenance.NonAdminPage;
18 import org.argeo.cms.util.CmsUtils;
19 import org.argeo.eclipse.ui.parts.UsersTable;
20 import org.argeo.jcr.ArgeoNames;
21 import org.argeo.jcr.JcrUtils;
22 import org.argeo.security.UserAdminService;
23 import org.eclipse.jface.dialogs.Dialog;
24 import org.eclipse.jface.dialogs.MessageDialog;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.eclipse.jface.viewers.ISelectionChangedListener;
27 import org.eclipse.jface.viewers.IStructuredSelection;
28 import org.eclipse.jface.viewers.SelectionChangedEvent;
29 import org.eclipse.jface.viewers.TableViewer;
30 import org.eclipse.jface.wizard.WizardDialog;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.events.DisposeEvent;
33 import org.eclipse.swt.events.DisposeListener;
34 import org.eclipse.swt.events.SelectionAdapter;
35 import org.eclipse.swt.events.SelectionEvent;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Button;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.springframework.security.provisioning.UserDetailsManager;
42
43 /**
44 * Simple page to manage users of a given repository. We still rely on Argeo
45 * model; with user stored in the main workspace
46 */
47 public class Users implements CmsUiProvider {
48
49 private final static Log log = LogFactory.getLog(Users.class);
50
51 // Enable user CRUD // INJECTED
52 private UserAdminService userAdminService;
53 // private UserDetailsManager userDetailsManager;
54 private String userWkspName;
55
56 // Local UI Providers
57 NonAdminPage nap = new NonAdminPage();
58 UserPage userPage = new UserPage();
59
60 // Manage authorization
61 @Override
62 public Control createUi(Composite parent, Node context)
63 throws RepositoryException {
64 if (isAdmin(context)) {
65 Session session = context.getSession().getRepository()
66 .login(userWkspName);
67 return createMainLayout(parent, session);
68 } else
69 nap.createUi(parent, context);
70 return null;
71 }
72
73 // Main layout
74 // Left: User Table - Right User Details Edition
75 private Control createMainLayout(Composite parent, final Session session)
76 throws RepositoryException {
77
78 Composite layoutCmp = new Composite(parent, SWT.NO_FOCUS);
79 layoutCmp.setLayoutData(CmsUtils.fillAll());
80 layoutCmp
81 .setLayout(CmsUtils.noSpaceGridLayout(new GridLayout(2, true)));
82
83 Composite left = new Composite(layoutCmp, SWT.NO_FOCUS);
84 left.setLayoutData(CmsUtils.fillAll());
85 UsersTable table = createUsersTable(left, session);
86
87 final Composite right = new Composite(layoutCmp, SWT.NO_FOCUS);
88 right.setLayoutData(CmsUtils.fillAll());
89 // Composite innerPage = createUserPage(right);
90 // final UserViewerOld userViewer = new UserViewerOld(innerPage);
91
92 final TableViewer viewer = table.getTableViewer();
93 viewer.addSelectionChangedListener(new ISelectionChangedListener() {
94
95 @Override
96 public void selectionChanged(SelectionChangedEvent event) {
97 IStructuredSelection selection = (IStructuredSelection) viewer
98 .getSelection();
99 if (selection.isEmpty()) {
100 // Should we clean the right column?
101 return;
102 } else {
103 Node context = (Node) selection.getFirstElement();
104 try {
105 CmsUtils.clear(right);
106 userPage.createUi(right, context);
107 right.layout();
108 right.getParent().layout();
109 } catch (RepositoryException e) {
110 e.printStackTrace();
111 throw new ArgeoException("unable to create "
112 + "editor for user " + context, e);
113 }
114 }
115 }
116 });
117 return left;
118 }
119
120 private UsersTable createUsersTable(Composite parent, final Session session)
121 throws RepositoryException {
122 parent.setLayout(CmsUtils.noSpaceGridLayout());
123
124 // Add user CRUD buttons
125 Composite buttonCmp = new Composite(parent, SWT.NO_FOCUS);
126 buttonCmp.setLayoutData(CmsUtils.fillWidth());
127 buttonCmp.setLayout(new GridLayout(2, false));
128 // Delete
129 final Button deleteBtn = new Button(buttonCmp, SWT.PUSH);
130 deleteBtn.setText("Delete selected");
131 deleteBtn
132 .setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
133
134 // Add
135 final Button addBtn = new Button(buttonCmp, SWT.PUSH);
136 addBtn.setText("Create");
137
138 // Create the composite that displays the list and a filter
139 final UsersTable userTableCmp = new UsersTable(parent, SWT.NO_FOCUS,
140 session);
141 userTableCmp.populate(true, false);
142 userTableCmp.setLayoutData(CmsUtils.fillAll());
143
144 // The various listeners
145 userTableCmp.addDisposeListener(new DisposeListener() {
146 private static final long serialVersionUID = -8854052549807709846L;
147
148 @Override
149 public void widgetDisposed(DisposeEvent event) {
150 JcrUtils.logoutQuietly(session);
151 }
152 });
153
154 deleteBtn.addSelectionListener(new SelectionAdapter() {
155 private static final long serialVersionUID = -7340611909297995666L;
156
157 @Override
158 public void widgetSelected(SelectionEvent e) {
159
160 TableViewer viewer = userTableCmp.getTableViewer();
161 ISelection selection = viewer.getSelection();
162 if (selection.isEmpty())
163 return;
164
165 Map<String, Node> toDelete = new TreeMap<String, Node>();
166 @SuppressWarnings("unchecked")
167 Iterator<Node> it = ((IStructuredSelection) selection)
168 .iterator();
169 nodes: while (it.hasNext()) {
170 Node profileNode = it.next();
171 try {
172 String userName = profileNode.getProperty(
173 ArgeoNames.ARGEO_USER_ID).getString();
174 if (userName.equals(profileNode.getSession()
175 .getUserID())) {
176 log.warn("Cannot delete its own user: " + userName);
177 continue nodes;
178 }
179 toDelete.put(userName, profileNode);
180 } catch (RepositoryException re) {
181 log.warn("Cannot interpred user " + profileNode);
182 }
183 }
184
185 if (!MessageDialog.openQuestion(
186 userTableCmp.getShell(),
187 "Delete User",
188 "Are you sure that you want to delete users "
189 + toDelete.keySet()
190 + "?\n"
191 + "This may lead to inconsistencies in the application."))
192 return;
193
194 for (String username : toDelete.keySet()) {
195 Session session = null;
196 try {
197 Node profileNode = toDelete.get(username);
198 userAdminService.deleteUser(username);
199 profileNode.getParent().remove();
200 session = profileNode.getSession();
201 session.save();
202 } catch (RepositoryException re) {
203 JcrUtils.discardQuietly(session);
204 throw new ArgeoException("Cannot list users", re);
205 }
206 }
207 userTableCmp.refresh();
208 }
209 });
210
211 addBtn.addSelectionListener(new SelectionAdapter() {
212 private static final long serialVersionUID = 9214984636836267786L;
213
214 @Override
215 public void widgetSelected(SelectionEvent e) {
216 NewUserWizard newUserWizard = new NewUserWizard(session,
217 userAdminService);
218 WizardDialog dialog = new WizardDialog(addBtn.getShell(),
219 newUserWizard);
220 if (dialog.open() == Dialog.OK)
221 userTableCmp.refresh();
222 }
223 });
224
225 // Configure
226 // userTableCmp.getTableViewer().addDoubleClickListener(
227 // new ViewDoubleClickListener());
228 // getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
229
230 // Add listener to refresh the list when something changes
231 // userStructureListener = new JcrUserListener(getSite().getShell()
232 // .getDisplay());
233 // JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
234 // | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
235 // userPropertiesListener = new JcrUserListener(getSite().getShell()
236 // .getDisplay());
237 // JcrUtils.addListener(session, userStructureListener,
238 // Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
239 // | Event.PROPERTY_REMOVED,
240 // ArgeoJcrConstants.PEOPLE_BASE_PATH,
241 // ArgeoTypes.ARGEO_USER_PROFILE);
242
243 return userTableCmp;
244 }
245
246 // protected Composite createUserPage(Composite parent) {
247 // parent.setLayout(CmsUtils.noSpaceGridLayout());
248 // ScrolledPage scrolled = new ScrolledPage(parent, SWT.NONE);
249 // scrolled.setLayoutData(CmsUtils.fillAll());
250 // scrolled.setLayout(CmsUtils.noSpaceGridLayout());
251 // // TODO manage style
252 // // CmsUtils.style(scrolled, "maintenance_user_form");
253 //
254 // Composite page = new Composite(scrolled, SWT.NONE);
255 // page.setLayout(CmsUtils.noSpaceGridLayout());
256 // page.setBackgroundMode(SWT.INHERIT_NONE);
257 //
258 // return page;
259 // }
260
261 private boolean isAdmin(Node node) throws RepositoryException {
262 // FIXME clean this once new user management policy has been
263 // implemented.
264 AccessControlManager acm = node.getSession().getAccessControlManager();
265 Privilege[] privs = new Privilege[1];
266 privs[0] = acm.privilegeFromName(Privilege.JCR_ALL);
267 return acm.hasPrivileges("/", privs);
268 }
269
270 // @Override
271 // public void dispose() {
272 // JcrUtils.removeListenerQuietly(session, userStructureListener);
273 // JcrUtils.removeListenerQuietly(session, userPropertiesListener);
274 // JcrUtils.logoutQuietly(session);
275 // super.dispose();
276 // }
277 //
278 // // public void setSession(Session session) {
279 // // this.session = session;
280 // // }
281 //
282 // public void refresh() {
283 // this.getSite().getShell().getDisplay().asyncExec(new Runnable() {
284 // @Override
285 // public void run() {
286 // userTableCmp.refresh();
287 // }
288 // });
289 // }
290 //
291 // private class JcrUserListener implements EventListener {
292 // private final Display display;
293 //
294 // public JcrUserListener(Display display) {
295 // super();
296 // this.display = display;
297 // }
298 //
299 // @Override
300 // public void onEvent(EventIterator events) {
301 // display.asyncExec(new Runnable() {
302 // @Override
303 // public void run() {
304 // userTableCmp.refresh();
305 // }
306 // });
307 // }
308 // }
309 //
310 // class ViewDoubleClickListener implements IDoubleClickListener {
311 // public void doubleClick(DoubleClickEvent evt) {
312 // if (evt.getSelection().isEmpty())
313 // return;
314 //
315 // Object obj = ((IStructuredSelection) evt.getSelection())
316 // .getFirstElement();
317 // if (obj instanceof Node) {
318 // try {
319 // String username = ((Node) obj).getProperty(ARGEO_USER_ID)
320 // .getString();
321 // String commandId = OpenArgeoUserEditor.COMMAND_ID;
322 // String paramName = OpenArgeoUserEditor.PARAM_USERNAME;
323 // CommandUtils.callCommand(commandId, paramName, username);
324 // } catch (RepositoryException e) {
325 // throw new ArgeoException("Cannot open user editor", e);
326 // }
327 // }
328 // }
329
330 /* DEPENDENCY INJECTION */
331 public void setWorkspaceName(String workspaceName) {
332 this.userWkspName = workspaceName;
333 }
334
335 public void setUserAdminService(UserAdminService userAdminService) {
336 this.userAdminService = userAdminService;
337 userPage.setUserAdminService(userAdminService);
338 }
339
340 public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
341 // this.userDetailsManager = userDetailsManager;
342 // userPage.setUserDetailsManager(userDetailsManager);
343 }
344 }