Browse Source

update the evergreen user lookup function

9.x-3.0
Paul Pound 1 week ago
parent
commit
9eaf39c6dc
  1. 6
      config/schema/upei_roblib_ill.schema.yml
  2. 137
      includes/utilities.inc
  3. 21
      src/Form/RoblibIllSettingsForm.php

6
config/schema/upei_roblib_ill.schema.yml

@ -29,3 +29,9 @@ upei_roblib_ill.settings:
evergreen_api_url: evergreen_api_url:
type: string type: string
label: 'Evergreen API URL' label: 'Evergreen API URL'
evergreen_username:
type: string
label: 'Evergreen Staff Username'
evergreen_password:
type: string
label: 'Evergreen Staff Password'

137
includes/utilities.inc

@ -94,68 +94,145 @@ call @phone. Note: if you are a student taking online courses only, please emai
} }
/** /**
* Lookup the user in Evergreen and verify the surname matches. * Authenticate against Evergreen and return an auth token.
* *
* @param string $campus_id * @param string $base_url
* The user's campus ID / barcode. * The base Evergreen URL.
* @param string $username
* The Evergreen staff username.
* @param string $password
* The Evergreen staff password.
*
* @return string|null
* The auth token, or NULL on failure.
*/
function upei_roblib_ill_evergreen_login($base_url, $username, $password) {
$gateway_url = rtrim($base_url, '/') . '/osrf-gateway-v1';
$client = \Drupal::httpClient();
// Step 1: Get the seed/nonce for the username.
$seed_response = $client->get($gateway_url, [
'timeout' => 10,
'query' => [
'service' => 'open-ils.auth',
'method' => 'open-ils.auth.authenticate.init',
'param' => '"' . $username . '"',
],
]);
$seed_data = json_decode((string) $seed_response->getBody(), TRUE);
$seed = $seed_data['payload'][0] ?? NULL;
if (empty($seed)) {
\Drupal::logger('upei_roblib_ill')->error('Evergreen auth init failed: no seed returned.');
return NULL;
}
// Step 2: Authenticate with the hashed password.
$hashed_password = md5($seed . md5($password));
$auth_response = $client->get($gateway_url, [
'timeout' => 10,
'query' => [
'service' => 'open-ils.auth',
'method' => 'open-ils.auth.authenticate.complete',
'param' => json_encode([
'username' => $username,
'password' => $hashed_password,
'type' => 'staff',
]),
],
]);
$auth_data = json_decode((string) $auth_response->getBody(), TRUE);
$auth_result = $auth_data['payload'][0] ?? NULL;
if (empty($auth_result) || ($auth_result['ilsevent'] ?? -1) != 0) {
$text_code = $auth_result['textcode'] ?? 'unknown';
\Drupal::logger('upei_roblib_ill')->error('Evergreen auth failed: @code', [
'@code' => $text_code,
]);
return NULL;
}
return $auth_result['payload']['authtoken'] ?? NULL;
}
/**
* Lookup the user in Evergreen via the REST API and verify the surname matches.
*
* Authenticates with Evergreen using staff credentials, then retrieves the
* patron by user ID and compares the family_name field against the provided
* surname.
*
* @param string $user_id
* The Evergreen user ID.
* @param string $surname * @param string $surname
* The surname to check against. * The surname to check against.
* *
* @return bool * @return bool
* TRUE if the surname matches, FALSE otherwise. * TRUE if the surname matches, FALSE otherwise.
*/ */
function upei_roblib_ill_authenticate($campus_id, $surname): bool function upei_roblib_ill_authenticate($user_id, $surname): bool
{ {
if (empty($campus_id) || empty($surname)) { if (empty($user_id) || empty($surname)) {
return FALSE; return FALSE;
} }
$config = \Drupal::config('upei_roblib_ill.settings'); $config = \Drupal::config('upei_roblib_ill.settings');
$evergreen_api_url = $config->get('evergreen_api_url'); $evergreen_api_url = $config->get('evergreen_api_url');
if (empty($evergreen_api_url)) { $eg_username = $config->get('evergreen_username');
\Drupal::logger('upei_roblib_ill')->error('Evergreen API URL is not configured.'); $eg_password = $config->get('evergreen_password');
if (empty($evergreen_api_url) || empty($eg_username) || empty($eg_password)) {
\Drupal::logger('upei_roblib_ill')->error('Evergreen API URL or credentials are not configured.');
return FALSE; return FALSE;
} }
// Construct the PatronAPI dump URL.
// Format: {evergreen_api_url}/api/patronapi/{campus_id}/dump
$url = rtrim($evergreen_api_url, '/') . '/api/patronapi/' . urlencode($campus_id) . '/dump';
try { try {
$response = \Drupal::httpClient()->get($url, [ // Authenticate to get an auth token.
$auth_token = upei_roblib_ill_evergreen_login($evergreen_api_url, $eg_username, $eg_password);
if (empty($auth_token)) {
return FALSE;
}
// Retrieve the patron by user ID using the auth token.
$gateway_url = rtrim($evergreen_api_url, '/') . '/osrf-gateway-v1';
$response = \Drupal::httpClient()->get($gateway_url, [
'timeout' => 10, 'timeout' => 10,
'query' => [
'service' => 'open-ils.actor',
'method' => 'open-ils.actor.user.retrieve',
'param' => ['"' . $auth_token . '"', '"' . $user_id . '"'],
],
]); ]);
$data = (string)$response->getBody(); $data = json_decode((string) $response->getBody(), TRUE);
// The PatronAPI dump endpoint returns data in a plain text/HTML format $patron = $data['payload'][0] ?? NULL;
// looking like `PATRN NAME[p]=Smith, John`. if (empty($patron) || isset($patron['ilsevent'])) {
if (preg_match('/PATRN NAME\[p\]=([^\[<]+)/i', $data, $matches)) { $evt = $patron['textcode'] ?? 'no data';
$patron_name = trim($matches[1]); \Drupal::logger('upei_roblib_ill')->warning('Evergreen REST API returned no patron for user ID @user_id: @evt', [
'@user_id' => $user_id,
'@evt' => $evt,
]);
return FALSE;
}
// Usually "Lastname, Firstname" $evergreen_surname = $patron['family_name'] ?? '';
$name_parts = explode(',', $patron_name);
if (count($name_parts) > 0) {
$evergreen_surname = trim($name_parts[0]);
// Case-insensitive comparison of the extracted surname and provided surname. // Case-insensitive comparison of the Evergreen surname and provided surname.
if (strcasecmp($evergreen_surname, trim($surname)) === 0) { if (strcasecmp(trim($evergreen_surname), trim($surname)) === 0) {
return TRUE; return TRUE;
}
}
} }
// Log failure for debugging. \Drupal::logger('upei_roblib_ill')->warning('Evergreen authentication failed for user ID @user_id. Expected surname: @surname, got: @evergreen_surname', [
\Drupal::logger('upei_roblib_ill')->warning('Evergreen authentication failed for @campus_id. Expected surname: @surname', [ '@user_id' => $user_id,
'@campus_id' => $campus_id,
'@surname' => $surname, '@surname' => $surname,
'@evergreen_surname' => $evergreen_surname,
]); ]);
return FALSE; return FALSE;
} }
catch (\Exception $e) { catch (\Exception $e) {
\Drupal::logger('upei_roblib_ill')->error('Failed to connect to Evergreen API: @message', [ \Drupal::logger('upei_roblib_ill')->error('Failed to connect to Evergreen REST API: @message', [
'@message' => $e->getMessage(), '@message' => $e->getMessage(),
]); ]);
return FALSE; return FALSE;

21
src/Form/RoblibIllSettingsForm.php

@ -73,11 +73,25 @@ class RoblibIllSettingsForm extends FormBase
$form['evergreen_fieldset']['evergreen_api_url'] = [ $form['evergreen_fieldset']['evergreen_api_url'] = [
'#type' => 'url', '#type' => 'url',
'#title' => t('Evergreen API URL'), '#title' => t('Evergreen API URL'),
'#description' => t('The base URL of your Evergreen server (e.g. https://catalogue.example.com). Used for PatronAPI lookups.'), '#description' => t('The base URL of your Evergreen server (e.g. https://catalogue.example.com). Used for REST API patron lookups.'),
'#default_value' => $config->get('evergreen_api_url'), '#default_value' => $config->get('evergreen_api_url'),
'#size' => 200, '#size' => 200,
'#required' => TRUE, '#required' => TRUE,
]; ];
$form['evergreen_fieldset']['evergreen_username'] = [
'#type' => 'textfield',
'#title' => t('Evergreen Staff Username'),
'#description' => t('A staff username for authenticating with the Evergreen REST API.'),
'#default_value' => $config->get('evergreen_username'),
'#size' => 200,
'#required' => TRUE,
];
$form['evergreen_fieldset']['evergreen_password'] = [
'#type' => 'password',
'#title' => t('Evergreen Staff Password'),
'#description' => t('The staff password for the Evergreen REST API. Leave blank to keep the existing value.'),
'#size' => 200,
];
// RapidILL settings. // RapidILL settings.
$form['rapid_ill_fieldset'] = [ $form['rapid_ill_fieldset'] = [
@ -143,6 +157,11 @@ class RoblibIllSettingsForm extends FormBase
// Evergreen settings. // Evergreen settings.
$config->set('evergreen_api_url', rtrim($form_state->getValue('evergreen_api_url'), '/'))->save(); $config->set('evergreen_api_url', rtrim($form_state->getValue('evergreen_api_url'), '/'))->save();
$config->set('evergreen_username', $form_state->getValue('evergreen_username'))->save();
$eg_password = $form_state->getValue('evergreen_password');
if (!empty($eg_password)) {
$config->set('evergreen_password', $eg_password)->save();
}
// RapidILL settings. // RapidILL settings.
$config->set('rapid_ill_username', $form_state->getValue('rapid_ill_username'))->save(); $config->set('rapid_ill_username', $form_state->getValue('rapid_ill_username'))->save();

Loading…
Cancel
Save