int is_identifier( const char* s);
int is_good_operator( const char* op );
+int setAuditInfo( osrfMethodContext* ctx );
+
#ifdef __cplusplus
}
#endif
- savepoint.set
- savepoint.release
- savepoint.rollback
+ - set_audit_info
For each non-virtual class, create up to eight class-specific methods:
osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
"rollbackSavepoint", "", 1, 0 );
+ buffer_reset(method_name);
+ OSRF_BUFFER_ADD(method_name, modulename );
+ OSRF_BUFFER_ADD(method_name, ".set_audit_info");
+ osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
+ "setAuditInfo", "", 3, 0 );
+
static const char* global_method[] = {
"create",
"retrieve",
- savepoint.set
- savepoint.release
- savepoint.rollback
+ - set_audit_info
For each non-virtual class, create up to eight class-specific methods:
osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
"rollbackSavepoint", "", 1, 0 );
+ buffer_reset(method_name);
+ OSRF_BUFFER_ADD(method_name, modulename );
+ OSRF_BUFFER_ADD(method_name, ".set_audit_info");
+ osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
+ "setAuditInfo", "", 3, 0 );
+
static const char* global_method[] = {
"create",
"retrieve",
- savepoint.set
- savepoint.release
- savepoint.rollback
+ - set_audit_info
For each non-virtual class, create up to eight class-specific methods:
osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
"rollbackSavepoint", "", 1, 0 );
+ buffer_reset(method_name);
+ OSRF_BUFFER_ADD(method_name, modulename );
+ OSRF_BUFFER_ADD(method_name, ".set_audit_info");
+ osrfAppRegisterMethod( modulename, OSRF_BUFFER_C_STR(method_name),
+ "setAuditInfo", "", 3, 0 );
+
static const char* global_method[] = {
"create",
"retrieve",
static int enforce_pcrud = 0; // Boolean
static char* modulename = NULL;
+int writeAuditInfo( osrfMethodContext* ctx, const char* user_id, const char* ws_id);
+
/**
@brief Connect to the database.
@return A database connection if successful, or NULL if not.
errnum, msg ? msg : "(No description available)" );
};
}
+ if( writehandle ) {
+ if( !dbi_conn_query( writehandle, "SELECT auditor.clear_audit_info();" ) ) {
+ const char* msg;
+ int errnum = dbi_conn_error( writehandle, &msg );
+ osrfLogWarning( OSRF_LOG_MARK, "Unable to perform audit info clearing: %d %s",
+ errnum, msg ? msg : "(No description available)" );
+ }
+ }
osrfHashFree( hash );
}
free( m );
jsonObjectFree( user );
user = NULL;
+ } else if( writeAuditInfo( ctx, oilsFMGetStringConst( user, "id" ), oilsFMGetStringConst( user, "wsid" ) ) ) {
+ // Failed to set audit information - But note that write_audit_info already set error information.
+ jsonObjectFree( user );
+ user = NULL;
}
setUserLogin( ctx, user );
pop_query_frame();
}
+/**
+ @brief Implement the set_audit_info method.
+ @param ctx Pointer to the method context.
+ @return Zero if successful, or -1 if not.
+
+ Issue a SAVEPOINT to the database server.
+
+ Method parameters:
+ - authkey
+ - user id (int)
+ - workstation id (int)
+
+ If user id is not provided the authkey will be used.
+ For PCRUD the authkey is always used, even if a user is provided.
+*/
+int setAuditInfo( osrfMethodContext* ctx ) {
+ if(osrfMethodVerifyContext( ctx )) {
+ osrfLogError( OSRF_LOG_MARK, "Invalid method context" );
+ return -1;
+ }
+
+ // Get the user id from the parameters
+ const char* user_id = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 1) );
+
+ if( enforce_pcrud || !user_id ) {
+ timeout_needs_resetting = 1;
+ const jsonObject* user = verifyUserPCRUD( ctx );
+ if( !user )
+ return -1;
+ osrfAppRespondComplete( ctx, NULL );
+ return 0;
+ }
+
+ // Not PCRUD and have a user_id?
+ int result = writeAuditInfo( ctx, user_id, jsonObjectGetString( jsonObjectGetIndex(ctx->params, 2) ) );
+ osrfAppRespondComplete( ctx, NULL );
+ return result;
+}
+
+/**
+ @brief Save a audit info
+ @param ctx Pointer to the method context.
+ @param user_id User ID to write as a string
+ @param ws_id Workstation ID to write as a string
+*/
+int writeAuditInfo( osrfMethodContext* ctx, const char* user_id, const char* ws_id) {
+ if( ctx && ctx->session ) {
+ osrfAppSession* session = ctx->session;
+
+ osrfHash* cache = session->userData;
+
+ // If the session doesn't already have a hash, create one. Make sure
+ // that the application session frees the hash when it terminates.
+ if( NULL == cache ) {
+ session->userData = cache = osrfNewHash();
+ osrfHashSetCallback( cache, &sessionDataFree );
+ ctx->session->userDataFree = &userDataFree;
+ }
+
+ dbi_result result = dbi_conn_queryf( writehandle, "SELECT auditor.set_audit_info( %s, %s );", user_id, ws_id ? ws_id : "NULL" );
+ if( !result ) {
+ osrfLogWarning( OSRF_LOG_MARK, "BAD RESULT" );
+ const char* msg;
+ int errnum = dbi_conn_error( writehandle, &msg );
+ osrfLogError(
+ OSRF_LOG_MARK,
+ "%s: Error setting auditor information: %d %s",
+ modulename,
+ errnum,
+ msg ? msg : "(No description available)"
+ );
+ osrfAppSessionStatus( ctx->session, OSRF_STATUS_INTERNALSERVERERROR,
+ "osrfMethodException", ctx->request, "Error setting auditor info" );
+ if( !oilsIsDBConnected( writehandle ))
+ osrfAppSessionPanic( ctx->session );
+ return -1;
+ } else {
+ dbi_result_free( result );
+ return 0;
+ }
+ }
+}
+
/*@}*/
$evt = check_group_perm($session, $user_obj, $patron);
return $evt if $evt;
+ $apputils->set_audit_info($session, $user_session, $user_obj->id, $user_obj->wsid);
# $new_patron is the patron in progress. $patron is the original patron
# passed in with the method. new_patron will change as the components
return $evt if $evt;
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($session, $ses, $requestor->id, $requestor->wsid);
for my $map (@$maps) {
my( $user_obj, $evt ) = $U->checkses($ses);
return $evt if $evt;
+ $apputils->set_audit_info($session, $ses, $user_obj->id, $user_obj->wsid);
my $perms = $session->request('open-ils.storage.permission.user_perms.atomic', $user_obj->id)->gather(1);
return $session;
}
+sub set_audit_info {
+ my $self = shift;
+ my $session = shift;
+ my $authtoken = shift;
+ my $user_id = shift;
+ my $ws_id = shift;
+
+ my $audit_req = $session->request( "open-ils.storage.set_audit_info", $authtoken, $user_id, $ws_id );
+ my $audit_resp = $audit_req->recv();
+ $audit_req->finish();
+}
+
my $PERM_QUERY = {
select => {
au => [ {
$transaction->clear_id;
my $session = $apputils->start_db_session;
+ $apputils->set_audit_info($login, $staff->id, $staff->wsid);
my $transid = $session->request(
'open-ils.storage.direct.money.grocery.create', $transaction)->gather(1);
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $newid = _create_stat_cat($session, $stat_cat, $method);
if( ref($stat_cat->entries) ) {
return $evt if $evt;
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $req = $session->request($method, $entry);
my $status = $req->gather(1);
$apputils->commit_db_session($session);
return $evt if $evt;
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $req = $session->request($method, $cat);
my $status = $req->gather(1);
$apputils->commit_db_session($session);
$entry->clear_id();
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $req = $session->request($method, $entry);
my $status = $req->gather(1);
$apputils->commit_db_session($session);
$map->clear_id();
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $req = $session->request($method, $map);
my $newid = $req->gather(1);
warn "Created new stat cat map with id $newid\n";
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $req = $session->request($method, $map);
my $newid = $req->gather(1);
warn "Updated new stat cat map with id $newid\n";
return $evt if $evt;
my $session = $apputils->start_db_session();
+ $apputils->set_audit_info($user_session, $user_obj->id, $user_obj->wsid);
my $err = undef; my $id;
($copy, $evt) = $U->fetch_copy_by_barcode($params{barcode}) unless $copy;
return $evt if $evt;
my $session = $U->start_db_session();
+ $U->set_audit_info($authtoken, $requestor->id, $requestor->wsid);
$evt = transit_receive( $self, $copy, $requestor, $session );
$U->commit_db_session($session) if $U->event_equals($evt,'SUCCESS');
return $evt;
my $source = $requestor->home_ou;
my $dest = $params{destination} || $copy->circ_lib;
my $transit = Fieldmapper::action::transit_copy->new;
+ $U->set_audit_info($authtoken, $requestor->id, $requestor->wsid);
$logger->activity("User ". $requestor->id ." creating a ".
" new copy transit for copy ".$copy->id." to org $dest");
# }
my $_xact_session;
+ my $_audit_session;
sub current_xact_session {
my $self = shift;
return undef;
}
+ sub current_audit_session {
+ my $self = shift;
+ if (defined($_audit_session)) {
+ return $_audit_session;
+ }
+ return undef;
+ }
+
sub current_xact_is_auto {
my $self = shift;
my $auto = shift;
return $_xact_session;
}
+ sub set_audit_session {
+ my $self = shift;
+ my $ses = shift;
+ if (!defined($ses)) {
+ return undef;
+ }
+ $_audit_session = $ses;
+ return $_audit_session;
+ }
+
sub unset_xact_session {
my $self = shift;
my $ses = $_xact_session;
return $ses;
}
+ sub unset_audit_session {
+ my $self = shift;
+ my $ses = $_audit_session;
+ undef $_audit_session;
+ return $ses;
+ }
+
}
1;
argc => 1,
);
+ sub pg_set_audit_info {
+ my $self = shift;
+ my $client = shift;
+ my $authtoken = shift;
+ my $user_id = shift;
+ my $ws_id = shift;
+
+ local $OpenILS::Application::Storage::WRITE = 1;
+
+ $log->debug("Setting auditor information", INFO);
+
+ if($pg->current_audit_session) {
+ $log->debug("Already sent audit data.", INFO);
+ return 1;
+ }
+
+ my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
+
+ try {
+ if(!$user_id) {
+ my $ses = OpenSRF::AppSession->create('open-ils.auth');
+ my $content = $ses->request('open-ils.auth.session.retrieve', $authtoken, 1)->gather(1);
+ if(!$content or !$content->{userObj}) {
+ return 0;
+ }
+ $user_id = $content->{userObj}->id;
+ $ws_id = $content->{userObj}->wsid;
+ }
+ $ws_id = 'NULL' unless $ws_id;
+ $dbh->do("SELECT auditor.set_audit_info($user_id, $ws_id);");
+ } catch Error with {
+ my $e = shift;
+ $log->debug("Failed to set auditor information: ".$e, INFO);
+ throw $e;
+ };
+
+ $pg->set_audit_session( $client->session );
+
+ my $death_cb = $client->session->register_callback(
+ death => sub {
+ __PACKAGE__->pg_clear_audit_info;
+ }
+ );
+
+ $log->debug("Registered 'death' callback [$death_cb] for clearing audit information", DEBUG);
+
+ $client->session->session_data( death_cb_ai => $death_cb );
+
+ return 1;
+
+ }
+ __PACKAGE__->register_method(
+ method => 'pg_set_audit_info',
+ api_name => 'open-ils.storage.set_audit_info',
+ api_level => 1,
+ argc => 3,
+ );
+
+ sub pg_clear_audit_info {
+ my $self = shift;
+
+ try {
+ my $dbh = OpenILS::Application::Storage::CDBI->db_Main;
+ $log->debug("Clearing Audit Information", INFO);
+ $dbh->do("SELECT auditor.clear_audit_info();");
+ } catch Error with {
+ my $e = shift;
+ $log->debug("Failed to clear audit information: ".$e, INFO);
+ };
+
+ $pg->current_audit_session->unregister_callback( death =>
+ $pg->current_audit_session->session_data( 'death_cb_ai' )
+ ) if ($pg->current_audit_session);
+
+ $pg->unset_audit_session;
+ }
+
+
sub copy_create_start {
my $self = shift;
my $stat = $self->request($self->app . '.transaction.begin');
$self->log(E, "error starting database transaction") unless $stat;
$self->{xact_id} = $stat;
+ if($self->authtoken) {
+ if(!$self->requestor) {
+ $self->checkauth;
+ }
+ my $user_id = undef;
+ my $ws_id = undef;
+ if($self->requestor) {
+ $user_id = $self->requestor->id;
+ $ws_id = $self->requestor->wsid;
+ }
+ $self->request($self->app . '.set_audit_info', $self->authtoken, $user_id, $ws_id);
+ }
}
$self->{xact} = 1;
return $self->{xact_id};
$self->log(D, "starting new db session");
my $stat = $self->request('open-ils.storage.transaction.begin');
$self->log(E, "error starting database transaction") unless $stat;
+ if($self->authtoken) {
+ if(!$self->requestor) {
+ $self->checkauth;
+ }
+ my $user_id = undef;
+ my $ws_id = undef;
+ if($self->requestor) {
+ $user_id = $self->requestor->id;
+ $ws_id = $self->requestor->wsid;
+ }
+ $self->request('open-ils.storage.set_audit_info', $self->authtoken, $user_id, $ws_id);
+ }
return $stat;
}
$cstore->connect();
$cstore->request('open-ils.cstore.transaction.begin')->gather(1);
+ $cstore->request('open-ils.cstore.set_audit_info', $auth_ses, $user->id, $user->wsid)->gather(1);
for my $xact ( @xacts ) {
try {
my $e = OpenSRF::AppSession->connect('open-ils.cstore');
$e->request('open-ils.cstore.transaction.begin')->gather(1);
+ $e->request('open-ils.cstore.set_audit_info', $authid, $usr->id, $usr->wsid)->gather(1);
# still no records ...
my $container = $cgi->param('containerid');