Friday, March 13, 2009

finding multiple chars in password

I just interacted with an authentication system that one of it password rules is not to repeat a certain character 3 or more times.  So it mad me think of how I would accomplish this validation if I wrote the code.

First thing that came to mind is a regular expressions (RE), i've tried and tried and couldn't figure out a RE that would solve any character repeated more than 3 times in a string.  I guess I'm not an expert in RE!  If anyone can figure this out, i'd appreciate knowing the RE.

Therefore, i moved my logic to just loop within a loop.  Example below.

<cfloop from="1" to="#len(variables.tmpPassword)#" index="pos">

    <cfset curChar = Mid(variables.tmpPassword,pos,1)>
    <cfset curCharCount = 0>
   
    <cfset curPos = FindNoCase(curChar,variables.tmpPassword)>
    <cfloop condition="#curPos# GT 0">
        <cfset curPos = FindNoCase(curChar,variables.tmpPassword,curPos+1)>   
        <cfset curCharCount = curCharCount + 1>
    </cfloop>
   
    <cfif curCharCount GTE 3>
        <cfset eValidate.addValidationError("password","edu.psu.fps.cfc.fpsGTW.validateForPassword.4","The password you entered cannot contain three or more occurrences of the same character (#curChar#).")>
        <cfbreak />
    </cfif>
</cfloop>






Wednesday, March 11, 2009

using application.cfc and webservices / ajax

I'm not going to blog about how to use the application.cfc file, because there are a lot of experts out there that already has.  And Ray Camden has posted a CF8 "template" for application.cfc.  But i haven't seen anyone answer the question about using onRequest method within the application.cfc while using ajax / webservices in the same directory.

As most of you have already seen, the normal "template" for onRequest is as follows:

<cffunction name="onRequest" returnType="void">
<cfargument name="thePage" type="string" required="true">
<cfinclude template="#arguments.thePage#">
</cffunction>


But since ajax and webservices are actually CFC methodology this included code will break it.

Now I am not sure if the following cures all scenarios, but it gave me the ability to do webservices / ajax.

<cffunction name="onRequest">
  <cfargument name = "targetPage" type="String" required=true/>
 <cfif Right(arguments.targetPage,3) EQ "cfc">
 <cfparam name="url.method" default="">
<cfset variables.component = Left(arguments.targetPage,Len(arguments.targetPage)-4)>
 <cfset variables.component = Replace(variables.component,"/",".","ALL")>
<cfinvoke method="#url.method#" component="admissions.#variables.component#" returnvariable="methodOutput">
<cfif IsDefined("methodOutput")>
<cfwddx input="#methodOutput#" output="wddxOutput" action="cfml2js" toplevelvariable="rtnData">
<cfoutput>#wddxOutput#</cfoutput>
</cfif>

<cfelse>
<cfinclude template="/admissions/#Arguments.targetPage#">
</cfif>
</cffunction>


Notice two things:
  1. The onRequest page now checks to see the extension of the file being requested (CFC or CFM).  If it is a CFC it invokes a method instead of including it.
  2. The CFC section if the function 'RETURNS' it output, using the cfreturn tag, then we need to convert it to WDDX.  This is the standard CF methodology.



Wednesday, March 4, 2009

Moving Databases

After reading on how to harden MSSQL 2005 installation, I realized the current directory structure doesn't lend itself for easy management of hardening the SQL installation, therefore, I am on a quest of moving the logical files in the database to a directory structure that makes it easier to lock down.

To move a single database it is somewhat easy.

ALTER DATABASE [name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE [name] SET OFFLINE

[move physical files]

[ don't forget each file {data/tLog/fulltext} ]
ALTER DATABASE [name] MODIFY FILE (NAME = 'logicalname' , FILENAME =  'LogicalFilename'

ALTER DATABASE [name] SET ONLINE
ALTER DATABASE [name] SET MULTI_USER

Moving all the databases wasn't that difficult either, it was just remembering to exec() the sql.  Also, using a script all databases had to be setup the same.  I had one database that had more than one data file - 2 for data, 2 for indexes.  I had to do that one manually.

There is another way also, use sql to PRINT the needed sql commands, and then use those printed commands to execute in the order you need.