@@ -54,6 +54,7 @@ Gitblit requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit | |||
- fixed: Gitblit now runs on Servlet 3.0 webservers (e.g. Tomcat 7, Jetty 8) (issue 23) | |||
- fixed: Set the RSS content type of syndication feeds for Firefox 4 (issue 22) | |||
- fixed: RSS feeds are now properly encoded to UTF-8 | |||
- fixed: RSS feeds now properly generated parameterized links if *web.mountParameters=false* | |||
- fixed: Null pointer exception if did not set federation strategy (issue 20) | |||
- fixed: Gitblit GO allows SSL renegotiation if running on Java 1.6.0_22 or later | |||
- updated: MarkdownPapers 1.2.4 |
@@ -19,6 +19,7 @@ The Gitblit RPC mechanism, like the Gitblit JGit servlet, syndication/feed servl | |||
<tr><td colspan='5'><em>web.enableRpcServlet=true</em></td></tr> | |||
<tr><td>LIST_REPOSITORIES</td><td>-</td><td>-</td><td>-</td><td>Map<String, RepositoryModel></td></tr> | |||
<tr><td>LIST_BRANCHES</td><td>-</td><td>-</td><td>-</td><td>Map<String, List<String>></td></tr> | |||
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>-</em></td><td>-</td><td>ServerSettings (basic keys)</td></tr> | |||
<tr><td colspan='5'><em>web.enableRpcManagement=true</em></td></tr> | |||
<tr><td>CREATE_REPOSITORY</td><td>repository name</td><td><em>admin</em></td><td>RepositoryModel</td><td>-</td></tr> | |||
<tr><td>EDIT_REPOSITORY</td><td>repository name</td><td><em>admin</em></td><td>RepositoryModel</td><td>-</td></tr> |
@@ -27,6 +27,7 @@ | |||
- fixed: Gitblit now runs on Servlet 3.0 webservers (e.g. Tomcat 7, Jetty 8) (issue 23) | |||
- fixed: Set the RSS content type of syndication feeds for Firefox 4 (issue 22) | |||
- fixed: RSS feeds are now properly encoded to UTF-8 | |||
- fixed: RSS feeds now properly generated parameterized links if *web.mountParameters=false* | |||
- fixed: Null pointer exception if did not set federation strategy (issue 20) | |||
- fixed: Gitblit GO allows SSL renegotiation if running on Java 1.6.0_22 or later | |||
- updated: MarkdownPapers 1.2.4 |
@@ -201,11 +201,13 @@ public class Constants { | |||
* a client. | |||
*/ | |||
public static enum RpcRequest { | |||
LIST_REPOSITORIES, LIST_BRANCHES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, | |||
LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS, | |||
SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, | |||
LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS, EDIT_SETTINGS, | |||
LIST_STATUS; | |||
// Order is important here. anything above LIST_SETTINGS requires | |||
// administrator privileges and web.allowRpcManagement. | |||
LIST_REPOSITORIES, LIST_BRANCHES, LIST_SETTINGS, CREATE_REPOSITORY, EDIT_REPOSITORY, | |||
DELETE_REPOSITORY, LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, | |||
LIST_REPOSITORY_MEMBERS, SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, | |||
LIST_FEDERATION_RESULTS, LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, | |||
EDIT_SETTINGS, LIST_STATUS; | |||
public static RpcRequest fromName(String name) { | |||
for (RpcRequest type : values()) { | |||
@@ -214,7 +216,7 @@ public class Constants { | |||
} | |||
} | |||
return null; | |||
} | |||
} | |||
public boolean exceeds(RpcRequest type) { | |||
return this.ordinal() > type.ordinal(); |
@@ -64,7 +64,7 @@ public class RpcFilter extends AuthenticationFilter { | |||
return; | |||
} | |||
boolean adminRequest = requestType.exceeds(RpcRequest.LIST_BRANCHES); | |||
boolean adminRequest = requestType.exceeds(RpcRequest.LIST_SETTINGS); | |||
// conditionally reject all rpc requests | |||
if (!GitBlit.getBoolean(Keys.web.enableRpcServlet, true)) { | |||
@@ -86,8 +86,8 @@ public class RpcFilter extends AuthenticationFilter { | |||
// conditionally reject rpc management/administration requests | |||
if (adminRequest && !GitBlit.getBoolean(Keys.web.enableRpcManagement, false)) { | |||
logger.warn(Keys.web.enableRpcManagement | |||
+ " must be set TRUE for management/administrative rpc requests."); | |||
logger.warn(MessageFormat.format("{0} must be set TRUE for {1} rpc requests.", | |||
Keys.web.enableRpcManagement, requestType.toString())); | |||
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); | |||
return; | |||
} |
@@ -68,10 +68,14 @@ public class RpcServlet extends JsonServlet { | |||
logger.info(MessageFormat.format("Rpc {0} request from {1}", reqType, | |||
request.getRemoteAddr())); | |||
boolean allowAdmin = GitBlit.getBoolean(Keys.web.enableRpcAdministration, false); | |||
UserModel user = (UserModel) request.getUserPrincipal(); | |||
boolean allowManagement = user != null && user.canAdmin | |||
&& GitBlit.getBoolean(Keys.web.enableRpcManagement, false); | |||
boolean allowAdmin = user != null && user.canAdmin | |||
&& GitBlit.getBoolean(Keys.web.enableRpcAdministration, false); | |||
Object result = null; | |||
if (RpcRequest.LIST_REPOSITORIES.equals(reqType)) { | |||
// Determine the Gitblit clone url | |||
@@ -224,9 +228,18 @@ public class RpcServlet extends JsonServlet { | |||
// return all settings | |||
result = settings; | |||
} else { | |||
// return management settings only | |||
String[] keys = { Keys.realm.minPasswordLength, Keys.realm.passwordStorage, | |||
Keys.federation.sets }; | |||
// anonymous users get a few settings to allow browser launching | |||
List<String> keys = new ArrayList<String>(); | |||
keys.add(Keys.web.siteName); | |||
keys.add(Keys.web.mountParameters); | |||
if (allowManagement) { | |||
// keys necessary for repository and/or user management | |||
keys.add(Keys.realm.minPasswordLength); | |||
keys.add(Keys.realm.passwordStorage); | |||
keys.add(Keys.federation.sets); | |||
} | |||
// build the settings | |||
ServerSettings managementSettings = new ServerSettings(); | |||
for (String key : keys) { | |||
managementSettings.add(settings.get(key)); |
@@ -32,8 +32,6 @@ import com.gitblit.utils.HttpUtils; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.SyndicationUtils; | |||
import com.sun.syndication.feed.synd.SyndContent; | |||
import com.sun.syndication.feed.synd.SyndContentImpl; | |||
/** | |||
* SyndicationServlet generates RSS 2.0 feeds and feed links. | |||
@@ -145,13 +143,22 @@ public class SyndicationServlet extends HttpServlet { | |||
List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, 0, length); | |||
List<SyndicatedEntryModel> entries = new ArrayList<SyndicatedEntryModel>(); | |||
boolean mountParameters = GitBlit.getBoolean(Keys.web.mountParameters, true); | |||
String urlPattern; | |||
if (mountParameters) { | |||
// mounted parameters | |||
urlPattern = "{0}/commit/{1}/{2}"; | |||
} else { | |||
// parameterized parameters | |||
urlPattern = "{0}/commit/?r={1}&h={2}"; | |||
} | |||
String gitblitUrl = HttpUtils.getGitblitURL(request); | |||
// convert RevCommit to SyndicatedEntryModel | |||
for (RevCommit commit : commits) { | |||
SyndicatedEntryModel entry = new SyndicatedEntryModel(); | |||
entry.title = commit.getShortMessage(); | |||
entry.author = commit.getAuthorIdent().getName(); | |||
entry.link = MessageFormat.format("{0}/commit/{1}/{2}", gitblitUrl, | |||
entry.link = MessageFormat.format(urlPattern, gitblitUrl, | |||
StringUtils.encodeURL(model.name), commit.getName()); | |||
entry.published = commit.getCommitterIdent().getWhen(); | |||
entry.contentType = "text/plain"; | |||
@@ -160,9 +167,20 @@ public class SyndicationServlet extends HttpServlet { | |||
entry.branch = objectId; | |||
entries.add(entry); | |||
} | |||
String feedLink; | |||
if (mountParameters) { | |||
// mounted url | |||
feedLink = MessageFormat.format("{0}/summary/{1}", gitblitUrl, | |||
StringUtils.encodeURL(model.name)); | |||
} else { | |||
// parameterized url | |||
feedLink = MessageFormat.format("{0}/summary/?r={1}", gitblitUrl, | |||
StringUtils.encodeURL(model.name)); | |||
} | |||
try { | |||
SyndicationUtils.toRSS(gitblitUrl, getTitle(model.name, objectId), model.description, | |||
model.name, entries, response.getOutputStream()); | |||
SyndicationUtils.toRSS(gitblitUrl, feedLink, getTitle(model.name, objectId), | |||
model.description, model.name, entries, response.getOutputStream()); | |||
} catch (Exception e) { | |||
logger.error("An error occurred during feed generation", e); | |||
} |
@@ -38,6 +38,7 @@ import com.gitblit.models.ServerStatus; | |||
import com.gitblit.models.SyndicatedEntryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.RpcUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.SyndicationUtils; | |||
/** | |||
@@ -96,6 +97,7 @@ public class GitblitClient implements Serializable { | |||
} | |||
public void login() throws IOException { | |||
refreshSettings(); | |||
refreshAvailableFeeds(); | |||
refreshRepositories(); | |||
@@ -110,7 +112,6 @@ public class GitblitClient implements Serializable { | |||
// credentials may not have administrator access | |||
// or server may have disabled rpc management | |||
refreshUsers(); | |||
refreshSettings(); | |||
allowManagement = true; | |||
} catch (UnauthorizedException e) { | |||
} catch (ForbiddenException e) { | |||
@@ -132,7 +133,6 @@ public class GitblitClient implements Serializable { | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public boolean allowManagement() { | |||
@@ -147,6 +147,33 @@ public class GitblitClient implements Serializable { | |||
return account != null && account.equalsIgnoreCase(model.owner); | |||
} | |||
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 ServerSettings getSettings() { | |||
return settings; | |||
} |
@@ -26,7 +26,6 @@ import java.awt.event.KeyEvent; | |||
import java.awt.event.MouseAdapter; | |||
import java.awt.event.MouseEvent; | |||
import java.io.IOException; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@@ -91,9 +90,8 @@ public abstract class RepositoriesPanel extends JPanel { | |||
browseRepository.addActionListener(new ActionListener() { | |||
public void actionPerformed(ActionEvent e) { | |||
RepositoryModel model = getSelectedRepositories().get(0); | |||
String u = MessageFormat.format("{0}/summary/{1}", gitblit.url, | |||
StringUtils.encodeURL(model.name)); | |||
Utils.browse(u); | |||
String url = gitblit.getURL("summary", model.name, null); | |||
Utils.browse(url); | |||
} | |||
}); | |||
@@ -51,6 +51,7 @@ public class SyndicationUtils { | |||
* Outputs an RSS feed of the list of entries to the outputstream. | |||
* | |||
* @param hostUrl | |||
* @param feedLink | |||
* @param title | |||
* @param description | |||
* @param repository | |||
@@ -59,16 +60,15 @@ public class SyndicationUtils { | |||
* @throws IOException | |||
* @throws FeedException | |||
*/ | |||
public static void toRSS(String hostUrl, String title, String description, String repository, | |||
List<SyndicatedEntryModel> entryModels, OutputStream os) throws IOException, | |||
FeedException { | |||
public static void toRSS(String hostUrl, String feedLink, String title, String description, | |||
String repository, List<SyndicatedEntryModel> entryModels, OutputStream os) | |||
throws IOException, FeedException { | |||
SyndFeed feed = new SyndFeedImpl(); | |||
feed.setFeedType("rss_2.0"); | |||
feed.setEncoding("UTF-8"); | |||
feed.setTitle(title); | |||
feed.setLink(MessageFormat.format("{0}/summary/{1}", hostUrl, | |||
StringUtils.encodeURL(repository))); | |||
feed.setLink(feedLink); | |||
feed.setDescription(description); | |||
SyndImageImpl image = new SyndImageImpl(); | |||
image.setTitle(Constants.NAME); |
@@ -42,8 +42,8 @@ public class SyndicationUtilsTest extends TestCase { | |||
entries.add(entry); | |||
} | |||
ByteArrayOutputStream os = new ByteArrayOutputStream(); | |||
SyndicationUtils.toRSS("http://localhost", "Title", "Description", "Repository", entries, | |||
os); | |||
SyndicationUtils.toRSS("http://localhost", "", "Title", "Description", "Repository", | |||
entries, os); | |||
String feed = os.toString(); | |||
os.close(); | |||
assertTrue(feed.indexOf("<title>Title</title>") > -1); |