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 );
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 );
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 ) {
}
// 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" ) );
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.
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 {
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};
}
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};
}
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");
}
}
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';
$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) {
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; };
}
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;
}
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";
}
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';