From 289efbc850b4413bdcfd54d84e3813576cdc540d Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 25 Jul 2013 18:05:55 -0400
Subject: [PATCH] Removed obsolete/legacy code from build script
---
src/main/java/com/gitblit/GitBlit.java | 259 +++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 215 insertions(+), 44 deletions(-)
diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java
index df17edd..e47c4c6 100644
--- a/src/main/java/com/gitblit/GitBlit.java
+++ b/src/main/java/com/gitblit/GitBlit.java
@@ -84,6 +84,7 @@
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
+import com.gitblit.Constants.AccountType;
import com.gitblit.Constants.AuthenticationType;
import com.gitblit.Constants.AuthorizationControl;
import com.gitblit.Constants.FederationRequest;
@@ -102,6 +103,7 @@
import com.gitblit.models.GitClientApplication;
import com.gitblit.models.Metric;
import com.gitblit.models.ProjectModel;
+import com.gitblit.models.RefModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.RepositoryUrl;
@@ -114,11 +116,13 @@
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.Base64;
import com.gitblit.utils.ByteFormat;
+import com.gitblit.utils.CommitCache;
import com.gitblit.utils.ContainerUtils;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.JGitUtils;
+import com.gitblit.utils.JGitUtils.LastChange;
import com.gitblit.utils.JsonUtils;
import com.gitblit.utils.MetricUtils;
import com.gitblit.utils.ObjectCache;
@@ -228,6 +232,33 @@
}
return gitblit;
}
+
+ /**
+ * Returns the boot date of the Gitblit server.
+ *
+ * @return the boot date of Gitblit
+ */
+ public static Date getBootDate() {
+ return self().serverStatus.bootDate;
+ }
+
+ /**
+ * Returns the most recent change date of any repository served by Gitblit.
+ *
+ * @return a date
+ */
+ public static Date getLastActivityDate() {
+ Date date = null;
+ for (String name : self().getRepositoryList()) {
+ Repository r = self().getRepository(name);
+ Date lastChange = JGitUtils.getLastChange(r).when;
+ r.close();
+ if (lastChange != null && (date == null || lastChange.after(date))) {
+ date = lastChange;
+ }
+ }
+ return date;
+ }
/**
* Determine if this is the GO variant of Gitblit.
@@ -273,6 +304,15 @@
self().timezone = TimeZone.getTimeZone(tzid);
}
return self().timezone;
+ }
+
+ /**
+ * Returns the active settings.
+ *
+ * @return the active settings
+ */
+ public static IStoredSettings getSettings() {
+ return self().settings;
}
/**
@@ -509,7 +549,7 @@
if (user == null) {
user = UserModel.ANONYMOUS;
}
- String username = UserModel.ANONYMOUS.equals(user) ? "" : user.username;
+ String username = encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
// http/https url
@@ -681,7 +721,15 @@
* @return true if the user service supports credential changes
*/
public boolean supportsCredentialChanges(UserModel user) {
- return (user != null && user.isLocalAccount()) || userService.supportsCredentialChanges();
+ if (user == null) {
+ return false;
+ } else if (AccountType.LOCAL.equals(user.accountType)) {
+ // local account, we can change credentials
+ return true;
+ } else {
+ // external account, ask user service
+ return userService.supportsCredentialChanges();
+ }
}
/**
@@ -715,6 +763,18 @@
}
/**
+ * Returns true if the username represents an internal account
+ *
+ * @param username
+ * @return true if the specified username represents an internal account
+ */
+ protected boolean isInternalAccount(String username) {
+ return !StringUtils.isEmpty(username)
+ && (username.equalsIgnoreCase(Constants.FEDERATION_USER)
+ || username.equalsIgnoreCase(UserModel.ANONYMOUS.username));
+ }
+
+ /**
* Authenticate a user based on a username and password.
*
* @see IUserService.authenticate(String, char[])
@@ -727,6 +787,7 @@
// can not authenticate empty username
return null;
}
+ String usernameDecoded = decodeUsername(username);
String pw = new String(password);
if (StringUtils.isEmpty(pw)) {
// can not authenticate empty password
@@ -735,13 +796,10 @@
// check to see if this is the federation user
if (canFederate()) {
- if (username.equalsIgnoreCase(Constants.FEDERATION_USER)) {
+ if (usernameDecoded.equalsIgnoreCase(Constants.FEDERATION_USER)) {
List<String> tokens = getFederationTokens();
if (tokens.contains(pw)) {
- // the federation user is an administrator
- UserModel federationUser = new UserModel(Constants.FEDERATION_USER);
- federationUser.canAdmin = true;
- return federationUser;
+ return getFederationUser();
}
}
}
@@ -750,7 +808,7 @@
if (userService == null) {
return null;
}
- return userService.authenticate(username, password);
+ return userService.authenticate(usernameDecoded, password);
}
/**
@@ -827,14 +885,27 @@
Principal principal = httpRequest.getUserPrincipal();
if (principal != null) {
String username = principal.getName();
- if (StringUtils.isEmpty(username)) {
+ if (!StringUtils.isEmpty(username)) {
+ boolean internalAccount = isInternalAccount(username);
UserModel user = getUserModel(username);
if (user != null) {
+ // existing user
flagWicketSession(AuthenticationType.CONTAINER);
logger.debug(MessageFormat.format("{0} authenticated by servlet container principal from {1}",
user.username, httpRequest.getRemoteAddr()));
return user;
- } else {
+ } else if (settings.getBoolean(Keys.realm.container.autoCreateAccounts, false)
+ && !internalAccount) {
+ // auto-create user from an authenticated container principal
+ user = new UserModel(username.toLowerCase());
+ user.displayName = username;
+ user.password = Constants.EXTERNAL_ACCOUNT;
+ userService.updateUserModel(user);
+ flagWicketSession(AuthenticationType.CONTAINER);
+ logger.debug(MessageFormat.format("{0} authenticated and created by servlet container principal from {1}",
+ user.username, httpRequest.getRemoteAddr()));
+ return user;
+ } else if (!internalAccount) {
logger.warn(MessageFormat.format("Failed to find UserModel for {0}, attempted servlet container authentication from {1}",
principal.getName(), httpRequest.getRemoteAddr()));
}
@@ -910,7 +981,10 @@
if (userService == null) {
return;
}
- if (userService.supportsCookies()) {
+ GitBlitWebSession session = GitBlitWebSession.get();
+ boolean standardLogin = session.authenticationType.isStandard();
+
+ if (userService.supportsCookies() && standardLogin) {
Cookie userCookie;
if (user == null) {
// clear cookie for logout
@@ -945,6 +1019,26 @@
}
/**
+ * Encode the username for user in an url.
+ *
+ * @param name
+ * @return the encoded name
+ */
+ protected String encodeUsername(String name) {
+ return name.replace("@", "%40").replace(" ", "%20").replace("\\", "%5C");
+ }
+
+ /**
+ * Decode a username from an encoded url.
+ *
+ * @param name
+ * @return the decoded name
+ */
+ protected String decodeUsername(String name) {
+ return name.replace("%40", "@").replace("%20", " ").replace("%5C", "\\");
+ }
+
+ /**
* Returns the list of all users available to the login service.
*
* @see IUserService.getAllUsernames()
@@ -977,7 +1071,15 @@
if (StringUtils.isEmpty(username)) {
return false;
}
- return userService.deleteUser(username);
+ String usernameDecoded = decodeUsername(username);
+ return userService.deleteUser(usernameDecoded);
+ }
+
+ protected UserModel getFederationUser() {
+ // the federation user is an administrator
+ UserModel federationUser = new UserModel(Constants.FEDERATION_USER);
+ federationUser.canAdmin = true;
+ return federationUser;
}
/**
@@ -991,7 +1093,8 @@
if (StringUtils.isEmpty(username)) {
return null;
}
- UserModel user = userService.getUserModel(username);
+ String usernameDecoded = decodeUsername(username);
+ UserModel user = userService.getUserModel(usernameDecoded);
return user;
}
@@ -1428,7 +1531,10 @@
}
// return sorted copy of cached list
- List<String> list = new ArrayList<String>(repositoryListCache.keySet());
+ List<String> list = new ArrayList<String>();
+ for (RepositoryModel model : repositoryListCache.values()) {
+ list.add(model.name);
+ }
StringUtils.sortRepositorynames(list);
return list;
}
@@ -1451,6 +1557,10 @@
* @return repository or null
*/
public Repository getRepository(String repositoryName, boolean logError) {
+ // Decode url-encoded repository name (issue-278)
+ // http://stackoverflow.com/questions/17183110
+ repositoryName = repositoryName.replace("%7E", "~").replace("%7e", "~");
+
if (isCollectingGarbage(repositoryName)) {
logger.warn(MessageFormat.format("Rejecting request for {0}, busy collecting garbage!", repositoryName));
return null;
@@ -1550,6 +1660,10 @@
* @return repository model or null
*/
public RepositoryModel getRepositoryModel(String repositoryName) {
+ // Decode url-encoded repository name (issue-278)
+ // http://stackoverflow.com/questions/17183110
+ repositoryName = repositoryName.replace("%7E", "~").replace("%7e", "~");
+
if (!repositoryListCache.containsKey(repositoryName)) {
RepositoryModel model = loadRepositoryModel(repositoryName);
if (model == null) {
@@ -1592,7 +1706,9 @@
model.hasCommits = JGitUtils.hasCommits(r);
}
- model.lastChange = JGitUtils.getLastChange(r);
+ LastChange lc = JGitUtils.getLastChange(r);
+ model.lastChange = lc.when;
+ model.lastChangeAuthor = lc.who;
if (!model.skipSizeCalculation) {
ByteFormat byteFormat = new ByteFormat();
model.size = byteFormat.format(calculateSize(model));
@@ -1618,6 +1734,30 @@
}
}
return count;
+ }
+
+ private void reloadProjectMarkdown(ProjectModel project) {
+ // project markdown
+ File pmkd = new File(getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/project.mkd");
+ if (pmkd.exists()) {
+ Date lm = new Date(pmkd.lastModified());
+ if (!projectMarkdownCache.hasCurrent(project.name, lm)) {
+ String mkd = com.gitblit.utils.FileUtils.readContent(pmkd, "\n");
+ projectMarkdownCache.updateObject(project.name, lm, mkd);
+ }
+ project.projectMarkdown = projectMarkdownCache.getObject(project.name);
+ }
+
+ // project repositories markdown
+ File rmkd = new File(getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/repositories.mkd");
+ if (rmkd.exists()) {
+ Date lm = new Date(rmkd.lastModified());
+ if (!projectRepositoriesMarkdownCache.hasCurrent(project.name, lm)) {
+ String mkd = com.gitblit.utils.FileUtils.readContent(rmkd, "\n");
+ projectRepositoriesMarkdownCache.updateObject(project.name, lm, mkd);
+ }
+ project.repositoriesMarkdown = projectRepositoriesMarkdownCache.getObject(project.name);
+ }
}
@@ -1654,27 +1794,7 @@
project.title = projectConfigs.getString("project", name, "title");
project.description = projectConfigs.getString("project", name, "description");
- // project markdown
- File pmkd = new File(getRepositoriesFolder(), (project.isRoot ? "" : name) + "/project.mkd");
- if (pmkd.exists()) {
- Date lm = new Date(pmkd.lastModified());
- if (!projectMarkdownCache.hasCurrent(name, lm)) {
- String mkd = com.gitblit.utils.FileUtils.readContent(pmkd, "\n");
- projectMarkdownCache.updateObject(name, lm, mkd);
- }
- project.projectMarkdown = projectMarkdownCache.getObject(name);
- }
-
- // project repositories markdown
- File rmkd = new File(getRepositoriesFolder(), (project.isRoot ? "" : name) + "/repositories.mkd");
- if (rmkd.exists()) {
- Date lm = new Date(rmkd.lastModified());
- if (!projectRepositoriesMarkdownCache.hasCurrent(name, lm)) {
- String mkd = com.gitblit.utils.FileUtils.readContent(rmkd, "\n");
- projectRepositoriesMarkdownCache.updateObject(name, lm, mkd);
- }
- project.repositoriesMarkdown = projectRepositoriesMarkdownCache.getObject(name);
- }
+ reloadProjectMarkdown(project);
configs.put(name.toLowerCase(), project);
}
@@ -1796,6 +1916,8 @@
// no repositories == no project
return null;
}
+
+ reloadProjectMarkdown(project);
return project;
}
@@ -1890,7 +2012,9 @@
model.name = repositoryName;
}
model.hasCommits = JGitUtils.hasCommits(r);
- model.lastChange = JGitUtils.getLastChange(r);
+ LastChange lc = JGitUtils.getLastChange(r);
+ model.lastChange = lc.when;
+ model.lastChangeAuthor = lc.who;
model.projectPath = StringUtils.getFirstPathElement(repositoryName);
StoredConfig config = r.getConfig();
@@ -1898,6 +2022,7 @@
if (config != null) {
model.description = getConfig(config, "description", "");
+ model.originRepository = getConfig(config, "originRepository", null);
model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
model.useTickets = getConfig(config, "useTickets", false);
model.useDocs = getConfig(config, "useDocs", false);
@@ -1953,7 +2078,7 @@
model.sparkleshareId = JGitUtils.getSparkleshareId(r);
r.close();
- if (model.origin != null && model.origin.startsWith("file://")) {
+ if (StringUtils.isEmpty(model.originRepository) && model.origin != null && model.origin.startsWith("file://")) {
// repository was cloned locally... perhaps as a fork
try {
File folder = new File(new URI(model.origin));
@@ -1963,6 +2088,9 @@
File repoFolder = new File(getRepositoriesFolder(), originRepo);
if (repoFolder.exists()) {
model.originRepository = originRepo.toLowerCase();
+
+ // persist the fork origin
+ updateConfiguration(r, model);
}
}
} catch (URISyntaxException e) {
@@ -2362,6 +2490,7 @@
String origin = config.getString("remote", "origin", "url");
origin = origin.replace(repositoryName, repository.name);
config.setString("remote", "origin", "url", origin);
+ config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.name);
config.save();
} catch (Exception e) {
logger.error("Failed to update repository fork config for " + fork, e);
@@ -2370,11 +2499,12 @@
}
}
- // remove this repository from any origin model's fork list
+ // update this repository's origin's fork list
if (!StringUtils.isEmpty(repository.originRepository)) {
RepositoryModel origin = repositoryListCache.get(repository.originRepository);
if (origin != null && !ArrayUtils.isEmpty(origin.forks)) {
origin.forks.remove(repositoryName);
+ origin.forks.add(repository.name);
}
}
@@ -2423,6 +2553,7 @@
public void updateConfiguration(Repository r, RepositoryModel repository) {
StoredConfig config = r.getConfig();
config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description);
+ config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.originRepository);
config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners));
config.setBoolean(Constants.CONFIG_GITBLIT, null, "useTickets", repository.useTickets);
config.setBoolean(Constants.CONFIG_GITBLIT, null, "useDocs", repository.useDocs);
@@ -2874,8 +3005,7 @@
String cloneUrl = sb.toString();
// Retrieve all available repositories
- UserModel user = new UserModel(Constants.FEDERATION_USER);
- user.canAdmin = true;
+ UserModel user = getFederationUser();
List<RepositoryModel> list = getRepositoryModels(user);
// create the [cloneurl, repositoryModel] map
@@ -3009,7 +3139,9 @@
if (repository != null) {
for (String teamname : userService.getTeamnamesForRepositoryRole(repository.name)) {
TeamModel team = userService.getTeamModel(teamname);
- scripts.addAll(team.preReceiveScripts);
+ if (!ArrayUtils.isEmpty(team.preReceiveScripts)) {
+ scripts.addAll(team.preReceiveScripts);
+ }
}
}
return new ArrayList<String>(scripts);
@@ -3059,7 +3191,9 @@
if (repository != null) {
for (String teamname : userService.getTeamnamesForRepositoryRole(repository.name)) {
TeamModel team = userService.getTeamModel(teamname);
- scripts.addAll(team.postReceiveScripts);
+ if (!ArrayUtils.isEmpty(team.postReceiveScripts)) {
+ scripts.addAll(team.postReceiveScripts);
+ }
}
}
return new ArrayList<String>(scripts);
@@ -3352,7 +3486,8 @@
configureJGit();
configureFanout();
configureGitDaemon();
-
+ configureCommitCache();
+
ContainerUtils.CVE_2007_0450.test();
}
@@ -3462,6 +3597,42 @@
}
}
+ protected void configureCommitCache() {
+ int daysToCache = settings.getInteger(Keys.web.activityCacheDays, 14);
+ if (daysToCache <= 0) {
+ logger.info("commit cache disabled");
+ } else {
+ long start = System.nanoTime();
+ long repoCount = 0;
+ long commitCount = 0;
+ logger.info(MessageFormat.format("preparing {0} day commit cache. please wait...", daysToCache));
+ CommitCache.instance().setCacheDays(daysToCache);
+ Date cutoff = CommitCache.instance().getCutoffDate();
+ for (String repositoryName : getRepositoryList()) {
+ RepositoryModel model = getRepositoryModel(repositoryName);
+ if (model.hasCommits && model.lastChange.after(cutoff)) {
+ repoCount++;
+ Repository repository = getRepository(repositoryName);
+ for (RefModel ref : JGitUtils.getLocalBranches(repository, true, -1)) {
+ if (!ref.getDate().after(cutoff)) {
+ // branch not recently updated
+ continue;
+ }
+ List<?> commits = CommitCache.instance().getCommits(repositoryName, repository, ref.getName());
+ if (commits.size() > 0) {
+ logger.info(MessageFormat.format(" cached {0} commits for {1}:{2}",
+ commits.size(), repositoryName, ref.getName()));
+ commitCount += commits.size();
+ }
+ }
+ repository.close();
+ }
+ }
+ logger.info(MessageFormat.format("built {0} day commit cache of {1} commits across {2} repositories in {3} msecs",
+ daysToCache, commitCount, repoCount, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
+ }
+ }
+
protected final Logger getLogger() {
return logger;
}
--
Gitblit v1.9.1