node_authlink.module 6.31 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php
// $Id$

/**
 * Alter of node_type_form.
 */
function node_authlink_form_node_type_form_alter(&$form, &$form_state) {
  $form['node_authlink'] = array(
    '#type' => 'fieldset',
Bobík's avatar
Bobík committed
10
    '#title' => t('Node authorize link'),
11 12 13 14 15 16 17 18
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
  );
  
  $form['node_authlink']['node_authlink_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable'),
Bobík's avatar
Bobík committed
19
    '#default_value' => variable_get('node_authlink_enable_' . $form['#node_type']->type, FALSE),
20 21 22 23 24 25
    '#description' => t('Disable of this feature will cost erase of authorization keys of all nodes in this node type.'),
  );
  
  $form['node_authlink']['node_authlink_grants'] = array(
    '#type' => 'checkboxes', 
    '#title' => t('Grants to give'), 
Bobík's avatar
Bobík committed
26
    '#default_value' => variable_get('node_authlink_grants_' . $form['#node_type']->type, array()),
27 28 29 30 31 32 33 34
    '#options' => array(
      'view' => t('View'),
      'update' => t('Update'), 
      'delete' => t('Delete'), 
    ),
    '#description' => t('What operations will be temporarily given to authorised user for the node. This not affect users who is authorised yet.'),
  );
  
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  $form['node_authlink']['node_authlink_batch'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#title' => t('Batch operations'),
    '#description' => t('Affects all nodes in this node type.'),
  );
  $form['node_authlink']['node_authlink_batch']['generate'] = array(
    '#type' => 'submit',
    '#value' => t('Generate authkeys'),
    '#submit' => array('node_authlink_batch_generate'),
  );
  $form['node_authlink']['node_authlink_batch']['delete'] = array(
    '#type' => 'submit',
    '#value' => t('Delete all authkeys'),
    '#submit' => array('node_authlink_batch_delete'),
  );
  
53 54 55 56 57 58 59
  $form['#submit'][] = 'node_authlink_form_node_type_form_alter_submit';
}

/**
 * Submit for node_type_form.
 */
function node_authlink_form_node_type_form_alter_submit(&$form, &$form_state) {
Bobík's avatar
Bobík committed
60
  $node_types = variable_get('node_authlink_types', array());
61
  
Bobík's avatar
Bobík committed
62 63 64
  // Enabled
  if($form_state['values']['node_authlink_enable']) {
    $node_types[$form_state['values']['type']] = $form_state['values']['type'];
65 66
  }
  
Bobík's avatar
Bobík committed
67 68 69 70 71
  // Disabled
  elseif(!$form_state['values']['node_authlink_enable']) {
    variable_del('node_authlink_enable_' . $form_state['values']['type']);
    variable_del('node_authlink_grants_' . $form_state['values']['type']);
    unset($node_types[$form_state['values']['type']]);
72 73
  }
  
Bobík's avatar
Bobík committed
74
  variable_set('node_authlink_types', $node_types);
75 76
}

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/**
 * Generate authkeys for all nodes in node type.
 */
function node_authlink_batch_generate(&$form, &$form_state) {
  // Load NIDs that are not in the authkeys table 
  $query = db_select('node', 'n');
  $query->leftJoin('node_authlink_nodes', 'a', 'n.nid = a.nid');
  $query->fields('n', array('nid'))
    ->condition('type', $form_state['values']['type'])
    ->isNull('authkey');
  $nids = $query->execute()->fetchCol();
  
  // Create keys
  foreach ($nids as $nid)
    node_authlink_node_insert($nid);
  
  drupal_set_message(t('%num authkeys has been generated.', array('%num' => count($nids))));
}

/**
 * Delete authkeys for all nodes in node type.
 */
function node_authlink_batch_delete(&$form, &$form_state) {
  // NIDs of nodes that are in this node type
  $query = db_select('node', 'n');
  $query->leftJoin('node_authlink_nodes', 'a', 'n.nid = a.nid');
  $query->fields('n', array('nid'))
    ->condition('type', $form_state['values']['type'])
    ->isNotNull('authkey');
  $nids = $query->execute()->fetchCol();
  
  // Delete keys
  $count = db_delete('node_authlink_nodes')
    ->condition('nid', $nids, 'IN')
    ->execute();
  
  drupal_set_message(t('%num authkeys has been deleted.', array('%num' => $count)));
}


117
/**
Bobík's avatar
Bobík committed
118 119 120
 * Implementation of hook_node_load().
 *
 * Appends authke to loaded node object.
121
 */
Bobík's avatar
Bobík committed
122 123 124 125 126
function node_authlink_node_load($nodes, $types) {
  foreach ($nodes as $nid => $node) {
    // TODO: check node type (performance)
    if($authkey = node_authlink_load_authkey($nid))
      $nodes[$nid]->authkey = $authkey;
127
  }
Bobík's avatar
Bobík committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
}

/**
 * Loads key from NID.
 */
function node_authlink_load_authkey($nid) {
  $result = db_query('SELECT authkey FROM {node_authlink_nodes} WHERE nid = :nid', array(':nid' => $nid));
  return $result->fetchField();
}


/**
 * Get edit URL of specified node.
 * @param $node Node object or NID.
 * @param $op Operation to do with node. view, edit (default) or delete. 
 */
function node_authlink_get_url($node, $op = 'edit') {
  if(is_numeric($node))
    $node = node_load($node);
147
  
Bobík's avatar
Bobík committed
148 149 150 151 152 153 154 155 156 157 158 159
  if(!isset($node->authkey))
    return FALSE;
  
  if($op == 'view')
    $op = '';
  else
    $op = '/' . $op;
  
  return url("node/$node->nid$op", array(
    'absolute' => TRUE,
    'query' => array('authkey' => $node->authkey),
  ));
160 161 162 163 164 165 166 167 168 169
}

/**
 * Implementation of hook_node_access().
 */
function node_authlink_node_access($node, $op, $account) {
  // Ignore if just creating node
  if($op == 'create')
    return NODE_ACCESS_IGNORE;
  
Bobík's avatar
Bobík committed
170 171 172 173
  // Ignore if node type is not enabled
  if(!variable_get('node_authlink_enable_' . $node->type, FALSE))
    return NODE_ACCESS_IGNORE;
  
174 175
  // Check key if:
  if(isset($_GET['authkey']) && // authkey param is set
Bobík's avatar
Bobík committed
176
     isset($node->authkey)) { // authkey in node is set
177
    
Bobík's avatar
Bobík committed
178
    if($node->authkey == $_GET['authkey']) {
179 180 181 182
      // Start session
      if(!isset($_SESSION))
        drupal_session_initialize();
      
Bobík's avatar
Bobík committed
183 184
      // Save allowed grants to session
      $_SESSION['node_authlink_nodes'][$node->nid] = variable_get('node_authlink_grants_' . $node->type, array());
185 186 187 188
    }
  }
  
  // Permit if checked
Bobík's avatar
Bobík committed
189 190
  if(isset($_SESSION['node_authlink_nodes'][$node->nid]) &&
     in_array($op, $_SESSION['node_authlink_nodes'][$node->nid]))
191 192 193 194
    return NODE_ACCESS_ALLOW;
}

/**
Bobík's avatar
Bobík committed
195 196 197
 * Implementation of hook_node_insert().
 *
 * Generate auth key for the new node.
198
 */
Bobík's avatar
Bobík committed
199
function node_authlink_node_insert($node) {
200 201 202 203 204 205 206 207 208 209
  // Allow key generate without load node object
  if(is_numeric($node))
    $nid = $node;
  else {
    $nid = $node->nid;
    
    // Ignore if node type is disabled
    if(!variable_get('node_authlink_enable_' . $node->type, FALSE))
      return;
  }
210 211
  
  // Generate new key
Bobík's avatar
Bobík committed
212 213 214 215 216
  $authkey = hash('sha256', drupal_random_bytes(64));
  
  // Save to DB
  db_insert('node_authlink_nodes')
    ->fields(array(
217
      'nid' => $nid, 
Bobík's avatar
Bobík committed
218 219 220 221
      'authkey' => $authkey,
      'created' => time(),
    ))
    ->execute();
222 223 224
}