예제 #1
0
  @Test
  public void testBogusLoginClone() throws Exception {
    // restrict repository access
    RepositoryModel model = GitBlit.self().getRepositoryModel("ticgit.git");
    model.accessRestriction = AccessRestrictionType.CLONE;
    GitBlit.self().updateRepositoryModel(model.name, model, false);

    // delete any existing working folder
    boolean cloned = false;
    try {
      CloneCommand clone = Git.cloneRepository();
      clone.setURI(MessageFormat.format("{0}/git/ticgit.git", url));
      clone.setDirectory(ticgit2Folder);
      clone.setBare(false);
      clone.setCloneAllBranches(true);
      clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider("bogus", "bogus"));
      close(clone.call());
      cloned = true;
    } catch (Exception e) {
      // swallow the exception which we expect
    }

    // restore anonymous repository access
    model.accessRestriction = AccessRestrictionType.NONE;
    GitBlit.self().updateRepositoryModel(model.name, model, false);

    assertFalse("Bogus login cloned a repository?!", cloned);
  }
예제 #2
0
  public EditRepositoryPage() {
    // create constructor
    super();
    isCreate = true;
    RepositoryModel model = new RepositoryModel();
    String restriction = GitBlit.getString(Keys.git.defaultAccessRestriction, null);
    model.accessRestriction = AccessRestrictionType.fromName(restriction);
    String authorization = GitBlit.getString(Keys.git.defaultAuthorizationControl, null);
    model.authorizationControl = AuthorizationControl.fromName(authorization);

    GitBlitWebSession session = GitBlitWebSession.get();
    UserModel user = session.getUser();
    if (user != null && user.canCreate() && !user.canAdmin()) {
      // personal create permissions, inject personal repository path
      model.name = user.getPersonalPath() + "/";
      model.projectPath = user.getPersonalPath();
      model.addOwner(user.username);
      // personal repositories are private by default
      model.accessRestriction = AccessRestrictionType.VIEW;
      model.authorizationControl = AuthorizationControl.NAMED;
    }

    setupPage(model);
    setStatelessHint(false);
    setOutputMarkupId(true);
  }
예제 #3
0
 /**
  * Returns true if the repository can be posted to Slack.
  *
  * @param repository
  * @return true if the repository can be posted to Slack
  */
 public boolean shallPost(RepositoryModel repository) {
   boolean postPersonalRepos =
       runtimeManager.getSettings().getBoolean(Plugin.SETTING_POST_PERSONAL_REPOS, false);
   if (repository.isPersonalRepository() && !postPersonalRepos) {
     return false;
   }
   return true;
 }
예제 #4
0
  @Test
  public void testUnauthorizedLoginClone() throws Exception {
    // restrict repository access
    RepositoryModel model = GitBlit.self().getRepositoryModel("ticgit.git");
    model.accessRestriction = AccessRestrictionType.CLONE;
    model.authorizationControl = AuthorizationControl.NAMED;
    UserModel user = new UserModel("james");
    user.password = "******";
    GitBlit.self().updateUserModel(user.username, user, true);
    GitBlit.self().updateRepositoryModel(model.name, model, false);

    FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

    // delete any existing working folder
    boolean cloned = false;
    try {
      CloneCommand clone = Git.cloneRepository();
      clone.setURI(MessageFormat.format("{0}/git/ticgit.git", url));
      clone.setDirectory(ticgit2Folder);
      clone.setBare(false);
      clone.setCloneAllBranches(true);
      clone.setCredentialsProvider(
          new UsernamePasswordCredentialsProvider(user.username, user.password));
      close(clone.call());
      cloned = true;
    } catch (Exception e) {
      // swallow the exception which we expect
    }

    assertFalse("Unauthorized login cloned a repository?!", cloned);

    FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

    // switch to authenticated
    model.authorizationControl = AuthorizationControl.AUTHENTICATED;
    GitBlit.self().updateRepositoryModel(model.name, model, false);

    // try clone again
    cloned = false;
    CloneCommand clone = Git.cloneRepository();
    clone.setURI(MessageFormat.format("{0}/git/ticgit.git", url));
    clone.setDirectory(ticgit2Folder);
    clone.setBare(false);
    clone.setCloneAllBranches(true);
    clone.setCredentialsProvider(
        new UsernamePasswordCredentialsProvider(user.username, user.password));
    close(clone.call());
    cloned = true;

    assertTrue("Authenticated login could not clone!", cloned);

    FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE);

    // restore anonymous repository access
    model.accessRestriction = AccessRestrictionType.NONE;
    model.authorizationControl = AuthorizationControl.NAMED;
    GitBlit.self().updateRepositoryModel(model.name, model, false);
    GitBlit.self().deleteUser(user.username);
  }
