1 package org.jivesoftware.openfire.pubsub; 2 3 import org.jivesoftware.openfire.XMPPServer; 4 import org.jivesoftware.openfire.group.Group; 5 import org.jivesoftware.openfire.group.GroupManager; 6 import org.jivesoftware.openfire.group.GroupNotFoundException; 7 import org.jivesoftware.openfire.user.UserManager; 8 import org.jivesoftware.util.LocaleUtils; 9 import org.jivesoftware.util.ParamUtils; 10 import org.slf4j.Logger; 11 import org.slf4j.LoggerFactory; 12 import org.xmpp.forms.DataForm; 13 import org.xmpp.forms.FormField; 14 import org.xmpp.packet.JID; 15 16 import java.util.*; 17 18 import javax.servlet.http.HttpServletRequest; 19 20 public class PubSubServiceInfo { 21 22 private static final Logger Log = LoggerFactory.getLogger(PubSubServiceInfo.class); 23 24 private PubSubService pubSubService; 25 26 private PubSubModule pubSubModule; 27 private XMPPServer xmppServer; 28 private UserManager userManager; 29 private GroupManager groupManager; 30 31 private String labelPreFix = "pubsub.service.form."; 32 private String variablePreFix = "pubsub#"; 33 PubSubServiceInfo(PubSubService pubSubService)34 public PubSubServiceInfo(PubSubService pubSubService) { 35 if (pubSubService == null) { 36 throw new IllegalArgumentException("Argument 'pubSubService' cannot be null."); 37 } 38 this.pubSubService = pubSubService; 39 40 xmppServer = XMPPServer.getInstance(); 41 pubSubModule = xmppServer.getPubSubModule(); 42 groupManager = GroupManager.getInstance(); 43 userManager = xmppServer.getUserManager(); 44 } 45 getNodes()46 public Collection<Node> getNodes() { 47 return pubSubService.getNodes(); 48 } 49 getNode(String nodeID)50 public Node getNode(String nodeID) { 51 return pubSubService.getNode(nodeID); 52 } 53 getLeafNodes()54 public List<Node> getLeafNodes() { 55 List<Node> leafNodes = new ArrayList<Node>(); 56 for (Node node : pubSubService.getNodes()) { 57 if (!node.isCollectionNode()) { 58 leafNodes.add(node); 59 } 60 } 61 return leafNodes; 62 } 63 getRootCollectionNode()64 public CollectionNode getRootCollectionNode() { 65 return pubSubService.getRootCollectionNode(); 66 } 67 getServiceID()68 public String getServiceID() { 69 return pubSubService.getServiceID(); 70 } 71 72 /* 73 * Returns a DataForm for configuring the pubsub service. Configurable fields 74 * 'serviceEnabled', 'nodeCreationRestricted', 'allowedToCreate', 'sysadmins' 75 * Some fields which appear to be configurable on the PubSubService interface 76 * are not configurable due to the PubSubModule implementation these include: 77 * 'MultipleSubscriptionsEnabled', 'InstantNodeSupported', 78 * 'CollectionNodesSupported' they are therefore not included on the form. 79 */ getServiceConfigurationForm()80 public DataForm getServiceConfigurationForm() { 81 82 DataForm form = new DataForm(DataForm.Type.result); 83 84 FormField formField = form.addField(); 85 formField.setVariable(variablePreFix + "serviceEnabled"); 86 formField.setType(FormField.Type.boolean_type); 87 formField.setLabel(LocaleUtils.getLocalizedString(labelPreFix + "serviceEnabled")); 88 formField.addValue(pubSubModule.isServiceEnabled()); 89 90 formField = form.addField(); 91 formField.setVariable(variablePreFix + "nodeCreationRestricted"); 92 formField.setType(FormField.Type.boolean_type); 93 formField.setLabel(LocaleUtils.getLocalizedString(labelPreFix + "nodeCreationRestricted")); 94 formField.addValue(pubSubModule.isNodeCreationRestricted()); 95 96 formField = form.addField(); 97 formField.setVariable(variablePreFix + "allowedToCreate"); 98 formField.setType(FormField.Type.jid_multi); 99 formField.setLabel(LocaleUtils.getLocalizedString(labelPreFix + "allowedToCreate")); 100 for (JID jid : pubSubModule.getUsersAllowedToCreate()) { 101 formField.addValue(jid); 102 } 103 104 formField = form.addField(); 105 formField.setVariable(variablePreFix + "sysadmins"); 106 formField.setType(FormField.Type.jid_multi); 107 formField.setLabel(LocaleUtils.getLocalizedString(labelPreFix + "sysadmins")); 108 for (JID jid : pubSubModule.getSysadmins()) { 109 formField.addValue(jid); 110 } 111 112 return form; 113 } 114 getValidJID(String username)115 public JID getValidJID(String username) { 116 if (username != null && !username.isEmpty()) { 117 try { 118 if (username.contains("@")) { 119 JID jid = new JID(username); 120 if (userManager.isRegisteredUser(jid, true)) { 121 return jid; 122 } 123 } else { 124 // Assume that the value refers to a user on the local server. 125 final JID jid = xmppServer.createJID(username, null); 126 if (userManager.isRegisteredUser(jid, false)) { 127 return jid; 128 } 129 } 130 } catch (IllegalArgumentException e) { 131 Log.debug("Unable to parse value '{}' as a JID.", username); 132 } 133 } 134 // Return null if JID is invalid or user not registered 135 return null; 136 } 137 isValidGroup(String groupName)138 public boolean isValidGroup(String groupName) { 139 if (groupName != null && !groupName.isEmpty()) { 140 try { 141 Group group = groupManager.getGroup(groupName); 142 if (group != null) { 143 return true; 144 } 145 } catch (GroupNotFoundException e) { 146 Log.debug("Group with name '{}' not found", groupName); 147 } 148 } 149 return false; 150 } 151 processForm(DataForm form, HttpServletRequest request, Collection<String> excludedFields)152 public DataForm processForm(DataForm form, HttpServletRequest request, Collection<String> excludedFields) { 153 154 DataForm completedForm = new DataForm(DataForm.Type.submit); 155 156 for (FormField field : form.getFields()) { 157 158 if (excludedFields == null || !excludedFields.contains(field.getVariable())) { 159 160 FormField completedField = completedForm.addField(field.getVariable(), field.getLabel(), field.getType()); 161 162 switch (field.getType()) { 163 case boolean_type: 164 completedField.addValue(ParamUtils.getBooleanParameter(request, field.getVariable())); 165 break; 166 case jid_multi: 167 for (String param : ParamUtils.getParameters(request, field.getVariable())) { 168 completedField.addValue(param); 169 } 170 break; 171 case list_multi: 172 for (String param : ParamUtils.getParameters(request, field.getVariable())) { 173 completedField.addValue(param); 174 } 175 break; 176 case list_single: 177 completedField.addValue(ParamUtils.getParameter(request, field.getVariable())); 178 break; 179 case text_single: 180 completedField.addValue(ParamUtils.getParameter(request, field.getVariable())); 181 break; 182 default: 183 break; 184 } 185 186 for(FormField.Option option: field.getOptions()) { 187 completedField.addOption(option.getLabel(), option.getValue()); 188 } 189 190 } 191 } 192 return completedForm; 193 } 194 configureService(DataForm form)195 public void configureService(DataForm form) { 196 197 for (FormField field : form.getFields()) { 198 switch (field.getVariable().substring(field.getVariable().indexOf("#") + 1)) { 199 case "serviceEnabled": 200 if (field.getFirstValue() != null) { 201 pubSubModule.setServiceEnabled("1".equals(field.getFirstValue())); 202 } 203 break; 204 case "nodeCreationRestricted": 205 if (field.getFirstValue() != null) { 206 pubSubModule.setNodeCreationRestricted("1".equals(field.getFirstValue())); 207 } 208 break; 209 case "allowedToCreate": 210 final Set<JID> allAllowed = new HashSet<>(); 211 for ( final String value : field.getValues() ) { 212 try { 213 allAllowed.add( new JID(value.trim()) ); 214 } catch ( IllegalArgumentException e ) { 215 Log.warn( "Unable to add to 'allowedToCreate'. Value is not a valid JID: {}", value, e); 216 } 217 } 218 pubSubModule.setUserAllowedToCreate(allAllowed); 219 break; 220 case "sysadmins": 221 final Set<JID> sysadmins = new HashSet<>(); 222 for ( final String value : field.getValues() ) { 223 try { 224 sysadmins.add( new JID(value.trim()) ); 225 } catch ( IllegalArgumentException e ) { 226 Log.warn( "Unable to add to 'sysadmins'. Value is not a valid JID: {}", value, e); 227 } 228 } 229 pubSubModule.setSysadmins(sysadmins); 230 break; 231 default: 232 // Shouldn't end up here 233 break; 234 } 235 } 236 } 237 validateAdditions(DataForm form, HttpServletRequest request, Map<String, listType> listTypes, Map<String, String> errors)238 public void validateAdditions(DataForm form, HttpServletRequest request, Map<String, listType> listTypes, 239 Map<String, String> errors) { 240 241 for (FormField field : form.getFields()) { 242 if (listTypes.containsKey(field.getVariable())) { 243 switch (listTypes.get(field.getVariable())) { 244 case group: 245 if (ParamUtils.getParameter(request, field.getVariable() + "-Add") != null) { 246 String groupName = ParamUtils.getParameter(request, field.getVariable() + "-Additional"); 247 if (isValidGroup(groupName)) { 248 249 if (!field.getValues().contains(groupName)) { 250 field.addValue(groupName); 251 } else { 252 // Group already in list 253 errors.put(field.getVariable(), LocaleUtils.getLocalizedString( 254 "pubsub.form.already_in_list", 255 Arrays.asList(LocaleUtils.getLocalizedString("pubsub.form.group"), groupName))); 256 } 257 } else { 258 // Not a valid group 259 errors.put(field.getVariable(), LocaleUtils.getLocalizedString("pubsub.form.not_valid", 260 Arrays.asList(groupName, LocaleUtils.getLocalizedString("pubsub.form.group")))); 261 } 262 } 263 264 break; 265 case user: 266 if (ParamUtils.getParameter(request, field.getVariable() + "-Add") != null) { 267 String username = ParamUtils.getParameter(request, field.getVariable() + "-Additional"); 268 JID newUser = getValidJID(username); 269 if (newUser != null) { 270 271 if (!field.getValues().contains(newUser.toBareJID())) { 272 field.addValue(newUser.toBareJID()); 273 } else { 274 // User already in list 275 errors.put(field.getVariable(), LocaleUtils.getLocalizedString( 276 "pubsub.form.already_in_list", 277 Arrays.asList(LocaleUtils.getLocalizedString("pubsub.form.user"), username))); 278 } 279 } else { 280 // Not a valid username 281 errors.put(field.getVariable(), LocaleUtils.getLocalizedString("pubsub.form.not_valid", 282 Arrays.asList(username, LocaleUtils.getLocalizedString("pubsub.form.user")))); 283 } 284 } 285 break; 286 default: 287 break; 288 } 289 } 290 } 291 } 292 293 public enum listType { 294 user, group; 295 } 296 297 } 298