Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude groups for sharing #49217

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

T0mWz
Copy link

@T0mWz T0mWz commented Nov 12, 2024

See also issue #49198

Certain application or configuration options require the use of groups. Think of enabling certain apps for a specific group of the option to restrict autocomplete with sharing for only users in a specific group.
When you make use of these options, it can only result in large groups. When someone accidentally shares data with such a group then, it can have data impact in addition to large system impact.

Example array response which we got in on line; https://github.com/nextcloud/server/blob/master/apps/files_sharing/lib/Controller/ShareesAPIController.php#L200

Array
(
    [exact] => Array
        (
            [users] => Array
                (
                )

            [groups] => Array
                (
                )

            [remotes] => Array
                (
                )

            [remote_groups] => Array
                (
                )

            [emails] => Array
                (
                )

            [circles] => Array
                (
                )

            [rooms] => Array
                (
                )

        )

    [users] => Array
        (
            [0] => Array
                (
                    [label] => jupyterUser
                    [subline] => 
                    [icon] => icon-user
                    [value] => Array
                        (
                            [shareType] => 0
                            [shareWith] => jupyterUser
                        )

                    [shareWithDisplayNameUnique] => jupyterUser
                    [status] => Array
                        (
                        )

                )

        )

    [groups] => Array
        (
            [0] => Array
                (
                    [label] => jupyter
                    [value] => Array
                        (
                            [shareType] => 1
                            [shareWith] => jupyter
                        )

                )

            [1] => Array
                (
                    [label] => jupyter1
                    [value] => Array
                        (
                            [shareType] => 1
                            [shareWith] => jupyter1
                        )

                )

        )

    [remotes] => Array
        (
        )

    [remote_groups] => Array
        (
        )

    [emails] => Array
        (
        )

    [lookup] => Array
        (
        )

    [circles] => Array
        (
        )

    [rooms] => Array
        (
        )

    [lookupEnabled] => 1
)

From this result we will filter the group jupyter as example.
Array will contain a list of groups which will be excluded for sharing purposes.

vi config.php
..
  'blacklisted_groups' =>
  array(
     0 => "admin",
     1 => "jupyter",
     2 => "all_employees",
  ),
..

Copy link
Member

@provokateurin provokateurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test for this

Comment on lines +201 to +202
// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
// Get a list of groups to exclude from search results
$sharingDisabledGroups = $this->config->getSystemValue('sharing.disabled_groups', true);

This name is too generic for a system option and blacklist should be avoided (it's better and clearer to use blocklist).

Comment on lines +201 to +202
// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', []);

The default value needs to be an empty array, as otherwise the later code will fail if the config is not set.

Comment on lines +206 to +210
$this->result['groups'] = array_filter($this->result['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['groups'] = array_values($this->result['groups']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->result['groups'] = array_filter($this->result['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['groups'] = array_values($this->result['groups']);
$this->result['groups'] = array_values(array_filter($this->result['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
}));

Comment on lines +214 to +218
$this->result['exact']['groups'] = array_filter($this->result['exact']['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['exact']['groups'] = array_values($this->result['exact']['groups']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->result['exact']['groups'] = array_filter($this->result['exact']['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['exact']['groups'] = array_values($this->result['exact']['groups']);
$this->result['exact']['groups'] = array_values(array_filter($this->result['exact']['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
}));

@provokateurin
Copy link
Member

Also some documentation in https://github.com/nextcloud/documentation about this would be nice as well.

@sorbaugh
Copy link
Contributor

sorbaugh commented Nov 13, 2024

@tomwezepoel thanks for the contribution and good luck with the reviews!

Copy link
Member

@provokateurin provokateurin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally to excluding groups from the search results we should actually prevent creating shares with one of the groups as the recipient. This needs to be implemented in the ShareAPIController.

Copy link
Contributor

@artonge artonge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@nfebe nfebe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRY adjustments and possible type guard addition

@@ -197,6 +197,27 @@ public function search(string $search = '', ?string $itemType = null, int $page
$result['exact'] = array_merge($this->result['exact'], $result['exact']);
}
$this->result = array_merge($this->result, $result);

// Get a list of groups to exclude from search results
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
Copy link
Contributor

@nfebe nfebe Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
$blacklisted_groups = $this->config->getSystemValue('blacklisted_groups', true);
if (!is_array($blacklisted_groups)) {
$blacklisted_groups = [];
}

Graceful handling if non array is passed? This can be needless if the source if SURE to provide arrays (when probably not configurable)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is fine to assume we get an array, but the default value needs to be an array like I already suggested above.

Comment on lines +205 to +219
if (isset($this->result['groups'])) {
$this->result['groups'] = array_filter($this->result['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['groups'] = array_values($this->result['groups']);
}

if (isset($this->result['exact']['groups'])) {
$this->result['exact']['groups'] = array_filter($this->result['exact']['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['exact']['groups'] = array_values($this->result['exact']['groups']);
}
Copy link
Contributor

@nfebe nfebe Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (isset($this->result['groups'])) {
$this->result['groups'] = array_filter($this->result['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['groups'] = array_values($this->result['groups']);
}
if (isset($this->result['exact']['groups'])) {
$this->result['exact']['groups'] = array_filter($this->result['exact']['groups'], function($group) use ($blacklisted_groups) {
return !in_array($group['label'], $blacklisted_groups);
});
// Reindex array to maintain sequential numeric keys
$this->result['exact']['groups'] = array_values($this->result['exact']['groups']);
}
$filterBlacklistedGroups = function ($groups) use ($blacklisted_groups) {
return array_values(array_filter($groups, function ($group) use ($blacklisted_groups) {
return isset($group['label']) && !in_array($group['label'], $blacklisted_groups);
}));
};
if (isset($this->result['groups'])) {
$this->result['groups'] = $filterBlacklistedGroups($this->result['groups']);
}
if (isset($this->result['exact']['groups'])) {
$this->result['exact']['groups'] = $filterBlacklistedGroups($this->result['exact']['groups']);
}

Since the filter logic is repeated, you can use an inline closure..... or define a function outside this method.

@T0mWz
Copy link
Author

T0mWz commented Nov 14, 2024

Thanks for all your feedback, really appreciated. 👍 😃
We will dive into it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants