@@ -17,6 +17,6 @@ | |||
/federation.properties | |||
/mailtest.properties | |||
/.settings/*.prefs | |||
/src/WEB-INF/gitblit.properties | |||
/src/WEB-INF/reference.properties | |||
/bin/ | |||
/.settings/ |
@@ -106,7 +106,7 @@ | |||
<!-- copy gitblit.properties to the WEB-INF folder. | |||
this file is only used for parsing setting descriptions. --> | |||
<copy todir="${basedir}/src/WEB-INF" overwrite="true" | |||
<copy tofile="${basedir}/src/WEB-INF/reference.properties" overwrite="true" | |||
file="${basedir}/distrib/gitblit.properties" /> | |||
<!-- Compile the build tool and execute it. | |||
@@ -311,11 +311,10 @@ | |||
<delete dir="${project.war.dir}" /> | |||
<!-- Copy web.xml, users.properties, and gitblit.properties to WEB-INF --> | |||
<!-- Copy web.xml and users.properties to WEB-INF --> | |||
<copy todir="${project.war.dir}/WEB-INF"> | |||
<fileset dir="${basedir}/distrib"> | |||
<include name="users.properties" /> | |||
<include name="gitblit.properties" /> | |||
</fileset> | |||
<fileset dir="${basedir}/src/WEB-INF"> | |||
<include name="web.xml" /> | |||
@@ -326,6 +325,10 @@ | |||
</fileset> | |||
</copy> | |||
<!-- Copy gitblit.properties as reference.properties --> | |||
<copy tofile="${project.war.dir}/WEB-INF/reference.properties" | |||
file="${basedir}/distrib/gitblit.properties"/> | |||
<!-- Build the docs for the WAR build --> | |||
<antcall target="buildDocs" inheritall="true" inheritrefs="true"> | |||
<param name="docs.output.dir" value="${project.war.dir}/WEB-INF/docs" /> |
@@ -31,6 +31,7 @@ The Gitblit RPC mechanism, like the Gitblit JGit servlet, syndication/feed servl | |||
<tr><td>LIST_FEDERATION_PROPOSALS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List<FederationProposal></td></tr> | |||
<tr><td>LIST_FEDERATION_SETS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List<FederationSet></td></tr> | |||
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>-</td><td>ServerSettings (see example below)</td></tr> | |||
<tr><td>EDIT_SETTINGS</td><td>-</td><td><em>admin</em></td><td>Map<String, String></td><td>-</td></tr> | |||
<tr><td>LIST_STATUS</td><td>-</td><td><em>admin</em></td><td>-</td><td>ServerStatus (see example below)</td></tr> | |||
</table> | |||
@@ -18,7 +18,11 @@ package com.gitblit; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.regex.Pattern; | |||
import com.gitblit.utils.FileUtils; | |||
/** | |||
* Dynamically loads and reloads a properties file by keeping track of the last | |||
@@ -74,6 +78,24 @@ public class FileSettings extends IStoredSettings { | |||
return properties; | |||
} | |||
/** | |||
* Updates the specified settings in the settings file. | |||
*/ | |||
public synchronized boolean saveSettings(Map<String, String> settings) { | |||
String content = FileUtils.readContent(propertiesFile, "\n"); | |||
for (Map.Entry<String, String> setting:settings.entrySet()) { | |||
String regex = "(?m)^(" + regExEscape(setting.getKey()) + "\\s*+=\\s*+)" | |||
+ "(?:[^\r\n\\\\]++|\\\\(?:\r?\n|\r|.))*+$"; | |||
content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue()); | |||
} | |||
FileUtils.writeContent(propertiesFile, content); | |||
return true; | |||
} | |||
private String regExEscape(String input) { | |||
return input.replace(".", "\\."); | |||
} | |||
/** | |||
* @return the last modification date of the properties file | |||
*/ |
@@ -25,7 +25,6 @@ import java.lang.reflect.Field; | |||
import java.text.MessageFormat; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
@@ -253,9 +252,8 @@ public class GitBlit implements ServletContextListener { | |||
* @param settings | |||
* @return true if the update succeeded | |||
*/ | |||
public boolean updateSettings(Collection<SettingModel> settings) { | |||
// TODO update the settings | |||
return false; | |||
public boolean updateSettings(Map<String, String> updatedSettings) { | |||
return settings.saveSettings(updatedSettings); | |||
} | |||
public ServerStatus getStatus() { | |||
@@ -1326,7 +1324,7 @@ public class GitBlit implements ServletContextListener { | |||
// Read bundled Gitblit properties to extract setting descriptions. | |||
// This copy is pristine and only used for populating the setting | |||
// models map. | |||
InputStream is = servletContext.getResourceAsStream("/WEB-INF/gitblit.properties"); | |||
InputStream is = servletContext.getResourceAsStream("/WEB-INF/reference.properties"); | |||
BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is)); | |||
StringBuilder description = new StringBuilder(); | |||
SettingModel setting = new SettingModel(); |
@@ -17,6 +17,7 @@ package com.gitblit; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import org.slf4j.Logger; | |||
@@ -194,4 +195,14 @@ public abstract class IStoredSettings { | |||
public void overrideSetting(String key, String value) { | |||
overrides.put(key, value); | |||
} | |||
/** | |||
* Updates the values for the specified keys and persists the entire | |||
* configuration file. | |||
* | |||
* @param map | |||
* of key, value pairs | |||
* @return true if successful | |||
*/ | |||
public abstract boolean saveSettings(Map<String, String> updatedSettings); | |||
} |
@@ -191,7 +191,7 @@ public class RpcServlet extends JsonServlet { | |||
} else if (RpcRequest.EDIT_SETTINGS.equals(reqType)) { | |||
// update settings on the server | |||
if (GitBlit.getBoolean(Keys.web.enableRpcAdministration, false)) { | |||
Collection<SettingModel> settings = deserialize(request, response, | |||
Map<String, String> settings = deserialize(request, response, | |||
RpcUtils.SETTINGS_TYPE); | |||
GitBlit.self().updateSettings(settings); | |||
} else { |
@@ -15,7 +15,13 @@ | |||
*/ | |||
package com.gitblit; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileOutputStream; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.util.Enumeration; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import javax.servlet.ServletContext; | |||
@@ -32,8 +38,11 @@ public class WebXmlSettings extends IStoredSettings { | |||
private final Properties properties = new Properties(); | |||
private final ServletContext context; | |||
public WebXmlSettings(ServletContext context) { | |||
super(WebXmlSettings.class); | |||
this.context = context; | |||
Enumeration<?> keys = context.getInitParameterNames(); | |||
while (keys.hasMoreElements()) { | |||
String key = keys.nextElement().toString(); | |||
@@ -41,6 +50,17 @@ public class WebXmlSettings extends IStoredSettings { | |||
properties.put(key, decodeValue(value)); | |||
logger.debug(key + "=" + properties.getProperty(key)); | |||
} | |||
// apply any web-configured overrides | |||
File file = new File(context.getRealPath("/WEB-INF/web.properties")); | |||
if (file.exists()) { | |||
try { | |||
InputStream is = new FileInputStream(file); | |||
properties.load(is); | |||
is.close(); | |||
} catch (Throwable t) { | |||
logger.error("Failed to load web.properties setting overrides", t); | |||
} | |||
} | |||
} | |||
private String decodeValue(String value) { | |||
@@ -53,6 +73,33 @@ public class WebXmlSettings extends IStoredSettings { | |||
return properties; | |||
} | |||
@Override | |||
public synchronized boolean saveSettings(Map<String, String> settings) { | |||
try { | |||
Properties props = new Properties(); | |||
// load pre-existing web-configuration | |||
File file = new File(context.getRealPath("/WEB-INF/web.properties")); | |||
if (file.exists()) { | |||
InputStream is = new FileInputStream(file); | |||
props.load(is); | |||
is.close(); | |||
} | |||
// put all new settings and persist | |||
props.putAll(settings); | |||
OutputStream os = new FileOutputStream(file); | |||
props.store(os, null); | |||
os.close(); | |||
// override current runtime settings | |||
properties.putAll(settings); | |||
return true; | |||
} catch (Throwable t) { | |||
logger.error("Failed to save settings!", t); | |||
} | |||
return false; | |||
} | |||
@Override | |||
public String toString() { | |||
return "WEB.XML"; |
@@ -30,7 +30,6 @@ import com.gitblit.models.FederationSet; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.ServerSettings; | |||
import com.gitblit.models.ServerStatus; | |||
import com.gitblit.models.SettingModel; | |||
import com.gitblit.models.UserModel; | |||
import com.google.gson.reflect.TypeToken; | |||
@@ -45,7 +44,7 @@ public class RpcUtils { | |||
public static final Type NAMES_TYPE = new TypeToken<Collection<String>>() { | |||
}.getType(); | |||
public static final Type SETTINGS_TYPE = new TypeToken<Collection<SettingModel>>() { | |||
public static final Type SETTINGS_TYPE = new TypeToken<Map<String, String>>() { | |||
}.getType(); | |||
private static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() { |
@@ -16,6 +16,7 @@ | |||
package com.gitblit.tests; | |||
import java.io.IOException; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
@@ -23,6 +24,7 @@ import junit.framework.TestCase; | |||
import com.gitblit.Constants.AccessRestrictionType; | |||
import com.gitblit.GitBlitException.UnauthorizedException; | |||
import com.gitblit.Keys; | |||
import com.gitblit.models.FederationModel; | |||
import com.gitblit.models.FederationProposal; | |||
import com.gitblit.models.FederationSet; | |||
@@ -210,9 +212,33 @@ public class RpcTests extends TestCase { | |||
ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); | |||
assertTrue("No settings were retrieved!", settings != null); | |||
} | |||
public void testServerStatus() throws Exception { | |||
ServerStatus status = RpcUtils.getStatus(url, account, password.toCharArray()); | |||
assertTrue("No status was retrieved!", status != null); | |||
} | |||
public void testUpdateSettings() throws Exception { | |||
Map<String, String> updated = new HashMap<String, String>(); | |||
// grab current setting | |||
ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); | |||
boolean showSizes = settings.get(Keys.web.showRepositorySizes).getBoolean(true); | |||
showSizes = !showSizes; | |||
// update setting | |||
updated.put(Keys.web.showRepositorySizes, String.valueOf(showSizes)); | |||
boolean success = RpcUtils.updateSettings(updated, "http://localhost:8080/gb", account, | |||
password.toCharArray()); | |||
assertTrue("Failed to update server settings", success); | |||
// confirm setting change | |||
settings = RpcUtils.getSettings(url, account, password.toCharArray()); | |||
boolean newValue = settings.get(Keys.web.showRepositorySizes).getBoolean(false); | |||
assertEquals(newValue, showSizes); | |||
// restore setting | |||
newValue = !newValue; | |||
updated.put(Keys.web.showRepositorySizes, String.valueOf(newValue)); | |||
} | |||
} |