Search in sources :

Example 66 with TeamModel

use of com.gitblit.models.TeamModel in project gitblit by gitblit.

the class FederationPullService method pull.

/**
	 * Mirrors a repository and, optionally, the server's users, and/or
	 * configuration settings from a origin Gitblit instance.
	 *
	 * @param registration
	 * @throws Exception
	 */
private void pull(FederationModel registration) throws Exception {
    Map<String, RepositoryModel> repositories = FederationUtils.getRepositories(registration, true);
    String registrationFolder = registration.folder.toLowerCase().trim();
    // confirm valid characters in server alias
    Character c = StringUtils.findInvalidCharacter(registrationFolder);
    if (c != null) {
        logger.error(MessageFormat.format("Illegal character ''{0}'' in folder name ''{1}'' of federation registration {2}!", c, registrationFolder, registration.name));
        return;
    }
    File repositoriesFolder = gitblit.getRepositoriesFolder();
    File registrationFolderFile = new File(repositoriesFolder, registrationFolder);
    registrationFolderFile.mkdirs();
    // Clone/Pull the repository
    for (Map.Entry<String, RepositoryModel> entry : repositories.entrySet()) {
        String cloneUrl = entry.getKey();
        RepositoryModel repository = entry.getValue();
        if (!repository.hasCommits) {
            logger.warn(MessageFormat.format("Skipping federated repository {0} from {1} @ {2}. Repository is EMPTY.", repository.name, registration.name, registration.url));
            registration.updateStatus(repository, FederationPullStatus.SKIPPED);
            continue;
        }
        // Determine local repository name
        String repositoryName;
        if (StringUtils.isEmpty(registrationFolder)) {
            repositoryName = repository.name;
        } else {
            repositoryName = registrationFolder + "/" + repository.name;
        }
        if (registration.bare) {
            // bare repository, ensure .git suffix
            if (!repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
                repositoryName += DOT_GIT_EXT;
            }
        } else {
            // normal repository, strip .git suffix
            if (repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
                repositoryName = repositoryName.substring(0, repositoryName.indexOf(DOT_GIT_EXT));
            }
        }
        // confirm that the origin of any pre-existing repository matches
        // the clone url
        String fetchHead = null;
        Repository existingRepository = gitblit.getRepository(repositoryName);
        if (existingRepository == null && gitblit.isCollectingGarbage(repositoryName)) {
            logger.warn(MessageFormat.format("Skipping local repository {0}, busy collecting garbage", repositoryName));
            continue;
        }
        if (existingRepository != null) {
            StoredConfig config = existingRepository.getConfig();
            config.load();
            String origin = config.getString("remote", "origin", "url");
            RevCommit commit = JGitUtils.getCommit(existingRepository, org.eclipse.jgit.lib.Constants.FETCH_HEAD);
            if (commit != null) {
                fetchHead = commit.getName();
            }
            existingRepository.close();
            if (!origin.startsWith(registration.url)) {
                logger.warn(MessageFormat.format("Skipping federated repository {0} from {1} @ {2}. Origin does not match, consider EXCLUDING.", repository.name, registration.name, registration.url));
                registration.updateStatus(repository, FederationPullStatus.SKIPPED);
                continue;
            }
        }
        // clone/pull this repository
        CredentialsProvider credentials = new UsernamePasswordCredentialsProvider(Constants.FEDERATION_USER, registration.token);
        logger.info(MessageFormat.format("Pulling federated repository {0} from {1} @ {2}", repository.name, registration.name, registration.url));
        CloneResult result = JGitUtils.cloneRepository(registrationFolderFile, repository.name, cloneUrl, registration.bare, credentials);
        Repository r = gitblit.getRepository(repositoryName);
        RepositoryModel rm = gitblit.getRepositoryModel(repositoryName);
        repository.isFrozen = registration.mirror;
        if (result.createdRepository) {
            // default local settings
            repository.federationStrategy = FederationStrategy.EXCLUDE;
            repository.isFrozen = registration.mirror;
            repository.showRemoteBranches = !registration.mirror;
            logger.info(MessageFormat.format("     cloning {0}", repository.name));
            registration.updateStatus(repository, FederationPullStatus.MIRRORED);
        } else {
            // fetch and update
            boolean fetched = false;
            RevCommit commit = JGitUtils.getCommit(r, org.eclipse.jgit.lib.Constants.FETCH_HEAD);
            String newFetchHead = commit.getName();
            fetched = fetchHead == null || !fetchHead.equals(newFetchHead);
            if (registration.mirror) {
                // mirror
                if (fetched) {
                    // update local branches to match the remote tracking branches
                    for (RefModel ref : JGitUtils.getRemoteBranches(r, false, -1)) {
                        if (ref.displayName.startsWith("origin/")) {
                            String branch = org.eclipse.jgit.lib.Constants.R_HEADS + ref.displayName.substring(ref.displayName.indexOf('/') + 1);
                            String hash = ref.getReferencedObjectId().getName();
                            JGitUtils.setBranchRef(r, branch, hash);
                            logger.info(MessageFormat.format("     resetting {0} of {1} to {2}", branch, repository.name, hash));
                        }
                    }
                    String newHead;
                    if (StringUtils.isEmpty(repository.HEAD)) {
                        newHead = newFetchHead;
                    } else {
                        newHead = repository.HEAD;
                    }
                    JGitUtils.setHEADtoRef(r, newHead);
                    logger.info(MessageFormat.format("     resetting HEAD of {0} to {1}", repository.name, newHead));
                    registration.updateStatus(repository, FederationPullStatus.MIRRORED);
                } else {
                    // indicate no commits pulled
                    registration.updateStatus(repository, FederationPullStatus.NOCHANGE);
                }
            } else {
                // non-mirror
                if (fetched) {
                    // indicate commits pulled to origin/master
                    registration.updateStatus(repository, FederationPullStatus.PULLED);
                } else {
                    // indicate no commits pulled
                    registration.updateStatus(repository, FederationPullStatus.NOCHANGE);
                }
            }
            // preserve local settings
            repository.isFrozen = rm.isFrozen;
            repository.federationStrategy = rm.federationStrategy;
            // merge federation sets
            Set<String> federationSets = new HashSet<String>();
            if (rm.federationSets != null) {
                federationSets.addAll(rm.federationSets);
            }
            if (repository.federationSets != null) {
                federationSets.addAll(repository.federationSets);
            }
            repository.federationSets = new ArrayList<String>(federationSets);
            // merge indexed branches
            Set<String> indexedBranches = new HashSet<String>();
            if (rm.indexedBranches != null) {
                indexedBranches.addAll(rm.indexedBranches);
            }
            if (repository.indexedBranches != null) {
                indexedBranches.addAll(repository.indexedBranches);
            }
            repository.indexedBranches = new ArrayList<String>(indexedBranches);
        }
        // only repositories that are actually _cloned_ from the origin
        // Gitblit repository are marked as federated. If the origin
        // is from somewhere else, these repositories are not considered
        // "federated" repositories.
        repository.isFederated = cloneUrl.startsWith(registration.url);
        gitblit.updateConfiguration(r, repository);
        r.close();
    }
    IUserService userService = null;
    try {
        // Pull USERS
        // TeamModels are automatically pulled because they are contained
        // within the UserModel. The UserService creates unknown teams
        // and updates existing teams.
        Collection<UserModel> users = FederationUtils.getUsers(registration);
        if (users != null && users.size() > 0) {
            File realmFile = new File(registrationFolderFile, registration.name + "_users.conf");
            realmFile.delete();
            userService = new ConfigUserService(realmFile);
            for (UserModel user : users) {
                userService.updateUserModel(user.username, user);
                // the user accounts of this Gitblit instance
                if (registration.mergeAccounts) {
                    // repositories are stored within subfolders
                    if (!StringUtils.isEmpty(registrationFolder)) {
                        if (user.permissions != null) {
                            // pulling from >= 1.2 version
                            Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions);
                            user.permissions.clear();
                            for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) {
                                user.setRepositoryPermission(registrationFolder + "/" + entry.getKey(), entry.getValue());
                            }
                        } else {
                            // pulling from <= 1.1 version
                            List<String> permissions = new ArrayList<String>(user.repositories);
                            user.repositories.clear();
                            for (String permission : permissions) {
                                user.addRepositoryPermission(registrationFolder + "/" + permission);
                            }
                        }
                    }
                    // insert new user or update local user
                    UserModel localUser = gitblit.getUserModel(user.username);
                    if (localUser == null) {
                        // create new local user
                        gitblit.addUser(user);
                    } else {
                        // update repository permissions of local user
                        if (user.permissions != null) {
                            // pulling from >= 1.2 version
                            Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions);
                            for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) {
                                localUser.setRepositoryPermission(entry.getKey(), entry.getValue());
                            }
                        } else {
                            // pulling from <= 1.1 version
                            for (String repository : user.repositories) {
                                localUser.addRepositoryPermission(repository);
                            }
                        }
                        localUser.password = user.password;
                        localUser.canAdmin = user.canAdmin;
                        gitblit.reviseUser(localUser.username, localUser);
                    }
                    for (String teamname : gitblit.getAllTeamNames()) {
                        TeamModel team = gitblit.getTeamModel(teamname);
                        if (user.isTeamMember(teamname) && !team.hasUser(user.username)) {
                            // new team member
                            team.addUser(user.username);
                            gitblit.updateTeamModel(teamname, team);
                        } else if (!user.isTeamMember(teamname) && team.hasUser(user.username)) {
                            // remove team member
                            team.removeUser(user.username);
                            gitblit.updateTeamModel(teamname, team);
                        }
                        // update team repositories
                        TeamModel remoteTeam = user.getTeam(teamname);
                        if (remoteTeam != null) {
                            if (remoteTeam.permissions != null) {
                                // pulling from >= 1.2
                                for (Map.Entry<String, AccessPermission> entry : remoteTeam.permissions.entrySet()) {
                                    team.setRepositoryPermission(entry.getKey(), entry.getValue());
                                }
                                gitblit.updateTeamModel(teamname, team);
                            } else if (!ArrayUtils.isEmpty(remoteTeam.repositories)) {
                                // pulling from <= 1.1
                                team.addRepositoryPermissions(remoteTeam.repositories);
                                gitblit.updateTeamModel(teamname, team);
                            }
                        }
                    }
                }
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve USERS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // mailing lists or push scripts without specifying users.
        if (userService != null) {
            Collection<TeamModel> teams = FederationUtils.getTeams(registration);
            if (teams != null && teams.size() > 0) {
                for (TeamModel team : teams) {
                    userService.updateTeamModel(team);
                }
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve TEAMS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // Pull SETTINGS
        Map<String, String> settings = FederationUtils.getSettings(registration);
        if (settings != null && settings.size() > 0) {
            Properties properties = new Properties();
            properties.putAll(settings);
            FileOutputStream os = new FileOutputStream(new File(registrationFolderFile, registration.name + "_" + Constants.PROPERTIES_FILE));
            properties.store(os, null);
            os.close();
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
    try {
        // Pull SCRIPTS
        Map<String, String> scripts = FederationUtils.getScripts(registration);
        if (scripts != null && scripts.size() > 0) {
            for (Map.Entry<String, String> script : scripts.entrySet()) {
                String scriptName = script.getKey();
                if (scriptName.endsWith(".groovy")) {
                    scriptName = scriptName.substring(0, scriptName.indexOf(".groovy"));
                }
                File file = new File(registrationFolderFile, registration.name + "_" + scriptName + ".groovy");
                FileUtils.writeContent(file, script.getValue());
            }
        }
    } catch (ForbiddenException e) {
    // ignore forbidden exceptions
    } catch (IOException e) {
        logger.warn(MessageFormat.format("Failed to retrieve SCRIPTS from federated gitblit ({0} @ {1})", registration.name, registration.url), e);
    }
}
Also used : RefModel(com.gitblit.models.RefModel) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RepositoryModel(com.gitblit.models.RepositoryModel) Properties(java.util.Properties) StoredConfig(org.eclipse.jgit.lib.StoredConfig) UserModel(com.gitblit.models.UserModel) TeamModel(com.gitblit.models.TeamModel) RevCommit(org.eclipse.jgit.revwalk.RevCommit) HashSet(java.util.HashSet) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) ForbiddenException(com.gitblit.GitBlitException.ForbiddenException) ConfigUserService(com.gitblit.ConfigUserService) AccessPermission(com.gitblit.Constants.AccessPermission) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) CredentialsProvider(org.eclipse.jgit.transport.CredentialsProvider) IOException(java.io.IOException) CloneResult(com.gitblit.utils.JGitUtils.CloneResult) Repository(org.eclipse.jgit.lib.Repository) IUserService(com.gitblit.IUserService) FileOutputStream(java.io.FileOutputStream) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map)

Example 67 with TeamModel

use of com.gitblit.models.TeamModel in project gitblit by gitblit.

the class RepositoryManager method setTeamAccessPermissions.

/**
	 * Sets the access permissions to the specified repository for the specified teams.
	 *
	 * @param repository
	 * @param permissions
	 * @return true if the team models have been updated
	 */
@Override
public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
    List<TeamModel> teams = new ArrayList<TeamModel>();
    for (RegistrantAccessPermission tp : permissions) {
        if (tp.mutable) {
            // only set explicitly defined access permissions
            TeamModel team = userManager.getTeamModel(tp.registrant);
            team.setRepositoryPermission(repository.name, tp.permission);
            teams.add(team);
        }
    }
    return userManager.updateTeamModels(teams);
}
Also used : TeamModel(com.gitblit.models.TeamModel) RegistrantAccessPermission(com.gitblit.models.RegistrantAccessPermission) ArrayList(java.util.ArrayList)

Example 68 with TeamModel

use of com.gitblit.models.TeamModel in project gitblit by gitblit.

the class RepositoryManager method getTeamAccessPermissions.

/**
	 * Returns the list of teams and their access permissions for the specified
	 * repository including the source of the permission such as the admin flag
	 * or a regular expression.
	 *
	 * @param repository
	 * @return a list of RegistrantAccessPermissions
	 */
@Override
public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {
    List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
    for (TeamModel team : userManager.getAllTeams()) {
        RegistrantAccessPermission ap = team.getRepositoryPermission(repository);
        if (ap.permission.exceeds(AccessPermission.NONE)) {
            list.add(ap);
        }
    }
    Collections.sort(list);
    return list;
}
Also used : TeamModel(com.gitblit.models.TeamModel) RegistrantAccessPermission(com.gitblit.models.RegistrantAccessPermission) ArrayList(java.util.ArrayList)

Example 69 with TeamModel

use of com.gitblit.models.TeamModel in project gitblit by gitblit.

the class GitblitManager method fork.

/*
	 * IGITBLIT
	 */
/**
	 * Creates a personal fork of the specified repository. The clone is view
	 * restricted by default and the owner of the source repository is given
	 * access to the clone.
	 *
	 * @param repository
	 * @param user
	 * @return the repository model of the fork, if successful
	 * @throws GitBlitException
	 */
@Override
public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
    String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
    String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name);
    // clone the repository
    try {
        Repository canonical = getRepository(repository.name);
        File folder = new File(repositoryManager.getRepositoriesFolder(), cloneName);
        CloneCommand clone = new CloneCommand();
        clone.setBare(true);
        // fetch branches with exclusions
        Collection<Ref> branches = canonical.getRefDatabase().getRefs(Constants.R_HEADS).values();
        List<String> branchesToClone = new ArrayList<String>();
        for (Ref branch : branches) {
            String name = branch.getName();
            if (name.startsWith(Constants.R_TICKET)) {
                // exclude ticket branches
                continue;
            }
            branchesToClone.add(name);
        }
        clone.setBranchesToClone(branchesToClone);
        clone.setURI(fromUrl);
        clone.setDirectory(folder);
        Git git = clone.call();
        // fetch tags
        FetchCommand fetch = git.fetch();
        fetch.setRefSpecs(new RefSpec("+refs/tags/*:refs/tags/*"));
        fetch.call();
        git.getRepository().close();
    } catch (Exception e) {
        throw new GitBlitException(e);
    }
    // create a Gitblit repository model for the clone
    RepositoryModel cloneModel = repository.cloneAs(cloneName);
    // owner has REWIND/RW+ permissions
    cloneModel.addOwner(user.username);
    // is not lower than the source repository  (issue-495/ticket-167)
    if (repository.accessRestriction.exceeds(cloneModel.accessRestriction)) {
        cloneModel.accessRestriction = repository.accessRestriction;
    }
    repositoryManager.updateRepositoryModel(cloneName, cloneModel, false);
    // add the owner of the source repository to the clone's access list
    if (!ArrayUtils.isEmpty(repository.owners)) {
        for (String owner : repository.owners) {
            UserModel originOwner = userManager.getUserModel(owner);
            if (originOwner != null && !originOwner.canClone(cloneModel)) {
                // origin owner can't yet clone fork, grant explicit clone access
                originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
                reviseUser(originOwner.username, originOwner);
            }
        }
    }
    // grant origin's user list clone permission to fork
    List<String> users = repositoryManager.getRepositoryUsers(repository);
    List<UserModel> cloneUsers = new ArrayList<UserModel>();
    for (String name : users) {
        if (!name.equalsIgnoreCase(user.username)) {
            UserModel cloneUser = userManager.getUserModel(name);
            if (cloneUser.canClone(repository) && !cloneUser.canClone(cloneModel)) {
                // origin user can't yet clone fork, grant explicit clone access
                cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE);
            }
            cloneUsers.add(cloneUser);
        }
    }
    userManager.updateUserModels(cloneUsers);
    // grant origin's team list clone permission to fork
    List<String> teams = repositoryManager.getRepositoryTeams(repository);
    List<TeamModel> cloneTeams = new ArrayList<TeamModel>();
    for (String name : teams) {
        TeamModel cloneTeam = userManager.getTeamModel(name);
        if (cloneTeam.canClone(repository) && !cloneTeam.canClone(cloneModel)) {
            // origin team can't yet clone fork, grant explicit clone access
            cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE);
        }
        cloneTeams.add(cloneTeam);
    }
    userManager.updateTeamModels(cloneTeams);
    // add this clone to the cached model
    repositoryManager.addToCachedRepositoryList(cloneModel);
    if (pluginManager != null) {
        for (RepositoryLifeCycleListener listener : pluginManager.getExtensions(RepositoryLifeCycleListener.class)) {
            try {
                listener.onFork(repository, cloneModel);
            } catch (Throwable t) {
                logger.error(String.format("failed to call plugin onFork %s", repository.name), t);
            }
        }
    }
    return cloneModel;
}
Also used : CloneCommand(org.eclipse.jgit.api.CloneCommand) ArrayList(java.util.ArrayList) GitBlitException(com.gitblit.GitBlitException) RepositoryModel(com.gitblit.models.RepositoryModel) JsonIOException(com.google.gson.JsonIOException) GitBlitException(com.gitblit.GitBlitException) JsonSyntaxException(com.google.gson.JsonSyntaxException) IOException(java.io.IOException) UserModel(com.gitblit.models.UserModel) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) Git(org.eclipse.jgit.api.Git) RefSpec(org.eclipse.jgit.transport.RefSpec) TeamModel(com.gitblit.models.TeamModel) FetchCommand(org.eclipse.jgit.api.FetchCommand) RepositoryLifeCycleListener(com.gitblit.extensions.RepositoryLifeCycleListener) File(java.io.File)

