How to get/set the "website" user account attribute by command line using occ

Support intro

Sorry to hear you’re facing problems :slightly_frowning_face:

help.nextcloud.com is for home/non-enterprise users. If you’re running a business, paid support can be accessed via portal.nextcloud.com where we can ensure your business keeps running smoothly.

In order to help you as quickly as possible, before clicking Create Topic please provide as much of the below as you can. Feel free to use a pastebin service for logs, otherwise either indent short log examples with four spaces:

example

Or for longer, use three backticks above and below the code snippet:

longer
example
here

Some or all of the below information will be requested if it isn’t supplied; for fastest response please provide as much as you can :heart:

Nextcloud version (eg, 25.0.3): 25.0.3
Operating system and version (eg, Ubuntu 20.04): Standard docker compose instance
Apache or nginx version (eg, Apache 2.4.25): (from docker compose)
PHP version (eg, 7.4): from docker compose)

The issue you are facing:

I’m searching for a way to handle the user profile attributes (mainly “website”) using occ.
I’ve been testing and searching around for a while, but I did not find a way to read the “website” attribut by “occ”, even if this attribute has correctly set on the GUI.

Does anyone know the “occ” arguments I should use to retrieve this information?

Have you seen the "occ user:setting <username>" command. It might allow you to set the parameter you’re looking for.

1 Like

For sure I stayed for a while playing around whit this command. :wink:

But, using this command with “get”, I was completely enable to display the attributes which have been set on the GUI.
I also tested issuing a “set” on the “website” attribute. The “get” returns the set value (indeed the “occ” command worked!!), but the GUI ignores the information set by “occ”.

I’m hitting something, but not the right target :cold_face:

Maybe the seen behavior is caused by any kind of caching. Have you tried to reload the web content or logged-off and logged-on again to see if the changes are loaded?

You can look where your occ–changes arrive in the database, since there are two different tables storing the ‘website’ vallue:

  1. oc_accounts_data

  2. oc_accounts

The query for 2. returns a JSON array. You need the command-line JSON processor jq to make it human readable (json-pretty):

which jq || apt install jq

The queries for the two results are as follows:

as root:

# change path and webserver-user accordingly:
occ_call="sudo -u www-data php -f /var/www/nextcloud/occ"
# basic data
dbname="$($occ_call config:system:get dbname)"
dbprfx="$($occ_call config:system:get dbtableprefix)"
dbuser="$($occ_call config:system:get dbuser)"
dbpw="$($occ_call config:system:get dbpassword)"

# user to check:
user=UID

# query string for 1:
mysql -u $dbuser -p$dbpw $dbname -Ne "SELECT * FROM ${dbprfx}accounts_data WHERE uid = '$user'"

# query string for 2:
mysql -u $dbuser -p$dbpw $dbname -Ne "SELECT data FROM ${dbprfx}accounts WHERE uid = '$user'" | jq

If you have a lot of users to query, you can iterate these queries through all users with a script like this one:

#!/bin/bash
# change path and webserver-user accordingly:
occ_call="sudo -u www-data php -f /var/www/nextcloud/occ"
# basic data
dbname="$($occ_call config:system:get dbname)"
dbprfx="$($occ_call config:system:get dbtableprefix)"
dbuser="$($occ_call config:system:get dbuser)"
dbpw="$($occ_call config:system:get dbpassword)"

# We need to take the detour via base64 to allow usernames with spaces
for user in $(echo $($occ_call user:list --output=json | jq -r 'keys_unsorted[] | @base64')); do
    user="$(echo "$user" | base64 --decode)"
    echo "processing User $user"
    echo
    read -p "Press ENTER to show 'accounts_data' query or ^C to cancel" dummy
    mysql -u $dbuser -p$dbpw $dbname -Ne "SELECT * FROM ${dbprfx}accounts_data WHERE uid = '$user'"
    read -p "Press ENTER to show 'accounts' query or ^C to cancel" dummy
    mysql -u $dbuser -p$dbpw $dbname -Ne "SELECT data FROM ${dbprfx}accounts WHERE uid = '$user'" | jq
    read -p "Press ENTER to show next user or ^C to cancel" dummy
    echo
done

Just my 2 cent

2 Likes

A very detailed answer for 2 cents :+1: :grinning:

Playing around directly in the DB makes of course things possible. But I was hoping to make it by “occ” to prevent any DB corruption.

So I search for the code which is able to change the “displayname” attribute, since this works by “occ”:

occ user:setting the_considered_user settings display_name the_new_display_name

An I found the following code:

                           if ($app === 'settings' && in_array($key, ['email', 'display_name'])) {
                                    $user = $this->userManager->get($uid);
                                    if ($user instanceof IUser) {
                                            if ($key === 'email') {
                                                    $user->setEMailAddress($input->getArgument('value'));
                                            } elseif ($key === 'display_name') {
                                                    if (!$user->setDisplayName($input->getArgument('value'))) {
                                                            if ($user->getDisplayName() === $input->getArgument('value')) {
                                                                    $output->writeln('<error>New and old display name are the same</error>');
                                                            } elseif ($input->getArgument('value') === '') {
                                                                    $output->writeln('<error>New display name can\'t be empty</error>');
                                                            } else {
                                                                    $output->writeln('<error>Could not set display name</error>');
                                                            }
                                                            return 1;
                                                    }
                                            }
                                            // setEmailAddress and setDisplayName both internally set the value
                                            return 0;
                                    }
                            }

It is clear that only the email address and the display name can be changed by this code => by “occ”.

A lack?

You are welcome :cowboy_hat_face:

It would have been somewhat helpful if at least the name and path of the file had been given.
I can give detailed answers, but if I only get rudimentary answers, then I don’t know if it’s meant seriously.

First of all, I take the code as is, and I have to work with it. So I’m not looking for lacks, I’m looking for solutions. There is always a solution. It solely depends on how much effort you are willing to invest to reach the goal.

You could install phpMyAdmin on your server, which would allow you to manipulate database entries in a graphical interface. However, it’s important to ensure that your installation is secure, as it can potentially serve as a gateway for attacks.

What else you can do to get your solution:

  1. You can rewrite the code so that it works and submit a CR (code review) to have it checked and merged.
  2. If you want to see this feature implemented by the maintainers, you can submit an FR (feature request).
  3. Alternatively, you could choose to do nothing and continue to work with the code as it is.

I hope i could help.