Index: hook_vud.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vote_up_down/hook_vud.php,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 hook_vud.php
--- hook_vud.php	20 Jun 2010 20:44:17 -0000	1.1.2.2
+++ hook_vud.php	9 Aug 2010 03:08:43 -0000
@@ -12,6 +12,34 @@
 define('VUD_NEWENTITY_WIDGET_MESSAGE_POSTPONED', 2);
 
 /**
+ * Allow modules to alter access to the voting operation.
+ *
+ * @param $perm
+ *   A string containing the permission required to modify the vote.
+ * @param $type
+ *   A string containing the type of content being voted on.
+ * @param $content_id
+ *   An integer containing the unique ID of the content being voted on.
+ * @param $value
+ *   An integer containing the vote value, 1 for an up vote, -1 for a down vote.
+ * @param $tag
+ *   A string containing the voting API tag.
+ * $param $account
+ *   An object containing the user voting on the content, NULL for the current
+ *   user.
+ *
+ * @return
+ *   A boolean forcing access to the vote, pass NULL if the function should
+ *   not modify the access restriction.
+ */
+function hook_vud_access($perm, $type, $content_id, $value, $tag, $account) {
+  // Denies access for all users other than user 1.
+  if ($account->uid != 1) {
+    return FALSE;
+  }
+}
+
+/**
  * Modify the array of know messages.
  *
  * For a real implementation take a look at
Index: vud.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vote_up_down/vud.module,v
retrieving revision 1.1.2.33
diff -u -p -r1.1.2.33 vud.module
--- vud.module	2 Aug 2010 05:14:51 -0000	1.1.2.33
+++ vud.module	9 Aug 2010 03:08:43 -0000
@@ -75,7 +75,8 @@ function vud_menu() {
     'title'            => 'Vote',
     'page callback'    => 'vud_vote',
     'page arguments'   => array(1, 2, 3, 4, 5, 6),
-    'access arguments' => array('use vote up/down'),
+    'access callback'  => 'vud_access',
+    'access arguments' => array('use vote up/down', 1, 2, 3, 4),
     'type'             => MENU_CALLBACK,
     'file'             => 'vud.theme.inc',
   );
@@ -84,7 +85,8 @@ function vud_menu() {
     'title'            => 'Reset vote',
     'page callback'    => 'vud_reset',
     'page arguments'   => array(1, 2, 3, 4),
-    'access arguments' => array('reset vote up/down votes'),
+    'access callback'  => 'vud_access',
+    'access arguments' => array('reset vote up/down votes', 1, 2, 3, 4),
     'type'             => MENU_CALLBACK,
   );
 
@@ -108,6 +110,46 @@ function vud_menu() {
 }
 
 /**
+ * Access callback for votes.
+ *
+ * @param $perm
+ *   A string containing the permission required to modify the vote.
+ * @param $type
+ *   A string containing the type of content being voted on.
+ * @param $content_id
+ *   An integer containing the unique ID of the content being voted on.
+ * @param $value
+ *   An integer containing the vote value, 1 for an up vote, -1 for a down vote.
+ * @param $tag
+ *   A string containing the voting API tag.
+ * $param $account
+ *   An object containing the user voting on the content, NULL for the current
+ *   user.
+ *
+ * @return
+ *   A boolean flagging whether or not the user has access to the vote.
+ */
+function vud_access($perm, $type, $content_id, $value, $tag, $account = NULL) {
+  if (NULL === $user) {
+    global $user;
+    $account = $user;
+  }
+
+  // Initializes access based on user's permission.
+  $access = user_access($perm, $account);
+
+  // Invokes hook_access(), gives modules ability to allow or disallow access.
+  $access_array = module_invoke_all('vud_access', $perm, $type, $content_id, $value, $tag, $account);
+  foreach ($access_array as $set_access) {
+    if (isset($set_access)) {
+      $access = $set_access;
+    }
+  }
+
+  return $access;
+}
+
+/**
  * Implementation of hook_perm().
  */
 function vud_perm() {
Index: vud_comment/vud_comment.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vote_up_down/vud_comment/vud_comment.module,v
retrieving revision 1.1.2.27
diff -u -p -r1.1.2.27 vud_comment.module
--- vud_comment/vud_comment.module	2 Aug 2010 05:14:51 -0000	1.1.2.27
+++ vud_comment/vud_comment.module	9 Aug 2010 03:08:43 -0000
@@ -98,8 +98,9 @@ function vud_comment_comment(&$comment, 
       $comment_allow = in_array($type, variable_get('vud_comment_node_types', array()), TRUE);
       if ($comment_allow && user_access('use vote up/down on comments')) {
         $tag = variable_get('vud_tag', 'vote');
+        $read_only = !vud_access('use vote up/down', 'comment', $comment->cid, 0, $tag);
         $widget = variable_get('vud_comment_widget', 'plain');
-        $comment->comment = theme('vud_widget', $comment->cid, 'comment', $tag, $widget) . $comment->comment;
+        $comment->comment = theme('vud_widget', $comment->cid, 'comment', $tag, $widget, $read_only) . $comment->comment;
       }
       break;
   }
Index: vud_node/vud_node.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vote_up_down/vud_node/vud_node.module,v
retrieving revision 1.1.2.43
diff -u -p -r1.1.2.43 vud_node.module
--- vud_node/vud_node.module	2 Aug 2010 05:14:51 -0000	1.1.2.43
+++ vud_node/vud_node.module	9 Aug 2010 03:08:44 -0000
@@ -72,6 +72,32 @@ function vud_node_tab_view_stats($node) 
 }
 
 /**
+ * Implementation of hook_vud_access().
+ */
+function vud_node_vud_access($perm, $type, $content_id, $value, $tag, $account) {
+  // Only act on nodes.
+  if ($type != 'node') {
+    return;
+  }
+
+  // If one time voting is enabled, checks if a vote has been registered.
+  if (variable_get('vud_node_vote_once', 0) && $perm != 'reset vote up/down votes') {
+    $criteria = array(
+      'content_type' => $type,
+      'content_id' => $content_id,
+      'tag' => $tag,
+    );
+    $criteria['uid'] = $account->uid;
+    if (!$account->uid) {
+      $criteria['vote_source'] = ip_address();
+    }
+    if ($user_vote = votingapi_select_single_vote_value($criteria)) {
+      return FALSE;
+    }
+  }
+}
+
+/**
  * Advanced menu settings callback.
  */
 function vud_node_admin_settings() {
@@ -115,8 +141,14 @@ function vud_node_admin_settings() {
     '#default_value' => variable_get('vud_node_reset', 0),
     '#options'       => array(0 => 'No', 1 => 'Yes'),
   );
-
-return system_settings_form($form);
+  $form['vud_node_vote_once'] = array(
+    '#type'          => 'radios',
+    '#title'         => t('One time voting'),
+    '#description'   => t('Choose if users are allowed to vote only once per node.'),
+    '#default_value' => variable_get('vud_node_vote_once', 0),
+    '#options'       => array(0 => t('No'), 1 => t('Yes')),
+  );
+  return system_settings_form($form);
 }
 
 /**
@@ -142,10 +174,11 @@ function vud_node_nodeapi(&$node, $op, $
       if (in_array($node->build_mode, $exclude_modes)) {
         break;
       }
-      if (($can_edit=user_access('use vote up/down on nodes')) || user_access('view vote up/down count on nodes')) {
+      $tag = variable_get('vud_tag', 'vote');
+      $can_edit = (user_access('use vote up/down on nodes') && vud_access('use vote up/down', 'node', $node->nid, 0, $tag));
+      if ($can_edit || user_access('view vote up/down count on nodes')) {
         $node_type = in_array($node->type, variable_get('vud_node_types', array()), TRUE);
         $widget_showmode = variable_get('vud_node_widget_show', VUD_NODE_DISPLAY_BOTH);
-        $tag = variable_get('vud_tag', 'vote');
         $widget = variable_get('vud_node_widget', 'plain');
         $vote_on_teaser = (bool)variable_get('vud_node_widget_vote_on_teaser', TRUE);
         $teaser = $a3;
Index: vud_term/vud_term.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/vote_up_down/vud_term/vud_term.module,v
retrieving revision 1.1.2.17
diff -u -p -r1.1.2.17 vud_term.module
--- vud_term/vud_term.module	2 Aug 2010 05:14:51 -0000	1.1.2.17
+++ vud_term/vud_term.module	9 Aug 2010 03:08:44 -0000
@@ -107,6 +107,7 @@ function _vud_term_generate_table(&$node
   foreach ($node->taxonomy as $term => $tdetails) {
     $content_id =  $tdetails->tid;
     $tag = "n$node->nid";
+    $read_only = !vud_access('use vote up/down', 'term', $content_id, 0, $tag);
     $reset_token = drupal_get_token("votereset/term/$content_id/$tag");
     if (variable_get('vud_term_reset', 0) && user_access('reset vote up/down votes')) {
       $header = array(
@@ -119,7 +120,7 @@ function _vud_term_generate_table(&$node
       $rows[] = array(
         $tdetails->name,
         $tdetails->description,
-        theme('vud_widget', $content_id, "term", $tag, $widget),
+        theme('vud_widget', $content_id, "term", $tag, $widget, $read_only),
         "<span id=\"total-votes-term-$content_id\">". _vud_term_get_row_votes($content_id, $tag) .'</span>',
         l('Reset your vote', "votereset/term/$content_id/$tag/$reset_token"),
       );
@@ -134,7 +135,7 @@ function _vud_term_generate_table(&$node
       $rows[] = array(
         $tdetails->name,
         $tdetails->description,
-        theme('vud_widget', $content_id, "term", $tag, $widget),
+        theme('vud_widget', $content_id, "term", $tag, $widget, $read_only),
         "<span id=\"total-votes-term-$content_id\">". _vud_term_get_row_votes($content_id, $tag) .'</span>',
       );
     }
