use of org.xmpp.forms.FormField in project Openfire by igniterealtime.
the class RegistrationHandler method getRegistrationForm.
/**
* Handles a IQ-register 'get' request, which is to be interpreted as a
* request for a registration form template. The template will be prefilled
* with data, if the requestee has a current registration with the gateway.
*
* @param packet the IQ-register 'get' stanza.
* @throws UnauthorizedException if the user is not allowed to make use of the gateway.
*/
private void getRegistrationForm(IQ packet) throws UnauthorizedException {
final JID from = packet.getFrom();
final IQ result = IQ.createResultIQ(packet);
// search for existing registrations
String curUsername = null;
String curPassword = null;
String curNickname = null;
Boolean registered = false;
final Collection<Registration> registrations = RegistrationManager.getInstance().getRegistrations(from, parent.transportType);
if (registrations.iterator().hasNext()) {
Registration registration = registrations.iterator().next();
curUsername = registration.getUsername();
curPassword = registration.getPassword();
curNickname = registration.getNickname();
registered = true;
}
// Verify that the user is allowed to make use of the gateway.
if (!registered && !parent.permissionManager.hasAccess(from)) {
// registered.
throw new UnauthorizedException(LocaleUtils.getLocalizedString("gateway.base.registrationdeniedbyacls", "kraken"));
}
// generate a template registration form.
final Element response = DocumentHelper.createElement(QName.get("query", NameSpace.IQ_REGISTER));
final DataForm form = new DataForm(DataForm.Type.form);
form.addInstruction(parent.getTerminologyRegistration());
final FormField usernameField = form.addField();
usernameField.setLabel(parent.getTerminologyUsername());
usernameField.setVariable("username");
usernameField.setType(FormField.Type.text_single);
if (curUsername != null) {
usernameField.addValue(curUsername);
}
final FormField passwordField = form.addField();
passwordField.setLabel(parent.getTerminologyPassword());
passwordField.setVariable("password");
passwordField.setType(FormField.Type.text_private);
if (curPassword != null) {
passwordField.addValue(curPassword);
}
final String nicknameTerm = parent.getTerminologyNickname();
if (nicknameTerm != null) {
FormField nicknameField = form.addField();
nicknameField.setLabel(nicknameTerm);
nicknameField.setVariable("nick");
nicknameField.setType(FormField.Type.text_single);
if (curNickname != null) {
nicknameField.addValue(curNickname);
}
}
response.add(form.getElement());
response.addElement("instructions").addText(parent.getTerminologyRegistration());
// exists.
if (registered) {
response.addElement("registered");
response.addElement("username").addText(curUsername);
if (curPassword == null) {
response.addElement("password");
} else {
response.addElement("password").addText(curPassword);
}
if (nicknameTerm != null) {
if (curNickname == null) {
response.addElement("nick");
} else {
response.addElement("nick").addText(curNickname);
}
}
} else {
response.addElement("username");
response.addElement("password");
if (nicknameTerm != null) {
response.addElement("nick");
}
}
// Add special indicator for rosterless gateway handling.
response.addElement(QName.get("x", NameSpace.IQ_GATEWAY_REGISTER));
result.setChildElement(response);
parent.sendPacket(result);
}
use of org.xmpp.forms.FormField in project Openfire by igniterealtime.
the class IQDiscoInfoHandler method getServerInfoProvider.
/**
* Returns the DiscoInfoProvider responsible for providing information at the server level. This
* means that this DiscoInfoProvider will provide information whenever a disco request whose
* recipient JID is the server (e.g. localhost) is made.
*
* @return the DiscoInfoProvider responsible for providing information at the server level.
*/
private DiscoInfoProvider getServerInfoProvider() {
return new DiscoInfoProvider() {
@Override
public Iterator<Element> getIdentities(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getIdentities(name, node, senderJID);
}
if (name == null || name.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
// Answer identity of the server itself.
final ArrayList<Element> identities = new ArrayList<>();
final Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "server");
identity.addAttribute("name", JiveGlobals.getProperty("xmpp.server.name", "Openfire Server"));
identity.addAttribute("type", "im");
identities.add(identity);
// Include identities from modules that implement ServerIdentitiesProvider
for (ServerIdentitiesProvider provider : serverIdentityProviders) {
final Iterator<Element> iterator = provider.getIdentities();
while (iterator.hasNext()) {
identities.add(iterator.next());
}
}
return identities.iterator();
} else if (node != null) {
return XMPPServer.getInstance().getIQPEPHandler().getIdentities(name, node, senderJID);
} else {
// Answer with identities of users of the server.
final Collection<UserIdentitiesProvider> providers;
if (SessionManager.getInstance().isAnonymousRoute(name)) {
// Answer identity of an anonymous user.
providers = anonymousUserIdentityProviders;
} else {
// Answer identity of a registered user.
// Note: We know that this user exists because #hasInfo returned true
providers = registeredUserIdentityProviders;
}
final Set<Element> result = new HashSet<>();
for (final UserIdentitiesProvider provider : providers) {
final Iterator<Element> identities = provider.getIdentities();
while (identities.hasNext()) {
result.add(identities.next());
}
}
return result.iterator();
}
}
@Override
public Iterator<String> getFeatures(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getFeatures(name, node, senderJID);
}
if (name == null || name.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
// Answer features of the server itself.
final Set<String> result = new HashSet<>(serverFeatures.keySet());
if (!UserManager.getInstance().isRegisteredUser(senderJID, false)) {
// Remove features not available to users from other servers or anonymous users.
// TODO this should be determined dynamically.
result.remove(IQPrivateHandler.NAMESPACE);
result.remove(IQBlockingHandler.NAMESPACE);
}
return result.iterator();
} else if (node != null) {
return XMPPServer.getInstance().getIQPEPHandler().getFeatures(name, node, senderJID);
} else {
// Answer with features of users of the server.
final Collection<UserFeaturesProvider> providers;
if (SessionManager.getInstance().isAnonymousRoute(name)) {
// Answer features of an anonymous user.
providers = anonymousUserFeatureProviders;
} else {
// Answer features of a registered user.
// Note: We know that this user exists because #hasInfo returned true
providers = registeredUserFeatureProviders;
}
final Set<String> result = new HashSet<>();
for (final UserFeaturesProvider provider : providers) {
final Iterator<String> features = provider.getFeatures();
while (features.hasNext()) {
result.add(features.next());
}
}
return result.iterator();
}
}
@Override
public boolean hasInfo(String name, String node, JID senderJID) {
if (node != null) {
if (serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).hasInfo(name, node, senderJID);
}
if (name != null) {
return XMPPServer.getInstance().getIQPEPHandler().hasInfo(name, node, senderJID);
}
// Unknown node
return false;
}
// anonymous user. We now support disco of user's bare JIDs
if (name == null) {
return true;
}
if (SessionManager.getInstance().isAnonymousRoute(name)) {
return true;
}
try {
if (UserManager.getInstance().getUser(name) != null) {
return true;
}
} catch (UserNotFoundException e) {
return false;
}
return false;
}
@Override
public DataForm getExtendedInfo(String name, String node, JID senderJID) {
return IQDiscoInfoHandler.getFirstDataForm(this.getExtendedInfos(name, node, senderJID));
}
@Override
public Set<DataForm> getExtendedInfos(String name, String node, JID senderJID) {
if (node != null && serverNodeProviders.get(node) != null) {
// Redirect the request to the disco info provider of the specified node
return serverNodeProviders.get(node).getExtendedInfos(name, node, senderJID);
}
if (name == null || name.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
// XEP-0157 Contact addresses for XMPP Services
if (!JiveGlobals.getBooleanProperty("admin.disable-exposure")) {
final Collection<JID> admins = XMPPServer.getInstance().getAdmins();
if (admins == null || admins.isEmpty()) {
return null;
}
final DataForm dataForm = new DataForm(DataForm.Type.result);
final FormField fieldType = dataForm.addField();
fieldType.setVariable("FORM_TYPE");
fieldType.setType(FormField.Type.hidden);
fieldType.addValue("http://jabber.org/network/serverinfo");
final FormField fieldAdminAddresses = dataForm.addField();
fieldAdminAddresses.setVariable("admin-addresses");
fieldAdminAddresses.setType(Type.list_multi);
final UserManager userManager = UserManager.getInstance();
for (final JID admin : admins) {
fieldAdminAddresses.addValue("xmpp:" + admin.asBareJID());
if (admin.getDomain().equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain()))
try {
final String email = userManager.getUser(admin.getNode()).getEmail();
if (email != null && !email.trim().isEmpty()) {
fieldAdminAddresses.addValue("mailto:" + email);
}
} catch (Exception e) {
continue;
}
}
// XEP-0232 includes extended information about Software Version in a data form
final DataForm dataFormSoftwareVersion = new DataForm(DataForm.Type.result);
final FormField fieldTypeSoftwareVersion = dataFormSoftwareVersion.addField();
fieldTypeSoftwareVersion.setVariable("FORM_TYPE");
fieldTypeSoftwareVersion.setType(FormField.Type.hidden);
fieldTypeSoftwareVersion.addValue("urn:xmpp:dataforms:softwareinfo");
final FormField fieldOs = dataFormSoftwareVersion.addField();
fieldOs.setType(Type.text_single);
fieldOs.setVariable("os");
fieldOs.addValue(System.getProperty("os.name"));
final FormField fieldOsVersion = dataFormSoftwareVersion.addField();
fieldOsVersion.setType(Type.text_single);
fieldOsVersion.setVariable("os_version");
fieldOsVersion.addValue(System.getProperty("os.version") + " " + System.getProperty("os.arch") + " - Java " + System.getProperty("java.version"));
final FormField fieldSoftware = dataFormSoftwareVersion.addField();
fieldSoftware.setType(Type.text_single);
fieldSoftware.setVariable("software");
fieldSoftware.addValue(AdminConsole.getAppName());
final FormField fieldSoftwareVersion = dataFormSoftwareVersion.addField();
fieldSoftwareVersion.setType(Type.text_single);
fieldSoftwareVersion.setVariable("software_version");
fieldSoftwareVersion.addValue(AdminConsole.getVersionString());
final Set<DataForm> dataForms = new HashSet<>();
if (ENABLED.getValue()) {
dataForms.add(dataFormSoftwareVersion);
}
dataForms.add(dataForm);
return dataForms;
}
}
if (node != null && name != null) {
return XMPPServer.getInstance().getIQPEPHandler().getExtendedInfos(name, node, senderJID);
}
return Collections.emptySet();
}
};
}
use of org.xmpp.forms.FormField in project Openfire by igniterealtime.
the class IQDiscoInfoHandlerTest method testGetFirstDataFormWithTwoNotNull.
/**
* Test for {@link IQDiscoInfoHandler#getFirstDataForm(dataForms)}. Verifies that an input argument that
* a collection that has two (no null) items returns the first not null Dataform.
*/
@Test
public void testGetFirstDataFormWithTwoNotNull() throws Exception {
// Setup fixture.
final DataForm dataForm = new DataForm(DataForm.Type.result);
final FormField fieldType = dataForm.addField();
fieldType.setVariable("FORM_TYPE");
fieldType.setType(FormField.Type.hidden);
fieldType.addValue("http://jabber.org/network/serverinfo");
final DataForm dataForm1 = new DataForm(DataForm.Type.result);
final FormField fieldType1 = dataForm1.addField();
fieldType1.setVariable("FORM_TYPE");
fieldType1.setType(FormField.Type.hidden);
fieldType1.addValue("urn:xmpp:dataforms:softwareinfo");
final Set<DataForm> dataForms = new HashSet<>();
dataForms.add(dataForm);
dataForms.add(dataForm1);
// Execute system under test.
final DataForm result = IQDiscoInfoHandler.getFirstDataForm(dataForms);
// Verify results.
Assert.assertNotNull(result);
}
use of org.xmpp.forms.FormField in project Openfire by igniterealtime.
the class IQDiscoInfoHandlerTest method testGetFirstDataFormWithTwoNotNullAndNull.
/**
* Test for {@link IQDiscoInfoHandler#getFirstDataForm(dataForms)}. Verifies that an input argument that
* a collection that has two (non-null) items returns a not null Dataform.
*/
@Test
public void testGetFirstDataFormWithTwoNotNullAndNull() throws Exception {
// Setup fixture.
final DataForm dataForm = new DataForm(DataForm.Type.result);
final FormField fieldType = dataForm.addField();
fieldType.setVariable("FORM_TYPE");
fieldType.setType(FormField.Type.hidden);
fieldType.addValue("http://jabber.org/network/serverinfo");
final DataForm dataForm1 = null;
final Set<DataForm> dataForms = new HashSet<>();
dataForms.add(dataForm1);
dataForms.add(dataForm);
// Execute system under test.
final DataForm result = IQDiscoInfoHandler.getFirstDataForm(dataForms);
// Verify results.
Assert.assertNotNull(result);
}
use of org.xmpp.forms.FormField in project Openfire by igniterealtime.
the class IQOwnerHandler method processConfigurationForm.
/**
* Processes the completed form sent by an owner of the room. This will modify the room's
* configuration as well as the list of owners and admins.
*
* @param completedForm the completed form sent by an owner of the room.
* @param senderRole the role of the user that sent the completed form.
* @throws ForbiddenException if the user does not have enough privileges.
* @throws ConflictException If the room was going to lose all of its owners.
* @throws NotAcceptableException if the room requires a password that was not supplied
*/
private void processConfigurationForm(DataForm completedForm, MUCRole senderRole) throws ForbiddenException, ConflictException, NotAcceptableException {
List<String> values;
FormField field;
// Get the new list of admins
field = completedForm.getField("muc#roomconfig_roomadmins");
boolean adminsSent = field != null;
List<JID> admins = new ArrayList<>();
if (field != null) {
for (String value : field.getValues()) {
// maintained based on the user's bare JID, (...)"
if (value != null && value.trim().length() != 0) {
// could be a group jid
admins.add(GroupJID.fromString((value.trim())).asBareJID());
}
}
}
// Get the new list of owners
field = completedForm.getField("muc#roomconfig_roomowners");
boolean ownersSent = field != null;
List<JID> owners = new ArrayList<>();
if (field != null) {
for (String value : field.getValues()) {
// maintained based on the user's bare JID, (...)"
if (value != null && value.trim().length() != 0) {
// could be a group jid
owners.add(GroupJID.fromString((value.trim())).asBareJID());
}
}
}
// Answer a conflict error if all the current owners will be removed
if (ownersSent && owners.isEmpty()) {
throw new ConflictException();
}
// Status codes signifying privacy-related configuration changes to be sent to everyone.
Set<Integer> statusCodes = new HashSet<>();
// Keep a registry of the updated presences
List<Presence> presences = new ArrayList<>(admins.size() + owners.size());
field = completedForm.getField("muc#roomconfig_roomname");
if (field != null) {
final String value = field.getFirstValue();
room.setNaturalLanguageName((value != null ? value : " "));
}
field = completedForm.getField("muc#roomconfig_roomdesc");
if (field != null) {
final String value = field.getFirstValue();
room.setDescription((value != null ? value : " "));
}
field = completedForm.getField("muc#roomconfig_changesubject");
if (field != null) {
room.setCanOccupantsChangeSubject(parseFirstValueAsBoolean(field, true));
}
field = completedForm.getField("muc#roomconfig_maxusers");
if (field != null) {
final String value = field.getFirstValue();
room.setMaxUsers((value != null ? Integer.parseInt(value) : 30));
}
field = completedForm.getField("muc#roomconfig_presencebroadcast");
if (field != null) {
values = new ArrayList<>(field.getValues());
room.setRolesToBroadcastPresence(values.stream().map(MUCRole.Role::valueOf).collect(Collectors.toList()));
}
field = completedForm.getField("muc#roomconfig_publicroom");
if (field != null) {
room.setPublicRoom(parseFirstValueAsBoolean(field, true));
}
field = completedForm.getField("muc#roomconfig_persistentroom");
if (field != null) {
boolean isPersistent = parseFirstValueAsBoolean(field, true);
// Delete the room from the DB if it's no longer persistent
if (room.isPersistent() && !isPersistent) {
MUCPersistenceManager.deleteFromDB(room);
}
room.setPersistent(isPersistent);
}
field = completedForm.getField("muc#roomconfig_moderatedroom");
if (field != null) {
room.setModerated(parseFirstValueAsBoolean(field, true));
}
field = completedForm.getField("muc#roomconfig_membersonly");
if (field != null) {
presences.addAll(room.setMembersOnly(parseFirstValueAsBoolean(field, true)));
}
field = completedForm.getField("muc#roomconfig_allowinvites");
if (field != null) {
room.setCanOccupantsInvite(parseFirstValueAsBoolean(field, true));
}
boolean passwordProtectionChanged = false;
boolean passwordChanged = false;
boolean updatedIsPasswordProtected = false;
String updatedPassword = null;
field = completedForm.getField("muc#roomconfig_passwordprotectedroom");
if (field != null) {
passwordProtectionChanged = true;
updatedIsPasswordProtected = parseFirstValueAsBoolean(field, true);
}
field = completedForm.getField("muc#roomconfig_roomsecret");
if (field != null) {
passwordChanged = true;
updatedPassword = completedForm.getField("muc#roomconfig_roomsecret").getFirstValue();
if (updatedPassword != null && updatedPassword.isEmpty()) {
updatedPassword = null;
}
}
if (passwordProtectionChanged) {
// The owner signifies that a change in password-protection status is desired.
if (!updatedIsPasswordProtected) {
// The owner lifts password protection.
room.setPassword(null);
} else if (updatedPassword == null && room.getPassword() == null) {
// The owner sets password-protection, but does not provide a password (and the room does not already have a password).
throw new NotAcceptableException("Room is made password-protected, but is missing a password.");
} else if (updatedPassword != null) {
// The owner sets password-protection and provided a new password.
room.setPassword(updatedPassword);
}
} else if (passwordChanged) {
// The owner did not explicitly signal a password protection change, but did change the password value.
// This implies a change in password protection.
room.setPassword(updatedPassword);
}
field = completedForm.getField("muc#roomconfig_whois");
if (field != null) {
final boolean newValue = ("anyone".equals(field.getFirstValue()));
final boolean oldValue = room.canAnyoneDiscoverJID();
room.setCanAnyoneDiscoverJID(newValue);
// XEP-0045, section 10.2.1: If the room is now non-anonymous, status code 172.
if (newValue && !oldValue) {
statusCodes.add(172);
}
// XEP-0045, section 10.2.1: If the room is now semi-anonymous, status code 173.
if (!newValue && oldValue) {
statusCodes.add(173);
}
}
field = completedForm.getField("muc#roomconfig_allowpm");
if (field != null) {
room.setCanSendPrivateMessage(field.getFirstValue());
}
field = completedForm.getField("muc#roomconfig_enablelogging");
if (field != null) {
final boolean newValue = parseFirstValueAsBoolean(field, true);
final boolean oldValue = room.isLogEnabled();
room.setLogEnabled(newValue);
// XEP-0045, section 10.2.1: If room logging is now enabled, status code 170.
if (newValue && !oldValue) {
statusCodes.add(170);
}
// XEP-0045, section 10.2.1: If room logging is now disabled, status code 171.
if (!newValue && oldValue) {
statusCodes.add(171);
}
}
field = completedForm.getField("x-muc#roomconfig_reservednick");
if (field != null) {
room.setLoginRestrictedToNickname(parseFirstValueAsBoolean(field, true));
}
field = completedForm.getField("x-muc#roomconfig_canchangenick");
if (field != null) {
room.setChangeNickname(parseFirstValueAsBoolean(field, true));
}
field = completedForm.getField("x-muc#roomconfig_registration");
if (field != null) {
room.setRegistrationEnabled(parseFirstValueAsBoolean(field, true));
}
// Update the modification date to reflect the last time when the room's configuration
// was modified
room.setModificationDate(new Date());
if (room.isPersistent()) {
room.saveToDB();
}
// Apply any configuration changes to the FMUC state.
room.getFmucHandler().applyConfigurationChanges();
// Set the new owners and admins of the room
presences.addAll(room.addOwners(owners, senderRole));
presences.addAll(room.addAdmins(admins, senderRole));
if (ownersSent) {
// Change the affiliation to "member" for the current owners that won't be neither
// owner nor admin (if the form included the owners field)
List<JID> ownersToRemove = new ArrayList<>(room.getOwners());
ownersToRemove.removeAll(admins);
ownersToRemove.removeAll(owners);
for (JID jid : ownersToRemove) {
// ignore group jids
if (!GroupJID.isGroup(jid)) {
presences.addAll(room.addMember(jid, null, senderRole));
}
}
}
if (adminsSent) {
// Change the affiliation to "member" for the current admins that won't be neither
// owner nor admin (if the form included the admins field)
List<JID> adminsToRemove = new ArrayList<>(room.getAdmins());
adminsToRemove.removeAll(admins);
adminsToRemove.removeAll(owners);
for (JID jid : adminsToRemove) {
// ignore group jids
if (!GroupJID.isGroup(jid)) {
presences.addAll(room.addMember(jid, null, senderRole));
}
}
}
// the room
if (!room.isPersistent() && room.getOccupantsCount() == 0) {
room.destroyRoom(null, null);
}
// Send the updated presences to the room occupants
for (Object presence : presences) {
room.send((Presence) presence, room.getRole());
}
// when the room configuration changes in a way that has an impact on the privacy or security profile of the room.
if (!statusCodes.isEmpty()) {
final Message message = new Message();
message.setFrom(room.getJID());
message.setTo(room.getJID());
message.setType(Message.Type.groupchat);
final Element x = message.addChildElement("x", "http://jabber.org/protocol/muc#user");
statusCodes.forEach(code -> x.addElement("status").addAttribute("code", String.valueOf(code)));
room.send(message, room.getRole());
}
}
Aggregations