[Coldbox 4.2.0] - settings not loading in coldbox config file

I create a structure for some new settings for a module that I’m creating. Restarted the app make sure the settings are loaded but they are not. All other settings in the config file load properly and adding additional settings to the settings structure works fine. these are the module settings I would like to load:

`

// ipFilter Settings
ipFilter = {
s3AccessID = “”,
s3SecretKey = “”,
productCode = “RTDM”,
TTL = 300,
lastmodified = “1900-01-01 00:00:00”
};

`

Can someone shed some light on this please?

Show your full config file and how you’re trying to access the settings.

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Within the modules cdc i am accessing the settings like so:

property name=“moduleSettings” inject=“coldbox:setting:ipFilter”;

when restarting the server i get “The setting ipFilter does not exist.”

`

component{

// Configure ColdBox Application
function configure(){

// coldbox directives
coldbox = {
//Application Setup
appName = “ApplicationCore”,
eventName = “event”,

//Development Settings
reinitPassword = “1”,
handlersIndexAutoReload = true,

//Implicit Events
defaultEvent = “”,
requestStartHandler = “Main.onRequestStart”,
requestEndHandler = “”,
applicationStartHandler = “Main.onAppInit”,
applicationEndHandler = “”,
sessionStartHandler = “”,
sessionEndHandler = “”,
missingTemplateHandler = “”,

//Extension Points
applicationHelper = “includes/helpers/ApplicationHelper.cfm”,
viewsHelper = “”,
modulesExternalLocation = [],
viewsExternalLocation = “”,
layoutsExternalLocation = “”,
handlersExternalLocation = “”,
requestContextDecorator = “”,
controllerDecorator = “”,

//Error/Exception Handling
exceptionHandler = “main.onException”,
onInvalidEvent = “”,
customErrorTemplate = “”,

//Application Aspects
handlerCaching = false,
eventCaching = false,
viewCaching = false
};

// custom settings
settings = {
currentYear="#year(now())#",
EncKey = “blah”,
PagingMaxRows = 50,
PagingBandGap = 10,
custServEmail = ‘customerService@blah’,
companyName = “blah, LLC”,
companySite = “http://blah”,
environmentName = “”,
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”
};

// ipFilter Settings
ipFilter = {
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”,
TTL = 300,
lastmodified = “1900-01-01 00:00:00”
};

// cbORM injection
orm = { injection = { enabled=true } };

// let CB know about datasources
datasources = {
realcama = {name=“applicationcore”, dbtype=“mySQL”}
};

// List all your webservices here that this module can tallk to.
webservices = {
RTDAUser = “http://blah/ra-user-service/UserService.cfc?wsdl
}
// environment settings, create a detectEnvironment() method to detect it yourself.
// create a function with the name of the environment so it can be executed if that environment is detected
// the value of the environment is a list of regex patterns to match the cgi.http_host.
environments = {
development = “localhost,^127.0.0.1”,
stage = “stage$”
};

// Module Directives
modules = {
//Turn to false in production
autoReload = false,
// An array of modules names to load, empty means all of them
include = [],
// An array of modules names to NOT load, empty means none
exclude = []
};

//LogBox DSL
logBox = {
// Define Appenders
appenders = {
coldboxTracer = { class=“coldbox.system.logging.appenders.ConsoleAppender” },
MyAsycFile = {
class=“coldbox.system.logging.appenders.RollingFileAppender”,
properties={
filePath=expandPath("/coldbox/system/log/tmp"),autoExpand=false,fileMaxArchives=1,fileMaxSize=3000
}
}
},
// Root Logger
root = { levelmax=“INFO”, appenders="*" },
// Implicit Level Categories
info = [ “coldbox.system” ],
debug = [ “cbsecurity”,“cbmailservices” ]
};

s3sdk = {
// Your amazon access key
accessKey = “blah”,
// Your amazon secret key
secretKey = “blah”,
// The default encryption character set
encryption_charset = “utf-8”,
// SSL mode or not on cfhttp calls.
ssl = false
};

//Layout Settings
layoutSettings = {
defaultLayout = “”,
defaultView = “”
};

//Interceptor Settings
interceptorSettings = {
throwOnInvalidStates = false,
customInterceptionPoints = “”
};

cbsecurity = {
useRegex = true,
rulesSource = “db”,
rulesDSN = “applicationCore”,
rulesTable = “securityRule”,
rulesSQL = “select * from securityRule”,
rulesOrderBy = “securityRuleID”,
//rulesFile = “modules/cbsecurity/config/security.xml.cfm”,
validatorModel=“SecurityService”
};

// Antisamy settings…cross site scripting protection
antisamy = {
// Activate auto request capture cleanups interceptor
autoClean = true,
// Default Policy to use, available are: antisamy, ebay, myspace, slashdot and tinymce. If the current policy is to restrictive it can be customized.
defaultPolicy = “ebay”,
// Custom Policy absolute path, leave empty if not used
customPolicy = “”
};

//mail settings
mailsettings = {
// The default token Marker Symbol
tokenMarker = “@”,
// protocol
protocol = {
class = “cbmailservices.models.protocols.CFMailProtocol”,
properties = {server=“RealacutionDAG.realauction.com”}
}
};
//Register interceptors as an array, we need order
interceptors = [
//SES
{class=“coldbox.system.interceptors.SES”,
properties={}
}
];

validation = {
sharedConstraints = {
userForm = {
role = {required=true},
firstName = {required=true},
lastName = {required=true},
emailAddress = {required=true, requiredMessage=“EMAIL address required.”, type=“email”},
addressLine1 = {required=true},
city = {required=true},
stateProvinceCd = {required=true},
postalCd = {required=true, type=“zipCode”},
countryCd = {required=true},
area = {required=true},
number = {required=true},
phoneType = {required=true},
isUserActive = {required=true},
isUserLockedOut = {required=true}
},
loginForm = {
username = {required=true}, password = {required=true}
},
changePasswordForm = {
password = {required=true,min=6, requiredMessage=‘Password confirmation does not match Password provided.’}, confirmPassword = {required=true, sameAs=“password”, min=6, sameAsMessage=“Passwords do not match.”}
},
menuForm = {
location = {required=true}, displayName = {required=true}, code = {required=true}, sortOrder = {required=true, type=“integer”}
},
roleForm = {
role = {required=true}, displayName = {required=true}
},
contentForm = {
title = {required=true}, body = {required=true}, type = {required=true}, menuID = {required=true}
},
stateProvinceForm = {
countryCd = {required=true}, stateProvince = {required=true}, stateProvinceCd = {required=true}
},
securityRuleForm = {
match = {required=true}, useSSL = {required=true}, securelist = {required=true}, roles = {required=true}, redirect = {required=true}
},
emailTemplateForm = {
code = {required=true}, emailSubject = {required=true}, emailBody = {required=true}
}

}
}

// flash scope configuration
flash = {
scope = “session”,
properties = {}, // constructor properties for the flash scope implementation
inflateToRC = true, // automatically inflate flash data into the RC scope
inflateToPRC = false, // automatically inflate flash data into the PRC scope
autoPurge = true, // automatically purge flash data for you
autoSave = true // automatically save flash scopes at end of a request and on relocations.
};

debugger = {
// Activate debugger for everybody
debugMode = false, // dev function turns it on
// Setup a password for the panel
debugPassword = “”,
enableDumpVar = true,
persistentRequestProfiler = true,
maxPersistentRequestProfilers = 10,
maxRCPanelQueryRows = 50,
showTracerPanel = true,
expandedTracerPanel = true,
showInfoPanel = true,
expandedInfoPanel = true,
showCachePanel = true,
expandedCachePanel = false,
showRCPanel = true,
expandedRCPanel = false,
showModulesPanel = true,
expandedModulesPanel = false,
showRCSnapshots = false,
wireboxCreationProfiler=false
}
/*
//Register Layouts
layouts = [
{ name = “login”,
file = “Layout.tester.cfm”,
views = “vwLogin,test”,
folders = “tags,pdf/single”
}
];

//Conventions
conventions = {
handlersLocation = “handlers”,
viewsLocation = “views”,
layoutsLocation = “layouts”,
modelsLocation = “models”,
eventAction = “index”
};

//Datasources
datasources = {
mysite = {name=“mySite”, dbType=“mysql”, username=“blah”, password=“blah”},
blog_dsn = {name=“myBlog”, dbType=“oracle”, username=“blah”, password=“blah”}
};
*/

}

/**

  • Development environment
    */
    function development(){
    coldbox.customErrorTemplate = “/coldbox/system/includes/BugReport.cfm”;
    debugger.debugMode = true;
    environmentName = ‘dev’
    }
    function stage(){
    coldbox.customErrorTemplate = “/coldbox/system/includes/BugReport.cfm”;
    debugger.debugMode = false;
    coldbox.environmentName = ‘stage’
    }
    }

`

