Index: signup.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.api.php,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 signup.api.php
--- signup.api.php	25 Jan 2009 05:09:12 -0000	1.1.2.1
+++ signup.api.php	25 Jul 2009 04:56:36 -0000
@@ -138,3 +138,39 @@ function hook_signup_suppress($node) {
   }
 }
 
+/**
+ * Hook invoked to control access to signup menu items.
+ *
+ * This hook is invoked to check access for signup menu items, in particular,
+ * the signup-related tabs on signup-enabled nodes. If no value is returned
+ * (NULL), the hook is ignored and the usual access logic is enforced via the
+ * Signup module. If multiple modules return a value, the logical OR is used,
+ * so if anyone returns TRUE, access is granted. If everyone returns FALSE,
+ * access is denied (even if the Signup module would normally grant access).
+ *
+ * @param $node
+ *   The fully-loaded node object where the menu items would be attached.
+ * @param $menu_type
+ *   String specifying what kind of menu item to test access for. Can be:
+ *   'signup': the signup form
+ *   'list': the signup attendee listing
+ *   'admin': the signup administration tab
+ *   'add': the signup administration tab to add other users (requires
+ *          that signups are currently open on the given node).
+ *   'broadcast': for the broadcast tab
+ *
+ * @return
+ *   TRUE if you want to allow access to the requested menu item, FALSE if you
+ *   want to deny access (although if another hook implementation returns
+ *   TRUE, that will take precedence), or NULL if you don't care and want to
+ *   let Signup module itself decide access based on its own logic.
+ *
+ * @see _signup_menu_access()
+ */
+function hook_signup_menu_access($node, $menu_type) {
+  // For example, you might want to test that the current user is the
+  // administrator of the organic group that a signup-enabled node belongs to,
+  // in which case, you'd return TRUE here to give that user full signup
+  // powers over events in their group.
+}
+
Index: signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.module,v
retrieving revision 1.205.2.23
diff -u -p -r1.205.2.23 signup.module
--- signup.module	22 Jul 2009 22:56:49 -0000	1.205.2.23
+++ signup.module	25 Jul 2009 04:56:37 -0000
@@ -371,7 +371,7 @@ function signup_menu() {
     'page callback' => 'signup_user_list_output',
     'page arguments' => array(1),
     'access callback' => '_signup_menu_access',
-    'access arguments' => array(1, 'list'),
+    'access arguments' => array(1, 'list-tab'),
     'type' => MENU_LOCAL_TASK,
     'weight' => -5,
     'file' => 'node_output.inc',
@@ -441,12 +441,13 @@ function signup_menu() {
  *   String specifying what kind of menu item to test access for.  Can be:
  *   'signup': the signup form
  *   'list': the signup attendee listing
+ *   'list-tab': the signup attendee listing tab
  *   'admin': the signup administration tab
  *   'add': the signup administration tab to add other users (requires
  *          that signups are currently open on the given node).
  *   'broadcast': for the broadcast tab
  *   'any': if the user has permission to see any of these
- *   
+ *
  * @return
  *   TRUE if the current node is signup enabled and the current user has
  *   permisison to access to requested menu item, otherwise FALSE.
@@ -459,6 +460,23 @@ function _signup_menu_access($node, $men
   if (empty($node->signup)) {
     return FALSE;
   }
+
+  // For certain menu types, invoke a hook to allow other modules to alter the
+  // access behavior for signup menu items. Just relying on hook_menu_alter()
+  // for this won't work, since there are places outside of the menu system,
+  // where we call this function to decide if a user should have access to
+  // something. If multiple modules return a value, the logical OR is used, so
+  // if anyone returns TRUE, access is granted.
+  if (in_array($menu_type, array('signup', 'list', 'admin', 'add', 'broadcast'))) {
+    $access_array = module_invoke_all('signup_menu_access', $node, $menu_type);
+    if (!empty($access_array)) {
+      // Return TRUE if any values are TRUE, otherwise, FALSE.
+      return in_array(TRUE, $access_array);
+    }
+  }
+
+  // No module returned a value in hook_signup_menu_access, so continue with
+  // the main logic.
   switch ($menu_type) {
     case 'signup':
       // See if this user can signup, if the node is configured to display the
@@ -466,6 +484,9 @@ function _signup_menu_access($node, $men
       return (user_access('sign up for content') && variable_get('signup_form_location', 'node') == 'tab') && _signup_needs_output($node);
 
     case 'list':
+      return user_access('view all signups') || _signup_menu_access($node, 'admin');
+
+    case 'list-tab':
       // See if this user can view signups, and if the site is configured to
       // display the signup user list as a tab.
       $user_list = variable_get('signup_display_signup_user_list', 'signup');
@@ -475,9 +496,8 @@ function _signup_menu_access($node, $men
       else {
         $user_list_tab = FALSE;
       }
-      $view_all = user_access('view all signups');
-      $admin = _signup_menu_access($node, 'admin');
-      return (($view_all || $admin) && $user_list_tab && _signup_needs_output($node));
+      $list_access = _signup_menu_access($node, 'list');
+      return $list_access && $user_list_tab && _signup_needs_output($node);
 
     case 'admin':
       $admin_all = user_access('administer all signups');
@@ -494,7 +514,7 @@ function _signup_menu_access($node, $men
 
     case 'any':
       $signup = _signup_menu_access($node, 'signup');
-      $list = _signup_menu_access($node, 'list');
+      $list = _signup_menu_access($node, 'list-tab');
       $admin = _signup_menu_access($node, 'admin');
       $email = _signup_menu_access($node, 'broadcast');
       return $signup || $list || $admin || $email;
Index: includes/node_output.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/node_output.inc,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 node_output.inc
--- includes/node_output.inc	3 Mar 2009 21:20:26 -0000	1.1.2.8
+++ includes/node_output.inc	25 Jul 2009 04:56:37 -0000
@@ -117,10 +117,8 @@ function signup_user_list_output($node) 
   // How should the list of signed-up users be displayed, if at all?
   $display_list = variable_get('signup_display_signup_user_list', 'signup');
 
-  // If the user has the view signups permission, or can adminisiter signups
-  // on this node, and the site admin decides to display the list at the
-  // bottom of the page, display the current signups.
-  if (user_access('view all signups') || _signup_menu_access($node, 'admin')) {
+  // Ensure the user has permission to view the signup list for this node.
+  if (_signup_menu_access($node, 'list')) {
     if ($display_list == 'signup' || $display_list == 'signup-tab') {
       // Admin wants the hard-coded signup listing.
       $registered_query = db_query("SELECT u.uid, u.name, s.signup_time, s.form_data FROM {signup_log} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.nid = %d AND u.uid <> 0", $node->nid);