예제 #5
0
  /**
   * Unfortunately must repeat part of AuthorizaitonStrategy here because that mechanism does not
   * take PageParameters into consideration, only page instantiation.
   *
   * <p>Repository Owners should be able to edit their repository.
   */
  private void checkPermissions(RepositoryModel model) {
    boolean authenticateAdmin = GitBlit.getBoolean(Keys.web.authenticateAdminPages, true);
    boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, true);

    GitBlitWebSession session = GitBlitWebSession.get();
    UserModel user = session.getUser();

    if (allowAdmin) {
      if (authenticateAdmin) {
        if (user == null) {
          // No Login Available
          error(getString("gb.errorAdminLoginRequired"), true);
        }
        if (isCreate) {
          // Create Repository
          if (!user.canCreate() && !user.canAdmin()) {
            // Only administrators or permitted users may create
            error(getString("gb.errorOnlyAdminMayCreateRepository"), true);
          }
        } else {
          // Edit Repository
          if (user.canAdmin()) {
            // Admins can edit everything
            isAdmin = true;
            return;
          } else {
            if (!model.isOwner(user.username)) {
              // User is not an Admin nor Owner
              error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true);
            }
          }
        }
      }
    } else {
      // No Administration Permitted
      error(getString("gb.errorAdministrationDisabled"), true);
    }
  }
예제 #6
0
  private void setup(PageParameters params) {
    setupPage("", "");
    // check to see if we should display a login message
    boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);
    if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
      String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit");
      String message = readMarkdown(messageSource, "login.mkd");
      Component repositoriesMessage = new Label("repositoriesMessage", message);
      add(repositoriesMessage.setEscapeModelStrings(false));
      add(new Label("activity").setVisible(false));
      add(new Label("repositoryTabs").setVisible(false));
      return;
    }

    // Load the markdown welcome message
    String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");
    String message = readMarkdown(messageSource, "welcome.mkd");
    Component repositoriesMessage =
        new Label("repositoriesMessage", message)
            .setEscapeModelStrings(false)
            .setVisible(message.length() > 0);
    add(repositoriesMessage);

    UserModel user = GitBlitWebSession.get().getUser();
    if (user == null) {
      user = UserModel.ANONYMOUS;
    }

    // parameters
    int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params);
    if (daysBack < 1) {
      daysBack = GitBlit.getInteger(Keys.web.activityDuration, 7);
    }
    Calendar c = Calendar.getInstance();
    c.add(Calendar.DATE, -1 * daysBack);
    Date minimumDate = c.getTime();

    // build repo lists
    List<RepositoryModel> starred = new ArrayList<RepositoryModel>();
    List<RepositoryModel> owned = new ArrayList<RepositoryModel>();
    List<RepositoryModel> active = new ArrayList<RepositoryModel>();

    for (RepositoryModel model : getRepositoryModels()) {
      if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) {
        owned.add(model);
      }

      if (user.getPreferences().isStarredRepository(model.name)) {
        starred.add(model);
      }

      if (model.isShowActivity() && model.lastChange.after(minimumDate)) {
        active.add(model);
      }
    }

    Comparator<RepositoryModel> lastUpdateSort =
        new Comparator<RepositoryModel>() {
          @Override
          public int compare(RepositoryModel o1, RepositoryModel o2) {
            return o2.lastChange.compareTo(o1.lastChange);
          }
        };

    Collections.sort(owned, lastUpdateSort);
    Collections.sort(starred, lastUpdateSort);
    Collections.sort(active, lastUpdateSort);

    String activityTitle;
    Set<RepositoryModel> feed = new HashSet<RepositoryModel>();
    feed.addAll(starred);
    feed.addAll(owned);
    if (feed.isEmpty()) {
      // no starred or owned, go with recent activity
      activityTitle = getString("gb.recentActivity");
      feed.addAll(active);
    } else if (starred.isEmpty()) {
      // no starred, owned repos feed
      activityTitle = getString("gb.owned");
    } else if (owned.isEmpty()) {
      // no owned, starred repos feed
      activityTitle = getString("gb.starred");
    } else {
      // starred and owned repositories
      activityTitle = getString("gb.starredAndOwned");
    }

    addActivity(user, feed, activityTitle, daysBack);

    Fragment repositoryTabs;
    if (UserModel.ANONYMOUS.equals(user)) {
      repositoryTabs = new Fragment("repositoryTabs", "anonymousTabsFragment", this);
    } else {
      repositoryTabs = new Fragment("repositoryTabs", "authenticatedTabsFragment", this);
    }

    add(repositoryTabs);

    // projects list
    List<ProjectModel> projects = GitBlit.self().getProjectModels(getRepositoryModels(), false);
    repositoryTabs.add(new FilterableProjectList("projects", projects));

    // active repository list
    if (active.isEmpty()) {
      repositoryTabs.add(new Label("active").setVisible(false));
    } else {
      FilterableRepositoryList repoList = new FilterableRepositoryList("active", active);
      repoList.setTitle(getString("gb.activeRepositories"), "icon-time");
      repositoryTabs.add(repoList);
    }

    // starred repository list
    if (ArrayUtils.isEmpty(starred)) {
      repositoryTabs.add(new Label("starred").setVisible(false));
    } else {
      FilterableRepositoryList repoList = new FilterableRepositoryList("starred", starred);
      repoList.setTitle(getString("gb.starredRepositories"), "icon-star");
      repositoryTabs.add(repoList);
    }

    // owned repository list
    if (ArrayUtils.isEmpty(owned)) {
      repositoryTabs.add(new Label("owned").setVisible(false));
    } else {
      FilterableRepositoryList repoList = new FilterableRepositoryList("owned", owned);
      repoList.setTitle(getString("gb.myRepositories"), "icon-user");
      repoList.setAllowCreate(user.canCreate() || user.canAdmin());
      repositoryTabs.add(repoList);
    }
  }
  /**
   * 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);
    }
  }
예제 #8
0
  protected void setupPage(RepositoryModel model) {
    this.repositoryModel = model;

    // ensure this user can create or edit this repository
    checkPermissions(repositoryModel);

    List<String> indexedBranches = new ArrayList<String>();
    List<String> federationSets = new ArrayList<String>();
    final List<RegistrantAccessPermission> repositoryUsers =
        new ArrayList<RegistrantAccessPermission>();
    final List<RegistrantAccessPermission> repositoryTeams =
        new ArrayList<RegistrantAccessPermission>();
    List<String> preReceiveScripts = new ArrayList<String>();
    List<String> postReceiveScripts = new ArrayList<String>();

    GitBlitWebSession session = GitBlitWebSession.get();
    final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser();
    final boolean allowEditName =
        isCreate || isAdmin || repositoryModel.isUsersPersonalRepository(user.username);

    if (isCreate) {
      if (user.canAdmin()) {
        super.setupPage(getString("gb.newRepository"), "");
      } else {
        super.setupPage(getString("gb.newRepository"), user.getDisplayName());
      }
    } else {
      super.setupPage(getString("gb.edit"), repositoryModel.name);
      repositoryUsers.addAll(GitBlit.self().getUserAccessPermissions(repositoryModel));
      repositoryTeams.addAll(GitBlit.self().getTeamAccessPermissions(repositoryModel));
      Collections.sort(repositoryUsers);
      Collections.sort(repositoryTeams);

      federationSets.addAll(repositoryModel.federationSets);
      if (!ArrayUtils.isEmpty(repositoryModel.indexedBranches)) {
        indexedBranches.addAll(repositoryModel.indexedBranches);
      }
    }

    final String oldName = repositoryModel.name;

    final RegistrantPermissionsPanel usersPalette =
        new RegistrantPermissionsPanel(
            "users",
            RegistrantType.USER,
            GitBlit.self().getAllUsernames(),
            repositoryUsers,
            getAccessPermissions());
    final RegistrantPermissionsPanel teamsPalette =
        new RegistrantPermissionsPanel(
            "teams",
            RegistrantType.TEAM,
            GitBlit.self().getAllTeamnames(),
            repositoryTeams,
            getAccessPermissions());

    // owners palette
    List<String> owners = new ArrayList<String>(repositoryModel.owners);
    List<String> persons = GitBlit.self().getAllUsernames();
    final Palette<String> ownersPalette =
        new Palette<String>(
            "owners",
            new ListModel<String>(owners),
            new CollectionModel<String>(persons),
            new StringChoiceRenderer(),
            12,
            true);

    // indexed local branches palette
    List<String> allLocalBranches = new ArrayList<String>();
    allLocalBranches.add(Constants.DEFAULT_BRANCH);
    allLocalBranches.addAll(repositoryModel.getLocalBranches());
    boolean luceneEnabled = GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true);
    final Palette<String> indexedBranchesPalette =
        new Palette<String>(
            "indexedBranches",
            new ListModel<String>(indexedBranches),
            new CollectionModel<String>(allLocalBranches),
            new StringChoiceRenderer(),
            8,
            false);
    indexedBranchesPalette.setEnabled(luceneEnabled);

    // federation sets palette
    List<String> sets = GitBlit.getStrings(Keys.federation.sets);
    final Palette<String> federationSetsPalette =
        new Palette<String>(
            "federationSets",
            new ListModel<String>(federationSets),
            new CollectionModel<String>(sets),
            new StringChoiceRenderer(),
            8,
            false);

    // pre-receive palette
    if (!ArrayUtils.isEmpty(repositoryModel.preReceiveScripts)) {
      preReceiveScripts.addAll(repositoryModel.preReceiveScripts);
    }
    final Palette<String> preReceivePalette =
        new Palette<String>(
            "preReceiveScripts",
            new ListModel<String>(preReceiveScripts),
            new CollectionModel<String>(GitBlit.self().getPreReceiveScriptsUnused(repositoryModel)),
            new StringChoiceRenderer(),
            12,
            true);

    // post-receive palette
    if (!ArrayUtils.isEmpty(repositoryModel.postReceiveScripts)) {
      postReceiveScripts.addAll(repositoryModel.postReceiveScripts);
    }
    final Palette<String> postReceivePalette =
        new Palette<String>(
            "postReceiveScripts",
            new ListModel<String>(postReceiveScripts),
            new CollectionModel<String>(
                GitBlit.self().getPostReceiveScriptsUnused(repositoryModel)),
            new StringChoiceRenderer(),
            12,
            true);

    // custom fields
    final Map<String, String> customFieldsMap = GitBlit.getMap(Keys.groovy.customFields);
    List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet());
    final ListView<String> customFieldsListView =
        new ListView<String>("customFieldsListView", customKeys) {

          private static final long serialVersionUID = 1L;

          @Override
          protected void populateItem(ListItem<String> item) {
            String key = item.getModelObject();
            item.add(new Label("customFieldLabel", customFieldsMap.get(key)));

            String value = "";
            if (repositoryModel.customFields != null
                && repositoryModel.customFields.containsKey(key)) {
              value = repositoryModel.customFields.get(key);
            }
            TextField<String> field =
                new TextField<String>("customFieldValue", new Model<String>(value));
            item.add(field);
          }
        };
    customFieldsListView.setReuseItems(true);

    CompoundPropertyModel<RepositoryModel> rModel =
        new CompoundPropertyModel<RepositoryModel>(repositoryModel);
    Form<RepositoryModel> form =
        new Form<RepositoryModel>("editForm", rModel) {

          private static final long serialVersionUID = 1L;

          @Override
          protected void onSubmit() {
            try {
              // confirm a repository name was entered
              if (repositoryModel.name == null && StringUtils.isEmpty(repositoryModel.name)) {
                error(getString("gb.pleaseSetRepositoryName"));
                return;
              }

              // ensure name is trimmed
              repositoryModel.name = repositoryModel.name.trim();

              // automatically convert backslashes to forward slashes
              repositoryModel.name = repositoryModel.name.replace('\\', '/');
              // Automatically replace // with /
              repositoryModel.name = repositoryModel.name.replace("//", "/");

              // prohibit folder paths
              if (repositoryModel.name.startsWith("/")) {
                error(getString("gb.illegalLeadingSlash"));
                return;
              }
              if (repositoryModel.name.startsWith("../")) {
                error(getString("gb.illegalRelativeSlash"));
                return;
              }
              if (repositoryModel.name.contains("/../")) {
                error(getString("gb.illegalRelativeSlash"));
                return;
              }
              if (repositoryModel.name.endsWith("/")) {
                repositoryModel.name =
                    repositoryModel.name.substring(0, repositoryModel.name.length() - 1);
              }

              // confirm valid characters in repository name
              Character c = StringUtils.findInvalidCharacter(repositoryModel.name);
              if (c != null) {
                error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c));
                return;
              }

              if (user.canCreate() && !user.canAdmin() && allowEditName) {
                // ensure repository name begins with the user's path
                if (!repositoryModel.name.startsWith(user.getPersonalPath())) {
                  error(
                      MessageFormat.format(
                          getString("gb.illegalPersonalRepositoryLocation"),
                          user.getPersonalPath()));
                  return;
                }

                if (repositoryModel.name.equals(user.getPersonalPath())) {
                  // reset path prefix and show error
                  repositoryModel.name = user.getPersonalPath() + "/";
                  error(getString("gb.pleaseSetRepositoryName"));
                  return;
                }
              }

              // confirm access restriction selection
              if (repositoryModel.accessRestriction == null) {
                error(getString("gb.selectAccessRestriction"));
                return;
              }

              // confirm federation strategy selection
              if (repositoryModel.federationStrategy == null) {
                error(getString("gb.selectFederationStrategy"));
                return;
              }

              // save federation set preferences
              if (repositoryModel.federationStrategy.exceeds(FederationStrategy.EXCLUDE)) {
                repositoryModel.federationSets.clear();
                Iterator<String> sets = federationSetsPalette.getSelectedChoices();
                while (sets.hasNext()) {
                  repositoryModel.federationSets.add(sets.next());
                }
              }

              // set author metric exclusions
              String ax = metricAuthorExclusions.getObject();
              if (!StringUtils.isEmpty(ax)) {
                Set<String> list = new HashSet<String>();
                for (String exclusion : StringUtils.getStringsFromValue(ax, " ")) {
                  if (StringUtils.isEmpty(exclusion)) {
                    continue;
                  }
                  if (exclusion.indexOf(' ') > -1) {
                    list.add("\"" + exclusion + "\"");
                  } else {
                    list.add(exclusion);
                  }
                }
                repositoryModel.metricAuthorExclusions = new ArrayList<String>(list);
              }

              // set mailing lists
              String ml = mailingLists.getObject();
              if (!StringUtils.isEmpty(ml)) {
                Set<String> list = new HashSet<String>();
                for (String address : ml.split("(,|\\s)")) {
                  if (StringUtils.isEmpty(address)) {
                    continue;
                  }
                  list.add(address.toLowerCase());
                }
                repositoryModel.mailingLists = new ArrayList<String>(list);
              }

              // indexed branches
              List<String> indexedBranches = new ArrayList<String>();
              Iterator<String> branches = indexedBranchesPalette.getSelectedChoices();
              while (branches.hasNext()) {
                indexedBranches.add(branches.next());
              }
              repositoryModel.indexedBranches = indexedBranches;

              // owners
              repositoryModel.owners.clear();
              Iterator<String> owners = ownersPalette.getSelectedChoices();
              while (owners.hasNext()) {
                repositoryModel.addOwner(owners.next());
              }

              // pre-receive scripts
              List<String> preReceiveScripts = new ArrayList<String>();
              Iterator<String> pres = preReceivePalette.getSelectedChoices();
              while (pres.hasNext()) {
                preReceiveScripts.add(pres.next());
              }
              repositoryModel.preReceiveScripts = preReceiveScripts;

              // post-receive scripts
              List<String> postReceiveScripts = new ArrayList<String>();
              Iterator<String> post = postReceivePalette.getSelectedChoices();
              while (post.hasNext()) {
                postReceiveScripts.add(post.next());
              }
              repositoryModel.postReceiveScripts = postReceiveScripts;

              // custom fields
              repositoryModel.customFields = new LinkedHashMap<String, String>();
              for (int i = 0; i < customFieldsListView.size(); i++) {
                ListItem<String> child = (ListItem<String>) customFieldsListView.get(i);
                String key = child.getModelObject();

                TextField<String> field = (TextField<String>) child.get("customFieldValue");
                String value = field.getValue();

                repositoryModel.customFields.put(key, value);
              }

              // save the repository
              GitBlit.self().updateRepositoryModel(oldName, repositoryModel, isCreate);

              // repository access permissions
              if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
                GitBlit.self().setUserAccessPermissions(repositoryModel, repositoryUsers);
                GitBlit.self().setTeamAccessPermissions(repositoryModel, repositoryTeams);
              }
            } catch (GitBlitException e) {
              error(e.getMessage());
              return;
            }
            setRedirect(false);
            setResponsePage(RepositoriesPage.class);
          }
        };

    // do not let the browser pre-populate these fields
    form.add(new SimpleAttributeModifier("autocomplete", "off"));

    // field names reflective match RepositoryModel fields
    form.add(new TextField<String>("name").setEnabled(allowEditName));
    form.add(new TextField<String>("description"));
    form.add(ownersPalette);
    form.add(
        new CheckBox("allowForks").setEnabled(GitBlit.getBoolean(Keys.web.allowForking, true)));
    DropDownChoice<AccessRestrictionType> accessRestriction =
        new DropDownChoice<AccessRestrictionType>(
            "accessRestriction",
            Arrays.asList(AccessRestrictionType.values()),
            new AccessRestrictionRenderer());
    form.add(accessRestriction);
    form.add(new CheckBox("isFrozen"));
    // TODO enable origin definition
    form.add(new TextField<String>("origin").setEnabled(false /* isCreate */));

    // allow relinking HEAD to a branch or tag other than master on edit repository
    List<String> availableRefs = new ArrayList<String>();
    if (!ArrayUtils.isEmpty(repositoryModel.availableRefs)) {
      availableRefs.addAll(repositoryModel.availableRefs);
    }
    form.add(
        new DropDownChoice<String>("HEAD", availableRefs).setEnabled(availableRefs.size() > 0));

    boolean gcEnabled = GitBlit.getBoolean(Keys.git.enableGarbageCollection, false);
    List<Integer> gcPeriods = Arrays.asList(1, 2, 3, 4, 5, 7, 10, 14);
    form.add(
        new DropDownChoice<Integer>("gcPeriod", gcPeriods, new GCPeriodRenderer())
            .setEnabled(gcEnabled));
    form.add(new TextField<String>("gcThreshold").setEnabled(gcEnabled));

    // federation strategies - remove ORIGIN choice if this repository has
    // no origin.
    List<FederationStrategy> federationStrategies =
        new ArrayList<FederationStrategy>(Arrays.asList(FederationStrategy.values()));
    if (StringUtils.isEmpty(repositoryModel.origin)) {
      federationStrategies.remove(FederationStrategy.FEDERATE_ORIGIN);
    }
    form.add(
        new DropDownChoice<FederationStrategy>(
            "federationStrategy", federationStrategies, new FederationTypeRenderer()));
    form.add(new CheckBox("useTickets"));
    form.add(new CheckBox("useDocs"));
    form.add(new CheckBox("useIncrementalPushTags"));
    form.add(new CheckBox("showRemoteBranches"));
    form.add(new CheckBox("showReadme"));
    form.add(new CheckBox("skipSizeCalculation"));
    form.add(new CheckBox("skipSummaryMetrics"));
    List<Integer> maxActivityCommits = Arrays.asList(-1, 0, 25, 50, 75, 100, 150, 200, 250, 500);
    form.add(
        new DropDownChoice<Integer>(
            "maxActivityCommits", maxActivityCommits, new MaxActivityCommitsRenderer()));

    metricAuthorExclusions =
        new Model<String>(
            ArrayUtils.isEmpty(repositoryModel.metricAuthorExclusions)
                ? ""
                : StringUtils.flattenStrings(repositoryModel.metricAuthorExclusions, " "));
    form.add(new TextField<String>("metricAuthorExclusions", metricAuthorExclusions));

    mailingLists =
        new Model<String>(
            ArrayUtils.isEmpty(repositoryModel.mailingLists)
                ? ""
                : StringUtils.flattenStrings(repositoryModel.mailingLists, " "));
    form.add(new TextField<String>("mailingLists", mailingLists));
    form.add(indexedBranchesPalette);

    List<AuthorizationControl> acList = Arrays.asList(AuthorizationControl.values());
    final RadioChoice<AuthorizationControl> authorizationControl =
        new RadioChoice<Constants.AuthorizationControl>(
            "authorizationControl", acList, new AuthorizationControlRenderer());
    form.add(authorizationControl);

    final CheckBox verifyCommitter = new CheckBox("verifyCommitter");
    verifyCommitter.setOutputMarkupId(true);
    form.add(verifyCommitter);

    form.add(usersPalette);
    form.add(teamsPalette);
    form.add(federationSetsPalette);
    form.add(preReceivePalette);
    form.add(
        new BulletListPanel(
            "inheritedPreReceive",
            getString("gb.inherited"),
            GitBlit.self().getPreReceiveScriptsInherited(repositoryModel)));
    form.add(postReceivePalette);
    form.add(
        new BulletListPanel(
            "inheritedPostReceive",
            getString("gb.inherited"),
            GitBlit.self().getPostReceiveScriptsInherited(repositoryModel)));

    WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection");
    customFieldsSection.add(customFieldsListView);
    form.add(
        customFieldsSection.setVisible(!GitBlit.getString(Keys.groovy.customFields, "").isEmpty()));

    // initial enable/disable of permission controls
    if (repositoryModel.accessRestriction.equals(AccessRestrictionType.NONE)) {
      // anonymous everything, disable all controls
      usersPalette.setEnabled(false);
      teamsPalette.setEnabled(false);
      authorizationControl.setEnabled(false);
      verifyCommitter.setEnabled(false);
    } else {
      // authenticated something
      // enable authorization controls
      authorizationControl.setEnabled(true);
      verifyCommitter.setEnabled(true);

      boolean allowFineGrainedControls =
          repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED);
      usersPalette.setEnabled(allowFineGrainedControls);
      teamsPalette.setEnabled(allowFineGrainedControls);
    }

    accessRestriction.add(
        new AjaxFormComponentUpdatingBehavior("onchange") {

          private static final long serialVersionUID = 1L;

          protected void onUpdate(AjaxRequestTarget target) {
            // enable/disable permissions panel based on access restriction
            boolean allowAuthorizationControl =
                repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE);
            authorizationControl.setEnabled(allowAuthorizationControl);
            verifyCommitter.setEnabled(allowAuthorizationControl);

            boolean allowFineGrainedControls =
                allowAuthorizationControl
                    && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED);
            usersPalette.setEnabled(allowFineGrainedControls);
            teamsPalette.setEnabled(allowFineGrainedControls);

            if (allowFineGrainedControls) {
              repositoryModel.authorizationControl = AuthorizationControl.NAMED;
            }

            target.addComponent(authorizationControl);
            target.addComponent(verifyCommitter);
            target.addComponent(usersPalette);
            target.addComponent(teamsPalette);
          }
        });

    authorizationControl.add(
        new AjaxFormChoiceComponentUpdatingBehavior() {

          private static final long serialVersionUID = 1L;

          protected void onUpdate(AjaxRequestTarget target) {
            // enable/disable permissions panel based on access restriction
            boolean allowAuthorizationControl =
                repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE);
            authorizationControl.setEnabled(allowAuthorizationControl);

            boolean allowFineGrainedControls =
                allowAuthorizationControl
                    && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED);
            usersPalette.setEnabled(allowFineGrainedControls);
            teamsPalette.setEnabled(allowFineGrainedControls);

            if (allowFineGrainedControls) {
              repositoryModel.authorizationControl = AuthorizationControl.NAMED;
            }

            target.addComponent(authorizationControl);
            target.addComponent(usersPalette);
            target.addComponent(teamsPalette);
          }
        });

    form.add(new Button("save"));
    Button cancel =
        new Button("cancel") {
          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            setResponsePage(RepositoriesPage.class);
          }
        };
    cancel.setDefaultFormProcessing(false);
    form.add(cancel);

    add(form);
  }
