123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719 |
- /*
- * 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);
- }
- }
|