drupal

Archived Posts from this Category

Portland Drupal Meetup

Posted by Greg on 13 Jun 2007 | Tagged as: drupal, planetosl

Whew! Just got back from an excellent Drupal user group meeting here in Portland. I am delighted to see such a healthy community growing in my own back yard. The meeting was an interesting mix of tech folks and non-technical, Drupal veterans and newcomers. There was a bit of something for everyone, I think. I hope future meetups are equally as interesting!

Thanks to Centerstance for sponsoring the grub, O’Reilly and Apress for the door prize books, and the wonderful crew at the Oregon Bus Project for hosting the event.

OpenID and Drupal 4.7, Part 2

Posted by Greg on 30 Jan 2007 | Tagged as: ORVSD, OpenID, drupal, planetosl

User name validation - a quick look at the Drupal API reveals exactly the function I needed: user_validate_name()

To add user name validation to the OpenID Drupal module, add the following code to the openid_create_account_submit() function immediately after the $query = $_POST; statement:
if (user_validate_name($query['edit']['fullname']) != NULL) {
$error = user_validate_name($query['edit']['fullname']);
drupal_set_message('Name is invalid. '.$error, 'error');
header("Location: " . url('openid/get_email'));
exit(0);
}

Worked like a charm. Any user name submitted when registering using an OpenID is now validated against Drupal’s internal user name validation - alphanumeric characters and spaces only. Anything else drops the user back to the name and email request form with an error telling them why the name was rejected. Slick!

Now I just need to figure out how to map existing Drupal users in the database to OpenIDs. Anyone done that before?

UPDATE: Resolved the above question. Add a record to the authmap table with the user’s UID and OpenID. Make sure the OpenID is normalized (has the trailing slash).

UPDATE #2: Updated the diff file that shows what I changed from the stock OpenID Drupal module.

OpenID and Drupal 4.7

Posted by Greg on 30 Jan 2007 | Tagged as: ORVSD, OpenID, drupal, planetosl

What can I say beyond, “It works!”

Oh, all right. I suppose I could say a few things. The stock OpenID Drupal module works, but it needed a bit of improvement to be useful to us. OpenID on DrupalBy default, the OpenID module creates a Drupal user whose name is their OpenID. That is somewhat problematic, since OpenIDs tend to be somewhat lengthy. So lengthy, in fact, that I have yet to find a Drupal theme that handles them well. They usually either get cropped or overflow into the next column, depending on the CSS. Less than optimal.

We really want to use OpenID as the authentication for the OVSD systems. Justin and I were talking in IRC about his efforts to get it running with Drupal 5. I was feeling inspired, so last night I took a whack at it. With a remarkably-small amount of head-scratching, I was able to modify the stock OpenID Drupal module (v1.1.1) to pull the user’s full name from their OpenID profile and use it as their Drupal name.