예제 #9
0
  private boolean validateFields() {
    String rname = nameField.getText();
    if (StringUtils.isEmpty(rname)) {
      error("Please enter a repository name!");
      return false;
    }

    // automatically convert backslashes to forward slashes
    rname = rname.replace('\\', '/');
    // Automatically replace // with /
    rname = rname.replace("//", "/");

    // prohibit folder paths
    if (rname.startsWith("/")) {
      error("Leading root folder references (/) are prohibited.");
      return false;
    }
    if (rname.startsWith("../")) {
      error("Relative folder references (../) are prohibited.");
      return false;
    }
    if (rname.contains("/../")) {
      error("Relative folder references (../) are prohibited.");
      return false;
    }

    // confirm valid characters in repository name
    Character c = StringUtils.findInvalidCharacter(rname);
    if (c != null) {
      error(MessageFormat.format("Illegal character ''{0}'' in repository name!", c));
      return false;
    }

    // verify repository name uniqueness on create
    if (isCreate) {
      // force repo names to lowercase
      // this means that repository name checking for rpc creation
      // is case-insensitive, regardless of the Gitblit server's
      // filesystem
      if (repositoryNames.contains(rname.toLowerCase())) {
        error(
            MessageFormat.format(
                "Can not create repository ''{0}'' because it already exists.", rname));
        return false;
      }
    } else {
      // check rename collision
      if (!repositoryName.equalsIgnoreCase(rname)) {
        if (repositoryNames.contains(rname.toLowerCase())) {
          error(
              MessageFormat.format(
                  "Failed to rename ''{0}'' because ''{1}'' already exists.",
                  repositoryName, rname));
          return false;
        }
      }
    }

    if (accessRestriction.getSelectedItem() == null) {
      error("Please select access restriction!");
      return false;
    }

    if (federationStrategy.getSelectedItem() == null) {
      error("Please select federation strategy!");
      return false;
    }

    repository.name = rname;
    repository.description = descriptionField.getText();
    repository.owner =
        ownerField.getSelectedItem() == null ? null : ownerField.getSelectedItem().toString();
    repository.HEAD =
        headRefField.getSelectedItem() == null ? null : headRefField.getSelectedItem().toString();
    repository.useTickets = useTickets.isSelected();
    repository.useDocs = useDocs.isSelected();
    repository.showRemoteBranches = showRemoteBranches.isSelected();
    repository.showReadme = showReadme.isSelected();
    repository.skipSizeCalculation = skipSizeCalculation.isSelected();
    repository.skipSummaryMetrics = skipSummaryMetrics.isSelected();
    repository.isFrozen = isFrozen.isSelected();

    String ml = mailingListsField.getText();
    if (!StringUtils.isEmpty(ml)) {
      Set<String> list = new HashSet<String>();
      for (String address : ml.split("(,|\\s)")) {
        if (StringUtils.isEmpty(address)) {
          continue;
        }
        list.add(address.toLowerCase());
      }
      repository.mailingLists = new ArrayList<String>(list);
    }

    repository.accessRestriction = (AccessRestrictionType) accessRestriction.getSelectedItem();
    repository.federationStrategy = (FederationStrategy) federationStrategy.getSelectedItem();

    if (repository.federationStrategy.exceeds(FederationStrategy.EXCLUDE)) {
      repository.federationSets = setsPalette.getSelections();
    }

    repository.indexedBranches = indexedBranchesPalette.getSelections();
    repository.preReceiveScripts = preReceivePalette.getSelections();
    repository.postReceiveScripts = postReceivePalette.getSelections();

    // Custom Fields
    repository.customFields = new LinkedHashMap<String, String>();
    if (customTextfields != null) {
      for (JTextField field : customTextfields) {
        String key = field.getName();
        String value = field.getText();
        repository.customFields.put(key, value);
      }
    }
    return true;
  }