[open-ils-commits] ***SPAM*** [GIT] Evergreen ILS branch master updated. 951b648d8fc770db14bec9d8621d090d8ccb0756

Evergreen Git git at git.evergreen-ils.org
Thu Sep 25 17:22:56 EDT 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  951b648d8fc770db14bec9d8621d090d8ccb0756 (commit)
       via  aa2931cf5e8a69eb06141bb34b86031347d1a67b (commit)
      from  63a26679e88b056909257b6e7657a0d4aed469f7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 951b648d8fc770db14bec9d8621d090d8ccb0756
Author: Bill Erickson <berick at esilibrary.com>
Date:   Fri Aug 1 13:29:41 2014 -0400

    LP#1347774 CStoreEditor anonymous PCRUD additions
    
    * Exporter repairs : use export_to_level
    * pcrud personality call argument mod repair
    * log pcrud personality json_query attempts loudly to ease transition
    * CStoreEditor anon/pcrud personality live test
    
    * CStoreEditor anon pcrud default to undef authtoken:
    The presence of an authtoken ("ANONYMOUS") in the editor can be
    misleading at higher levels of the code, since it implies a
    presumably functional authtoken has been provided somewhow.
    Apply ANONYMOUS only as needed to API calls instead.
    
    Signed-off-by: Bill Erickson <berick at esilibrary.com>
    Signed-off-by: Mike Rylander <miker at esilibrary.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
index 9954610..c289324 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
@@ -69,7 +69,8 @@ sub import {
         }
     }
 
-    return $class->SUPER::import( @super_args );
+    # Exporter doesn't like you to call it's import() directly
+    return $class->export_to_level(1, $class, @super_args);
 }
 
 sub new_editor { return OpenILS::Utils::CStoreEditor->new(@_); }
