Issue Details (XML | Word | Printable)

Key: MODPYTHON-43
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Graham Dumpleton
Reporter: Graham Dumpleton
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
mod_python

mod_python.publisher auth functions access to globals

Created: 03/Apr/05 10:51 AM   Updated: 02/Apr/07 11:17 AM
Return to search
Component/s: publisher
Affects Version/s: 3.1.4
Fix Version/s: 3.3.1

Time Tracking:
Not Specified

File Attachments:
  Size
File Licensed for inclusion in ASF works grahamd_20060224_MP43_1.diff 2006-02-24 07:35 AM Graham Dumpleton 1 kB

Resolution Date: 07/Mar/06 09:39 AM


 Description  « Hide
In the mod_python.publisher code, the code for performing basic authentication
has in a few spots code of the form:

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, globals())
                found_auth = 1

What this does is that if the target of the request is a function and that function
contains a nested function, which in this case is called "__auth__", then that
nested function is turned into a callable object and is subsequently called to
determine if the user is able to perform the request.

In making the nested function callable, it uses "globals()". By using this though
it is using the globals from the mod_python.publisher module and not the
module which the nested function is contained within. This means that the
following code will actually fail.

  import xxx

  def function(req):

    def __auth__(req,username,password):
      return xxx.auth(req,username,password)

This is because the module "xxx" imported at global scope within the module isn't
available to the nested function when it is called as it is seeing the globals of
mod_python.publisher instead. To get around the problem, the import has to be
local to the nested function.

  def function(req):

    def __auth__(req,username,password):
      import xxx
      return xxx.auth(req,username,password)

Since in this case the auth function being called is a nested function, we know that
we can actually grab the globals for the correct module by getting "func_globals"
from the enclosing function.

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, object.func_globals)
                found_auth = 1

Ie., instead of "globals()", use "object.func_globals" where "object is the enclosing
function object.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Graham Dumpleton made changes - 24/Feb/06 07:35 AM
Field Original Value New Value
Attachment grahamd_20060224_MP43_1.diff [ 12323342 ]
Graham Dumpleton made changes - 05/Mar/06 03:41 PM
Fix Version/s 3.3 [ 12310101 ]
Environment
Description In the mod_python.publisher code, the code for performing basic authentication
has in a few spots code of the form:

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, globals())
                found_auth = 1

What this does is that if the target of the request is a function and that function
contains a nested function, which in this case is called "__auth__", then that
nested function is turned into a callable object and is subsequently called to
determine if the user is able to perform the request.

In making the nested function callable, it uses "globals()". By using this though
it is using the globals from the mod_python.publisher module and not the
module which the nested function is contained within. This means that the
following code will actually fail.

  import xxx

  def function(req):

    def __auth__(req,username,password):
      return xxx.auth(req,username,password)

This is because the module "xxx" imported at global scope within the module isn't
available to the nested function when it is called as it is seeing the globals of
mod_python.publisher instead. To get around the problem, the import has to be
local to the nested function.

  def function(req):

    def __auth__(req,username,password):
      import xxx
      return xxx.auth(req,username,password)

Since in this case the auth function being called is a nested function, we know that
we can actually grab the globals for the correct module by getting "func_globals"
from the enclosing function.

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, object.func_globals)
                found_auth = 1

Ie., instead of "globals()", use "object.func_globals" where "object is the enclosing
function object.
In the mod_python.publisher code, the code for performing basic authentication
has in a few spots code of the form:

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, globals())
                found_auth = 1

What this does is that if the target of the request is a function and that function
contains a nested function, which in this case is called "__auth__", then that
nested function is turned into a callable object and is subsequently called to
determine if the user is able to perform the request.

In making the nested function callable, it uses "globals()". By using this though
it is using the globals from the mod_python.publisher module and not the
module which the nested function is contained within. This means that the
following code will actually fail.

  import xxx

  def function(req):

    def __auth__(req,username,password):
      return xxx.auth(req,username,password)

This is because the module "xxx" imported at global scope within the module isn't
available to the nested function when it is called as it is seeing the globals of
mod_python.publisher instead. To get around the problem, the import has to be
local to the nested function.

  def function(req):

    def __auth__(req,username,password):
      import xxx
      return xxx.auth(req,username,password)

Since in this case the auth function being called is a nested function, we know that
we can actually grab the globals for the correct module by getting "func_globals"
from the enclosing function.

            if "__auth__" in func_code.co_names:
                i = list(func_code.co_names).index("__auth__")
                __auth__ = func_code.co_consts[i+1]
                if hasattr(__auth__, "co_name"):
                    __auth__ = new.function(__auth__, object.func_globals)
                found_auth = 1

Ie., instead of "globals()", use "object.func_globals" where "object is the enclosing
function object.
Assignee Graham Dumpleton [ grahamd ]
Graham Dumpleton made changes - 05/Mar/06 03:46 PM
Status Open [ 1 ] In Progress [ 3 ]
Graham Dumpleton made changes - 07/Mar/06 09:39 AM
Resolution Fixed [ 1 ]
Status In Progress [ 3 ] Resolved [ 5 ]
Graham Dumpleton made changes - 02/Apr/07 11:17 AM
Status Resolved [ 5 ] Closed [ 6 ]