Excellent, Thank you both Adam and Christopher.  I appreciate you taking the
time to write out a detailed explanation.
" files = get_files(user.static_dir) "

Q1. so this is pulling from the User model, so would I add another field to
the model which holds the static_dir?

Q2. Do I have to manually serve files through CP?  Is there a way for CP to
just serve up anything that's not a .py or .kid source file as a
downloadable file?  Would save some time, however the method you provided
would definitely work and I would have more flexibility with individual
files that way as well.
What I'm most interested in is that anything under /Users/$username/files/
are all static files which are downloadable.  I just want to make sure
$username matches "identity.current.user" correct?

Thanks again!

-----Original Message-----
From: [email protected] [mailto:[EMAIL PROTECTED] On
Behalf Of Christopher Arndt
Sent: Monday, January 01, 2007 8:38 PM
To: [email protected]
Subject: [TurboGears] Re: Securing Resources


Adam Jones schrieb:
There is only a slight problem though, we wanted to use
"http://www.example.com/$username"; as the url, not /sample. To solve
this you should probably look into CherryPy filters, which are designed
for this sort of thing.

I don't think that you need filters for this. If URLs like the following are ok:

http://myserver.com/users/foo
http://myserver.com/users/foo/files/myfile

then you could do the following (untested):

- Code a secured subcontroller like Adam suggested that checks that the user is not anonymous.

- Mount this subcontroller in your root controller:

    class Root(controllers.RootController):
        users = UsersController()

- Make the subcontroller have a default method like this:

    @expose(template='your.template.here')
    def default(self, user_name, *args, **kwargs):
        if args:
            action = getattr(self, args[0], None)
            if not action or not getattr(action, 'exposed'):
                raise cherrypy.NotFound
            return action(user_name, *args[1:], **kwargs)
        # else
        user = identity.current.user
        if user_name != user.user_name:
            raise IdentityFailure(['Wrong user name'])
        # Your User object stores the file system location of the static
        # files for the user. 'get_files' finds all files under this
        # directory and returns a list of 'File' objects
        files = get_files(user.static_dir)
        return dict(files=files)

- In your template for the above method, list all files and link them to the method to retrieve the file, e.g.:

    <li py:for="file in files">
<a href="$tg.url('/users/%s/files/%s' % (file.user, file.name))">$file.name</a>
    </li>

- In the subcontroller, add another method to retrieve a file for a user:

    @expose()
    def files(self, user_name, file_name):
        user = identity.current.user
        # 'get_file' finds a user's file and returns a 'File' object
        file = get_file(user, file_name)
        if file.user.id != user.id:
            raise IdentityFailure(['Not your file'])
        cherrypy.serve_file(file.path, file.mimetype)


This assumes that your model defines a class "File" that provides the following attributes:

user - reference to the user owning the file
name - the basename of the file
path - the pathname of the file on the server
mimetype - the MIME type of the file

This doesn't necessarily have to come from the database, you could also create the instances of File by reading the contents of a directory.


Of course, you also have to add a few validators to catch wrong/missing user or file names etc.

HTH, Chris


--
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.432 / Virus Database: 268.16.1/611 - Release Date: 12/31/2006
12:47 PM


--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.5.432 / Virus Database: 268.16.1/611 - Release Date: 12/31/2006
12:47 PM



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to