You are here: Foswiki>Tasks Web>Item14810 (23 Apr 2019, MichaelDaum)Edit Attach

Item14810: Programmatic calls to Foswiki::Func::saveTopic may fail to update DBCache

pencil
Priority: Normal
Current State: New
Released In: n/a
Target Release: n/a
Applies To: Extension
Component: DBCacheContrib
Branches:
Reported By: PaulMerchantJr
Waiting For:
Last Change By: MichaelDaum
Programmatically calling Foswiki::Func::saveTopic with ignorepermissions option set to create a new topic in a restricted web will fail to update DBCache unless the Foswiki object has been initialized with a default user that has permission to read the web.

I'm sorry that creating a stand alone test case from my code is rather complex, so I hope I can describe what I'm seeing well enough that someone will know how to fix it.

I have a web with view, change and rename permission restricted to a group of users. In the web are a form topic and a template topic with the form attached to it. My perl script creates a new topic in the web by reading the template topic (Foswiki::Func::readTopic) and creating the new topic via Foswiki::Func::saveTopic. In pseudo code:

   $Foswiki::cfg{Engine} = 'Foswiki::Engine::CLI';
   require Foswiki;

   $my wikiSession = Foswiki->new();

   my ($meta, $template) = Foswiki::Func::readTopic('Web', 'templateTopic');

   # Save the updated topic
   Foswiki::Func::saveTopic('Web', 'Topic', $meta, $template, {
      ignorepermissions => 1, 
      forcenewrevision => 1,
      author => 'SomeUser'
   });

After the call to saveTopic, the new topic exists on disk, but a call to DBQuery that should match the topic will not find it. Rebuilding the cache (./rest /DBCachePlugin/updateCache) makes the topic findable.

I've tracked the issue down to a permission error bubbling up through DBCacheContrib.pm around line 581 from _loadTopic: (site specific information removed)

lib/Foswiki/Contrib/DBCacheContrib.pm line 582.
   Foswiki::Contrib::DBCacheContrib::_updateTopic(Foswiki::Plugins::DBCachePlugin::WebDB=HASH(0x451c5d0), "Web", "Topic") called at lib/Foswiki/Contrib/DBCacheContrib.pm line 537
   eval {...} called at lib/Foswiki/Contrib/DBCacheContrib.pm line 537
   Foswiki::Contrib::DBCacheContrib::loadTopic(Foswiki::Plugins::DBCachePlugin::WebDB=HASH(0x451c5d0), "Web", "Topic") called at lib/Foswiki/Plugins/DBCachePlugin/Core.pm line 94
   Foswiki::Plugins::DBCachePlugin::Core::afterSaveHandler(Foswiki::Plugins::DBCachePlugin::Core=HASH(0x4143ba8), "Web", "topic") called at lib/Foswiki/Plugins/DBCachePlugin.pm line 195
   Foswiki::Plugins::DBCachePlugin::afterSaveHandler("%META:TOPICINFO{author=\"SomeUser\" comment=\"\" date=\"154756485"..., "Topic", "Web", undef, Foswiki::Meta=HASH(0x40c6520)) called at lib/Foswiki/Plugin.pm line 311
   Foswiki::Plugin::invoke(Foswiki::Plugin=HASH(0x28a53c0), "afterSaveHandler", "%META:TOPICINFO{author=\"SomeUser\" comment=\"\" date=\"154756485"..., "Topic", "Web", undef, Foswiki::Meta=HASH(0x40c6520)) called at lib/Foswiki/Plugins.pm line 376
   Foswiki::Plugins::dispatch(Foswiki::Plugins=HASH(0x1c41080), "afterSaveHandler", "%META:TOPICINFO{author=\"SomeUser\" comment=\"\" date=\"154756485"..., "Topic", "Web", undef, Foswiki::Meta=HASH(0x40c6520)) called at lib/Foswiki/Meta.pm line 2016
   Foswiki::Meta::save(Foswiki::Meta=HASH(0x40c6520), "author", "SomeUser", "forcenewrevision", 1, "ignorepermissions", 1) called at lib/Foswiki/Func.pm line 2115
   Foswiki::Func::saveTopic("Web", "Topic", Foswiki::Meta=HASH(0x40b87b0), "..."..., HASH(0x40c6460)) called at save2wiki.pl line xxx