I cracked open the openid.module file and made the following changes:

  1. First, we need to tell the OpenID consumer to grab the user’s full name from their OpenID profile. To do that, we change the request from this:
    $auth_request->addExtensionArg('sreg', 'optional', 'email');

    to this:
    $auth_request->addExtensionArg('sreg', 'optional', 'email,fullname');

  2. Now that we have the user’s full name, we need to store it for use later. To do that, we add a line in this statement:
    if ($sreg) {
    $_SESSION['sreg_email'] = $sreg['email'];
    }

    to look like this:
    if ($sreg) {
    $_SESSION['sreg_email'] = $sreg['email'];
    $_SESSION['sreg_fullname'] = $sreg['fullname'];
    }

  3. Now that we have the information we need, we can use it in the registration form. When the module gets a login request from a user not already in the Drupal user table, it prompts them to enter their e-mail address:
    $form['email'] = array('#type' => 'textfield',
    '#title' => t('Email Address'),
    '#default_value' => @$_SESSION['sreg_email'],
    '#size' => 25,
    '#maxlength' => 64,
    '#description' => t('Enter your email address.')
    );
    $form['submit'] = array('#type' => 'submit',
    '#value' => t('Submit')
    );
    $form['#action'] = url('openid/get_email');
    $content = sprintf("<h3>Create account with OpenID</h3><p>Before logging in " .
    "with your OpenID (%s), you must enter an email address:</p> %s",
    $_SESSION['openid'], drupal_get_form('openid_create_account',
    $form));

    So we just need to add the user’s full name to the registration form:
    $form['email'] = array('#type' => 'textfield',
    '#title' => t('Email Address'),
    '#default_value' => @$_SESSION['sreg_email'],
    '#size' => 25,
    '#maxlength' => 64,
    '#description' => t('Enter your email address.')
    );
    $form['fullname'] = array('#type' => 'textfield',
    '#title' => t('Full name'),
    '#default_value' => @$_SESSION['sreg_fullname'],
    '#size' => 25,
    '#maxlength' => 64,
    '#description' => t('Enter your full name.')
    );
    $form['submit'] = array('#type' => 'submit',
    '#value' => t('Submit')
    );
    $form['#action'] = url('openid/get_email');
    $content = sprintf("<h3>Create account with OpenID</h3><p>Before logging in " .
    "with your OpenID (%s), you must enter your name and email address:</p> %s",
    $_SESSION['openid'], drupal_get_form('openid_create_account',
    $form));

  4. Lastly, we need to create the user. The stock OpenID module sets the Drupal “name” field in the “users” table to be their OpenID here:
    $user = user_save('', array('name' => $_SESSION['openid'],
    'pass' => user_password(),
    'mail' => $query['edit']['email'],
    'init' => $_SESSION['openid'],

    To use the “fullname” variable we grabbed from the user’s OpenID profile, we just need to change it to this:
    $user = user_save('', array('name' => $query['edit']['fullname'],
    'pass' => user_password(),
    'mail' => $query['edit']['email'],
    'init' => $_SESSION['openid'],

I’ve posted a diff file that shows the exact changes from the stock OpenID Drupal module.

Security note: If you decide to use this code, be aware that there is no verification done on the user’s name yet. Whatever the user enters in the name field of the registration form is submitted directly into Drupal as the user’s name. So it’s possible there is a security/exploit issue if a malicious user puts something wacky in there. I need to wade into it the code and see if Drupal already has some safeguards in place, or whether I need to add a bit of sanitizing code to the module to ensure there’s nothing nasty embedded in the name. In the mean time, use at your own risk.

HOWTO: Embedding an OpenLaszlo application in Drupal

Posted by Greg on 15 Jul 2006 | Tagged as: drupal, howto, openlaszlo, planetosl

New job, new tools, new fun!

Being relatively new to the OSL, I have been gleefully learning some new tools. Specifically, Drupal and OpenLaszlo. In fact, I’m having so much fun with them I feel the need to share. So, with that in mind …

The problem. Well, OK, it’s not really a problem. Let’s call it a “challenge”. Drupal, for reasons too in-depth to go into right now, does not allow page authors to embed JavaScript directly into the body of a page. OpenLaszlo, on the other hand, uses JavaScript to embed applications in pages.

Hmm. So how does one embed an application developed in OpenLaszlo in a Drupal site?

Well, after a bit of head-scratching, this is what I learned:

Drupal has two handly little tools - drupal_add_js() and drupal_call_js() - to help. drupal_add_js() allows you to add external JavaScript files to the page header, and drupal_call_js() allows you to call the functions in the external scripts.

Normally, to embed an OpenLaszlo application you add the following code to the desired page:

<script src="/lps-3.3/lps/includes/embed.js" type="text/javascript"> </script>
<script type="text/javascript">
lzEmbed({url: 'AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
</script>

However (hah! You should have known it wasn’t going to be quite that easy), there are some small issues that need to be dealt with before it will work properly. First of all, the script assumes it is being run from the Laszlo server directly, rather than the Drupal server. So we need to copy the Laszlo embed.js resource script from the Laszlo server over to the Drupal server and turn that JavaScript into something Drupal-compatible using drupal_add_js():

drupal_add_js('/drupal/path/to/embed.js');

And we need to drop the rest of the JavaScript into a file (we’ll call it laszloapp.js) that we can load using drupal_add_js() and save it to the Drupal server filesystem:

function load() {
lzEmbed({url: 'http://laszloserver.org:8080/AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
}

To load the script into the Drupal page, we call it thusly:

drupal_add_js('/drupal/path/to/laszloapp.js');

Notice we have put the lzEmbed() function inside a load() function. This is because the drupal_add_js() function inserts the JavaScript (and therefore the Laszlo object) into the page head, above the rest of the page content. So to control where the Laszlo object is embedded in the page, we need to use the drupal_call_js() function to call the load() function from laszloapp.js. At the point in the page where you want to insert the Laszlo object:

<div id="laszlo_object">
<?php
$js = drupal_call_js(load);
return $js;
?>

Et voila! The Laszlo application loads within the “laszlo_object” div.

In a nutshell:

  1. Copy the embed.js file from the Laszlo server to the Drupal server
  2. Create a laszloapp.js file containing the following:
    function load() {
    lzEmbed({url: 'http://laszloserver.org:8080/AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
    }
  3. Add the following code to the Drupal page:
    <?php
    drupal_add_js('http://newosl.osuosl.org/themes/newosl/embed.js');
    drupal_add_js('http://newosl.osuosl.org/themes/newosl/oslmon.js');
    ?>
    <div id="laszlo_object">
    <?php
    $js = drupal_call_js(load);
    return $js;
    ?></div>