Yep, to use settings like that, you need to make them part of the top-level settings struct. The settings struct doesn’t have to contain strings-- it can be nested structs, arrays, etc.

// custom settings
settings = {
currentYear="#year(now())#",
EncKey = “blah”,
PagingMaxRows = 50,
PagingBandGap = 10,
custServEmail = ‘customerService@blah’,
companyName = “blah, LLC”,
companySite = “http://blah”,
environmentName = “”,
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”,
// ipFilter Settings
ipFilter = {
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”,
TTL = 300,
lastmodified = “1900-01-01 00:00:00”
}
};

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Ugh, the E-mail killed my tabs… Here it is with spaces.

// custom settings
settings = {
currentYear="#year(now())#",
EncKey = “blah”,
PagingMaxRows = 50,
PagingBandGap = 10,
custServEmail = ‘customerService@blah’,
companyName = “blah, LLC”,
companySite = “http://blah”,
environmentName = “”,
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”,
// ipFilter Settings
ipFilter = {
s3AccessID = “blah”,
s3SecretKey = “blah”,
productCode = “RTDM”,
TTL = 300,
lastmodified = “1900-01-01 00:00:00”
}
};

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Ok. That will Work. Thanks. but one question…why is it that settings for things like antisamy work outside of the custom settings?

Look at the antisammy module to see how those settings are being accessed :slight_smile:

