Code

- Add explicit "Search" permissions, see Security Fix below.
[roundup.git] / roundup / configuration.py
index 4fa4c942758698717493e3e29cb17e61bcb9d33f..8e42cef1418840d171bb0753449acaed89c17d7b 100644 (file)
@@ -370,7 +370,7 @@ class OctalNumberOption(Option):
 
 class NullableOption(Option):
 
-    """Option that is set to None if it's string value is one of NULL strings
+    """Option that is set to None if its string value is one of NULL strings
 
     Default nullable strings list contains empty string only.
     There is constructor parameter allowing to specify different nullables.
@@ -530,6 +530,13 @@ SETTINGS = (
             "stop-words (eg. A,AND,ARE,AS,AT,BE,BUT,BY, ...)"),
         (OctalNumberOption, "umask", "02",
             "Defines the file creation mode mask."),
+        (IntegerNumberOption, 'csv_field_size', '131072',
+            "Maximum size of a csv-field during import. Roundups export\n"
+            "format is a csv (comma separated values) variant. The csv\n"
+            "reader has a limit on the size of individual fields\n"
+            "starting with python 2.5. Set this to a higher value if you\n"
+            "get the error 'Error: field larger than field limit' during\n"
+            "import."),
     )),
     ("tracker", (
         (Option, "name", "Roundup issue tracker",
@@ -551,6 +558,11 @@ SETTINGS = (
             "or LANG, in that order of preference."),
     )),
     ("web", (
+        (BooleanOption, "allow_html_file", "no",
+            "Setting this option enables Roundup to serve uploaded HTML\n"
+            "file content *as HTML*. This is a potential security risk\n"
+            "and is therefore disabled by default. Set to 'yes' if you\n"
+            "trust *all* users uploading content to your tracker."),
         (BooleanOption, 'http_auth', "yes",
             "Whether to use HTTP Basic Authentication, if present.\n"
             "Roundup will use either the REMOTE_USER or HTTP_AUTHORIZATION\n"
@@ -592,8 +604,14 @@ SETTINGS = (
         (NullableOption, 'read_default_group', 'roundup',
             "Name of the group to use in the MySQL defaults file (.my.cnf).\n"
             "Only used in MySQL connections."),
+        (IntegerNumberOption, 'sqlite_timeout', '30',
+            "Number of seconds to wait when the SQLite database is locked\n"
+            "Default: use a 30 second timeout (extraordinarily generous)\n"
+            "Only used in SQLite connections."),
+        (IntegerNumberOption, 'cache_size', '100',
+            "Size of the node cache (in elements)"),
     ), "Settings in this section are used"
-        " by Postgresql and MySQL backends only"
+        " by RDBMS backends only"
     ),
     ("logging", (
         (FilePathOption, "config", "",
@@ -711,6 +729,10 @@ SETTINGS = (
             "will match an issue for the interval after the issue's\n"
             "creation or last activity. The interval is a standard\n"
             "Roundup interval."),
+        (BooleanOption, "subject_updates_title", "yes",
+            "Update issue title if incoming subject of email is different.\n"
+            "Setting this to \"no\" will ignore the title part of"
+            " the subject\nof incoming email messages.\n"),
         (RegExpOption, "refwd_re", "(\s*\W?\s*(fw|fwd|re|aw|sv|ang)\W)+",
             "Regular expression matching a single reply or forward\n"
             "prefix prepended by the mailer. This is explicitly\n"
@@ -726,6 +748,10 @@ SETTINGS = (
             "Regular expression matching end of line."),
         (RegExpOption, "blankline_re", r"[\r\n]+\s*[\r\n]+",
             "Regular expression matching a blank line."),
+        (BooleanOption, "unpack_rfc822", "no",
+            "Unpack attached messages (encoded as message/rfc822 in MIME)\n"
+            "as multiple parts attached as files to the issue, if not\n"
+            "set we handle message/rfc822 attachments as a single file."),
         (BooleanOption, "ignore_alternatives", "no",
             "When parsing incoming mails, roundup uses the first\n"
             "text/plain part it finds. If this part is inside a\n"
@@ -874,7 +900,7 @@ class Config:
             _options.append(_name)
         # (section, name) key is used for writing .ini file
         self.options[(_section, _name)] = option
-        # make the option known under all of it's A.K.A.s
+        # make the option known under all of its A.K.A.s
         for _name in option.aliases:
             self.options[_name] = option
 
@@ -1235,6 +1261,14 @@ class CoreConfig(Config):
         if home_dir is None:
             self.init_logging()
 
+    def copy(self):
+        new = CoreConfig()
+        new.sections = list(self.sections)
+        new.section_descriptions = dict(self.section_descriptions)
+        new.section_options = dict(self.section_options)
+        new.options = dict(self.options)
+        return new
+
     def _get_unset_options(self):
         need_set = Config._get_unset_options(self)
         # remove MAIL_PASSWORD if MAIL_USER is empty
@@ -1264,8 +1298,8 @@ class CoreConfig(Config):
             return
 
         _file = self["LOGGING_FILENAME"]
-        # set file & level on the root logger
-        logger = logging.getLogger()
+        # set file & level on the roundup logger
+        logger = logging.getLogger('roundup')
         if _file:
             hdlr = logging.FileHandler(_file)
         else:
@@ -1274,6 +1308,9 @@ class CoreConfig(Config):
             '%(asctime)s %(levelname)s %(message)s')
         hdlr.setFormatter(formatter)
         # no logging API to remove all existing handlers!?!
+        for h in logger.handlers:
+            h.close()
+            logger.removeHandler(hdlr)
         logger.handlers = [hdlr]
         logger.setLevel(logging._levelNames[self["LOGGING_LEVEL"] or "ERROR"])