Global functions in Lucee/Coldfusion - coldfusion

I am trying to create global functions in Lucee. I have followed the directions here and have it "Kind of" working. Inside of Application.cfc I placed the following code:
public void function onRequest() {
URL.IsInternalUser = function() { return (SESSION.user.ID ?: 0); };
}
This seems to work fine in some cases but if we need to access this function in a subdirectory that contains an Application.cfc that does not have the function re-defined it will error out saying the function doesn't exist.
The ultimate goal I am trying to achive is to have a cfc file that contains several user defined functions and then have them accessible throughout the entire application without redefining things over and over again.
Is there a better way to accomplish what we want? I ask this because on the page I referenced earlier in the comments section there is a quote:
I concur. Wouldn't surprise me to see it somewhere else in the future.
What I like about Railo's method is that it is completely sandboxed.
Host A's tags & functions libraries never cross/conflict with Host B's
libraries unless they're put into the global server folders. It's the
same way for the virtual file system too and pretty much everything
else (datasources, etc).
It specifically mentions Railo having a way to create UDF but I can not find any documentaion on this anywhere. Since we are using Lucee which is a fork of Railo I figure it must have what Railo has for creating UDF. Hoping someone that reads this can help me out and point me in the right direction.

Railo/Lucee support custom functions. You can declare them in /WEB-INF/{railo|lucee}/library/function/ of the site. Save the function in a .cfm file and name the file the same as the function. The server needs a restart after creating new functions. Here is Railo's blog post about it.
Adobe ColdFusion doesn't support this AFAIK. So you have to store your functions in the SERVER scope here.

Related

Is it possible to reuse Postman scripts among different Api's test cases?

We have a situation in our project in which we need to access same methods in different Api test cases. Currently we have copy pasted all these methods in every Api test cases. Is it possible to make these methods in a common method and access from it?
It is possible to store these methods in Global variable. It will work fine in Postman, but it fails while running in Newman.
There are two ways you can go about this - both of them are "hacky" and by that I mean that they are a byproduct of what Postman allows you to do for other purposes.
Create a function and assign it to a variable of the window object - there's an example in one of the the GitHub threads on the Postman project. Quote:
I've found a hackish workaround is to wrap functions you want to share
across test inside a global object. In your first pre request script
it would look something like this:
// window.{name of wrapper}
window.Utils = {
percentChange: function(val1, val2) {
return (((val1 - val2) / val2) * 100).toFixed(2) + '%';
}
};
In all the tests that are run after you can call that function without
needing to put 'window' before it
Utils.percentChange(responseTime, newTime);
I actually couldn't manage to get this to work, plus it was not viable for my case, because I wanted to create a framework that would be defined only once and then available in any request.
A blogger - sorry I cannot find the original blog post right now - suggested an approach which I ultimately used successfully.
EDIT: The almost exact solution is showcased on a blogpost (TIP #5: reuse
code) on the official Postman blog.
2.1 Create your reusable code and then store it as an environment or global variable.
2.2 In your pre-request or tests script, call eval on the variable that you defined in the previous step.
NB: There is one major issue with either approach - debugging problems or changing the reusable code that you have stored. I struggled with this when I needed to determine where an inconsistent behavior of the reusable code was coming from. Basically, I ended up using console.log a lot.

Embedded Crystal variables in templating

I’m new to Crystal (and never really used ruby) so apologies for the ignorance here! I've looked at the ecr docs but can't seem to find an answer there.
I’m looking at using Embedded Crystal for dynamic templates in Kemal. Can I confirm - can templates only render variables that are available in the scope of the call, or can one make method/function calls from within the template itself? I.E. is there any possibility/risk of being able to execute “malicious” crystal code from within a template (in this case malicious refers to I/O or file access etc)?
To take an example from the Kemal docs:
get "/:name" do |env|
name = env.params.url["name"]
render "src/views/hello.ecr"
end
In the view hello.ecr - is name the only item that will be available in the template, or could one call File.delete("./foo")from within the template for example?
A template is compiled into Crystal code, you can write any kind of code in there, like File.delete("./foo"), for example if you write <% File.delete("./foo") %> inside of your template.
If your worry is that name will contain code and that will somehow get executed, then don't worry, that's not going to happen. Dynamic runtime code execution in Crystal is not possible, so there's no way someone will inject malicious code into your templates.

Locking a ColdFusion Application Variable that points to instance of an object

I'm running my applications on CF 9. I created a CFC to concentrate my cookie handling instead of all the tags strewn about. It is simple. It has two attributes (name, value), and has 5 methods (setCookie, deleteCookie, verifyCookie, clearAllCookies, and init).
Since I wanted this method to be available throughout the application, I put this code in the onApplicationStart method of my application.cfc file:
application.oCookie = createObject("com.mycookie").init();
When I need to set a cookie in any code file I just call it like so:
application.oCookie.name="testCookieName";
application.oCookie.value="testCookieValue";
application.oCookie.setCookie();
My question is: Do I need to put a lock on this code each time I do this? If two separate users were to be on pages accessing this code at the same exact instant, can I end up with mixed up cookie values being set?
To make your oCookie thread-safe, it has to be a singleton (with no state) that only acts as a thin layer to the <cfcookie> or the cookie scope.
Therefore you should design your com.mycookie so that it accepts application.oCookie.setCookie(name, value) instead. And make sure you var-scope everything and don't store anything in the variables scope of mycookie.
And I don't think you need to use cflock.
If you haven't already, you may want to checkout WireBox.

