Hi,
I've been trying to implement a more OOP oriented approach to dealing with user security on one of my websites, and I am trying to validate the user against an array of roles, however I am struggling with a type error:
I am definately passing in an array, or at least a list which I think are basically the same thing? Here is my code for the instantiating the User object (contained in /index.cfm):
and here is the User.cfc object:
Could someone point out where I am going wrong?
Thanks,
Chromis
I've been trying to implement a more OOP oriented approach to dealing with user security on one of my websites, and I am trying to validate the user against an array of roles, however I am struggling with a type error:
Code:
The argument ROLES passed to function setRoles() is not of type array. If the component name is specified as a type of this argument, the reason for this error might be that a definition file for such component cannot be found or is not accessible. The error occurred in D:\***\***\AppTest\com\user.cfc: line 50 48 : <cffunction name="getRoles" access="public" output="true" returntype="array"> 49 : <cfreturn variables.roles /> 50 : </cffunction> 51 : 52 : <cffunction name="setRoles" access="public" output="false" returntype="void">
I am definately passing in an array, or at least a list which I think are basically the same thing? Here is my code for the instantiating the User object (contained in /index.cfm):
Code:
if(NOT isDefined("Session.user")) {
Request.Ses.user = createObject("component","com.user").init(Request.App.Dsn);
Request.Ses.user.setUsername("eddy");
Request.Ses.user.setPassword("eddy");
Request.Ses.user.setRoles("staff, user");
}
Code:
<!--- security component --->
<cfcomponent displayname="user" output="false" hint="Provides authentication for users">
<cffunction name="init" access="public" output="false" returntype="user" hint="Constructor for this CFC">
<!--- take DSN as argument --->
<cfargument name="dsn" type="string" required="true" hint="The datasource name" />
<!--- put dsn in variables scope so we can use it throughout the CFC --->
<cfscript>
// datasource
variables.dsn = arguments.dsn;
// user details
variables.username = "";
variables.password = "";
variables.loginStatus = 0;
variables.roles = ArrayNew(1);
</cfscript>
<!--- return this CFC --->
<cfreturn this />
</cffunction>
<!--- Object data functions --->
<cffunction name="getUsername" access="public" output="false" returntype="string">
<cfreturn variables.username />
</cffunction>
<cffunction name="setUsername" access="public" output="false" returntype="void">
<cfargument name="username" type="string" required="true" />
<cfset variables.username = arguments.username />
</cffunction>
<cffunction name="getPassword" access="private" output="false" returntype="string">
<cfreturn variables.password />
</cffunction>
<cffunction name="setPassword" access="public" output="false" returntype="void">
<cfargument name="password" type="string" required="true" />
<cfset variables.password = arguments.password />
</cffunction>
<cffunction name="getLoginStatus" access="private" output="false" returntype="string">
<cfreturn variables.loginStatus />
</cffunction>
<cffunction name="setLoginStatus" access="public" output="false" returntype="void">
<cfargument name="loginStatus" type="string" required="true" />
<cfset variables.loginStatus = arguments.loginStatus />
</cffunction>
<cffunction name="getRoles" access="public" output="true" returntype="array">
<cfreturn variables.roles />
</cffunction>
<cffunction name="setRoles" access="public" output="false" returntype="void">
<cfargument name="roles" type="array" required="true" />
<cfset variables.roles = arguments.roles />
</cffunction>
<!--- C,R,U,D Methods --->
<cffunction name="read" access="public" output="false" returntype="Void" hint="CRUD Method">
<cfargument name="user" type="user" required="yes" />
<cfargument name="username" type="string" required="yes" />
<cfset var qread = 0 />
<cfquery name="qRead" datasource="#variables.dsn#">
SELECT
username, roles
FROM cms_security
WHERE
username = <cfqueryparam value="#variables.getUsername()#"
cfsqltype="cf_sql_varchar" />
</cfquery>
<cfif qRead.RecordCount>
<cfset arguments.User.setRoles(qRead.roles) />
<cfelse>
<cfthrow type="emptyRecordset" errorcode="User.read.emptyRecordset" message="User with name #arguments.username# not found" />
</cfif>
</cffunction>
<!--- Persistent data functions --->
<cffunction name="checkRoles" access="public" output="false" returntype="boolean" hint="Checks user roles against a supplied array or list">
<!--- Initialise variables --->
<cfset var results = StructNew() />
<cfset var qCheckRoles = 0 />
<!--- defaults --->
<cfset results.success = true />
<cfset results.message = "The user has been validated." />
<cftry>
<cfquery name="qCheckRoles" datasource="#variables.dsn#">
SELECT roles
FROM cms_security
WHERE username = <cfqueryparam value="#variables.getUsername()#"
cfsqltype="cf_sql_varchar" />
</cfquery>
<cfcatch type="database">
<cfset results.success = false />
<cfset results.message = "User role check failed. The error details if available
are as follows: " & CFCATCH.Detail />
</cfcatch>
</cftry>
<!--- if we got data back, initialize the object --->
<cfif IsQuery(qCheckRoles) AND qCheckRoles.RecordCount EQ 1>
<cfdump var="#qCheckRoles#">
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>
<cffunction name="validate" access="public" output="false" returntype="boolean" hint="validates username and password">
<!--- Initialise variables --->
<cfset var results = StructNew() />
<cfset var qValidate = 0 />
<!--- defaults --->
<cfset results.success = true />
<cfset results.message = "The user has been validated." />
<cftry>
<cfquery name="qValidate" datasource="#variables.dsn#">
SELECT username,password
FROM cms_security
WHERE username = <cfqueryparam value="#variables.getUsername()#"
cfsqltype="cf_sql_varchar" />
AND password = '#hash(variables.password)#'
</cfquery>
<cfcatch type="database">
<cfset results.success = false />
<cfset results.message = "The person insert failed. The error details if available
are as follows: " & CFCATCH.Detail />
</cfcatch>
</cftry>
<!--- if we got data back, initialize the object --->
<cfif IsQuery(qValidate) AND qValidate.RecordCount EQ 1>
<cfset setLoginStatus(true) />
<cfreturn true>
<cfelse>
<cfreturn false>
</cfif>
</cffunction>
</cfcomponent>
Thanks,
Chromis
Comment