I am answering myself:

I found a workaround. Thanks, pbreit, for pointing me the right
direction.

In the read_document function I put customized download url:
#--- cut ---
@auth.requires_login()
def read_document():
    """Read form for one document"""

    #Customize download function
    crud.settings.download_url = URL('download_check_permission')

    #Get readonly form
    form = crud.read(db.uploads,request.args(0))
    return dict(form=form)
#--- cut ---

In the customized download I am finding the table name and field name
in question, I am selecting the record.id with accessible_query(...)
and if the user has no read permissions, I return 'Error: Access
denied'
#--- cut ---
@auth.requires_login()
def download_check_permission():
    """Special download function with read permission checks"""

    #Find the table and field names by splitting the requested file
name
    filename_split = request.args(0).split(".")
    tablename = filename_split[0]
    fieldname = filename_split[1]

    #Select the record.id
    # - if the user has read permissions, the record will be selected
    # - if the user has no permissions, record = None
    table = db[tablename]
    field = table[fieldname]
    query = auth.accessible_query('read', table, auth.user.id) &
(field == request.args(0))
    record = db(query).select(table.id)

    #Return error if no read permissions
    if not record:
        return "Error: Access denied"

    #Return the file if reached here
    return response.download(request,db)
#--- cut ---

Cheers,
TTT

On Aug 8, 9:24 pm, Todor Todorov <[email protected]>
wrote:
> Thanks, pbreit, for the answer!
> Actually each record in the table has different read permissions: some
> of them could be read by one user, others by other users.
>
> For the fields, other than 'upload' type the web2py authorization
> scheme works fine, but unfortunately for 'upload' field type -
> according to the documentation - the only way is to set a function for
> db.<table_name>.<field_name>.authorization = <lambda_with_auth_code>.
> In my case the lambda function is not working.
>
> Is there any way to find the tablename.fieldname (in my case
> uploads.document) and the requested record id within the download
> function?
> This way I could check the current user permissions against the
> particular record id.
>
> On Aug 8, 8:01 pm, pbreit <[email protected]> wrote:
>
> > If you want to password protect the download, you need to decorate it:
>
> > @auth.requires_login()
> > def download():
> >     ...
>
> > If you want to make sure only the owner can download it, you would need some
> > additional code (db.uploads.created_by==auth.user_id).
>
>

Reply via email to