https://github.com/coldbox-modules/cbox-antisamy/blob/development/modules/cbantisamy/ModuleConfig.cfc#L57

You should also note that we’ve introduced a new convention in ColdBox 4.3, where that ugly chunk of code I linked to above is no longer needed. ColdBox apps can directly override module settings now by convention. Please see the docs here under the section titled “Overriding Module Settings”.

https://coldbox.ortusbooks.com/content/full/modules/retrieving_&_interacting_with_module_settings/

So with ColdBox 4.3, you simply put the default setting into your ModuleConfig’s settings struct and then inject it wherever you need it with the injection DSL. Then your parent ColdBox app can override that setting by convention like so:

    moduleSettings = {
      myModule = {
        someSetting = "overridden" 
      }
    };

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Robert,

Generally, all settings for modules are keys of the top-level Coldbox settings struct. Your custom settings struct, in theory, should only contain settings that are unique to your application.

If you were traverse down in to the custom settings on lookup of a module config, you’d you’d have a bunch of conditionals on the lookup and needless recursion - slowing things down.

Jon

appreciate the help brad!!!

One last question on this Brad, is it possible to have the module reload itself? or more specifically, call the modules onLoad function in the moduleConfig.cfc from the cfc in the modules model folder?

Here is the scenario. I have a file that gets loaded into a structure when the module loads. The file is loaded in the onLoad function of the module config file. At some point that file may change and the structure that gets created needs to be refreshed. So rather than reload the module i would prefer to call the modules unload function. Is that possible?

I would abstract that out into a service inside your module. Then call that service from your module onLoad as well as anywhere else you want the logic to be run.

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Awesome. Thanks Again!

I created a service layer and moved the code i had in the configure function which loads the file to the new service layer. The file is in the models folder and is called ipFilterRedirectService.cfc. I’m making the call from the onLoad function in the moduleConfig file to the service layer now, but i’m getting “variable ipFilterRedirectService does not exist” error. Here is the module config code:

`

component {

property name=“ipFilterRedirectService” inject=“model”;

// Module Properties
this.title = “IP Filter and Redirect”;
this.author = “Bill Fears/Robert Cruz”;
this.webURL = “http://www.realauction.com”;
this.description = “Redirects request to 404 template if Client IP Address is in malicious list”;
this.version = “1.0.0”;
this.entryPoint = “ipFilterRedicrect”;
this.cfmapping = “ipFilterRedicrect”;

/**

  • Configure
    */
    function configure(){
    }

function onLoad() {
ipFilterRedirectService.loadBlackListedIPs();
}
}

`

