| /* | |
| * Copyright 2011 gitblit.com. | |
| * | |
| * 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 com.gitblit; | |
| import java.io.IOException; | |
| import java.text.MessageFormat; | |
| import java.util.ArrayList; | |
| import java.util.Collection; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import javax.servlet.ServletException; | |
| import javax.servlet.http.HttpServletRequest; | |
| import javax.servlet.http.HttpServletResponse; | |
| import org.eclipse.jgit.lib.Repository; | |
| import com.gitblit.Constants.RpcRequest; | |
| import com.gitblit.models.RefModel; | |
| import com.gitblit.models.RepositoryModel; | |
| import com.gitblit.models.ServerSettings; | |
| import com.gitblit.models.TeamModel; | |
| import com.gitblit.models.UserModel; | |
| import com.gitblit.utils.HttpUtils; | |
| import com.gitblit.utils.JGitUtils; | |
| import com.gitblit.utils.RpcUtils; | |
| /** | |
| * Handles remote procedure calls. | |
| * | |
| * @author James Moger | |
| * | |
| */ | |
| public class RpcServlet extends JsonServlet { | |
| private static final long serialVersionUID = 1L; | |
| public static final int PROTOCOL_VERSION = 2; | |
| public RpcServlet() { | |
| super(); | |
| } | |
| /** | |
| * Processes an rpc request. | |
| * | |
| * @param request | |
| * @param response | |
| * @throws javax.servlet.ServletException | |
| * @throws java.io.IOException | |
| */ | |
| @Override | |
| protected void processRequest(HttpServletRequest request, HttpServletResponse response) | |
| throws ServletException, IOException { | |
| RpcRequest reqType = RpcRequest.fromName(request.getParameter("req")); | |
| String objectName = request.getParameter("name"); | |
| logger.info(MessageFormat.format("Rpc {0} request from {1}", reqType, | |
| request.getRemoteAddr())); | |
| UserModel user = (UserModel) request.getUserPrincipal(); | |
| boolean allowManagement = user != null && user.canAdmin | |
| && GitBlit.getBoolean(Keys.web.enableRpcManagement, false); | |
| boolean allowAdmin = user != null && user.canAdmin | |
| && GitBlit.getBoolean(Keys.web.enableRpcAdministration, false); | |
| Object result = null; | |
| if (RpcRequest.GET_PROTOCOL.equals(reqType)) { | |
| // Return the protocol version | |
| result = PROTOCOL_VERSION; | |
| } else if (RpcRequest.LIST_REPOSITORIES.equals(reqType)) { | |
| // Determine the Gitblit clone url | |
| String gitblitUrl = HttpUtils.getGitblitURL(request); | |
| StringBuilder sb = new StringBuilder(); | |
| sb.append(gitblitUrl); | |
| sb.append(Constants.GIT_PATH); | |
| sb.append("{0}"); | |
| String cloneUrl = sb.toString(); | |
| // list repositories | |
| List<RepositoryModel> list = GitBlit.self().getRepositoryModels(user); | |
| Map<String, RepositoryModel> repositories = new HashMap<String, RepositoryModel>(); | |
| for (RepositoryModel model : list) { | |
| String url = MessageFormat.format(cloneUrl, model.name); | |
| repositories.put(url, model); | |
| } | |
| result = repositories; | |
| } else if (RpcRequest.LIST_BRANCHES.equals(reqType)) { | |
| // list all local branches in all repositories accessible to user | |
| Map<String, List<String>> localBranches = new HashMap<String, List<String>>(); | |
| List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user); | |
| for (RepositoryModel model : models) { | |
| if (!model.hasCommits) { | |
| // skip empty repository | |
| continue; | |
| } | |
| // get local branches | |
| Repository repository = GitBlit.self().getRepository(model.name); | |
| List<RefModel> refs = JGitUtils.getLocalBranches(repository, false, -1); | |
| if (model.showRemoteBranches) { | |
| // add remote branches if repository displays them | |
| refs.addAll(JGitUtils.getRemoteBranches(repository, false, -1)); | |
| } | |
| if (refs.size() > 0) { | |
| List<String> branches = new ArrayList<String>(); | |
| for (RefModel ref : refs) { | |
| branches.add(ref.getName()); | |
| } | |
| localBranches.put(model.name, branches); | |
| } | |
| repository.close(); | |
| } | |
| result = localBranches; | |
| } else if (RpcRequest.LIST_USERS.equals(reqType)) { | |
| // list users | |
| List<String> names = GitBlit.self().getAllUsernames(); | |
| List<UserModel> users = new ArrayList<UserModel>(); | |
| for (String name : names) { | |
| users.add(GitBlit.self().getUserModel(name)); | |
| } | |
| result = users; | |
| } else if (RpcRequest.LIST_TEAMS.equals(reqType)) { | |
| // list teams | |
| List<String> names = GitBlit.self().getAllTeamnames(); | |
| List<TeamModel> teams = new ArrayList<TeamModel>(); | |
| for (String name : names) { | |
| teams.add(GitBlit.self().getTeamModel(name)); | |
| } | |
| result = teams; | |
| } else if (RpcRequest.CREATE_REPOSITORY.equals(reqType)) { | |
| // create repository | |
| RepositoryModel model = deserialize(request, response, RepositoryModel.class); | |
| try { | |
| GitBlit.self().updateRepositoryModel(model.name, model, true); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.EDIT_REPOSITORY.equals(reqType)) { | |
| // edit repository | |
| RepositoryModel model = deserialize(request, response, RepositoryModel.class); | |
| // name specifies original repository name in event of rename | |
| String repoName = objectName; | |
| if (repoName == null) { | |
| repoName = model.name; | |
| } | |
| try { | |
| GitBlit.self().updateRepositoryModel(repoName, model, false); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.DELETE_REPOSITORY.equals(reqType)) { | |
| // delete repository | |
| RepositoryModel model = deserialize(request, response, RepositoryModel.class); | |
| GitBlit.self().deleteRepositoryModel(model); | |
| } else if (RpcRequest.CREATE_USER.equals(reqType)) { | |
| // create user | |
| UserModel model = deserialize(request, response, UserModel.class); | |
| try { | |
| GitBlit.self().updateUserModel(model.username, model, true); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.EDIT_USER.equals(reqType)) { | |
| // edit user | |
| UserModel model = deserialize(request, response, UserModel.class); | |
| // name parameter specifies original user name in event of rename | |
| String username = objectName; | |
| if (username == null) { | |
| username = model.username; | |
| } | |
| try { | |
| GitBlit.self().updateUserModel(username, model, false); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.DELETE_USER.equals(reqType)) { | |
| // delete user | |
| UserModel model = deserialize(request, response, UserModel.class); | |
| if (!GitBlit.self().deleteUser(model.username)) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.CREATE_TEAM.equals(reqType)) { | |
| // create team | |
| TeamModel model = deserialize(request, response, TeamModel.class); | |
| try { | |
| GitBlit.self().updateTeamModel(model.name, model, true); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.EDIT_TEAM.equals(reqType)) { | |
| // edit team | |
| TeamModel model = deserialize(request, response, TeamModel.class); | |
| // name parameter specifies original team name in event of rename | |
| String teamname = objectName; | |
| if (teamname == null) { | |
| teamname = model.name; | |
| } | |
| try { | |
| GitBlit.self().updateTeamModel(teamname, model, false); | |
| } catch (GitBlitException e) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.DELETE_TEAM.equals(reqType)) { | |
| // delete team | |
| TeamModel model = deserialize(request, response, TeamModel.class); | |
| if (!GitBlit.self().deleteTeam(model.name)) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.LIST_REPOSITORY_MEMBERS.equals(reqType)) { | |
| // get repository members | |
| RepositoryModel model = GitBlit.self().getRepositoryModel(objectName); | |
| result = GitBlit.self().getRepositoryUsers(model); | |
| } else if (RpcRequest.SET_REPOSITORY_MEMBERS.equals(reqType)) { | |
| // update repository access list | |
| RepositoryModel model = GitBlit.self().getRepositoryModel(objectName); | |
| Collection<String> names = deserialize(request, response, RpcUtils.NAMES_TYPE); | |
| List<String> users = new ArrayList<String>(names); | |
| if (!GitBlit.self().setRepositoryUsers(model, users)) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.LIST_REPOSITORY_TEAMS.equals(reqType)) { | |
| // get repository teams | |
| RepositoryModel model = GitBlit.self().getRepositoryModel(objectName); | |
| result = GitBlit.self().getRepositoryTeams(model); | |
| } else if (RpcRequest.SET_REPOSITORY_TEAMS.equals(reqType)) { | |
| // update repository team access list | |
| RepositoryModel model = GitBlit.self().getRepositoryModel(objectName); | |
| Collection<String> names = deserialize(request, response, RpcUtils.NAMES_TYPE); | |
| List<String> teams = new ArrayList<String>(names); | |
| if (!GitBlit.self().setRepositoryTeams(model, teams)) { | |
| response.setStatus(failureCode); | |
| } | |
| } else if (RpcRequest.LIST_FEDERATION_REGISTRATIONS.equals(reqType)) { | |
| // return the list of federation registrations | |
| if (allowAdmin) { | |
| result = GitBlit.self().getFederationRegistrations(); | |
| } else { | |
| response.sendError(notAllowedCode); | |
| } | |
| } else if (RpcRequest.LIST_FEDERATION_RESULTS.equals(reqType)) { | |
| // return the list of federation result registrations | |
| if (allowAdmin && GitBlit.canFederate()) { | |
| result = GitBlit.self().getFederationResultRegistrations(); | |
| } else { | |
| response.sendError(notAllowedCode); | |
| } | |
| } else if (RpcRequest.LIST_FEDERATION_PROPOSALS.equals(reqType)) { | |
| // return the list of federation proposals | |
| if (allowAdmin && GitBlit.canFederate()) { | |
| result = GitBlit.self().getPendingFederationProposals(); | |
| } else { | |
| response.sendError(notAllowedCode); | |
| } | |
| } else if (RpcRequest.LIST_FEDERATION_SETS.equals(reqType)) { | |
| // return the list of federation sets | |
| if (allowAdmin && GitBlit.canFederate()) { | |
| String gitblitUrl = HttpUtils.getGitblitURL(request); | |
| result = GitBlit.self().getFederationSets(gitblitUrl); | |
| } else { | |
| response.sendError(notAllowedCode); | |
| } | |
| } else if (RpcRequest.LIST_SETTINGS.equals(reqType)) { | |
| // return the server's settings | |
| ServerSettings settings = GitBlit.self().getSettingsModel(); | |
| if (allowAdmin) { | |
| // return all settings | |
| result = settings; | |
| } else { | |
| // anonymous users get a few settings to allow browser launching | |
| List<String> keys = new ArrayList<String>(); | |
| keys.add(Keys.web.siteName); | |
| keys.add(Keys.web.mountParameters); | |
| keys.add(Keys.web.syndicationEntries); | |
| if (allowManagement) { | |
| // keys necessary for repository and/or user management | |
| keys.add(Keys.realm.minPasswordLength); | |
| keys.add(Keys.realm.passwordStorage); | |
| keys.add(Keys.federation.sets); | |
| } | |
| // build the settings | |
| ServerSettings managementSettings = new ServerSettings(); | |
| for (String key : keys) { | |
| managementSettings.add(settings.get(key)); | |
| } | |
| if (allowManagement) { | |
| managementSettings.pushScripts = settings.pushScripts; | |
| } | |
| result = managementSettings; | |
| } | |
| } else if (RpcRequest.EDIT_SETTINGS.equals(reqType)) { | |
| // update settings on the server | |
| if (allowAdmin) { | |
| Map<String, String> 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 | |
| if (allowAdmin) { | |
| result = GitBlit.self().getStatus(); | |
| } else { | |
| response.sendError(notAllowedCode); | |
| } | |
| } | |
| // send the result of the request | |
| serialize(response, result); | |
| } | |
| } |