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: -
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): -
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");
-
}
-
and here is the User.cfc object:
Could someone point out where I am going wrong?
Thanks,
Chromis
14 3245 acoder 16,027
Recognized Expert Moderator MVP
You're passing a list rather than an array. What you could do is accept a string as the input and convert to an array in the function, or create the array with cfset and pass that to setRoles.
You're passing a list rather than an array. What you could do is accept a string as the input and convert to an array in the function, or create the array with cfset and pass that to setRoles.
Ah right ok I'll do that. Thanks alot for your help, I'll no doubt have some questions shortly!
acoder 16,027
Recognized Expert Moderator MVP
No problem, if you do, you know where to come :)
No problem, if you do, you know where to come :)
Ok I'm getting a little confused, basically I want to create an OOP method for validating a user, the user must have a valid username, password and also have one of the roles for the particular page that they are viewing.
I've got the fundamentals of the validation working now, though i'm sure i'm not getting the structure of the User.cfc quite right. I've read about OOP and it talks about DAOs and Gateways I have tryed to implement this sort of structure. Tho I have struggled to separate the database calls into a Gateway file.
At the moment i seem to have a kind of mis-match of the two in one file. Could you tell me how i could improve this code?
Instantiation and data output (/index.cfm): -
<cfscript>
-
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");
-
}
-
</cfscript>
-
-
<cfdump var="#Request#">
-
-
<cfoutput>Validate result: #Request.Ses.user.validate()#</cfoutput>
-
Roles: <cfoutput>#Request.Ses.user.getRoles()#</cfoutput>
-
Actual Roles:<cfoutput>#Request.Ses.user.getActualRoles()#</cfoutput>
-
Validate roles: <cfoutput>#Request.Ses.user.checkRoles("staff,user")#</cfoutput>
-
User DAO / Gateway (/com/User.cfc):
The parts I want to look at specifically are the checkRoles and validate methods. Should I put them into one method or attempt to separate the checkRoles and validate database calls into two different methods and have one validate method? I'm a bit confused :)
Thanks,
Chromis
[code]
acoder 16,027
Recognized Expert Moderator MVP
It probably would be a good idea to put the database calls in its own object which you can instantiate/call when the user object is initialised. Then it'd smply be a function call to make the query which would return true/false or a result struct. As for the validate() and checkRoles() functions, it depends on whether you ever need only the checkRoles function. If you do, you can call checkRoles within validate should validate() also validate roles.
It probably would be a good idea to put the database calls in its own object which you can instantiate/call when the user object is initialised. Then it'd smply be a function call to make the query which would return true/false or a result struct. As for the validate() and checkRoles() functions, it depends on whether you ever need only the checkRoles function. If you do, you can call checkRoles within validate should validate() also validate roles.
Thanks acoder, I'll have a go and post back what i come up with.
Hi acoder,
Ok, I'm had some time to look at this code again and I think what I need to do is create a UserDAO.cfc for my persistent data functions and then pass the user.cfc object to the UserDAO.cfc object upon initialisation, I can then authenticate and check the roles using UserDAO, is this right?
On various pages I'll need to the check the user roles against the role for that page and then redirect the user to another page, do I need to create another object for this, security.cfc for instance? My thinking is that the user objects shouldn't really be used for this sort of thing, as it's not a user objects responsibility to perform the business logic.
Thanks,
Chromis
acoder 16,027
Recognized Expert Moderator MVP
That's right, though you could have a method in user.cfc which performs this logic, i.e. checks that the user has the role for that page; if not, redirect.
Ok, I started going down the route of creating a separate object (security.cfc) to deal with the business logic of redirecting the user, but that got me into the realm of keeping that object persistent aswell which seemed really overkill. In the end I took your advice and put a protect function in the user.cfc to redirect the user to a different page if the roles for the user were not found. This is definately the easiest method and for this project not one that's going to cause any problems so I guess I'll stick with it.
I guess what I'm trying to find out whilst learning OOP is when to separate logic and when not to, alot of what I have read so far talks about making one object do one thing well and what felt wrong about the user.cfc having a protect function and also the database interaction functions, was that it was no longer just defining a user, but providing functions to deal with it within the application.
Could you give me any advice regarding this?
Anyway here's my protect statement which I'm putting in my index.cfm's, if the user does not have the specified role record in the database, the user will be redirected to the specified URL.
index.cfm -
Request.Ses.User.protect("staff","../index.cfm");
-
User.cfc - protect function. -
<cffunction name="protect" access="public" output="true" returntype="boolean" hint="Checks user roles against a supplied array or list">
-
<cfargument name="roles" type="string" required="true" />
-
<cfargument name="redirectURL" type="string" required="true" />
-
-
<cfif variables.checkRoles(arguments.roles) EQ true>
-
<cflocation url="#arguments.redirectURL#">
-
<cfreturn true>
-
<cfelse>
-
<cflocation url="#arguments.redirectURL#">
-
<cfreturn false>
-
</cfif>
-
-
</cffunction>
-
Again thanks for your help!
acoder 16,027
Recognized Expert Moderator MVP
I see what you mean. Coldfusion doesn't place any restrictions in terms of OOP, though this may change in future versions.
You could look at frameworks such as Fusebox/Mach-II which might help. You could also look into the MVC (Model-View-Controller) pattern for separation.
Ok well that's put me at ease a bit. I have looked into machII and the MVC pattern, I've only developed a couple of tests so far. I have a few questions regarding this though:
1. At what scale of application does the machII begin to be useful?
2. Is it good for rapid application development?
3. Does it lend itself well to OOP techniques?
4. What do you develop with?
acoder 16,027
Recognized Expert Moderator MVP
Mach-II is probably better suited for large, complex applications. Another alternative is Model-Glue which can be simpler. Both enforce MVC whereas Fusebox doesn't. You may find this article/slideshow useful which compares the three.
What do I use? I don't use any, though I probably should. If I was developing from the ground up, I would and I'd change my programming style too.
Thanks I'll take a look at that. I guess for the app i'm developing at the moment I won't be needing a framework. But from what I have seen so far I think MachII would be my choice.
Again thanks for you help i'll no doubt be asking more questions soon!
acoder 16,027
Recognized Expert Moderator MVP
No problem. This is an interesting discussion probably not covered in this forum before. Fire away when the need comes and I'll see what I can do :)
Sign in to post your reply or Sign up for a free account.
Similar topics |
by: Rhy Mednick |
last post by:
I'm creating a custom control (inherited from UserControl) that is displayed
by other controls on the form. I would like for the control to disappear
when the user clicks outside my control the same way a menu does. To do
this my control needs to get notified when the user tried to click off of
it. The Leave and LostFocus events of the...
|
by: Eran Kampf |
last post by:
I am trying to dynamically create directories in my ASP.NET application (I
am using Server.MapPath("/")+"test" as the folder)
and I am getting a DirectoryNotFoundException saying "Could not find a part
of the path "D:\".
My site is hosted on a public ISP that for obvious security reasons does not
allow my read access above my wwwroot folder...
|
by: Robin Bonin |
last post by:
In my user contol I am creating a set of dropdownlists.
Each list is created based on input from the other lists.
The problem I am having is setting the selected index on
the lists.
If someone changes box1, I want to set the selected index in
box2 = 0. When I do this, I dont get an error, but when the
page loads, it still has the selected...
|
by: Venkat Chellam |
last post by:
I have a peculiar problem. I have a simple web application which loads
some data from the oracle table and display in the datagrid in the
webpage and datagrid has page enabled which shows 10 rows at a page.I
have a search criteria to search the records based on the data range i
give
This is what i have done, in the !IsPostBack section. I...
|
by: Jeff B |
last post by:
I am having a very perplexing problem with setting the user's roles. I have
tried to figure this out for 2 days now.
When the user logs in to the site, I retrieve the roles from the database
and create a semicolon delimited string listing the roles returned and store
them in the forms authentication cookie. Then in the global.asax...
| |
by: Mikael Östberg |
last post by:
Hello all!
I have this login function which doesn't work really well.
I tried to do extend the built-in functionality in order to store things
such as userName and email address in Session.
I have this User class which contains some public properties and a number of
static methods. The class implements the singelton pattern, which...
|
by: Charles Law |
last post by:
For some reason, when I click the X to close my MDI parent form, the action
appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.
What should happen, is that the main MDI form should close, taking the child
forms with it. There is code to loop through the child forms,...
|
by: Dany |
last post by:
Our web service was working fine until we installed .net Framework 1.1 service pack 1. Uninstalling SP1 is not an option because our largest customer says service packs marked as "critical" by Microsoft must be installed on their servers.
Now german Umlaute (ä, ü, ö) and quotes are returned incorrectly in SOAP fault responses.
This can be...
|
by: =?Utf-8?B?UHVjY2E=?= |
last post by:
Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
forms. I want allow users to move forward and backward with the forms and
retain the data users have entered. I thought I'll make the inactive forms
invisible but this is creating a memory corruption problem when user close
the form2 or form3 and not the formMain.
...
|
by: Motoma |
last post by:
This article is cross posted from my personal blog. You can find the original article, in all its splendor, at http://motomastyle.com/creating-a-mysql-data-abstraction-layer-in-php/.
Introduction:
The goal of this tutorial is to design a Data Abstraction Layer (DAL) in PHP, that will allow us to ignore the intricacies of MySQL and focus our...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
| |
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it. ...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...
| |