James Moger
2011-10-23 d03aff630cbcd49f02d51f08ec59ac3cf7f41d0e
Separate management from administration in rpc servlet.

Added skeleton mechanism to update server settings via rpc.
8 files modified
148 ■■■■ changed files
distrib/gitblit.properties 12 ●●●● patch | view | raw | blame | history
src/com/gitblit/Constants.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java 26 ●●●●● patch | view | raw | blame | history
src/com/gitblit/RpcFilter.java 9 ●●●●● patch | view | raw | blame | history
src/com/gitblit/RpcServlet.java 14 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitClient.java 27 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitPanel.java 32 ●●●● patch | view | raw | blame | history
src/com/gitblit/utils/RpcUtils.java 26 ●●●●● patch | view | raw | blame | history
distrib/gitblit.properties
@@ -93,8 +93,16 @@
# SINCE 0.7.0 
web.enableRpcServlet = true
# Allows remote clients to administer the Gitblit instance, if the authenticated
# account has administrator permissions.  Requires *web.enableRpcServlet=true*.
# Allows remote clients to manage repositories and users of the Gitblit instance,
# if the authenticated account has administrator permissions.
# Requires *web.enableRpcServlet=true*.
#
# SINCE 0.7.0
web.enableRpcManagement = false
# Allows remote clients to control the server settings of the Gitblit instance,
# if the authenticated account has administrator permissions.
# Requires *web.enableRpcServlet=true* and *web.enableRpcManagement*.
#
# SINCE 0.7.0 
web.enableRpcAdministration = false
src/com/gitblit/Constants.java
@@ -204,7 +204,7 @@
        LIST_REPOSITORIES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY,
        LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS,
        SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS,
        LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS,
        LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS, EDIT_SETTINGS,
        LIST_STATUS;
        public static RpcRequest fromName(String name) {
src/com/gitblit/GitBlit.java
@@ -25,6 +25,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -67,9 +68,9 @@
import com.gitblit.models.Metric;
import com.gitblit.models.ObjectCache;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
import com.gitblit.models.SettingModel;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.FederationUtils;
@@ -244,6 +245,17 @@
     */
    public static boolean isDebugMode() {
        return self().settings.getBoolean(Keys.web.debugMode, false);
    }
    /**
     * Updates the list of server settings.
     *
     * @param settings
     * @return true if the update succeeded
     */
    public boolean updateSettings(Collection<SettingModel> settings) {
        // TODO update the settings
        return false;
    }
    public ServerStatus getStatus() {
@@ -442,10 +454,9 @@
            throws GitBlitException {
        if (!username.equalsIgnoreCase(user.username)) {
            if (userService.getUserModel(user.username) != null) {
                throw new GitBlitException(
                        MessageFormat
                                .format("Failed to rename ''{0}'' because ''{1}'' already exists.",
                                        username, user.username));
                throw new GitBlitException(MessageFormat.format(
                        "Failed to rename ''{0}'' because ''{1}'' already exists.", username,
                        user.username));
            }
        }
        if (!userService.updateUserModel(username, user)) {
@@ -735,9 +746,8 @@
                    repository.name += org.eclipse.jgit.lib.Constants.DOT_GIT_EXT;
                }
                if (new File(repositoriesFolder, repository.name).exists()) {
                    throw new GitBlitException(
                            MessageFormat
                                    .format("Failed to rename ''{0}'' because ''{1}'' already exists.",
                    throw new GitBlitException(MessageFormat.format(
                            "Failed to rename ''{0}'' because ''{1}'' already exists.",
                                            repositoryName, repository.name));
                }
                closeRepository(repositoryName);
src/com/gitblit/RpcFilter.java
@@ -76,7 +76,7 @@
        boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, false);
        boolean authenticateAdmin = GitBlit.getBoolean(Keys.web.authenticateAdminPages, true);
        
        // Wrap the HttpServletRequest with the RpcServletnRequest which
        // Wrap the HttpServletRequest with the RpcServletRequest which
        // overrides the servlet container user principal methods.
        AuthenticatedRequest authenticatedRequest = new AuthenticatedRequest(httpRequest);
        UserModel user = getUser(httpRequest);
@@ -84,9 +84,10 @@
            authenticatedRequest.setUser(user);
        }
        
        // conditionally reject rpc administration requests
        if (adminRequest && !GitBlit.getBoolean(Keys.web.enableRpcAdministration, false)) {
            logger.warn(Keys.web.enableRpcAdministration + " must be set TRUE for administrative rpc requests.");
        // conditionally reject rpc management/administration requests
        if (adminRequest && !GitBlit.getBoolean(Keys.web.enableRpcManagement, false)) {
            logger.warn(Keys.web.enableRpcManagement
                    + " must be set TRUE for management/administrative rpc requests.");
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
src/com/gitblit/RpcServlet.java
@@ -29,6 +29,7 @@
import com.gitblit.Constants.RpcRequest;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SettingModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.RpcUtils;
@@ -182,7 +183,20 @@
            }
        } else if (RpcRequest.LIST_SETTINGS.equals(reqType)) {
            // return the server's settings
            if (GitBlit.getBoolean(Keys.web.enableRpcAdministration, false)) {
            result = GitBlit.self().getSettingsModel();
            } else {
                response.sendError(notAllowedCode);
            }
        } else if (RpcRequest.EDIT_SETTINGS.equals(reqType)) {
            // update settings on the server
            if (GitBlit.getBoolean(Keys.web.enableRpcAdministration, false)) {
                Collection<SettingModel> settings = deserialize(request, response,
                        RpcUtils.SETTINGS_TYPE);
                GitBlit.self().updateSettings(settings);
            } else {
                response.sendError(notAllowedCode);
            }
        } else if (RpcRequest.LIST_STATUS.equals(reqType)) {
            // return the server's status information
            result = GitBlit.self().getStatus();
src/com/gitblit/client/GitblitClient.java
@@ -49,7 +49,9 @@
    private final char[] password;
    private volatile boolean isAdmin;
    private volatile boolean allowManagement;
    private volatile boolean allowAdministration;
    private volatile ServerSettings settings;
@@ -75,19 +77,32 @@
        refreshRepositories();
        try {
            settings = RpcUtils.getSettings(url, account, password);
            status = RpcUtils.getStatus(url, account, password);
            refreshUsers();
            isAdmin = true;
            allowManagement = true;
        } catch (UnauthorizedException e) {
        } catch (ForbiddenException e) {
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
        try {
            settings = RpcUtils.getSettings(url, account, password);
            status = RpcUtils.getStatus(url, account, password);
            allowAdministration = true;
        } catch (UnauthorizedException e) {
        } catch (ForbiddenException e) {
        } catch (IOException e) {
            System.err.println(e.getMessage());
    }
    public boolean allowAdmin() {
        return isAdmin;
    }
    public boolean allowManagement() {
        return allowManagement;
    }
    public boolean allowAdministration() {
        return allowAdministration;
    }
    public boolean isOwner(RepositoryModel model) {
src/com/gitblit/client/GitblitPanel.java
@@ -185,7 +185,8 @@
        repositoriesTable = Utils.newTable(repositoriesModel);
        repositoriesTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
        repositoriesTable.setRowSorter(defaultRepositoriesSorter);
        repositoriesTable.getRowSorter().toggleSortOrder(RepositoriesTableModel.Columns.Name.ordinal());
        repositoriesTable.getRowSorter().toggleSortOrder(
                RepositoriesTableModel.Columns.Name.ordinal());
        setRepositoryRenderer(RepositoriesTableModel.Columns.Name, nameRenderer, -1);
        setRepositoryRenderer(RepositoriesTableModel.Columns.Indicators, typeRenderer, 100);
@@ -208,7 +209,7 @@
                    RepositoryModel model = ((RepositoriesTableModel) repositoriesTable.getModel()).list
                            .get(modelRow);
                    editRepository.setEnabled(singleSelection
                            && (gitblit.allowAdmin() || gitblit.isOwner(model)));
                            && (gitblit.allowManagement() || gitblit.isOwner(model)));
                } else {
                    editRepository.setEnabled(false);
                }
@@ -217,7 +218,7 @@
        repositoriesTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2 && gitblit.allowAdmin()) {
                if (e.getClickCount() == 2 && gitblit.allowManagement()) {
                    editRepository(getSelectedRepositories().get(0));
                }
            }
@@ -266,8 +267,8 @@
        return repositoriesPanel;
    }
    private void setRepositoryRenderer(RepositoriesTableModel.Columns col, TableCellRenderer renderer,
            int maxWidth) {
    private void setRepositoryRenderer(RepositoriesTableModel.Columns col,
            TableCellRenderer renderer, int maxWidth) {
        String name = repositoriesTable.getColumnName(col.ordinal());
        repositoriesTable.getColumn(name).setCellRenderer(renderer);
        if (maxWidth > 0) {
@@ -457,9 +458,8 @@
        updateRepositoriesTable();
        Utils.packColumns(repositoriesTable, 2);
        if (gitblit.allowAdmin()) {
        if (gitblit.allowManagement()) {
            updateUsersTable();
            updateSettingsTable();
        } else {
            // user does not have administrator privileges
            // hide admin repository buttons
@@ -468,8 +468,21 @@
            delRepository.setVisible(false);
            while (tabs.getTabCount() > 1) {
                // remove admin tabs
                // remove all management/administration tabs
                tabs.removeTabAt(1);
            }
        }
        if (gitblit.allowAdministration()) {
            updateSettingsTable();
        } else {
            // remove the settings tab
            String settingsTitle = Translation.get("gb.settings");
            for (int i= 0; i < tabs.getTabCount(); i++) {
                if (tabs.getTitleAt(i).equals(settingsTitle)) {
                    tabs.removeTabAt(i);
                    break;
                }
            }
        }
    }
@@ -547,7 +560,8 @@
                return false;
            }
        };
        TableRowSorter<SettingsTableModel> sorter = new TableRowSorter<SettingsTableModel>(settingsModel);
        TableRowSorter<SettingsTableModel> sorter = new TableRowSorter<SettingsTableModel>(
                settingsModel);
        sorter.setRowFilter(containsFilter);
        settingsTable.setRowSorter(sorter);
    }
src/com/gitblit/utils/RpcUtils.java
@@ -28,8 +28,9 @@
import com.gitblit.models.FederationProposal;
import com.gitblit.models.FederationSet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.ServerStatus;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
import com.gitblit.models.SettingModel;
import com.gitblit.models.UserModel;
import com.google.gson.reflect.TypeToken;
@@ -42,6 +43,9 @@
public class RpcUtils {
    public static final Type NAMES_TYPE = new TypeToken<Collection<String>>() {
    }.getType();
    public static final Type SETTINGS_TYPE = new TypeToken<Collection<SettingModel>>() {
    }.getType();
    private static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
@@ -344,11 +348,29 @@
    public static ServerSettings getSettings(String serverUrl, String account, char[] password)
            throws IOException {
        String url = asLink(serverUrl, RpcRequest.LIST_SETTINGS);
        ServerSettings settings = JsonUtils.retrieveJson(url, ServerSettings.class, account, password);
        ServerSettings settings = JsonUtils.retrieveJson(url, ServerSettings.class, account,
                password);
        return settings;
    }
    /**
     * Update the settings on the Gitblit server.
     *
     * @param settings
     *            the settings to update
     * @param serverUrl
     * @param account
     * @param password
     * @return true if the action succeeded
     * @throws IOException
     */
    public static boolean updateSettings(Map<String, String> settings, String serverUrl,
            String account, char[] password) throws IOException {
        return doAction(RpcRequest.EDIT_SETTINGS, null, settings, serverUrl, account, password);
    }
    /**
     * Retrieves the server status object.
     * 
     * @param serverUrl