The Foswiki log also shows this message:

| 2019-01-15T10:01:04-05:00 warning | Foswiki::Contrib::DBCacheContrib | DBCache: Cache read failed: AccessControlException: Access to VIEW Web.Form for BaseUserMapping_666 is denied. access denied on web |

The fundamental problem seems to be that the process for updating the cache is sensitive to the permissions of the current user, so although the save operation ignores permissions, the cache update does not and that causes the two states to lose synchronization.

There is a work around: set "AdminUser" as the default when initializing Foswiki (Foswiki->new('AdminUser')).

-- PaulMerchantJr - 15 Jan 2019

Which settings have you got for {DBCachePlugin} as well as {DBCacheContrib}?

-- MichaelDaum - 15 Jan 2019

$Foswiki::cfg{DBCacheContrib}{AlwaysUpdateCache} = 0;
$Foswiki::cfg{DBCacheContrib}{Archivist} = 'Foswiki::Contrib::DBCacheContrib::Archivist::Segmentable';
$Foswiki::cfg{DBCacheContrib}{LoadFileLimit} = '0';

$Foswiki::cfg{DBCachePlugin}{MemoryCache} = 1;
$Foswiki::cfg{DBCachePlugin}{UseUploadHandler} = 0;
$Foswiki::cfg{Plugins}{DBCachePlugin}{Enabled} = 1;
$Foswiki::cfg{Plugins}{DBCachePlugin}{Module} = 'Foswiki::Plugins::DBCachePlugin';

-- PaulMerchantJr - 15 Jan 2019

Actually, any script executing Foswiki from the command line does run as admin user. Home comes this is not the case for you? Further more, how are you able to view the topic when you don't have access rights to it? Or is it an unrelated topic not directly addressed by your call to saveTopic?

In any other case, your "work around" is correct: initializing the Foswiki object as admin user. I don't see an action item here otherwise. Please reopen if there is anything else we can do about it.

-- MichaelDaum - 16 Apr 2019

Interesting, my configuration does not appear to have a "DefaultUserName" which may explain the difference. At any rate, the main issue is the inconsistent behavior between the fundamental "Save" code which honors the "ignorepermissions" flag and the DBCachePlugin which does not even see that flag. I'm not sure "ignore permissions" is even a good concept to include in the "saveTopic" API, particularly if the flag isn't passed on to all the components that might be invoked during a save. It feels like a kludge. Running as user "admin" is an alternative way for a script to ignore the permissions, works uniformly across all the components, and at least to me has a clearer set of implications. When should code running as a non-admin user be able to ignore permissions? My suggestion would be to simplify the API by eliminating the "ignorepermissions" flag, and just rely on the conventional user permissions exclusively. No doubt that'll break something, though, as I see it used in Listy and MetaComment in my site.

-- PaulMerchantJr - 22 Apr 2019

 

ItemTemplate edit

Summary Programmatic calls to Foswiki::Func::saveTopic may fail to update DBCache
ReportedBy PaulMerchantJr
Codebase 2.1.6
SVN Range
AppliesTo Extension
Component DBCacheContrib
Priority Normal
CurrentState New
WaitingFor
Checkins
TargetRelease n/a
ReleasedIn n/a
CheckinsOnBranches
trunkCheckins
masterCheckins
ItemBranchCheckins
Release02x01Checkins
Release02x00Checkins
Release01x01Checkins
Topic revision: r6 - 23 Apr 2019, MichaelDaum
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy