/**
  * Schedules the next check of the federated Gitblit instance.
  *
  * @param registration
  */
 private void schedule(FederationModel registration) {
   // schedule the next pull
   int mins = TimeUtils.convertFrequencyToMinutes(registration.frequency);
   registration.nextPull = new Date(System.currentTimeMillis() + (mins * 60 * 1000L));
   GitBlit.self()
       .executor()
       .schedule(new FederationPullExecutor(registration), mins, TimeUnit.MINUTES);
   logger.info(
       MessageFormat.format(
           "Next pull of {0} @ {1} scheduled for {2,date,yyyy-MM-dd HH:mm}",
           registration.name, registration.url, registration.nextPull));
 }
 /**
  * Sends a status acknowledgment to the origin Gitblit instance. This includes the results of the
  * federated pull.
  *
  * @param registration
  * @throws Exception
  */
 private void sendStatusAcknowledgment(FederationModel registration) throws Exception {
   if (!registration.sendStatus) {
     // skip status acknowledgment
     return;
   }
   InetAddress addr = InetAddress.getLocalHost();
   String federationName = GitBlit.getString(Keys.federation.name, null);
   if (StringUtils.isEmpty(federationName)) {
     federationName = addr.getHostName();
   }
   FederationUtils.acknowledgeStatus(addr.getHostAddress(), registration);
   logger.info(MessageFormat.format("Pull status sent to {0}", registration.url));
 }
 /** Run method for this pull executor. */
 @Override
 public void run() {
   for (FederationModel registration : registrations) {
     FederationPullStatus was = registration.getLowestStatus();
     try {
       Date now = new Date(System.currentTimeMillis());
       pull(registration);
       sendStatusAcknowledgment(registration);
       registration.lastPull = now;
       FederationPullStatus is = registration.getLowestStatus();
       if (is.ordinal() < was.ordinal()) {
         // the status for this registration has downgraded
         logger.warn("Federation pull status of {0} is now {1}", registration.name, is.name());
         if (registration.notifyOnError) {
           String message =
               "Federation pull of "
                   + registration.name
                   + " @ "
                   + registration.url
                   + " is now at "
                   + is.name();
           GitBlit.self()
               .sendMailToAdministrators(
                   "Pull Status of " + registration.name + " is " + is.name(), message);
         }
       }
     } catch (Throwable t) {
       logger.error(
           MessageFormat.format(
               "Failed to pull from federated gitblit ({0} @ {1})",
               registration.name, registration.url),
           t);
     } finally {
       if (isDaemon) {
         schedule(registration);
       }
     }
   }
 }
Пример #4
0
 /**
  * Determine if the user can access the repository and perform the specified action.
  *
  * @param repository
  * @param user
  * @param action
  * @return true if user may execute the action on the repository
  */
 @Override
 protected boolean canAccess(RepositoryModel repository, UserModel user, String action) {
   if (!GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
     // Git Servlet disabled
     return false;
   }
   boolean readOnly = repository.isFrozen;
   if (readOnly || repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) {
     boolean authorizedUser = user.canAccessRepository(repository);
     if (action.equals(gitReceivePack)) {
       // Push request
       if (!readOnly && authorizedUser) {
         // clone-restricted or push-authorized
         return true;
       } else {
         // user is unauthorized to push to this repository
         logger.warn(
             MessageFormat.format(
                 "user {0} is not authorized to push to {1}", user.username, repository));
         return false;
       }
     } else if (action.equals(gitUploadPack)) {
       // Clone request
       boolean cloneRestricted = repository.accessRestriction.atLeast(AccessRestrictionType.CLONE);
       if (!cloneRestricted || (cloneRestricted && authorizedUser)) {
         // push-restricted or clone-authorized
         return true;
       } else {
         // user is unauthorized to clone this repository
         logger.warn(
             MessageFormat.format(
                 "user {0} is not authorized to clone {1}", user.username, repository));
         return false;
       }
     }
   }
   return true;
 }
  /**
   * doFilter does the actual work of preprocessing the request to ensure that the user may proceed.
   *
   * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
   *     javax.servlet.FilterChain)
   */
  @Override
  public void doFilter(
      final ServletRequest request, final ServletResponse response, final FilterChain chain)
      throws IOException, ServletException {

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String fullUrl = getFullUrl(httpRequest);
    String repository = extractRepositoryName(fullUrl);

    // Determine if the request URL is restricted
    String fullSuffix = fullUrl.substring(repository.length());
    String urlRequestType = getUrlRequestAction(fullSuffix);

    // Load the repository model
    RepositoryModel model = GitBlit.self().getRepositoryModel(repository);
    if (model == null) {
      // repository not found. send 404.
      logger.info(
          MessageFormat.format("ARF: {0} ({1})", fullUrl, HttpServletResponse.SC_NOT_FOUND));
      httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    // Confirm that the action may be executed on the repository
    if (!isActionAllowed(model, urlRequestType)) {
      logger.info(
          MessageFormat.format(
              "ARF: action {0} on {1} forbidden ({2})",
              urlRequestType, model, HttpServletResponse.SC_FORBIDDEN));
      httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }

    // Wrap the HttpServletRequest with the AccessRestrictionRequest which
    // overrides the servlet container user principal methods.
    // JGit requires either:
    //
    // 1. servlet container authenticated user
    // 2. http.receivepack = true in each repository's config
    //
    // Gitblit must conditionally authenticate users per-repository so just
    // enabling http.receivepack is insufficient.
    AuthenticatedRequest authenticatedRequest = new AuthenticatedRequest(httpRequest);
    UserModel user = getUser(httpRequest);
    if (user != null) {
      authenticatedRequest.setUser(user);
    }

    // BASIC authentication challenge and response processing
    if (!StringUtils.isEmpty(urlRequestType) && requiresAuthentication(model, urlRequestType)) {
      if (user == null) {
        // challenge client to provide credentials. send 401.
        if (GitBlit.isDebugMode()) {
          logger.info(MessageFormat.format("ARF: CHALLENGE {0}", fullUrl));
        }
        httpResponse.setHeader("WWW-Authenticate", CHALLENGE);
        httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return;
      } else {
        // check user access for request
        AppFacAuthClient authCilent = new AppFacAuthClient();

        // if (user.canAdmin || canAccess(model, user, urlRequestType)) {
        logger.info(model.name);
        logger.info(user.username);
        boolean st = canAccess(model, user, urlRequestType);
        String appId = model.name.replaceAll(".git", "");
        boolean vt = authCilent.hasAccess(user.username, appId);
        logger.info(st + "" + vt);

        if (authCilent.hasAccess(user.username, appId)) {

          // authenticated request permitted.
          // pass processing to the restricted servlet.
          newSession(authenticatedRequest, httpResponse);
          logger.info("Need to chnage here" + model.name);
          logger.info(
              MessageFormat.format(
                  "ARF: {0} ({1}) authenticated", fullUrl, HttpServletResponse.SC_CONTINUE));
          chain.doFilter(authenticatedRequest, httpResponse);
          return;
        }
        // valid user, but not for requested access. send 403.
        if (GitBlit.isDebugMode()) {
          logger.info(
              MessageFormat.format("ARF: {0} forbidden to access {1}", user.username, fullUrl));
        }
        httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
      }
    }

    if (GitBlit.isDebugMode()) {
      logger.info(
          MessageFormat.format(
              "ARF: {0} ({1}) unauthenticated", fullUrl, HttpServletResponse.SC_CONTINUE));
    }
    // unauthenticated request permitted.
    // pass processing to the restricted servlet.
    chain.doFilter(authenticatedRequest, httpResponse);
  }
Пример #6
0
  /**
   * 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.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.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.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_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));
        }
        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);
  }
Пример #7
0
 @Override
 public void setup(IStoredSettings settings) {
   File realmFile = GitBlit.getFileOrFolder(Keys.realm.userService, "${baseFolder}/users.conf");
   serviceImpl = createUserService(realmFile);
   logger.info("GUS delegating to " + serviceImpl.toString());
 }
  /**
   * 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 = new File(GitBlit.getString(Keys.git.repositoriesFolder, "git"));
    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.self().getRepository(repositoryName);

      if (existingRepository == null && GitBlit.self().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.self().getRepository(repositoryName);
      RepositoryModel rm = GitBlit.self().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.self().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);

          // merge the origin permissions and origin accounts into
          // the user accounts of this Gitblit instance
          if (registration.mergeAccounts) {
            // reparent all repository permissions if the local
            // 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.self().getUserModel(user.username);
            if (localUser == null) {
              // create new local user
              GitBlit.self().updateUserModel(user.username, user, true);
            } 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.self().updateUserModel(localUser.username, localUser, false);
            }

            for (String teamname : GitBlit.self().getAllTeamnames()) {
              TeamModel team = GitBlit.self().getTeamModel(teamname);
              if (user.isTeamMember(teamname) && !team.hasUser(user.username)) {
                // new team member
                team.addUser(user.username);
                GitBlit.self().updateTeamModel(teamname, team, false);
              } else if (!user.isTeamMember(teamname) && team.hasUser(user.username)) {
                // remove team member
                team.removeUser(user.username);
                GitBlit.self().updateTeamModel(teamname, team, false);
              }

              // 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.self().updateTeamModel(teamname, team, false);
                } else if (!ArrayUtils.isEmpty(remoteTeam.repositories)) {
                  // pulling from <= 1.1
                  team.addRepositoryPermissions(remoteTeam.repositories);
                  GitBlit.self().updateTeamModel(teamname, team, false);
                }
              }
            }
          }
        }
      }
    } 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 {
      // Pull TEAMS
      // We explicitly pull these even though they are embedded in
      // UserModels because it is possible to use teams to specify
      // 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);
    }
  }