Package com.gitblit.client

Source Code of com.gitblit.client.GitblitClient

/*
* Copyright 2011 gitblit.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitblit.client;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Constants.PermissionType;
import com.gitblit.Constants.RegistrantType;
import com.gitblit.GitBlitException.ForbiddenException;
import com.gitblit.GitBlitException.NotAllowedException;
import com.gitblit.GitBlitException.UnauthorizedException;
import com.gitblit.GitBlitException.UnknownRequestException;
import com.gitblit.Keys;
import com.gitblit.models.FederationModel;
import com.gitblit.models.FeedEntryModel;
import com.gitblit.models.FeedModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.RpcUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.SyndicationUtils;

/**
* GitblitClient is a object that retrieves data from a Gitblit server, caches
* it for local operations, and allows updating or creating Gitblit objects.
*
* @author James Moger
*
*/
public class GitblitClient implements Serializable {

  private static final long serialVersionUID = 1L;

  private static final Date NEVER = new Date(0);

  protected final GitblitRegistration reg;

  public final String url;

  public final String account;

  private final char[] password;

  private volatile int protocolVersion;

  private volatile boolean allowManagement;

  private volatile boolean allowAdministration;

  private volatile ServerSettings settings;

  private final List<RepositoryModel> allRepositories;

  private final List<UserModel> allUsers;

  private final List<TeamModel> allTeams;

  private final List<FederationModel> federationRegistrations;

  private final List<FeedModel> availableFeeds;

  private final List<FeedEntryModel> syndicatedEntries;

  private final Set<String> subscribedRepositories;

  private ServerStatus status;

  public GitblitClient(GitblitRegistration reg) {
    this.reg = reg;
    this.url = reg.url;
    this.account = reg.account;
    this.password = reg.password;

    this.allUsers = new ArrayList<UserModel>();
    this.allTeams = new ArrayList<TeamModel>();
    this.allRepositories = new ArrayList<RepositoryModel>();
    this.federationRegistrations = new ArrayList<FederationModel>();
    this.availableFeeds = new ArrayList<FeedModel>();
    this.syndicatedEntries = new ArrayList<FeedEntryModel>();
    this.subscribedRepositories = new HashSet<String>();
  }

