/* * 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.tests; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AuthorizationControl; import com.gitblit.Constants.PermissionType; import com.gitblit.Constants.RegistrantType; import com.gitblit.GitBlitException.ForbiddenException; import com.gitblit.GitBlitException.UnauthorizedException; import com.gitblit.Keys; import com.gitblit.models.FederationModel; import com.gitblit.models.FederationProposal; import com.gitblit.models.FederationSet; 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.gitblit.servlet.RpcServlet; import com.gitblit.utils.RpcUtils; /** * Tests all the rpc client utility methods, the rpc filter and rpc servlet. * * @author James Moger * */ public class RpcTests extends GitblitUnitTest { String url = GitBlitSuite.url; String account = GitBlitSuite.account; String password = GitBlitSuite.password; private static final AtomicBoolean started = new AtomicBoolean(false); @BeforeClass public static void startGitblit() throws Exception { started.set(GitBlitSuite.startGitblit()); } @AfterClass public static void stopGitblit() throws Exception { if (started.get()) { GitBlitSuite.stopGitblit(); } } @Test public void testGetProtocolVersion() throws IOException { int protocol = RpcUtils.getProtocolVersion(url, null, null); assertEquals(RpcServlet.PROTOCOL_VERSION, protocol); } @Test public void testListRepositories() throws IOException { Map<String, RepositoryModel> map = RpcUtils.getRepositories(url, null, null); assertNotNull("Repository list is null!", map); assertTrue("Repository list is empty!", map.size() > 0); } @Test public void testListUsers() throws IOException { List<UserModel> list = null; try { list = RpcUtils.getUsers(url, null, null); } catch (UnauthorizedException e) { } assertNull("Server allows anyone to admin!", list); list = RpcUtils.getUsers(url, "admin", "admin".toCharArray()); assertTrue("User list is empty!", list.size() > 0); } @Test public void testGetUser() throws IOException { UserModel user = null; try { user = RpcUtils.getUser("admin", url, null, null); } catch (ForbiddenException e) { } assertNull("Server allows anyone to get user!", user); user = RpcUtils.getUser("admin", url, "admin", "admin".toCharArray()); assertEquals("User is not the admin!", "admin", user.username); assertTrue("User is not an administrator!", user.canAdmin()); } @Test public void testListTeams() throws IOException { List<TeamModel> list = null; try { list = RpcUtils.getTeams(url, null, null); } catch (UnauthorizedException e) { } assertNull("Server allows anyone to admin!", list); list = RpcUtils.getTeams(url, "admin", "admin".toCharArray()); assertTrue("Team list is empty!", list.size() > 0); assertEquals("admins", list.get(0).name); } @Test public void testUserAdministration() throws IOException { UserModel user = new UserModel("garbage"); user.canAdmin = true; user.password = "whocares"; // create assertTrue("Failed to create user!", RpcUtils.createUser(user, url, account, password.toCharArray())); UserModel retrievedUser = findUser(user.username); assertNotNull("Failed to find " + user.username, retrievedUser); assertTrue("Retrieved user can not administer Gitblit", retrievedUser.canAdmin); // rename and toggle admin permission String originalName = user.username; user.username = "garbage2"; user.canAdmin = false; assertTrue("Failed to update user!", RpcUtils.updateUser(originalName, user, url, account, password.toCharArray())); retrievedUser = findUser(user.username); assertNotNull("Failed to find " + user.username, retrievedUser); assertTrue("Retrieved user did not update", !retrievedUser.canAdmin); // delete assertTrue("Failed to delete " + user.username, RpcUtils.deleteUser(retrievedUser, url, account, password.toCharArray())); retrievedUser = findUser(user.username); assertNull("Failed to delete " + user.username, retrievedUser); } private UserModel findUser(String name) throws IOException { List<UserModel> users = RpcUtils.getUsers(url, account, password.toCharArray()); UserModel retrievedUser = null; for (UserModel model : users) { if (model.username.equalsIgnoreCase(name)) { retrievedUser = model; break; } } return retrievedUser; } @Test public void testRepositoryAdministration() throws IOException { RepositoryModel model = new RepositoryModel(); model.name = "garbagerepo.git"; model.description = "created by RpcUtils"; model.addOwner("garbage"); model.accessRestriction = AccessRestrictionType.VIEW; model.authorizationControl = AuthorizationControl.AUTHENTICATED; // create RpcUtils.deleteRepository(model, url, account, password.toCharArray()); assertTrue("Failed to create repository!", RpcUtils.createRepository(model, url, account, password.toCharArray())); RepositoryModel retrievedRepository = findRepository(model.name); assertNotNull("Failed to find " + model.name, retrievedRepository); assertEquals(AccessRestrictionType.VIEW, retrievedRepository.accessRestriction); assertEquals(AuthorizationControl.AUTHENTICATED, retrievedRepository.authorizationControl); // rename and change access restriciton String originalName = model.name; model.name = "garbagerepo2.git"; model.accessRestriction = AccessRestrictionType.CLONE; model.authorizationControl = AuthorizationControl.NAMED; RpcUtils.deleteRepository(model, url, account, password.toCharArray()); assertTrue("Failed to update repository!", RpcUtils.updateRepository(originalName, model, url, account, password.toCharArray())); retrievedRepository = findRepository(model.name); assertNotNull("Failed to find " + model.name, retrievedRepository); assertTrue("Access retriction type is wrong", AccessRestrictionType.CLONE.equals(retrievedRepository.accessRestriction)); // restore VIEW restriction retrievedRepository.accessRestriction = AccessRestrictionType.VIEW; assertTrue("Failed to update repository!", RpcUtils.updateRepository(retrievedRepository.name, retrievedRepository, url, account, password.toCharArray())); retrievedRepository = findRepository(retrievedRepository.name); // memberships UserModel testMember = new UserModel("justadded"); assertTrue(RpcUtils.createUser(testMember, url, account, password.toCharArray())); List<RegistrantAccessPermission> permissions = RpcUtils.getRepositoryMemberPermissions(retrievedRepository, url, account, password.toCharArray()); assertEquals("Unexpected permissions! " + permissions.toString(), 1, permissions.size()); permissions.add(new RegistrantAccessPermission(testMember.username, AccessPermission.VIEW, PermissionType.EXPLICIT, RegistrantType.USER, null, true)); assertTrue( "Failed to set member permissions!", RpcUtils.setRepositoryMemberPermissions(retrievedRepository, permissions, url, account, password.toCharArray())); permissions = RpcUtils.getRepositoryMemberPermissions(retrievedRepository, url, account, password.toCharArray()); boolean foundMember = false; for (RegistrantAccessPermission permission : permissions) { if (permission.registrant.equalsIgnoreCase(testMember.username)) { foundMember = true; assertEquals(AccessPermission.VIEW, permission.permission); break; } } assertTrue("Failed to find member!", foundMember); // delete assertTrue("Failed to delete " + model.name, RpcUtils.deleteRepository(retrievedRepository, url, account, password.toCharArray())); retrievedRepository = findRepository(model.name); assertNull("Failed to delete " + model.name, retrievedRepository); for (UserModel u : RpcUtils.getUsers(url, account, password.toCharArray())) { if (u.username.equals(testMember.username)) { assertTrue(RpcUtils.deleteUser(u, url, account, password.toCharArray())); break; } } } private RepositoryModel findRepository(String name) throws IOException { Map<String, RepositoryModel> repositories = RpcUtils.getRepositories(url, account, password.toCharArray()); RepositoryModel retrievedRepository = null; for (RepositoryModel model : repositories.values()) { if (model.name.equalsIgnoreCase(name)) { retrievedRepository = model; break; } } return retrievedRepository; } @Test public void testTeamAdministration() throws IOException { List<TeamModel> teams = RpcUtils.getTeams(url, account, password.toCharArray()); assertEquals(1, teams.size()); // Create the A-Team TeamModel aTeam = new TeamModel("A-Team"); aTeam.users.add("admin"); aTeam.addRepositoryPermission("helloworld.git"); assertTrue(RpcUtils.createTeam(aTeam, url, account, password.toCharArray())); aTeam = null; teams = RpcUtils.getTeams(url, account, password.toCharArray()); assertEquals(2, teams.size()); for (TeamModel team : teams) { if (team.name.equals("A-Team")) { aTeam = team; break; } } assertNotNull(aTeam); assertTrue(aTeam.hasUser("admin")); assertTrue(aTeam.hasRepositoryPermission("helloworld.git")); RepositoryModel helloworld = null; Map<String, RepositoryModel> repositories = RpcUtils.getRepositories(url, account, password.toCharArray()); for (RepositoryModel repository : repositories.values()) { if (repository.name.equals("helloworld.git")) { helloworld = repository; break; } } assertNotNull(helloworld); // Confirm that we have added the team List<String> helloworldTeams = RpcUtils.getRepositoryTeams(helloworld, url, account, password.toCharArray()); assertEquals(1, helloworldTeams.size()); assertTrue(helloworldTeams.contains(aTeam.name)); // set no teams List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>(); for (String team : helloworldTeams) { permissions.add(new RegistrantAccessPermission(team, AccessPermission.NONE, PermissionType.EXPLICIT, RegistrantType.TEAM, null, true)); } assertTrue(RpcUtils.setRepositoryTeamPermissions(helloworld, permissions, url, account, password.toCharArray())); helloworldTeams = RpcUtils.getRepositoryTeams(helloworld, url, account, password.toCharArray()); assertEquals(0, helloworldTeams.size()); // delete the A-Team assertTrue(RpcUtils.deleteTeam(aTeam, url, account, password.toCharArray())); teams = RpcUtils.getTeams(url, account, password.toCharArray()); assertEquals(1, teams.size()); } @Test public void testFederationRegistrations() throws Exception { List<FederationModel> registrations = RpcUtils.getFederationRegistrations(url, account, password.toCharArray()); assertTrue("No federation registrations were retrieved!", registrations.size() >= 0); } @Test public void testFederationResultRegistrations() throws Exception { List<FederationModel> registrations = RpcUtils.getFederationResultRegistrations(url, account, password.toCharArray()); assertTrue("No federation result registrations were retrieved!", registrations.size() >= 0); } @Test public void testFederationProposals() throws Exception { List<FederationProposal> proposals = RpcUtils.getFederationProposals(url, account, password.toCharArray()); assertTrue("No federation proposals were retrieved!", proposals.size() >= 0); } @Test public void testFederationSets() throws Exception { List<FederationSet> sets = RpcUtils.getFederationSets(url, account, password.toCharArray()); assertTrue("No federation sets were retrieved!", sets.size() >= 0); } @Test public void testSettings() throws Exception { ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); assertNotNull("No settings were retrieved!", settings); } @Test public void testServerStatus() throws Exception { ServerStatus status = RpcUtils.getStatus(url, account, password.toCharArray()); assertNotNull("No status was retrieved!", status); } @Test public void testUpdateSettings() throws Exception { Map<String, String> updated = new HashMap<String, String>(); // grab current setting ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); boolean showSizes = settings.get(Keys.web.showRepositorySizes).getBoolean(true); showSizes = !showSizes; // update setting updated.put(Keys.web.showRepositorySizes, String.valueOf(showSizes)); boolean success = RpcUtils.updateSettings(updated, url, account, password.toCharArray()); assertTrue("Failed to update server settings", success); // confirm setting change settings = RpcUtils.getSettings(url, account, password.toCharArray()); boolean newValue = settings.get(Keys.web.showRepositorySizes).getBoolean(false); assertEquals(newValue, showSizes); // restore setting newValue = !newValue; updated.put(Keys.web.showRepositorySizes, String.valueOf(newValue)); success = RpcUtils.updateSettings(updated, url, account, password.toCharArray()); assertTrue("Failed to update server settings", success); settings = RpcUtils.getSettings(url, account, password.toCharArray()); showSizes = settings.get(Keys.web.showRepositorySizes).getBoolean(true); assertEquals(newValue, showSizes); } @Test public void testBranches() throws Exception { Map<String, Collection<String>> branches = RpcUtils.getBranches(url, account, password.toCharArray()); 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()); } }