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.cms.e4.users.handlers;
17  
18  import java.util.Dictionary;
19  import java.util.Map;
20  
21  import javax.inject.Inject;
22  
23  import org.argeo.cms.CmsException;
24  import org.argeo.cms.e4.users.UserAdminWrapper;
25  import org.argeo.eclipse.ui.EclipseUiUtils;
26  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
27  import org.argeo.naming.LdapAttrs;
28  import org.argeo.osgi.useradmin.UserAdminConf;
29  import org.eclipse.e4.core.di.annotations.Execute;
30  import org.eclipse.jface.wizard.Wizard;
31  import org.eclipse.jface.wizard.WizardDialog;
32  import org.eclipse.jface.wizard.WizardPage;
33  import org.eclipse.swt.SWT;
34  import org.eclipse.swt.events.FocusEvent;
35  import org.eclipse.swt.events.FocusListener;
36  import org.eclipse.swt.layout.GridData;
37  import org.eclipse.swt.layout.GridLayout;
38  import org.eclipse.swt.widgets.Combo;
39  import org.eclipse.swt.widgets.Composite;
40  import org.eclipse.swt.widgets.Display;
41  import org.eclipse.swt.widgets.Label;
42  import org.eclipse.swt.widgets.Text;
43  import org.osgi.service.useradmin.Group;
44  import org.osgi.service.useradmin.Role;
45  import org.osgi.service.useradmin.UserAdminEvent;
46  
47  /** Create a new group */
48  public class NewGroup {
49  	// public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup";
50  
51  	/* DEPENDENCY INJECTION */
52  	@Inject
53  	private UserAdminWrapper userAdminWrapper;
54  
55  	@Execute
56  	public Object execute() {
57  		NewGroupWizard newGroupWizard = new NewGroupWizard();
58  		newGroupWizard.setWindowTitle("Group creation");
59  		WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), newGroupWizard);
60  		dialog.open();
61  		return null;
62  	}
63  
64  	private class NewGroupWizard extends Wizard {
65  
66  		// Pages
67  		private MainGroupInfoWizardPage mainGroupInfo;
68  
69  		// UI fields
70  		private Text dNameTxt, commonNameTxt, descriptionTxt;
71  		private Combo baseDnCmb;
72  
73  		public NewGroupWizard() {
74  		}
75  
76  		@Override
77  		public void addPages() {
78  			mainGroupInfo = new MainGroupInfoWizardPage();
79  			addPage(mainGroupInfo);
80  		}
81  
82  		@SuppressWarnings({ "rawtypes", "unchecked" })
83  		@Override
84  		public boolean performFinish() {
85  			if (!canFinish())
86  				return false;
87  			String commonName = commonNameTxt.getText();
88  			try {
89  				userAdminWrapper.beginTransactionIfNeeded();
90  				String dn = getDn(commonName);
91  				Group group = (Group) userAdminWrapper.getUserAdmin().createRole(dn, Role.GROUP);
92  				Dictionary props = group.getProperties();
93  				String descStr = descriptionTxt.getText();
94  				if (EclipseUiUtils.notEmpty(descStr))
95  					props.put(LdapAttrs.description.name(), descStr);
96  				userAdminWrapper.commitOrNotifyTransactionStateChange();
97  				userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CREATED, group));
98  				return true;
99  			} catch (Exception e) {
100 				ErrorFeedback.show("Cannot create new group " + commonName, e);
101 				return false;
102 			}
103 		}
104 
105 		private class MainGroupInfoWizardPage extends WizardPage implements FocusListener {
106 			private static final long serialVersionUID = -3150193365151601807L;
107 
108 			public MainGroupInfoWizardPage() {
109 				super("Main");
110 				setTitle("General information");
111 				setMessage("Please choose a domain, provide a common name " + "and a free description");
112 			}
113 
114 			@Override
115 			public void createControl(Composite parent) {
116 				Composite bodyCmp = new Composite(parent, SWT.NONE);
117 				setControl(bodyCmp);
118 				bodyCmp.setLayout(new GridLayout(2, false));
119 
120 				dNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Distinguished name");
121 				dNameTxt.setEnabled(false);
122 
123 				baseDnCmb = createGridLC(bodyCmp, "Base DN");
124 				// Initialise before adding the listener to avoid NPE
125 				initialiseDnCmb(baseDnCmb);
126 				baseDnCmb.addFocusListener(this);
127 
128 				commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp, "Common name");
129 				commonNameTxt.addFocusListener(this);
130 
131 				Label descLbl = new Label(bodyCmp, SWT.LEAD);
132 				descLbl.setText("Description");
133 				descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
134 				descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI | SWT.WRAP | SWT.BORDER);
135 				descriptionTxt.setLayoutData(EclipseUiUtils.fillAll());
136 				descriptionTxt.addFocusListener(this);
137 
138 				// Initialize buttons
139 				setPageComplete(false);
140 				getContainer().updateButtons();
141 			}
142 
143 			@Override
144 			public void focusLost(FocusEvent event) {
145 				String name = commonNameTxt.getText();
146 				if (EclipseUiUtils.isEmpty(name))
147 					dNameTxt.setText("");
148 				else
149 					dNameTxt.setText(getDn(name));
150 
151 				String message = checkComplete();
152 				if (message != null) {
153 					setMessage(message, WizardPage.ERROR);
154 					setPageComplete(false);
155 				} else {
156 					setMessage("Complete", WizardPage.INFORMATION);
157 					setPageComplete(true);
158 				}
159 				getContainer().updateButtons();
160 			}
161 
162 			@Override
163 			public void focusGained(FocusEvent event) {
164 			}
165 
166 			/** @return the error message or null if complete */
167 			protected String checkComplete() {
168 				String name = commonNameTxt.getText();
169 
170 				if (name.trim().equals(""))
171 					return "Common name must not be empty";
172 				Role role = userAdminWrapper.getUserAdmin().getRole(getDn(name));
173 				if (role != null)
174 					return "Group " + name + " already exists";
175 				return null;
176 			}
177 
178 			@Override
179 			public void setVisible(boolean visible) {
180 				super.setVisible(visible);
181 				if (visible)
182 					if (baseDnCmb.getSelectionIndex() == -1)
183 						baseDnCmb.setFocus();
184 					else
185 						commonNameTxt.setFocus();
186 			}
187 		}
188 
189 		private Map<String, String> getDns() {
190 			return userAdminWrapper.getKnownBaseDns(true);
191 		}
192 
193 		private String getDn(String cn) {
194 			Map<String, String> dns = getDns();
195 			String bdn = baseDnCmb.getText();
196 			if (EclipseUiUtils.notEmpty(bdn)) {
197 				Dictionary<String, ?> props = UserAdminConf.uriAsProperties(dns.get(bdn));
198 				String dn = LdapAttrs.cn.name() + "=" + cn + "," + UserAdminConf.groupBase.getValue(props) + "," + bdn;
199 				return dn;
200 			}
201 			return null;
202 		}
203 
204 		private void initialiseDnCmb(Combo combo) {
205 			Map<String, String> dns = userAdminWrapper.getKnownBaseDns(true);
206 			if (dns.isEmpty())
207 				throw new CmsException("No writable base dn found. Cannot create group");
208 			combo.setItems(dns.keySet().toArray(new String[0]));
209 			if (dns.size() == 1)
210 				combo.select(0);
211 		}
212 	}
213 
214 	private Combo createGridLC(Composite parent, String label) {
215 		Label lbl = new Label(parent, SWT.LEAD);
216 		lbl.setText(label);
217 		lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
218 		Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY);
219 		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
220 		return combo;
221 	}
222 
223 	/* DEPENDENCY INJECTION */
224 	public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
225 		this.userAdminWrapper = userAdminWrapper;
226 	}
227 }