# Buggy code
def get_config(self, key=None, default=None, role="admin", return_bool=False):
    """
    :param key: A key to retrieve
    :type key: string
    :param default: The default value, if it does not exist in the database
    :param role: The role which wants to retrieve the system config. Can be
        "admin" or "public". If "public", only values with type="public"
        are returned.
    :type role: string
    :param return_bool: If the a boolean value should be returned. Returns
        True if value is "True", "true", 1, "1", True...
    :return: If key is None, then a dictionary is returned. If a certain key
        is given a string/bool is returned.
    """
    default_true_keys = [
        SYSCONF.PREPENDPIN,
        SYSCONF.SPLITATSIGN,
        SYSCONF.INCFAILCOUNTER,
        SYSCONF.RETURNSAML,
    ]

    r_config = {}

    # reduce the dictionary to only public keys!
    reduced_config = {}
    for ckey, cvalue in self.config.iteritems():
        if role == "admin" or cvalue.get("Type") == "public":
            reduced_config[ckey] = self.config[ckey]
    if not reduced_config and role == "admin":
        reduced_config = self.config

    for ckey, cvalue in reduced_config.iteritems():
        if cvalue.get("Type") == "password":
            # decrypt the password
            r_config[ckey] = decryptPassword(cvalue.get("Value"))
        else:
            r_config[ckey] = cvalue.get("Value")

    for t_key in default_true_keys:
        if t_key not in r_config:
            r_config[t_key] = "True"

    if key:
        # We only return a single key
        r_config = r_config.get(key, default)

    if return_bool:
        if isinstance(r_config, bool):
            pass
        if isinstance(r_config, int):
            r_config = r_config > 0
        if isinstance(r_config, basestring):
            r_config = is_true(r_config.lower())

    return r_config


# Traceback (UnicodeDecodeError)
[2018-08-14 14:49:53,123] ERROR in app: Exception on /system/documentation [GET]
Traceback (most recent call last):
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/lib/prepolicy.py", line 120, in policy_wrapper
return wrapped_function(*args, **kwds)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/auth.py", line 316, in decorated_function
return f(*args, **kwargs)
File "/home/fred/privacyidea/privacyidea/privacyidea/api/system.py", line 113, in get_config_documentation
context=context))
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/templating.py", line 135, in render_template
context, ctx.app)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/flask/templating.py", line 117, in _render
rv = template.render(context)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/home/fred/privacyidea/privacyidea/venv/lib/python2.7/site-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/fred/privacyidea/privacyidea/privacyidea/static/templates/documentation.rst", line 56, in top-level template code
{{k}}: **{{v}}**
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)

# Fixed code
def get_config(self, key=None, default=None, role="admin", return_bool=False):
    """
    :param key: A key to retrieve
    :type key: string
    :param default: The default value, if it does not exist in the database
    :param role: The role which wants to retrieve the system config. Can be
        "admin" or "public". If "public", only values with type="public"
        are returned.
    :type role: string
    :param return_bool: If the a boolean value should be returned. Returns
        True if value is "True", "true", 1, "1", True...
    :return: If key is None, then a dictionary is returned. If a certain key
        is given a string/bool is returned.
    """
    default_true_keys = [
        SYSCONF.PREPENDPIN,
        SYSCONF.SPLITATSIGN,
        SYSCONF.INCFAILCOUNTER,
        SYSCONF.RETURNSAML,
    ]

    r_config = {}

    # reduce the dictionary to only public keys!
    reduced_config = {}
    for ckey, cvalue in self.config.iteritems():
        if role == "admin" or cvalue.get("Type") == "public":
            reduced_config[ckey] = self.config[ckey]
    if not reduced_config and role == "admin":
        reduced_config = self.config

    for ckey, cvalue in reduced_config.iteritems():
        if cvalue.get("Type") == "password":
            # decrypt the password
            r_config[ckey] = decryptPassword(cvalue.get("Value"), convert_unicode=True)
        else:
            r_config[ckey] = cvalue.get("Value")

    for t_key in default_true_keys:
        if t_key not in r_config:
            r_config[t_key] = "True"

    if key:
        # We only return a single key
        r_config = r_config.get(key, default)

    if return_bool:
        if isinstance(r_config, bool):
            pass
        if isinstance(r_config, int):
            r_config = r_config > 0
        if isinstance(r_config, basestring):
            r_config = is_true(r_config.lower())

    return r_config