How to secure users profile on xwiki with public space

Hi,

On our login-protected xwiki 10.11.3, we want open a public space for non registered users.
To make it work properly I enabled general read access for guests and disabled read access to private space.
It working well, except that user profiles (LDAP account) are readable by guest (because profile are in Xwiki space). It is very annoying because user profile displayed phone number, address and other private stuff.
I wonder how can I secure users profiles on my xwiki because these profiles are stored in a flat way in xwiki location.

I think about it and the solution could be to disable read access for non-registered users on each users profile.
Do you have a better idea to secure them?

I could launch a velocity script to add an XWiki.XWikiRights object to disable read for non-registered users but I don’t like a lot this solution (because new user could have their profile non secure during some hours).

How can I secure users profile at user profile creation?

Thxs for your help.

Pascal B

Why do you make the whole XWiki space viewable by guest ? You could allow view access to XWiki space only for registered user and give view right to guest only on the few things they need like the skin. Then any new page in the XWiki space won’t be viewable by guest.

Thxs, I started with your suggetion but it is difficult to make xwiki work fine for guests.
It is complicated to choose space/page to allowed for guests: skin of course but search engine/solr, (maybe live table) etc.
Some page to allow are on main location, other in xwiki (with include instruction often). velocity code with include. For example, suggest search engine doesn’t work.

Anyway I didn’t find a full list of pages to allowed for guest.

Right it depends how many features you want guests to be allowed to use.

So when guest have default view right on XWiki all I can think of is a listener which automatically add a right object with vew right on XWikiAllGroup when a new user is created.

That I want for guests are: all read only xwiki features.

Hum, I previously try to add a listener but I didn’t manage to make it work (xwiki was very slow after this)

Ok finally I try your proposal but I have an issue with skin of searchSuggest tools.
With guest account, when I typing some word to find, suggetions are temporaly displayed at the bottom of the page.


I could not find wich CSS missing…

Ok I found the missing CSS: /bin/skin/resources/css/xwiki-min.css.

If I’m log in xwiki: HTML source contain correct CSS file:

<link rel='stylesheet' type='text/css' href='/bin/skin/resources/css/xwiki-min.css?colorTheme=FlamingoThemes.iWiki_V1&amp;language=fr'/>

but with a guest account xwiki-min.css missing in HTML source…

I think this issue coming from: templates/stylesheets.vm

## Hook for inserting CSS skin extensions
#styleSheetExtensionHooks

Does guest have access to FlamingoThemes.iWiki_V1 page ?

Thanks! This fix my issue.
I will post all location that guest must read here if someone else interested.

I disabled view for non-registered users on my xwiki and enable view only for these locations and terminal pages:
Locations:

  • FlamingoThemes.WebPreferences
  • FlamingoThemesCode.WebPreferences
  • Help.WebPreferences
  • IconThemes.WebPreferences
  • Invitation.WebPreferences
  • Macros.WebPreferences
  • Main.WebPreferences
  • Panels.WebPreferences
  • PanelsCode.WebPreferences
  • Personnalisation.WebPreferences (custom CSS and Menu)
  • Public.WebPreferences (public custom location)
  • Rendering.WebPreferences
  • SandboxTemplate.WebPreferences
  • Scheduler.WebPreferences
  • WikiManager.WebPreferences
  • XWiki.WebPreferences (to hide user profiles select enable view for guests on all individual pages of xwiki location (except users profiles)
  • XWiki.XWikiPreferences

Terminal pages (add individual pages of xwiki location)

  • Invitation.InvitationGuestActions
  • Main.SpaceIndex
  • XWiki.ResetPassword
  • XWiki.DocumentTree
  • XWiki.SuggestSolrMacros
  • XWiki.Registration
  • XWiki.ForgotUsername
  • XWiki.DocumentTreeMacros
  • Invitation.InvitationCommon
  • XWiki.WatchListRss
  • XWiki.ResetPasswordMailContent
  • XWiki.ResetPasswordComplete

And finaly, here a snippet to list all public locations and terminal pages of your xwiki:

{{velocity}}
Cf. https://forum.xwiki.org/t/how-to-secure-users-profile-on-xwiki-with-public-space/5008/5
Liste tous les emplacements publique d'iWiki
(recherche de l'objet XWiki.XWikiGlobalRights et XWiki.XWikiGuest avec XWiki.XWikiGuest = view)

#set($classsName=['XWiki.XWikiGlobalRights','XWiki.XWikiRights'])
#foreach ($className in $classsName)
##set($className='XWiki.XWikiGlobalRights')
## XWiki.XWikiRights
#if ($className == 'XWiki.XWikiGlobalRights')
  **Public Locations (with XWiki.XWikiGuest = view)**
#else
  **Public Terminal Pages (with XWiki.XWikiGuest = view)**
#end

$xwiki.ssfx.use("js/xwiki/table/table.css")
$xwiki.jsfx.use("js/xwiki/table/tablefilterNsort.js", true)

{{html wiki='true'}}
<table id="tableid${velocityCount}" class="grid sortable filterable doOddEven">
  <tr class="sortHeader">
    <th>Location</th> <th>Read for guest</th>
  </tr>
#set($hql = "select distinct obj.name from BaseObject obj where obj.className='$className'")
## display 10 users
## set($results = $xwiki.search($hql, 10, 0))
#set($results = $xwiki.search($hql))
#foreach ($Page in $results)
  ## * [[$User]]
  ## if you have more than one object on a page, you will have to loop over them and use "$doc.use"
  #set($MyDoc = $xwiki.getDocument("$Page"))
  #set($class = $xwiki.getClass("$className"))
  #set($count = 0)

  ## loop over all objects
  #foreach($obj in $MyDoc.getObjects("$className"))
   #set ($displayLocation="")
    #set($discard = $MyDoc.use($obj))
    #set($count = $velocityCount)
    #set($rawLevel = $obj.getProperty('levels').value)
    #set($rawUsers = $obj.getProperty('users').value)
    ##set ($displayLocation='<tr><td>' + "[[$MyDoc>>$MyDoc.fullName]]" + '</td><td>' + $count + $!obj.levels + $!obj.users+ '</td></tr>')
    ## $displayLocation
    #if (($rawLevel.contains('view')) && ($rawUsers.contains('XWiki.XWikiGuest')))
      #set ($displayLocation='<tr><td>' + "[[$MyDoc>>$MyDoc.fullName]]" + '</td><td>' + $count + ', ' + $rawLevel + ' : ' + $rawUsers + '</td></tr>')
      $!displayLocation
    #end
  #end
#end
</table>
<br>
{{/html}}

##end "foreach ($className in"
#end

{{/velocity}}
1 Like

On Xwiki location I set read for guest to these pages:

  • XWiki.TagCloud
  • XWiki.ResetPassword
  • XWiki.Notifications.Code.NotificationFilterPreferenceLivetableResults
  • XWiki.UserDirectoryLivetableResults
  • XWiki.DocumentTree
  • XWiki.UserDirectoryMacros
  • XWiki.SuggestSolrMacros
  • XWiki.DocumentSheetBinding
  • XWiki.Registration
  • XWiki.ForgotUsername
  • XWiki.SuggestSolrService
  • XWiki.SearchSuggestSourceSheet
  • XWiki.XWikiUserWatchListLiveTableResults
  • XWiki.DocumentTreeMacros
  • XWiki.XWikiClassesLiveTableResults
  • XWiki.WatchListRss
  • XWiki.LiveTableResults
  • XWiki.SearchCode
  • XWiki.SearchSuggestConfig
  • XWiki.SearchSuggestConfigSheet
  • XWiki.LiveTableResultsMacros
  • XWiki.ResetPasswordMailContent
  • XWiki.SearchSuggestSourceClass
  • XWiki.ResetPasswordComplete

To complete my issue:
here a snippet to list pages of Xwiki location without groups and users profiles.
(I use a loop because i didn’t found a nice query for this)

{{velocity}}
Liste les pages de l'espace XWiki en excluant les profils utilisateurs.

## Pages Ă  exclure
#set($className='XWiki.XWikiUsers')
#set($classNameGroup='XWiki.XWikiGroups')
#set($SpaceName='XWiki')

**Docs on XWiki location without user profile: (exclude user profile and groups)**

$xwiki.ssfx.use("js/xwiki/table/table.css")
$xwiki.jsfx.use("js/xwiki/table/tablefilterNsort.js", true)

{{html wiki='true'}}
<table id="tableid" class="grid sortable filterable doOddEven">
  <tr class="sortHeader">
    <th>Doc</th>
  </tr>
## Query to select doc on XWiki space without user profile
##set($hql = ", BaseObject as obj where doc.fullName = obj.name and obj.className != '$className' and doc.space like '${SpaceName}.%'")
##set($hql = ", BaseObject obj where ((doc.fullName = obj.name and obj.className != '$className') and (doc.space like '${SpaceName}.%' and doc.name = 'WebHome'))")
#set($hql = ", BaseObject as obj where doc.fullName = obj.name and obj.className != '$className' and (doc.space like '${SpaceName}.%' or doc.space like '${SpaceName}')")

##, BaseObject as obj where doc.fullName = obj.name and obj.className = 'XWiki.XWikiUsers'

#set($hql = "where doc.space like '${SpaceName}' or doc.space like '${SpaceName}.%'")

#set($results = $services.query.hql($hql).execute())

#foreach ($Doc in $results)
  ## if you have more than one object on a page, you will have to loop over them and use "$doc.use"
  #set($MyDoc = $xwiki.getDocument("$Doc"))
  ##set($class = $xwiki.getClass("$className"))
  ##set($displayPage = False )
  ## loop over all objects
  ##if ($MyDoc.getObjects("$className"))
  #if (($MyDoc.getObjectNumbers("$className")  == 0) && ($MyDoc.getObjectNumbers("$classNameGroup") == 0) )
    <tr><td>[[$MyDoc>>$MyDoc]]</td></tr>
  #end
  ## $!displayUser
  ##set ($PreviousDoc="$MyDoc")
#end
</table>
{{/html}}

{{/velocity}}

Here’s also a link to a snippet which was published in the meantime and which allows to restrict access to user profiles automatically on user creation.