/* * Copyright (C) 2005-2008 Jive Software. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.openfire.admin; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.util.ClassUtils; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.PropertyEventDispatcher; import org.jivesoftware.util.PropertyEventListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmpp.packet.JID; /** * The AdminManager manages the AdminProvider configured for this server, caches knowledge of * accounts with admin permissions, and provides a single point of entry for handling * getting and setting administrative accounts. * * The provider can be specified using the system property: * * <ul> * <li><tt>provider.admin.className = my.admin.provider</tt></li> * </ul> * * @author Daniel Henninger */ public class AdminManager { private static final Logger Log = LoggerFactory.getLogger(AdminManager.class); // Wrap this guy up so we can mock out the AdminManager class. private static class AdminManagerContainer { private static AdminManager instance = new AdminManager(); } /** * Returns the currently-installed AdminProvider. <b>Warning:</b> in virtually all * cases the admin provider should not be used directly. Instead, the appropriate * methods in AdminManager should be called. Direct access to the admin provider is * only provided for special-case logic. * * @return the current AdminProvider. */ public static AdminProvider getAdminProvider() { return AdminManagerContainer.instance.provider; } /** * Returns a singleton instance of AdminManager. * * @return a AdminManager instance. */ public static AdminManager getInstance() { return AdminManagerContainer.instance; } /* Cache of admin accounts */ private List<JID> adminList; private AdminProvider provider; /** * Constructs a AdminManager, propery listener, and setting up the provider. */ private AdminManager() { // Load an admin provider. initProvider(); // Detect when a new admin provider class is set PropertyEventListener propListener = new PropertyEventListener() { @Override public void propertySet(String property, Map<String, Object> params) { if ("provider.admin.className".equals(property)) { initProvider(); } } @Override public void propertyDeleted(String property, Map<String, Object> params) { //Ignore } @Override public void xmlPropertySet(String property, Map<String, Object> params) { //Ignore } @Override public void xmlPropertyDeleted(String property, Map<String, Object> params) { //Ignore } }; PropertyEventDispatcher.addListener(propListener); } /** * Initializes the server's admin provider, based on configuration and defaults to * DefaultAdminProvider if the specified provider is not valid or not specified. */ private void initProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("provider.admin.className"); String className = JiveGlobals.getProperty("provider.admin.className", "org.jivesoftware.openfire.admin.DefaultAdminProvider"); // Check if we need to reset the provider class if (provider == null || !className.equals(provider.getClass().getName())) { try { Class c = ClassUtils.forName(className); provider = (AdminProvider) c.newInstance(); } catch (Exception e) { Log.error("Error loading admin provider: " + className, e); provider = new DefaultAdminProvider(); } } } /** * Reads the admin list from the provider and sets up the cache. */ private void loadAdminList() { adminList = provider.getAdmins(); } /** * Refreshs the list of admin users from the provider. */ public void refreshAdminAccounts() { loadAdminList(); } /** * Returns the list of admin users from the provider. * * @return The list of users with admin status. */ public List<JID> getAdminAccounts() { if (adminList == null) { loadAdminList(); } return adminList; } /** * Adds a new account to the list of Admin accounts, based off a username, which will be converted * into a JID. * * @param username Username of account to add to list of admins. */ public void addAdminAccount(String username) { if (adminList == null) { loadAdminList(); } JID userJID = XMPPServer.getInstance().createJID(username, null); if (adminList.contains(userJID)) { // Already have them. return; } // Add new admin to cache. adminList.add(userJID); // Store updated list of admins with provider. provider.setAdmins(adminList); } /** * Adds a new account to the list of Admin accounts, based off a JID. * * @param jid JID of account to add to list of admins. */ public void addAdminAccount(JID jid) { if (adminList == null) { loadAdminList(); } JID bareJID = jid.asBareJID(); if (adminList.contains(bareJID)) { // Already have them. return; } // Add new admin to cache. adminList.add(bareJID); // Store updated list of admins with provider. provider.setAdmins(adminList); } /** * Removes an account from the list of Admin accounts, based off username, which will be converted * to a JID. * * @param username Username of user to remove from admin list. */ public void removeAdminAccount(String username) { if (adminList == null) { loadAdminList(); } JID userJID = XMPPServer.getInstance().createJID(username, null); if (!adminList.contains(userJID)) { return; } // Remove user from admin list cache. adminList.remove(userJID); // Store updated list of admins with provider. provider.setAdmins(adminList); } /** * Removes an account from the list of Admin accounts, based off JID. * * @param jid JID of user to remove from admin list. */ public void removeAdminAccount(JID jid) { if (adminList == null) { loadAdminList(); } JID bareJID = jid.asBareJID(); if (!adminList.contains(bareJID)) { return; } // Remove user from admin list cache. adminList.remove(bareJID); // Store updated list of admins with provider. provider.setAdmins(adminList); } /** * Returns true if the user is an admin. * * @param username Username of user to check whether they are an admin or not. * @param allowAdminIfEmpty Allows the "admin" user to log in if the adminList is empty. * @return True or false if user is an admin. */ public boolean isUserAdmin(String username, boolean allowAdminIfEmpty) { if (adminList == null) { loadAdminList(); } if (allowAdminIfEmpty && adminList.isEmpty()) { return "admin".equals(username); } JID userJID = XMPPServer.getInstance().createJID(username, null); return adminList.contains(userJID); } /** * Returns true if the user is an admin. * * @param jid JID of user to check whether they are an admin or not. * @param allowAdminIfEmpty Allows the "admin" user to log in if the adminList is empty. * @return True or false if user is an admin. */ public boolean isUserAdmin(JID jid, boolean allowAdminIfEmpty) { if (adminList == null) { loadAdminList(); } if (allowAdminIfEmpty && adminList.isEmpty()) { return "admin".equals(jid.getNode()); } JID bareJID = jid.asBareJID(); return adminList.contains(bareJID); } /** * Clears the list of admin users. */ public void clearAdminUsers() { // Clear the admin list cache. if (adminList == null) { adminList = new ArrayList<>(); } else { adminList.clear(); } // Store empty list of admins with provider. provider.setAdmins(adminList); } /** * Sets the list of admin users based off of a list of usernames. Clears list first. * * @param usernames List of usernames to set as admins. */ public void setAdminUsers(List<String> usernames) { if (adminList == null) { adminList = new ArrayList<>(); } else { adminList.clear(); } List<JID> admins = new ArrayList<>(); for (String username : usernames) { admins.add(XMPPServer.getInstance().createJID(username, null)); } adminList.addAll(admins); provider.setAdmins(admins); } /** * Sets the list of admin users based off of a list of jids. Clears list first. * * @param jids List of jids to set as admins. */ public void setAdminJIDs(List<JID> jids) { if (adminList == null) { adminList = new ArrayList<>(); } else { adminList.clear(); } List<JID> admins = new ArrayList<>(); for (JID jid : jids) { if (jid != null) { admins.add(jid.asBareJID()); } } adminList.addAll(admins); provider.setAdmins(admins); } }