Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 39 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
# Team folders
# Group folders

[![REUSE status](https://api.reuse.software/badge/github.com/nextcloud/groupfolders)](https://api.reuse.software/info/github.com/nextcloud/groupfolders)

Expand All @@ -15,48 +15,52 @@

[^1]: The releases are now managed in a [dedicated release repository](https://github.com/nextcloud-releases/groupfolders/releases). The releases in this repository may be outdated.

## Configuring Team folder
## Configuring group folders

Team folders can be configured through *Team folders* under *Administration settings*.
Group folders can be configured through *Group folders* under *Administration settings*.

After a folder is created, the admin can give access to the folder to one or more groups, users or Teams (formerly Circles). A quota can be assigned for the folder and advanced permissions can be activated and configured.

![edit](screenshots/edit.png)

Permissions to the content of a Team folder can be configured on a per-group/team/user basis.
Permissions to the content of a group folder can be configured on a per-group/team/user basis.

![permissions](screenshots/permissions.png)

The configuration options include the _Write_, _Share_ and _Delete_ permissions for each group.

## Using Team folders
## Using group folders

Once configured, the folders will show up in the home folder for each user in the configured groups or teams.

![folders](screenshots/folders.png)

>[!WARNING]
> There is no record of when a user or team was added to a Team folder, and anything related to the team is considered shared knowledge, including previous versions and deleted files.
> There is no record of when a user or team was added to a group folder, and anything related to the team is considered shared knowledge, including previous versions and deleted files.

## Team Folder Data Storage
## Team folders

Where and how Team folder data is stored depends on your Nextcloud instance’s storage configuration.
Team folders are the main storage for teams and have a 1:1 relationship with a team. Their lifecycle and permissions are managed by the team integration, while group folders remain freely configurable by administrators.

## Group folder data storage

Where and how group folder data is stored depends on your Nextcloud instance’s storage configuration.

### Default Storage on Filesystem

By default, all files, versions, and trash for each Team folder are stored **on your server’s local filesystem**, inside your Nextcloud `datadirectory` under a special subdirectory:
By default, all files, versions, and trash for each group folder are stored **on your server’s local filesystem**, inside your Nextcloud `datadirectory` under a special subdirectory:

```
<datadirectory>/__groupfolders/<folder_id>/files/
<datadirectory>/__groupfolders/<folder_id>/trash/
<datadirectory>/__groupfolders/<folder_id>/versions/
```

where `<folder_id>` is the numeric ID of the Team folder. Each Team folder gets its own folder within `__groupfolders`.
where `<folder_id>` is the numeric ID of the group folder. Each group folder gets its own folder within `__groupfolders`.

### Object Storage as Primary Storage

If your Nextcloud instance is configured to use **primary object storage** (e.g., S3, Swift), all Team folder data is stored in the object storage bucket, using the same logical layout as above:
If your Nextcloud instance is configured to use **primary object storage** (e.g., S3, Swift), all group folder data is stored in the object storage bucket, using the same logical layout as above:

```
__groupfolders/<folder_id>/files/
Expand All @@ -71,33 +75,33 @@ In this case, data is never stored on the server’s local disk. The mapping and

### End-User and Admin Experience

Team folders always appear as special shared folders in users’ file lists, regardless of whether you are using local or object storage. No additional configuration is needed for accessing or sharing files, regardless of backend storage type.
Group folders always appear as special shared folders in users’ file lists, regardless of whether you are using local or object storage. No additional configuration is needed for accessing or sharing files, regardless of backend storage type.

All access control, configuration, and permissions for Team folders are managed within the Nextcloud database and UI as before.
All access control, configuration, and permissions for group folders are managed within the Nextcloud database and UI as before.


## Setting Advanced Permissions

_Advanced Permissions_ allows entitled users to configure permissions inside Team folders on a per file and folder basis.
_Advanced Permissions_ allows entitled users to configure permissions inside group folders on a per file and folder basis.

Permissions are configured by setting one or more of "Read", "Write", "Create", "Delete" or "Share" permissions to "allow" or "deny". Any permission not explicitly set will inherit the permissions from the parent folder. If multiple configured advanced permissions for a single file or folder apply for a single user (such as when a user belongs to multiple groups), the "allow" permission will overwrite any "deny" permission. Denied permissions configured for the Team folder itself cannot be overwritten to "allow" permissions by the advanced permission rules.
Permissions are configured by setting one or more of "Read", "Write", "Create", "Delete" or "Share" permissions to "allow" or "deny". Any permission not explicitly set will inherit the permissions from the parent folder. If multiple configured advanced permissions for a single file or folder apply for a single user (such as when a user belongs to multiple groups), the "allow" permission will overwrite any "deny" permission. Denied permissions configured for the group folder itself cannot be overwritten to "allow" permissions by the advanced permission rules.

Take a look at this example to understand how to properly configure Advanced Permissions for more complex scenarios with multiple groups or Teams:
1. You have the groups "Management", "Employees" with some users only belonging to "Management", but everyone being part of "Employees".
2. You configure a Team folder and add the groups "Management", "Employees" with "Read" and "Write" permissions.
3. For a sub folder in the Team folder you explicitly configure the group "Employees" to have NO "Write" permission, but still "Read" permission.
2. You configure a group folder and add the groups "Management", "Employees" with "Read" and "Write" permissions.
3. For a sub folder in the group folder you explicitly configure the group "Employees" to have NO "Write" permission, but still "Read" permission.
4. For the same sub folder you configure "Management" to have "Read" and "Write" permissions.

Now only users in the "Management" group can write in the sub folder, while all users in the "Employees" group can not.

Note that currently (Nextcloud 31/Hub 10) you need to be a member or admin of a team in order to assign it to a Team folder.
Note that currently (Nextcloud 31/Hub 10) you need to be a member or admin of a team in order to assign it to a group folder.

All ACL rules always need to have the least permissions for any user/group/Team with access to the sub folder.
For those users/groups/Teams that need more permissions you need to add a second rule that grants them the desired permissions.

![advanced permissions](screenshots/acl.png)

Users or whole groups can be entitled to set advanced permissions for each Team folder separately on the Team folders admin page.
Users or whole groups can be entitled to set advanced permissions for each group folder separately on the Group folders admin page.
For entitlements, only users from those groups are selectable which have to be configured selected in the Groups column.

![advanced permission entitlement](screenshots/aclAdmin.png)
Expand All @@ -106,7 +110,7 @@ For entitlements, only users from those groups are selectable which have to be c

Some settings are currently only exposed via `config/config.php`:

### Default quota for new Team folders
### Default quota for new group folders

```injectablephp
'groupfolders.quota.default' => -3,
Expand All @@ -116,24 +120,24 @@ The special value `-3` means unlimited and any other value is the quota limit in

## Command-line interface management and configuration (via `occ`)

Team folders can be configured and managed from the command-line interface (CLI). This is accomplished by using the `occ` command.
Group folders can be configured and managed from the command-line interface (CLI). This is accomplished by using the `occ` command.

The `occ` command is utilized throughout Nextcloud for many operations and is not specific to Team folders. When the Team folders app is enabled, the `occ` command gains additional functionality specific to Team folders.
The `occ` command is utilized throughout Nextcloud for many operations and is not specific to group folders. When the Group folders app is enabled, the `occ` command gains additional functionality specific to group folders.

If you're unfamiliar with `occ` see [Using the occ command](https://docs.nextcloud.com/server/latest/admin_manual/occ_command.html) in the Nextcloud Server Administration Guide for general guidance.

### Commands Available

- `occ groupfolders:create <name>` &rarr; create a Team folder
- `occ groupfolders:delete <folder_id> [-f|--force]` &rarr; delete a Team folder and all its contents
- `occ groupfolders:create <name>` &rarr; create a group folder
- `occ groupfolders:delete <folder_id> [-f|--force]` &rarr; delete a group folder and all its contents
- `occ groupfolders:expire` &rarr; trigger file version and trashbin expiration (see [Nextcloud docs for versioning](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/file_versioning.html) and [Nextcloud docs for the trash bin](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/trashbin_configuration.html) for details)
- `occ groupfolders:group <folder_id> <group_id> [-d|--delete] [write|share|delete]` &rarr; assign groups and their rights to a Team folder
- `occ groupfolders:list` &rarr; list configured Team folders
- `occ groupfolders:group <folder_id> <group_id> [-d|--delete] [write|share|delete]` &rarr; assign groups and their rights to a group folder
- `occ groupfolders:list` &rarr; list configured group folders
- `occ groupfolders:permissions` &rarr; configure advanced permissions (see below for details)
- `occ groupfolders:quota <folder_id> [<quota>|unlimited]` &rarr; set a quota for a Team folder
- `occ groupfolders:rename <folder_id> <name>` &rarr; rename a Team folder
- `occ groupfolders:scan <folder_id>` &rarr; trigger a filescan for a Team folder
- `occ groupfolders:trashbin:cleanup` &rarr; empty the trashbin of all Team folders
- `occ groupfolders:quota <folder_id> [<quota>|unlimited]` &rarr; set a quota for a group folder
- `occ groupfolders:rename <folder_id> <name>` &rarr; rename a group folder
- `occ groupfolders:scan <folder_id>` &rarr; trigger a filescan for a group folder
- `occ groupfolders:trashbin:cleanup` &rarr; empty the trashbin of all group folders
- `occ config:app:set groupfolders enable_encryption --value="true"` &rarr; activate encryption (server-side) support

### Configuring Advanced Permissions via `occ`
Expand All @@ -142,7 +146,7 @@ Advanced permissions can also be configured through the `occ groupfolders:permis

#### Enabling

Before configuring any advanced permissions you'll first have to enable advanced permissions for the folder using `occ groupfolders:permissions <folder_id> --enable`. To do this you'll first need to find the `folder_id` of the Team folder you're trying to configure. You can use `occ groupfolders:list` to find the `folder_id` of the target folder.
Before configuring any advanced permissions you'll first have to enable advanced permissions for the folder using `occ groupfolders:permissions <folder_id> --enable`. To do this you'll first need to find the `folder_id` of the group folder you're trying to configure. You can use `occ groupfolders:list` to find the `folder_id` of the target folder.

#### Using

Expand Down Expand Up @@ -172,7 +176,7 @@ To manage the users or groups entitled to set advanced permissions, use `occ gro

#### Disabling

To disable the advanced permissions feature for a Team folder, use `occ groupfolders:permissions <folder_id> --disable`.
To disable the advanced permissions feature for a group folder, use `occ groupfolders:permissions <folder_id> --disable`.

## APIs

Expand All @@ -182,9 +186,9 @@ See the [OpenAPI specification](openapi.json) to learn about all available API e

### WebDAV API

Team folders are also exposed through a separate [WebDAV API](https://docs.nextcloud.com/server/latest/user_manual/en/files/access_webdav.html) at `/remote.php/dav/groupfolders/<user id>`.
Group folders are also exposed through a separate [WebDAV API](https://docs.nextcloud.com/server/latest/user_manual/en/files/access_webdav.html) at `/remote.php/dav/groupfolders/<user id>`.

In addition to browsing the contents of the Team folders, you can also request the mount point for the Team folder by requesting the `{http://nextcloud.org/ns}mount-point` property.
In addition to browsing the contents of the group folders, you can also request the mount point for the group folder by requesting the `{http://nextcloud.org/ns}mount-point` property.


## 🚧 Development setup
Expand All @@ -193,4 +197,4 @@ In addition to browsing the contents of the Team folders, you can also request t
2. Run `npm ci` to install JS/frontend dependencies.
3. Run `npm run build` for a production build or `npm run dev` for a watch/dev build.
4. Then activate the app through the apps management.
5. Start using the app in "Team folders" in administration settings.
5. Start using the app in "Group folders" in administration settings.
14 changes: 7 additions & 7 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
-->
<info>
<id>groupfolders</id>
<name>Team Folders</name>
<summary>Shared folders managed by admins, accessible to designated teams with configurable permissions and quotas</summary>
<name>Group folders</name>
<summary>Shared folders managed by admins, accessible to designated groups and teams with configurable permissions and quotas</summary>
<description>
<![CDATA[
Team Folders (formerly "Group Folders") allows administrators to create and manage shared
folders for selected teams within Nextcloud.
The Group folders app allows administrators to create and manage shared folders for selected
groups and teams within Nextcloud.

Admins can grant one or more teams access to a folder, configure permissions (such as read,
write, and sharing rights), and assign storage quotas from the Team Folders section (under
Admins can grant one or more groups or teams access to a folder, configure permissions (such
as read, write, and sharing rights), and assign storage quotas from the Group folders section (under
admin settings). The app also supports advanced permissions and integration with Nextcloud’s
trash and versioning systems.

As of Hub 10 / Nextcloud 31, admins must be members of a team to assign that team to a Team
Folder.
folder.
]]>
</description>
<version>24.0.0-dev.0</version>
Expand Down
6 changes: 3 additions & 3 deletions lib/BackgroundJob/RepairMisplacedTrashItemsJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/**
* One-off repair to find trash items whose `group_folders_trash` row was
* updated to point to a new Team folder but the actual entries weren't.
* updated to point to a new group folder but the actual entries weren't.
*/
class RepairMisplacedTrashItemsJob extends QueuedJob {
public function __construct(
Expand All @@ -28,14 +28,14 @@ public function __construct(
}

public function getName(): string {
return 'Repair team folder trash item to their correct storage';
return 'Repair group folder trash item to their correct storage';
}

#[\Override]
public function run(mixed $argument): void {
$fixed = $this->trashBackend->repairMisplacedTrashItems();
if ($fixed > 0) {
$this->logger->info("Moved $fixed team folder trash item(s) to their correct storage");
$this->logger->info("Moved $fixed group folder trash item(s) to their correct storage");
}
}
}
2 changes: 1 addition & 1 deletion lib/Command/ACL.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function __construct(
protected function configure(): void {
$this
->setName('groupfolders:permissions')
->setDescription('Configure advanced permissions for a configured Team folder')
->setDescription('Configure advanced permissions for a configured group folder')
->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure')
->addOption('enable', 'e', InputOption::VALUE_NONE, 'Enable advanced permissions for the folder')
->addOption('disable', 'd', InputOption::VALUE_NONE, 'Disable advanced permissions for the folder')
Expand Down
2 changes: 1 addition & 1 deletion lib/Command/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function __construct(
protected function configure(): void {
$this
->setName('groupfolders:create')
->setDescription('Create a new Team folder')
->setDescription('Create a new group folder')
->addArgument('name', InputArgument::REQUIRED, 'Name or mount point of the new folder')
->addOption('bucket', null, InputOption::VALUE_REQUIRED, 'Overwrite the bucket used for the new folder')
->addOption('acl-no-default-permission', null, InputOption::VALUE_NONE, 'Do not grant any advanced permission by default');
Expand Down
4 changes: 2 additions & 2 deletions lib/Command/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Delete extends FolderCommand {
protected function configure(): void {
$this
->setName('groupfolders:delete')
->setDescription('Delete Team folder')
->setDescription('Delete group folder')
->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to rename')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Skip confirmation');
parent::configure();
Expand All @@ -38,7 +38,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion('Are you sure you want to delete the Team folder ' . $folder->mountPoint . ' and all files within, this cannot be undone (y/N).', false);
$question = new ConfirmationQuestion('Are you sure you want to delete the group folder ' . $folder->mountPoint . ' and all files within, this cannot be undone (y/N).', false);
if ($input->getOption('force') || $helper->ask($input, $output, $question)) {
$this->folderStorageManager->deleteStoragesForFolder($folder);
$this->folderManager->removeFolder($folder->id);
Expand Down
4 changes: 2 additions & 2 deletions lib/Command/ExpireGroupVersionsPlaceholder.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ class ExpireGroupVersionsPlaceholder extends Base {
protected function configure(): void {
$this
->setName('groupfolders:expire')
->setDescription('Trigger expiry of versions for files stored in Team folders');
->setDescription('Trigger expiry of versions for files stored in group folders');
parent::configure();
}

#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int {
$output->writeln('<error>Team folder version handling is only supported with Nextcloud 15 and up</error>');
$output->writeln('<error>Group folder version handling is only supported with Nextcloud 15 and up</error>');
return 0;
}
}
2 changes: 1 addition & 1 deletion lib/Command/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct(
protected function configure(): void {
$this
->setName('groupfolders:group')
->setDescription('Edit the groups that have access to a Team folder')
->setDescription('Edit the groups that have access to a group folder')
->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure')
->addArgument('group', InputArgument::REQUIRED, 'The group to configure')
->addArgument('permissions', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The permissions to set for the group as a white space separated list (ex: read write). Leave empty for read only')
Expand Down
Loading
Loading