User System Hacks


Though they are strongly related, the user modules are actually separate from the registration module. Changes to the latter only indirectly affect the user data. For example, requiring additional fields during the registration process is great for initially populating user information, but nothing prevents a user from editing his information and deleting all that data after he is registered. To protect user data you want to maintain, you need to hack the user system.

Requiring Fields in User Management

This hack works very similarly to the steps outlined for required fields during registration, but because of the way the NS-Your_Account files are written, the User Management version is a bit easier. This hack edits the form users reach by entering their account management area.

Two files are relevant to this change:

 /modules/NS-Your_Account/user/modules/changeinfo.php /modules/NS-NewUser/lang/eng/global.php 

The global.php file contains the descriptive text displayed in the form, but because this form already has most of the text you need defined, you should only need to add one new global variable unless you want to expand on the default wording of other text.

You can set any of the form fields to be required, but to complete your example from earlier in the chapter, you need to make changes to the Real Name field.

Tip

Additional fields not present in the standard release can also be added and made required. The process is more complex, but it can be made easier by converting one of the existing fields you don't need into the new one. Change the old field in the database, and hunt down references to it in the user files.


Open the changeinfo.php file in your editor and scroll down to line 81. You should see these lines:

 case "_UREALNAME":     echo "<input type=\"text\" name=\"name\" value=\"" . pnVarPrepForDisplay(pnUser GetVar('name')) . "\" size=\"30\" maxlength=\"60\">" . "&nbsp;" . _OPTIONAL . "</td>";     break; 

This is the code that writes out the field users see in their management form. Just like the registration system, the name attribute also contains the value "name" here. It also has a convenient reference to the _OPTIONAL global that prints out the "(optional)" text at the end of the form element. You can see from scanning the surrounding other fields that there is also a _REQUIRED global predefined and ready for you to use.

You know the field will be required soon, so go ahead and change the code to have the required label:

 case "_UREALNAME":     echo "<input type=\"text\" name=\"name\" value=\"" . pnVarPrepForDisplay(pnUse rGetVar('name')) . "\" size=\"30\" maxlength=\"60\">" . "&nbsp;" . _REQUIRED . "</td>";     break; 