@@ -213,7 +214,6 @@ sub died {
 sub authtoken {
     my( $self, $auth ) = @_;
     $self->{authtoken} = $auth if $auth;
-    return 'ANONYMOUS' if ($self->personality eq 'open-ils.pcrud' and !defined($self->{authtoken}));
     return $self->{authtoken};
 }
 
@@ -743,7 +743,7 @@ sub __arg_to_string {
 # return $e->event unless @$results; 
 # -----------------------------------------------------------------------------
 sub runmethod {
-    my( $self, $action, $type, $arg, $options ) = @_;
+    my( $self, $action, $type, $hint, $arg, $options ) = @_;
 
    $options ||= {};
 
@@ -762,7 +762,7 @@ sub runmethod {
     my @arg = ( ref($arg) eq 'ARRAY' ) ? @$arg : ($arg);
     my $method = '';
     if ($self->personality eq 'open-ils.pcrud') {
-        $method = $self->app.".$action.$type";
+        $method = $self->app.".$action.$hint";
     } else {
         $method = $self->app.".direct.$type.$action";
     }
@@ -827,8 +827,9 @@ sub runmethod {
     my $obj; 
     my $err = '';
 
-    # In pcrud mode, sub authtoken returns 'ANONYMOUS' if one is not yet set
-    unshift(@$arg, $self->authtoken) if ($self->personality eq 'open-ils.pcrud');
+    # in PCRUD mode, if no authtoken is set, fall back to anonymous.
+    unshift(@arg, ($self->authtoken || 'ANONYMOUS')) 
+        if ($self->personality eq 'open-ils.pcrud');
 
     try {
         $obj = $self->request($method, @arg);
@@ -918,14 +919,10 @@ sub init {
     my $map = $Fieldmapper::fieldmap;
     for my $object (keys %$map) {
         my $obj  = __fm2meth($object, '_');
-        my $type;
-        if (__PACKAGE__->personality eq 'open-ils.pcrud') {
-            $type = $object->json_hint;
-        } else {
-            $type = __fm2meth($object, '.');
-        }
+        my $type = __fm2meth($object, '.');
+        my $hint = $object->json_hint;
         foreach my $command (qw/ update retrieve search create delete batch_retrieve retrieve_all /) {
-            eval "sub ${command}_$obj {return shift()->runmethod('$command', '$type', \@_);}\n";
+            eval "sub ${command}_$obj {return shift()->runmethod('$command', '$type', '$hint', \@_);}\n";
         }
         # TODO: performance test against concatenating a big string of all the subs and eval'ing only ONCE.
     }
@@ -937,6 +934,9 @@ sub json_query {
     my( $self, $arg, $options ) = @_;
 
     if( $self->personality eq 'open-ils.pcrud' ) {
+        $self->log(E, "json_query is not allowed when using the ".
+            "open-ils.pcrud personality of CStoreEditor: " .Dumper($arg));
+
         $self->event(
             OpenILS::Event->new(
                 'JSON_QUERY_NOT_ALLOWED',
diff --git a/Open-ILS/src/perlmods/live_t/07-anon_pcrud.t b/Open-ILS/src/perlmods/live_t/07-anon_pcrud.t
new file mode 100644
index 0000000..9fddac7
--- /dev/null
+++ b/Open-ILS/src/perlmods/live_t/07-anon_pcrud.t
@@ -0,0 +1,31 @@
+#!perl
+
+use Test::More tests => 5;
+
+diag("Tests Anonymous PCRUD personality for CStoreEditor");
+
+use strict; use warnings;
+
+use OpenILS::Utils::TestUtils;
+use OpenILS::Utils::CStoreEditor (':funcs', personality => 'open-ils.pcrud');
+my $script = OpenILS::Utils::TestUtils->new();
+$script->bootstrap;
+
+my $e = new_editor;
+$e->init;
+
+is ($e->personality, 'open-ils.pcrud', 'Confirm personality');
+
+my $org = $e->retrieve_actor_org_unit(1);
+is($org->id, 1, 'Anon org unit retrieved');
+
+my $user = $e->retrieve_actor_user(1);
+is($user,  undef, 'Anon user not retrieved');
+
+$org = $e->search_actor_org_unit({id => 1})->[0];
+is($org->id, 1, 'Anon org unit searched');
+
+$user = $e->search_actor_user({id => 1})->[0];
+is($user,  undef, 'Anon user not searched');
+
+

commit aa2931cf5e8a69eb06141bb34b86031347d1a67b
Author: Mike Rylander <mrylander at gmail.com>
Date:   Thu Jul 24 15:03:37 2014 -0400

    LP#1347774 Anonymous PCRUD mode
    
    Support for anonymous access to public (field_safe=true) IDL data
    via PCRUD without requiring an authtoken.  To use, pass an authtoken of
    ANONYMOUS.
    
    Includes initial CStoreEditor plugin for anon pcrud.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/c-apps/oils_sql.c b/Open-ILS/src/c-apps/oils_sql.c
index 77cb12c..d29c6f2 100644
--- a/Open-ILS/src/c-apps/oils_sql.c
+++ b/Open-ILS/src/c-apps/oils_sql.c
@@ -119,6 +119,7 @@ static ClassInfo* add_joined_class( const char* alias, const char* classname );
 static void clear_query_stack( void );
 
 static const jsonObject* verifyUserPCRUD( osrfMethodContext* );
+static const jsonObject* verifyUserPCRUDfull( osrfMethodContext*, int );
 static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, int );
 static const char* org_tree_root( osrfMethodContext* ctx );
 static jsonObject* single_hash( const char* key, const char* value );
@@ -1406,48 +1407,62 @@ static int verifyObjectClass ( osrfMethodContext* ctx, const jsonObject* param )
 	server; otherwise NULL.
 */
 static const jsonObject* verifyUserPCRUD( osrfMethodContext* ctx ) {
+	return verifyUserPCRUDfull( ctx, 0 );
+}
+
+static const jsonObject* verifyUserPCRUDfull( osrfMethodContext* ctx, int anon_ok ) {
 
 	// Get the authkey (the first method parameter)
 	const char* auth = jsonObjectGetString( jsonObjectGetIndex( ctx->params, 0 ) );
 
-	// See if we have the same authkey, and a user object,
-	// locally cached from a previous call
-	const char* cached_authkey = getAuthkey( ctx );
-	if( cached_authkey && !strcmp( cached_authkey, auth ) ) {
-		const jsonObject* cached_user = getUserLogin( ctx );
-		if( cached_user )
-			return cached_user;
-	}
-
-	// We have no matching authentication data in the cache.  Authenticate from scratch.
-	jsonObject* auth_object = jsonNewObject( auth );
-
-	// Fetch the user object from the authentication server
-	jsonObject* user = oilsUtilsQuickReq( "open-ils.auth", "open-ils.auth.session.retrieve",
-			auth_object );
-	jsonObjectFree( auth_object );
-
-	if( !user->classname || strcmp(user->classname, "au" )) {
+	jsonObject* user = NULL;
+
+	// If we are /not/ in anonymous mode
+	if( strcmp( "ANONYMOUS", auth ) ) {
+		// See if we have the same authkey, and a user object,
+		// locally cached from a previous call
+		const char* cached_authkey = getAuthkey( ctx );
+		if( cached_authkey && !strcmp( cached_authkey, auth ) ) {
+			const jsonObject* cached_user = getUserLogin( ctx );
+			if( cached_user )
+				return cached_user;
+		}
 
-		growing_buffer* msg = buffer_init( 128 );
-		buffer_fadd(
-			msg,
-			"%s: permacrud received a bad auth token: %s",
-			modulename,
-			auth
-		);
+		// We have no matching authentication data in the cache.  Authenticate from scratch.
+		jsonObject* auth_object = jsonNewObject( auth );
+	
+		// Fetch the user object from the authentication server
+		user = oilsUtilsQuickReq( "open-ils.auth", "open-ils.auth.session.retrieve", auth_object );
+		jsonObjectFree( auth_object );
+	
+		if( !user->classname || strcmp(user->classname, "au" )) {
+	
+			growing_buffer* msg = buffer_init( 128 );
+			buffer_fadd(
+				msg,
+				"%s: permacrud received a bad auth token: %s",
+				modulename,
+				auth
+			);
+	
+			char* m = buffer_release( msg );
+			osrfAppSessionStatus( ctx->session, OSRF_STATUS_UNAUTHORIZED, "osrfMethodException",
+					ctx->request, m );
+	
+			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;
+		}
 
-		char* m = buffer_release( msg );
-		osrfAppSessionStatus( ctx->session, OSRF_STATUS_UNAUTHORIZED, "osrfMethodException",
-				ctx->request, m );
 
-		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;
+	} else if ( anon_ok ) { // we /are/ (attempting to be) anonymous
+		user = jsonNewObjectType(JSON_ARRAY);
+		jsonObjectSetClass( user, "aou" );
+		oilsFMSetString(user, "id", "-1");
 	}
 
 	setUserLogin( ctx, user );
@@ -1503,6 +1518,12 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
 		fetch = 1; // MUST go to the db for the object for update and delete
 	}
 
+	// In retrieve or search ONLY we allow anon. Later perm checks will fail as they should,
+	// in the face of a fake user but required permissions.
+	int anon_ok = 0;
+	if( *method_type == 'r' )
+		anon_ok = 1;
+
 	// Get the appropriate permacrud entry from the IDL, depending on method type
 	osrfHash* pcrud = osrfHashGet( osrfHashGet( class, "permacrud" ), method_type );
 	if( !pcrud ) {
@@ -1527,9 +1548,9 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
 	}
 
 	// Get the user id, and make sure the user is logged in
-	const jsonObject* user = verifyUserPCRUD( ctx );
+	const jsonObject* user = verifyUserPCRUDfull( ctx, anon_ok );
 	if( !user )
-		return 0;    // Not logged in?  No access.
+		return 0;    // Not logged in or anon?  No access.
 
 	int userid = atoi( oilsFMGetStringConst( user, "id" ) );
 
@@ -1544,6 +1565,10 @@ static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const js
 		return 1;
 	}
 
+	// But, if there are perms and the user is anonymous ... FAIL
+	if ( -1 == userid )
+		return 0;
+
 	// Build a list of org units that own the row.  This is fairly convoluted because there
 	// are several different ways that an org unit may own the row, as defined by the
 	// permacrud entry.
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
index 4ad858f..9954610 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm
@@ -48,6 +48,30 @@ use base qw/Exporter/;
 push @EXPORT_OK, ( 'new_editor', 'new_rstore_editor' );
 %EXPORT_TAGS = ( funcs => [ qw/ new_editor new_rstore_editor / ] );
 
+our $personality = 'open-ils.cstore';
+
+sub personality { 
+    my( $self, $app ) = @_;
+    $personality = $app if $app;
+    init() if $app; # rewrite if we changed personalities
+    return $personality;
+}
+
+sub import {
+    my $class = shift;
+
+    my @super_args = ();
+    while ( my $a = shift ) {
+        if ($a eq 'personality') {
+            $class->personality( shift );
+        } else {
+            push @super_args, $a;
+        }
+    }
+
+    return $class->SUPER::import( @super_args );
+}
+
 sub new_editor { return OpenILS::Utils::CStoreEditor->new(@_); }
 
 sub new_rstore_editor { 
@@ -90,7 +114,7 @@ sub DESTROY {
 sub app {
     my( $self, $app ) = @_;
     $self->{app} = $app if $app;
-    $self->{app} = 'open-ils.cstore' unless $self->{app};
+    $self->{app} = $self->personality unless $self->{app};
     return $self->{app};
 }
 
@@ -189,6 +213,7 @@ sub died {
 sub authtoken {
     my( $self, $auth ) = @_;
     $self->{authtoken} = $auth if $auth;
+    return 'ANONYMOUS' if ($self->personality eq 'open-ils.pcrud' and !defined($self->{authtoken}));
     return $self->{authtoken};
 }
 
@@ -418,7 +443,7 @@ sub request {
     if( ($self->{xact} or $always_xact) and 
             $self->session->state != OpenSRF::AppSession::CONNECTED() ) {
         #$logger->error("CStoreEditor lost it's connection!!");
-        throw OpenSRF::EX::ERROR ("CStore connection timed out - transaction cannot continue");
+        throw OpenSRF::EX::ERROR ($self->app." connection timed out - transaction cannot continue");
     }
 
 
@@ -735,7 +760,12 @@ sub runmethod {
     }
 
     my @arg = ( ref($arg) eq 'ARRAY' ) ? @$arg : ($arg);
-    my $method = $self->app.".direct.$type.$action";
+    my $method = '';
+    if ($self->personality eq 'open-ils.pcrud') {
+        $method = $self->app.".$action.$type";
+    } else {
+        $method = $self->app.".direct.$type.$action";
+    }
 
     if( $action eq 'search' ) {
         $method .= '.atomic';
@@ -784,7 +814,8 @@ sub runmethod {
         $self->log_activity($method, $type, $action, $arg);
     }
 
-    if($$options{checkperm}) {
+    # only check perms this way in non-pcrud mode
+    if($self->personality ne 'open-ils.pcrud' and $$options{checkperm}) {
         my $a = ($action eq 'search') ? 'retrieve' : $action;
         my $e = $self->_checkperm($type, $a, $$options{permorg});
         if($e) {
@@ -796,6 +827,9 @@ sub runmethod {
     my $obj; 
     my $err = '';
 
+    # In pcrud mode, sub authtoken returns 'ANONYMOUS' if one is not yet set
+    unshift(@$arg, $self->authtoken) if ($self->personality eq 'open-ils.pcrud');
+
     try {
         $obj = $self->request($method, @arg);
     } catch Error with { $err = shift; };
@@ -840,7 +874,7 @@ sub runmethod {
     }
 
     if( $action eq 'search' ) {
-        $self->log(I, "$type.$action : returned ".scalar(@$obj). " result(s)");
+        $self->log(I, "$method: returned ".scalar(@$obj). " result(s)");
         $self->event(_mk_not_found($type, $arg)) unless @$obj;
     }
 
@@ -884,7 +918,12 @@ sub init {
     my $map = $Fieldmapper::fieldmap;
     for my $object (keys %$map) {
         my $obj  = __fm2meth($object, '_');
-        my $type = __fm2meth($object, '.');
+        my $type;
+        if (__PACKAGE__->personality eq 'open-ils.pcrud') {
+            $type = $object->json_hint;
+        } else {
+            $type = __fm2meth($object, '.');
+        }
         foreach my $command (qw/ update retrieve search create delete batch_retrieve retrieve_all /) {
             eval "sub ${command}_$obj {return shift()->runmethod('$command', '$type', \@_);}\n";
         }
@@ -896,6 +935,18 @@ init();  # Add very many subs to this namespace
 
 sub json_query {
     my( $self, $arg, $options ) = @_;
+
+    if( $self->personality eq 'open-ils.pcrud' ) {
+        $self->event(
+            OpenILS::Event->new(
+                'JSON_QUERY_NOT_ALLOWED',
+                attempted_query => $arg,
+                debug => "json_query is not allowed when using the open-ils.pcrud personality of CStoreEditor" 
+            )
+        );
+        return undef;
+    }
+
     $options ||= {};
     my @arg = ( ref($arg) eq 'ARRAY' ) ? @$arg : ($arg);
     my $method = $self->app.'.json_query.atomic';

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/src/c-apps/oils_sql.c                     |   99 ++++++++++++-------
 .../src/perlmods/lib/OpenILS/Utils/CStoreEditor.pm |   65 ++++++++++++--
 Open-ILS/src/perlmods/live_t/07-anon_pcrud.t       |   31 ++++++
 3 files changed, 151 insertions(+), 44 deletions(-)
 create mode 100644 Open-ILS/src/perlmods/live_t/07-anon_pcrud.t


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list