On 1/3/06, Mike Pirnat <[EMAIL PROTECTED]> wrote:
>
> > +1 on pure Python configs.  They aren't much more complicated but are
> > way more flexible.  We just have to be careful that we don't start
> > seeing listcomps in them ;-)
>
> I love having configs that are pure Python as they make life
> tremendously simple in many ways... But they do open up some
> interesting security issues that will mean you want to be slightly
> more paranoid than usual (depending on implementation of course).
> Anything that gets imported or execed in order to get loaded into your
> app has the possibility of executing code that might make you very
> unhappy, if, say, a bad guy dropped a new config file into place while
> you weren't looking.
>
> Of course, if bad guys are on your box, you probably have multiple
> other problems to worry about. ;-)

If attackers can change a devcfg.py script, they could have changed a
dev.cfg script (say, to use /etc/passwd as a sqlite database). If
they've gotten that far, either you left your webapp world-writable,
or they have root on your box. Either way, you're about to experience
a world of pain anyway, and having config files not be .py files isn't
going to lessen your pain.

Other than black hats rooting your box, the main thing that might
cause pain for unwary developers is if they do something with side
effects in their config. Yes, any experienced Python programmer will
tell you that doing something with side effects on import is a bad
idea, but some people do it anyway. (I've been guilty of it myself in
the past; if I had to rewrite that app now, I'd certainly do it
differently). It might not be a bad idea to put a warning in the
config docs about that. "Warning: this file gets imported from all
over the place, including inside tg-admin. Don't do anything with
side-effects in here, because you can really cause yourself some
serious pain if you do."

Paranoia aside, though, I'm +1 on this.

Question: How do we get this thing in more-or-less declarative format?
I'd like to be able to write:

    sqlobject.dburi = "sqlite:///my/database"

instead of:

    set_option("sqlobject.dburi", "sqlite:///my/database")

One way I can think of to do this is to have a special module (or
package) that the config files would import, which could set up magic
objects with the right names (sqlobject, autoreload, tg, kid) whose
setattr() functions would then set the options. The configmagic module
could also have a couple of helper functions for defining new
settings. For example:

    from configmagic import *
    sqlobject.dburi = "sqlite:///my/database"
    myconfig = new_config_section()
    myconfig.spam = "eggs"
    settings_for_uri("/admin")
    tg.allow_json = True
    settings_for_uri("/")
    tg.allow_json = False

I don't quite know how the settings_for_uri() would work. You might
need to make it a decorator and put each URI's settings into a
function, thus:

    from configmagic import *
    @settings_for_uri("/admin")
    def admin_settings():  # Function name wouldn't matter
        tg.allow_json = True
    @settings_for_uri("/")
    def main_settings():
        tg.allow_json = False

That's all I can come up with for now. I'll post other ideas later if
I have 'em.

--
Robin Munn
[EMAIL PROTECTED]
GPG key 0xD6497014

Reply via email to