Example 70 with TeamModel

use of com.gitblit.models.TeamModel in project gitblit by gitblit.

the class FederationTests method testPullTeams.

@Test
public void testPullTeams() throws Exception {
    TeamModel team = new TeamModel("testteam");
    team.addUser("test");
    team.addRepositoryPermission("helloworld.git");
    assertTrue(RpcUtils.createTeam(team, url, account, password.toCharArray()));
    List<TeamModel> teams = FederationUtils.getTeams(getRegistration());
    assertNotNull(teams);
    assertTrue(teams.size() > 0);
    assertTrue(RpcUtils.deleteTeam(team, url, account, password.toCharArray()));
}
Also used : TeamModel(com.gitblit.models.TeamModel) Test(org.junit.Test)

Aggregations

TeamModel (com.gitblit.models.TeamModel)109 RepositoryModel (com.gitblit.models.RepositoryModel)68 Test (org.junit.Test)67 Date (java.util.Date)62 UserModel (com.gitblit.models.UserModel)58 ArrayList (java.util.ArrayList)18 HashSet (java.util.HashSet)8 RegistrantAccessPermission (com.gitblit.models.RegistrantAccessPermission)6 HashMap (java.util.HashMap)6 Map (java.util.Map)5 GitBlitException (com.gitblit.GitBlitException)4 SearchResult (com.unboundid.ldap.sdk.SearchResult)4 SearchResultEntry (com.unboundid.ldap.sdk.SearchResultEntry)4 File (java.io.File)4 IOException (java.io.IOException)4 AccessPermission (com.gitblit.Constants.AccessPermission)3 List (java.util.List)3 Repository (org.eclipse.jgit.lib.Repository)3 StoredConfig (org.eclipse.jgit.lib.StoredConfig)3 IUserService (com.gitblit.IUserService)2