Now scroll down to function saveuser() at about line 245. Also identical to the registration hack, the "name" value is converted into the $name variable in this function. At about line 298, the function starts validating the required fields. It is in that area you need to add a new check for the Real Name field. The exact positioning doesn't matter, other than it needs to not be nested in another check. Place it at the top after the password checks. The inserted code is nearly identical to the example earlier in the chapter, and the completed change looks like this:

 if ((isset($pass)) && ("$pass" != "$vpass")) {     $htmltext = "<div style=\"text-align:center\"><span class=\"pn-title\">" . _PASSDIFFERENT . "</div></span><br /><br /><br /><br />";     edituser($htmltext); } elseif (($pass != "") && (strlen($pass) < $minpass)) {     $htmltext = "<div style=\"text-align:center\"><span class=\"pn-title\">" . _YOURPASSMUSTBE . " $minpass " . _CHARLONG . "</div></span><br /><br /><br /><br />";     edituser($htmltext); // Code below added for required Real Name field validation } elseif ((!$name)|| ($name=="")|| (!preg_match("/^[a-zA-Z \.\'\-]+$/", $name))) {     $htmltext = "<div style=\"text-align:center\"><span class=\"pn-title\">". _REALNAMEINVALID."</div></span><br />";     edituser($htmltext); } else { 

The new code begins on the eighth line at the second elseif. It checks to see if the field is blank or if it contains any characters other than letters, spaces, hyphens, apostrophes, or periods. Common contracted or combined names are allowed, as well as middle initial use. More specific checks can be made, and the check should be customized to the field you want to validate.

The new code also makes a call to the _REALNAMEINVALID variable. For the last change in this hack, you need to edit the global.php file mentioned earlier and add this line:

 define('_REALNAMEINVALID','The real name you have entered contains characters that are not allowed. Please try again.'); 

Keep the sort order of the globals by placing the line after _PERSONALINFO. Now, the Real Name field is required for your users.

Disabling/Enabling User Logins

Another handy addition to the PostNuke feature set is the capability to toggle user login capability. Suppose, for example, you are in the process of moving the site to a new host. If you've already pulled all the database content and files, but the switchover hasn't happened, you don't want users going to the old site and adding content that will be lost in the change of sites. This capability is also handy if you're trying out a new site feature visible only to logged-in users. You can lock the users out during final testing, and then toggle the logins back on when you're ready to open the doors.

Note

This hack prevents new logins, but existing users retain access until they log out or visit the site's home page.


There are two main parts to this hack: creating the administrative toggle option in Website Settings and adding the additional security check to the login system.

Creating Login Toggle

First create the toggle option for your site. Open this file in your editor:

 /modules/NS-Settings/lang/eng/global.php 

You need to add two new text entries at about line 59, just after the _LOCALEFORMAT definition. The additions are this:

 define('_LOCKLOGIN','Lock User Login'); define('_LOCKLOGININFO','(This will prevent anyone but administrators from logging in to the site.)'); 

The text in these fields describes the form element. You can close that file out of your editor and open this one next:

 /modules/NS-Settings/admin.php 

Scroll down roughly halfway through the file to line 301. Just before the _BLOCKSINARTICLES code and after the preceding select close and HTML table row break, add these lines:

 // Login lockout hack addition ._LOCKLOGIN.'</td><td class=\"pn-normal\">' ."<input type=\"radio\" name=\"xloginlocked\" value=\"0\" class=\"pn-normal\"$sel_ loginlocked[0] />"._YES.' &nbsp;' ."<input type=\"radio\" name=\"xloginlocked\" value=\"1\" class=\"pn-normal\"$sel_ loginlocked[1] />"._NO."&nbsp;&nbsp;"._LOCKLOGININFO ."</td></tr><tr><td class=\"pn-normal\">" 

The tables are split between the echo lines, so to make it perfectly clear, the code with the preceding addition looks like this:

 .'</select>' ."</td></tr><tr><td class=\"pn-normal\">" // Login lockout hack addition ._LOCKLOGIN.'</td><td class=\"pn-normal\">' ."<input type=\"radio\" name=\"xloginlocked\" value=\"0\" class=\"pn-normal\"$sel_ loginlocked [0] />"._YES.' &nbsp;' ."<input type=\"radio\" name=\"xloginlocked\" value=\"1\" class=\"pn-normal\"$sel_ loginlocked [1] />"._NO."&nbsp;&nbsp;"._LOCKLOGININFO ."</td></tr><tr><td class=\"pn-normal\">" ._BLOCKSINARTICLES.'</td><td class=\"pn-normal\">' 

This code adds the new form elements to the page, duplicating the style used by other similar elements. It's important to note that the yes/no options used on this page are reversed from what you might think with a binary toggle. Yes is represented by "0," and No is represented by the "1" value.

Now scroll back up in the file to about line 87 and insert the following lines just before the first $sel_nobox.

 $sel_loginlocked['0'] = ''; $sel_loginlocked['1'] = ''; $sel_loginlocked[pnConfigGetVar('loginlocked')] = ' checked="checked"'; 

This code preps the form elements and defines which should be selected based on information stored in the database. As this is a new field, it does not exist in the database yet, so you must create it. Find the nuke_module_vars table using your database administrative tool. Enter a new row of data with the values in Table 23.1.

Table 23.1. Login Toggle Database Values

FIELD

VALUE

pn_modname

/PNConfig

pn_name

loginlocked

pn_value

s:1:"1";


The seed value of "1" for loginlocked sets the form element to "no" by default. After the database entry is done, the toggle in Website Settings works. When you submit the form, it changes the database value.

Toggle Check at Login

Now, you need to tie the loginlocked value to whether users can log in. Back in your text editor, load up the login access file:

 /modules/NS-User/user/access.php 

The access_user_login function at about line 41 performs the login operation itself. Failed logins are redirected to the user login screen to try again.

You need to set up two operations. The first is to see if the new toggle variable is set to "0." The second is to see if the user logging in is an administrator. This way, if the logins are locked, administrators can still successfully log in to the site.

These operations could be done in the access.php file, but although the login operation takes place there, the security information associated with the user is cached and is not updated to reflect the login until a new page is loaded. After login, the user is redirected back to the page she came from using the $url variable. It's at that point that you need to add the new security check, but you can't add checks to every page the user might be coming from. The easiest solution is to send all incoming users to the root home page after a login. Then, the check can be added there to secure the site.

Change the existing access_user_login function to look like this:

 function access_user_login($uname, $pass, $url, $rememberme) {     if (pnUserLogIn($uname, $pass, $rememberme)) { //      Original redirect changed for login lock toggle. //      redirect_index(_LOGGINGYOU, $url);         redirect_index(_LOGGINGYOU, '/index.php');     } else {         pnRedirect('user.php?stop=1');     } } 

Now go to the index.php file in your PostNuke root folder. Add the check at the top of the file, just after the list variable assignments. Add the following code at about line 48:

 if (pnUserLoggedIn()) {     if (pnConfigGetVar('loginlocked') == 0) {         if (!(pnSecAuthAction(0, '.*', '.*', ACCESS_ADMIN))) {             pnUserLogOut();             $ThemeSel = pnUserGetTheme();             echo "<html><head><meta http-equiv=\"refresh\" content=\"4; url=/index.php\">\n";             echo "<link rel=\"stylesheet\" href=\"".WHERE_IS_PERSO."themes/$ThemeSel/style/styleNN.css\" type=\"text/css\">";             echo "<style type=\"text/css\">";             echo "@import url(\"".WHERE_IS_PERSO."themes/$ThemeSel/style/style.css\"); ";             echo "</style>\n";             echo "</head><body bgcolor=\"$GLOBALS[bgcolor1]\" text=\"$GLOBALS [textcolor1]\">\n";             echo "<div style=\"text-align:center\" class=\"pn-title\">". _NOLOGINAVAILABLE."</div></body></html>";             exit;         }     } } 

The first if statement checks to see whether the user is logged in. If not, the entire script is ignored. The second check examines the loginlocked value in the database to see if it is turned "on." If that passes, the third statement calls pnSecAuthAction to see if the user is an administrator. If not, the short page code is written out with the text message contained in _NOLOGINAVAILABLE.

Tip

This hack is designed to allow administrators to log in when everyone else is locked out, but the pnSecAuthAction function can be used to identify any group of users. You could create a special group named "Backup" or "BetaTesters" who are allowed to log in to the site when regular users are excluded. This group could be made of both administrators and special users.


The meta refresh line displays the message for four seconds with the preceding code. You can change that variable to be longer if you want to provide a larger message.

The message itself is defined by opening the global global.php file in your editor:

 /language/eng/global.php 

At about line 274, just after the _NOEDITORIAL definition, add this line:

 define('_NOLOGINAVAILABLE','User logins are currently disabled. Please try back later.'); 

As stated earlier, the message you tell your users can be anything. You can just as easily write "down for maintenance" or provide a date or time when the logins will be reinstated. If you use this feature often, you might want to edit the message each time to personalize it to the occasion the way businesses update their voice mail messages daily.

The only limitation to this hack is that it does not prevent users who are currently logged in from staying on the site. Anyone who returns to the home page will be logged off, but there is no way to force them to browse there.



    PostNuke Content Management
    PostNuke Content Management
    ISBN: 0672326868
    EAN: 2147483647
    Year: 2003
    Pages: 207
    Authors: Kevin Hatch

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net