View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.connect.ui.parts;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import javax.naming.InvalidNameException;
22  import javax.naming.ldap.LdapName;
23  import javax.naming.ldap.Rdn;
24  
25  import org.argeo.connect.ConnectException;
26  import org.argeo.connect.UserAdminService;
27  import org.argeo.connect.ui.ConnectImages;
28  import org.argeo.eclipse.ui.ColumnDefinition;
29  import org.argeo.eclipse.ui.EclipseUiUtils;
30  import org.argeo.eclipse.ui.parts.LdifUsersTable;
31  import org.argeo.naming.LdapAttrs;
32  import org.argeo.naming.LdapObjs;
33  import org.argeo.node.NodeConstants;
34  import org.eclipse.jface.dialogs.MessageDialog;
35  import org.eclipse.jface.dialogs.TrayDialog;
36  import org.eclipse.jface.viewers.ColumnLabelProvider;
37  import org.eclipse.jface.viewers.DoubleClickEvent;
38  import org.eclipse.jface.viewers.IDoubleClickListener;
39  import org.eclipse.jface.viewers.ISelectionChangedListener;
40  import org.eclipse.jface.viewers.IStructuredSelection;
41  import org.eclipse.jface.viewers.SelectionChangedEvent;
42  import org.eclipse.jface.viewers.TableViewer;
43  import org.eclipse.swt.SWT;
44  import org.eclipse.swt.events.SelectionAdapter;
45  import org.eclipse.swt.events.SelectionEvent;
46  import org.eclipse.swt.events.SelectionListener;
47  import org.eclipse.swt.graphics.Image;
48  import org.eclipse.swt.layout.FillLayout;
49  import org.eclipse.swt.layout.GridData;
50  import org.eclipse.swt.layout.GridLayout;
51  import org.eclipse.swt.widgets.Button;
52  import org.eclipse.swt.widgets.Composite;
53  import org.eclipse.swt.widgets.Control;
54  import org.eclipse.swt.widgets.Shell;
55  import org.osgi.framework.InvalidSyntaxException;
56  import org.osgi.service.useradmin.Role;
57  import org.osgi.service.useradmin.User;
58  
59  /** Dialog with a user (or group) list to pick up one */
60  public class PickUpGroupDialog extends TrayDialog {
61  	private static final long serialVersionUID = -7137186164861036609L;
62  
63  	// Business objects
64  	private final UserAdminService userAdminService;
65  	// private final UserAdmin userAdmin;
66  	private User selectedUser;
67  
68  	// this page widgets and UI objects
69  	private String title;
70  	private LdifUsersTable userTableViewerCmp;
71  	private TableViewer userViewer;
72  	private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
73  
74  	/**
75  	 * A dialog to pick up a group or a user, showing a table with default columns
76  	 */
77  	public PickUpGroupDialog(Shell parentShell, String title, UserAdminService userAdminService) {
78  		super(parentShell);
79  		this.title = title;
80  		this.userAdminService = userAdminService;
81  
82  		columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 26));
83  		columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
84  		columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 120));
85  	}
86  
87  	/** A dialog to pick up a group or a user */
88  	public PickUpGroupDialog(Shell parentShell, String title, UserAdminService userAdminService,
89  			List<ColumnDefinition> columnDefs) {
90  		super(parentShell);
91  		this.title = title;
92  		this.userAdminService = userAdminService;
93  		this.columnDefs = columnDefs;
94  	}
95  
96  	@Override
97  	protected void okPressed() {
98  		if (getSelected() == null)
99  			MessageDialog.openError(getShell(), "No user chosen", "Please, choose a user or press Cancel.");
100 		else
101 			super.okPressed();
102 	}
103 
104 	protected Control createDialogArea(Composite parent) {
105 		Composite dialogArea = (Composite) super.createDialogArea(parent);
106 		dialogArea.setLayout(new FillLayout());
107 
108 		Composite bodyCmp = new Composite(dialogArea, SWT.NO_FOCUS);
109 		bodyCmp.setLayout(new GridLayout());
110 
111 		// Create and configure the table
112 		userTableViewerCmp = new MyUserTableViewer(bodyCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
113 
114 		userTableViewerCmp.setColumnDefinitions(columnDefs);
115 		userTableViewerCmp.populateWithStaticFilters(false, false);
116 		GridData gd = EclipseUiUtils.fillAll();
117 		gd.minimumHeight = 300;
118 		userTableViewerCmp.setLayoutData(gd);
119 		userTableViewerCmp.refresh();
120 
121 		// Controllers
122 		userViewer = userTableViewerCmp.getTableViewer();
123 		userViewer.addDoubleClickListener(new MyDoubleClickListener());
124 		userViewer.addSelectionChangedListener(new MySelectionChangedListener());
125 
126 		parent.pack();
127 		return dialogArea;
128 	}
129 
130 	public User getSelected() {
131 		if (selectedUser == null)
132 			return null;
133 		else
134 			return selectedUser;
135 	}
136 
137 	protected void configureShell(Shell shell) {
138 		super.configureShell(shell);
139 		shell.setText(title);
140 	}
141 
142 	class MyDoubleClickListener implements IDoubleClickListener {
143 		public void doubleClick(DoubleClickEvent evt) {
144 			if (evt.getSelection().isEmpty())
145 				return;
146 
147 			Object obj = ((IStructuredSelection) evt.getSelection()).getFirstElement();
148 			if (obj instanceof User) {
149 				selectedUser = (User) obj;
150 				okPressed();
151 			}
152 		}
153 	}
154 
155 	class MySelectionChangedListener implements ISelectionChangedListener {
156 		@Override
157 		public void selectionChanged(SelectionChangedEvent event) {
158 			if (event.getSelection().isEmpty()) {
159 				selectedUser = null;
160 				return;
161 			}
162 			Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement();
163 			if (obj instanceof User) {
164 				selectedUser = (User) obj;
165 			}
166 		}
167 	}
168 
169 	private class MyUserTableViewer extends LdifUsersTable {
170 		private static final long serialVersionUID = -2106849828614352347L;
171 
172 		private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.cn.name(), LdapAttrs.DN };
173 
174 		private Button showSystemRoleBtn;
175 		private Button showUserBtn;
176 
177 		public MyUserTableViewer(Composite parent, int style) {
178 			super(parent, style);
179 		}
180 
181 		protected void populateStaticFilters(Composite staticFilterCmp) {
182 			staticFilterCmp.setLayout(new GridLayout());
183 			showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK);
184 			showSystemRoleBtn.setText("Show system roles  ");
185 
186 			showUserBtn = new Button(staticFilterCmp, SWT.CHECK);
187 			showUserBtn.setText("Show users  ");
188 
189 			SelectionListener sl = new SelectionAdapter() {
190 				private static final long serialVersionUID = -7033424592697691676L;
191 
192 				@Override
193 				public void widgetSelected(SelectionEvent e) {
194 					refresh();
195 				}
196 			};
197 
198 			showSystemRoleBtn.addSelectionListener(sl);
199 			showUserBtn.addSelectionListener(sl);
200 		}
201 
202 		@Override
203 		protected List<User> listFilteredElements(String filter) {
204 			Role[] roles;
205 			try {
206 				StringBuilder builder = new StringBuilder();
207 
208 				StringBuilder filterBuilder = new StringBuilder();
209 				if (notNull(filter))
210 					for (String prop : knownProps) {
211 						filterBuilder.append("(");
212 						filterBuilder.append(prop);
213 						filterBuilder.append("=*");
214 						filterBuilder.append(filter);
215 						filterBuilder.append("*)");
216 					}
217 
218 				String typeStr = "(" + LdapAttrs.objectClass.name() + "=" + LdapObjs.groupOfNames.name() + ")";
219 				if ((showUserBtn.getSelection()))
220 					typeStr = "(|(" + LdapAttrs.objectClass.name() + "=" + LdapObjs.inetOrgPerson.name() + ")" + typeStr
221 							+ ")";
222 
223 				if (!showSystemRoleBtn.getSelection())
224 					typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*" + NodeConstants.ROLES_BASEDN + ")))";
225 
226 				if (filterBuilder.length() > 1) {
227 					builder.append("(&" + typeStr);
228 					builder.append("(|");
229 					builder.append(filterBuilder.toString());
230 					builder.append("))");
231 				} else {
232 					builder.append(typeStr);
233 				}
234 				roles = userAdminService.getRoles(builder.toString());
235 			} catch (InvalidSyntaxException e) {
236 				throw new ConnectException("Unable to get roles with filter: " + filter, e);
237 			}
238 			List<User> users = new ArrayList<User>();
239 			for (Role role : roles)
240 				if (!users.contains(role))
241 					users.add((User) role);
242 			return users;
243 		}
244 	}
245 
246 	private boolean notNull(String string) {
247 		if (string == null)
248 			return false;
249 		else
250 			return !"".equals(string.trim());
251 	}
252 
253 	private abstract class UserAdminAbstractLP extends ColumnLabelProvider {
254 		private static final long serialVersionUID = 137336765024922368L;
255 
256 		@Override
257 		public String getText(Object element) {
258 			User user = (User) element;
259 			return getText(user);
260 		}
261 
262 		public abstract String getText(User user);
263 
264 	}
265 
266 	private class RoleIconLP extends UserAdminAbstractLP {
267 		private static final long serialVersionUID = 6550449442061090388L;
268 
269 		@Override
270 		public String getText(User user) {
271 			return "";
272 		}
273 
274 		@Override
275 		public Image getImage(Object element) {
276 			User user = (User) element;
277 			// String dn = user.getName();
278 			if (user.getType() == Role.GROUP)
279 				return ConnectImages.GROUP;
280 			else if (user.getType() == Role.USER)
281 				return ConnectImages.USER;
282 			// dn.matches(".*(" + NodeConstants.ROLES_BASEDN + ")")
283 			else if (user.getType() == Role.ROLE)
284 				return ConnectImages.ROLE;
285 			else
286 				return null;
287 		}
288 	}
289 
290 	private class DomainNameLP extends UserAdminAbstractLP {
291 		private static final long serialVersionUID = 5256703081044911941L;
292 
293 		@Override
294 		public String getText(User user) {
295 			String dn = user.getName();
296 			// if (dn.endsWith(AuthConstants.ROLES_BASEDN))
297 			if (dn.matches(".*(" + NodeConstants.ROLES_BASEDN + ")"))
298 				return "System roles";
299 			try {
300 				LdapName name;
301 				name = new LdapName(dn);
302 				List<Rdn> rdns = name.getRdns();
303 				return (String) rdns.get(1).getValue() + '.' + (String) rdns.get(0).getValue();
304 			} catch (InvalidNameException e) {
305 				throw new ConnectException("Unable to get domain name for " + dn, e);
306 			}
307 		}
308 	}
309 
310 	private class CommonNameLP extends UserAdminAbstractLP {
311 		private static final long serialVersionUID = 5256703081044911941L;
312 
313 		@Override
314 		public String getText(User user) {
315 			Object obj = user.getProperties().get(LdapAttrs.cn.name());
316 			if (obj != null)
317 				return (String) obj;
318 			else
319 				return "";
320 		}
321 	}
322 }