Browse Source

Redid the job_id encoding to make the URLs prettier while still obfuscating it so researchers are not tempted to look at blast results not their own...

Lacey Sanderson 10 năm trước cách đây
mục cha
commit
402bb1f00d

+ 2 - 2
blast_ui.module

@@ -214,12 +214,12 @@ function blast_ui_help($path, $arg) {
  *  Return HTML output of the BLAST results to be displayed to the user
  *
  */
-function show_blast_output($job_id) {
+function show_blast_output($job_string) {
 
   // BLASTs are run as a Tripal job. As such we need to determine whether the current
   // BLAST is in the queue, running or complete in order to determine what to show the user
   //decode the job_id
-  $job_id = base64_decode($job_id);
+  $job_id = blast_ui_reveal_secret($job_string);
   $job = tripal_get_job($job_id);
 
   // 1) Job is in the Queue

+ 4 - 4
includes/blast_ui.form_advanced_options.inc

@@ -25,7 +25,7 @@
 function blast_ui_blastn_advanced_options_form(&$form, $form_state) {
   $all_job_data = variable_get('job_data', '');
   if (isset($_GET['jid']) && isset($all_job_data)) {    
-     $jid = base64_decode($_GET['jid']);
+     $jid = blast_ui_reveal_secret($_GET['jid']);
      $job_data = $all_job_data[$jid];
   }
   else {
@@ -173,7 +173,7 @@ function blast_ui_blastn_advanced_options_form_submit($form, $form_state) {
 function blast_ui_blastx_advanced_options_form(&$form, $form_state) {
   $all_job_data = variable_get('job_data', '');
   if (isset($_GET['jid']) && isset($all_job_data)) {    
-     $jid = base64_decode($_GET['jid']);
+     $jid = blast_ui_reveal_secret($_GET['jid']);
      $job_data = $all_job_data[$jid];
   }
   else {
@@ -308,7 +308,7 @@ function blast_ui_blastx_advanced_options_form_submit($form, $form_state) {
 function blast_ui_blastp_advanced_options_form(&$form, $form_state) {
   $all_job_data = variable_get('job_data', '');
   if (isset($_GET['jid']) && isset($all_job_data)) {    
-     $jid = base64_decode($_GET['jid']);
+     $jid = blast_ui_reveal_secret($_GET['jid']);
      $job_data = $all_job_data[$jid];
   }
   else {
@@ -970,7 +970,7 @@ function ajax_dependent_dropdown_callback($form, $form_state) {
 function blast_ui_tblastn_advanced_options_form(&$form, $form_state) {
   $all_job_data = variable_get('job_data', '');
   if (isset($_GET['jid']) && isset($all_job_data)) {    
-     $jid = base64_decode($_GET['jid']);
+     $jid = blast_ui_reveal_secret($_GET['jid']);
      $job_data = $all_job_data[$jid];
   }
   else {

+ 3 - 3
includes/blast_ui.form_per_program.inc

@@ -28,7 +28,7 @@ function blast_ui_per_blast_program_form($form, $form_state) {
   //   Approach: persist the form data and read it back using JobID
   $job_data = variable_get('job_data', '');
   if (isset($_GET['jid']) && isset($job_data)) {    
-    $jid = base64_decode($_GET['jid']);
+    $jid = blast_ui_reveal_secret($_GET['jid']);
   }  
   else {
     $job_data = array();
@@ -512,7 +512,7 @@ your sequence headers include pipes (i.e.: | ) they adhere to '
        session_start();
     }
     $sid = session_id();
-    $job_encode_id = base64_encode($job_id);
+    $job_encode_id = blast_ui_make_secret($job_id);
     $job_url = "blast/report/$job_encode_id";
 
     $all_jobs = $_SESSION['all_jobs'];
@@ -534,7 +534,7 @@ your sequence headers include pipes (i.e.: | ) they adhere to '
     tripal_jobs_launch(1, $job_id);
     
     //Encode the job_id
-    $job_encode_id = base64_encode($job_id);
+    $job_encode_id = blast_ui_make_secret($job_id);
     
     // Redirect to the BLAST results page
     drupal_goto("blast/report/$job_encode_id");

+ 1 - 1
theme/blast_report.tpl.php

@@ -332,7 +332,7 @@ else {
 <p><?php print l(
   'Edit this query and re-submit', 
   $blast_job->form_options['job_url'],
-  array('query' => array('jid' => base64_encode($job_id))));
+  array('query' => array('jid' => blast_ui_make_secret($job_id))));
 ?></p>
 </div>
 

+ 135 - 1
theme/blast_ui.theme.inc

@@ -87,4 +87,138 @@ function blast_ui_theme_registry_alter(&$theme_registry) {
       }
     }
   }
-}
+}
+
+/**
+ * Makes the tripal job_id unrecognizable.
+ * 
+ * @param $job_id
+ *   The tripal job_id of the blast you want to make secret.
+ *
+ * @return
+ *   A short string representing the job_id.
+ */
+function blast_ui_make_secret($job_id) {
+
+  $mapping = blast_ui_secret_mapping();
+  $secret = str_replace(array_keys($mapping), $mapping, $job_id);
+  
+  return $secret;
+}
+
+/**
+ * Reveals the true job_id for your secret blast result.
+ *
+ * @param $secret
+ *    The job_id previously made secret by blast_ui_make_secret().
+ *
+ * @return
+ *    The revealed tripal job_id.
+ */
+function blast_ui_reveal_secret($secret) {
+
+  $mapping = blast_ui_secret_mapping(TRUE);
+  $job_id = str_replace(array_keys($mapping), $mapping, $secret);
+  
+  // Check that the job_id exists if it is an integer.
+  if (is_integer($job_id)) {
+
+    $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', array(':id' => $job_id))->fetchField();
+    if (!$exists) {
+      tripal_report_error(
+        'blast_ui',
+        TRIPAL_ERROR,
+        'Unable to decode the blast job_id from :id.',
+        array(':id' => $secret)
+      );
+    }
+    else {
+      return $job_id;
+    }
+  }  
+  // Last ditch effort: maybe this job was encoded before the upgrade?
+  else {
+  
+    $job_id = base64_decode($secret);
+    $exists = db_query('SELECT job_id FROM {tripal_jobs} WHERE job_id=:id', array(':id' => $job_id))->fetchField();
+    if (!$exists) {
+      tripal_report_error(
+        'blast_ui',
+        TRIPAL_ERROR,
+        'Unable to decode the blast job_id from :id.',
+        array(':id' => $secret)
+      );
+    }
+    else {
+      return $job_id;
+    }
+  }
+  
+  return FALSE;
+}
+
+/**
+ * A single location for keeping track of the mapping used in our secrets.
+ */
+function blast_ui_secret_mapping($reveal = FALSE) {
+  $mapping = array(
+    1 => 'P',
+    2 => 'sA',
+    3 => 'b',
+    4 => 'Q',
+    5 => 'Hi',
+    6 => 'yt',
+    7 => 'f',
+    8 => 'zE',
+    9 => 'Km',
+    0 => 'jVo',
+  );
+  
+  // Since this is an open-source module with all the code publically available, 
+  // our secret is not very secret... We are ok with this since the liklihood of 
+  // profiting by stealing random blast results is pretty low. That said, if this bothers
+  // you, feel free to implement the following function in a private module to change
+  // this mapping to something that cannot easily be looked up on github. ;-).
+  // NOTE: Ensure that the mapping you come up with is unique to ensure that the
+  // job_id can be consistently revealed or your users might end up unable to find 
+  // their own blast results...
+  if (function_exists('private_make_mapping_ultra_secret')) {
+    $mapping = private_make_mapping_ultra_secret($mapping);
+  }
+  
+  if ($reveal) {
+    return array_flip($mapping);
+  }
+  else {
+    return $mapping;
+  }
+}
+
+/**
+ * Tests your secret mapping over a set of random integers 
+ * to ensure the job_id can be recovered.
+ *
+ * @param $num_iterations
+ *    An integer representing the number of times you wish to test your mapping.
+ */
+function blast_ui_test_secret_mapping($num_iterations = 10000) {
+
+  $all_work = TRUE;
+  
+  for($i = 0; $i <= $num_iterations; $i++) {
+    $job_id = mt_rand(0,100000);
+    
+    $secret = blast_ui_make_secret($job_id);
+    $recovered_job_id = blast_ui_reveal_secret($secret);
+    
+    if ($job_id != $recovered_job_id) {
+      drupal_set_message("Unable to recover job_id: $job_id; Secret: $secret.",'error');
+      $all_work = FALSE;
+    }
+  }
+  
+  if ($all_work) {
+    drupal_Set_message("Secret Mapping works over $num_iterations iterations with random integers.");
+  }
+  
+}