Issue Summary:

Why is it needed?
This module allows Drupal administrators to easily integrate the MYDIGIPASS.COM service into a Drupal website.
MYDIGIPASS.COM is an authentication service which uses two-factor authentication (password and one-time password) to identify users.

Why does it require an independent module?
This module is different from other Drupal modules because:

  • It integrates MYDIGIPASS.COM easily into the website and does some actions which are specific to MYDIGIPASS.COM
  • It integrates completely with the Drupal user account management: a MYDIGIPASS.COM can be linked to an existing Drupal user account or can be linked to a new Drupal user account.
  • This module does not duplicate code from other modules: it uses only standard Drupal functionality.
  • This module uses Drupal functions in almost all places. Examples are user_external_login() for authentication and drupal_http_request() for communication with MYDIGIPASS.COM

For a complete overview of the implemented functionality in the module, check the following requirements specification: http://mdpdemo.dev.vanstechelman.com/functional-requirements

Technical description:
Once enabled, the module adds a (configurable) button to the login and user registration form. This button allows to authenticate to MYDIGIPASS.COM. After successfull authentication, the end-user is redirected to a callback page (also provided by this module) which handles the authentication to Drupal. If the MYDIGIPASS.COM user is already linked to a Drupal user, the Drupal user is authenticated. Otherwise is wizard is shown which allows the end-user to link to an existing user or to create a new user.
The creation of the new user also takes into account the preferences of the Drupal site administrator regarding user registration (i.e. no registration at all or with/without administrator approval).

Module requirement:
None. In order to work, the Drupal site must be able to make HTTPS connections to the MYDIGIPASS.COM service.

Drupal version:
Drupal 6 (Drupal 7 is in the pipeline)

Repository:
http://git.drupal.org/sandbox/lva/1687376.git
git clone http://git.drupal.org/sandbox/lva/1687376.git mydigipass

Useful links:

Reviews of other projects:
http://drupal.org/node/1674674#comment-6249364
http://drupal.org/node/1630686#comment-6249470
http://drupal.org/node/1691664#comment-6249524
---
http://drupal.org/node/1479034#comment-6303118
http://drupal.org/node/1404202#comment-6302072
http://drupal.org/node/1707028#comment-6297966

Comments

cthiebault’s picture

Your code seems very good and follow Drupal standards :-)

A few things I found :

  • callback.inc.php, line 18: variable $client_id is unused
  • mydigipass.module, line 103: variable $user is unused
  • mydigipass.module, line 634 & 659: $output is defined and immediately overwritten.
lva’s picture

Hi Cedric,

Thank you for your review. I fixed the issues you mentioned.

lva’s picture

Issue tags: +PAreview: review bonus

Requesting "Review Bonus"

klausi’s picture

Status: Needs review » Needs work
Issue tags: -PAreview: review bonus +PAreview: security

Thank you for you reviews! When finishing your review comment also set the issue status either to "needs work" (you found some problems with the project) or "reviewed & tested by the community" (you found no flaws).

manual review:

  1. mydigipass_admin_settings_user_profile_fields_form(): $all_user_data_fields is third party provided input and needs to be sanitized before it can be use in #options on checkboxes form elements in Drupal 6. See http://drupal.org/node/28984 . I would say this is a security issue, correct me if I'm wrong.
  2. mydigipass_admin_settings_button_style_form(): all the user facing options should run through t() for translation.
  3. mydigipass_init(): please add a comment why you cannot use drupal_add_js().
  4. mydigipass_form_alter(): use l() to generate link markup, it is capable of attributes. Also elsewhere.

Otherwise this looks nearly ready. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

lva’s picture

Status: Needs work » Needs review
Issue tags: -PAreview: security

Hello Klaus,

Thank you for your manual review! I fixed your accurate remarks. Allow me to respond to the issues you found:

  1. You are correct. I shouldn't have trusted the input from the third party: it could pose quite some issues! I updated the code in this function by passing all external data through check_plain(). There was also some other code where I was using this third party data, I updated that as well.
  2. Correct. There is data which is user facing. My initial idea was that the data which is user facing is really specific to the API I implemented. Nevertheless this doesn't mean that a translator shouldn't be able to change it. So I wrapped the user facing data in t().
  3. From what I've understood from the drupal_add_js() function description, there is no way in which I can include a javascript from a third party website in Drupal 6. In D7 there is the 'external' option parameter, but I haven't found a way to mimic this in D6. Please correct me if I'm wrong or missing something.
  4. I've changed the different pieces of code which rendered the button. I followed the API implementation guide a bit to strict there.

I'm changing back to "needs review" since I believe I fixed the issued you mentioned. I have also already checked that my changes did not introduce any coding standard issues by checking through PAReview.

lva’s picture

Issue tags: +PAreview: review bonus

I added 3 more project reviews.
Requesting another review bonus.

Yaron Tal’s picture

I didn't find any real problems with your modules, these are mostly little hints and some realy small tweaks.

Manual review:
For your include files, there is no need to add .php behind the .inc. You could name then callback.inc and mydigipass.admin.inc (no need to change it everywhere, just saying).

When adding the validation handlers to the forms:

$form['#validate'] = array_merge(array('mydigipass_enforce_authentication_mode_during_login'), $form['#validate']);

You could also use array_unshift().

array_unshift($form['#validate'], 'mydigipass_enforce_authentication_mode_during_login');

In you comments on line 181-.. you mention that you need the hidden value, because the validation handler expects it. You know you can also use the type "value" which is not send to the browser at all?
http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.ht...

On line 219/290/353/459/... you do a SELECT COUNT(*) to check if a result exists. SELECT 1 would have the same result, but a tiny bit faster.

In a couple of SQL queries you select from multiple tables and join them with a where statement. I am not sure which version is faster, but since Drupal mostly uses JOINs I'd advice using those since it would make them easier readable.
$sql = "SELECT UD.attribute_value FROM {mydigipass_user_link} UL, {mydigipass_user_data} UD WHERE UL.drupal_uid = %d AND UL.mdp_uuid = UD.mdp_uuid AND UD.attribute_key = 'email'";
vs
$sql = "SELECT UD.attribute_value FROM {mydigipass_user_link} UL LEFT JOIN {mydigipass_user_data} UD ON UL.mdp_uuid = UD.mdp_uuid WHERE UL.drupal_uid = %d AND UD.attribute_key = 'email'";

on line 239 you have a subselect, which I think is not needed. I am not 100% sure, but I think this would do the same (a tiny bit) faster:

SELECT * 
FROM {mydigipass_user_link} UL
LEFT JOIN {mydigipass_user_data} UD ON UL.mdp_uuid = UD.mdp_uuid
LEFT JOIN {mydigipass_profile_fields} PF ON PF.name = UD.attribute_key
WHERE UL.drupal_uid = %d AND PF.name IS NOT NULL
ORDER BY UD.attribute_key";

On line 302/423/... I don't think drupal_goto(); works that way (with ). Just give it an empty string to redirect to the frontpage: drupal_goto('');

On line 577 you might want to add a watchdog call so an admin at least gets a message that something is wrong.

In your hook_schema in the .install file:
{mydigipass_user_link} probably also needs a unique index on drupal_uid (this is unique right?) because I noticed some queries on it.

In mydigipass.admin.inc.php
On line 189 you delete all rows. Truncate is faster and also works in all D6 (and D7) supported database engines.

On line 198 you have this line:

$success &= db_query($sql, $value);

1. Why is this by reference?
2. By overwriting this value every time you only save the success of the last query.
I'd make it something like:

$success = db_query($sql, $value) && $success;

Callback.inc.php
On line 115 COUNT() is not all-capitals.

Overall nice module! Setting it to RTBC since there are no real errors. If the module gets approved before you have the chance to look at these things, just copy them to your issue queue and put it on the lowest priority.

Yaron Tal’s picture

Status: Needs review » Reviewed & tested by the community
lva’s picture

Waw! Nice feedback! I reviewed your remarks and fixed most of them. Some replies:

  • About redirecting to the front page using drupal_goto: it is allowed to use the '<front>' since the path argument is passed to the url() function and '<front>' is a explicitly defined in url().
  • And about adding a watchdog call when something would not be correctly set: I'm doing a watchdog call, but in the functions which called the _mydigipass_get_endpoint_url(). This allows me to give a bit more sense and context in the watchdog message.

So the remaining open items are updating the SQL queries with JOIN.

klausi’s picture

Status: Reviewed & tested by the community » Fixed

manual review:

  • "$form['mail']['#default_value'] = check_plain($mdp_email);": do not use check_plain() on #default_value, the form API will sanitize that for you. See http://drupal.org/node/28984

But that is not an application blocker, so ...

Thanks for your contribution, lva!

I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.

Here are some recommended readings to help with excellent maintainership:

You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!

Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

Thanks to the dedicated reviewer(s) as well.

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Added 3 more reviews to apply for one more review bonus.