Possible bug with user_signature?

78 views
Skip to first unread message

Bruce Wade

unread,
Feb 22, 2012, 6:19:04 PM2/22/12
to web...@googlegroups.com
When using user_signature=True in a form that action goes to another method and that method has @auth.requires_signature I am getting access denied, if I remove the @auth.requires_signature I still see the signature but don't have the access denied message.

FORM: 
# adviewer.viewads();

locationform=FORM(
        DIV(
            SELECT(countries_options,_id='by-country',_name='country', _onchange="updateProvinces(this)", value=selected_country),
            _id='country_options', _class='filter-selects'    
        ),
        DIV(
            SELECT(provinces_options,_id='by-province', _name='province_state',_onchange="updateCities(this)", value=selected_province),        
            _id='province_options', _class='filter-selects' 
        ),
        DIV(SELECT(
            cities_options,_id='by-province', _name='city', value=selected_city),
            _id='city_options', _class='filter-selects' 
        ),
        DIV(_class='clear'),
        INPUT(_type='submit', _value='Save', _class='filter-btn'),
        _name='locationform',
        _action=URL('adviewer','savesettings/location', user_signature=True)
    )

Capture Method:
# adviewer.savesettings()
@auth.requires_login()
@auth.requires_signature()  # If I remove this there is no access denied.
def savesettings():
    print request.vars
    print request.args(0)
    from youadAPI.adviewer_api import AdViewerEngine
    if request.args(0) == 'location':
        adviewer_engine.update_or_create_adviewer_settings(
            AdViewerEngine.location, 
            dict(
                 country=request.vars['country'], 
                 province=request.vars['province_state'],
                 city=request.vars['city']
            )
        )
    elif request.args(0) == 'language':
        adviewer_engine.update_or_create_adviewer_settings(
            AdViewerEngine.language,
            dict(
                language = request.vars['language']
            )                                             
        )
    elif request.args(0) == 'keywords':
        adviewer_engine.update_or_create_adviewer_settings(
            AdViewerEngine.keywords,
            dict(
                keywords = request.vars['keywords'] 
            )
        )

--
--
Regards,
Bruce Wade
http://ca.linkedin.com/in/brucelwade
http://www.wadecybertech.com
http://www.warplydesigned.com
http://www.fitnessfriendsfinder.com

Bruce Wade

unread,
Feb 27, 2012, 1:22:25 PM2/27/12
to web...@googlegroups.com
Ok it looks like the bug is related to:

URL('action/additional_parms', user_signature=True) if you have something in addition to the action @auth.requires_signature fails.

When using: FORM(_action=URL('adviewer','savesettings/location', user_signature=True)) or redirect(URL('payment/%s' % has_unpaid_orders.access_key, user_signature=True)) with @auth.requires_signature() on the action it fails with access denied. 

Massimo Di Pierro

unread,
Feb 27, 2012, 2:31:55 PM2/27/12
to web2py-users
Is the user logged in? If the user is not logged in this is the
intended behavior.

Massimo
> // URL submitted to this method:http://127.0.0.1:8000/zh/adviewer/savesettings/location?_signature=82...

Anthony

unread,
Feb 27, 2012, 3:07:03 PM2/27/12
to web...@googlegroups.com
In

URL('adviewer', 'savesettings/location', user_signature=True)

the URL() function sees function='savesettings/location' and args=None. However, when a request is made to the URL generated by the above, the function that verifies the signature sees function='savesettings' and args='location'. The problem is, function='savesettings' and args='location' does not generate the same signature as function='savesettings/location' and args=None. The reason is that when generating the signature, the extension is first added to the function before concatenating the args, so when the signature is first generated, it is a hash of a URL that includes "/savesettings/location.html", but when verified, the signature is a hash of a URL that includes "/savesettings.html/location". Therefore, the hashes won't match because they are created from different strings.

Is there any reason you are using the above rather than:

URL('adviewer', 'savesettings', args='location', user_signature=True) 

which is really the correct way to use the URL() function? If you explicitly specify "location" as the args argument to URL(), I think it should work.

Anthony

Bruce Wade

unread,
Feb 27, 2012, 3:46:14 PM2/27/12
to web...@googlegroups.com
User is logged in, it works on other URLs.

Anthony, thanks for explaining how URL works, changing the URL to use args has solved the problem.

Massimo Di Pierro

unread,
Feb 27, 2012, 5:58:07 PM2/27/12
to web2py-users
I am treating this as a bug. now fixed in trunk.
> >>http://127.0.0.1:8000/zh/adviewer/savesettings/location?_signature=82...

Bruce Wade

unread,
Feb 27, 2012, 6:23:59 PM2/27/12
to web...@googlegroups.com
Thanks 
Reply all
Reply to author
Forward
0 new messages