Commit 9acf53b8 authored by Greg Thomas's avatar Greg Thomas

Allow the JDBCAdminProvider to update as well as read admin's

parent 23fa6f11
...@@ -49,7 +49,13 @@ import org.xmpp.packet.JID; ...@@ -49,7 +49,13 @@ import org.xmpp.packet.JID;
* <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&amp;password=secret</tt></li> * <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&amp;password=secret</tt></li>
* <li><tt>jdbcAdminProvider.getAdminsSQL = SELECT user FROM myAdmins</tt></li> * <li><tt>jdbcAdminProvider.getAdminsSQL = SELECT user FROM myAdmins</tt></li>
* </ul> * </ul>
* * <p>
* If you want to be able to update the admin users via the UI, add the following properties:
* <ul>
* <li><tt>jdbcAdminProvider.insertAdminsSQL = INSERT INTO myAdmins (user) VALUES (?)</tt></li>
* <li><tt>jdbcAdminProvider.deleteAdminsSQL = DELETE FROM myAdmins WHERE user = ?</tt></li>
* </ul>
* <p>
* In order to use the configured JDBC connection provider do not use a JDBC * In order to use the configured JDBC connection provider do not use a JDBC
* connection string, set the following property * connection string, set the following property
* *
...@@ -65,6 +71,8 @@ public class JDBCAdminProvider implements AdminProvider { ...@@ -65,6 +71,8 @@ public class JDBCAdminProvider implements AdminProvider {
private static final Logger Log = LoggerFactory.getLogger(JDBCAdminProvider.class); private static final Logger Log = LoggerFactory.getLogger(JDBCAdminProvider.class);
private final String getAdminsSQL; private final String getAdminsSQL;
private final String insertAdminsSQL;
private final String deleteAdminsSQL;
private final String xmppDomain; private final String xmppDomain;
private final boolean useConnectionProvider; private final boolean useConnectionProvider;
...@@ -84,14 +92,15 @@ public class JDBCAdminProvider implements AdminProvider { ...@@ -84,14 +92,15 @@ public class JDBCAdminProvider implements AdminProvider {
// Load database statement for reading admin list // Load database statement for reading admin list
getAdminsSQL = JiveGlobals.getProperty("jdbcAdminProvider.getAdminsSQL"); getAdminsSQL = JiveGlobals.getProperty("jdbcAdminProvider.getAdminsSQL");
insertAdminsSQL = JiveGlobals.getProperty("jdbcAdminProvider.insertAdminsSQL", "");
deleteAdminsSQL = JiveGlobals.getProperty("jdbcAdminProvider.deleteAdminsSQL", "");
// Load the JDBC driver and connection string // Load the JDBC driver and connection string
if (!useConnectionProvider) { if (!useConnectionProvider) {
String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver");
try { try {
Class.forName(jdbcDriver).newInstance(); Class.forName(jdbcDriver).newInstance();
} } catch (Exception e) {
catch (Exception e) {
Log.error("Unable to load JDBC driver: " + jdbcDriver, e); Log.error("Unable to load JDBC driver: " + jdbcDriver, e);
return; return;
} }
...@@ -106,34 +115,61 @@ public class JDBCAdminProvider implements AdminProvider { ...@@ -106,34 +115,61 @@ public class JDBCAdminProvider implements AdminProvider {
ResultSet rs = null; ResultSet rs = null;
List<JID> jids = new ArrayList<>(); List<JID> jids = new ArrayList<>();
synchronized (getAdminsSQL) {
try { try {
con = getConnection(); con = getConnection();
pstmt = con.prepareStatement(getAdminsSQL); pstmt = con.prepareStatement(getAdminsSQL);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
while (rs.next()) { while (rs.next()) {
String name = rs.getString(1); String name = rs.getString(1);
jids.add(new JID(name + "@" + xmppDomain)); jids.add(new JID(name + "@" + xmppDomain));
}
return jids;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
} }
return jids;
} }
catch (SQLException e) { }
throw new RuntimeException(e);
@Override
public void setAdmins(List<JID> newAdmins) {
if (isReadOnly()) {
// Reject the operation since the provider is read-only
throw new UnsupportedOperationException();
} }
finally {
DbConnectionManager.closeConnection(rs, pstmt, con); synchronized (getAdminsSQL) {
final List<JID> currentAdmins = getAdmins();
// Get a list of everyone in the new list not in the current list
final List<JID> adminsToAdd = new ArrayList<>(newAdmins);
adminsToAdd.removeAll(currentAdmins);
// Get a list of everyone in the current list not in the new list
currentAdmins.removeAll(newAdmins);
try (final Connection con = getConnection()) {
changeAdmins(con, insertAdminsSQL, adminsToAdd);
changeAdmins(con, deleteAdminsSQL, currentAdmins);
} catch (SQLException e) {
throw new RuntimeException(e);
}
} }
} }
@Override private void changeAdmins(final Connection con, final String sql, final List<JID> admins) throws SQLException {
public void setAdmins(List<JID> admins) { if (!admins.isEmpty()) {
// Reject the operation since the provider is read-only try (final PreparedStatement pstmt = con.prepareStatement(sql)) {
throw new UnsupportedOperationException(); for (final JID jid : admins) {
pstmt.setString(1, jid.getNode());
pstmt.execute();
}
}
}
} }
@Override @Override
public boolean isReadOnly() { public boolean isReadOnly() {
return true; return insertAdminsSQL.isEmpty() || deleteAdminsSQL.isEmpty();
} }
private Connection getConnection() throws SQLException { private Connection getConnection() throws SQLException {
......
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