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