Am i doing something wrong?

ModuleConfig files aren’t autowired like a handler or model I’m not actually sure if there’s a good reason for that, but it’s pretty much the same with any config file in ColdBox- they are created outside WireBox.

The fix should be simple tho-- you should have a reference to WireBox right there in the config file. Just ask Wirebox for your service like so:

wirebox.getinstance( ‘ipFilterRedirectService’ );

Also note, that’s the Wirebox ID for your CFC if it’s in the parent app’s models folder. if that service is part of your module, you’ll want to do this:

wirebox.getinstance( ‘ipFilterRedirectService@yourModuleName’ );

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Sorry i’m being such a pain…getting variable [WIREBOX] doesn’t existt with the config file modified like below:

`

component {

//property name=“ipFilterRedirectService” inject=“ipFilterRedirectService@ipFilterRedirect”;

//dump(ipFilterRedirectService); abort;
ipFilterRedirectService = wirebox.getinstance( ‘ipFilterRedirectService@ipFilterRedirect’ );

// Module Properties
this.title = “IP Filter and Redirect”;
this.author = “Bill Fears/Robert Cruz”;
this.webURL = “http://www.realauction.com”;
this.description = “Redirects request to 404 template if Client IP Address is in malicious list”;
this.version = “1.0.0”;
this.entryPoint = “ipFilterRedicrect”;
this.cfmapping = “ipFilterRedicrect”;

/**

  • Configure
    */
    function configure(){
    }

function onLoad() {
ipFilterRedirectService.loadBlackListedIPs();
}
}

`

And now getting this error:

That’s because you tried to put that code in the pseudo constructor which is run before the config file gets injected. You need to put that logic in your actual onLoad() method.

Thanks!

~Brad

ColdBox/CommandBox Developer Advocate
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Thanks Brad! That worked perfectly. Appreciate all the help!

Everything is working perfectly as desired. Really appreciate all the help. Now for the last bit and then i promise i will leave you alone ;).

I would like to turn the cdc that actually checks the incoming requests ip address to see if it is on the black list and does the redirect into an interceptor that will run with every request. I was looking at the cbsecurity module for some guidance, and see that i have to put that template into an interceptor folder, and create a setting for the interceptor pointing to its location. Am i missing anything else? Below is the code that i’d like to use as an interceptor:

`

component accessors=“true” {

property name=“ipFilterRedirectService” inject=“ipFilterRedirectService@ipFilterRedirect”;
property name=“moduleSettings” inject=“coldbox:setting:ipFilter”;

function init(){
return this;
}

public void function validateRequest(required ipAddress){
var logMessage = “”;
var needsUpdate = false;

lock name=“lastSyncTime” throwOnTimeout=true timeout=“5” type=“readOnly”{

if( DateDiff(‘s’,application.lastSyncTime,Now()) > moduleSettings.TTL ){
needsUpdate = true;
}

}

if( needsUpdate ){

lock name=“lastSyncTime” throwOnTimeout=true timeout=“5” type=“exclusive” {
application.lastSyncTime = Now();
}

thread
action=“run”
priority=“normal”
name=“process#getTickCount()#” {
ipFilterRedirectService.loadBlackListedIPs();
}
}

try{

lock name=“ipblacklist” throwOnTimeout=true timeout=“5” type=“readOnly”{

if(structkeyexists(application.IpStruct,ipAddress)){

logMessage = ipAddress & " redirected: " & application.IpStruct[ipAddress];
writelog(text=logMessage, type=“info”,file=“IPFilter”);

location(application.IpStruct[ipAddress]);
}
}

}catch(err){

logMessage = err.detail & " " & err.message;
writelog(text=logMessage, type=“ERROR”,file=“IPFilter”);

}
}

}

`

No worries, i have the interceptor working. Though the AfterAspectLoad function does not seem to be doing anything at all. Pre process function works fine. I have it working where the code that i want loaded with the app is called as it was before from the module config files onLoad function, then the intercepter just handles each request. Would be nice if the Afteraspect load was working. Im probably missing something.