  public void login() throws IOException {
    protocolVersion = RpcUtils.getProtocolVersion(url, account, password);
    refreshSettings();
    refreshAvailableFeeds();
    refreshRepositories();
    refreshSubscribedFeeds(0);

    try {
      // credentials may not have administrator access
      // or server may have disabled rpc management
      refreshUsers();
      if (protocolVersion > 1) {
        refreshTeams();
      }
      allowManagement = true;
    } catch (UnauthorizedException e) {
    } catch (ForbiddenException e) {
    } catch (NotAllowedException e) {
    } catch (UnknownRequestException e) {
    } catch (IOException e) {
      e.printStackTrace();
    }

    try {
      // credentials may not have administrator access
      // or server may have disabled rpc administration
      refreshStatus();
      allowAdministration = true;
    } catch (UnauthorizedException e) {
    } catch (ForbiddenException e) {
    } catch (NotAllowedException e) {
    } catch (UnknownRequestException e) {
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public int getProtocolVersion() {
    return protocolVersion;
  }

  public boolean allowManagement() {
    return allowManagement;
  }

  public boolean allowAdministration() {
    return allowAdministration;
  }

  public boolean isOwner(RepositoryModel model) {
    return model.isOwner(account);
  }

  public String getURL(String action, String repository, String objectId) {
    boolean mounted = settings.get(Keys.web.mountParameters).getBoolean(true);
    StringBuilder sb = new StringBuilder();
    sb.append(url);
    sb.append('/');
    sb.append(action);
    sb.append('/');
    if (mounted) {
      // mounted url/action/repository/objectId
      sb.append(StringUtils.encodeURL(repository));
      if (!StringUtils.isEmpty(objectId)) {
        sb.append('/');
        sb.append(objectId);
      }
      return sb.toString();
    } else {
      // parameterized url/action/&r=repository&h=objectId
      sb.append("?r=");
      sb.append(repository);
      if (!StringUtils.isEmpty(objectId)) {
        sb.append("&h=");
        sb.append(objectId);
      }
      return sb.toString();
    }
  }

  public AccessRestrictionType getDefaultAccessRestriction() {
    String restriction = "PUSH";
    if (settings.hasKey(Keys.git.defaultAccessRestriction)) {
      restriction = settings.get(Keys.git.defaultAccessRestriction).currentValue;
    }
    return AccessRestrictionType.fromName(restriction);
  }

  public AuthorizationControl getDefaultAuthorizationControl() {
    String authorization = null;
    if (settings.hasKey(Keys.git.defaultAuthorizationControl)) {
      authorization = settings.get(Keys.git.defaultAuthorizationControl).currentValue;
    }
    return AuthorizationControl.fromName(authorization);
  }

  /**
   * Returns the list of pre-receive scripts the repository inherited from the
   * global settings and team affiliations.
   *
   * @param repository
   *            if null only the globally specified scripts are returned
   * @return a list of scripts
   */
  public List<String> getPreReceiveScriptsInherited(RepositoryModel repository) {
    Set<String> scripts = new LinkedHashSet<String>();
    // Globals
    for (String script : settings.get(Keys.groovy.preReceiveScripts).getStrings()) {
      if (script.endsWith(".groovy")) {
        scripts.add(script.substring(0, script.lastIndexOf('.')));
      } else {
        scripts.add(script);
      }
    }

    // Team Scripts
    if (repository != null) {
      for (String teamname : getPermittedTeamnames(repository)) {
        TeamModel team = getTeamModel(teamname);
        if (!ArrayUtils.isEmpty(team.preReceiveScripts)) {
          scripts.addAll(team.preReceiveScripts);
        }
      }
    }
    return new ArrayList<String>(scripts);
  }

  /**
   * Returns the list of all available Groovy pre-receive push hook scripts
   * that are not already inherited by the repository. Script files must have
   * .groovy extension
   *
   * @param repository
   *            optional parameter
   * @return list of available hook scripts
   */
  public List<String> getPreReceiveScriptsUnused(RepositoryModel repository) {
    Set<String> inherited = new TreeSet<String>(getPreReceiveScriptsInherited(repository));

    // create list of available scripts by excluding inherited scripts
    List<String> scripts = new ArrayList<String>();
    if (!ArrayUtils.isEmpty(settings.pushScripts)) {
      for (String script : settings.pushScripts) {
        if (!inherited.contains(script)) {
          scripts.add(script);
        }
      }
    }
    return scripts;
  }

  /**
   * Returns the list of post-receive scripts the repository inherited from
   * the global settings and team affiliations.
   *
   * @param repository
   *            if null only the globally specified scripts are returned
   * @return a list of scripts
   */
  public List<String> getPostReceiveScriptsInherited(RepositoryModel repository) {
    Set<String> scripts = new LinkedHashSet<String>();
    // Global Scripts
    for (String script : settings.get(Keys.groovy.postReceiveScripts).getStrings()) {
      if (script.endsWith(".groovy")) {
        scripts.add(script.substring(0, script.lastIndexOf('.')));
      } else {
        scripts.add(script);
      }
    }
    // Team Scripts
    if (repository != null) {
      for (String teamname : getPermittedTeamnames(repository)) {
        TeamModel team = getTeamModel(teamname);
        if (!ArrayUtils.isEmpty(team.postReceiveScripts)) {
          scripts.addAll(team.postReceiveScripts);
        }
      }
    }
    return new ArrayList<String>(scripts);
  }

  /**
   * Returns the list of unused Groovy post-receive push hook scripts that are
   * not already inherited by the repository. Script files must have .groovy
   * extension
   *
   * @param repository
   *            optional parameter
   * @return list of available hook scripts
   */
  public List<String> getPostReceiveScriptsUnused(RepositoryModel repository) {
    Set<String> inherited = new TreeSet<String>(getPostReceiveScriptsInherited(repository));

    // create list of available scripts by excluding inherited scripts
    List<String> scripts = new ArrayList<String>();
    if (!ArrayUtils.isEmpty(settings.pushScripts)) {
      for (String script : settings.pushScripts) {
        if (!inherited.contains(script)) {
          scripts.add(script);
        }
      }
    }
    return scripts;
  }

  public ServerSettings getSettings() {
    return settings;
  }

  public ServerStatus getStatus() {
    return status;
  }

  public String getSettingDescription(String key) {
    return settings.get(key).description;
  }

  public List<RepositoryModel> refreshRepositories() throws IOException {
    Map<String, RepositoryModel> repositories = RpcUtils
        .getRepositories(url, account, password);
    allRepositories.clear();
    allRepositories.addAll(repositories.values());
    Collections.sort(allRepositories);
    markSubscribedFeeds();
    return allRepositories;
  }

  public List<UserModel> refreshUsers() throws IOException {
    List<UserModel> users = RpcUtils.getUsers(url, account, password);
    allUsers.clear();
    allUsers.addAll(users);
    Collections.sort(users);
    return allUsers;
  }

  public List<TeamModel> refreshTeams() throws IOException {
    List<TeamModel> teams = RpcUtils.getTeams(url, account, password);
    allTeams.clear();
    allTeams.addAll(teams);
    Collections.sort(teams);
    return allTeams;
  }

  public ServerSettings refreshSettings() throws IOException {
    settings = RpcUtils.getSettings(url, account, password);
    return settings;
  }

  public ServerStatus refreshStatus() throws IOException {
    status = RpcUtils.getStatus(url, account, password);
    return status;
  }

  public List<String> getBranches(String repository) {
    List<FeedModel> feeds = getAvailableFeeds(repository);
    List<String> branches = new ArrayList<String>();
    for (FeedModel feed : feeds) {
      branches.add(feed.branch);
    }
    Collections.sort(branches);
    return branches;
  }

  public List<FeedModel> getAvailableFeeds() {
    return availableFeeds;
  }

  public List<FeedModel> getAvailableFeeds(RepositoryModel repository) {
    return getAvailableFeeds(repository.name);
  }

  public List<FeedModel> getAvailableFeeds(String repository) {
    List<FeedModel> repositoryFeeds = new ArrayList<FeedModel>();
    if (repository == null) {
      return repositoryFeeds;
    }
    for (FeedModel feed : availableFeeds) {
      if (feed.repository.equalsIgnoreCase(repository)) {
        repositoryFeeds.add(feed);
      }
    }
    return repositoryFeeds;
  }

  public List<FeedModel> refreshAvailableFeeds() throws IOException {
    List<FeedModel> feeds = RpcUtils.getBranchFeeds(url, account, password);
    availableFeeds.clear();
    availableFeeds.addAll(feeds);
    markSubscribedFeeds();
    return availableFeeds;
  }

  public List<FeedEntryModel> refreshSubscribedFeeds(int page) throws IOException {
    Set<FeedEntryModel> allEntries = new HashSet<FeedEntryModel>();
    if (reg.feeds.size() > 0) {
      for (FeedModel feed : reg.feeds) {
        feed.lastRefreshDate = feed.currentRefreshDate;
        feed.currentRefreshDate = new Date();
        List<FeedEntryModel> entries = SyndicationUtils.readFeed(url, feed.repository,
            feed.branch, -1, page, account, password);
        allEntries.addAll(entries);
      }
    }
    reg.cacheFeeds();
    syndicatedEntries.clear();
    syndicatedEntries.addAll(allEntries);
    Collections.sort(syndicatedEntries);
    return syndicatedEntries;
  }

  public void updateSubscribedFeeds(List<FeedModel> list) {
    reg.updateSubscribedFeeds(list);
    markSubscribedFeeds();
  }

  private void markSubscribedFeeds() {
    subscribedRepositories.clear();
    for (FeedModel feed : availableFeeds) {
      // mark feed in the available list as subscribed
      feed.subscribed = reg.feeds.contains(feed);
      if (feed.subscribed) {
        subscribedRepositories.add(feed.repository.toLowerCase());
      }
    }
  }

  public Date getLastFeedRefresh(String repository, String branch) {
    FeedModel feed = new FeedModel();
    feed.repository = repository;
    feed.branch = branch;
    if (reg.feeds.contains(feed)) {
      int idx = reg.feeds.indexOf(feed);
      feed = reg.feeds.get(idx);
      return feed.lastRefreshDate;
    }
    return NEVER;
  }

  public boolean isSubscribed(RepositoryModel repository) {
    return subscribedRepositories.contains(repository.name.toLowerCase());
  }

  public List<FeedEntryModel> getSyndicatedEntries() {
    return syndicatedEntries;
  }

  public List<FeedEntryModel> log(String repository, String branch, int numberOfEntries, int page)
      throws IOException {
    return SyndicationUtils.readFeed(url, repository, branch, numberOfEntries, page, account,
        password);
  }

  public List<FeedEntryModel> search(String repository, String branch, String fragment,
      Constants.SearchType type, int numberOfEntries, int page) throws IOException {
    return SyndicationUtils.readSearchFeed(url, repository, branch, fragment, type,
        numberOfEntries, page, account, password);
  }

  public List<FederationModel> refreshFederationRegistrations() throws IOException {
    List<FederationModel> list = RpcUtils.getFederationRegistrations(url, account, password);
    federationRegistrations.clear();
    federationRegistrations.addAll(list);
    return federationRegistrations;
  }

  public List<UserModel> getUsers() {
    return allUsers;
  }

  public UserModel getUser(String username) {
    for (UserModel user : getUsers()) {
      if (user.username.equalsIgnoreCase(username)) {
        return user;
      }
    }
    return null;
  }

  public List<String> getUsernames() {
    List<String> usernames = new ArrayList<String>();
    for (UserModel user : this.allUsers) {
      usernames.add(user.username);
    }
    Collections.sort(usernames);
    return usernames;
  }

  public List<String> getPermittedUsernames(RepositoryModel repository) {
    List<String> usernames = new ArrayList<String>();
    for (UserModel user : this.allUsers) {
      if (user.hasRepositoryPermission(repository.name)) {
        usernames.add(user.username);
      }
    }
    return usernames;
  }

  /**
   * Returns the effective list of permissions for this user, taking into account
   * team memberships, ownerships.
   *
   * @param user
   * @return the effective list of permissions for the user
   */
  public List<RegistrantAccessPermission> getUserAccessPermissions(UserModel user) {
    Set<RegistrantAccessPermission> set = new LinkedHashSet<RegistrantAccessPermission>();
    set.addAll(user.getRepositoryPermissions());
    // Flag missing repositories
    for (RegistrantAccessPermission permission : set) {
      if (permission.mutable && PermissionType.EXPLICIT.equals(permission.permissionType)) {
        RepositoryModel rm = getRepository(permission.registrant);
        if (rm == null) {
          permission.permissionType = PermissionType.MISSING;
          permission.mutable = false;
          continue;
        }
      }
    }

    // TODO reconsider ownership as a user property
    // manually specify personal repository ownerships
    for (RepositoryModel rm : allRepositories) {
      if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {
        RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,
            PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);
        // user may be owner of a repository to which they've inherited
        // a team permission, replace any existing perm with owner perm
        set.remove(rp);
        set.add(rp);
      }
    }

    List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>(set);
    Collections.sort(list);
    return list;
  }

  public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {
    List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
    if (AccessRestrictionType.NONE.equals(repository.accessRestriction)) {
      // no permissions needed, REWIND for everyone!
      return list;
    }
    if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl)) {
      // no permissions needed, REWIND for authenticated!
      return list;
    }
    // NAMED users and teams
    for (UserModel user : allUsers) {
      RegistrantAccessPermission ap = user.getRepositoryPermission(repository);
      if (ap.permission.exceeds(AccessPermission.NONE)) {
        list.add(ap);
      }
    }
    return list;
  }

  public boolean setUserAccessPermissions(RepositoryModel repository, List<RegistrantAccessPermission> permissions) throws IOException {
    return RpcUtils.setRepositoryMemberPermissions(repository, permissions, url, account, password);
  }

  public List<TeamModel> getTeams() {
    return allTeams;
  }

  public List<String> getTeamnames() {
    List<String> teamnames = new ArrayList<String>();
    for (TeamModel team : this.allTeams) {
      teamnames.add(team.name);
    }
    Collections.sort(teamnames);
    return teamnames;
  }

  public List<String> getPermittedTeamnames(RepositoryModel repository) {
    List<String> teamnames = new ArrayList<String>();
    for (TeamModel team : this.allTeams) {
      if (team.hasRepositoryPermission(repository.name)) {
        teamnames.add(team.name);
      }
    }
    return teamnames;
  }

  public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {
    List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
    for (TeamModel team : allTeams) {
      RegistrantAccessPermission ap = team.getRepositoryPermission(repository);
      if (ap.permission.exceeds(AccessPermission.NONE)) {
        list.add(ap);
      }
    }
    Collections.sort(list);
    return list;
  }

  public boolean setTeamAccessPermissions(RepositoryModel repository, List<RegistrantAccessPermission> permissions) throws IOException {
    return RpcUtils.setRepositoryTeamPermissions(repository, permissions, url, account, password);
  }

  public TeamModel getTeamModel(String name) {
    for (TeamModel team : allTeams) {
      if (team.name.equalsIgnoreCase(name)) {
        return team;
      }
    }
    return null;
  }

  public List<String> getFederationSets() {
    return settings.get(Keys.federation.sets).getStrings();
  }

  public List<RepositoryModel> getRepositories() {
    return allRepositories;
  }

  public RepositoryModel getRepository(String name) {
    for (RepositoryModel repository : allRepositories) {
      if (repository.name.equalsIgnoreCase(name)) {
        return repository;
      }
    }
    return null;
  }

  public boolean createRepository(RepositoryModel repository, List<RegistrantAccessPermission> userPermissions)
      throws IOException {
    return createRepository(repository, userPermissions, null);
  }

  public boolean createRepository(RepositoryModel repository, List<RegistrantAccessPermission> userPermissions,
      List<RegistrantAccessPermission> teamPermissions) throws IOException {
    boolean success = true;
    success &= RpcUtils.createRepository(repository, url, account, password);
    if (userPermissions != null && userPermissions.size() > 0) {
      // if new repository has named members, set them
      success &= RpcUtils.setRepositoryMemberPermissions(repository, userPermissions, url, account,
          password);
    }
    if (teamPermissions != null && teamPermissions.size() > 0) {
      // if new repository has named teams, set them
      success &= RpcUtils.setRepositoryTeamPermissions(repository, teamPermissions, url, account,
          password);
    }
    return success;
  }

  public boolean updateRepository(String name, RepositoryModel repository,
      List<RegistrantAccessPermission> userPermissions) throws IOException {
    return updateRepository(name, repository, userPermissions, null);
  }

  public boolean updateRepository(String name, RepositoryModel repository,
      List<RegistrantAccessPermission> userPermissions,  List<RegistrantAccessPermission> teamPermissions) throws IOException {
    boolean success = true;
    success &= RpcUtils.updateRepository(name, repository, url, account, password);
    // set the repository members
    if (userPermissions != null) {
      success &= RpcUtils.setRepositoryMemberPermissions(repository, userPermissions, url, account,
          password);
    }
    if (teamPermissions != null) {
      success &= RpcUtils.setRepositoryTeamPermissions(repository, teamPermissions, url, account,
          password);
    }
    return success;
  }

  public boolean deleteRepository(RepositoryModel repository) throws IOException {
    return RpcUtils.deleteRepository(repository, url, account, password);
  }

  public boolean clearRepositoryCache() throws IOException {
    return RpcUtils.clearRepositoryCache(url, account, password);
  }

  public boolean createUser(UserModel user) throws IOException {
    return RpcUtils.createUser(user, url, account, password);
  }

  public boolean updateUser(String name, UserModel user) throws IOException {
    return RpcUtils.updateUser(name, user, url, account, password);
  }

  public boolean deleteUser(UserModel user) throws IOException {
    return RpcUtils.deleteUser(user, url, account, password);
  }

  public boolean createTeam(TeamModel team) throws IOException {
    return RpcUtils.createTeam(team, url, account, password);
  }

  public boolean updateTeam(String name, TeamModel team) throws IOException {
    return RpcUtils.updateTeam(name, team, url, account, password);
  }

  public boolean deleteTeam(TeamModel team) throws IOException {
    return RpcUtils.deleteTeam(team, url, account, password);
  }

  public boolean updateSettings(Map<String, String> newSettings) throws IOException {
    return RpcUtils.updateSettings(newSettings, url, account, password);
  }
}
TOP

Related Classes of com.gitblit.client.GitblitClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.