1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.security.app.dialog.action;
35
36 import static info.magnolia.cms.security.MgnlUserManager.*;
37 import static info.magnolia.cms.security.SecurityConstants.*;
38
39 import info.magnolia.cms.security.SecuritySupport;
40 import info.magnolia.cms.security.User;
41 import info.magnolia.cms.security.UserManager;
42 import info.magnolia.jcr.util.NodeTypes;
43 import info.magnolia.jcr.util.NodeUtil;
44 import info.magnolia.jcr.util.PropertyUtil;
45 import info.magnolia.security.app.util.UsersWorkspaceUtil;
46 import info.magnolia.ui.admincentral.dialog.action.SaveDialogAction;
47 import info.magnolia.ui.api.action.ActionExecutionException;
48 import info.magnolia.ui.form.EditorCallback;
49 import info.magnolia.ui.form.EditorValidator;
50 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
51 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
52 import info.magnolia.ui.vaadin.integration.jcr.ModelConstants;
53
54 import java.util.Collection;
55
56 import javax.jcr.Node;
57 import javax.jcr.PropertyIterator;
58 import javax.jcr.RepositoryException;
59 import javax.jcr.Session;
60
61 import org.apache.commons.lang3.StringUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 import com.vaadin.data.Item;
66
67
68
69
70 public class SaveUserDialogAction extends SaveDialogAction<SaveUserDialogActionDefinition> {
71
72 private static final Logger log = LoggerFactory.getLogger(SaveUserDialogAction.class);
73
74 private SecuritySupport securitySupport;
75
76 public SaveUserDialogAction(SaveUserDialogActionDefinition definition, Item item, EditorValidator validator, EditorCallback callback, SecuritySupport securitySupport) {
77 super(definition, item, validator, callback);
78 this.securitySupport = securitySupport;
79 }
80
81 @Override
82 public void execute() throws ActionExecutionException {
83
84 validator.showValidation(true);
85 if (validator.isValid()) {
86
87 final JcrNodeAdapter nodeAdapter = (JcrNodeAdapter) item;
88 createOrUpdateUser(nodeAdapter);
89 callback.onSuccess(getDefinition().getName());
90
91 } else {
92
93 }
94 }
95
96 private void createOrUpdateUser(final JcrNodeAdapter userItem) throws ActionExecutionException {
97 try {
98 String userManagerRealm = getDefinition().getUserManagerRealm();
99 if (StringUtils.isBlank(userManagerRealm)){
100 log.debug("userManagerRealm property is not defined -> will try to get realm from node path");
101 userManagerRealm = resolveUserManagerRealm(userItem);
102 }
103 UserManager userManager = securitySupport.getUserManager(userManagerRealm);
104 if (userManager == null){
105 throw new ActionExecutionException("User cannot be created. No user manager with realm name " + userManagerRealm + " is defined.");
106 }
107
108 String newUserName = (String) userItem.getItemProperty(ModelConstants.JCR_NAME).getValue();
109 String newPassword = (String) userItem.getItemProperty(PROPERTY_PASSWORD).getValue();
110
111 User user;
112 Node userNode;
113 if (userItem instanceof JcrNewNodeAdapter) {
114
115
116 Node parentNode = userItem.getJcrItem();
117 String parentPath = parentNode.getPath();
118
119 if ("/".equals(parentPath)) {
120 throw new ActionExecutionException("Users cannot be created directly under root");
121 }
122
123
124 parentNode.getSession().checkPermission(parentNode.getPath(), Session.ACTION_ADD_NODE);
125
126 user = userManager.createUser(parentPath, newUserName, newPassword);
127 userNode = parentNode.getNode(user.getName());
128 } else {
129 userNode = userItem.getJcrItem();
130 String existingUserName = userNode.getName();
131 user = userManager.getUser(existingUserName);
132
133 if (!StringUtils.equals(existingUserName, newUserName)) {
134 String pathBefore = userNode.getPath();
135 NodeUtil.renameNode(userNode, newUserName);
136 userNode.setProperty("name", newUserName);
137 UsersWorkspaceUtil.updateAcls(userNode, pathBefore);
138 }
139
140 String existingPasswordHash = user.getProperty(PROPERTY_PASSWORD);
141 if (!StringUtils.equals(newPassword, existingPasswordHash)) {
142 userManager.setProperty(user, PROPERTY_PASSWORD, newPassword);
143 }
144 }
145
146 String enabled = userItem.getItemProperty(PROPERTY_ENABLED).toString();
147 userManager.setProperty(user, PROPERTY_ENABLED, enabled);
148
149 String title = userItem.getItemProperty(PROPERTY_TITLE).toString();
150 userManager.setProperty(user, PROPERTY_TITLE, title);
151
152 String email = userItem.getItemProperty(PROPERTY_EMAIL).toString();
153 userManager.setProperty(user, PROPERTY_EMAIL, email);
154
155 String language = userItem.getItemProperty(PROPERTY_LANGUAGE).toString();
156 userManager.setProperty(user, PROPERTY_LANGUAGE, language);
157
158 final Collection<String> groups = (Collection<String>) userItem.getItemProperty(NODE_GROUPS).getValue();
159 log.debug("Assigning user the following groups [{}]", groups);
160 storeCollectionAsNodeWithProperties(userNode, NODE_GROUPS, groups);
161
162 final Collection<String> roles = (Collection<String>) userItem.getItemProperty(NODE_ROLES).getValue();
163 log.debug("Assigning user the following roles [{}]", roles);
164 storeCollectionAsNodeWithProperties(userNode, NODE_ROLES, roles);
165
166 userNode.getSession().save();
167
168 } catch (final RepositoryException e) {
169 throw new ActionExecutionException(e);
170 }
171 }
172
173 private String resolveUserManagerRealm(final JcrNodeAdapter userItem) throws RepositoryException{
174 String userPath = userItem.getJcrItem().getPath();
175 if (userItem instanceof JcrNewNodeAdapter && !"/".equals(userPath)) {
176
177 userPath += "/";
178 }
179 return StringUtils.substringBetween(userPath, "/");
180 }
181
182 private void storeCollectionAsNodeWithProperties(Node parentNode, String name, Collection<String> values) throws RepositoryException {
183 try {
184
185 Node node = NodeUtil.createPath(parentNode, name, NodeTypes.ContentNode.NAME);
186
187
188 PropertyIterator pi = node.getProperties();
189 while (pi.hasNext()) {
190 javax.jcr.Property p = pi.nextProperty();
191 if (!p.getName().startsWith(NodeTypes.JCR_PREFIX)) {
192 p.remove();
193 }
194 }
195
196 int i = 0;
197 for (String value : values) {
198 PropertyUtil.setProperty(node, String.valueOf(i), value.trim());
199 i++;
200 }
201 } catch (RepositoryException ex) {
202 throw new RepositoryException("Error saving assigned " + name + " of the [" + parentNode.getName() + "] user.", ex);
203 }
204 }
205 }