]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/users/UsersPage.java
d5bfeb7cdb1b3d481997d32e566831bfc13b8b1d
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / users / UsersPage.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
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.argeo.ArgeoException;
14 import org.argeo.cms.CmsUiProvider;
15 import org.argeo.cms.maintenance.NonAdminPage;
16 import org.argeo.cms.util.CmsUtils;
17 import org.argeo.eclipse.ui.parts.UsersTable;
18 import org.argeo.jcr.ArgeoNames;
19 import org.argeo.jcr.JcrUtils;
20 import org.argeo.security.UserAdminService;
21 import org.eclipse.jface.dialogs.Dialog;
22 import org.eclipse.jface.dialogs.MessageDialog;
23 import org.eclipse.jface.viewers.ISelection;
24 import org.eclipse.jface.viewers.ISelectionChangedListener;
25 import org.eclipse.jface.viewers.IStructuredSelection;
26 import org.eclipse.jface.viewers.SelectionChangedEvent;
27 import org.eclipse.jface.viewers.TableViewer;
28 import org.eclipse.jface.wizard.WizardDialog;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.DisposeEvent;
31 import org.eclipse.swt.events.DisposeListener;
32 import org.eclipse.swt.events.SelectionAdapter;
33 import org.eclipse.swt.events.SelectionEvent;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.springframework.security.core.Authentication;
40 import org.springframework.security.core.GrantedAuthority;
41 import org.springframework.security.core.context.SecurityContextHolder;
42
43 /**
44 * Simple page to manage users of a given repository. It relies on Argeo user
45 * model: user profile nodes are stored in the main workspace
46 */
47 public class UsersPage implements CmsUiProvider {
48 private final static Log log = LogFactory.getLog(UsersPage.class);
49
50 /* DEPENDENCY INJECTION */
51 private UserAdminService userAdminService;
52 private String userWkspName;
53
54 // TODO use a constant
55 private final static String ROLE_USER_ADMIN = "ROLE_USER_ADMIN";
56
57 // Local UI Providers
58 private NonAdminPage nap = new NonAdminPage();
59 private UserPage userPage = new UserPage();
60
61 @Override
62 public Control createUi(Composite parent, Node context)
63 throws RepositoryException {
64 // This page is only visible to user with role USER_ADMIN
65 if (isAdmin(context)) {
66 Session session = context.getSession().getRepository()
67 .login(userWkspName);
68 return createMainLayout(parent, session);
69 } else
70 nap.createUi(parent, context);
71 return null;
72 }
73
74 // Main layout
75 // Left: User Table - Right User Details Edition
76 private Control createMainLayout(Composite parent, final Session session)
77 throws RepositoryException {
78
79 Composite layoutCmp = new Composite(parent, SWT.NO_FOCUS);
80 layoutCmp.setLayoutData(CmsUtils.fillAll());
81 layoutCmp
82 .setLayout(CmsUtils.noSpaceGridLayout(new GridLayout(2, true)));
83
84 Composite left = new Composite(layoutCmp, SWT.NO_FOCUS);
85 left.setLayoutData(CmsUtils.fillAll());
86 UsersTable table = createUsersTable(left, session);
87
88 final Composite right = new Composite(layoutCmp, SWT.NO_FOCUS);
89 right.setLayoutData(CmsUtils.fillAll());
90
91 final TableViewer viewer = table.getTableViewer();
92 viewer.addSelectionChangedListener(new ISelectionChangedListener() {
93
94 @Override
95 public void selectionChanged(SelectionChangedEvent event) {
96 IStructuredSelection selection = (IStructuredSelection) viewer
97 .getSelection();
98 if (selection.isEmpty()) {
99 // Should we clean the right column?
100 CmsUtils.clear(right);
101 right.layout();
102 return;
103 } else {
104 Node context = (Node) selection.getFirstElement();
105 try {
106 CmsUtils.clear(right);
107 userPage.createUi(right, context);
108 right.layout();
109 right.getParent().layout();
110 } catch (RepositoryException e) {
111 e.printStackTrace();
112 throw new ArgeoException("unable to create "
113 + "editor for user " + context, e);
114 }
115 }
116 }
117 });
118 return left;
119 }
120
121 private UsersTable createUsersTable(Composite parent, final Session session)
122 throws RepositoryException {
123 parent.setLayout(CmsUtils.noSpaceGridLayout());
124
125 // Add user CRUD buttons
126 Composite buttonCmp = new Composite(parent, SWT.NO_FOCUS);
127 buttonCmp.setLayoutData(CmsUtils.fillWidth());
128 buttonCmp.setLayout(new GridLayout(2, false));
129 // Delete
130 final Button deleteBtn = new Button(buttonCmp, SWT.PUSH);
131 deleteBtn.setText("Delete selected");
132 deleteBtn
133 .setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
134
135 // Add
136 final Button addBtn = new Button(buttonCmp, SWT.PUSH);
137 addBtn.setText("Create");
138
139 // Create the composite that displays the list and a filter
140 final UsersTable userTableCmp = new UsersTable(parent, SWT.BORDER,
141 session);
142 userTableCmp.populate(true, false);
143 userTableCmp.setLayoutData(CmsUtils.fillAll());
144
145 // The various listeners
146 userTableCmp.addDisposeListener(new DisposeListener() {
147 private static final long serialVersionUID = -8854052549807709846L;
148
149 @Override
150 public void widgetDisposed(DisposeEvent event) {
151 JcrUtils.logoutQuietly(session);
152 }
153 });
154
155 deleteBtn.addSelectionListener(new SelectionAdapter() {
156 private static final long serialVersionUID = -7340611909297995666L;
157
158 @Override
159 public void widgetSelected(SelectionEvent e) {
160
161 TableViewer viewer = userTableCmp.getTableViewer();
162 ISelection selection = viewer.getSelection();
163 if (selection.isEmpty())
164 return;
165
166 Map<String, Node> toDelete = new TreeMap<String, Node>();
167 @SuppressWarnings("unchecked")
168 Iterator<Node> it = ((IStructuredSelection) selection)
169 .iterator();
170 nodes: while (it.hasNext()) {
171 Node profileNode = it.next();
172 try {
173 String userName = profileNode.getProperty(
174 ArgeoNames.ARGEO_USER_ID).getString();
175 if (userName.equals(profileNode.getSession()
176 .getUserID())) {
177 log.warn("Cannot delete its own user: " + userName);
178 continue nodes;
179 }
180 toDelete.put(userName, profileNode);
181 } catch (RepositoryException re) {
182 log.warn("Cannot interpred user " + profileNode);
183 }
184 }
185
186 if (!MessageDialog.openQuestion(
187 userTableCmp.getShell(),
188 "Delete User",
189 "Are you sure that you want to delete users "
190 + toDelete.keySet()
191 + "?\n"
192 + "This may lead to inconsistencies in the application."))
193 return;
194
195 for (String username : toDelete.keySet()) {
196 Session session = null;
197 try {
198 Node profileNode = toDelete.get(username);
199 userAdminService.deleteUser(username);
200 profileNode.getParent().remove();
201 session = profileNode.getSession();
202 session.save();
203 } catch (RepositoryException re) {
204 JcrUtils.discardQuietly(session);
205 throw new ArgeoException("Cannot list users", re);
206 }
207 }
208 userTableCmp.refresh();
209 }
210 });
211
212 addBtn.addSelectionListener(new SelectionAdapter() {
213 private static final long serialVersionUID = 9214984636836267786L;
214
215 @Override
216 public void widgetSelected(SelectionEvent e) {
217 NewUserWizard newUserWizard = new NewUserWizard(session,
218 userAdminService);
219 WizardDialog dialog = new WizardDialog(addBtn.getShell(),
220 newUserWizard);
221 if (dialog.open() == Dialog.OK)
222 userTableCmp.refresh();
223 }
224 });
225
226 // Configure
227 // userTableCmp.getTableViewer().addDoubleClickListener(
228 // new ViewDoubleClickListener());
229 // getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
230
231 // Add listener to refresh the list when something changes
232 // userStructureListener = new JcrUserListener(getSite().getShell()
233 // .getDisplay());
234 // JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
235 // | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
236 // userPropertiesListener = new JcrUserListener(getSite().getShell()
237 // .getDisplay());
238 // JcrUtils.addListener(session, userStructureListener,
239 // Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
240 // | Event.PROPERTY_REMOVED,
241 // ArgeoJcrConstants.PEOPLE_BASE_PATH,
242 // ArgeoTypes.ARGEO_USER_PROFILE);
243
244 return userTableCmp;
245 }
246
247 private boolean isAdmin(Node node) throws RepositoryException {
248 return isUserInRole(ROLE_USER_ADMIN);
249 }
250
251 /**
252 * Returns true if the current user is in the specified role TODO factoize
253 * in the user admin service
254 */
255 private boolean isUserInRole(String role) {
256 Authentication authen = SecurityContextHolder.getContext()
257 .getAuthentication();
258 for (GrantedAuthority ga : authen.getAuthorities()) {
259 if (ga.getAuthority().equals(role))
260 return true;
261 }
262 return false;
263 }
264
265 /* DEPENDENCY INJECTION */
266 public void setWorkspaceName(String workspaceName) {
267 this.userWkspName = workspaceName;
268 }
269
270 public void setUserAdminService(UserAdminService userAdminService) {
271 this.userAdminService = userAdminService;
272 userPage.setUserAdminService(userAdminService);
273 }
274 }