Unable to set by default profile privacy settings

Nextcloud version (eg, 20.0.5) : 25.0.7
Operating system and version (eg, Ubuntu 20.04) : Debian 11
PHP version (eg, 7.4) : 8.1

I’m trying to make more restrictive our default privacy settings without having to disable profiles, but I’m failing. What I want to achieve is hide any user details by default, so if a non logged user access https://mynextcloudinstance.com/u/[user_id] just found a page with no details.

From user profile page is as simple as set all visibility settings as “Show only to users” and works fine. But the problem comes when I try to set it as default for every new user. I’ve followed the instructions indicated on admin_manual and set this in my config.php file

'account_manager.default_property_scope' => [
  \OCP\Accounts\IAccountManager::PROPERTY_DISPLAYNAME => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_ADDRESS => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_WEBSITE => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_EMAIL => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_AVATAR => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_PHONE => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_TWITTER => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_ORGANISATION => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_ROLE => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_HEADLINE => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE,
  \OCP\Accounts\IAccountManager::PROPERTY_BIOGRAPHY => \OCP\Accounts\IAccountManager::SCOPE_PRIVATE
]

But when I create a new user all visibility settings are the same than before: avatar, biography, headline, organization. role… are visible to anyone. Is just ignoring those scope settings.

I dive in database and found 2 different tables related to this topic: oc_accounts (which seems to store the “scope” related settings by user) and oc_profile_config (with seems to store user profile “visibility” settings

oc_accounts value for the new user stores “correct” settings, at least as I defined in config.php

 {"displayname":{"value":"My new user name","scope":"v2-local","verified":"0"},"address":{"value":"","scope":"v2-private","verified":"0"},"website":{"value":"","scope":"v2-private","verified":"0"},"email":{"value":"mynewuser@email.com","scope":"v2-local","verified":"1"},"avatar":{"value":"","scope":"v2-private","verified":"0"},"phone":{"value":"","scope":"v2-private","verified":"0"},"twitter":{"value":"","scope":"v2-private","verified":"0"},"organisation":{"value":"","scope":"v2-private","verified":"0"},"role":{"value":"","scope":"v2-private","verified":"0"},"headline":{"value":"","scope":"v2-private","verified":"0"},"biography":{"value":"","scope":"v2-private","verified":"0"},"profile_enabled":{"value":"1","scope":"v2-local","verified":"0"}}

But oc_profile_visibilty stores a different one. The ones that make publicy available some private information.

{"talk":{"visibility":"show_users_only"},"email":{"visibility":"show_users_only"},"address":{"visibility":"show_users_only"},"avatar":{"visibility":"show"},"biography":{"visibility":"show"},"displayname":{"visibility":"show"},"headline":{"visibility":"show"},"organisation":{"visibility":"show"},"role":{"visibility":"show"},"phone":{"visibility":"show_users_only"},"twitter":{"visibility":"show"},"website":{"visibility":"show"}}

Maybe I’m missing some important concept? Is profile visibly a different setting from profile scope? Is it possible to set default visibility settings without having to completely disable profiles?

The setting will only be taken into account for new users.

1 Like

That’s clear @szaimen, and is written in admin manual . This happens with NEW users. I know that existing ones won’t change their settings.

Then no idea :man_shrugging:

Hello,
I would like to know if you were able to finally find the correct configuration.

Thanks gonzalo.cao for your post, the root cause is now apparent and quite deep, it is caused by 4 different bugs.

Bugs
• Account Scope - can only be set from defaults, not settings
• AccountManager.php - rejects some defaults (e.g. private email)
• Profile Visibility - can only be set from settings, not defaults
• Profile Visibility - stored into “oc_profile_config” db, does not get deleted with user deletion, which causes any new default changes to be ignored if user is recreated.

Thoughts
Having 2 diff fields (scope/visibility) is redundant. (at least frontend wise)
This is also the cause for the bug, where the contact list shows everyone’s emails regardless of settings.
I haven’t figured a workaround fix yet, seems quite complex.

Here is the workaround for the issues

SQL leaked entries

If you delete a user, the user entry in oc_profile_config doesn’t get deleted which will mess up your defaults test.

Simply delete it via phpadmin, or via SSH as follows:

  1. Login to your SQL nextcloud database.
  2. List users
    SELECT id, user_id FROM oc_profile_config;
    
  3. Delete leaked user entry
    DELETE FROM oc_profile_config WHERE user_id = 'username';
    

Default profile visibility (hidden)

  1. edit IProfileManager.php

    nano /var/www/nextcloud/lib/public/Profile/IProfileManager.php
    
  2. find (ctrl-w) & comment out line

    IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY,
    
  3. and instead paste this

    // IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY,
    IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_HIDE,
    

Default account scope (private)

  1. edit AccountManager.php

    nano /var/www/nextcloud/lib/private/Accounts/AccountManager.php
    
  2. same deal, find the line, comment out and paste as follows

    // 'scope' => $scopes[self::PROPERTY_EMAIL]
    'scope' => self::SCOPE_PRIVATE,
    
  3. and again for this line

    //&& in_array($property->getName(), [self::PROPERTY_DISPLAYNAME, self::PROPERTY_EMAIL])
    && in_array($property->getName(), [self::PROPERTY_DISPLAYNAME])
    
1 Like