Search This Blog

Loading...

Wednesday, September 26, 2007

SVN4DW - Hard to Find SVN Extension for Dreamweaver


I've been using this extension for a while and it's pretty handy for updating/committing code from/to your SVN repository. I tried to find it on the net tonight so I can install it at home but it seems to have vanished. So I looked through my work PC and there it was. Awesome! For those folks that like to use it, I've put it up on my personal site. The link is http://tech-cats.net/blog/downloads/SVN4DW.zip

Querying Active Directory Through SQL Server

Integrating your application with Active Directory (or another LDAP based directory) is a common requirement in many business applications. Almost every language has a way to query LDAP but little known is the approach of integrating SQL Server with your LDAP controller. This quick article will guide you through setting up and using LDAP queries through SQL Server 2000 with Active Directory as the LDAP controller.

First, you need to create a SQL Server linked server. Set it up through SQL Server Enterprise Manager:

  1. Open SQL Server Enterprise Manager
  2. Go to the database server to which you will be adding the linked server
  3. Expend "Security"
  4. Right-click on "Linked Servers" and click on "New Linked Server..."
  5. Fill in the following:
    1. Under the General tab:
      1. Linked Server: adsi (or whatever you want to call it)
      2. Server type: select Other Data Source
      3. Provider name:select OLE DB Provider for Microsoft Directory Services
      4. Under Provider Options: check that Allow InProcess is checked
      5. Leave the rest of the fields blank
    2. Under the Security tab:
      1. Local Login: sqlServerUser
      2. Remote User: ntaccount@domain.com (such as bkostadinov@ica.com or ica.com\bkostadinov)
      3. Remote Password: userPassword for the above domain account
Through Query Analyzer:
  1. Change the "AllowInProcess" registry key under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\ADSDSOObject to "dword:00000001"
    1. Edit the registry manually or put the following in a .reg file and execute it:
      Windows Registry Editor Version 5.00
      
      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\ADSDSOObject]
      
      "AllowInProcess"=dword:00000001
            
  2. Open Query Analyzer (or your choice of query tool)
  3. Connect to the server to which you will be adding the linked server
  4. Change the provided values and execute the following code:
-- Change 'adsi' to the desired name of the linked server
exec sp_addlinkedserver
  'adsi',
  '',
  'ADSDSOObject',
  ''
go

-- Change 'adsi' to the desired name of the linked server
-- Change 'sqlUser' to the username of local sql server user
-- Change 'domainName\userName' to a domain account
-- (the format can be 'domainName\userName' or 'userName@domainName')
-- Change 'domainUserPassword' to the password of the domain account
exec sp_addlinkedsrvlogin
  'adsi',
  false,
  'sqlServerUser',
  'domainName\userName',
  'domainUserPassword'
go

Or you can just fill in the values on top of the following script and run that:

declare @linkedServerSql nvarchar(4000),
  @linkedServerName varchar(100),
  @localSqlUsername varchar(100),
  @domainUsername varchar(100),
  @domainUserPassword varchar(100)

-- Set the local sql server user
set @localSqlUsername = 'sqlUser'
-- format can be 'domainName\userName' or 'userName@domainName'
set @domainUsername = 'domainName\userName'
set @domainUserPassword = 'domainUserPassword'

set @linkedServerName = 'adsi'

set @linkedServerSql = '
  exec sp_addlinkedserver
  ''' + @linkedServerName + ''',
  '''',
  ''ADSDSOObject'',
  '''' 

exec sp_addlinkedsrvlogin
  ''' + @linkedServerName + ''',
  false,
  ''' + @localSqlUsername + ''',
  ''' + @domainUsername + ''',
  ''' + @domainUserPassword + ''''

