Home directory for Malawi's wwwroot
Duncan Ewan
2021-02-19 3e758c29e0fde36fc088efcfc88f9a3014432b64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
<!--- 
* Copyright 2003-2006 Adobe Macromedia Software LLC. All rights reserved.
--->
<cfcomponent>
<cfsetting enablecfoutputonly="yes" showdebugoutput="no">
 
    <!--- where we store our data in the server scope --->
    <cfset CACHE_ROOT = "cfc">
    <!--- cache time out in minutes --->
    <cfset CACHE_TIMEOUT = 30>
    <!--- do we even use the cache? --->
    <cfset CACHE_ENABLED = TRUE>
    
    <cfinclude template="cfcexplorer_utils.cfm">
 
    <cffunction name="getComponentRoots" returnType="array" access="remote"
        hint="Returns array of component root directories. Each root directory is specified by its physical path using forward slashes a no trailing slash.">
 
        <cfscript>
            var authorizedFolders = "";
            var file = "";
            
            factory = CreateObject("java", "coldfusion.server.ServiceFactory");
            runtime = factory.getRuntimeService();
            security = factory.getSecurityService();
            customTagRoots = runtime.getCustomtags();
            mappings = runtime.getMappings() ;
                        
            roots = ArrayNew(1) ;
            
            // add first all cf virtual directories in descendent order, this will
            // help preserve resolution precedence
            skipWebroot = false ;
            virtualDirs = StructKeyArray(mappings) ;
            ArraySort( virtualDirs, "TEXTNOCASE", "DESC" ) ;
            for ( i=1; i lte ArrayLen(virtualDirs); i=i+1 ) {
                prefix = NormalizePath( virtualDirs[i] );
                prefix = Replace( prefix, '/', '.', 'ALL' ) ;
                if ( Find( '.', prefix ) eq 1 )
                    prefix = RemoveChars( prefix, 1, 1 ) ;
                if ( prefix eq '' and not skipWebroot )
                    skipWebroot = true ;
            
                root = StructNew() ;
                root.prefix = prefix  ;
                root.physicalPath = NormalizePath( mappings[virtualDirs[i]] ) ;
                // for multiuser logins, check if the current user has access to folders
                if(security.isSandboxSecurityEnabled())
                {
                    if(hasAccessToFolder(root.physicalPath))
                    {
                        ArrayAppend(roots, root);
                    }
                }
                else
                {
                    ArrayAppend(roots,root);
                }
                
            }
            
            // add webroot
            if ( not skipWebroot ) {
                temp = 'abcdefghijklmno.abcdefghijklmno' ; // temporary hack for IIS
                webroot = Replace(expandPath('/' & temp ), temp, '') ;
                root = StructNew() ;
                root.prefix = '' ;
                root.physicalPath = NormalizePath( webroot ) ;
                // for multiuser logins, check if the current user has access to folders
                if(security.isSandboxSecurityEnabled())
                {
                    if(hasAccessToFolder(root.physicalPath))
                    {
                        ArrayAppend(roots, root);
                    }
                }
                else
                {
                    ArrayAppend(roots,root);
                }
            }
            
            // get custom tag roots
            installationRoot = Replace( server.coldfusion.rootdir, '\', '/', 'ALL' ) ;
            for ( ctRoot in customTagRoots ) {
                root = StructNew() ;
                root.prefix = '' ;
                // temporary workaround
                root.physicalPath = NormalizePath( 
                    Replace( CustomTagRoots[ctRoot], "##server.coldfusion.rootdir##", installationRoot ) ) ;
                // for multiuser logins, check if the current user has access to folders
                if(security.isSandboxSecurityEnabled())
                {
                    if(hasAccessToFolder(root.physicalPath))
                    {
                        ArrayAppend(roots, root);
                    }
                }
                else
                {
                    ArrayAppend(roots,root);
                }
            }
            return roots ;
        </cfscript>
    </cffunction>
    
    <cffunction name="getcfcs" returnType="array" access="remote"
        hint="Returns array of component metadata structs. Each metadata struct contains: <ul><li>name - full component name</li><li>package - package name</li><li>path - physical path of the component with forward slashes</li><li>cfcroot - physical path of the root under which this component was found (all forward slashes, no trailing slash). If sandbox security is enabled, only those components that are present in the sandboxes accessible to the user are retrieved.</li></ul>">
 
        <cfargument name="refreshCache" type="boolean" default="no">
 
        <cfscript>
            var key = "";
            factory = CreateObject("java", "coldfusion.server.ServiceFactory");
            security = factory.getSecurityService();
            if(security.isSandBoxSecurityEnabled())
            {
                key = "getcfcs"&getCurrentUser();
            }
            else
            {
                key = "getcfcs";
            }
            readFromCache = checkCache(key) and not refreshCache ;
    
            if ( readFromCache ) {
                return getCache(key) ;
                
            }
            else {
                roots = getComponentRoots() ;
 
                components = StructNew() ;
                packages = StructNew() ;                
                ignoreShadowedPackages = true ;
                
                for ( i=1; i lte ArrayLen( roots ); i=i+1 ) {
 
                    root = CreateObject( "java", "java.io.File" ) ;
                    root.init( roots[i].physicalPath ) ;
                    browseForComponents( roots[i].prefix, root, roots[i].physicalPath, ignoreShadowedPackages ) ;
 
                    // toggle the switch once we passed the web root (first root without
                    // the package prefix
                    if ( ignoreShadowedPackages and roots[i].prefix eq '' )
                        ignoreShadowedPackages = false ;
 
                }
                
                result = ArrayNew(1) ;
                for ( name in components ) {
                    ArrayAppend( result, components[name] ) ;
                }
                
                setCache(key, result) ;
                
                return result ;
            }
        </cfscript>
 
    </cffunction>
    
    
    <cffunction name="getcfcsinmcdl" returnType="struct" output="false" access="remote"
        hint="Returns associative array (struct) where keys are full component names and values are MCDL documents representing the components. If sandbox security is enabled, the struct contains the keys (component names) that are present in the sandboxes that can be accessed by the current user.">
 
        <cfargument name="refreshCache" type="boolean" default="no" />
 
         <!--- check to see if we have a cached version --->
        <cfset readCache = checkCache("getcfcsinmcdl") and not refreshcache>
        <cfif readCache>
            <cfset result = getCache("getcfcsinmcdl")>
        <cfelse>
            <cfset mcdl_struct = structNew()>
            <cfset cfcs = getcfcs(refreshCache)>
            <cfloop index="x" from=1 to="#arrayLen(cfcs)#">
                <cfset error = structNew()>
                
                <cftry>
                    <cfset mcdl = getcfcinmcdl( cfcs[x].name )>
                    <cfcatch>
                        <cfset error = cfcatch>
                        <cfset mcdl = "">
                    </cfcatch>
                </cftry>
 
                <cfif structIsEmpty(error)>
                    <cfset mcdl_struct[cfcs[x].name] = trim(mcdl)>
                <cfelse>
                    <cfset tempError = structnew()>
                    <cfset tempError.Name = error.message>
                    <cfset mcdl_struct[cfcs[x].name] = tempError>
                </cfif>
            
            </cfloop>
            <cfset result = mcdl_struct>
            <cfset setCache("getcfcsinmcdl", result)>
            
        </cfif>
    
        <cfreturn result>
 
    </cffunction>
    
    <cffunction name="getCFCMetaData" returnType="struct" output="no" access="remote"
        hint="Returns MCDL document representing the specified component.">
 
        <cfargument name="name" type="string" required="no" />
        <cfargument name="path" type="string" required="no" />
        
        <cftry>
            <cfscript>
                if ( IsDefined('arguments.path') and arguments.path neq '' ) 
                {
                    resourcescanonicalpath = createObject("java","java.io.File").init(arguments.path).getCanonicalPath();
                    var indexOfCFC = FindNoCase("cfc.",reverse(resourcescanonicalpath));  // "cfc." = reverse(".cfc")
                    if (indexOfCFC neq 1)  
                    {
                        //if path is not a cfc we throw error.                     
                        Throw(type="Invalid Data", message="Unsupported file type. Check usage for Component Browser.");                        
                    }
                    
                    // we are trimming the extension if provided with path. because of
                    // 76373. We want to use GetComponentMetadata method as it gives advantage 
                    // over GetMetadata, in terms of not initializing the object to get metadata.
                    // but Flex builder request come to call this method directly which have .cfc appended in the path.
                    var trimmedPath = HTMLEditFormat(arguments.path);
                    var indexOfCFC = FindNoCase("cfc.",reverse(trimmedPath));  // "cfc." = reverse(".cfc")
                    if (indexOfCFC eq 1)  // trimmedPath ends with .cfc
                    {
                        trimmedPath = Left(trimmedPath, len(trimmedPath) - 4);  // Remove .cfc
                    }
                    return getComponentMetaData(trimmedPath);    
                } 
                else if( isDefined('arguments.name') )
                {
                    //This name should be a fully qualified name.
                    return getComponentMetaData(HTMLEditFormat(name));                    
                }
            </cfscript>
        <cfcatch type="coldfusion.runtime.CfJspPage$NoSuchTemplateException">
            <cfoutput><h4>Component not found</h4>
            The component definition file for component '#HTMLEditFormat(name)#' cannot be found on this server.</cfoutput>
        </cfcatch>
        <cfcatch type="any">
            <cfrethrow>
        </cfcatch>
        </cftry>
    </cffunction>
    
    
    <cffunction name="getcfcinmcdl" returnType="string" output="no" access="remote"
        hint="Returns MCDL document representing the specified component.">
 
        <cfargument name="name" type="string" required="yes" />
        
        <cfscript>
            comp = CreateObject( "component", name ) ;
            utils = CreateObject( "component", "utils" ) ;
            return utils.cfcToMCDL(comp) ;
        </cfscript>
    </cffunction>
    
    
    <cffunction name="getcfcinhtml" access="remote" returnType="void"
        hint="Generates html descriptor of a component with the specified name or URI path as the http response.">
        <cfargument name="name" type="string" required="yes" />
        <cfargument name="path" type="string" required="no" />
        
        <cftry>
            <cfscript>
                proxy = CreateObject( "java", "coldfusion.runtime.TemplateProxyFactory" ) ;
                if ( IsDefined('arguments.path') and arguments.path neq '' ) {
                    resourcescanonicalpath = createObject("java","java.io.File").init(arguments.path).getCanonicalPath();
                    var indexOfCFC = FindNoCase("cfc.",reverse(resourcescanonicalpath));  // "cfc." = reverse(".cfc")
                    if (indexOfCFC neq 1)  
                    {                        
                        //if path is not a cfc we throw error.                     
                        Throw(type="Invalid Data", message="Unsupported file type. Check usage for Component Browser.");                        
                    }
                    comp = proxy.ResolvePath( HTMLEditFormat(arguments.path), getPageContext() ) ;                    
                } else {
                    comp = proxy.resolveName(HTMLEditFormat(name),getPageContext());
                }
                proxy.verifyInterfaceImplementation(comp,getPageContext());
                
                utils = CreateObject( "component", "utils" ) ;
                WriteOutput( utils.cfcToHTML(comp) ) ;
            </cfscript>
        <cfcatch type="coldfusion.runtime.CfJspPage$NoSuchTemplateException">
            <cfoutput><h4>Component not found</h4>
            The component definition file for component '#HTMLEditFormat(name)#' cannot be found on this server.</cfoutput>
        </cfcatch>
        <cfcatch type="any">
            <cfrethrow>
        </cfcatch>
        </cftry>
    </cffunction>
 
 
    <cffunction name="getcfctree" returnType="struct" access="remote"
        hint="Returns associative array (struct) where keys are physical paths for each component root and values are associative arrays of packages found under each root. Each associative array of packages is a struct where keys are package names and values are arrays of short component names belonging to a package. If sandbox security is enabled, the returned struct contains the keys (component roots) that are present in the folders that can be accessed by the current user.</li></ul>">
 
        <cfargument name="refreshCache" type="boolean" default="no"  />
 
        <cfscript>
            tree = StructNew() ;
 
            cfcs = getcfcs(refreshCache) ;
 
            roots = getcomponentroots() ;
            for ( i=1; i lte ArrayLen(roots); i=i+1 ) {
                tree[roots[i].physicalPath] = StructNew() ;
            }
 
            for ( i=1; i lte ArrayLen(cfcs); i=i+1 ) {
                cfc = cfcs[i] ;
                if ( StructKeyExists( tree, cfc.cfcroot ) ) {
                    if ( not StructKeyExists( tree[cfc.cfcroot], cfc.package ) ) {
                        // add new package to the package struct
                        tree[cfc.cfcroot][cfc.package] = ArrayNew(1) ;
                    }
                    ArrayAppend( tree[cfc.cfcroot][cfc.package], ListLast( cfc.name, '.' ) ) ;
                }
            }
            
            return tree ;
        </cfscript>
        
    </cffunction>
    
 
 
    <cffunction name="exists" returnType="boolean" output="no" access="remote"
        hint="Returns true if component with specifed name exists, false otherwise. This method always refreshes the internal cfc cache. If sandbox security is enabled, this function checks for the availability of components in the sandboxes that the current user has access to.">
 
        <cfargument name="name" type="string" required="yes" />
 
        <cfscript>
            cfcs = getcfcs(true) ;
        
            for ( i=1; i lte ArrayLen(cfcs); i=i+1 ) {
                if ( cfcs[i].name eq name )
                    return true ;
            }
            
            return false ;
        </cfscript>
 
    </cffunction>
 
<cfsetting enablecfoutputonly="no"></cfcomponent>