Back to index

plone3  3.1.7
URLTool.py
Go to the documentation of this file.
00001 from Products.CMFCore.URLTool import URLTool as BaseTool
00002 from Products.CMFPlone import ToolNames
00003 from AccessControl import ClassSecurityInfo
00004 from Globals import InitializeClass
00005 from Products.CMFPlone.PloneBaseTool import PloneBaseTool
00006 
00007 from urlparse import urlparse
00008 
00009 class URLTool(PloneBaseTool, BaseTool):
00010 
00011     meta_type = ToolNames.URLTool
00012     security = ClassSecurityInfo()
00013     toolicon = 'skins/plone_images/link_icon.gif'
00014 
00015     __implements__ = (PloneBaseTool.__implements__, BaseTool.__implements__, )
00016 
00017     security.declarePublic('isURLInPortal')
00018     def isURLInPortal(self, url, context=None):
00019         """ Check if a given url is on the same host and contains the portal
00020             path.  Used to ensure that login forms can determine relevant
00021             referrers (i.e. in portal).  Also return true for some relative urls
00022             if context is passed in to allow for url parsing. When context is
00023             not provided, assume that relative urls are in the portal. It is
00024             assumed that http://portal is the same portal as https://portal.
00025         """
00026         p_url = self()
00027         portal_path = urlparse(p_url)[0:3]
00028         url_path = urlparse(url)[0:3]
00029         p = {#'protocol':portal_path[0],
00030              'host':portal_path[1],
00031              'path':portal_path[2]}
00032         u = {#'protocol':url_path[0],
00033              'host':url_path[1],
00034              'path':url_path[2]}
00035         # check for urls without protocol (i.e. relative urls), or urls with
00036         # the same host and path.
00037         
00038         if not u['host'] and not u['path'].startswith('/'): #relatively relative url!
00039             #url is a relative path that needs to be checked. URLs that start with / can be quickly checked
00040             #urls that start with ../ need to have a bit of traversal
00041             if u['path'].startswith('.'):
00042                 if context is None:
00043                     return True #old behavior
00044                 else: #gentlemen, start your parsing engines
00045                     if not context.isPrincipiaFolderish:
00046                         useurl = context.aq_parent.absolute_url()
00047                     else:
00048                         useurl = context.absolute_url()
00049                     currpath = urlparse(useurl)[2].split('/') #just the path
00050                     for node in u['path'].split('/'): #path is something like "../../target"
00051                         if node == '..':
00052                             if currpath:
00053                                 currpath.pop()
00054                             else: #we have more ../ than in the current context, we can't be in the portal
00055                                 return False
00056                         elif node == '.':
00057                             continue
00058                         else: #We shouldn't have to deal with crazy urls like ../../somefolder/../otherfolder/../content
00059                             #add the current node to give us a bit more breathing room, in case somone was silly and used the name of the portal in the relative path
00060                             return ('/'.join(currpath)+'/'+node).startswith(p['path']) 
00061             else: #url is in the form: path/to/another/object.jpg
00062                 return True 
00063         else:
00064             return (p['host'] == u['host'] or not u['host']) and u['path'].startswith(p['path'])
00065 
00066 URLTool.__doc__ = BaseTool.__doc__
00067 
00068 InitializeClass(URLTool)