? tokenauth_ui.patch
Index: tokenauth.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tokenauth/tokenauth.info,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 tokenauth.info
--- tokenauth.info	10 Nov 2006 23:34:02 -0000	1.1
+++ tokenauth.info	29 May 2007 07:28:15 -0000
@@ -1,3 +1,4 @@
 ; $Id: tokenauth.info,v 1.1 2006/11/10 23:34:02 weitzman Exp $
 name = Token authentication
-description = "Enable feed readers and other simple clients to see certain private pages by providing an authentication token"
\ No newline at end of file
+description = Enable aggregators, feed readers and other simple clients to see restricted content by providing an authentication token.
+version = "$Name:  $"
Index: tokenauth.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tokenauth/tokenauth.module,v
retrieving revision 1.8
diff -u -p -u -p -r1.8 tokenauth.module
--- tokenauth.module	11 Mar 2007 13:33:38 -0000	1.8
+++ tokenauth.module	29 May 2007 07:28:15 -0000
@@ -1,23 +1,224 @@
 <?php
 // $Id: tokenauth.module,v 1.8 2007/03/11 13:33:38 weitzman Exp $
 
+/**
+ * Implementation of hook_perm().
+ */
+function tokenauth_perm() {
+  return array('access tokenauth', 'administer tokenauth');
+}
+
+/**
+ * Implementation of hook_settings().
+ */
+function tokenauth_admin_settings() {
+
+  $form['tokenauth_general'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Token settings'),
+  );
+  $form['tokenauth_general']['tokenauth_length'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Token length'),
+    '#size' => 4,
+    '#maxlength' => 4,
+    '#required' => TRUE,
+    '#default_value' => variable_get('tokenauth_length', 10),
+    '#description' => t('Only used for new users and when tokens are reset. If this value is changed you need to save the settings for it to take effect, i.e. before you hit reset'),
+  );
+  $form['tokenauth_general']['tokenauth_pages'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Activate Tokens on specific pages'),
+    '#default_value' => variable_get('tokenauth_pages', "rss.xml\n*/feed\n*/opml"),
+    '#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>')),
+  );
+
+  $form['tokenauth_advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Token actions'),
+    '#description' => t('Reset the tokens for all users.'),
+  );
+  $form['tokenauth_advanced']['tokenauth_reset'] = array(
+    '#type' => 'submit',
+    '#value' => t('Reset tokens')
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function tokenauth_menu($may_cache) {
+  global $user;
+
+  $items = array();
+
+  if ($may_cache) {
+    $items[] = array(
+      'path' => 'admin/settings/tokenauth',
+      'title' => t('Token auth'),
+      'description' => t('Configure Token auth behavior.'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => 'tokenauth_admin_settings',
+      'access' => user_access('administer tokenauth')
+    );
+    $items[] = array('path' => 'admin/settings/tokenauth/reset',
+      'title' => t('Reset tokens'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('tokenauth_reset_confirm'),
+      'access' => user_access('administer tokenauth'),
+      'type' => MENU_CALLBACK
+    );
+  }
+  else {
+    if (arg(0) == 'user' && is_numeric(arg(1))) {
+      $items[] = array(
+        'path' => 'user/'. arg(1) .'/tokenauth',
+        'title' => t('Token auth'),
+        'callback' => 'tokenauth_userpage',
+        'access' => user_access('access tokenauth'),
+        'type' => MENU_IS_LOCAL_TASK
+      );
+      $items[] = array(
+        'path' => 'user/'. arg(1) .'/tokenauth/reset',
+        'title' => t('Reset token'),
+        'callback' => 'drupal_get_form',
+        'callback arguments' => array('tokenauth_user_reset_confirm'),
+        'access' => (user_access('administer users') || $user->uid == arg(1)) && user_access('access tokenauth'),
+        'type' => MENU_CALLBACK
+      );
+    }
+  }
+
+  return $items;
+}
+
+/**
+ * Validate callback.
+ */
+function tokenauth_admin_settings_validate($form_id, $form_values) {
+  if ($form_values['op'] == t('Reset tokens')) {
+    drupal_goto('admin/settings/tokenauth/reset');
+  }
+  if ($form_values['tokenauth_length'] > 33) {
+    form_set_error('tokenauth_length', t('The maximum token length is 32.'));
+  }
+}
+
+/**
+ * Menu callback: confirm reset tokens.
+ */
+function tokenauth_reset_confirm() {
+  return confirm_form(array(), t('Are you sure you want to reset all tokens?'),
+           'admin/settings/tokenauth', t('After the tokens has been reset all users who use tokenised URLs will have to update them. This action cannot be undone.'), t('Reset tokens'), t('Cancel'));
+}
+
+/**
+ * Handler for reset tokens confirmation
+ */
+function tokenauth_reset_confirm_submit($form_id, &$form) {
+  if ($form['confirm']) {
+    tokenauth_reset();
+    drupal_set_message(t('The tokens have been reset.'));
+    return 'admin/settings/tokenauth';
+  }
+}
+
+/**
+ * Reset all tokens.
+ */
+function tokenauth_reset() {
+  $length = variable_get('tokenauth_length', 10);
+  $sql = 'SELECT uid FROM {users}';
+  $result = db_query($sql);
+  while ($row = db_fetch_object($result)) {
+    $sql = "UPDATE {tokenauth_tokens} SET token = '%s' WHERE uid = %d";
+    db_query($sql, user_password($length), $row->uid);
+  }
+}
+
+/**
+ * Menu callback: confirm reset  users token.
+ */
+function tokenauth_user_reset_confirm() {
+  global $user;
+
+  return confirm_form(array(), t('Are you sure you want to reset your token?'),
+           "user/$user->uid/tokenauth", t('After the token has been reset all your tokenised URLs will have to be updated. This action cannot be undone.'), t('Reset token'), t('Cancel'));
+}
+
+/**
+ * Handler for reset tokens confirmation
+ */
+function tokenauth_user_reset_confirm_submit($form_id, &$form) {
+  global $user;
+
+  if ($form['confirm']) {
+    tokenauth_user_reset();
+    drupal_set_message(t('The token have been reset.'));
+    return "user/$user->uid/tokenauth";
+  }
+}
+
+/**
+ * Reset a users token.
+ */
+function tokenauth_user_reset() {
+  global $user;
+
+  $length = variable_get('tokenauth_length', 10);
+  $sql = "UPDATE {tokenauth_tokens} SET token = '%s' WHERE uid = %d";
+  db_query($sql, user_password($length), $user->uid);
+}
+
+/**
+ * Menu callback. Prints the token and instructions.
+ */
+function tokenauth_userpage() {
+  if ($account = user_load(array('uid' => arg(1), 'status' => 1))) {
+    if (user_access('access tokenauth', $account)) {
+      drupal_set_title(check_plain($account->name));
+      $token = db_result(db_query("SELECT tt.token FROM {tokenauth_tokens} tt WHERE tt.uid = %d", $account->uid));
+      $output = t('To enable aggregators, feed readers and other simple clients to see restricted content on this site you may use an authentication token.') .'<br /><br />';
+      $output .= t('The token is unique and tied to your account so keep it private.') .'<br /><br />';
+      $output .= t('Simply add this query to any feed on this site:') .'<br />';
+      $output .= '<code>'. check_plain("?token=$token") .'</code><br /><br />';
+      $output .= t('Here are some examples to get you started:');
+      $items = array();
+      $items[] = l(t('Front page'), 'rss.xml', array('title' => url('rss.xml', "token=$token", NULL, TRUE)), "token=$token", NULL, FALSE, TRUE);
+      $items[] = l(t('Blog'), 'blog/feed', array('title' => url('blog/feed', "token=$token", NULL, TRUE)), "token=$token", NULL, FALSE, TRUE);
+      $output .= theme('item_list', $items);
+
+      $output2 = l(t('Reset token'), "user/$account->uid/tokenauth/reset");
+
+      return theme('box', t('Token authentication'), $output) . theme('box', t('Token actions'), $output2);
+    }
+  }
+}
+
+/**
+ * Implementation of hook_init().
+ */
 function tokenauth_init() {
   global $user;
-  // process any provided token and log in user
+  // Process any provided token and log in user
   if (!$user->uid && $_REQUEST['token'] && tokenauth_allowed_pages($_GET['q']) && function_exists('drupal_set_content')) {
     $sql = "SELECT tt.uid FROM {tokenauth_tokens} tt INNER JOIN {users} u ON tt.uid = u.uid WHERE token = '%s' AND u.status != 0";
     if ($uid = db_result(db_query($sql, $_REQUEST['token']))) {
       $user = user_load(array('uid' => $uid));
-      $_SESSION['tokenauth_auth'] = TRUE; // just store the fact that this user authenticated via token
+      $_SESSION['tokenauth_auth'] = TRUE; // Just store the fact that this user authenticated via token
     }
     else {
-      // supplied an invalid token
+      // Supplied an invalid token
       drupal_access_denied();
     }
   }
 }
 
-// deliberately insure that this session will not be saved by sess_write(). safety
+/**
+ * Deliberately insure that this session will not be saved by sess_write(). safety
+ */
 function tokenauth_exit() {
   if ($_SESSION['tokenauth_auth']) {
     unset($_COOKIE[session_name()]);
@@ -25,13 +226,31 @@ function tokenauth_exit() {
   }
 }
 
-// TODO: make UI. for now, edit this function as needed
-// return TRUE if current page may be viewed using only a token
+/**
+ * Return TRUE if current page may be viewed using only a token
+ */
 function tokenauth_allowed_pages($path) {
-  return strpos($path, 'feed') || strpos($path, 'opml');
+  // Code from the block_list funtion in block.module.
+  // If the path doesn't match any of the exeptions, return TRUE.
+  $pathalias = drupal_get_path_alias($path);
+  $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote(variable_get('tokenauth_pages', "rss.xml\n*/feed\n*/opml"), '/')) .')$/';
+  // Compare with the internal and path alias (if any).
+  $page_match = preg_match($regexp, $pathalias);
+  if ($pathalias != $path) {
+    $page_match = $page_match || preg_match($regexp, $path);
+  }
+  if ($page_match) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
 }
 
-// boring code to change tokens. no UI yet.
+/**
+ * Implementation of hook_user().
+ * Boring code to change tokens. No UI yet.
+ */
 function tokenauth_user($op, &$edit, &$account, $category = NULL) {
   switch ($op) {
     case 'update':
