@@ -11,9 +11,11 @@ r24: { | |||
security: ~ | |||
fixes: ~ | |||
changes: ~ | |||
additions: ~ | |||
additions: | |||
- Add FORK_REPOSITORY RPC request type (issue-371, pr-161, ticket-65) | |||
dependencyChanges: ~ | |||
contributors: ~ | |||
contributors: | |||
- Manisha Gayathri | |||
} | |||
# |
@@ -350,10 +350,11 @@ public class Constants { | |||
* a client. | |||
*/ | |||
public static enum RpcRequest { | |||
// Order is important here. anything above LIST_SETTINGS requires | |||
// Order is important here. anything after LIST_SETTINGS requires | |||
// administrator privileges and web.allowRpcManagement. | |||
CLEAR_REPOSITORY_CACHE, REINDEX_TICKETS, GET_PROTOCOL, LIST_REPOSITORIES, LIST_BRANCHES, GET_USER, LIST_SETTINGS, | |||
CREATE_REPOSITORY, FORK_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, | |||
CLEAR_REPOSITORY_CACHE, REINDEX_TICKETS, GET_PROTOCOL, LIST_REPOSITORIES, LIST_BRANCHES, GET_USER, | |||
FORK_REPOSITORY, LIST_SETTINGS, | |||
CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, | |||
LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, | |||
LIST_TEAMS, CREATE_TEAM, EDIT_TEAM, DELETE_TEAM, | |||
LIST_REPOSITORY_MEMBERS, SET_REPOSITORY_MEMBERS, LIST_REPOSITORY_TEAMS, SET_REPOSITORY_TEAMS, |
@@ -1,47 +0,0 @@ | |||
package com.gitblit.models; | |||
/* | |||
* 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. | |||
*/ | |||
import com.gitblit.utils.StringUtils; | |||
import java.io.Serializable; | |||
public class UserRepositoryCompositeModel implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
public UserModel userModel; | |||
public RepositoryModel repositoryModel; | |||
public UserModel getUserModel() { | |||
return userModel; | |||
} | |||
public void setUserModel(UserModel userModel) { | |||
this.userModel = userModel; | |||
} | |||
public RepositoryModel getRepositoryModel() { | |||
return repositoryModel; | |||
} | |||
public void setRepositoryModel(RepositoryModel repositoryModel) { | |||
this.repositoryModel = repositoryModel; | |||
} | |||
} |
@@ -27,7 +27,6 @@ import javax.servlet.ServletException; | |||
import javax.servlet.http.HttpServletRequest; | |||
import javax.servlet.http.HttpServletResponse; | |||
import com.gitblit.models.*; | |||
import org.eclipse.jgit.lib.Repository; | |||
import com.gitblit.Constants; | |||
@@ -36,6 +35,12 @@ import com.gitblit.GitBlitException; | |||
import com.gitblit.IStoredSettings; | |||
import com.gitblit.Keys; | |||
import com.gitblit.manager.IGitblit; | |||
import com.gitblit.models.RefModel; | |||
import com.gitblit.models.RegistrantAccessPermission; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.ServerSettings; | |||
import com.gitblit.models.TeamModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.DeepCopier; | |||
import com.gitblit.utils.HttpUtils; | |||
import com.gitblit.utils.JGitUtils; | |||
@@ -53,7 +58,7 @@ public class RpcServlet extends JsonServlet { | |||
private static final long serialVersionUID = 1L; | |||
public static final int PROTOCOL_VERSION = 7; | |||
public static final int PROTOCOL_VERSION = 8; | |||
private IStoredSettings settings; | |||
@@ -191,22 +196,31 @@ public class RpcServlet extends JsonServlet { | |||
response.setStatus(failureCode); | |||
} | |||
} else if (RpcRequest.FORK_REPOSITORY.equals(reqType)) { | |||
// fork repository | |||
UserRepositoryCompositeModel userRepositoryCompositeModel = deserialize(request, response, | |||
UserRepositoryCompositeModel.class); | |||
RepositoryModel repoModel = userRepositoryCompositeModel.getRepositoryModel(); | |||
UserModel userModel = userRepositoryCompositeModel.getUserModel(); | |||
try { | |||
if (repoModel != null && userModel != null) { | |||
gitblit.fork(repoModel, userModel); | |||
} else { | |||
System.out.println("Non existing user model or repo model"); | |||
response.setStatus(failureCode); | |||
} | |||
} catch (GitBlitException e) { | |||
response.setStatus(failureCode); | |||
} | |||
// fork repository | |||
RepositoryModel origin = gitblit.getRepositoryModel(objectName); | |||
if (origin == null) { | |||
// failed to find repository, error is logged by the repository manager | |||
response.setStatus(failureCode); | |||
} else { | |||
if (user == null || !user.canFork(origin)) { | |||
logger.error("User {} is not permitted to fork '{}'!", | |||
user == null ? "anonymous" : user.username, objectName); | |||
response.setStatus(failureCode); | |||
} else { | |||
try { | |||
// fork the origin | |||
RepositoryModel fork = gitblit.fork(origin, user); | |||
if (fork == null) { | |||
logger.error("Failed to fork repository '{}'!", objectName); | |||
response.setStatus(failureCode); | |||
} else { | |||
logger.info("User {} has forked '{}'!", user.username, objectName); | |||
} | |||
} catch (GitBlitException e) { | |||
response.setStatus(failureCode); | |||
} | |||
} | |||
} | |||
} else if (RpcRequest.EDIT_REPOSITORY.equals(reqType)) { | |||
// edit repository | |||
RepositoryModel model = deserialize(request, response, RepositoryModel.class); |
@@ -25,7 +25,16 @@ import java.util.Map; | |||
import com.gitblit.Constants; | |||
import com.gitblit.Constants.RpcRequest; | |||
import com.gitblit.GitBlitException.UnknownRequestException; | |||
import com.gitblit.models.*; | |||
import com.gitblit.models.FederationModel; | |||
import com.gitblit.models.FederationProposal; | |||
import com.gitblit.models.FederationSet; | |||
import com.gitblit.models.FeedModel; | |||
import com.gitblit.models.RegistrantAccessPermission; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.ServerSettings; | |||
import com.gitblit.models.ServerStatus; | |||
import com.gitblit.models.TeamModel; | |||
import com.gitblit.models.UserModel; | |||
import com.google.gson.reflect.TypeToken; | |||
/** | |||
@@ -195,20 +204,16 @@ public class RpcUtils { | |||
} | |||
/** | |||
* Create a fork of an already existing repo | |||
* Create a fork of a repository. | |||
* | |||
* @param repository | |||
* @param user | |||
* @return true if the action succeeded | |||
* @throws IOException | |||
*/ | |||
public static boolean forkRpository(RepositoryModel repository, UserModel user, String serverUrl, | |||
public static boolean forkRepository(RepositoryModel repository, String serverUrl, | |||
String account, char[] password) throws IOException { | |||
UserRepositoryCompositeModel userRepositoryCompositeModel = new UserRepositoryCompositeModel(); | |||
userRepositoryCompositeModel.setRepositoryModel(repository); | |||
userRepositoryCompositeModel.setUserModel(user); | |||
return doAction(RpcRequest.FORK_REPOSITORY, null, userRepositoryCompositeModel, serverUrl, account, password); | |||
return doAction(RpcRequest.FORK_REPOSITORY, repository.name, null, serverUrl, account, password); | |||
} | |||
@@ -57,9 +57,10 @@ The Gitblit API includes methods for retrieving and interpreting RSS feeds. The | |||
<tr><td>Gitblit v0.8.0</td><td>2</td></tr> | |||
<tr><td>Gitblit v0.9.0 - v1.0.0</td><td>3</td></tr> | |||
<tr><td>Gitblit v1.1.0</td><td>4</td></tr> | |||
<tr><td>Gitblit v1.2.0+</td><td>5</td></tr> | |||
<tr><td>Gitblit v1.3.1+</td><td>6</td></tr> | |||
<tr><td>Gitblit v1.4.0+</td><td>7</td></tr> | |||
<tr><td>Gitblit v1.2.0</td><td>5</td></tr> | |||
<tr><td>Gitblit v1.3.1</td><td>6</td></tr> | |||
<tr><td>Gitblit v1.4.0</td><td>7</td></tr> | |||
<tr><td>Gitblit v1.6.0</td><td>8</td></tr> | |||
</tbody> | |||
</table> | |||
@@ -81,6 +82,7 @@ Use *SET_REPOSITORY_TEAM_PERMISSIONS* instead. | |||
<tr><td>LIST_BRANCHES</td><td>-</td><td>-</td><td>1</td><td>-</td><td>Map<String, List<String>></td></tr> | |||
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>-</em></td><td>1</td><td>-</td><td>ServerSettings (basic keys)</td></tr> | |||
<tr><td>GET_USER</td><td>user name</td><td>-</td><td>6</td><td>-</td><td>UserModel</td></tr> | |||
<tr><td>FORK_REPOSITORY</td><td>repository name</td><td><em>-</em></td><td>8</td><td>-</td><td>-</td></tr> | |||
<tr><td colspan='6'><em>web.enableRpcManagement=true</em></td></tr> | |||
<tr><td>CREATE_REPOSITORY</td><td>repository name</td><td><em>admin</em></td><td>1</td><td>RepositoryModel</td><td>-</td></tr> | |||
<tr><td>EDIT_REPOSITORY</td><td>repository name</td><td><em>admin</em></td><td>1</td><td>RepositoryModel</td><td>-</td></tr> |
@@ -6,6 +6,7 @@ | |||
role = "#notfederated" | |||
[user "sampleuser"] | |||
password = sampleuser | |||
cookie = 6e07ed42149fc166206319faffdfba2e2ec82e43 | |||
accountType = LOCAL | |||
role = "#none" | |||
[team "admins"] |
@@ -191,12 +191,6 @@ public class RpcTests extends GitblitUnitTest { | |||
assertEquals(AccessRestrictionType.VIEW, retrievedRepository.accessRestriction); | |||
assertEquals(AuthorizationControl.AUTHENTICATED, retrievedRepository.authorizationControl); | |||
//fork repo | |||
UserModel userModel = new UserModel("garbageUser"); | |||
assertTrue("Failed to create Fork Repository!", | |||
RpcUtils.forkRpository(model, userModel, url, account, password.toCharArray())); | |||
// rename and change access restriciton | |||
String originalName = model.name; | |||
model.name = "garbagerepo2.git"; | |||
@@ -403,4 +397,67 @@ public class RpcTests extends GitblitUnitTest { | |||
assertNotNull(branches); | |||
assertTrue(branches.size() > 0); | |||
} | |||
@Test | |||
public void testFork() throws Exception { | |||
// test forking by an administrator | |||
// admins are all-powerful and can fork the unforakable :) | |||
testFork(account, password, true, true); | |||
testFork(account, password, false, true); | |||
// test forking by a permitted normal user | |||
UserModel forkUser = new UserModel("forkuser"); | |||
forkUser.password = forkUser.username; | |||
forkUser.canFork = true; | |||
RpcUtils.deleteUser(forkUser, url, account, password.toCharArray()); | |||
RpcUtils.createUser(forkUser, url, account, password.toCharArray()); | |||
testFork(forkUser.username, forkUser.password, true, true); | |||
testFork(forkUser.username, forkUser.password, false, false); | |||
RpcUtils.deleteUser(forkUser, url, account, password.toCharArray()); | |||
// test forking by a non-permitted normal user | |||
UserModel noForkUser = new UserModel("noforkuser"); | |||
noForkUser.password = noForkUser.username; | |||
noForkUser.canFork = false; | |||
RpcUtils.deleteUser(noForkUser, url, account, password.toCharArray()); | |||
RpcUtils.createUser(noForkUser, url, account, password.toCharArray()); | |||
testFork(forkUser.username, forkUser.password, true, false); | |||
testFork(forkUser.username, forkUser.password, false, false); | |||
RpcUtils.deleteUser(noForkUser, url, account, password.toCharArray()); | |||
} | |||
private void testFork(String forkAcct, String forkAcctPassword, boolean allowForks, boolean expectSuccess) throws Exception { | |||
// test does not exist | |||
RepositoryModel dne = new RepositoryModel(); | |||
dne.name = "doesNotExist.git"; | |||
assertFalse(String.format("Successfully forked %s!", dne.name), | |||
RpcUtils.forkRepository(dne, url, forkAcct, forkAcctPassword.toCharArray())); | |||
// delete any previous fork | |||
RepositoryModel fork = findRepository(String.format("~%s/helloworld.git", forkAcct)); | |||
if (fork != null) { | |||
RpcUtils.deleteRepository(fork, url, account, password.toCharArray()); | |||
} | |||
// update the origin to allow forks or not | |||
RepositoryModel origin = findRepository("helloworld.git"); | |||
origin.allowForks = allowForks; | |||
RpcUtils.updateRepository(origin.name, origin, url, account, password.toCharArray()); | |||
// fork the repository | |||
if (expectSuccess) { | |||
assertTrue(String.format("Failed to fork %s!", origin.name), | |||
RpcUtils.forkRepository(origin, url, forkAcct, forkAcctPassword.toCharArray())); | |||
} else { | |||
assertFalse(String.format("Successfully forked %s!", origin.name), | |||
RpcUtils.forkRepository(origin, url, forkAcct, forkAcctPassword.toCharArray())); | |||
} | |||
// attempt another fork | |||
assertFalse(String.format("Successfully forked %s!", origin.name), | |||
RpcUtils.forkRepository(origin, url, forkAcct, forkAcctPassword.toCharArray())); | |||
// delete the fork repository | |||
RpcUtils.deleteRepository(fork, url, account, password.toCharArray()); | |||
} | |||
} |
@@ -1,11 +0,0 @@ | |||
package com.gitblit.tests; | |||
/** | |||
* Created with IntelliJ IDEA. | |||
* User: manisha | |||
* Date: 3/21/14 | |||
* Time: 12:03 PM | |||
* To change this template use File | Settings | File Templates. | |||
*/ | |||
public @interface Test { | |||
} |