exec sp_executesql @linkedServerSql
Run a query to verify that the linked server works. The query below will give you all the users in the dc=ica,dc=com (change that to match your own domain):
select  *
from  openquery(adsi, '
select  givenName,
    sn,
    sAMAccountName,
    displayName,
    mail,
    telephoneNumber,
    mobile,
    physicalDeliveryOfficeName,
    department,
    division
from    ''LDAP://dc=ica,dc=com''
where   objectCategory = ''Person''
        and
        objectClass = ''user''
')
Below, is an alternate syntax which you can use to apply ldap filters with almost universal syntax. The following will get all the users in LDAP but limit the result set to those users who's "given" & "sn" names are not empty. It will also apply a filter to the "division" attribute and exclude any records that match "system" and "generic".
declare @ldapFilter nvarchar(1000), @ldapSQL nvarchar(4000)

-- Set the filter to exlude objects that have a division of "System" and "Generic"
set @ldapFilter = '(!division=System*)(!division=Generic)'

-- Create an ldap query to get all users under dc=ica,dc=com
set @ldapSQL = '
select  givenName as firstName,
        sn as lastName,
        displayName,
        lower(sAMAccountName) as accountName,
        telephoneNumber as phoneNumber,
        mobile as cellPhoneNumber,
        mail as emailAddress,
        department,
        physicalDeliveryOfficeName as siteName
from    openquery(adsi, ''<LDAP://dc=ica,dc=com>
    (&(objectCategory=Person)(objectClass=user)'+ @ldapFilter + ');
        givenName,
    sn,
    sAMAccountName,
    displayName,
    mail,
    telephoneNumber,
    mobile,
    physicalDeliveryOfficeName,
    department,
    division;
    subtree'')
where   givenName is not null
    and
    sn is not null'

exec sp_executesql @ldapSQL

Some things to note:

"LDAP" is case sensitive, if you try using "ldap", the query will throw an error.

Querying the Active Directory server will work fine from Query Analyzer even if you do not run sp_addlinkedserverlogin. However, if you try to execute the query from the web (with something like ColdFusion, you will get an error similar to:

[Macromedia][SQLServer JDBC Driver][SQLServer]OLE DB provider 'ADSDSOObject' reported an error. The provider indicates that the user did not have the permission to perform the operation.

Tuesday, September 25, 2007

Web Application Deadly Sin

I have ran across this situation more than a couple of times recently. First it was my hosting provider, than the new web application I tried today (called Fuser). When signing up, they let you pick your password and I use a totally random password each time somewhere around 16-20 characters. So it happens that the applications above, cut my password to their allowed length but do not let me know they are doing so. Nowhere does it say that the password should be 10 or 15 characters. So end up with a newly created account that I cannot log into only to find out (after I go through the "forgot password" procedure) that my password was chopped. That is annoying and enough to turn me off using the application. Common sense, where are you?

Reactor Oops - Case Sensitive Dictionary XML

Here is the message I got today while trying to do some work with reactor and model-glue.

Message An error occurred while Transforming an XML document.

Detail Empty expression!

Extended Info

Tag Context D:\_Webroot\reactor\core\objectTranslator.cfc (149) D:\_Webroot\reactor\core\objectTranslator.cfc (164) D:\_Webroot\reactor\core\objectTranslator.cfc (164) D:\_Webroot\reactor\core\objectTranslator.cfc (101) D:\_Webroot\reactor\core\objectFactory.cfc (223) D:\_Webroot\reactor\reactorFactory.cfc (80) D:\_Webroot\reactor\base\abstractRecord.cfc (393) D:\_Webroot\reactor\project\myproject\Validator\usersValidator.cfc (10)

It turned out that the dictionary file that reactor generated is case sensitive. I need to change "<Users>" to "<users>". The table is defined as "users" but I had to change it to "<Users>" on my home machine. It seems that reactor can't make up it's mind on how it wont's the table to be called. Why is it "Users" at home and "users" at work? I'm using Apache on Windows with the same version of MySQL and reactor on both machines.

Update: So I just learned that:

<cfset usersRecord = variables.reactor.createRecord("users") />
is not the same as:
<cfset usersRecord = variables.reactor.createRecord("Users") />
The dictionary file was created with "Users" as the table name so reactor was looking for the same case. I think this is only an issue with MySQL.

Updating Web Applications in Production

Disclaimer: This is just an idea so far, but it is worth documenting so I remember to do it. It also assumes that you are using some kind of source control system such as Subversion.

Wouldn't it be cool to know when your production web application is out of date? By that I mean there is a newer version of it available in your source code repository. So instead of the usual steps:

  1. Check-in latest changes to the application
  2. Go to the production sever and update the code from the repository
  3. Reinitialize the application (I use Model-Glue)

You can simply:

  1. Check-in latest changes to the application
  2. Go to the web application in production
  3. Click a button to updated to the latest revision

Same number of steps I guess but doesn't the second solution seem so much nicer. I will have to implement this across all the web applications I maintain/develop.

Thursday, September 20, 2007

CSSVista - Edit your CSS code live on Internet Explorer and Firefox

I came across this pretty nice tool called CSSVista. It lets you edit css on the fly. Sure, the web developer toolbar and Firebug already does this for Firefox but it's still cool.

JSValidation Kicks Butt - Validation Library for Prototype.js

to get it to work, simply include the library like so:

<script language="javascript" type="text/javascript" src="js/jsvalidate/jsvalidate.js"></script>
Add some css styles:
.jsvalidation { color: #ff0000; font-size: 14px; }
add "jsrequired" (for a required field) and the jsvalidate type (such as "jsvalidate_number") to the "class" attribute of your text element.
<input type="text" name="year" id="year" size="4" class="jsrequired jsvalidate_number" />
and finally set the message to be displayed when the validation fails in the "alt" attribute of the element:
<input type="text" name="year" id="year" size="4" class="jsrequired jsvalidate_number" alt="Please enter a Year" />
More on the jsvalidation types at the docs

Monday, September 17, 2007

Quake Style Command Prompt - Cool Stuff

This is based on the guide provided on Instructables. I'm posting this here because I finally got around trying this out. I have to say it's pretty nice. The idea is simple. You press the Windows key + '~' (tilda) and get a semi-transparent console window in the top left corner of your screen. You press the same combination key again and the window disappears. Very handy for those of us that use the command prompt often. Here is the end result. Click on the thumbnail to see a larger picture: To get started: 1. Get AutoHotkey 2. Download the last stable version of Console (as of 09.17.2007 that is 1.5 so get "Console-1.5.zip" 3. Get the customized "console.xml" file from the bottom of the Instructable or from here directly 4. Get the AutoHotkey script from the bottom of the Instructable or from here directly 5. Install AutoHotkey 6. Extract Console-1.5.zip to "c:\program files\console" or wherever you desire 7. Create a shortcut to "console.exe" in your "c:\windows" directory 8. Copy the customized "console.xml" to "c:\program files\console" (or wherever you installed Console) and overwrite the file that's there 9. Start the AutoHotkey script you got in step 4. You can also put a shortcut to the script in the "Startup" folder on your Start Menu.

Using Regular Expression in SQL Server

Who doesn’t love regular expressions?! If you don’t know what they are, you should take some time to learn. Regular expressions or from here on RegEx are a very powerful way to search/replace string within strings. That being said, almost any language supports RegEx and for a while I’ve been using them with SQL Server thanks to xp_pcre - Regular Expressions in T-SQL Here is an example use of two of the functions that come with the above extended sql server library:

declare @out varchar(8000)
declare @str varchar(500)

-- Create a string containing an ldap common name

set @str = lower(’LDAP://CN=APO Conference Room,OU=Locations,OU=APO,OU=Sites,DC=ica,DC=com’)

-- Strip everything from the string and replace with the ’ou’ that comes after ’ou=locations’

exec master.dbo.xp_pcre_replace @str, ’.*ou=locations,ou=(’w+).*’, ’$1’, @out out

-- Print the results
print @out

-- Create a string containing an ldap common name
set @str = lower(’LDAP://OU=SMD,OU=Sites,DC=ica,DC=com’)

-- Return 1 if there is a match of ’ou=’ followed by ’ou=sites’
select master.dbo.fn_pcre_match(@str, ’^ldap://ou=’w+,ou=sites’)
More information here: http://www.codeproject.com/database/xp_pcre.asp?df=100&forumid=16452&exp=0&select=1191266

Thursday, September 13, 2007

Draw Flow Charts Online

Download Squad just had a post about this nifty online tool. Anybody that draws diagrams (that means you Doug), will benefit from this. Draw Anywhere - easy online diagramming, flow chart

Disabling Forms with Prototype - Gotcha

I love using Prototype for all my JavaScript needs. Ajax calls are real easy with or without parameters. To get some form parameters to pass with your request, you would simply do:

var params = $('myForm').serialize();
and then you would disable the form like so:
$('myForm').disable();
However, here is a little gotcha I always seem to forget:
  • DO NOT disable the form before you read your form values
If you do, code such as:
$F('myFormFiled');
or
$('myForm').serialize();
will no longer work. By not working, I mean will just return empty and you will be beating your head against the desk.

Chad Vader - Funny Stuff

Whoever hasn't seen the Chad Vader creation of Matt Sloan and Aeron Yonda should. It's pretty amusing. You can find it at