]> git.argeo.org Git - lgpl/argeo-commons.git/blob - users/UsersPage.java
Prepare next development cycle
[lgpl/argeo-commons.git] / 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 Composite bottomCmp = new Composite(parent, SWT.NO_FOCUS);
140 bottomCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
141 bottomCmp.setLayout(new GridLayout());
142
143
144 // Create the composite that displays the list and a filter
145 final UsersTable userTableCmp = new UsersTable(bottomCmp, SWT.BORDER,
146 session);
147 userTableCmp.populate(true, false);
148 userTableCmp.setLayoutData(CmsUtils.fillAll());
149
150 // The various listeners
151 userTableCmp.addDisposeListener(new DisposeListener() {
152 private static final long serialVersionUID = -8854052549807709846L;
153
154 @Override
155 public void widgetDisposed(DisposeEvent event) {
156 JcrUtils.logoutQuietly(session);
157 }
158 });
159
160 deleteBtn.addSelectionListener(new SelectionAdapter() {
161 private static final long serialVersionUID = -7340611909297995666L;
162
163 @Override
164 public void widgetSelected(SelectionEvent e) {
165
166 TableViewer viewer = userTableCmp.getTableViewer();
167 ISelection selection = viewer.getSelection();
168 if (selection.isEmpty())
169 return;
170
171 Map<String, Node> toDelete = new TreeMap<String, Node>();
172 @SuppressWarnings("unchecked")
173 Iterator<Node> it = ((IStructuredSelection) selection)
174 .iterator();
175 nodes: while (it.hasNext()) {
176 Node profileNode = it.next();
177 try {
178 String userName = profileNode.getProperty(
179 ArgeoNames.ARGEO_USER_ID).getString();
180 if (userName.equals(profileNode.getSession()
181 .getUserID())) {
182 log.warn("Cannot delete its own user: " + userName);
183 continue nodes;
184 }
185 toDelete.put(userName, profileNode);
186 } catch (RepositoryException re) {
187 log.warn("Cannot interpred user " + profileNode);
188 }
189 }
190
191 if (!MessageDialog.openQuestion(
192 userTableCmp.getShell(),
193 "Delete User",
194 "Are you sure that you want to delete users "
195 + toDelete.keySet()
196 + "?\n"
197 + "This may lead to inconsistencies in the application."))
198 return;
199
200 for (String username : toDelete.keySet()) {
201 Session session = null;
202 try {
203 Node profileNode = toDelete.get(username);
204 userAdminService.deleteUser(username);
205 profileNode.getParent().remove();
206 session = profileNode.getSession();
207 session.save();
208 } catch (RepositoryException re) {
209 JcrUtils.discardQuietly(session);
210 throw new ArgeoException("Cannot list users", re);
211 }
212 }
213 userTableCmp.refresh();
214 }
215 });
216
217 addBtn.addSelectionListener(new SelectionAdapter() {
218 private static final long serialVersionUID = 9214984636836267786L;
219
220 @Override
221 public void widgetSelected(SelectionEvent e) {
222 NewUserWizard newUserWizard = new NewUserWizard(session,
223 userAdminService);
224 WizardDialog dialog = new WizardDialog(addBtn.getShell(),
225 newUserWizard);
226 if (dialog.open() == Dialog.OK)
227 userTableCmp.refresh();
228 }
229 });
230
231 // Configure
232 // userTableCmp.getTableViewer().addDoubleClickListener(
233 // new ViewDoubleClickListener());
234 // getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
235
236 // Add listener to refresh the list when something changes
237 // userStructureListener = new JcrUserListener(getSite().getShell()
238 // .getDisplay());
239 // JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
240 // | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
241 // userPropertiesListener = new JcrUserListener(getSite().getShell()
242 // .getDisplay());
243 // JcrUtils.addListener(session, userStructureListener,
244 // Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
245 // | Event.PROPERTY_REMOVED,
246 // ArgeoJcrConstants.PEOPLE_BASE_PATH,
247 // ArgeoTypes.ARGEO_USER_PROFILE);
248
249 return userTableCmp;
250 }
251
252 private boolean isAdmin(Node node) throws RepositoryException {
253 return isUserInRole(ROLE_USER_ADMIN);
254 }
255
256 /**
257 * Returns true if the current user is in the specified role TODO factoize
258 * in the user admin service
259 */
260 private boolean isUserInRole(String role) {
261 Authentication authen = SecurityContextHolder.getContext()
262 .getAuthentication();
263 for (GrantedAuthority ga : authen.getAuthorities()) {
264 if (ga.getAuthority().equals(role))
265 return true;
266 }
267 return false;
268 }
269
270 /* DEPENDENCY INJECTION */
271 public void setWorkspaceName(String workspaceName) {
272 this.userWkspName = workspaceName;
273 }
274
275 public void setUserAdminService(UserAdminService userAdminService) {
276 this.userAdminService = userAdminService;
277 userPage.setUserAdminService(userAdminService);
278 }
279 }