CFInclude vs Custom Tag vs CFC for Presentation and Security

I'm just starting out with ColdFusion OOP and I am wanting to make a DIV which shows different links to users depending on what page they are on and what login rights (role) they have. Basically a 'context' menu.
Should I put this toolbar/navigation DIV in a .cfm or .cfc file?
To reiterate; The cfm or cfc file needs to know what page the user is on and will also check what role they have. Depending on these two pieces of information it will display a set of links to the user. The role information comes from the database and stored in a SESSION variable, and to find out what page they are on I guess it could use #GetFileFromPath(GetBaseTemplatePath())#.
My first thought was to have a normal .cfm file, put all the presentation and logic in that file (the HTML and lots of <cfif> statements) to ensure the correct information is displayed in the DIV, and then use <cfinclude> to display it on the page. Then I started thinking maybe I should make a Custom Tag and ask the calling page to pass in the user's credentials and the #GetFileFromPath(GetBaseTemplatePath())# as arguments and then have that Custom Tag return all the presentational data.
Finally I guess a CFC could do the above as well, but I'd be breaking the 'rule' of having presentational and logic data in a CFC.
Any suggestions on the best practice to achieve what I'm trying to do? It will eventually serve thousands of customers so I need to make sure my solution is easy to scale.
Anything that outputs HTML to the screen should be in a .cfm file.
That being said, depending on your need, you could have methods in a CFC that generate HTML, but the method simply returns the HTML as a string.
In programming, there are very few absolutes, but here is one: You should NEVER directly output anything inside of a function or method by using output="true". Instead, whatever content is generated, it should be returned from the method.
If you will have a need to use this display element more than once, a custom tag might be the best way to go rather than an include.
I see security as being a combination of what menu items I can see and what pages can be ran.
The main security function is inside of the main session object
On the menus
I call a function called
if (session.objState.checkSecurity(Section, Item) == 1)
then ...
For page security
function setupRequest() {
...
if (session.objState.checkSecurity(getSection(), getItem()) == 0) {
location("#request.self#?message=LoginExpired", "no");
return;
}
...
}
The particulars of what checkSecurity can do varies from application to application, but it is tied into how FW/1 works. The following security variations exist:
session.objState.checkSecurity(getSection())
session.objState.checkSecurity(getSection(), getItem())
session.objState.checkSecurity(getSection(), getItem(), Identifier)
None of the presentation files know anything about security.
Rules by which I live:) :
No CF business logic in CFM files. Just use some service which will serve template and provide needed data.
navService = com.foobar.services.Navigation(form, url);
and later output #navService.GetNavConent()#
No direct output from CFC files, functions should always return content. For example, make one function which makes one link based on some logic, second which wraps that and returns to cfm template.
Also one more hint, avoid using application and session scopes in your services.
This makes refactoring, testing and debugging too difficult.
For session you can make session.currentUser , CurrentUser.cfc which provides all things you need. e.g. session.currentUser.isAuthorized("backend/administration") and if true, show link to backend/administration.
Same for application, if you need locale, applicaiton wide setting or some singleton, make application.applicationSettings, ApplicationSettings.cfc and use that to retrieve all info you need in cfc's.
These rules will make your application to be easier to test and debug, and really easy to migrate tomorrow on some javascript based UI like Angular or backbone.js since all th edata you need is already in CFC and theoretically you just need to put remote in CFC or make some remote facade in the middle and you're done.

Coldfusion 9, Coldbox, Coldspring, Transfer, and the missing functions in CFDump

My company has haphazardly upgraded the production server of our website to CF9, and while we were relatively lucky with very few incompatibilities, I am running into one problem that over the last week has caused me a considerable amount of grief.
Our sites use the Coldbox framework with the Transfer ORM, with function inheritance through abstract objects. Previously in CF8, when I would cfdump an object, I could view all of my setters and getters that existed in the object. However, CF9 modified the cfdump function to dump only the metadata for the object. The new CF9 documentation states that there is a metainfo tag that when set as true, should dump inherited objects (like my setters and getters for my database columns), but in this instance, it does not work.
While ultimately this isn't a back-breaking problem, it's become a considerable pain for me as I don't have rote memorization of all the functions in these objects; I'll be looking to dump a function because I know what I'm looking for but don't quite remember the name, only to find that it's not being dumped because of the way it's inherited from Transfer. I've tried the following things so far as solutions without any luck:
cfdump metainfo=true
Creating dump function in the abstract decorator
creating a dump function in the base decorator
Creating dump functions in defined override decorators
We're using the latest versions of Coldspring and Transfer, and Coldbox 2.6.4. Any insight as to workarounds or resolutions would be appreciated.
If you're not getting cfump to do it for you, first thing to do is file a bug at http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html
The next thing I would do is use the Component Browser in a separate tab to keep an always ready copy of your full component documentation ready to use:
http://[yoursite]/CFIDE/componentutils/componentdoc.cfm
Faster than cfdump, save, reload, check, undo, save, retest. The component docs should show you all of your inherited methods.
if your still really want the old functionality back and you happen to have a CF8 install somewhere CFDUMP was implemented as a custom tag internaly so you grab the old one from CF8 and port it into your cf9 install.
just copy /WEB-INF/cftags/dump.cfm and rename it as you go..
how about creating a dump function that does this
<cfdump var="#myobject#" label="built-in dump">
<cfdump var="#getMetaData(myobject)#" label="object metadata">
getMetaData() would give you back your getters and setters