Commit 1df0b9a0 authored by Ryan Graham's avatar Ryan Graham Committed by ryang

* Added the ability to import user roster data when using a read-only user...

* Added the ability to import user roster data when using a read-only user store such as LDAP or POP3.
* Added the ability to allow user elements in the import file to be in any order.
* Added a check to make sure that the username is valid.
* Removed an unnecessary check when creating roster items.
* Updated UI to match later versions of Wildfire.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@6859 b35dd754-fafc-0310-a699-88a17e54d16e
parent 8a3ff84a
...@@ -142,14 +142,21 @@ hr { ...@@ -142,14 +142,21 @@ hr {
</head> </head>
<body> <body>
<div id="pageContainer"> <div id="pageContainer">
<div id="pageHeader"> <div id="pageHeader">
<h1>User Import/Export Plugin Changelog</h1> <h1>User Import/Export Plugin Changelog</h1>
</div> </div>
<div id="pageBody"> <div id="pageBody">
<h2>2.1.0 -- <span style="font-weight: normal;">Januar 29, 2007</span></h2>
<ul>
<li>Added the ability to import user roster data when using a read-only user store such as LDAP or POP3.</li>
<li>Added the ability to allow user elements in the import file to be in any order.</li>
<li>Added a check to make sure that the username is valid.</li>
<li>Removed an unnecessary check when creating roster items.</li>
<li>Updated UI to match later versions of Wildfire.</li>
</ul>
<h2>2.0.4 -- <span style="font-weight: normal;">October 06, 2006</span></h2> <h2>2.0.4 -- <span style="font-weight: normal;">October 06, 2006</span></h2>
<ul> <ul>
<li>Updated to use compression offered by Wildfire 3.1</li> <li>Updated to use compression offered by Wildfire 3.1</li>
...@@ -189,7 +196,7 @@ hr { ...@@ -189,7 +196,7 @@ hr {
<li>Initial release.</li> <li>Initial release.</li>
</ul> </ul>
</div> </div>
</div> </div>
</body> </body>
......
...@@ -4,77 +4,76 @@ ...@@ -4,77 +4,76 @@
<xs:element name="Wildfire"> <xs:element name="Wildfire">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element ref="User" maxOccurs="unbounded"/> <xs:element ref="User" maxOccurs="unbounded" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="User"> <xs:element name="User">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:all>
<xs:element ref="Username" use="required"/> <xs:element ref="Username" use="required" />
<xs:element ref="Password" use="required"/> <xs:element ref="Password" use="required" />
<xs:element ref="Email"/> <xs:element ref="Email" />
<xs:element ref="Name"/> <xs:element ref="Name" />
<xs:element ref="CreationDate"/> <xs:element ref="CreationDate" />
<xs:element ref="ModifiedDate"/> <xs:element ref="ModifiedDate" />
<xs:element ref="Roster"/> <xs:element ref="Roster" />
</xs:sequence> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="Username" type="xs:string"/> <xs:element name="Username" type="xs:string" />
<xs:element name="Password" type="xs:string"/> <xs:element name="Password" type="xs:string" />
<xs:element name="Email" type="xs:string"/> <xs:element name="Email" type="xs:string" />
<xs:element name="Name" type="xs:string"/> <xs:element name="Name" type="xs:string" />
<xs:element name="CreationDate" type="jive-date"/> <xs:element name="CreationDate" type="jive-date" />
<xs:element name="ModifiedDate" type="jive-date"/> <xs:element name="ModifiedDate" type="jive-date" />
<xs:element name="Roster"> <xs:element name="Roster">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element ref="Item" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="Item" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="Item"> <xs:element name="Item">
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
<xs:element ref="Group" maxOccurs="unbounded"/> <xs:element ref="Group" maxOccurs="unbounded" />
</xs:sequence> </xs:sequence>
<xs:attribute ref="jid" use="required"/> <xs:attribute ref="jid" use="required" />
<xs:attribute name="askstatus" use="required"/> <xs:attribute name="askstatus" use="required" />
<xs:attribute name="recvstatus" use="required"/> <xs:attribute name="recvstatus" use="required" />
<xs:attribute name="substatus" use="required"/> <xs:attribute name="substatus" use="required" />
<xs:attribute name="name"/> <xs:attribute name="name" />
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name="Group" type="xs:string"/> <xs:element name="Group" type="xs:string" />
<xs:attribute name="jid" type="xs:string"/> <xs:attribute name="jid" type="xs:string" />
<xs:attribute name="name" type="xs:string"/> <xs:attribute name="name" type="xs:string" />
<xs:attribute name="askstatus"> <xs:attribute name="askstatus">
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:integer"> <xs:restriction base="xs:integer">
<xs:minInclusive value="-1"/> <xs:minInclusive value="-1" />
<xs:maxInclusive value="3"/> <xs:maxInclusive value="3" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="recvstatus"> <xs:attribute name="recvstatus">
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:integer"> <xs:restriction base="xs:integer">
<xs:minInclusive value="-1"/> <xs:minInclusive value="-1" />
<xs:maxInclusive value="3"/> <xs:maxInclusive value="3" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="substatus"> <xs:attribute name="substatus">
<xs:simpleType> <xs:simpleType>
<xs:restriction base="xs:integer"> <xs:restriction base="xs:integer">
<xs:minInclusive value="-1"/> <xs:minInclusive value="-1" />
<xs:maxInclusive value="3"/> <xs:maxInclusive value="3" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:simpleType name="jive-date"> <xs:simpleType name="jive-date">
<xs:restriction base="xs:string"> <xs:restriction base="xs:string"></xs:restriction>
</xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:schema> </xs:schema>
\ No newline at end of file
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
<name>User Import Export</name> <name>User Import Export</name>
<description>Enables import and export of user data</description> <description>Enables import and export of user data</description>
<author>Ryan Graham</author> <author>Ryan Graham</author>
<version>2.0.4</version> <version>2.1.0</version>
<date>10/06/2006</date> <date>01/29/2007</date>
<minServerVersion>3.1.0</minServerVersion> <minServerVersion>3.1.0</minServerVersion>
<adminconsole> <adminconsole>
......
...@@ -170,9 +170,9 @@ hr { ...@@ -170,9 +170,9 @@ hr {
<h2>Overview</h2> <h2>Overview</h2>
<p>The user import/export plugin provides a way to import and export Wildfire user data via <p>The user import/export plugin provides a way to import and export Wildfire user data via
the Admin Console. The user data consists of jid (aka "username"), name, email address, password the Admin Console. The user data consists of username, password, name, email address, creation
and roster list (aka "buddy list"). This plugin also can aid in the migration of users from other and modified date, and roster list (aka "buddy list"). This plugin also can aid in the migration
Jabber/XMPP based systems to Wildfire.</p> of users from other Jabber/XMPP based systems to Wildfire.</p>
<h2>Installation</h2> <h2>Installation</h2>
<p>Copy the userImportExport.jar into the plugins directory of your Wildfire installation. <p>Copy the userImportExport.jar into the plugins directory of your Wildfire installation.
...@@ -184,19 +184,22 @@ userImportExport.jar file over the existing file.</p> ...@@ -184,19 +184,22 @@ userImportExport.jar file over the existing file.</p>
<h2>Using the Plugin</h2> <h2>Using the Plugin</h2>
<p>The plugin is accessed via the "User Import & Export" sidebar item located under the <p>The plugin is accessed via the "User Import & Export" sidebar item located under the
"Users/Groups" tab in the Admin Console. Note: if you are using LDAP as your user data source the "Users/Groups" tab in the Admin Console. Note: if you are using a read-only user store such as LDAP
following message will appear: "Sorry, because you are using LDAP as your user store this plugin or POP3 this plugin will still work with two caveats:
will not work with your Wildfire installation." <ol>
<li><b>Importing</b> - Select the "Import User Data" option from the user import/export selection <li>When exporting, the username will be placed in the password element.
<li>When importing, no new users will be created but if the user exists in the user store thier roster will be loaded.
</ol>
<li><strong>Importing</strong> - Select the "Import User Data" option from the user import/export selection
page. On the import page, use the "Browse" button to locate the file that contains the user page. On the import page, use the "Browse" button to locate the file that contains the user
information you want to locate and then click on the "Import" button. If the plugin is successful information you want to locate and then click on the "Import" button. If the plugin is successful
in importing all user data, you will be presented with the message: "All users added successfully". in importing all user data, you will be presented with the message: "All users added successfully".
If the plugin was not successful in importing all user data you, will receive a message indicating If the plugin was not successful in importing all user data you, will receive a message indicating
what might have gone wrong. If during the import process, the plugin detects that you are trying to what might have gone wrong. If during the import process, the plugin detects that you are trying to
import a user that already exists in the system, it will not import that user or any roster import a user that already exists in the system, it will not import that user or any roster
information.</li> information, except in the case of using a read-only user store.</li>
<br> <br>
<li><b>Exporting</b> - Select the "Export User Data" option from the user import/export selection <li><strong>Exporting</strong> - Select the "Export User Data" option from the user import/export selection
page. User data can be exported either to a file or directly to the screen. To export to a file, page. User data can be exported either to a file or directly to the screen. To export to a file,
select the "To File" radio button, enter the name you want your export file to be called in the select the "To File" radio button, enter the name you want your export file to be called in the
"Export File Name" and then click on the "Export" button. Note: the plugin will automatically append "Export File Name" and then click on the "Export" button. Note: the plugin will automatically append
...@@ -204,16 +207,16 @@ an ".xml" extension to the file name if it is not already present. To export to ...@@ -204,16 +207,16 @@ an ".xml" extension to the file name if it is not already present. To export to
the "To Screen" radio button and then click on the "Export" button. The user data will be placed in the "To Screen" radio button and then click on the "Export" button. The user data will be placed in
the provided text area.</li> the provided text area.</li>
<br> <br>
<li><b>Migration</b> - To import user data from another instant messaging system using the plugin, <li><strong>Migration</strong> - To import user data from another instant messaging system using the plugin,
the import file must conform to the wildfire-user-schema.xsd.xml schema file (located in the classes the import file must conform to the wildfire-user-schema.xsd.xml schema file (located in the classes
directory of the userImportExport.jar). When importing a user data file the plugin will first validate directory of the userImportExport.jar). When importing a user data file the plugin will first validate
the file against the schema file." If the plugin cannot validate the import file the user data will the file against the schema file. If the plugin cannot validate the import file the user data will
not be imported. During the import process the plugin gives you the ability to update user roster not be imported. During the import process the plugin gives you the ability to update user roster
entries domain names to server name of your Wildfire installation. For example, say you have a user entries domain names to server name of your Wildfire installation. For example, say you have a user
whose roster looks like: whose roster looks like:
</li> </li>
<br>
<p>
<div class="xmltable"> <div class="xmltable">
<table> <table>
<tr> <tr>
...@@ -238,15 +241,18 @@ whose roster looks like: ...@@ -238,15 +241,18 @@ whose roster looks like:
</tr> </tr>
</table> </table>
</div> </div>
<br> </p>
<p>
Mike and Jane's accounts both reside on server whose domain name is "im.olddomain.net" and are being Mike and Jane's accounts both reside on server whose domain name is "im.olddomain.net" and are being
imported to a Wildfire installation whose server name is "im.newdomain.net". If on the import screen imported to a Wildfire installation whose server name is "im.newdomain.net". If on the import screen
the "Optional Existing Domain" field is filled in with "im.olddomain.net" (without the quotes) any the "Optional Existing Domain" field is filled in with "im.olddomain.net" (without the quotes) any
roster item jid that contains "im.olddomain.net" will be replaced with "im.newdomain.net". So, in roster item jid that contains "im.olddomain.net" will be replaced with "im.newdomain.net". So, in
effect, the import file would be transformed to look like: effect, the import file would be transformed to look like:
<br> <br>
<br> </p>
<p>
<div class="xmltable"> <div class="xmltable">
<table> <table>
<tr> <tr>
...@@ -271,14 +277,14 @@ effect, the import file would be transformed to look like: ...@@ -271,14 +277,14 @@ effect, the import file would be transformed to look like:
</tr> </tr>
</table> </table>
</div> </div>
</p>
<br> <p>
<br>
Below is a sample of an exported user list from Wildfire than contains two users, Joe and Sally, who Below is a sample of an exported user list from Wildfire than contains two users, Joe and Sally, who
have added each other to their respective rosters. have added each other to their respective rosters.
<br> </p>
<br>
<p>
<div class="xmltable"> <div class="xmltable">
<table> <table>
<tr> <tr>
...@@ -317,12 +323,11 @@ have added each other to their respective rosters. ...@@ -317,12 +323,11 @@ have added each other to their respective rosters.
</tr> </tr>
</table> </table>
</div> </div>
</p>
<br> <p>
<br>
Below is a list of the different status types and what their associated numbers mean. Below is a list of the different status types and what their associated numbers mean.
<br> </p>
<br>
<div class="datatable"> <div class="datatable">
<table cellpadding="3" cellspacing="1" border="0" width="700"> <table cellpadding="3" cellspacing="1" border="0" width="700">
...@@ -406,7 +411,7 @@ Below is a list of the different status types and what their associated numbers ...@@ -406,7 +411,7 @@ Below is a list of the different status types and what their associated numbers
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</body> </body>
......
...@@ -19,6 +19,8 @@ import org.jivesoftware.wildfire.user.UserAlreadyExistsException; ...@@ -19,6 +19,8 @@ import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.wildfire.user.UserManager; import org.jivesoftware.wildfire.user.UserManager;
import org.jivesoftware.wildfire.user.UserNotFoundException; import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.user.UserProvider; import org.jivesoftware.wildfire.user.UserProvider;
import org.jivesoftware.stringprep.Stringprep;
import org.jivesoftware.stringprep.StringprepException;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -28,32 +30,26 @@ import java.io.IOException; ...@@ -28,32 +30,26 @@ import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
/** /**
* The user import/export plugin provides a way to import and export Wildfire * The user import/export plugin provides a way to import and export Wildfire
* user data via the Admin Console. The user data consists of jid (aka "username"), * user data via the Admin Console. The user data consists of username,
* name, email address, password and roster list (aka "buddy list"). This plugin also * name, email address, password and roster list (aka "buddy list"). This plugin also
* can aid in the migration of users from other Jabber/XMPP based systems to Jive * can aid in the migration of users from other Jabber/XMPP based systems to Jive
* Wildfire. * Wildfire.
* *
* @author Ryan Graham * @author <a href="mailto:ryan@version2software.com">Ryan Graham</a>
*/ */
public class ImportExportPlugin implements Plugin { public class ImportExportPlugin implements Plugin {
private UserManager userManager; private UserManager userManager;
private UserProvider provider; private UserProvider provider;
private String serverName; private String serverName;
public ImportExportPlugin() { public ImportExportPlugin() {
userManager = XMPPServer.getInstance().getUserManager(); userManager = XMPPServer.getInstance().getUserManager();
provider = UserManager.getUserProvider(); provider = UserManager.getUserProvider();
serverName = XMPPServer.getInstance().getServerInfo().getName(); serverName = XMPPServer.getInstance().getServerInfo().getName();
} }
...@@ -66,11 +62,23 @@ public class ImportExportPlugin implements Plugin { ...@@ -66,11 +62,23 @@ public class ImportExportPlugin implements Plugin {
serverName = null; serverName = null;
} }
/**
* Convenience method that returns true if this UserProvider is read-only.
*
* @return true if the user provider is read-only.
*/
public boolean isUserProviderReadOnly() { public boolean isUserProviderReadOnly() {
return provider.isReadOnly(); return provider.isReadOnly();
} }
public byte[] exportUsersToFile() throws IOException { /**
* Converts the user data that is to be exported to a byte[]. If a read-only
* user store is being used a user's password will be the same as their username.
*
* @return a byte[] of the user data.
* @throws IOException if there's a problem writing to the XMLWriter.
*/
public byte[] exportUsersToByteArray() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint()); XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
...@@ -79,6 +87,13 @@ public class ImportExportPlugin implements Plugin { ...@@ -79,6 +87,13 @@ public class ImportExportPlugin implements Plugin {
return out.toByteArray(); return out.toByteArray();
} }
/**
* Converts the exported user data to a String. If a read-only
* user store is being used a user's password will be the same as their username.
*
* @return a formatted String representation of the user data.
* @throws IOException if there's a problem writing to the XMLWriter.
*/
public String exportUsersToString() throws IOException { public String exportUsersToString() throws IOException {
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
XMLWriter writer = null; XMLWriter writer = null;
...@@ -97,12 +112,32 @@ public class ImportExportPlugin implements Plugin { ...@@ -97,12 +112,32 @@ public class ImportExportPlugin implements Plugin {
return stringWriter.toString(); return stringWriter.toString();
} }
public List<String> importUserData(FileItem file, String previousDomain) throws IOException, DocumentException { /**
* Returns a list of usernames that were unable to be imported or whose rosters could not imported. Users are not able to be
* imported for the following reasons:
* <li>Their username is not properly formatted.
* <li>If a read-only user data store is being used and the user could not be found.
* <li>If a writeable user data store is being used and the user already exists.
*
* @param file a FileItem containing the user data to be imported.
* @param previousDomain a String an optional parameter that if supplied will replace the user roster entries domain names to
* server name of current Wildfire installation.
* @return True if FileItem matches the wildfire user schema.
* @throws IOException if there is a problem reading the FileItem.
* @throws DocumentException if an error occurs during parsing.
*/
public List<String> importUserData(FileItem file, String previousDomain) throws DocumentException, IOException {
SAXReader reader = new SAXReader(); SAXReader reader = new SAXReader();
Document document = reader.read(file.getInputStream()); Document document = reader.read(file.getInputStream());
return importUsers(document, previousDomain); return importUsers(document, previousDomain);
} }
/**
* Returns whether or not the supplied FileItem matches the wildfire user schema
*
* @param file a FileItem to be validated.
* @return True if FileItem matches the wildfire user schema.
*/
public boolean validateImportFile(FileItem file) { public boolean validateImportFile(FileItem file) {
try { try {
return new UserSchemaValidator(file, "wildfire-user-schema.xsd.xml").validate(); return new UserSchemaValidator(file, "wildfire-user-schema.xsd.xml").validate();
...@@ -127,8 +162,11 @@ public class ImportExportPlugin implements Plugin { ...@@ -127,8 +162,11 @@ public class ImportExportPlugin implements Plugin {
userElement.addElement("Password").addText(AuthFactory.getPassword(user.getUsername())); userElement.addElement("Password").addText(AuthFactory.getPassword(user.getUsername()));
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
//this should never happen Log.info("User " + userName + " not found, setting their password to their username");
Log.info("User not found: " + userName + ", setting password to their username"); userElement.addElement("Password").addText(userName);
}
catch (UnsupportedOperationException e) {
Log.info("Unable to retrieve " + userName + " password, setting their password to their username");
userElement.addElement("Password").addText(userName); userElement.addElement("Password").addText(userName);
} }
userElement.addElement("Email").addText(user.getEmail() == null ? "" : user.getEmail()); userElement.addElement("Email").addText(user.getEmail() == null ? "" : user.getEmail());
...@@ -163,13 +201,11 @@ public class ImportExportPlugin implements Plugin { ...@@ -163,13 +201,11 @@ public class ImportExportPlugin implements Plugin {
} }
private List<String> importUsers(Document document, String previousDomain) { private List<String> importUsers(Document document, String previousDomain) {
List<String> duplicateUsers = new ArrayList<String>(); List<String> invalidUsers = new ArrayList<String>();
UserManager userManager = UserManager.getInstance(); UserManager userManager = UserManager.getInstance();
RosterItemProvider rosterItemProvider = RosterItemProvider.getInstance(); RosterItemProvider rosterItemProvider = RosterItemProvider.getInstance();
Map<String, List<RosterItem>> rosterMap = new HashMap<String, List<RosterItem>>();
Element users = document.getRootElement(); Element users = document.getRootElement();
Iterator usersIter = users.elementIterator("User"); Iterator usersIter = users.elementIterator("User");
...@@ -187,7 +223,6 @@ public class ImportExportPlugin implements Plugin { ...@@ -187,7 +223,6 @@ public class ImportExportPlugin implements Plugin {
Element userElement = (Element) userElements.next(); Element userElement = (Element) userElements.next();
String nameElement = userElement.getName(); String nameElement = userElement.getName();
if ("Username".equals(nameElement)) { if ("Username".equals(nameElement)) {
userName = userElement.getText(); userName = userElement.getText();
} }
...@@ -236,44 +271,33 @@ public class ImportExportPlugin implements Plugin { ...@@ -236,44 +271,33 @@ public class ImportExportPlugin implements Plugin {
if ((userName != null) && (password != null)) { if ((userName != null) && (password != null)) {
try { try {
userName = Stringprep.nodeprep(userName);
if (!isUserProviderReadOnly()) {
userManager.createUser(userName, password, name, email); userManager.createUser(userName, password, name, email);
rosterMap.put(userName, rosterItems);
}
catch (UserAlreadyExistsException e) {
Log.info("User already exists: " + userName);
duplicateUsers.add(userName);
}
}
} }
//this prevents a user from adding a non-existent user to their roster //Check to see user exists before adding their roster, this is for read-only user providers.
for (String userName: rosterMap.keySet()) { userManager.getUser(userName);
for (RosterItem ri: rosterMap.get(userName)) { for (RosterItem ri : rosterItems) {
try {
// If the contact is a local user then check that the user exists
if (serverName.equals(ri.getJid().getDomain())) {
userManager.getUser(removeDoman(ri.getJid()));
}
rosterItemProvider.createItem(userName, ri); rosterItemProvider.createItem(userName, ri);
} }
catch (UserNotFoundException e) {
Log.info("User '" + removeDoman(ri.getJid()) + "' not found, will not be added to '" + userName + "' roster.");
} }
catch (UserAlreadyExistsException e) { catch (StringprepException se) {
Log.info("User '" + removeDoman(ri.getJid()) + "' already belongs to '" + userName + "' roster."); Log.info("Invalid username " + userName);
invalidUsers.add(userName);
} }
catch (UserAlreadyExistsException e) {
Log.info("User already exists " + userName);
invalidUsers.add(userName);
} }
catch (UserNotFoundException e) {
Log.info("User not found " + userName);
invalidUsers.add(userName);
} }
return duplicateUsers;
} }
private static String removeDoman(JID jid) {
StringTokenizer tokens = new StringTokenizer(jid.toBareJID(), "@");
if (tokens.hasMoreTokens()) {
return tokens.nextToken();
} }
return null; return invalidUsers;
} }
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
response.setContentType("application/x-download"); response.setContentType("application/x-download");
response.setHeader("Content-Disposition","attachment;filename="+fileName+".xml"); response.setHeader("Content-Disposition","attachment;filename="+fileName+".xml");
ImportExportPlugin plugin = (ImportExportPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userimportexport"); ImportExportPlugin plugin = (ImportExportPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userimportexport");
byte[] content = plugin.exportUsersToFile(); byte[] content = plugin.exportUsersToByteArray();
OutputStream os = response.getOutputStream(); OutputStream os = response.getOutputStream();
os.write(content); os.write(content);
os.flush(); os.flush();
......
...@@ -85,9 +85,8 @@ ...@@ -85,9 +85,8 @@
<form action="export-user-data.jsp?exportUsers" method="post"> <form action="export-user-data.jsp?exportUsers" method="post">
<fieldset> <div class="jive-contentBoxHeader">Export Options</div>
<legend>Export Options</legend> <div class="jive-contentBox">
<div>
<p> <p>
Select the radio button next to the desired export option and then click on the Export button. Select the radio button next to the desired export option and then click on the Export button.
</p> </p>
...@@ -112,10 +111,7 @@ ...@@ -112,10 +111,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</fieldset>
<br><br>
<input type="submit" value="Export"> <input type="submit" value="Export">
</form> </form>
......
...@@ -16,12 +16,6 @@ ...@@ -16,12 +16,6 @@
<p> <p>
<% if (plugin.isUserProviderReadOnly()) { %>
Sorry, because you are using LDAP as your user store, this plugin will not work with your Wildfire installation.
<% } else { %>
The import and export functions allow you to read data into and write user The import and export functions allow you to read data into and write user
data from your Wildfire installation. data from your Wildfire installation.
...@@ -30,7 +24,13 @@ data from your Wildfire installation. ...@@ -30,7 +24,13 @@ data from your Wildfire installation.
<li><a href="export-user-data.jsp">Export User Data</a></li> <li><a href="export-user-data.jsp">Export User Data</a></li>
</ul> </ul>
<% if (plugin.isUserProviderReadOnly()) { %>
Note: because you are using a read-only user data store such as LDAP or POP3 you will only be able to import user roster data, not users themselves.
Please see the <a href="../../plugin-admin.jsp?plugin=userimportexport&showReadme=true&decorator=none">readme</a> for details.
<% } %> <% } %>
</p>
</body> </body>
</html> </html>
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
<% <%
boolean importUsers = request.getParameter("importUsers") != null; boolean importUsers = request.getParameter("importUsers") != null;
boolean success = request.getParameter("success") != null;
ImportExportPlugin plugin = (ImportExportPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userimportexport"); ImportExportPlugin plugin = (ImportExportPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userimportexport");
List<String> duplicateUsers = new ArrayList<String>(); List<String> duplicateUsers = new ArrayList<String>();
...@@ -42,7 +41,7 @@ ...@@ -42,7 +41,7 @@
return; return;
} }
errors.put("userAlreadyExists", "userAlreadyExists"); errors.put("invalidUser", "invalidUser");
} }
catch (MalformedURLException e) { catch (MalformedURLException e) {
errors.put("IOException", "IOException"); errors.put("IOException", "IOException");
...@@ -80,8 +79,13 @@ ...@@ -80,8 +79,13 @@
Import failed. Import failed.
<% } else if (errors.containsKey("invalidUserFile")) { %> <% } else if (errors.containsKey("invalidUserFile")) { %>
The import file does not match the user schema. The import file does not match the user schema.
<% } else if (errors.containsKey("userAlreadyExists")) { %> <% } else if (errors.containsKey("invalidUser")) { %>
The following users are already exist in the system and were not loaded:<br>
<% if (plugin.isUserProviderReadOnly()) { %>
The following users did not exist in the system or have invalid username so their roster was not loaded:<br>
<% } else { %>
The following users already exist in the system or have invalid username and were not loaded:<br>
<% } %>
<% <%
Iterator iter = duplicateUsers.iterator(); Iterator iter = duplicateUsers.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
...@@ -108,7 +112,11 @@ ...@@ -108,7 +112,11 @@
<tbody> <tbody>
<tr> <tr>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td> <td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<% if (plugin.isUserProviderReadOnly()) { %>
<td class="jive-icon-label">User roster data added successfully.</td>
<% } else { %>
<td class="jive-icon-label">All users added successfully.</td> <td class="jive-icon-label">All users added successfully.</td>
<% } %>
</tr> </tr>
</tbody> </tbody>
</table> </table>
...@@ -122,9 +130,8 @@ Use the form below to import a user data XML file. ...@@ -122,9 +130,8 @@ Use the form below to import a user data XML file.
<form action="import-user-data.jsp?importUsers" method="post" enctype="multipart/form-data"> <form action="import-user-data.jsp?importUsers" method="post" enctype="multipart/form-data">
<fieldset> <div class="jive-contentBoxHeader">Import</div>
<legend>Import</legend> <div class="jive-contentBox">
<div>
<p> <p>
Choose a file to import:</p> Choose a file to import:</p>
<input type="file" name="thefile"> <input type="file" name="thefile">
...@@ -136,10 +143,7 @@ Use the form below to import a user data XML file. ...@@ -136,10 +143,7 @@ Use the form below to import a user data XML file.
See the migration section of the <a href="../../plugin-admin.jsp?plugin=userimportexport&showReadme=true&decorator=none">readme</a> for details. See the migration section of the <a href="../../plugin-admin.jsp?plugin=userimportexport&showReadme=true&decorator=none">readme</a> for details.
</p> </p>
Replace Domain: <input type="text" size="20" maxlength="150" name="previousDomain" value=""/> Replace Domain: <input type="text" size="20" maxlength="150" name="previousDomain" value=""/>
</div>
</div>
</fieldset>
<br><br>
<input type="submit" value="Import"> <input type="submit" value="Import">
</form> </form>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment