Skip to content

Commit

Permalink
Add group_backend option to mirroring the circle as a group
Browse files Browse the repository at this point in the history
The main goal is to have better integrations with Nextcloud applications
and clients.

The group name is automatically suffixed by ` Circle`
And you can customize the prefix and/or suffix group name with the
`group_backend_name_prefix` and `group_backend_name_suffix` options

You should also hide these mirrored circles in Nextcloud applications
and clients, because their equivalent group will be used instead, via
the `allow_listed_circles` option set to `0`.

Fix #363

Signed-off-by: Tortue Torche <tortuetorche@users.noreply.github.com>
  • Loading branch information
tortuetorche committed Apr 1, 2020
1 parent 0dff4ea commit 459d92c
Show file tree
Hide file tree
Showing 12 changed files with 739 additions and 20 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ In non-SSL environments (like on development setups) it is necessary to set two

`./occ config:app:set circles --value 1 local_is_non_ssl`

## Allow mirroring circles as groups

```bash
./occ maintenance:mode --on

./occ config:app:set circles --value 1 group_backend # Mirroring circles as groups
./occ config:app:set circles --value 0 allow_listed_circles # Hide circles in shared list, useful with the 'group_backend' option

# ./occ config:app:set circles --value "🌀 " group_backend_name_prefix # You can customize group name prefix
# ./occ config:app:set circles --value " " group_backend_name_suffix # Remove default group name suffix with a `space` character

./occ config:app:set circles --value 12 allow_circles # Only show 'public' and 'closed' circles
./occ config:app:set circles --value 1 skip_invitation_to_closed_circles

./occ config:app:set circles --value 0 allow_files_filtered_by_circles # Disable files list filtering by circles in the 'files' application
./occ config:app:set circles --value 0 allow_adding_any_group_members # Adding group members only for groups where the current user is a member or global administrators

./occ maintenance:mode --off
```

# Credits

App Icon by [Madebyoliver](http://www.flaticon.com/authors/madebyoliver) under Creative Commons BY 3.0
44 changes: 44 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
use OCA\Circles\Api\v1\Circles;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\DavService;
use OCA\Circles\Service\GroupsBackendService;
use OCA\Files\App as FilesApp;
use OCP\App\ManagerEvent;
use OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\QueryException;
use OCP\IGroup;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Util;

Expand Down Expand Up @@ -79,6 +81,7 @@ public function register()
$this->registerFilesPlugin();
$this->registerHooks();
$this->registerDavHooks();
$this->registerGroupsBackendHooks();
}

/**
Expand Down Expand Up @@ -203,7 +206,48 @@ public function registerDavHooks() {
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', [$davService, 'onCreateCard']);
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', [$davService, 'onUpdateCard']);
$this->dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', [$davService, 'onDeleteCard']);
}

public function registerGroupsBackendHooks() {
try {
/** @var ConfigService $configService */
$configService = $this->server->query(ConfigService::class);
if (!$configService->isGroupsBackend()) {
return;
}

/** @var GroupsBackendService $groupsBackendService */
$groupsBackendService = $this->server->query(GroupsBackendService::class);
} catch (QueryException $e) {
return;
}

$this->dispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, [$groupsBackendService, 'onAppEnabled']);
$this->dispatcher->addListener('\OCA\Circles::onCircleCreation', [$groupsBackendService, 'onCircleCreation']);
$this->dispatcher->addListener('\OCA\Circles::onCircleDestruction', [$groupsBackendService, 'onCircleDestruction']);
$this->dispatcher->addListener('\OCA\Circles::onMemberNew', [$groupsBackendService, 'onMemberNew']);
$this->dispatcher->addListener('\OCA\Circles::onMemberInvited', [$groupsBackendService, 'onMemberInvited']);
$this->dispatcher->addListener('\OCA\Circles::onMemberRequesting', [$groupsBackendService, 'onMemberRequesting']);
$this->dispatcher->addListener('\OCA\Circles::onMemberLeaving', [$groupsBackendService, 'onMemberLeaving']);
$this->dispatcher->addListener('\OCA\Circles::onMemberLevel', [$groupsBackendService, 'onMemberLevel']);
$this->dispatcher->addListener('\OCA\Circles::onMemberOwner', [$groupsBackendService, 'onMemberOwner']);
$this->dispatcher->addListener('\OCA\Circles::onGroupLink', [$groupsBackendService, 'onGroupLink']);
$this->dispatcher->addListener('\OCA\Circles::onGroupUnlink', [$groupsBackendService, 'onGroupUnlink']);
$this->dispatcher->addListener('\OCA\Circles::onGroupLevel', [$groupsBackendService, 'onGroupLevel']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestSent', [$groupsBackendService, 'onLinkRequestSent']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestReceived', [$groupsBackendService, 'onLinkRequestReceived']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestRejected', [$groupsBackendService, 'onLinkRequestRejected']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestCanceled', [$groupsBackendService, 'onLinkRequestCanceled']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestAccepted', [$groupsBackendService, 'onLinkRequestAccepted']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRequestAccepting', [$groupsBackendService, 'onLinkRequestAccepting']);
$this->dispatcher->addListener('\OCA\Circles::onLinkUp', [$groupsBackendService, 'onLinkUp']);
$this->dispatcher->addListener('\OCA\Circles::onLinkDown', [$groupsBackendService, 'onLinkDown']);
$this->dispatcher->addListener('\OCA\Circles::onLinkRemove', [$groupsBackendService, 'onLinkRemove']);
$this->dispatcher->addListener('\OCA\Circles::onSettingsChange', [$groupsBackendService, 'onSettingsChange']);

$this->dispatcher->addListener(IGroup::class . '::postAddUser', [$groupsBackendService, 'onGroupPostAddUser']);
$this->dispatcher->addListener(IGroup::class . '::postRemoveUser', [$groupsBackendService, 'onGroupPostRemoveUser']);
$this->dispatcher->addListener(IGroup::class . '::postDelete', [$groupsBackendService, 'onGroupPostDelete']);
}

}
33 changes: 32 additions & 1 deletion lib/Db/CirclesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,36 @@ public function forceGetCircleByName($name) {
}


/**
* forceGetCircleByGroupId();
*
* returns data of a circle from its Group ID.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, do not use this method.
*
* @param $groupId
*
* @return null|Circle
*/
public function forceGetCircleByGroupId($groupId) {
$qb = $this->getCirclesSelectSql();

$this->limitToGroupId($qb, $groupId);

$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();

if ($data === false) {
return null;
}

$entry = $this->parseCirclesSelectSql($data);

return $entry;
}

/**
* @param string $userId
* @param int $type
Expand Down Expand Up @@ -331,7 +361,8 @@ public function updateCircle(Circle $circle, $userId) {
$qb = $this->getCirclesUpdateSql($circle->getUniqueId(true));
$qb->set('name', $qb->createNamedParameter($circle->getName()))
->set('description', $qb->createNamedParameter($circle->getDescription()))
->set('settings', $qb->createNamedParameter($circle->getSettings(true)));
->set('settings', $qb->createNamedParameter($circle->getSettings(true)))
->set('group_id', $qb->createNamedParameter($circle->getGroupId()));

$qb->execute();
}
Expand Down
3 changes: 2 additions & 1 deletion lib/Db/CirclesRequestBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ protected function getCirclesSelectSql() {
$qb->selectDistinct('c.unique_id')
->addSelect(
'c.id', 'c.name', 'c.description', 'c.settings', 'c.type', 'contact_addressbook',
'contact_groupname', 'c.creation'
'contact_groupname', 'c.creation', 'c.group_id'
)
->from(CoreRequestBuilder::TABLE_CIRCLES, 'c');
$this->default_select_alias = 'c';
Expand All @@ -418,6 +418,7 @@ protected function parseCirclesSelectSql($data) {
if ($data['contact_groupname'] !== null) {
$circle->setContactGroupName($data['contact_groupname']);
}
$circle->setGroupId($data['group_id']);
$circle->setSettings($data['settings']);
$circle->setType($data['type']);
$circle->setCreation($data['creation']);
Expand Down
9 changes: 8 additions & 1 deletion lib/Db/MembersRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,14 @@ public function unlinkAllFromGroup($groupId) {
}


public function unlinkFromGroup($circleId, $groupId) {
$qb = $this->getGroupsDeleteSql($groupId);
$this->limitToCircleId($qb, $circleId);

$qb->execute();
}


/**
* @param string $contactId
*
Expand Down Expand Up @@ -731,4 +739,3 @@ public function removeMembersByContactId(string $contactId, int $type = 0) {


}

81 changes: 81 additions & 0 deletions lib/Migration/Version0017Date20200221173726.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2019
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

declare(strict_types=1);

namespace OCA\Circles\Migration;

use Closure;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Type;
use OCP\DB\ISchemaWrapper;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* Auto-generated migration step: Please modify to your needs!
*/
class Version0017Date20200221173726 extends SimpleMigrationStep {


/** @var IDBConnection */
private $connection;


/**
* @param IDBConnection $connection
*/
public function __construct(IDBConnection $connection) {
$this->connection = $connection;
}


/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return null|ISchemaWrapper
* @throws SchemaException
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

$table = $schema->getTable('circles_circles');
$table->addColumn(
'group_id', 'string', [
'notnull' => false,
'default' => '',
'length' => 64,
]
);

return $schema;
}

}
19 changes: 19 additions & 0 deletions lib/Model/BaseCircle.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class BaseCircle {
/** @var int */
private $contactAddressBook = 0;

/** @var string */
private $groupId = '';

/** @var string */
private $creation;
Expand Down Expand Up @@ -307,6 +309,23 @@ public function getContactGroupName() {
return $this->contactGroupName;
}

/**
* @param string $groupId
*
* @return BaseCircle
*/
public function setGroupId($groupId) {
$this->groupId = (string) $groupId;

return $this;
}

/**
* @return string
*/
public function getGroupId() {
return (string) $this->groupId;
}

/**
* @param string|array $settings
Expand Down
3 changes: 1 addition & 2 deletions lib/Model/Circle.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public function jsonSerialize() {
'viewer' => $this->getHigherViewer(),
'description' => $this->getDescription(),
'settings' => $this->getSettings(),
'group_id' => $this->getGroupId(),
'type' => $this->getType(),
'creation' => $this->getCreation(),
'type_string' => $this->getTypeString(),
Expand Down Expand Up @@ -253,5 +254,3 @@ public static function typeLongString($type) {


}


Loading

0 comments on commit 459d92c

Please sign in to comment.