Browse Source

Merge a0044658e1 into f17b65965b

pull/205/merge
Jason MacWilliams 13 years ago
parent
commit
bf372bacd9
  1. 95
      includes/islandora_authtokens.inc
  2. 67
      islandora.install
  3. 82
      islandora.module

95
includes/islandora_authtokens.inc

@ -0,0 +1,95 @@
<?php
/**
* @file
*/
// Token lifespan: after this duration the token expires.
define('TOKEN_TIMEOUT', 30000);
/**
* Request islandora to construct an object/datastream authentication token.
* This token can later be turned in for access to the requested object or
* datastream.
* @param string $pid
* @param string $dsid
* @return The generated authentication token.
*/
function islandora_get_object_token($pid, $dsid) {
global $user;
$time = time();
$token = hash("sha256", $user->uid . $pid . $dsid . $time);
/* optional block to check if this request is allowed
// CURRENTLY DISABLED
module_load_include("inc", "islandora", "includes/tuque");
// test if this is a valid request
$validator = new IslandoraTuque($user);
try {
$result = $validator->connection->getRequest("objects/$pid/datastreams/$dsid/content", true);
}
catch (RepositoryException $rx) {
//print_r("authentication failed");
return FALSE;
}
*/
$id = db_insert("islandora_authtokens")
->fields(array(
'token' => $token,
'uid' => $user->uid,
'pid' => $pid,
'dsid' => $dsid,
'time' => $time,
))
->execute();
return $token;
}
/**
* Submit a token to islandora for authentication. Supply islandora with the
* token and the object/datastream it is for and you will receive access if
* authentication passes. Tokens can only be redeemed in a short window after
* their creation.
* @param string $pid
* The pid of the object to retrieve.
* @param string @dsid
* The datastream id to retrieve.
* @param string $token
* The registered token that allows access to this object.
* @return The user credentials for access if the token validation passes,
* FALSE otherwise
*/
function islandora_validate_object_token($pid, $dsid, $token) {
global $user;
// check for database token
$time = time();
$query = db_select('islandora_authtokens', 'tokens');
$query->join('users', 'u', 'tokens.uid = u.uid');
$result = $query
->fields('u', array('uid', 'name', 'pass'))
->condition('token', $token, '=')
->condition('pid', $pid, '=')
->condition('dsid', $dsid, '=')
->condition('time', $time, '<=')
->condition('time', $time-TOKEN_TIMEOUT, '>')
->execute()
->fetchAll();
//** this is for one-time use tokens **//
// remove the authtoken (if it exists) so it can't be used again
db_delete("islandora_authtokens")
->condition('token', $token, '=')
->condition('pid', $pid, '=')
->condition('dsid', $dsid, '=')
->execute();
//** **//
if ($result) {
return $result[0];
}
else {
return FALSE;
}
}

67
islandora.install

@ -25,4 +25,69 @@ function islandora_uninstall() {
module_load_include('inc', 'islandora', 'includes/solution_packs'); module_load_include('inc', 'islandora', 'includes/solution_packs');
// uninstall callback // uninstall callback
islandora_install_solution_pack('islandora', 'uninstall'); islandora_install_solution_pack('islandora', 'uninstall');
} }
/**
* Implements hook_schema().
*
* @return array
*/
function islandora_schema() {
$schema['islandora_authtokens'] = array(
'description' => 'The hub for all islandora authentication tokens',
'fields' => array(
'id' => array(
'description' => 'key',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'token' => array(
'description' => 'a unique identifier for this token',
'type' => 'varchar',
'length' => 64,
),
'uid' => array(
'description' => 'the user id that requested this token',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'time' => array(
'description' => 'when this token was created',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'pid' => array(
'description' => 'the pid of the object this token unlocks',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'dsid' => array(
'description' => 'the datasteram id of the object this token unlocks',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
),
),
'unique keys' => array(
'id' => array('id'),
),
'primary key' => array('id'),
);
return $schema;
}
/**
* Implements hook_update_N().
*
* Add the required table for handling authtokens.
* This is the first instance that has this table.
*/
function islandora_update_7002(&$sandbox) {
drupal_install_schema('islandora');
$t = get_t();
return $t("Islandora database updates complete");
}

82
islandora.module

@ -164,8 +164,11 @@ function islandora_menu() {
'access arguments' => array(2, FEDORA_ADD_DS) 'access arguments' => array(2, FEDORA_ADD_DS)
); );
$items['islandora/object/%islandora_object/datastream/%'] = array( // this menu item has been modified to use a tokened version of islandora_object_load
// added load arguments to pass both pid and dsid to loader
$items['islandora/object/%islandora_tokened_object/datastream/%'] = array(
'title' => 'View datastream', 'title' => 'View datastream',
'load arguments' => array(4),
'page callback' => 'islandora_view_datastream', 'page callback' => 'islandora_view_datastream',
'page arguments' => array(2, 4), 'page arguments' => array(2, 4),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
@ -174,7 +177,8 @@ function islandora_menu() {
'access arguments' => array(2, FEDORA_VIEW), 'access arguments' => array(2, FEDORA_VIEW),
); );
$items['islandora/object/%islandora_object/datastream/%/view'] = array( // this menu item has been modified to use a tokened version of islandora_object_load
$items['islandora/object/%islandora_tokened_object/datastream/%/view'] = array(
'title' => 'View datastream', 'title' => 'View datastream',
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
); );
@ -208,7 +212,25 @@ function islandora_menu() {
'access callback' => 'islandora_access_callback', 'access callback' => 'islandora_access_callback',
'access arguments' => array(2, FEDORA_PURGE), 'access arguments' => array(2, FEDORA_PURGE),
); );
/*
// These are two test hooks that can be used to create and validate authentication tokens
// They are for debug purposes only and are currently disabled
$items['admin/islandora/get_object_token'] = array(
'title' => 'Object Token',
'page callback' => 'islandora_get_object_token',
'access callback' => TRUE,
'file' => 'includes/islandora_authtokens.inc',
'type' => MENU_CALLBACK,
);
$items['admin/islandora/validate_object_token'] = array(
'title' => 'Validate Object Token',
'page callback' => 'islandora_validate_object_token',
'access callback' => TRUE,
'file' => 'includes/islandora_authtokens.inc',
'type' => MENU_CALLBACK,
);
*/
return $items; return $items;
} }
@ -420,7 +442,6 @@ function islandora_view_object($fedora_object = NULL) {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
global $user; global $user;
if (!$fedora_object) { if (!$fedora_object) {
return drupal_not_found(); return drupal_not_found();
} }
@ -498,6 +519,57 @@ function islandora_object_load($object_id) {
} }
} }
/**
* A helper function to get a connection and return an object using a token for authentication.
*
* @param string $object_id
* @param string $datastream_id
* @return FedoraObject
*/
function islandora_tokened_object_load($object_id, $datastream_id) {
if (in_array('token', $_GET)) {
$token = $_GET['token'];
}
else {
$token = NULL;
}
if ($token) {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
$tokenUser = islandora_validate_object_token($object_id, $datastream_id, $token);
if ($tokenUser) {
// The following block is the same as the islandora_object_load function
// and we can probably just update the islandora_tuque static object and call
// islandora_object_load so we don't have to duplicate the function code
module_load_include('inc', 'islandora', 'includes/tuque');
$islandora_tuque = &drupal_static(__FUNCTION__);
if (!$islandora_tuque) {
$islandora_tuque = new IslandoraTuque($tokenUser);
}
if (IslandoraTuque::exists()) {
try {
$fedora_object = $islandora_tuque->repository->getObject($object_id);
} catch (Exception $e) {
return NULL;
}
drupal_alter('islandora_object', $fedora_object);
return $fedora_object;
}
else {
IslandoraTuque::getError();
return NULL;
}
//
}
}
// By default, if no token is found, use original load function
return islandora_object_load($object_id);
}
/** /**
* A helper function to get a connection and purge an object * A helper function to get a connection and purge an object
* *
@ -634,7 +706,3 @@ function islandora_islandora_required_objects() {
); );
} }

Loading…
Cancel
Save