6 Replies Latest reply on Sep 15, 2009 4:31 PM by Adam Cameron.

    Tell which template called cfinclude

    Dinghus Level 1

      Is it possible to tell what template did a cfinclude?

       

      What I'm looking at is a client asked to put security on his site (after the fact). The person who built it used a low end switch box type framework.

       

      Ie cfswitch to determine what templates to include.

       

      Now the problem comes in that you can navigate to any of those pages that are cfincluded bypassing the whole framework. The security was a very basic check of the access rights at the switch level.

       

      So something like this:

       

      <cfswitch expression="#TRIM(session.clearance)#">
      <cfcase value="S">
        <cfinclude template="supervisorHome.cfm">
      </cfcase>

      <cfcase value="A">

           <cfinclude template="adminHome.cfm">

      </cfcase>

      .

      .

      .

      </cfswitch>

       

      But I can go to adminHome.cfm directly and no problem. Client says I can not change the way it is built but I need to make it so the visitor is forced to go through the framework. My guess is to go in the onRequestStart in the Application.cfc and see if the page request is NOT index.cfm, then make it so. But of course this means all the cfincluded pages will also go to the index.cfm page. I tried throwing in a flag saying to only go to the index.cfm page if the flag was not set. The flag being set on the initial request to true and then when the index template finishes loading it gets set to false.

       

      Not working. So now I'm thinking if I can see the top most request page then I can do logic against that.

        • 1. Re: Tell which template called cfinclude
          Adam Cameron. Level 5

          Is it possible to tell what template did a cfinclude?

           

          Yep. But I'll get back to the answer to this after I address something else you say...

           

          My guess is to go in the onRequestStart in the Application.cfc and see if the page request is NOT index.cfm, then make it so. But of course this means all the cfincluded pages will also go to the index.cfm page.

          I don't follow here.  The act of including a file is part of the request already running, it does not make it's own request, so whatever is in onRequestStart() is irrelevant.

           

          So there should not be a problem here.

           

          Also re this:

           

          But I can go to adminHome.cfm directly and no problem.

          OK, so the problem here is that files that are only intended to be included are in some directory that is web browseable.  They probably shouldn't be.  Only files that are intended to be web browseable should be made so.

           

          Your app could be structured thus:

           

          /cfroot

               /webroot

                    index.cfm

                    /js

                    /images

                    /css

               /inc

                    /admin

                         home.cfm

           

          Where /webroot has files in it that need to be web browseable, and /inc is [i]not[/i] web browseable.

           

          I suspect you've just got all your files together in the one (web browseable) directory.

           

           

          Now.  To answer your original question. There is getBaseTemplatePath() (http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_e-g_31.html#1104820) which will get the absolute top-level file initially called (which shoudl be index.cfm, in your requirement).  However if one ever has a template third.cfm which is included by second.cfm which is itslef included by index.cfm, then if you call getbaseTemplatePath() from third.cfm, you'll get index.cfm.  This is fine for you, but if - say - you wanted to find out which template included third.cfm, there's no built-in function to do this.

           

          However one can leverage Java to get this info.  If one creates an instance of java.lang.Exception, then one can access the tagContext array to pull out the full sequence of files executed "upstream" from the the in which the exception was created.

           

          --

          Adam

          • 2. Re: Tell which template called cfinclude
            GArlington Level 1

            As A Cameron mentioned the onRequestStart method will be called only once per request, your includes are parts of the same request, so you can do what you intended...

            Better still (again as he mentioned) move all includes outside webroot too...

            • 3. Re: Tell which template called cfinclude
              Dinghus Level 1

              This is not right as anyone who has had a run away request knows. If I

              cfinclude a template it also does its own request. Maybe that isn't how

              it is supposed to work but I've made that mistake before and suddenly

              ended up with a never ending loop of cfincludes etc.

              Try it. But I'm sure there has to be a way of doing it that won't let it

              run away. Something that says "don't reload the index page on every

              cfinclude call".

              No. They are not all in the same folder. BUT I can't change the folders

              or anything like that anyway. I have to work with what is there already.

              I could go to each page and add in a check to see if they have the

              proper permissions to view it, but that is soooo cumbersome.

              • 4. Re: Tell which template called cfinclude
                ilssac Level 5

                It is, of course, possible to make a never ending, runaway request by creating an infinite <cfinclude...> loop.  File a includes file b which includes file a, etc.  But each <cfinclude....> operation does NOT start a new request.  The onRequestStart() function will only fire once, not once for every <cfinclude....> operation.

                • 5. Re: Tell which template called cfinclude
                  GArlington Level 1

                  OK,

                  just tried it...

                   

                  Added line

                  <cflog file="requestLog" type="information" text="Session #session.SessionID# onRequestStart(#targetPage#).">

                  to onRequestStart

                   

                  The result - only index.cfm is logged as target page (and I am using ColdBox framework which is VERY heavy on <cfinclude > usage)...

                  • 6. Re: Tell which template called cfinclude
                    Adam Cameron. Level 5

                    This is not right

                     

                    In finest panto form: "ooh yes it is!"

                     

                    If I

                    cfinclude a template it also does its own request.

                    No, it does not.  You do not seem to understand what the concept of a "request" is, in this context.  That is fine, but I assure you I do know what I am talking about here.

                     

                    See Ian's reply to this for further detail.

                     

                    --

                    Adam