Signed URLs - is this understanding correct?

143 views
Skip to first unread message

lyn2py

unread,
Jul 27, 2012, 11:00:23 AM7/27/12
to web...@googlegroups.com
I want to create a protected folder containing file uploads, which can only be accessed selectively (different set of files for different users, depending on their permissions).

They should not be able to access it even if they have the direct link.

Can I (or should I) do this using digitally signed urls?
Or is there a better way about it?


Massimo Di Pierro

unread,
Jul 27, 2012, 11:55:24 AM7/27/12
to web...@googlegroups.com
No this is not what signed urls are for. Signed urls are for delegating access control from one controller action to another. Consider this code:

@auth.requires_membership('admin'):
def index()
    link = URL('other')
    return dict(link=link)

@auth.requires_membership('admin'):
def other():
    return dict(message='hello world')

Both actions requires the same membership (group "admin"). So if a user that follows the link, the membership is checked twice. For more complex rules this can be time consuming. Signed url simplify the process:

@auth.requires_membership('admin'):
def index()
    link = URL('other',user_signature=True) #1
    return dict(link=link)

@auth.requires_signature()  #2
def other():
    return dict(message='hello world')

This mean the index() action degenerates a one time link that only works for this one user within this one session. Only this user within this one session can access the "other" action by following the link. the link will be different for another user. If the user logs out or somebody steals it, the link does not use it. This is the same as:

What you need is different. What you need depends on how the files got in that folder. If they were uploaded using

db.define_table(...Field('file','upload')...)

then you simply need to set 

db.define_table(...Field('file','upload',authorize=lambda row: auth.has_permission('download','file'))...)

if these are stati files that you create server side then you need your own controller:

@auth.has_permission('download','file'))
def getfile():
     return response.stream(open(os.path.join('/location/',request.args(0)))

This assumes your users are members of a group (for example 'downloaders') and this group has permission to 'download', 'file'. You can create the group and the permission entry using appadmin.

Massimo

lyn2py

unread,
Jul 28, 2012, 10:16:38 PM7/28/12
to web...@googlegroups.com
Thank you Massimo, very clear. I will try the code now!
Reply all
Reply to author
Forward
0 new messages