Drupal

Fixing "Page not found" in Drupal's OpenID

It is very often when you enable OpenID module in Drupal and try to login with OpenID, you receive "Page not found", whilst everything works quite fine at localhost.

The problem occurs after you have authenticated at OpenID provider website and it is redirecting you back to your website with URL in format: http://www.gerixsoft.com/openid/authenticate?destination=user&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&...

The problem is that params of this redirect URL contain another URLs. Such kind of URLs are considered dangerous and are very often blocked by hosters by means of Apache mod_security module; it is mod_security that actually generates 403/404/Page not found.

One solution is to follow guidelines found on the net and ask your hosting provider to disable 1234234, 340151, 340153, 340163 mod_security rules. However after some time modifications may be reset and you will face the problem again. Another option is to disable mod_security but this is not secure and may expose your site to even bigger problems.

The solution I have come to is to selectively reverse the effect of mod_security in PHP code. The patch I have developed undoes 403/404 generated by mod_security for OpenID URLs only, rest of URLs are not touched. So both OpenID works and website is protected.

Just open index.php and put below code at line 20, just below "$return = menu_execute_active_handler();" code:

// © by Andriy Gerasika from GerixSoft, Ltd.
if (is_int($return) && $return == MENU_NOT_FOUND) {
	$uri = $_SERVER['REQUEST_URI'];
	$path = parse_url($uri, PHP_URL_PATH);
	if ($path == '/openid/authenticate' || ereg('^/user/[0-9]+/openid$', $path)!=false) {
		$path = substr($path, 1);
		$query = 'q=' . $path . '&' . parse_url($uri, PHP_URL_QUERY);
		$_SERVER['QUERY_STRING'] = $query;
		parse_str($query, $_REQUEST);
		parse_str($query, $_GET);
		$return = menu_execute_active_handler();
	}
}

P.S.
Now, once OpenID works in Drupal ok, you may give a try to my OpenID Selector Drupal module ;)

OpenID Selector for Drupal

Drupal's OpenID module is somewhat not complete.

If you enable OpenID module in Drupal, it modifies user/login screen with "Log in using OpenID" link:

and when you click on that link, OpenID login form pop's up:

This form was always puzzling me: instead of remembering passwords, are now users supposed to remember their OpenID URLs?

For example, Google's OpenID URL format is "https://www.google.com/accounts/o8/id?id=<40-digit hash code>", and if user wants to login w/ Gmail account, is user supposed to type-in that string, or copy-paste the string from some place?

This form does not make Drupal's default login form any simpler, it makes it only harder. That's why I was never enabling OpenID module on any of my Drupal sites.

However, recently I was visiting SourceForge, and noticed they have incorporated OpenID login in a lot nicer form:

 

After viewing page source, I have figured out they are using openid-selector Javascript library from http://code.google.com/p/openid-selector/

Brief googling for "Drupal OpenID selector" did not produce any reasonable/good looking results except some weird commerical product at https://www.idselector.com/ (why make so simple thing so complex?)

Then I decided to write my own module integrating Javascript OpenID selector into Drupal.

After one day of heavy tweaking, I was able to marry it w/ Drupal's OpenID module.

Below is a screenshot of how OpenID login form now looks at http://www.gerixsoft.com/user/login

 

User profile's "OpenID identities" form at "/user/<id>/openid" has been enhanced w/ openid-selector as well.

Now, I release the module integrating OpenID Selector w/ Drupal as open source under GPL v2 license. You can find it attached.

Feel free to use it on your websites and unveil the true power of Drupal's OpenID module!

P.S.
The only drawback of the module is that it requires patching of Drupal core. After you've enabled it, you should open /modules/openid/openid.js, and comment out the following code (at line #23 as of Drupal version 6.17):

      $("#edit-openid-identifier")[0].focus();

You should restore(uncomment) this line back on disabling the module.

Drupal in WordPress LinkedIn application

In this article I will show how I have integrated Drupal feed from www.gerixsoft.com into WordPress application on LinkedIn.

When I first tried to add GerixSoft's feed into WordPress application, it refused saying "Only WordPress feeds are supported". After comparing Drupal and WordPress feeds, I have figured out they are using the same RSS standard. The only difference is meta "generator" element, absent on Drupal but present on WordPress XML.

Wild guess have confirmed that WordPress is using this string to block RSS from non-WordPress platforms.

To fix this, open includes/common.inc, locate format_rss_channel function and apply the following patch:

 /**
 * Formats an RSS channel.
 *
 * Arbitrary elements may be added using the $args associative array.
 */
function format_rss_channel($title, $link, $description, $items, $langcode = NULL, $args = array()) {
  global $language;
  $langcode = $langcode ? $langcode : $language->language;

  $output = "<channel>\n";
  $output .= ' <title>'. check_plain($title) ."</title>\n";
  $output .= ' <link>'. check_url($link) ."</link>\n";

  // The RSS 2.0 "spec" doesn't indicate HTML can be used in the description.
  // We strip all HTML tags, but need to prevent double encoding from properly
  // escaped source data (such as &amp becoming &amp;amp;).
  $output .= ' <description>'. check_plain(decode_entities(strip_tags($description))) ."</description>\n";
  
  
  // © by Andriy Gerasika from GerixSoft, Ltd.
  $output .= "<generator>http://wordpress.org/?v=MU</generator>\n";


  $output .= ' <language>'. check_plain($langcode) ."</language>\n";
  $output .= format_xml_elements($args);
  $output .= $items;
  $output .= "</channel>\n";

  return $output;
}

Note, when you'll be resubmitting feed into WordPress application, it still might say feed is not from WordPress – just try several times and it will accept the feed ultimately (seems there is some sort of cache on the server).

Syndicate content