migrate therinaldos.com data
Build & Deploy to DigitalOcean Space / build (push) Failing after 2m38s

This commit is contained in:
2024-05-05 15:50:45 -04:00
commit ef1ff240d4
23182 changed files with 3801898 additions and 0 deletions
@@ -0,0 +1,97 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Traits\TStringTools;
use OCA\Circles\Exceptions\MemberDoesNotExistException;
class AccountsRequest extends AccountsRequestBuilder {
use TStringTools;
public function getAccountData(string $userId): array {
$qb = $this->getAccountsSelectSql();
$this->limitToDBField($qb, 'uid', $userId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
return [];
}
return $this->parseAccountsSelectSql($data);
}
/**
* @param string $userId
*
* @deprecated
* @return array
* @throws MemberDoesNotExistException
*/
public function getFromUserId(string $userId): array {
$qb = $this->getAccountsSelectSql();
$this->limitToDBField($qb, 'uid', $userId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new MemberDoesNotExistException();
}
return $this->parseAccountsSelectSql($data);
}
/**
* @deprecated
* @return array
*/
public function getAll(): array {
$qb = $this->getAccountsSelectSql();
$accounts = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$account = $this->parseAccountsSelectSql($data);
$accounts[$account['userId']] = $account;
}
$cursor->closeCursor();
return $accounts;
}
}
@@ -0,0 +1,114 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Traits\TArrayTools;
use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* Class AccountsRequestBuilder
*
* @package OCA\Circles\Db
*/
class AccountsRequestBuilder extends DeprecatedRequestBuilder {
use TArrayTools;
/**
* Base of the Sql Insert request for Accounts
*
* @return IQueryBuilder
*/
protected function getAccountsInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::NC_TABLE_ACCOUNTS);
return $qb;
}
/**
* Base of the Sql Update request for Accounts
*
* @return IQueryBuilder
*/
protected function getAccountsUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::NC_TABLE_ACCOUNTS);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getAccountsSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select('a.uid', 'a.data')
->from(self::NC_TABLE_ACCOUNTS, 'a');
$this->default_select_alias = 'a';
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getAccountsDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::NC_TABLE_ACCOUNTS);
return $qb;
}
/**
* @param array $entry
*
* @return array
*/
protected function parseAccountsSelectSql(array $entry): array {
$data = json_decode($entry['data'], true);
if (!is_array($data)) {
$data = [];
}
return [
'userId' => $entry['uid'],
'displayName' => $this->get('displayname.value', $data)
];
}
}
@@ -0,0 +1,101 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\GSStatusException;
/**
* @deprecated
* Class CircleProviderRequest
*
* @package OCA\Circles\Db
*/
class CircleProviderRequest extends CircleProviderRequestBuilder {
/**
* @param $userId
* @param $circleUniqueIds
* @param $limit
* @param $offset
*
* @return array
* @throws GSStatusException
*/
public function getFilesForCircles($userId, $circleUniqueIds, $limit, $offset) {
$qb = $this->getCompleteSelectSql();
$this->linkToFileCache($qb, $userId);
$this->limitToPage($qb, $limit, $offset);
$this->limitToCircles($qb, $circleUniqueIds);
$this->linkToMember($qb, $userId, false, 'c');
// $this->leftJoinShareInitiator($qb);
$cursor = $qb->execute();
$object_ids = [];
while ($data = $cursor->fetch()) {
self::editShareFromParentEntry($data);
if (self::isAccessibleResult($data)) {
$object_ids[] = $data['file_source'];
}
}
$cursor->closeCursor();
return $object_ids;
}
/**
* Returns whether the given database result can be interpreted as
* a share with accessible file (not trashed, not deleted)
*
* @param $data
*F
*
* @return bool
*/
protected static function isAccessibleResult($data) {
if ($data['fileid'] === null || $data['path'] === null) {
return false;
}
return (!(explode('/', $data['path'], 2)[0] !== 'files'
&& explode(':', $data['storage_string_id'], 2)[0] === 'home'));
}
/**
* @param $data
*/
protected static function editShareFromParentEntry(&$data) {
if ($data['parent_id'] > 0) {
$data['permissions'] = $data['parent_perms'];
$data['file_target'] = $data['parent_target'];
}
}
}
@@ -0,0 +1,531 @@
<?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>
* @author Vinicius Cubas Brand <vinicius@eita.org.br>
* @author Daniel Tygel <dtygel@eita.org.br>
*
* @copyright 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use Doctrine\DBAL\Query\QueryBuilder;
use OC;
use OCA\Circles\Model\DeprecatedMember;
use OCP\DB\QueryBuilder\ICompositeExpression;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\NotFoundException;
use OCP\Share\IShare;
/**
* @deprecated
* Class CircleProviderRequestBuilder
*
* @package OCA\Circles\Db
*/
class CircleProviderRequestBuilder extends DeprecatedRequestBuilder {
/**
* returns the SQL request to get a specific share from the fileId and circleId
*
* @param int $fileId
* @param int $circleId
*
* @return IQueryBuilder
*/
protected function findShareParentSql($fileId, $circleId) {
$qb = $this->getBaseSelectSql();
$this->limitToShareParent($qb);
$this->limitToCircles($qb, [$circleId]);
$this->limitToFiles($qb, $fileId);
return $qb;
}
/**
* Limit the request to the given Circles.
*
* @param IQueryBuilder $qb
* @param array $circleUniqueIds
*/
protected function limitToCircles(IQueryBuilder $qb, $circleUniqueIds) {
if (!is_array($circleUniqueIds)) {
$circleUniqueIds = [$circleUniqueIds];
}
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
$qb->andWhere(
$expr->in(
$pf . 'share_with',
$qb->createNamedParameter($circleUniqueIds, IQueryBuilder::PARAM_STR_ARRAY)
)
);
}
/**
* Limit the request to the Share by its Id.
*
* @param IQueryBuilder $qb
* @param $shareId
*/
protected function limitToShare(IQueryBuilder $qb, $shareId) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
$qb->andWhere($expr->eq($pf . 'id', $qb->createNamedParameter($shareId)));
}
/**
* Limit the request to the top share (no children)
*
* @param IQueryBuilder $qb
*/
protected function limitToShareParent(IQueryBuilder $qb) {
$expr = $qb->expr();
$qb->andWhere($expr->isNull('parent'));
}
/**
* limit the request to the children of a share
*
* @param IQueryBuilder $qb
* @param $userId
* @param int $parentId
*/
protected function limitToShareChildren(IQueryBuilder $qb, $userId, $parentId = -1) {
$expr = $qb->expr();
$qb->andWhere($expr->eq('share_with', $qb->createNamedParameter($userId)));
if ($parentId > -1) {
$qb->andWhere($expr->eq('parent', $qb->createNamedParameter($parentId)));
} else {
$qb->andWhere($expr->isNotNull('parent'));
}
}
/**
* limit the request to the share itself AND its children.
* perfect if you want to delete everything related to a share
*
* @param IQueryBuilder $qb
* @param $circleId
*/
protected function limitToShareAndChildren(IQueryBuilder $qb, $circleId) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
$qb->andWhere(
$expr->orX(
$expr->eq($pf . 'parent', $qb->createNamedParameter($circleId)),
$expr->eq($pf . 'id', $qb->createNamedParameter($circleId))
)
);
}
/**
* limit the request to a fileId.
*
* @param IQueryBuilder $qb
* @param $files
*/
protected function limitToFiles(IQueryBuilder $qb, $files) {
if (!is_array($files)) {
$files = [$files];
}
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
$qb->andWhere(
$expr->in(
$pf . 'file_source',
$qb->createNamedParameter($files, IQueryBuilder::PARAM_INT_ARRAY)
)
);
}
/**
* @param IQueryBuilder $qb
* @param int $limit
* @param int $offset
*/
protected function limitToPage(IQueryBuilder $qb, $limit = -1, $offset = 0) {
if ($limit !== -1) {
$qb->setMaxResults($limit);
}
$qb->setFirstResult($offset);
}
/**
* limit the request to a userId
*
* @param IQueryBuilder $qb
* @param string $userId
* @param bool $reShares
*/
protected function limitToShareOwner(IQueryBuilder $qb, $userId, $reShares = false) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
if ($reShares === false) {
$qb->andWhere($expr->eq($pf . 'uid_initiator', $qb->createNamedParameter($userId)));
} else {
$qb->andWhere(
$expr->orX(
$expr->eq($pf . 'uid_owner', $qb->createNamedParameter($userId)),
$expr->eq($pf . 'uid_initiator', $qb->createNamedParameter($userId))
)
);
}
}
/**
* link circle field
*
* @param IQueryBuilder $qb
* @param int $shareId
*
* @deprecated
*
*/
protected function linkCircleField(IQueryBuilder $qb, $shareId = -1) {
$expr = $qb->expr();
$qb->from(DeprecatedRequestBuilder::TABLE_CIRCLES, 'c');
$tmpOrX = $expr->eq('s.share_with', 'c.unique_id');
if ($shareId === -1) {
$qb->andWhere($tmpOrX);
return;
}
$qb->andWhere(
$expr->orX(
$tmpOrX,
$expr->eq('s.parent', $qb->createNamedParameter($shareId))
)
);
}
/**
* @param IQueryBuilder $qb
*/
protected function linkToCircleOwner(IQueryBuilder $qb) {
$expr = $qb->expr();
$qb->selectAlias('mo.user_id', 'circle_owner');
$qb->leftJoin(
'c', DeprecatedRequestBuilder::TABLE_MEMBERS, 'mo', $expr->andX(
$expr->eq('mo.circle_id', 'c.unique_id'),
$expr->eq('mo.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER)),
$expr->eq('mo.level', $qb->createNamedParameter(DeprecatedMember::LEVEL_OWNER))
)
);
}
/**
* Link to member (userId) of circle
*
* @param IQueryBuilder $qb
* @param string $userId
* @param bool $groupMemberAllowed
* @param string $aliasCircles
*/
protected function linkToMember(
IQueryBuilder $qb, string $userId, bool $groupMemberAllowed, string $aliasCircles
) {
$qb->from(DeprecatedRequestBuilder::TABLE_MEMBERS, 'mcm');
$expr = $qb->expr();
$orX = $expr->orX();
$orX->add($this->exprLinkToMemberAsCircleMember($qb, $userId, 'mcm', $aliasCircles));
if ($groupMemberAllowed) {
$orX->add($this->exprLinkToMemberAsGroupMember($qb, $userId, 'mcm', $aliasCircles));
}
$qb->andWhere($orX);
}
/**
* generate CompositeExpression to link to a Member as a Real Circle Member
*
* @param IQueryBuilder $qb
* @param string $userId
* @param string $aliasM
* @param string $aliasC
*
* @return ICompositeExpression
*/
private function exprLinkToMemberAsCircleMember(
IQueryBuilder $qb, string $userId, string $aliasM, string $aliasC
): ICompositeExpression {
$expr = $qb->expr();
$andX = $expr->andX();
$andX->add($expr->eq($aliasM . '.user_id', $qb->createNamedParameter($userId)));
$andX->add($expr->eq($aliasM . '.circle_id', $aliasC . '.unique_id'));
$andX->add($expr->gte($aliasM . '.level', $qb->createNamedParameter(DeprecatedMember::LEVEL_MEMBER)));
$andX->add($expr->eq($aliasM . '.instance', $qb->createNamedParameter('')));
$andX->add($expr->eq($aliasM . '.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER)));
return $andX;
}
/**
* generate CompositeExpression to link to a Member as a Group Member (core NC)
*
* @param IQueryBuilder $qb
* @param string $userId
* @param string $aliasM
* @param string $aliasC
*
* @return ICompositeExpression
*/
private function exprLinkToMemberAsGroupMember(
IQueryBuilder $qb, string $userId, string $aliasM, string $aliasC
) {
$expr = $qb->expr();
$qb->leftJoin(
$aliasM, self::NC_TABLE_GROUP_USER, 'ncgu',
$expr->eq('ncgu.uid', $qb->createNamedParameter($userId))
);
$andX = $expr->andX();
$andX->add($expr->eq($aliasM . '.user_id', 'ncgu.gid'));
$andX->add($expr->eq($aliasM . '.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_GROUP)));
$andX->add($expr->eq($aliasM . '.instance', $qb->createNamedParameter('')));
$andX->add($expr->eq($aliasM . '.circle_id', $aliasC . '.unique_id'));
$andX->add($expr->gte($aliasM . '.level', $qb->createNamedParameter(DeprecatedMember::LEVEL_MEMBER)));
return $andX;
}
/**
* Link to all members of circle
*
* @param IQueryBuilder $qb
*/
protected function joinCircleMembers(IQueryBuilder $qb) {
$expr = $qb->expr();
$qb->addSelect('m.user_id')
->from(DeprecatedRequestBuilder::TABLE_MEMBERS, 'm')
->andWhere(
$expr->andX(
$expr->eq('s.share_with', 'm.circle_id'),
$expr->eq('m.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER))
)
);
}
/**
* Link to storage/filecache
*
* @param IQueryBuilder $qb
* @param string $userId
*/
protected function linkToFileCache(IQueryBuilder $qb, $userId) {
$expr = $qb->expr();
$qb->leftJoin('s', 'filecache', 'f', $expr->eq('s.file_source', 'f.fileid'))
->leftJoin('f', 'storages', 'st', $expr->eq('f.storage', 'st.numeric_id'))
->leftJoin(
's', 'share', 's2', $expr->andX(
$expr->eq('s.id', 's2.parent'),
$expr->eq('s2.share_with', $qb->createNamedParameter($userId))
)
);
$qb->selectAlias('s2.id', 'parent_id');
$qb->selectAlias('s2.file_target', 'parent_target');
$qb->selectAlias('s2.permissions', 'parent_perms');
}
/**
* add share to the database and return the ID
*
* @param IShare $share
*
* @return IQueryBuilder
* @throws NotFoundException
*/
protected function getBaseInsertSql($share) {
$qb = $this->dbConnection->getQueryBuilder();
$hasher = OC::$server->getHasher();
$password = ($share->getPassword() !== null) ? $hasher->hash($share->getPassword()) : '';
$qb->insert('share')
->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE))
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->setValue('password', $qb->createNamedParameter($password))
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
->setValue('token', $qb->createNamedParameter($share->getToken()))
->setValue('stime', (string)$qb->createFunction('UNIX_TIMESTAMP()'));
return $qb;
}
/**
* generate and return a base sql request.
*
* @param int $shareId
*
* @return IQueryBuilder
*/
protected function getBaseSelectSql($shareId = -1) {
$qb = $this->dbConnection->getQueryBuilder();
$qb->select(
's.id', 's.share_type', 's.share_with', 's.uid_owner', 's.uid_initiator',
's.parent', 's.item_type', 's.item_source', 's.item_target', 's.permissions', 's.stime',
's.accepted', 's.expiration', 's.token', 's.mail_send', 'c.type AS circle_type',
'c.name AS circle_name', 'c.alt_name AS circle_alt_name'
);
$this->linkToCircleOwner($qb);
$this->joinShare($qb);
// TODO: Left-join circle and REMOVE this line
$this->linkCircleField($qb, $shareId);
return $qb;
}
/**
* Generate and return a base sql request
* This one should be used to retrieve a complete list of users (ie. access list).
*
* @return IQueryBuilder
*/
protected function getAccessListBaseSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
$this->joinCircleMembers($qb);
$this->joinShare($qb);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getCompleteSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->selectDistinct('s.id')
->addSelect(
's.*', 'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage',
'f.path_hash', 'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart',
'f.size', 'f.mtime', 'f.storage_mtime', 'f.encrypted', 'f.unencrypted_size',
'f.etag', 'f.checksum', 'c.type AS circle_type', 'c.name AS circle_name',
'c.alt_name AS circle_alt_name'
)
->selectAlias('st.id', 'storage_string_id');
$this->linkToCircleOwner($qb);
$this->joinShare($qb);
$this->linkCircleField($qb);
return $qb;
}
/**
* @param IQueryBuilder $qb
*/
private function joinShare(IQueryBuilder $qb) {
$expr = $qb->expr();
$qb->addSelect('s.file_source', 's.file_target');
$qb->from('share', 's')
->andWhere($expr->eq('s.share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)))
->andWhere(
$expr->orX(
$expr->eq('s.item_type', $qb->createNamedParameter('file')),
$expr->eq('s.item_type', $qb->createNamedParameter('folder'))
)
);
}
/**
* generate and return a base sql request.
*
* @return IQueryBuilder
*/
protected function getBaseDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$expr = $qb->expr();
$qb->delete('share')
->where($expr->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)));
return $qb;
}
/**
* generate and return a base sql request.
*
* @return IQueryBuilder
*/
protected function getBaseUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$expr = $qb->expr();
$qb->update('share')
->where($expr->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)));
return $qb;
}
}
@@ -0,0 +1,521 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCA\Circles\Exceptions\FederatedUserNotFoundException;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Exceptions\OwnerNotFoundException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\SingleCircleNotFoundException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\Probes\DataProbe;
/**
* Class CircleRequest
*
* @package OCA\Circles\Db
*/
class CircleRequest extends CircleRequestBuilder {
/**
* @param Circle $circle
*
* @throws InvalidIdException
*/
public function save(Circle $circle): void {
$this->confirmValidId($circle->getSingleId());
$qb = $this->getCircleInsertSql();
$qb->setValue('unique_id', $qb->createNamedParameter($circle->getSingleId()))
->setValue('name', $qb->createNamedParameter($circle->getName()))
->setValue('source', $qb->createNamedParameter($circle->getSource()))
->setValue('display_name', $qb->createNamedParameter($circle->getDisplayName()))
->setValue('sanitized_name', $qb->createNamedParameter($circle->getSanitizedName()))
->setValue('description', $qb->createNamedParameter($circle->getDescription()))
->setValue('contact_addressbook', $qb->createNamedParameter($circle->getContactAddressBook()))
->setValue('contact_groupname', $qb->createNamedParameter($circle->getContactGroupName()))
->setValue('settings', $qb->createNamedParameter(json_encode($circle->getSettings())))
->setValue('config', $qb->createNamedParameter($circle->getConfig()));
$qb->execute();
}
/**
* @param Circle $circle
*/
public function edit(Circle $circle): void {
$qb = $this->getCircleUpdateSql();
$qb->set('name', $qb->createNamedParameter($circle->getName()))
->set('display_name', $qb->createNamedParameter($circle->getDisplayName()))
->set('sanitized_name', $qb->createNamedParameter($circle->getSanitizedName()))
->set('description', $qb->createNamedParameter($circle->getDescription()));
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param Circle $circle
*/
public function update(Circle $circle) {
$qb = $this->getCircleUpdateSql();
$qb->set('name', $qb->createNamedParameter($circle->getName()))
->set('display_name', $qb->createNamedParameter($circle->getDisplayName()))
->set('description', $qb->createNamedParameter($circle->getDescription()))
->set('settings', $qb->createNamedParameter(json_encode($circle->getSettings())))
->set('config', $qb->createNamedParameter($circle->getConfig()));
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param Circle $circle
*
* @throws InvalidIdException
*/
public function insertOrUpdate(Circle $circle): void {
try {
$this->getCircle($circle->getSingleId());
$this->update($circle);
} catch (CircleNotFoundException $e) {
$this->save($circle);
}
}
/**
* @param string $singleId
* @param string $displayName
*/
public function updateDisplayName(string $singleId, string $displayName): void {
$qb = $this->getCircleUpdateSql();
$qb->set('display_name', $qb->createNamedParameter($displayName));
$qb->limitToUniqueId($singleId);
$qb->execute();
}
/**
* @param Circle $circle
*/
public function updateConfig(Circle $circle) {
$qb = $this->getCircleUpdateSql();
$qb->set('config', $qb->createNamedParameter($circle->getConfig()));
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param Circle $circle
*/
public function updateSettings(Circle $circle) {
$qb = $this->getCircleUpdateSql();
$qb->set('settings', $qb->createNamedParameter(json_encode($circle->getSettings())));
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param IFederatedUser|null $initiator
* @param CircleProbe $probe
*
* @return Circle[]
* @throws RequestBuilderException
*/
public function getCircles(?IFederatedUser $initiator, CircleProbe $probe): array {
$qb = $this->getCircleSelectSql();
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
array_merge(
$probe->getAsOptions(),
[
'getData' => true,
'initiatorDirectMember' => true
]
)
);
$qb->filterCircles(CoreQueryBuilder::CIRCLE, $probe);
if (!is_null($initiator)) {
$qb->limitToInitiator(CoreQueryBuilder::CIRCLE, $initiator);
$qb->orderBy($qb->generateAlias(CoreQueryBuilder::CIRCLE, CoreQueryBuilder::INITIATOR) . '.level', 'desc');
$qb->addOrderBy(CoreQueryBuilder::CIRCLE . '.display_name', 'asc');
}
if ($probe->hasFilterMember()) {
$qb->limitToDirectMembership(CoreQueryBuilder::CIRCLE, $probe->getFilterMember());
}
if ($probe->hasFilterCircle()) {
$qb->filterCircleDetails($probe->getFilterCircle());
}
if ($probe->hasFilterRemoteInstance()) {
$qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $probe->getFilterRemoteInstance(), false);
}
$qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
/**
* get data about single Circle.
*
* - CircleProbe is used to confirm the visibility of the targeted circle,
* - DataProbe is used to define the complexity of the data to be returned for each entry of the list
*
* @param string $singleId
* @param IFederatedUser|null $initiator
* @param CircleProbe $circleProbe
* @param DataProbe $dataProbe
*
* @return Circle
* @throws CircleNotFoundException
* @throws RequestBuilderException
*/
public function probeCircle(
string $singleId,
?IFederatedUser $initiator,
CircleProbe $circleProbe,
DataProbe $dataProbe
): Circle {
$qb = $this->buildProbeCircle($initiator, $circleProbe, $dataProbe);
$qb->limit('unique_id', $singleId);
return $this->getItemFromRequest($qb);
}
/**
* get data about multiple Circles.
*
* - CircleProbe is used to define the list of circles to be returned by the method,
* - DataProbe is used to define the complexity of the data to be returned for each entry of the list
*
* @param IFederatedUser|null $initiator
* @param CircleProbe $circleProbe
* @param DataProbe $dataProbe
*
* @return Circle[]
* @throws RequestBuilderException
*/
public function probeCircles(
?IFederatedUser $initiator,
CircleProbe $circleProbe,
DataProbe $dataProbe
): array {
$qb = $this->buildProbeCircle($initiator, $circleProbe, $dataProbe);
$qb->chunk($circleProbe->getItemsOffset(), $circleProbe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
/**
* @param IFederatedUser|null $initiator
* @param CircleProbe $circleProbe
* @param DataProbe $dataProbe
*
* @return CoreQueryBuilder
* @throws RequestBuilderException
*/
private function buildProbeCircle(
?IFederatedUser $initiator,
CircleProbe $circleProbe,
DataProbe $dataProbe
): CoreQueryBuilder {
$qb = $this->getCircleSelectSql();
if (!$dataProbe->has(DataProbe::MEMBERSHIPS)) {
$dataProbe->add(DataProbe::MEMBERSHIPS);
}
$qb->setSqlPath(CoreQueryBuilder::CIRCLE, $dataProbe->getPath())
->setOptions([CoreQueryBuilder::CIRCLE], $circleProbe->getAsOptions())
->filterCircles(CoreQueryBuilder::CIRCLE, $circleProbe);
if ($circleProbe->hasFilterCircle()) {
$qb->filterCircleDetails($circleProbe->getFilterCircle());
}
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
$qb->innerJoinMembership($circleProbe, CoreQueryBuilder::CIRCLE);
$aliasMembership = $qb->generateAlias(CoreQueryBuilder::CIRCLE, CoreQueryBuilder::MEMBERSHIPS);
$limit = $qb->expr()->orX();
if (is_null($initiator)) {
// to get unique result, enforce a limit on level=owner
$limit->add($qb->exprLimitInt('level', Member::LEVEL_OWNER, $aliasMembership));
} else {
$limit->add(
$qb->exprLimit(
'single_id',
$initiator->getSingleId(),
$aliasMembership
)
);
$qb->completeProbeWithInitiator(CoreQueryBuilder::CIRCLE, 'single_id', $aliasMembership);
}
$qb->andWhere($limit);
$qb->resetSqlPath();
return $qb;
}
/**
* @param array $circleIds
*
* @return array
* @throws RequestBuilderException
*/
public function getCirclesByIds(array $circleIds): array {
$qb = $this->getCircleSelectSql();
$qb->setOptions(
[CoreQueryBuilder::CIRCLE], ['getData' => true, 'minimumLevel' => Member::LEVEL_NONE]
);
$qb->limitInArray('unique_id', $circleIds);
// $qb->filterCircles(CoreQueryBuilder::CIRCLE, $filter);
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
return $this->getItemsFromRequest($qb);
}
/**
* @param string $id
* @param IFederatedUser|null $initiator
* @param CircleProbe|null $probe
*
* @return Circle
* @throws CircleNotFoundException
* @throws RequestBuilderException
*/
public function getCircle(
string $id,
?IFederatedUser $initiator = null,
?CircleProbe $probe = null
): Circle {
if (is_null($probe)) {
$probe = new CircleProbe();
$probe->includeSystemCircles()
->emulateVisitor();
}
$qb = $this->getCircleSelectSql(CoreQueryBuilder::CIRCLE, true);
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
array_merge(
$probe->getAsOptions(),
[
'getData' => true,
'initiatorDirectMember' => true
]
)
);
$qb->limitToUniqueId($id);
$qb->filterCircles(CoreQueryBuilder::CIRCLE, $probe);
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
// $qb->setOptions(
// [CoreRequestBuilder::CIRCLE, CoreRequestBuilder::INITIATOR], [
// 'mustBeMember' => false,
// 'viewableAsVisitor' => true
// ]
// );
if (!is_null($initiator)) {
$qb->limitToInitiator(CoreQueryBuilder::CIRCLE, $initiator);
}
if ($probe->hasFilterRemoteInstance()) {
$qb->limitToRemoteInstance(CoreQueryBuilder::CIRCLE, $probe->getFilterRemoteInstance(), false);
}
return $this->getItemFromRequest($qb);
}
/**
* @param string $singleId
*
* @return FederatedUser
* @throws OwnerNotFoundException
* @throws RequestBuilderException
* @throws FederatedUserNotFoundException
*/
public function getFederatedUserBySingleId(string $singleId): FederatedUser {
$qb = $this->getCircleSelectSql(CoreQueryBuilder::CIRCLE, true);
$qb->limitToUniqueId($singleId);
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
try {
$circle = $this->getItemFromRequest($qb);
} catch (CircleNotFoundException $e) {
throw new FederatedUserNotFoundException('singleId not found');
}
$federatedUser = new FederatedUser();
$federatedUser->importFromCircle($circle);
return $federatedUser;
}
/**
* method that return the single-user Circle based on a FederatedUser.
*
* @param IFederatedUser $initiator
*
* @return Circle
* @throws SingleCircleNotFoundException
* @throws RequestBuilderException
*/
public function getSingleCircle(IFederatedUser $initiator): Circle {
$qb = $this->getCircleSelectSql(CoreQueryBuilder::SINGLE, true);
if ($initiator instanceof FederatedUser) {
$member = new Member();
$member->importFromIFederatedUser($initiator);
$member->setLevel(Member::LEVEL_OWNER);
} else {
$member = clone $initiator;
}
$qb->limitToDirectMembership(CoreQueryBuilder::SINGLE, $member);
$qb->limitToConfigFlag(Circle::CFG_SINGLE);
try {
return $this->getItemFromRequest($qb);
} catch (CircleNotFoundException $e) {
throw new SingleCircleNotFoundException();
}
}
/**
* @param Circle $circle
* @param IFederatedUser|null $initiator
*
* @return Circle
* @throws CircleNotFoundException
* @throws RequestBuilderException
*/
public function searchCircle(Circle $circle, ?IFederatedUser $initiator = null): Circle {
$qb = $this->getCircleSelectSql();
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
if ($circle->getName() !== '') {
$qb->limitToName($circle->getName());
}
if ($circle->getDisplayName() !== '') {
$qb->limitToDisplayName($circle->getDisplayName());
}
if ($circle->getSanitizedName() !== '') {
$qb->limitToSanitizedName($circle->getSanitizedName());
}
if ($circle->getConfig() > 0) {
$qb->limitToConfig($circle->getConfig());
}
if ($circle->getSource() > 0) {
$qb->limitToSource($circle->getSource());
}
if ($circle->hasOwner()) {
$aliasOwner = $qb->generateAlias(CoreQueryBuilder::CIRCLE, CoreQueryBuilder::OWNER);
$qb->filterDirectMembership($aliasOwner, $circle->getOwner());
}
if (!is_null($initiator)) {
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
[
'getData' => true,
'initiatorDirectMember' => true
]
);
$qb->limitToInitiator(CoreQueryBuilder::CIRCLE, $initiator);
}
return $this->getItemFromRequest($qb);
}
/**
* @return Circle[]
* @throws RequestBuilderException
*/
public function getFederated(): array {
$qb = $this->getCircleSelectSql();
$qb->limitToConfigFlag(Circle::CFG_FEDERATED, CoreQueryBuilder::CIRCLE);
$qb->leftJoinOwner(CoreQueryBuilder::CIRCLE);
return $this->getItemsFromRequest($qb);
}
/**
* @param Circle $circle
*/
public function delete(Circle $circle): void {
$qb = $this->getCircleDeleteSql();
$qb->limitToUniqueId($circle->getSingleId());
$qb->execute();
}
/**
* @param IFederatedUser $federatedUser
*/
public function deleteFederatedUser(IFederatedUser $federatedUser): void {
$qb = $this->getCircleDeleteSql();
$qb->limitToUniqueId($federatedUser->getSingleId());
$qb->execute();
}
}
@@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\CircleNotFoundException;
use OCA\Circles\Model\Circle;
/**
* Class CircleRequestBuilder
*
* @package OCA\Circles\Db
*/
class CircleRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getCircleInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_CIRCLE)
->setValue('creation', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getCircleUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_CIRCLE);
return $qb;
}
/**
* @param string $alias
* @param bool $single
*
* @return CoreQueryBuilder
*/
protected function getCircleSelectSql(
string $alias = CoreQueryBuilder::CIRCLE,
bool $single = false
): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(self::TABLE_CIRCLE, self::$tables[self::TABLE_CIRCLE], $alias);
if (!$single) {
$qb->orderBy($alias . '.creation', 'asc');
}
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getCircleDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_CIRCLE);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Circle
* @throws CircleNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): Circle {
/** @var Circle $circle */
try {
$circle = $qb->asItem(Circle::class);
} catch (RowNotFoundException $e) {
throw new CircleNotFoundException('Circle not found');
} catch (\Exception $e) {
throw new \Exception($qb->getSQL());
}
return $circle;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Circle[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var Circle[] $result */
return $qb->asItems(Circle::class);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,320 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use Exception;
use OC\DB\Connection;
use OC\DB\SchemaWrapper;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\TimezoneService;
use OCP\Share\IShare;
/**
* Class CoreQueryBuilder
*
* @package OCA\Circles\Db
*/
class CoreRequestBuilder {
public const TABLE_SHARE = 'share';
public const TABLE_FILE_CACHE = 'filecache';
public const TABLE_STORAGES = 'storages';
public const TABLE_CIRCLE = 'circles_circle';
public const TABLE_MEMBER = 'circles_member';
public const TABLE_MEMBERSHIP = 'circles_membership';
public const TABLE_REMOTE = 'circles_remote';
public const TABLE_EVENT = 'circles_event';
public const TABLE_MOUNT = 'circles_mount';
public const TABLE_MOUNTPOINT = 'circles_mountpoint';
// wip
public const TABLE_SHARE_LOCK = 'circles_share_lock';
public const TABLE_TOKEN = 'circles_token';
public const TABLE_GSSHARES = 'circle_gsshares'; // rename ?
public const TABLE_GSSHARES_MOUNTPOINT = 'circle_gsshares_mp'; // rename ?
public const NC_TABLE_ACCOUNTS = 'accounts';
public const NC_TABLE_GROUP_USER = 'group_user';
/** @var array */
public static $tables = [
self::TABLE_CIRCLE => [
'unique_id',
'name',
'display_name',
'sanitized_name',
'source',
'description',
'settings',
'config',
'contact_addressbook',
'contact_groupname',
'creation'
],
self::TABLE_MEMBER => [
'circle_id',
'member_id',
'single_id',
'user_id',
'instance',
'user_type',
'level',
'status',
'note',
'contact_id',
'cached_name',
'cached_update',
'contact_meta',
'joined'
],
self::TABLE_MEMBERSHIP => [
'single_id',
'circle_id',
'level',
'inheritance_first',
'inheritance_last',
'inheritance_path',
'inheritance_depth'
],
self::TABLE_REMOTE => [
'id',
'type',
'interface',
'uid',
'instance',
'href',
'item',
'creation'
],
self::TABLE_EVENT => [
'token',
'event',
'result',
'instance',
'interface',
'severity',
'retry',
'status',
'creation'
],
self::TABLE_MOUNT => [
'id',
'mount_id',
'circle_id',
'single_id',
'token',
'parent',
'mountpoint',
'mountpoint_hash'
],
self::TABLE_MOUNTPOINT => [],
self::TABLE_SHARE_LOCK => [],
self::TABLE_TOKEN => [
'id',
'share_id',
'circle_id',
'single_id',
'member_id',
'token',
'password',
'accepted'
],
self::TABLE_GSSHARES => [],
self::TABLE_GSSHARES_MOUNTPOINT => []
];
public static $outsideTables = [
self::TABLE_SHARE => [
'id',
'share_type',
'share_with',
'uid_owner',
'uid_initiator',
'parent',
'item_type',
'item_source',
'item_target',
'file_source',
'file_target',
'permissions',
'attributes',
'stime',
'accepted',
'expiration',
'token',
'mail_send'
],
self::TABLE_FILE_CACHE => [
'fileid',
'path',
'permissions',
'storage',
'path_hash',
'parent',
'name',
'mimetype',
'mimepart',
'size',
'mtime',
'storage_mtime',
'encrypted',
'unencrypted_size',
'etag',
'checksum'
],
self::TABLE_STORAGES => [
'id'
]
];
/** @var TimezoneService */
protected $timezoneService;
/** @var ConfigService */
protected $configService;
/**
* CoreQueryBuilder constructor.
*
* @param TimezoneService $timezoneService
* @param ConfigService $configService
*/
public function __construct(TimezoneService $timezoneService, ConfigService $configService) {
$this->timezoneService = $timezoneService;
$this->configService = $configService;
}
/**
* @return CoreQueryBuilder
*/
public function getQueryBuilder(): CoreQueryBuilder {
return new CoreQueryBuilder();
}
/**
* @param array $ids
*
* @throws InvalidIdException
*/
public function confirmValidIds(array $ids): void {
foreach ($ids as $id) {
$this->confirmValidId($id);
}
}
/**
* @param string $id
*
* @throws InvalidIdException
*/
public function confirmValidId(string $id): void {
if (strlen($id) < 14) {
throw new InvalidIdException();
}
}
/**
* @param bool $shares
*/
public function cleanDatabase(bool $shares = false): void {
foreach (array_keys(self::$tables) as $table) {
$qb = $this->getQueryBuilder();
try {
$qb->delete($table);
$qb->execute();
} catch (Exception $e) {
}
}
if ($shares) {
$qb = $this->getQueryBuilder();
$expr = $qb->expr();
$qb->delete(self::TABLE_SHARE);
$qb->where($expr->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE)));
$qb->execute();
}
}
public function uninstall(): void {
$this->uninstallAppTables();
$this->uninstallFromMigrations();
$this->uninstallFromJobs();
$this->configService->unsetAppConfig();
}
/**
* this just empty all tables from the app.
*/
public function uninstallAppTables() {
$dbConn = \OC::$server->get(Connection::class);
$schema = new SchemaWrapper($dbConn);
foreach (array_keys(self::$tables) as $table) {
if ($schema->hasTable($table)) {
$schema->dropTable($table);
}
}
$schema->performDropTableCalls();
}
/**
*
*/
public function uninstallFromMigrations() {
$qb = $this->getQueryBuilder();
$qb->delete('migrations');
$qb->limit('app', 'circles');
$qb->unlike('version', '001%');
$qb->execute();
}
/**
*
*/
public function uninstallFromJobs() {
$qb = $this->getQueryBuilder();
// $qb->delete('jobs');
// $qb->where($this->exprLimitToDBField($qb, 'class', 'OCA\Circles\', true, true));
// $qb->execute();
}
}
@@ -0,0 +1,410 @@
<?php
declare(strict_types=1);
/**
* 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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\CircleDoesNotExistException;
use OCA\Circles\Exceptions\ConfigNoCircleAvailableException;
use OCA\Circles\Exceptions\GSStatusException;
use OCA\Circles\Model\DeprecatedCircle;
use OCA\Circles\Model\DeprecatedMember;
class DeprecatedCirclesRequest extends DeprecatedCirclesRequestBuilder {
/**
* forceGetCircle();
*
* returns data of a circle from its Id.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use getCircle() instead.
*
* @param string $circleUniqueId
* @param bool $allSettings
*
* @return DeprecatedCircle
* @throws CircleDoesNotExistException
*/
public function forceGetCircle($circleUniqueId, bool $allSettings = false) {
$qb = $this->getCirclesSelectSql();
$this->leftJoinOwner($qb, '');
$this->limitToUniqueId($qb, $circleUniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
}
return $this->parseCirclesSelectSql($data, $allSettings);
}
/**
* forceGetCircles();
*
* returns data of a all circles.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use getCircles() instead.
*
* @param string $ownerId
*
* @return DeprecatedCircle[]
*/
public function forceGetCircles(string $ownerId = '') {
$qb = $this->getCirclesSelectSql();
$this->leftJoinOwner($qb, $ownerId);
$circles = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$circles[] = $this->parseCirclesSelectSql($data, true);
}
$cursor->closeCursor();
return $circles;
}
/**
* forceGetCircleByName();
*
* returns data of a circle from its Name.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, do not use this method.
*
* @param $name
*
* @return null|DeprecatedCircle
* @throws CircleDoesNotExistException
*/
public function forceGetCircleByName($name) {
$qb = $this->getCirclesSelectSql();
$this->limitToName($qb, $name);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
}
return $this->parseCirclesSelectSql($data);
}
/**
* @param string $userId
* @param int $circleType
* @param string $name
* @param int $level
* @param bool $forceAll
* @param string $ownerId
*
* @return DeprecatedCircle[]
* @throws ConfigNoCircleAvailableException
* @throws GSStatusException
*/
public function getCircles(
string $userId, int $circleType = 0, string $name = '', int $level = 0, bool $forceAll = false,
string $ownerId = ''
) {
if ($circleType === 0) {
$circleType = DeprecatedCircle::CIRCLES_ALL;
}
// todo - make it works based on $type
$typeViewer = DeprecatedMember::TYPE_USER;
$qb = $this->getCirclesSelectSql();
$this->leftJoinUserIdAsViewer($qb, $userId, $typeViewer, '');
$this->leftJoinOwner($qb, $ownerId);
$this->leftJoinNCGroupAndUser($qb, $userId, 'c.unique_id');
if ($level > 0) {
$this->limitToLevel($qb, $level, ['u', 'g']);
}
$this->limitRegardingCircleType($qb, $userId, -1, $circleType, $name, $forceAll);
$circles = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
if ($name === '' || stripos(strtolower($data['name']), strtolower($name)) !== false
|| stripos(strtolower($data['alt_name']), strtolower($name)) !== false) {
$circles[] = $this->parseCirclesSelectSql($data);
}
}
$cursor->closeCursor();
return $circles;
}
/**
*
* @param string $circleUniqueId
* @param string $viewerId
* @param int $type
* @param string $instanceId
* @param bool $forceAll
*
* @return DeprecatedCircle
* @throws CircleDoesNotExistException
* @throws ConfigNoCircleAvailableException
*/
public function getCircle(
string $circleUniqueId, string $viewerId, int $type = DeprecatedMember::TYPE_USER,
string $instanceId = '',
bool $forceAll = false
) {
$qb = $this->getCirclesSelectSql();
$this->limitToUniqueId($qb, $circleUniqueId);
$this->leftJoinUserIdAsViewer($qb, $viewerId, $type, $instanceId);
$this->leftJoinOwner($qb);
if ($instanceId === '') {
$this->leftJoinNCGroupAndUser($qb, $viewerId, 'c.unique_id');
}
$this->limitRegardingCircleType(
$qb, $viewerId, $circleUniqueId, DeprecatedCircle::CIRCLES_ALL, '', $forceAll
);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new CircleDoesNotExistException($this->l10n->t('Circle not found ' . $circleUniqueId));
}
$circle = $this->parseCirclesSelectSql($data);
if ($instanceId === '') {
$circle->setGroupViewer(
$this->membersRequest->forceGetHigherLevelGroupFromUser($circleUniqueId, $viewerId)
);
}
return $circle;
}
/**
* createCircle();
*
* Create a circle with $userId as its owner.
* Will returns the circle
*
* @param DeprecatedCircle $circle
*/
public function createCircle(DeprecatedCircle $circle) {
$config = DeprecatedCircle::convertTypeToConfig($circle->getType());
$qb = $this->getCirclesInsertSql();
$qb->setValue('unique_id', $qb->createNamedParameter($circle->getUniqueId()))
->setValue('long_id', $qb->createNamedParameter($circle->getUniqueId(true)))
->setValue('name', $qb->createNamedParameter($circle->getName(true)))
->setValue('alt_name', $qb->createNamedParameter($circle->getAltName()))
->setValue('description', $qb->createNamedParameter($circle->getDescription()))
->setValue('contact_addressbook', $qb->createNamedParameter($circle->getContactAddressBook()))
->setValue('contact_groupname', $qb->createNamedParameter($circle->getContactGroupName()))
->setValue('settings', $qb->createNamedParameter($circle->getSettings(true)))
->setValue('type', $qb->createNamedParameter($circle->getType()))
->setValue('config', $qb->createNamedParameter($config));
$qb->execute();
}
/**
* remove a circle
*
* @param string $circleUniqueId
*/
public function destroyCircle($circleUniqueId) {
}
/**
* returns if the circle is already in database
*
* @param DeprecatedCircle $circle
* @param string $userId
*
* @return bool
* @throws ConfigNoCircleAvailableException
*/
public function isCircleUnique(DeprecatedCircle $circle, $userId = '') {
if ($circle->getType() === DeprecatedCircle::CIRCLES_PERSONAL) {
return $this->isPersonalCircleUnique($circle, $userId);
}
$qb = $this->getCirclesSelectSql();
$this->limitToNonPersonalCircle($qb);
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
if (strtolower($data['name']) === strtolower($circle->getName())
&& $circle->getUniqueId(true) !== $data['unique_id']) {
return false;
}
}
$cursor->closeCursor();
return true;
}
/**
* return if the personal circle is unique
*
* @param DeprecatedCircle $circle
* @param string $userId
*
* @return bool
* @throws ConfigNoCircleAvailableException
*/
private function isPersonalCircleUnique(DeprecatedCircle $circle, $userId = '') {
if ($userId === '') {
return true;
}
$list = $this->getCircles(
$userId, DeprecatedCircle::CIRCLES_PERSONAL, $circle->getName(),
DeprecatedMember::LEVEL_OWNER
);
foreach ($list as $test) {
if (strtolower($test->getName()) === strtolower($circle->getName())
&& $circle->getUniqueId(true) !== $test->getUniqueId(true)) {
return false;
}
}
return true;
}
/**
* @param string $uniqueId
*
* @return DeprecatedCircle
* @throws CircleDoesNotExistException
*/
public function getCircleFromUniqueId($uniqueId) {
$qb = $this->getCirclesSelectSql();
$this->limitToUniqueId($qb, (string)$uniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
}
return $this->parseCirclesSelectSql($data);
}
/**
* @param int $addressBookId
*
* @return array
*/
public function getFromBook(int $addressBookId) {
$qb = $this->getCirclesSelectSql();
$this->limitToAddressBookId($qb, $addressBookId);
$circles = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$circles[] = $this->parseCirclesSelectSql($data);
}
$cursor->closeCursor();
return $circles;
}
/**
* @param int $addressBookId
*
* @return DeprecatedCircle[]
*/
public function getFromContactBook(int $addressBookId): array {
$qb = $this->getCirclesSelectSql();
if ($addressBookId > 0) {
$this->limitToAddressBookId($qb, $addressBookId);
}
$circles = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$circles[] = $this->parseCirclesSelectSql($data);
}
$cursor->closeCursor();
return $circles;
}
/**
* @param int $addressBookId
* @param string $group
*
* @return DeprecatedCircle
* @throws CircleDoesNotExistException
*/
public function getFromContactGroup(int $addressBookId, string $group): DeprecatedCircle {
$qb = $this->getCirclesSelectSql();
$this->limitToAddressBookId($qb, $addressBookId);
$this->limitToContactGroup($qb, $group);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
}
return $this->parseCirclesSelectSql($data);
}
}
@@ -0,0 +1,270 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use Doctrine\DBAL\Query\QueryBuilder;
use OCA\Circles\Exceptions\ConfigNoCircleAvailableException;
use OCA\Circles\Model\DeprecatedCircle;
use OCA\Circles\Model\DeprecatedMember;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\MiscService;
use OCA\Circles\Service\TimezoneService;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IL10N;
class DeprecatedCirclesRequestBuilder extends DeprecatedRequestBuilder {
/** @var DeprecatedMembersRequest */
protected $membersRequest;
/**
* CirclesRequestBuilder constructor.
*
* {@inheritdoc}
* @param DeprecatedMembersRequest $membersRequest
*/
public function __construct(
IL10N $l10n, IDBConnection $connection, DeprecatedMembersRequest $membersRequest,
ConfigService $configService, TimezoneService $timezoneService, MiscService $miscService
) {
parent::__construct($l10n, $connection, $configService, $timezoneService, $miscService);
$this->membersRequest = $membersRequest;
}
/**
* Limit the search to a non-personal circle
*
* @param IQueryBuilder $qb
*/
protected function limitToNonPersonalCircle(IQueryBuilder $qb) {
$expr = $qb->expr();
$qb->andWhere(
$expr->neq('c.type', $qb->createNamedParameter(DeprecatedCircle::CIRCLES_PERSONAL))
);
}
/**
* @param IQueryBuilder $qb
* @param string $userId
* @param string $circleUniqueId
* @param $type
* @param $name
* @param bool $forceAll
*
* @deprecated
* @throws ConfigNoCircleAvailableException
*/
protected function limitRegardingCircleType(
IQueryBuilder $qb, string $userId, $circleUniqueId, int $type,
string $name, bool $forceAll = false
) {
}
/**
* @param IQueryBuilder $qb
* @param string $circleUniqueId
* @param $userId
* @param $type
* @param $name
* @param bool $forceAll
*
* @return array
*/
private function generateLimit(
IQueryBuilder $qb, $circleUniqueId, $userId, $type, $name, $forceAll = false
) {
return [];
}
/**
* add a request to the members list, using the current user ID.
* will returns level and stuff.
*
* @param IQueryBuilder $qb
* @param string $userId
* @param int $type
* @param string $instanceId
*/
public function leftJoinUserIdAsViewer(IQueryBuilder $qb, string $userId, int $type, string $instanceId
) {
if ($qb->getType() !== QueryBuilder::SELECT) {
return;
}
$expr = $qb->expr();
$pf = '' . $this->default_select_alias . '.';
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->selectAlias('u.user_id', 'viewer_userid')
->selectAlias('u.user_type', 'viewer_type')
->selectAlias('u.instance', 'viewer_instance')
->selectAlias('u.status', 'viewer_status')
->selectAlias('u.member_id', 'viewer_member_id')
->selectAlias('u.cached_name', 'viewer_cached_name')
->selectAlias('u.cached_update', 'viewer_cached_update')
->selectAlias('u.level', 'viewer_level')
->leftJoin(
$this->default_select_alias, DeprecatedRequestBuilder::TABLE_MEMBERS, 'u',
$expr->andX(
$expr->eq('u.circle_id', $pf . 'unique_id'),
$expr->eq('u.user_id', $qb->createNamedParameter($userId)),
$expr->eq('u.instance', $qb->createNamedParameter($instanceId)),
$expr->eq('u.user_type', $qb->createNamedParameter($type))
)
);
}
/**
* Left Join members table to get the owner of the circle.
*
* @param IQueryBuilder $qb
* @param string $ownerId
*/
public function leftJoinOwner(IQueryBuilder $qb, string $ownerId = '') {
if ($qb->getType() !== QueryBuilder::SELECT) {
return;
}
$expr = $qb->expr();
$pf = $this->default_select_alias . '.';
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->selectAlias('o.user_id', 'owner_userid')
->selectAlias('o.member_id', 'owner_member_id')
->selectAlias('o.instance', 'owner_instance')
->selectAlias('o.cached_name', 'owner_cached_name')
->selectAlias('o.cached_update', 'owner_cached_update')
->selectAlias('o.status', 'owner_status')
->selectAlias('o.level', 'owner_level')
->leftJoin(
$this->default_select_alias, DeprecatedRequestBuilder::TABLE_MEMBERS, 'o',
$expr->andX(
$expr->eq('o.circle_id', $pf . 'unique_id'),
$expr->eq('o.level', $qb->createNamedParameter(DeprecatedMember::LEVEL_OWNER)),
$expr->eq('o.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER))
)
);
if ($ownerId !== '') {
$qb->andWhere($expr->eq('o.user_id', $qb->createNamedParameter($ownerId)));
}
}
/**
* Base of the Sql Insert request for Shares
*
*
* @return IQueryBuilder
*/
protected function getCirclesInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_CIRCLES)
->setValue('creation', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getCirclesSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->selectDistinct('c.unique_id')
->addSelect(
'c.id', 'c.name', 'c.alt_name', 'c.description', 'c.settings', 'c.type', 'contact_addressbook',
'contact_groupname', 'c.creation'
)
->from(DeprecatedRequestBuilder::TABLE_CIRCLES, 'c');
$this->default_select_alias = 'c';
return $qb;
}
/**
* @param array $data
* @param bool $allSettings
*
* @return DeprecatedCircle
*/
protected function parseCirclesSelectSql($data, bool $allSettings = false) {
$circle = new DeprecatedCircle();
$circle->setId($data['id']);
$circle->setUniqueId($data['unique_id']);
$circle->setName($data['name']);
$circle->setAltName($data['alt_name']);
$circle->setDescription($data['description']);
if ($data['contact_addressbook'] !== null) {
$circle->setContactAddressBook($data['contact_addressbook']);
}
if ($data['contact_groupname'] !== null) {
$circle->setContactGroupName($data['contact_groupname']);
}
$circle->setSettings($data['settings'], $allSettings);
$circle->setType($data['type']);
$circle->setCreation($data['creation']);
if (key_exists('viewer_level', $data)) {
$user = new DeprecatedMember(
$data['viewer_userid'], DeprecatedMember::TYPE_USER, $circle->getUniqueId()
);
$user->setStatus($data['viewer_status']);
$user->setMemberId($data['viewer_member_id']);
$user->setCachedName($data['viewer_cached_name']);
$user->setType($data['viewer_type']);
$user->setInstance($data['viewer_instance']);
$user->setLevel($data['viewer_level']);
$circle->setViewer($user);
}
if (key_exists('owner_level', $data)) {
$owner = new DeprecatedMember(
$data['owner_userid'], DeprecatedMember::TYPE_USER, $circle->getUniqueId()
);
$owner->setCachedName($data['owner_cached_name']);
$owner->setMemberId($data['owner_member_id']);
$owner->setStatus($data['owner_status']);
$owner->setInstance($data['owner_instance']);
$owner->setLevel($data['owner_level']);
$circle->setOwner($owner);
}
return $circle;
}
}
@@ -0,0 +1,781 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Traits\TStringTools;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Exception;
use OCA\Circles\Exceptions\GSStatusException;
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
use OCA\Circles\Exceptions\MemberDoesNotExistException;
use OCA\Circles\Model\DeprecatedMember;
use OCP\IGroup;
class DeprecatedMembersRequest extends DeprecatedMembersRequestBuilder {
use TStringTools;
/**
* Returns information about a member.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use MembersService->getMember() instead.
*
* @param string $circleUniqueId
* @param string $userId
* @param $type
*
* @param string $instance
*
* @return DeprecatedMember
* @throws MemberDoesNotExistException
*/
public function forceGetMember($circleUniqueId, $userId, $type, string $instance = '') {
$qb = $this->getMembersSelectSql();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
$this->limitToUserId($qb, $userId);
$this->limitToUserType($qb, $type);
$this->limitToInstance($qb, $instance);
$this->limitToCircleId($qb, $circleUniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
}
return $this->parseMembersSelectSql($data);
}
/**
* @param string $memberId
*
* @return DeprecatedMember
* @throws MemberDoesNotExistException
*/
public function forceGetMemberById(string $memberId): DeprecatedMember {
$qb = $this->getMembersSelectSql();
$this->limitToMemberId($qb, $memberId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
}
return $this->parseMembersSelectSql($data);
}
/**
* Returns members list of a circle, based on their level.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use getMembers() instead.
*
* @param string $circleUniqueId
* @param int $level
* @param int $type
* @param bool $incGroup
*
* @return DeprecatedMember[]
*/
public function forceGetMembers(
string $circleUniqueId, $level = DeprecatedMember::LEVEL_MEMBER, int $type = 0, $incGroup = false
) {
$qb = $this->getMembersSelectSql();
$this->limitToMembersAndAlmost($qb);
$this->limitToLevel($qb, $level);
if ($type > 0) {
$this->limitToUserType($qb, $type);
}
$this->limitToCircleId($qb, $circleUniqueId);
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$members[] = $this->parseMembersSelectSql($data);
}
$cursor->closeCursor();
try {
// if ($this->configService->isLinkedGroupsAllowed() && $incGroup === true) {
// $this->includeGroupMembers($members, $circleUniqueId, $level);
// }
} catch (GSStatusException $e) {
}
return $members;
}
/**
* Returns all members.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use getMembers() instead.
*
*
* @return DeprecatedMember[]
*/
public function forceGetAllMembers() {
$qb = $this->getMembersSelectSql();
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$members[] = $this->parseMembersSelectSql($data);
}
$cursor->closeCursor();
return $members;
}
/**
* Returns members generated from Contacts that are not 'checked' (as not sent existing shares).
*
*
* @return DeprecatedMember[]
*/
public function forceGetAllRecentContactEdit() {
$qb = $this->getMembersSelectSql();
$this->limitToUserType($qb, DeprecatedMember::TYPE_CONTACT);
$expr = $qb->expr();
$orX = $expr->orX();
$orX->add($expr->isNull('contact_checked'));
$orX->add($expr->neq('contact_checked', $qb->createNamedParameter('1')));
$qb->andWhere($orX);
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$members[] = $this->parseMembersSelectSql($data);
}
$cursor->closeCursor();
return $members;
}
/**
* @param DeprecatedMember $member
* @param bool $check
*/
public function checkMember(DeprecatedMember $member, bool $check) {
$qb = $this->getMembersUpdateSql(
$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
);
$qb->set('contact_checked', $qb->createNamedParameter(($check) ? 1 : 0));
$qb->execute();
}
/**
* @param string $circleUniqueId
* @param DeprecatedMember $viewer
* @param bool $force
*
* @return DeprecatedMember[]
*/
public function getMembers(string $circleUniqueId, ?DeprecatedMember $viewer, bool $force = false) {
try {
if ($force === false) {
$viewer->hasToBeMember();
}
$members = $this->forceGetMembers($circleUniqueId, DeprecatedMember::LEVEL_NONE);
if ($force === false) {
if (!$viewer->isLevel(DeprecatedMember::LEVEL_MODERATOR)) {
array_map(
function (DeprecatedMember $m) {
$m->setNote('');
}, $members
);
}
}
return $members;
} catch (Exception $e) {
return [];
}
}
/**
* forceGetGroup();
*
* returns group information as a member within a Circle.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of interaction with users, Please use getGroup() instead.
*
* @param string $circleUniqueId
* @param string $groupId
* @param string $instance
*
* @return DeprecatedMember
* @throws MemberDoesNotExistException
*/
public function forceGetGroup(string $circleUniqueId, string $groupId, string $instance) {
$qb = $this->getMembersSelectSql();
$this->limitToUserId($qb, $groupId);
$this->limitToUserType($qb, DeprecatedMember::TYPE_GROUP);
$this->limitToInstance($qb, $instance);
$this->limitToCircleId($qb, $circleUniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
}
return $this->parseMembersSelectSql($data);
}
/**
* includeGroupMembers();
*
* This function will get members of a circle throw NCGroups and fill the result an existing
* Members List. In case of duplicate, higher level will be kept.
*
* @param DeprecatedMember[] $members
* @param string $circleUniqueId
* @param int $level
*/
private function includeGroupMembers(array &$members, $circleUniqueId, $level) {
$groupMembers = $this->forceGetGroupMembers($circleUniqueId, $level);
$this->avoidDuplicateMembers($members, $groupMembers);
}
/**
* avoidDuplicateMembers();
*
* Use this function to add members to the list (1st argument), keeping the higher level in case
* of duplicate
*
* @param DeprecatedMember[] $members
* @param DeprecatedMember[] $groupMembers
*/
public function avoidDuplicateMembers(array &$members, array $groupMembers) {
foreach ($groupMembers as $member) {
$index = $this->indexOfMember($members, $member->getUserId());
if ($index === -1) {
array_push($members, $member);
} elseif ($members[$index]->getLevel() < $member->getLevel()) {
$members[$index] = $member;
}
}
}
/**
* returns the index of a specific UserID in a Members List
*
* @param array $members
* @param $userId
*
* @return int
*/
private function indexOfMember(array $members, $userId) {
foreach ($members as $k => $member) {
if ($member->getUserId() === $userId) {
return intval($k);
}
}
return -1;
}
/**
* Check if a fresh member can be generated (by addMember/joinCircle)
*
* @param string $circleUniqueId
* @param string $name
* @param int $type
*
* @param string $instance
*
* @return DeprecatedMember
*/
public function getFreshNewMember($circleUniqueId, string $name, int $type, string $instance) {
try {
$member = $this->forceGetMember($circleUniqueId, $name, $type, $instance);
} catch (MemberDoesNotExistException $e) {
$member = new DeprecatedMember($name, $type, $circleUniqueId);
$member->setInstance($instance);
// $member->setMemberId($this->token(14));
}
// if ($member->alreadyExistOrJoining()) {
// throw new MemberAlreadyExistsException(
// $this->l10n->t('This account is already a member of the circle')
// );
// }
return $member;
}
/**
* Returns members list of all Group Members of a Circle. The Level of the linked group will be
* assigned to each entry
*
* NOTE: Can contains duplicate.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* Do not use in case of direct interaction with users.
*
* @param string $circleUniqueId
* @param int $level
*
* @return DeprecatedMember[]
*/
public function forceGetGroupMembers($circleUniqueId, $level = DeprecatedMember::LEVEL_MEMBER) {
$qb = $this->getMembersSelectSql();
$this->limitToUserType($qb, DeprecatedMember::TYPE_GROUP);
$this->limitToLevel($qb, $level);
$this->limitToCircleId($qb, $circleUniqueId);
$this->limitToNCGroupUser($qb);
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$members[] = $this->parseGroupsSelectSql($data);
}
$cursor->closeCursor();
return $members;
}
/**
* returns all users from a Group as a list of Members.
*
* @param DeprecatedMember $group
*
* @return DeprecatedMember[]
*/
public function getGroupMemberMembers(DeprecatedMember $group) {
/** @var IGroup $grp */
$grp = $this->groupManager->get($group->getUserId());
if ($grp === null) {
return [];
}
$members = [];
$users = $grp->getUsers();
foreach ($users as $user) {
$member = clone $group;
//Member::fromJSON($this->l10n, json_encode($group));
$member->setType(DeprecatedMember::TYPE_USER);
$member->setUserId($user->getUID());
$members[] = $member;
}
return $members;
}
/**
* return the higher level group linked to a circle, that include the userId.
*
* WARNING: This function does not filters data regarding the current user/viewer.
* In case of direct interaction with users, Please don't use this.
*
* @param string $circleUniqueId
* @param string $userId
*
* @return DeprecatedMember
*/
public function forceGetHigherLevelGroupFromUser($circleUniqueId, $userId) {
$qb = $this->getMembersSelectSql();
$this->limitToUserType($qb, DeprecatedMember::TYPE_GROUP);
$this->limitToInstance($qb, '');
$this->limitToCircleId($qb, $circleUniqueId);
$this->limitToNCGroupUser($qb);
$this->limitToNCGroupUser($qb, $userId);
/** @var DeprecatedMember $group */
$group = null;
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$entry = $this->parseGroupsSelectSql($data);
if ($group === null || $entry->getLevel() > $group->getLevel()) {
$group = $entry;
}
}
$cursor->closeCursor();
return $group;
}
/**
* Insert Member into database.
*
* @param DeprecatedMember $member
*
* @throws MemberAlreadyExistsException
*/
public function createMember(DeprecatedMember $member) {
if ($member->getMemberId() === '') {
$member->setMemberId($this->token(14));
}
$instance = $member->getInstance();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
try {
$qb = $this->getMembersInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
->setValue('member_id', $qb->createNamedParameter($member->getMemberId()))
->setValue('user_type', $qb->createNamedParameter($member->getType()))
->setValue('cached_name', $qb->createNamedParameter($member->getCachedName()))
->setValue('cached_update', $qb->createNamedParameter($this->timezoneService->getUTCDate()))
->setValue('instance', $qb->createNamedParameter($instance))
->setValue('level', $qb->createNamedParameter($member->getLevel()))
->setValue('status', $qb->createNamedParameter($member->getStatus()))
->setValue('contact_id', $qb->createNamedParameter($member->getContactId()))
->setValue('note', $qb->createNamedParameter($member->getNote()));
$qb->execute();
} catch (UniqueConstraintViolationException $e) {
throw new MemberAlreadyExistsException(
$this->l10n->t('This account is already a member of the circle')
);
}
}
/**
* @param string $circleUniqueId
* @param DeprecatedMember $viewer
*
* @return DeprecatedMember[]
*/
public function getGroupsFromCircle($circleUniqueId, DeprecatedMember $viewer) {
if ($viewer->getLevel() < DeprecatedMember::LEVEL_MEMBER) {
return [];
}
$qb = $this->getMembersSelectSql();
$this->limitToUserType($qb, DeprecatedMember::TYPE_GROUP);
$this->limitToLevel($qb, DeprecatedMember::LEVEL_MEMBER);
$this->limitToInstance($qb, '');
$this->limitToCircleId($qb, $circleUniqueId);
$cursor = $qb->execute();
$groups = [];
while ($data = $cursor->fetch()) {
if ($viewer->getLevel() < DeprecatedMember::LEVEL_MODERATOR) {
$data['note'] = '';
}
$groups[] = $this->parseGroupsSelectSql($data);
}
$cursor->closeCursor();
return $groups;
}
/**
* update database entry for a specific Member.
*
* @param DeprecatedMember $member
*/
public function updateMemberLevel(DeprecatedMember $member) {
$instance = $member->getInstance();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
$qb = $this->getMembersUpdateSql(
$member->getCircleId(), $member->getUserId(), $instance, $member->getType()
);
$qb->set('level', $qb->createNamedParameter($member->getLevel()))
->set('status', $qb->createNamedParameter($member->getStatus()));
$qb->execute();
}
/**
* update database entry for a specific Member.
*
* @param DeprecatedMember $member
*/
public function updateMemberInfo(DeprecatedMember $member) {
$instance = $member->getInstance();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
$qb = $this->getMembersUpdateSql(
$member->getCircleId(), $member->getUserId(), $instance, $member->getType()
);
$qb->set('note', $qb->createNamedParameter($member->getNote()))
->set('cached_name', $qb->createNamedParameter($member->getCachedName()))
->set('cached_update', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
$qb->execute();
}
/**
* update database entry for a specific Member.
*
* @param DeprecatedMember $member
*/
public function updateContactMeta(DeprecatedMember $member) {
$qb = $this->getMembersUpdateSql(
$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
);
$qb->set('contact_meta', $qb->createNamedParameter(json_encode($member->getContactMeta())));
$qb->execute();
}
/**
* removeAllFromCircle();
*
* Remove All members from a Circle. Used when deleting a Circle.
*
* @param string $uniqueCircleId
*/
public function removeAllFromCircle($uniqueCircleId) {
$qb = $this->getMembersDeleteSql();
$expr = $qb->expr();
$qb->where($expr->eq('circle_id', $qb->createNamedParameter($uniqueCircleId)));
$qb->execute();
}
/**
* removeAllMembershipsFromUser();
*
* remove All membership from a User. Used when removing a User from the Cloud.
*
* @param DeprecatedMember $member
*/
public function removeAllMembershipsFromUser(DeprecatedMember $member) {
if ($member->getUserId() === '') {
return;
}
$instance = $member->getInstance();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
$qb = $this->getMembersDeleteSql();
$expr = $qb->expr();
$qb->where(
$expr->andX(
$expr->eq('user_id', $qb->createNamedParameter($member->getUserId())),
$expr->eq('instance', $qb->createNamedParameter($instance)),
$expr->eq('user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER))
)
);
$qb->execute();
}
/**
* remove member, identified by its id, type and circleId
*
* @param DeprecatedMember $member
*/
public function removeMember(DeprecatedMember $member) {
$instance = $member->getInstance();
if ($this->configService->isLocalInstance($instance)) {
$instance = '';
}
$qb = $this->getMembersDeleteSql();
$this->limitToCircleId($qb, $member->getCircleId());
$this->limitToUserId($qb, $member->getUserId());
$this->limitToInstance($qb, $instance);
$this->limitToUserType($qb, $member->getType());
if ($member->getContactId() !== '') {
$this->limitToContactId($qb, $member->getContactId());
}
$qb->execute();
}
/**
* update database entry for a specific Group.
*
* @param DeprecatedMember $member
*
* @return bool
*/
public function updateGroup(DeprecatedMember $member) {
$qb = $this->getMembersUpdateSql(
$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
);
$qb->set('level', $qb->createNamedParameter($member->getLevel()));
$qb->execute();
return true;
}
public function unlinkAllFromGroup($groupId) {
$qb = $this->getMembersDeleteSql();
$this->limitToUserId($qb, $groupId);
$this->limitToUserType($qb, DeprecatedMember::TYPE_GROUP);
$this->limitToInstance($qb, '');
$qb->execute();
}
/**
* @param string $contactId
*
* @return DeprecatedMember[]
*/
public function getMembersByContactId(string $contactId = ''): array {
$qb = $this->getMembersSelectSql();
if ($contactId === '') {
$expr = $qb->expr();
$qb->andWhere($expr->neq('contact_id', $qb->createNamedParameter('')));
} else {
$this->limitToContactId($qb, $contactId);
}
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$member = $this->parseMembersSelectSql($data);
$members[] = $member;
}
$cursor->closeCursor();
return $members;
}
/**
* @param string $circleId
* @param string $contactId
*
* @return DeprecatedMember
* @throws MemberDoesNotExistException
*/
public function getContactMember(string $circleId, string $contactId): DeprecatedMember {
$qb = $this->getMembersSelectSql();
$this->limitToContactId($qb, $contactId);
$this->limitToCircleId($qb, $circleId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
}
return $this->parseMembersSelectSql($data);
}
/**
* @param string $contactId
*
* @return DeprecatedMember[]
*/
public function getLocalContactMembers(string $contactId): array {
$qb = $this->getMembersSelectSql();
$this->limitToContactId($qb, $contactId);
$this->limitToUserType($qb, DeprecatedMember::TYPE_USER);
$members = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$members[] = $this->parseMembersSelectSql($data);
}
$cursor->closeCursor();
return $members;
}
/**
* @param string $contactId
* @param int $type
*/
public function removeMembersByContactId(string $contactId, int $type = 0) {
$this->miscService->log($contactId);
if ($contactId === '') {
return;
}
$qb = $this->getMembersDeleteSql();
$this->limitToContactId($qb, $contactId);
if ($type > 0) {
$this->limitToUserType($qb, $type);
}
$qb->execute();
}
}
@@ -0,0 +1,188 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\DeprecatedMember;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\MiscService;
use OCA\Circles\Service\TimezoneService;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IL10N;
class DeprecatedMembersRequestBuilder extends DeprecatedRequestBuilder {
/** @var IGroupManager */
protected $groupManager;
/**
* CirclesRequestBuilder constructor.
*
* {@inheritdoc}
* @param IGroupManager $groupManager
*/
public function __construct(
IL10N $l10n, IDBConnection $connection, IGroupManager $groupManager,
ConfigService $configService, TimezoneService $timezoneService, MiscService $miscService
) {
parent::__construct($l10n, $connection, $configService, $timezoneService, $miscService);
$this->groupManager = $groupManager;
}
/**
* Base of the Sql Insert request for Shares
*
* @return IQueryBuilder
*/
protected function getMembersInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_MEMBERS)
->setValue('joined', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getMembersSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
'm.user_id', 'm.instance', 'm.user_type', 'm.circle_id', 'm.level', 'm.status', 'm.note',
'm.contact_id', 'm.member_id', 'm.cached_name', 'm.cached_update', 'm.contact_meta', 'm.joined'
)
->from(self::TABLE_MEMBERS, 'm')
->orderBy('m.joined');
$this->default_select_alias = 'm';
return $qb;
}
/**
* Base of the Sql Updte request for Members
*
* @param string /$circleId
* @param string $userId
* @param string $instance
* @param int $type
*
* @return IQueryBuilder
*/
protected function getMembersUpdateSql(string $circleId, string $userId, string $instance, int $type) {
$qb = $this->dbConnection->getQueryBuilder();
$expr = $qb->expr();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->update(self::TABLE_MEMBERS)
->where(
$expr->andX(
$expr->eq('circle_id', $qb->createNamedParameter($circleId)),
$expr->eq('user_id', $qb->createNamedParameter($userId)),
$expr->eq('instance', $qb->createNamedParameter($instance)),
$expr->eq('user_type', $qb->createNamedParameter($type))
)
);
return $qb;
}
/**
* Base of the Sql Delete request for Members
*
* @return IQueryBuilder
*/
protected function getMembersDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(DeprecatedRequestBuilder::TABLE_MEMBERS);
return $qb;
}
/**
* @param array $data
*
* @return DeprecatedMember
*/
protected function parseMembersSelectSql(array $data) {
$member = new DeprecatedMember($data['user_id'], $data['user_type'], $data['circle_id']);
$member->setNote($data['note']);
$member->setContactId($data['contact_id']);
$member->setMemberId($data['member_id']);
$member->setCachedName($data['cached_name']);
$member->setCachedUpdate($this->timezoneService->convertToTimestamp($data['cached_update']));
$contactMeta = json_decode($data['contact_meta'], true);
if (is_array($contactMeta)) {
$member->setContactMeta($contactMeta);
}
$member->setLevel($data['level']);
$member->setInstance($data['instance']);
$member->setStatus($data['status']);
$member->setJoined($this->timezoneService->convertTimeForCurrentUser($data['joined']));
$joined = $this->timezoneService->convertToTimestamp($data['joined']);
$member->setJoinedSince(time() - $joined);
return $member;
}
/**
* @param array $data
*
* @return DeprecatedMember
*/
protected function parseGroupsSelectSql(array $data) {
$member = new DeprecatedMember();
$member->setCircleId($data['circle_id']);
$member->setNote($data['note']);
$member->setLevel($data['level']);
if (key_exists('user_id', $data)) {
$member->setType(DeprecatedMember::TYPE_USER);
$member->setUserId($data['user_id']);
} else {
$member->setType(DeprecatedMember::TYPE_GROUP);
$member->setUserId($data['group_id']);
}
$member->setJoined($this->timezoneService->convertTimeForCurrentUser($data['joined']));
return $member;
}
}
@@ -0,0 +1,513 @@
<?php
/**
* Created by PhpStorm.
* User: maxence
* Date: 7/4/17
* Time: 5:01 PM
*/
namespace OCA\Circles\Db;
use Doctrine\DBAL\Query\QueryBuilder;
use OCA\Circles\Exceptions\GSStatusException;
use OCA\Circles\Model\DeprecatedMember;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\MiscService;
use OCA\Circles\Service\TimezoneService;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IL10N;
class DeprecatedRequestBuilder {
public const TABLE_FILE_SHARES = 'share';
public const SHARE_TYPE = 7;
public const TABLE_CIRCLES = 'circle_circles';
public const TABLE_MEMBERS = 'circle_members';
public const TABLE_GROUPS = 'circle_groups';
public const TABLE_SHARES = 'circle_shares';
public const TABLE_LINKS = 'circle_links';
public const TABLE_TOKENS = 'circle_tokens';
public const TABLE_GSEVENTS = 'circle_gsevents';
public const TABLE_GSSHARES = 'circle_gsshares';
public const TABLE_GSSHARES_MOUNTPOINT = 'circle_gsshares_mp';
public const TABLE_REMOTE = 'circle_remotes';
public const NC_TABLE_ACCOUNTS = 'accounts';
public const NC_TABLE_GROUP_USER = 'group_user';
/** @var array */
private $tables = [
self::TABLE_CIRCLES,
self::TABLE_GROUPS,
self::TABLE_MEMBERS,
self::TABLE_SHARES,
self::TABLE_LINKS,
self::TABLE_TOKENS,
self::TABLE_GSEVENTS,
self::TABLE_GSSHARES,
self::TABLE_GSSHARES_MOUNTPOINT
];
/** @var IDBConnection */
protected $dbConnection;
/** @var IL10N */
protected $l10n;
/** @var ConfigService */
protected $configService;
/** @var TimezoneService */
protected $timezoneService;
/** @var MiscService */
protected $miscService;
/** @var string */
protected $default_select_alias;
/** @var bool */
protected $leftJoinedNCGroupAndUser = false;
/**
* CoreQueryBuilder constructor.
*
* @param IL10N $l10n
* @param IDBConnection $connection
* @param ConfigService $configService
* @param TimezoneService $timezoneService
* @param MiscService $miscService
*/
public function __construct(
IL10N $l10n, IDBConnection $connection, ConfigService $configService,
TimezoneService $timezoneService, MiscService $miscService
) {
$this->l10n = $l10n;
$this->dbConnection = $connection;
$this->configService = $configService;
$this->timezoneService = $timezoneService;
$this->miscService = $miscService;
}
/**
* Limit the request by its Id.
*
* @param IQueryBuilder $qb
* @param int $id
*/
protected function limitToId(IQueryBuilder $qb, $id) {
$this->limitToDBField($qb, 'id', $id);
}
/**
* Limit the request by its UniqueId.
*
* @param IQueryBuilder $qb
* @param int $uniqueId
*/
protected function limitToUniqueId(IQueryBuilder $qb, $uniqueId) {
$this->limitToDBField($qb, 'unique_id', $uniqueId);
}
/**
* Limit the request by its addressbookId.
*
* @param IQueryBuilder $qb
* @param int $bookId
*/
protected function limitToAddressBookId(IQueryBuilder $qb, $bookId) {
$this->limitToDBField($qb, 'contact_addressbook', (string)$bookId);
}
/**
* Limit the request by its addressbookId.
*
* @param IQueryBuilder $qb
* @param string $groupName
*/
protected function limitToContactGroup(IQueryBuilder $qb, $groupName) {
$this->limitToDBField($qb, 'contact_groupname', $groupName);
}
/**
* Limit the request to the Circle by its Id.
*
* @param IQueryBuilder $qb
* @param string $contactId
*/
protected function limitToContactId(IQueryBuilder $qb, $contactId) {
$this->limitToDBField($qb, 'contact_id', $contactId);
}
/**
* Limit the request by its Token.
*
* @param IQueryBuilder $qb
* @param string $token
*/
protected function limitToToken(IQueryBuilder $qb, $token) {
$this->limitToDBField($qb, 'token', $token);
}
/**
* Limit the request to the User by its Id.
*
* @param IQueryBuilder $qb
* @param $userId
*/
protected function limitToUserId(IQueryBuilder $qb, $userId) {
$this->limitToDBField($qb, 'user_id', $userId);
}
/**
* Limit the request to the owner
*
* @param IQueryBuilder $qb
* @param $owner
*/
protected function limitToOwner(IQueryBuilder $qb, $owner) {
$this->limitToDBField($qb, 'owner', $owner);
}
/**
* Limit the request to the Member by its Id.
*
* @param IQueryBuilder $qb
* @param string $memberId
*/
protected function limitToMemberId(IQueryBuilder $qb, string $memberId) {
$this->limitToDBField($qb, 'member_id', $memberId);
}
/**
* Limit the request to the Type entry.
*
* @param IQueryBuilder $qb
* @param int $type
*/
protected function limitToUserType(IQueryBuilder $qb, $type) {
$this->limitToDBField($qb, 'user_type', $type);
}
/**
* Limit the request to the Instance.
*
* @param IQueryBuilder $qb
* @param string $instance
*/
protected function limitToInstance(IQueryBuilder $qb, string $instance) {
$this->limitToDBField($qb, 'instance', $instance);
}
/**
* Limit the request to the Circle by its Id.
*
* @param IQueryBuilder $qb
* @param string $circleUniqueId
*/
protected function limitToCircleId(IQueryBuilder $qb, $circleUniqueId) {
$this->limitToDBField($qb, 'circle_id', $circleUniqueId);
}
/**
* Limit the request to the Circle by its Id.
*
* @param IQueryBuilder $qb
* @param int $shareId
*/
protected function limitToShareId(IQueryBuilder $qb, int $shareId) {
$this->limitToDBField($qb, 'share_id', $shareId);
}
/**
* Limit the request to the Circle by its Id.
*
* @param IQueryBuilder $qb
* @param string $mountpoint
*/
protected function limitToMountpoint(IQueryBuilder $qb, string $mountpoint) {
$this->limitToDBField($qb, 'share_id', $mountpoint);
}
/**
* Limit the request to the Circle by its Id.
*
* @param IQueryBuilder $qb
* @param string $hash
*/
protected function limitToMountpointHash(IQueryBuilder $qb, string $hash) {
$this->limitToDBField($qb, 'share_id', $hash);
}
//
// /**
// * Limit the request to the Circle by its Shorten Unique Id.
// *
// * @param IQueryBuilder $qb
// * @param string $circleUniqueId
// * @param $length
// */
// protected function limitToShortenUniqueId(IQueryBuilder $qb, $circleUniqueId, $length) {
// $expr = $qb->expr();
// $pf = ($qb->getType() === QueryBuilder::SELECT) ? '`' . $this->default_select_alias . '`.' : '';
//
// $qb->andWhere(
// $expr->eq(
// $qb->createNamedParameter($circleUniqueId),
// $qb->createFunction('SUBSTR(' . $pf . '`unique_id`' . ', 1, ' . $length . ')')
// )
// );
//
// }
/**
* Limit the request to the Group by its Id.
*
* @param IQueryBuilder $qb
* @param int $groupId
*/
protected function limitToGroupId(IQueryBuilder $qb, $groupId) {
$this->limitToDBField($qb, 'group_id', $groupId);
}
/**
* Limit the search by its Name
*
* @param IQueryBuilder $qb
* @param string $name
*/
protected function limitToName(IQueryBuilder $qb, $name) {
$this->limitToDBField($qb, 'name', $name);
}
/**
* Limit the search by its Status (or greater)
*
* @param IQueryBuilder $qb
* @param string $name
*/
protected function limitToStatus(IQueryBuilder $qb, $name) {
$this->limitToDBFieldOrGreater($qb, 'status', $name);
}
/**
* Limit the request by its Id.
*
* @param IQueryBuilder $qb
* @param string $type
*/
protected function limitToShareType(IQueryBuilder $qb, string $type) {
$this->limitToDBField($qb, 'share_type', $type);
}
/**
* Limit the request by its Id.
*
* @param IQueryBuilder $qb
* @param string $with
*/
protected function limitToShareWith(IQueryBuilder $qb, string $with) {
$this->limitToDBField($qb, 'share_with', $with);
}
/**
* Limit the request to a minimum member level.
*
* if $pf is an array, will generate an SQL OR request to limit level in multiple tables
*
* @param IQueryBuilder $qb
* @param int $level
* @param string|array $pf
*/
protected function limitToLevel(IQueryBuilder $qb, int $level, $pf = '') {
$expr = $qb->expr();
if ($pf === '') {
$p = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
$qb->andWhere($expr->gte($p . 'level', $qb->createNamedParameter($level)));
return;
}
if (!is_array($pf)) {
$pf = [$pf];
}
$orX = $this->generateLimitToLevelMultipleTableRequest($qb, $level, $pf);
$qb->andWhere($orX);
}
/**
* @param IQueryBuilder $qb
* @param int $level
* @param array $pf
*
* @return mixed
*/
private function generateLimitToLevelMultipleTableRequest(IQueryBuilder $qb, int $level, $pf) {
$expr = $qb->expr();
$orX = $expr->orX();
foreach ($pf as $p) {
if ($p === 'g' && !$this->leftJoinedNCGroupAndUser) {
continue;
}
$orX->add($expr->gte($p . '.level', $qb->createNamedParameter($level)));
}
return $orX;
}
/**
* Limit the search to Members and Almost members
*
* @param IQueryBuilder $qb
*/
protected function limitToMembersAndAlmost(IQueryBuilder $qb) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
$orX = $expr->orX();
$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(DeprecatedMember::STATUS_MEMBER)));
$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(DeprecatedMember::STATUS_INVITED)));
$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(DeprecatedMember::STATUS_REQUEST)));
$qb->andWhere($orX);
}
/**
* @param IQueryBuilder $qb
* @param string $field
* @param string|integer $value
*/
public function limitToDBField(IQueryBuilder $qb, $field, $value) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
$qb->andWhere($expr->eq($pf . $field, $qb->createNamedParameter($value)));
}
/**
* @param IQueryBuilder $qb
* @param string $field
* @param string|integer $value
*/
private function limitToDBFieldOrGreater(IQueryBuilder $qb, $field, $value) {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
$qb->andWhere($expr->gte($pf . $field, $qb->createNamedParameter($value)));
}
/**
* link to the groupId/UserId of the NC DB.
* If userId is empty, we add the uid of the NCGroup Table in the select list with 'user_id'
* alias
*
* @param IQueryBuilder $qb
* @param string $userId
*/
protected function limitToNCGroupUser(IQueryBuilder $qb, $userId = '') {
$expr = $qb->expr();
$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
$and = $expr->andX($expr->eq($pf . 'user_id', 'ncgu.gid'));
if ($userId !== '') {
$and->add($expr->eq('ncgu.uid', $qb->createNamedParameter($userId)));
} else {
$qb->selectAlias('ncgu.uid', 'user_id');
}
$qb->from(self::NC_TABLE_GROUP_USER, 'ncgu');
$qb->andWhere($and);
}
/**
* Left Join circle table to get more information about the circle.
*
* @param IQueryBuilder $qb
*/
protected function leftJoinCircle(IQueryBuilder $qb) {
if ($qb->getType() !== QueryBuilder::SELECT) {
return;
}
$expr = $qb->expr();
$pf = $this->default_select_alias . '.';
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->selectAlias('lc.type', 'circle_type')
->selectAlias('lc.name', 'circle_name')
->selectAlias('lc.alt_name', 'circle_alt_name')
->selectAlias('lc.settings', 'circle_settings')
->leftJoin(
$this->default_select_alias, DeprecatedRequestBuilder::TABLE_CIRCLES, 'lc',
$expr->eq($pf . 'circle_id', 'lc.unique_id')
);
}
/**
* link to the groupId/UserId of the NC DB.
*
* @param IQueryBuilder $qb
* @param string $userId
* @param string $field
*
* @throws GSStatusException
*/
protected function leftJoinNCGroupAndUser(IQueryBuilder $qb, $userId, $field) {
return;
if (!$this->configService->isLinkedGroupsAllowed()) {
return;
}
$expr = $qb->expr();
$qb->leftJoin(
$this->default_select_alias, self::NC_TABLE_GROUP_USER, 'ncgu',
$expr->eq('ncgu.uid', $qb->createNamedParameter($userId))
);
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->leftJoin(
$this->default_select_alias, DeprecatedRequestBuilder::TABLE_MEMBERS, 'g',
$expr->andX(
$expr->eq('g.user_id', 'ncgu.gid'),
$expr->eq('g.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_GROUP)),
$expr->eq('g.instance', $qb->createNamedParameter('')),
$expr->eq('g.circle_id', $field)
)
);
$this->leftJoinedNCGroupAndUser = true;
}
}
@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
/**
* 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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\Federated\EventWrapper;
/**
* Class EventWrapperRequest
*
* @package OCA\Circles\Db
*/
class EventWrapperRequest extends EventWrapperRequestBuilder {
/**
* @param EventWrapper $wrapper
*/
public function save(EventWrapper $wrapper): void {
$qb = $this->getEventWrapperInsertSql();
$qb->setValue('token', $qb->createNamedParameter($wrapper->getToken()))
->setValue(
'event', $qb->createNamedParameter(json_encode($wrapper->getEvent(), JSON_UNESCAPED_SLASHES))
)
->setValue(
'result', $qb->createNamedParameter(json_encode($wrapper->getResult(), JSON_UNESCAPED_SLASHES))
)
->setValue('instance', $qb->createNamedParameter($wrapper->getInstance()))
->setValue('interface', $qb->createNamedParameter($wrapper->getInterface()))
->setValue('severity', $qb->createNamedParameter($wrapper->getSeverity()))
->setValue('retry', $qb->createNamedParameter($wrapper->getRetry()))
->setValue('status', $qb->createNamedParameter($wrapper->getStatus()))
->setValue('creation', $qb->createNamedParameter($wrapper->getCreation()));
$qb->execute();
}
/**
* @param EventWrapper $wrapper
*/
public function update(EventWrapper $wrapper): void {
$qb = $this->getEventWrapperUpdateSql();
$qb->set('result', $qb->createNamedParameter(json_encode($wrapper->getResult())))
->set('status', $qb->createNamedParameter($wrapper->getStatus()))
->set('retry', $qb->createNamedParameter($wrapper->getRetry()));
$qb->limitToInstance($wrapper->getInstance());
$qb->limitToToken($wrapper->getToken());
$qb->execute();
}
/**
* @param string $token
* @param int $status
*/
public function updateAll(string $token, int $status): void {
$qb = $this->getEventWrapperUpdateSql();
$qb->set('status', $qb->createNamedParameter($status));
$qb->limitToToken($token);
$qb->execute();
}
/**
* returns unique token not set as FAILED
*
* @return EventWrapper[]
*/
public function getFailedEvents(array $retryRange): array {
$qb = $this->getEventWrapperSelectSql();
$expr = $qb->expr();
$qb->andWhere(
$expr->orX(
$qb->exprLimitInt('status', EventWrapper::STATUS_FAILED),
$expr->andX(
$qb->exprLimitInt('status', EventWrapper::STATUS_INIT),
$qb->exprGt('creation', time() - 86400), // only freshly created; less than 3 hours
$qb->exprLt('creation', time() - 900) // but not too fresh, at least 15 minutes
)
)
);
$qb->gt('retry', $retryRange[0], true);
$qb->lt('retry', $retryRange[1]);
return $this->getItemsFromRequest($qb);
}
/**
* @param string $token
*
* @return EventWrapper[]
*/
public function getByToken(string $token): array {
$qb = $this->getEventWrapperSelectSql();
$qb->limitToToken($token);
return $this->getItemsFromRequest($qb);
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\EventWrapperNotFoundException;
use OCA\Circles\Model\Federated\EventWrapper;
/**
* Class GSEventsRequestBuilder
*
* @package OCA\Circles\Db
*/
class EventWrapperRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getEventWrapperInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_EVENT);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getEventWrapperUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_EVENT);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getEventWrapperSelectSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(
self::TABLE_EVENT,
self::$tables[self::TABLE_EVENT],
CoreQueryBuilder::FEDERATED_EVENT
);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getEventWrapperDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_EVENT);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return EventWrapper
* @throws EventWrapperNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): EventWrapper {
/** @var EventWrapper $wrapper */
try {
$wrapper = $qb->asItem(EventWrapper::class);
} catch (RowNotFoundException $e) {
throw new EventWrapperNotFoundException();
}
return $wrapper;
}
/**
* @param CoreQueryBuilder $qb
*
* @return EventWrapper[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var EventWrapper[] $result */
return $qb->asItems(EventWrapper::class);
}
}
@@ -0,0 +1,223 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\FederatedLinkDoesNotExistException;
use OCA\Circles\Model\FederatedLink;
/**
* @deprecated
* Class FederatedLinksRequest
*
* @package OCA\Circles\Db
*/
class FederatedLinksRequest extends FederatedLinksRequestBuilder {
/**
* @param FederatedLink $link
*
* @return bool
* @throws \Exception
*/
public function create(FederatedLink $link) {
try {
$qb = $this->getLinksInsertSql();
$qb->setValue('status', $qb->createNamedParameter($link->getStatus()))
->setValue('circle_id', $qb->createNamedParameter($link->getCircleId()))
->setValue('unique_id', $qb->createNamedParameter($link->getUniqueId(true)))
->setValue('address', $qb->createNamedParameter($link->getAddress()))
->setValue('token', $qb->createNamedParameter($link->getToken(true)));
$qb->execute();
return true;
} catch (\Exception $e) {
throw $e;
}
}
/**
* @param FederatedLink $link
*/
public function update(FederatedLink $link) {
if ($link->getStatus() === FederatedLink::STATUS_LINK_REMOVE) {
$this->delete($link);
return;
}
$qb = $this->getLinksUpdateSql();
$qb->set('status', $qb->createNamedParameter($link->getStatus()));
if ($link->getUniqueId() !== '') {
$qb->set('unique_id', $qb->createNamedParameter($link->getUniqueId(true)));
}
$this->limitToToken($qb, $link->getToken(true));
$this->limitToCircleId($qb, $link->getCircleId());
$qb->execute();
}
/**
* @param FederatedLink $link
*/
public function delete(FederatedLink $link) {
if ($link === null) {
return;
}
$qb = $this->getLinksDeleteSql();
$this->limitToToken($qb, $link->getToken(true));
$this->limitToCircleId($qb, $link->getCircleId());
$qb->execute();
}
/**
* @param array $data
*
* @return FederatedLink
*/
public function getLinkFromEntry($data) {
if ($data === false || $data === null) {
return null;
}
$link = new FederatedLink();
$link->setId($data['id'])
->setUniqueId($data['unique_id'])
->setStatus($data['status'])
->setAddress($data['address'])
->setToken($data['token'])
->setCircleId($data['circle_id']);
return $link;
}
/**
* returns all FederatedLink from a circle
*
* @param string $circleUniqueId
* @param int $status
*
* @return FederatedLink[]
*/
public function getLinksFromCircle($circleUniqueId, $status = 0) {
$qb = $this->getLinksSelectSql();
$this->limitToCircleId($qb, $circleUniqueId);
$this->limitToStatus($qb, $status);
$links = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$links[] = $this->parseLinksSelectSql($data);
}
$cursor->closeCursor();
return $links;
}
/**
* returns a FederatedLink from a circle identified by its full unique Id
*
* @param string $circleUniqueId
* @param string $linkUniqueId
*
* @return FederatedLink
* @throws FederatedLinkDoesNotExistException
*/
public function getLinkFromCircle($circleUniqueId, $linkUniqueId) {
$qb = $this->getLinksSelectSql();
$this->limitToCircleId($qb, $circleUniqueId);
$this->limitToUniqueId($qb, $linkUniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new FederatedLinkDoesNotExistException($this->l10n->t('Federated link not found'));
}
return $this->parseLinksSelectSql($data);
}
/**
* return the FederatedLink identified by a remote Circle UniqueId and the Token of the link
*
* @param string $token
* @param string $uniqueId
*
* @return FederatedLink
* @throws FederatedLinkDoesNotExistException
*/
public function getLinkFromToken($token, $uniqueId) {
$qb = $this->getLinksSelectSql();
$this->limitToUniqueId($qb, (string)$uniqueId);
$this->limitToToken($qb, (string)$token);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new FederatedLinkDoesNotExistException($this->l10n->t('Federated link not found'));
}
return $this->parseLinksSelectSql($data);
}
/**
* return the FederatedLink identified by a its Id
*
* @param string $linkUniqueId
*
* @return FederatedLink
* @throws FederatedLinkDoesNotExistException
*/
public function getLinkFromId($linkUniqueId) {
$qb = $this->getLinksSelectSql();
$this->limitToUniqueId($qb, $linkUniqueId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new FederatedLinkDoesNotExistException($this->l10n->t('Federated link not found'));
}
return $this->parseLinksSelectSql($data);
}
}
@@ -0,0 +1,133 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\FederatedLink;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\MiscService;
use OCA\Circles\Service\TimezoneService;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IL10N;
/**
* @deprecated
* Class FederatedLinksRequestBuilder
*
* @package OCA\Circles\Db
*/
class FederatedLinksRequestBuilder extends DeprecatedRequestBuilder {
/**
* CirclesRequestBuilder constructor.
*
* {@inheritdoc}
*/
public function __construct(
IL10N $l10n, IDBConnection $connection, ConfigService $configService,
TimezoneService $timezoneService, MiscService $miscService
) {
parent::__construct($l10n, $connection, $configService, $timezoneService, $miscService);
}
/**
* Base of the Sql Insert request
*
* @return IQueryBuilder
*/
protected function getLinksInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_LINKS)
->setValue('creation', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* Base of the Sql Update request
*
* @return IQueryBuilder
*/
protected function getLinksUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::TABLE_LINKS);
return $qb;
}
/**
* Base of the Sql Select request for Shares
*
* @return IQueryBuilder
*/
protected function getLinksSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
'l.id', 'l.status', 'l.address', 'l.token', 'l.circle_id', 'l.unique_id', 'l.creation'
)
->from(self::TABLE_LINKS, 'l');
$this->default_select_alias = 'l';
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getLinksDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_LINKS);
return $qb;
}
/**
* @param array $data
*
* @return FederatedLink
*/
protected function parseLinksSelectSql($data) {
$link = new FederatedLink();
$link->setId($data['id'])
->setUniqueId($data['unique_id'])
->setStatus($data['status'])
->setCreation($data['creation'])
->setAddress($data['address'])
->setToken($data['token'])
->setCircleId($data['circle_id']);
return $link;
}
}
@@ -0,0 +1,116 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\DeprecatedMember;
/**
* @deprecated
* Class SharesRequest
*
* @package OCA\Circles\Db
*/
class FileSharesRequest extends FileSharesRequestBuilder {
/**
* remove shares from a member to a circle
*
* @param DeprecatedMember $member
*/
public function removeSharesFromMember(DeprecatedMember $member): void {
$qb = $this->getFileSharesDeleteSql();
$expr = $qb->expr();
$andX = $expr->andX();
$andX->add($expr->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE)));
$andX->add($expr->eq('share_with', $qb->createNamedParameter($member->getCircleId())));
$andX->add($expr->eq('uid_initiator', $qb->createNamedParameter($member->getUserId())));
$qb->andWhere($andX);
$qb->execute();
}
/**
* @param string $circleId
*/
public function removeSharesToCircleId(string $circleId): void {
$qb = $this->getFileSharesDeleteSql();
$expr = $qb->expr();
$andX = $expr->andX();
$andX->add($expr->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE)));
$andX->add($expr->eq('share_with', $qb->createNamedParameter($circleId)));
$qb->andWhere($andX);
$qb->execute();
}
/**
* @param string $circleId
*
* @return array
*/
public function getSharesForCircle(string $circleId): array {
$qb = $this->getFileSharesSelectSql();
$this->limitToShareWith($qb, $circleId);
$this->limitToShareType($qb, self::SHARE_TYPE);
$shares = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$shares[] = $data;
}
$cursor->closeCursor();
return $shares;
}
/**
* @return array
*/
public function getShares(): array {
$qb = $this->getFileSharesSelectSql();
$expr = $qb->expr();
$this->limitToShareType($qb, self::SHARE_TYPE);
$qb->andWhere($expr->isNull($this->default_select_alias . '.parent'));
$shares = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$shares[] = $data;
}
$cursor->closeCursor();
return $shares;
}
}
@@ -0,0 +1,91 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* @deprecated
* Class FileSharesRequestBuilder
*
* @package OCA\Circles\Db
*/
class FileSharesRequestBuilder extends DeprecatedRequestBuilder {
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getFileSharesDeleteSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_FILE_SHARES);
$qb->where(
$qb->expr()
->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE))
);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getFileSharesSelectSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
's.id',
's.share_with',
's.file_source',
's.uid_owner',
's.uid_initiator',
's.permissions',
's.token',
's.password',
's.file_target'
)
->from(self::TABLE_FILE_SHARES, 's');
$this->default_select_alias = 's';
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getFileSharesUpdateSql(): IQueryBuilder {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::TABLE_FILE_SHARES);
return $qb;
}
}
@@ -0,0 +1,218 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Traits\TStringTools;
use OCA\Circles\Model\GlobalScale\GSShare;
use OCA\Circles\Model\GlobalScale\GSShareMountpoint;
use OCA\Circles\Model\DeprecatedMember;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Share\Exceptions\ShareNotFound;
/**
* @deprecated
* Class GSSharesRequest
*
* @package OCA\Circles\Db
*/
class GSSharesRequest extends GSSharesRequestBuilder {
use TStringTools;
/**
* @param GSShare $gsShare
*/
public function create(GSShare $gsShare): void {
$hash = $this->token();
$qb = $this->getGSSharesInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($gsShare->getCircleId()))
->setValue('owner', $qb->createNamedParameter($gsShare->getOwner()))
->setValue('instance', $qb->createNamedParameter($gsShare->getInstance()))
->setValue('token', $qb->createNamedParameter($gsShare->getToken()))
->setValue('parent', $qb->createNamedParameter($gsShare->getParent()))
->setValue('mountpoint', $qb->createNamedParameter($gsShare->getMountPoint()))
->setValue('mountpoint_hash', $qb->createNamedParameter($hash));
$qb->execute();
}
/**
* @param string $userId
*
* @return GSShare[]
*/
public function getForUser(string $userId): array {
$qb = $this->getGSSharesSelectSql();
$this->joinMembership($qb, $userId);
$this->leftJoinMountPoint($qb, $userId);
$shares = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$shares[] = $this->parseGSSharesSelectSql($data);
}
$cursor->closeCursor();
return $shares;
}
/**
* @param DeprecatedMember $member
*/
public function removeGSSharesFromMember(DeprecatedMember $member) {
$qb = $this->getGSSharesDeleteSql();
$this->limitToCircleId($qb, $member->getCircleId());
$this->limitToInstance($qb, $member->getInstance());
$this->limitToOwner($qb, $member->getUserId());
$qb->execute();
}
/**
* @param IQueryBuilder $qb
* @param string $userId
*/
private function joinMembership(IQueryBuilder $qb, string $userId) {
$qb->from(DeprecatedRequestBuilder::TABLE_MEMBERS, 'm');
$expr = $qb->expr();
$andX = $expr->andX();
$andX->add($expr->eq('m.user_id', $qb->createNamedParameter($userId)));
$andX->add($expr->eq('m.instance', $qb->createNamedParameter('')));
$andX->add($expr->gt('m.level', $qb->createNamedParameter(0)));
$andX->add($expr->eq('m.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER)));
$andX->add($expr->eq('m.circle_id', 'gsh.circle_id'));
$qb->andWhere($andX);
}
private function leftJoinMountPoint(IQueryBuilder $qb, string $userId) {
$expr = $qb->expr();
$pf = '' . $this->default_select_alias . '.';
$on = $expr->andX();
$on->add($expr->eq('mp.user_id', $qb->createNamedParameter($userId)));
$on->add($expr->eq('mp.share_id', $pf . 'id'));
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->selectAlias('mp.mountPoint', 'gsshares_mountpoint')
->leftJoin($this->default_select_alias, DeprecatedRequestBuilder::TABLE_GSSHARES_MOUNTPOINT, 'mp', $on);
}
/**
* @param string $userId
* @param string $target
*
* @return GSShareMountpoint
* @throws ShareNotFound
*/
public function getShareMountPointByPath(string $userId, string $target): GSShareMountpoint {
$qb = $this->getGSSharesMountpointSelectSql();
$targetHash = md5($target);
$this->limitToUserId($qb, $userId);
$this->limitToMountpointHash($qb, $targetHash);
$shares = [];
$cursor = $qb->execute();
$data = $cursor->fetch();
if ($data === false) {
throw new ShareNotFound();
}
return $this->parseGSSharesMountpointSelectSql($data);
}
/**
* @param int $gsShareId
* @param string $userId
*
* @return GSShareMountpoint
* @throws ShareNotFound
*/
public function getShareMountPointById(int $gsShareId, string $userId): GSShareMountpoint {
$qb = $this->getGSSharesMountpointSelectSql();
$this->limitToShareId($qb, $gsShareId);
$this->limitToUserId($qb, $userId);
$shares = [];
$cursor = $qb->execute();
$data = $cursor->fetch();
if ($data === false) {
throw new ShareNotFound();
}
return $this->parseGSSharesMountpointSelectSql($data);
}
/**
* @param GSShareMountpoint $mountpoint
*/
public function generateShareMountPoint(GSShareMountpoint $mountpoint) {
$qb = $this->getGSSharesMountpointInsertSql();
$hash = ($mountpoint->getMountPoint() === '-') ? '' : md5($mountpoint->getMountPoint());
$qb->setValue('user_id', $qb->createNamedParameter($mountpoint->getUserId()))
->setValue('share_id', $qb->createNamedParameter($mountpoint->getShareId()))
->setValue('mountpoint', $qb->createNamedParameter($mountpoint->getMountPoint()))
->setValue('mountpoint_hash', $qb->createNamedParameter($hash));
$qb->execute();
}
/**
* @param GSShareMountpoint $mountpoint
*
* @return bool
*/
public function updateShareMountPoint(GSShareMountpoint $mountpoint) {
$qb = $this->getGSSharesMountpointUpdateSql();
$hash = ($mountpoint->getMountPoint() === '-') ? '' : md5($mountpoint->getMountPoint());
$qb->set('mountpoint', $qb->createNamedParameter($mountpoint->getMountPoint()))
->set('mountpoint_hash', $qb->createNamedParameter($hash));
$this->limitToShareId($qb, $mountpoint->getShareId());
$this->limitToUserId($qb, $mountpoint->getUserId());
$nb = $qb->execute();
return ($nb === 1);
}
}
@@ -0,0 +1,179 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\GlobalScale\GSShare;
use OCA\Circles\Model\GlobalScale\GSShareMountpoint;
use OCP\DB\QueryBuilder\IQueryBuilder;
/** * @deprecated
*
* Class GSSharesRequestBuilder
*
* @package OCA\Circles\Db
*/
class GSSharesRequestBuilder extends DeprecatedRequestBuilder {
/**
* Base of the Sql Insert request for Shares
*
* @return IQueryBuilder
*/
protected function getGSSharesInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_GSSHARES);
return $qb;
}
/**
* Base of the Sql Insert request for Shares Mountpoint
*
* @return IQueryBuilder
*/
protected function getGSSharesMountpointInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_GSSHARES_MOUNTPOINT);
return $qb;
}
/**
* Base of the Sql Update request
*
* @return IQueryBuilder
*/
protected function getGSSharesUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::TABLE_GSSHARES);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getGSSharesMountpointUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::TABLE_GSSHARES_MOUNTPOINT);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getGSSharesSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
'gsh.id', 'gsh.circle_id', 'gsh.owner', 'gsh.instance', 'gsh.token', 'gsh.parent',
'gsh.mountpoint', 'gsh.mountpoint_hash'
)
->from(self::TABLE_GSSHARES, 'gsh');
$this->default_select_alias = 'gsh';
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getGSSharesMountpointSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select(
'gsmp.user_id', 'gsmp.share_id', 'gsmp.mountpoint', 'gsmp.mountpoint_hash'
)
->from(self::TABLE_GSSHARES_MOUNTPOINT, 'gsmp');
$this->default_select_alias = 'gsmp';
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getGSSharesDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_GSSHARES);
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getGSSharesMountpointDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_GSSHARES_MOUNTPOINT);
return $qb;
}
/**
* @param array $data
*
* @return GSShare
*/
protected function parseGSSharesSelectSql($data): GSShare {
$share = new GSShare();
$share->importFromDatabase($data);
return $share;
}
/**
* @param array $data
*
* @return GSShareMountpoint
*/
protected function parseGSSharesMountpointSelectSql($data): GSShareMountpoint {
$share = new GSShareMountpoint();
$share->importFromDatabase($data);
return $share;
}
}
@@ -0,0 +1,429 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Exceptions\MemberNotFoundException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\Probes\MemberProbe;
/**
* Class MemberRequest
*
* @package OCA\Circles\Db
*/
class MemberRequest extends MemberRequestBuilder {
/**
* @param Member $member
*
* @throws InvalidIdException
*/
public function save(Member $member): void {
$this->confirmValidIds([$member->getCircleId(), $member->getSingleId(), $member->getId()]);
$qb = $this->getMemberInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
->setValue('single_id', $qb->createNamedParameter($member->getSingleId()))
->setValue('member_id', $qb->createNamedParameter($member->getId()))
->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
->setValue('user_type', $qb->createNamedParameter($member->getUserType()))
->setValue('cached_name', $qb->createNamedParameter($member->getDisplayName()))
->setValue('cached_update', $qb->createNamedParameter($this->timezoneService->getUTCDate()))
->setValue('instance', $qb->createNamedParameter($qb->getInstance($member)))
->setValue('level', $qb->createNamedParameter($member->getLevel()))
->setValue('status', $qb->createNamedParameter($member->getStatus()))
->setValue('contact_id', $qb->createNamedParameter($member->getContactId()))
->setValue('note', $qb->createNamedParameter(json_encode($member->getNotes())));
if ($member->hasInvitedBy()) {
$qb->setValue('invited_by', $qb->createNamedParameter($member->getInvitedBy()->getSingleId()));
}
$qb->execute();
}
/**
* @param Member $member
*
* @throws InvalidIdException
*/
public function update(Member $member): void {
$this->confirmValidIds([$member->getCircleId(), $member->getSingleId(), $member->getId()]);
$qb = $this->getMemberUpdateSql();
$qb->set('member_id', $qb->createNamedParameter($member->getId()))
->set('cached_name', $qb->createNamedParameter($member->getDisplayName()))
->set('cached_update', $qb->createNamedParameter($this->timezoneService->getUTCDate()))
->set('level', $qb->createNamedParameter($member->getLevel()))
->set('status', $qb->createNamedParameter($member->getStatus()))
->set('contact_id', $qb->createNamedParameter($member->getContactId()))
->set('note', $qb->createNamedParameter(json_encode($member->getNotes())));
$qb->limitToCircleId($member->getCircleId());
$qb->limitToSingleId($member->getSingleId());
$qb->execute();
}
/**
* @param Member $member
*
* @throws InvalidIdException
* @throws RequestBuilderException
*/
public function insertOrUpdate(Member $member): void {
try {
$this->searchMember($member);
$this->update($member);
} catch (MemberNotFoundException $e) {
$this->save($member);
}
}
/**
* @param string $singleId
* @param string $displayName
* @param string $circleId
*/
public function updateDisplayName(string $singleId, string $displayName, string $circleId = ''): void {
$qb = $this->getMemberUpdateSql();
$qb->set('cached_name', $qb->createNamedParameter($displayName))
->set('cached_update', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
$qb->limitToSingleId($singleId);
if ($circleId !== '') {
$qb->limitToCircleId($circleId);
}
$qb->execute();
}
/**
* @param Member $member
*/
public function delete(Member $member) {
$qb = $this->getMemberDeleteSql();
$qb->limitToCircleId($member->getCircleId());
$qb->limitToSingleId($member->getSingleId());
$qb->execute();
}
/**
* @param IFederatedUser $federatedUser
*/
public function deleteFederatedUser(IFederatedUser $federatedUser): void {
$qb = $this->getMemberDeleteSql();
$qb->limitToSingleId($federatedUser->getSingleId());
$qb->limitToMemberId($federatedUser->getSingleId());
$qb->limitToCircleId($federatedUser->getSingleId());
$qb->execute();
}
/**
* @param IFederatedUser $federatedUser
* @param Circle $circle
*/
public function deleteFederatedUserFromCircle(IFederatedUser $federatedUser, Circle $circle): void {
$qb = $this->getMemberDeleteSql();
$qb->limitToSingleId($federatedUser->getSingleId());
$qb->limitToCircleId($circle->getSingleId());
$qb->execute();
}
/**
*
* @param Circle $circle
*/
public function deleteAllFromCircle(Circle $circle) {
$qb = $this->getMemberDeleteSql();
$qb->andWhere(
$qb->expr()->orX(
$qb->exprLimit('single_id', $circle->getSingleId()),
$qb->exprLimit('circle_id', $circle->getSingleId())
)
);
$qb->execute();
}
/**
* @param Member $member
*/
public function updateLevel(Member $member): void {
$qb = $this->getMemberUpdateSql();
$qb->set('level', $qb->createNamedParameter($member->getLevel()));
$qb->limitToMemberId($member->getId());
$qb->limitToCircleId($member->getCircleId());
$qb->limitToSingleId($member->getSingleId());
$qb->execute();
}
/**
* @param string $singleId
* @param IFederatedUser|null $initiator
* @param MemberProbe|null $probe
*
* @return Member[]
* @throws RequestBuilderException
*/
public function getMembers(
string $singleId,
?IFederatedUser $initiator = null,
?MemberProbe $probe = null
): array {
if (is_null($probe)) {
$probe = new MemberProbe();
}
$qb = $this->getMemberSelectSql($initiator);
$qb->limitToCircleId($singleId);
$qb->setOptions(
[CoreQueryBuilder::MEMBER],
array_merge(
$probe->getAsOptions(),
['viewableThroughKeyhole' => true]
)
);
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER, $initiator);
$qb->leftJoinInvitedBy(CoreQueryBuilder::MEMBER);
if ($probe->hasFilterRemoteInstance()) {
$aliasCircle = $qb->generateAlias(CoreQueryBuilder::MEMBER, CoreQueryBuilder::CIRCLE);
$qb->limitToRemoteInstance(
CoreQueryBuilder::MEMBER,
$probe->getFilterRemoteInstance(),
true,
$aliasCircle
);
}
if ($probe->hasFilterMember()) {
$qb->filterDirectMembership(CoreQueryBuilder::MEMBER, $probe->getFilterMember());
}
$qb->orderBy($qb->getDefaultSelectAlias() . '.level', 'desc');
$qb->addOrderBy($qb->getDefaultSelectAlias() . '.cached_name', 'asc');
return $this->getItemsFromRequest($qb);
}
/**
* @param string $singleId
* @param bool $getData
* @param int $level
*
* @return Member[]
* @throws RequestBuilderException
*/
public function getInheritedMembers(string $singleId, bool $getData = false, int $level = 0): array {
$qb = $this->getMemberSelectSql(null, $getData);
if ($getData) {
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER);
$qb->setOptions([CoreQueryBuilder::MEMBER], ['getData' => $getData]);
}
$qb->limitToMembersByInheritance(CoreQueryBuilder::MEMBER, $singleId, $level);
$aliasMembership = $qb->generateAlias(CoreQueryBuilder::MEMBER, CoreQueryBuilder::MEMBERSHIPS);
$qb->orderBy($aliasMembership . '.inheritance_depth', 'asc');
return $this->getItemsFromRequest($qb);
}
/**
* @param string $circleId
* @param string $singleId
* @param CircleProbe|null $probe
*
* @return Member
* @throws MemberNotFoundException
* @throws RequestBuilderException
*/
public function getMember(string $circleId, string $singleId, ?CircleProbe $probe = null): Member {
$qb = $this->getMemberSelectSql();
$qb->limitToCircleId($circleId);
$qb->limitToSingleId($singleId);
if (!is_null($probe)) {
$qb->setOptions([CoreQueryBuilder::MEMBER], $probe->getAsOptions());
}
return $this->getItemFromRequest($qb);
}
/**
* @param string $memberId
* @param FederatedUser|null $initiator
* @param MemberProbe|null $probe
*
* @return Member
* @throws MemberNotFoundException
* @throws RequestBuilderException
*/
public function getMemberById(
string $memberId,
?FederatedUser $initiator = null,
?MemberProbe $probe = null
): Member {
if (is_null($probe)) {
$probe = new MemberProbe();
}
$qb = $this->getMemberSelectSql();
$qb->limitToMemberId($memberId);
$qb->setOptions([CoreQueryBuilder::MEMBER], $probe->getAsOptions());
if (!is_null($initiator)) {
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER, $initiator);
}
return $this->getItemFromRequest($qb);
}
/**
* @param string $circleId
*
* @return array
* @throws RequestBuilderException
*/
public function getMemberInstances(string $circleId): array {
$qb = $this->getMemberSelectSql();
$qb->limitToCircleId($circleId);
$qb->andwhere($qb->expr()->nonEmptyString(CoreQueryBuilder::MEMBER . '.instance'));
return array_map(
function (Member $member): string {
return $member->getInstance();
}, $this->getItemsFromRequest($qb)
);
}
/**
* @param string $singleId
*
* @return Member[]
* @throws RequestBuilderException
*/
public function getMembersBySingleId(string $singleId): array {
$qb = $this->getMemberSelectSql();
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER);
$qb->limitToSingleId($singleId);
return $this->getItemsFromRequest($qb);
}
/**
* @param Member $member
* @param FederatedUser|null $initiator
*
* @return Member
* @throws MemberNotFoundException
* @throws RequestBuilderException
*/
public function searchMember(Member $member, ?FederatedUser $initiator = null): Member {
$qb = $this->getMemberSelectSql();
$qb->limitToCircleId($member->getCircleId());
$qb->limitToSingleId($member->getSingleId());
$qb->leftJoinCircle(CoreQueryBuilder::MEMBER, $initiator);
return $this->getItemFromRequest($qb);
}
/**
* @param string $needle
*
* @return FederatedUser[]
* @throws RequestBuilderException
*/
public function searchFederatedUsers(string $needle): array {
$qb = $this->getMemberSelectSql();
$qb->searchInDBField('user_id', '%' . $needle . '%');
return $this->getItemsFromRequest($qb, true);
}
/**
* @param IFederatedUser $federatedUser
*
* @return Member[]
* @throws RequestBuilderException
*/
public function getAlternateSingleId(IFederatedUser $federatedUser): array {
$qb = $this->getMemberSelectSql();
$qb->limitToSingleId($federatedUser->getSingleId());
$qb->leftJoinRemoteInstance(CoreQueryBuilder::MEMBER);
// $expr = $qb->expr();
// $orX = $expr->orX(
// $qb->exprFilter('user_id', $federatedUser->getUserId()),
// $qb->exprFilterInt('user_type', $federatedUser->getUserType()),
// $qb->exprFilter('instance', $qb->getInstance($federatedUser), '', false)
// );
//
// $qb->andWhere($orX);
return $this->getItemsFromRequest($qb);
}
}
@@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\MemberNotFoundException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
/**
* Class MemberRequestBuilder
*
* @package OCA\Circles\Db
*/
class MemberRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getMemberInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_MEMBER)
->setValue('joined', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getMemberUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_MEMBER);
return $qb;
}
/**
* @param IFederatedUser|null $initiator
* @param bool $getBasedOn
*
* @return CoreQueryBuilder
* @throws RequestBuilderException
*/
protected function getMemberSelectSql(
?IFederatedUser $initiator = null,
bool $getBasedOn = true
): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(
self::TABLE_MEMBER,
self::$tables[self::TABLE_MEMBER],
CoreQueryBuilder::MEMBER
)
->orderBy(CoreQueryBuilder::MEMBER . '.joined');
if ($getBasedOn) {
$qb->leftJoinBasedOn(CoreQueryBuilder::MEMBER, $initiator);
}
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getMemberDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_MEMBER);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Member
* @throws MemberNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): Member {
/** @var Member $member */
try {
$member = $qb->asItem(Member::class);
} catch (RowNotFoundException $e) {
throw new MemberNotFoundException();
}
return $member;
}
/**
* @param CoreQueryBuilder $qb
* @param bool $asFederatedUser
*
* @return Member[]|FederatedUser[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb, bool $asFederatedUser = false): array {
$object = Member::class;
if ($asFederatedUser) {
$object = FederatedUser::class;
}
/** @var Member|FederatedUser[] $result */
return $qb->asItems($object);
}
}
@@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\MembershipNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Membership;
use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* Class MembershipRequest
*
* @package OCA\Circles\Db
*/
class MembershipRequest extends MembershipRequestBuilder {
/**
* @param Membership $membership
*/
public function insert(Membership $membership) {
$qb = $this->getMembershipInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($membership->getCircleId()));
$qb->setValue('single_id', $qb->createNamedParameter($membership->getSingleId()));
$qb->setValue('level', $qb->createNamedParameter($membership->getLevel()));
$qb->setValue('inheritance_first', $qb->createNamedParameter($membership->getInheritanceFirst()));
$qb->setValue('inheritance_last', $qb->createNamedParameter($membership->getInheritanceLast()));
$qb->setValue(
'inheritance_path',
$qb->createNamedParameter(json_encode($membership->getInheritancePath(), JSON_UNESCAPED_SLASHES))
);
$qb->setValue('inheritance_depth', $qb->createNamedParameter($membership->getInheritanceDepth()));
$qb->execute();
}
/**
* @param Membership $membership
*/
public function update(Membership $membership) {
$qb = $this->getMembershipUpdateSql();
$qb->set('level', $qb->createNamedParameter($membership->getLevel()));
$qb->set('inheritance_last', $qb->createNamedParameter($membership->getInheritanceLast()));
$qb->set('inheritance_first', $qb->createNamedParameter($membership->getInheritanceFirst()));
$qb->set(
'inheritance_path',
$qb->createNamedParameter(json_encode($membership->getInheritancePath(), JSON_UNESCAPED_SLASHES))
);
$qb->set('inheritance_depth', $qb->createNamedParameter($membership->getInheritanceDepth()));
$qb->limitToSingleId($membership->getSingleId());
$qb->limitToCircleId($membership->getCircleId());
$qb->execute();
}
/**
* @param string $circleId
* @param string $singleId
*
* @return Membership
* @throws MembershipNotFoundException
*/
public function getMembership(string $circleId, string $singleId): Membership {
$qb = $this->getMembershipSelectSql();
$qb->limitToCircleId($circleId);
$qb->limitToSingleId($singleId);
$qb->leftJoinCircleConfig(self::TABLE_MEMBERSHIP);
return $this->getItemFromRequest($qb);
}
/**
* @param string $singleId
*
* @return Membership[]
*/
public function getMemberships(string $singleId): array {
$qb = $this->getMembershipSelectSql();
$qb->limitToSingleId($singleId);
$qb->leftJoinCircleConfig(CoreQueryBuilder::MEMBERSHIPS);
return $this->getItemsFromRequest($qb);
}
/**
* @param string $singleId
* @param int $level
*
* @return Membership[]
*/
public function getInherited(string $singleId, int $level = 0): array {
$qb = $this->getMembershipSelectSql();
$qb->limitToCircleId($singleId);
$qb->leftJoinCircleConfig(self::TABLE_MEMBERSHIP);
if ($level > 1) {
$expr = $qb->expr();
$qb->andWhere($expr->gte('level', $qb->createNamedParameter($level, IQueryBuilder::PARAM_INT)));
}
return $this->getItemsFromRequest($qb);
}
/**
* @param string $singleId
* @param bool $all
*
* @return void
*/
public function removeBySingleId(string $singleId, bool $all = false): void {
$qb = $this->getMembershipDeleteSql();
if (!$all) {
$qb->limitToSingleId($singleId);
}
$qb->execute();
}
/**
* @param Membership $membership
*/
public function delete(Membership $membership): void {
$qb = $this->getMembershipDeleteSql();
$qb->limitToSingleId($membership->getSingleId());
$qb->limitToCircleId($membership->getCircleId());
$qb->execute();
}
/**
* @param FederatedUser $federatedUser
*/
public function deleteFederatedUser(FederatedUser $federatedUser): void {
$qb = $this->getMembershipDeleteSql();
$qb->limitToSingleId($federatedUser->getSingleId());
$qb->execute();
}
}
@@ -0,0 +1,120 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\MembershipNotFoundException;
use OCA\Circles\Model\Membership;
/**
* Class MembershipRequestBuilder
*
* @package OCA\Circles\Db
*/
class MembershipRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getMembershipInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_MEMBERSHIP);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getMembershipUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_MEMBERSHIP);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getMembershipSelectSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(
self::TABLE_MEMBERSHIP,
self::$tables[self::TABLE_MEMBERSHIP],
CoreQueryBuilder::MEMBERSHIPS
);
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getMembershipDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_MEMBERSHIP);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Membership
* @throws MembershipNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): Membership {
/** @var Membership $membership */
try {
$membership = $qb->asItem(Membership::class);
} catch (RowNotFoundException $e) {
throw new MembershipNotFoundException();
}
return $membership;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Membership[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var Membership[] $result */
return $qb->asItems(Membership::class);
}
}
@@ -0,0 +1,285 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Traits\TStringTools;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\IFederatedUser;
use OCA\Circles\Model\Mount;
/**
* Class MountRequest
*
* @package OCA\Circles\Db
*/
class MountRequest extends MountRequestBuilder {
use TStringTools;
/**
* @param Mount $mount
*/
public function save(Mount $mount): void {
$qb = $this->getMountInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($mount->getCircleId()))
->setValue('mount_id', $qb->createNamedParameter($mount->getMountId()))
->setValue('single_id', $qb->createNamedParameter($mount->getOwner()->getSingleId()))
->setValue('token', $qb->createNamedParameter($mount->getToken()))
->setValue('parent', $qb->createNamedParameter($mount->getParent()))
->setValue('mountpoint', $qb->createNamedParameter($mount->getMountPoint()))
->setValue('mountpoint_hash', $qb->createNamedParameter(md5($mount->getMountPoint())));
$qb->execute();
}
/**
* @param string $token
*/
public function delete(string $token): void {
$qb = $this->getMountDeleteSql();
$qb->limitToToken($token);
$qb->execute();
}
/**
* @param IFederatedUser $federatedUser
*
* @return Mount[]
* @throws RequestBuilderException
*/
public function getForUser(IFederatedUser $federatedUser): array {
$qb = $this->getMountSelectSql();
$qb->setOptions([CoreQueryBuilder::MOUNT], ['getData' => true]);
$qb->leftJoinMember(CoreQueryBuilder::MOUNT);
$qb->leftJoinMountpoint(CoreQueryBuilder::MOUNT);
$qb->limitToInitiator(CoreQueryBuilder::MOUNT, $federatedUser, 'circle_id');
return $this->getItemsFromRequest($qb);
// FederatedUser $federatedUser,
// int $nodeId,
// int $offset,
// int $limit,
// bool $getData = false
// ): array {
// $qb = $this->getShareSelectSql();
// $qb->setOptions([CoreRequestBuilder::SHARE], ['getData' => $getData]);
// if ($getData) {
// $qb->leftJoinCircle(CoreRequestBuilder::SHARE, null, 'share_with');
// }
//
// $qb->limitToInitiator(CoreRequestBuilder::SHARE, $federatedUser, 'share_with');
//
// $qb->leftJoinFileCache(CoreRequestBuilder::SHARE);
// $qb->limitToDBFieldEmpty('parent', true);
// $qb->leftJoinShareChild(CoreRequestBuilder::SHARE);
//
// if ($nodeId > 0) {
// $qb->limitToFileSource($nodeId);
// }
//
// $qb->chunk($offset, $limit);
//
// return $this->getItemsFromRequest($qb);
// $this->joinMembership($qb, $userId);
// $this->leftJoinMountPoint($qb, $userId);
// $shares = [];
// $cursor = $qb->execute();
// while ($data = $cursor->fetch()) {
// $shares[] = $this->parseGSSharesSelectSql($data);
// }
// $cursor->closeCursor();
//
// return $shares;
}
// /**
// * @param string $userId
// *
// * @return Mount[]
// */
// public function getForUser(string $userId): array {
// $qb = $this->getMountSelectSql();
//
// $this->
// $this->joinMembership($qb, $userId);
// $this->leftJoinMountPoint($qb, $userId);
//
// $shares = [];
// $cursor = $qb->execute();
// while ($data = $cursor->fetch()) {
// $shares[] = $this->parseGSSharesSelectSql($data);
// }
// $cursor->closeCursor();
//
// return $shares;
// }
//
// /**
// * @param DeprecatedMember $member
// */
// public function removeGSSharesFromMember(DeprecatedMember $member) {
// $qb = $this->getMountDeleteSql();
// $this->limitToCircleId($qb, $member->getCircleId());
// $this->limitToInstance($qb, $member->getInstance());
// $this->limitToOwner($qb, $member->getUserId());
//
// $qb->execute();
// }
//
//
// /**
// * @param IQueryBuilder $qb
// * @param string $userId
// */
// private function joinMembership(IQueryBuilder $qb, string $userId) {
// $qb->from(DeprecatedRequestBuilder::TABLE_MEMBERS, 'm');
//
// $expr = $qb->expr();
// $andX = $expr->andX();
//
// $andX->add($expr->eq('m.user_id', $qb->createNamedParameter($userId)));
// $andX->add($expr->eq('m.instance', $qb->createNamedParameter('')));
// $andX->add($expr->gt('m.level', $qb->createNamedParameter(0)));
// $andX->add($expr->eq('m.user_type', $qb->createNamedParameter(DeprecatedMember::TYPE_USER)));
// $andX->add($expr->eq('m.circle_id', 'gsh.circle_id'));
//
// $qb->andWhere($andX);
// }
//
//
// private function leftJoinMountPoint(IQueryBuilder $qb, string $userId) {
// $expr = $qb->expr();
// $pf = '' . $this->default_select_alias . '.';
//
// $on = $expr->andX();
// $on->add($expr->eq('mp.user_id', $qb->createNamedParameter($userId)));
// $on->add($expr->eq('mp.share_id', $pf . 'id'));
//
// /** @noinspection PhpMethodParametersCountMismatchInspection */
// $qb->selectAlias('mp.mountPoint', 'gsshares_mountpoint')
// ->leftJoin($this->default_select_alias, DeprecatedRequestBuilder::TABLE_GSSHARES_MOUNTPOINT, 'mp', $on);
// }
//
//
// /**
// * @param string $userId
// * @param string $target
// *
// * @return GSShareMountpoint
// * @throws ShareNotFound
// */
// public function getShareMountPointByPath(string $userId, string $target): GSShareMountpoint {
// $qb = $this->getMountMountpointSelectSql();
//
// $targetHash = md5($target);
// $this->limitToUserId($qb, $userId);
// $this->limitToMountpointHash($qb, $targetHash);
//
// $shares = [];
// $cursor = $qb->execute();
// $data = $cursor->fetch();
//
// if ($data === false) {
// throw new ShareNotFound();
// }
//
// return $this->parseGSSharesMountpointSelectSql($data);
// }
//
//
// /**
// * @param int $gsShareId
// * @param string $userId
// *
// * @return GSShareMountpoint
// * @throws ShareNotFound
// */
// public function getShareMountPointById(int $gsShareId, string $userId): GSShareMountpoint {
// $qb = $this->getMountMountpointSelectSql();
//
// $this->limitToShareId($qb, $gsShareId);
// $this->limitToUserId($qb, $userId);
//
// $shares = [];
// $cursor = $qb->execute();
// $data = $cursor->fetch();
// if ($data === false) {
// throw new ShareNotFound();
// }
//
// return $this->parseGSSharesMountpointSelectSql($data);
// }
//
//
// /**
// * @param GSShareMountpoint $mountpoint
// */
// public function generateShareMountPoint(GSShareMountpoint $mountpoint) {
// $qb = $this->getMountMountpointInsertSql();
//
// $hash = ($mountpoint->getMountPoint() === '-') ? '' : md5($mountpoint->getMountPoint());
//
// $qb->setValue('user_id', $qb->createNamedParameter($mountpoint->getUserId()))
// ->setValue('share_id', $qb->createNamedParameter($mountpoint->getShareId()))
// ->setValue('mountpoint', $qb->createNamedParameter($mountpoint->getMountPoint()))
// ->setValue('mountpoint_hash', $qb->createNamedParameter($hash));
// $qb->execute();
// }
//
//
// /**
// * @param GSShareMountpoint $mountpoint
// *
// * @return bool
// */
// public function updateShareMountPoint(GSShareMountpoint $mountpoint) {
// $qb = $this->getMountMountpointUpdateSql();
//
// $hash = ($mountpoint->getMountPoint() === '-') ? '' : md5($mountpoint->getMountPoint());
//
// $qb->set('mountpoint', $qb->createNamedParameter($mountpoint->getMountPoint()))
// ->set('mountpoint_hash', $qb->createNamedParameter($hash));
//
// $this->limitToShareId($qb, $mountpoint->getShareId());
// $this->limitToUserId($qb, $mountpoint->getUserId());
// $nb = $qb->execute();
//
// return ($nb === 1);
// }
//
}
@@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\MountNotFoundException;
use OCA\Circles\Model\Mount;
/**
* Class MountRequestBuilder
*
* @package OCA\Circles\Db
*/
class MountRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getMountInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_MOUNT);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getMountUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_MOUNT);
return $qb;
}
/**
* @param string $alias
*
* @return CoreQueryBuilder
*/
protected function getMountSelectSql(string $alias = CoreQueryBuilder::MOUNT): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(self::TABLE_MOUNT, self::$tables[self::TABLE_MOUNT], $alias);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getMountDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_MOUNT);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Mount
* @throws MountNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): Mount {
/** @var Mount $circle */
try {
$circle = $qb->asItem(Mount::class);
} catch (RowNotFoundException $e) {
throw new MountNotFoundException('Mount not found');
}
return $circle;
}
/**
* @param CoreQueryBuilder $qb
*
* @return Mount[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var Mount[] $result */
return $qb->asItems(Mount::class);
}
}
@@ -0,0 +1,286 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\RemoteNotFoundException;
use OCA\Circles\Exceptions\RemoteUidException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Model\Circle;
use OCA\Circles\Model\Federated\RemoteInstance;
use OCA\Circles\Model\Member;
use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* Class RemoteRequest
*
* @package OCA\Circles\Db
*/
class RemoteRequest extends RemoteRequestBuilder {
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function save(RemoteInstance $remote): void {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteInsertSql();
$qb->setValue('uid', $qb->createNamedParameter($remote->getUid(true)))
->setValue('instance', $qb->createNamedParameter($remote->getInstance()))
->setValue('href', $qb->createNamedParameter($remote->getId()))
->setValue('type', $qb->createNamedParameter($remote->getType()))
->setValue('interface', $qb->createNamedParameter($remote->getInterface()))
->setValue('item', $qb->createNamedParameter(json_encode($remote->getOrigData())));
$qb->execute();
}
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function update(RemoteInstance $remote) {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteUpdateSql();
$qb->set('uid', $qb->createNamedParameter($remote->getUid(true)))
->set('href', $qb->createNamedParameter($remote->getId()))
->set('type', $qb->createNamedParameter($remote->getType()))
->set('item', $qb->createNamedParameter(json_encode($remote->getOrigData())));
$qb->limitToInstance($remote->getInstance());
$qb->execute();
}
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function updateItem(RemoteInstance $remote) {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteUpdateSql();
$qb->set('item', $qb->createNamedParameter(json_encode($remote->getOrigData())));
$qb->limit('uid', $remote->getUid(true), '', false);
$qb->execute();
}
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function updateInstance(RemoteInstance $remote) {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteUpdateSql();
$qb->set('instance', $qb->createNamedParameter($remote->getInstance()));
$qb->limit('uid', $remote->getUid(true), '', false);
$qb->execute();
}
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function updateType(RemoteInstance $remote) {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteUpdateSql();
$qb->set('type', $qb->createNamedParameter($remote->getType()));
$qb->limit('uid', $remote->getUid(true), '', false);
$qb->execute();
}
/**
* @param RemoteInstance $remote
*
* @throws RemoteUidException
*/
public function updateHref(RemoteInstance $remote) {
$remote->mustBeIdentityAuthed();
$qb = $this->getRemoteUpdateSql();
$qb->set('href', $qb->createNamedParameter($remote->getId()));
$qb->limit('uid', $remote->getUid(true), '', false);
$qb->execute();
}
/**
* @return RemoteInstance[]
*/
public function getAllInstances(): array {
$qb = $this->getRemoteSelectSql();
return $this->getItemsFromRequest($qb);
}
/**
* @return RemoteInstance[]
*/
public function getKnownInstances(): array {
$qb = $this->getRemoteSelectSql();
$qb->filter('type', RemoteInstance::TYPE_UNKNOWN, '', false);
return $this->getItemsFromRequest($qb);
}
/**
* - returns:
* - all GLOBAL_SCALE
* - TRUSTED if Circle is Federated
* - EXTERNAL if Circle is Federated and a contains a member from instance
*
* @param Circle $circle
* @param bool $broadcastAsFederated
*
* @return RemoteInstance[]
* @throws RequestBuilderException
*/
public function getOutgoingRecipient(Circle $circle, bool $broadcastAsFederated = false): array {
$qb = $this->getRemoteSelectSql();
$expr = $qb->expr();
$orX = $expr->orX();
$orX->add($qb->exprLimit('type', RemoteInstance::TYPE_GLOBALSCALE, '', false));
if ($circle->isConfig(Circle::CFG_FEDERATED) || $broadcastAsFederated) {
// get all TRUSTED
$orX->add($qb->exprLimit('type', RemoteInstance::TYPE_TRUSTED, '', false));
// get EXTERNAL with Members
$aliasMember = $qb->generateAlias(CoreQueryBuilder::REMOTE, CoreQueryBuilder::MEMBER);
$qb->leftJoin(
CoreQueryBuilder::REMOTE, self::TABLE_MEMBER, $aliasMember,
$expr->andX(
$expr->eq($aliasMember . '.circle_id', $qb->createNamedParameter($circle->getSingleId())),
$expr->eq($aliasMember . '.instance', CoreQueryBuilder::REMOTE . '.instance'),
$expr->gte(
$aliasMember . '.level',
$qb->createNamedParameter(Member::LEVEL_MEMBER, IQueryBuilder::PARAM_INT)
)
)
);
$external = $expr->andX();
$external->add($qb->exprLimit('type', RemoteInstance::TYPE_EXTERNAL, '', false));
$external->add($expr->isNotNull($aliasMember . '.instance'));
$orX->add($external);
}
$qb->andWhere($orX);
return $this->getItemsFromRequest($qb);
}
/**
* @param string $host
*
* @return RemoteInstance
* @throws RemoteNotFoundException
*/
public function getFromInstance(string $host): RemoteInstance {
$qb = $this->getRemoteSelectSql();
$qb->limitToInstance($host);
return $this->getItemFromRequest($qb);
}
/**
* @param string $href
*
* @return RemoteInstance
* @throws RemoteNotFoundException
*/
public function getFromHref(string $href): RemoteInstance {
$qb = $this->getRemoteSelectSql();
$qb->limit('href', $href, '', false);
return $this->getItemFromRequest($qb);
}
/**
* @param string $status
*
* @return RemoteInstance[]
*/
public function getFromType(string $status): array {
$qb = $this->getRemoteSelectSql();
$qb->limitToTypeString($status);
return $this->getItemsFromRequest($qb);
}
/**
* @param RemoteInstance $remoteInstance
*
* @return RemoteInstance
* @throws RemoteNotFoundException
*/
public function searchDuplicate(RemoteInstance $remoteInstance): RemoteInstance {
$qb = $this->getRemoteSelectSql();
$orX = $qb->expr()->orX();
$orX->add($qb->exprLimit('href', $remoteInstance->getId(), '', false));
$orX->add($qb->exprLimit('uid', $remoteInstance->getUid(true), '', false));
$orX->add($qb->exprLimit('instance', $remoteInstance->getInstance(), '', false));
$qb->andWhere($orX);
return $this->getItemFromRequest($qb);
}
/**
* @param RemoteInstance $remoteInstance
*/
public function deleteById(RemoteInstance $remoteInstance) {
$qb = $this->getRemoteDeleteSql();
$qb->limitToId($remoteInstance->getDbId());
$qb->execute();
}
}
@@ -0,0 +1,121 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\RemoteNotFoundException;
use OCA\Circles\Model\Federated\RemoteInstance;
/**
* Class RemoteRequestBuilder
*
* @package OCA\Circles\Db
*/
class RemoteRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getRemoteInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_REMOTE)
->setValue('creation', $qb->createNamedParameter($this->timezoneService->getUTCDate()));
return $qb;
}
/**
* Base of the Sql Update request for Groups
*
* @return CoreQueryBuilder
*/
protected function getRemoteUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_REMOTE);
return $qb;
}
/**
* @param string $alias
*
* @return CoreQueryBuilder
*/
protected function getRemoteSelectSql(string $alias = CoreQueryBuilder::REMOTE): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(self::TABLE_REMOTE, self::$tables[self::TABLE_REMOTE], $alias);
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getRemoteDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_REMOTE);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return RemoteInstance
* @throws RemoteNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): RemoteInstance {
/** @var RemoteInstance $appService */
try {
$appService = $qb->asItem(RemoteInstance::class);
} catch (RowNotFoundException $e) {
throw new RemoteNotFoundException('Unknown remote instance');
}
return $appService;
}
/**
* @param CoreQueryBuilder $qb
*
* @return RemoteInstance[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var RemoteInstance[] $result */
return $qb->asItems(RemoteInstance::class);
}
}
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\FederatedShareNotFoundException;
use OCA\Circles\Exceptions\InvalidIdException;
use OCA\Circles\Model\Federated\FederatedShare;
/**
* Class ShareRequest
*
* @package OCA\Circles\Db
*/
class ShareLockRequest extends ShareLockRequestBuilder {
/**
* @param FederatedShare $share
*
* @throws InvalidIdException
*/
public function save(FederatedShare $share): void {
$this->confirmValidIds([$share->getItemId()]);
$qb = $this->getShareLockInsertSql();
$qb->setValue('item_id', $qb->createNamedParameter($share->getItemId()))
->setValue('circle_id', $qb->createNamedParameter($share->getCircleId()))
->setValue('instance', $qb->createNamedParameter($qb->getInstance($share)));
$qb->execute();
}
/**
* @param string $itemId
* @param string $circleId
*
* @return FederatedShare
* @throws FederatedShareNotFoundException
*/
public function getShare(string $itemId, string $circleId = ''): FederatedShare {
$qb = $this->getShareLockSelectSql();
$qb->limitToItemId($itemId);
if ($circleId !== '') {
$qb->limitToCircleId($circleId);
}
return $this->getItemFromRequest($qb);
}
}
@@ -0,0 +1,117 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\FederatedShareNotFoundException;
use OCA\Circles\Model\Federated\FederatedShare;
/**
* Class ShareRequestBuilder
*
* @package OCA\Circles\Db
*/
class ShareLockRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getShareLockInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_SHARE_LOCK);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getShareLockSelectSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->select('s.id', 's.item_id', 's.circle_id', 's.instance')
->from(self::TABLE_SHARE_LOCK, 's')
->setDefaultSelectAlias('s');
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getShareLockUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_SHARE_LOCK);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getShareDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_SHARE_LOCK);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return FederatedShare
* @throws FederatedShareNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): FederatedShare {
/** @var FederatedShare $circle */
try {
$circle = $qb->asItem(FederatedShare::class);
} catch (RowNotFoundException $e) {
throw new FederatedShareNotFoundException();
}
return $circle;
}
/**
* @param CoreQueryBuilder $qb
*
* @return FederatedShare[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var FederatedShare[] $result */
return $qb->asItems(FederatedShare::class);
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Exceptions\ShareTokenNotFoundException;
use OCA\Circles\Model\ShareToken;
/**
* Class ShareTokenRequest
*
* @package OCA\Circles\Db
*/
class ShareTokenRequest extends ShareTokenRequestBuilder {
/**
* @param ShareToken $token
*
* @return void
*/
public function save(ShareToken $token): void {
$qb = $this->getTokenInsertSql();
$qb->setValue('share_id', $qb->createNamedParameter($token->getShareId()))
->setValue('circle_id', $qb->createNamedParameter($token->getCircleId()))
->setValue('single_id', $qb->createNamedParameter($token->getSingleId()))
->setValue('member_id', $qb->createNamedParameter($token->getMemberId()))
->setValue('token', $qb->createNamedParameter($token->getToken()))
->setValue('password', $qb->createNamedParameter($token->getPassword()))
->setValue('accepted', $qb->createNamedParameter($token->getAccepted()));
$qb->execute();
$id = $qb->getLastInsertId();
$token->setDbId($id);
}
/**
* @param ShareToken $shareToken
*
* @return ShareToken
* @throws ShareTokenNotFoundException
*/
public function search(ShareToken $shareToken): ShareToken {
$qb = $this->getTokenSelectSql();
$qb->limitInt('share_id', $shareToken->getshareId());
$qb->limitToCircleId($shareToken->getCircleId());
$qb->limitToSingleId($shareToken->getSingleId());
return $this->getItemFromRequest($qb);
}
/**
* @param string $token
*
* @return ShareToken
* @throws ShareTokenNotFoundException
*/
public function getByToken(string $token): ShareToken {
$qb = $this->getTokenSelectSql();
$qb->limitToToken($token);
return $this->getItemFromRequest($qb);
}
/**
* @param string $circleId
* @param string $hashedPassword
*/
public function updateSharePassword(string $circleId, string $hashedPassword) {
$qb = $this->getTokenUpdateSql();
$qb->limitToCircleId($circleId);
$qb->set('password', $qb->createNamedParameter($hashedPassword));
$qb->executeStatement();
}
/**
* @param string $singleId
* @param string $circleId
*/
public function removeTokens(string $singleId, string $circleId) {
$qb = $this->getTokenDeleteSql();
$qb->limitToSingleId($singleId);
$qb->limitToCircleId($circleId);
$qb->execute();
}
}
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\ShareTokenNotFoundException;
use OCA\Circles\Model\ShareToken;
/**
* Class ShareTokenRequestBuilder
*
* @package OCA\Circles\Db
*/
class ShareTokenRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getTokenInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_TOKEN);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getTokenUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_TOKEN);
return $qb;
}
/**
* @param string $alias
*
* @return CoreQueryBuilder
*/
protected function getTokenSelectSql(string $alias = CoreQueryBuilder::TOKEN): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(self::TABLE_TOKEN, self::$tables[self::TABLE_TOKEN], $alias);
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getTokenDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_TOKEN);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return ShareToken
* @throws ShareTokenNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): ShareToken {
/** @var ShareToken $shareToken */
try {
$shareToken = $qb->asItem(ShareToken::class);
} catch (RowNotFoundException $e) {
throw new ShareTokenNotFoundException();
}
return $shareToken;
}
/**
* @param CoreQueryBuilder $qb
*
* @return ShareToken[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var ShareToken[] $result */
return $qb->asItems(ShareToken::class);
}
}
@@ -0,0 +1,523 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use JsonException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Membership;
use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\Share\Exceptions\IllegalIDChangeException;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
/**
* Class ShareWrapperRequest
*
* @package OCA\Circles\Db
*/
class ShareWrapperRequest extends ShareWrapperRequestBuilder {
/**
* @param IShare $share
* @param int $parentId
*
* @return int
* @throws NotFoundException
*/
public function save(IShare $share, int $parentId = 0): int {
// $hasher = \OC::$server->getHasher();
// $password = ($share->getPassword() !== null) ? $hasher->hash($share->getPassword()) : '';
$password = '';
$qb = $this->getShareInsertSql();
$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()))
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->setValue('password', $qb->createNamedParameter($password))
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
->setValue('token', $qb->createNamedParameter($share->getToken()))
->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
if ($parentId > 0) {
$qb->setValue('parent', $qb->createNamedParameter($parentId));
}
$qb->execute();
$id = $qb->getLastInsertId();
try {
$share->setId($id);
} catch (IllegalIDChangeException $e) {
}
return $id;
}
/**
* @param ShareWrapper $shareWrapper
*/
public function update(ShareWrapper $shareWrapper): void {
$qb = $this->getShareUpdateSql();
$shareAttributes = $this->formatShareAttributes($shareWrapper->getAttributes());
$qb->set('file_target', $qb->createNamedParameter($shareWrapper->getFileTarget()))
->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()))
->set('expiration', $qb->createNamedParameter($shareWrapper->getExpirationDate(), IQueryBuilder::PARAM_DATE))
->set('attributes', $qb->createNamedParameter($shareAttributes));
$qb->limitToId((int)$shareWrapper->getId());
$qb->execute();
}
/**
* @param Membership $membership
*/
public function deleteByMembership(Membership $membership) {
$qb = $this->getShareDeleteSql();
$qb->limitToShareWith($membership->getCircleId());
$qb->limit('uid_initiator', $membership->getSingleId());
$qb->execute();
}
/**
* @return array
*/
public function getShares(): array {
$qb = $this->getShareSelectSql();
return $this->getItemsFromRequest($qb);
}
/**
* @param string $circleId
* @param FederatedUser|null $shareRecipient
* @param FederatedUser|null $shareInitiator
* @param bool $completeDetails
*
* @return ShareWrapper[]
* @throws RequestBuilderException
*/
public function getSharesToCircle(
string $circleId,
?FederatedUser $shareRecipient = null,
?FederatedUser $shareInitiator = null,
bool $completeDetails = false
): array {
$qb = $this->getShareSelectSql();
$qb->limitNull('parent', false);
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => true]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
// TODO: filter direct-shares ?
$aliasUpstreamMembership =
$qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::UPSTREAM_MEMBERSHIPS);
$qb->limitToInheritedMemberships(CoreQueryBuilder::SHARE, $circleId, 'share_with');
// if (!is_null($shareRecipient)) {
// $qb->limitToInitiator(CoreRequestBuilder::SHARE, $shareRecipient, 'share_with');
// }
// TODO: add shareInitiator and shareRecipient to filter the request
if (!is_null($shareRecipient) || $completeDetails) {
$qb->leftJoinInheritedMembers(
$aliasUpstreamMembership,
'circle_id',
$qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::INHERITED_BY)
);
$aliasMembership = $qb->generateAlias($aliasUpstreamMembership, CoreQueryBuilder::MEMBERSHIPS);
$qb->leftJoinFileCache(CoreQueryBuilder::SHARE);
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE, $aliasMembership);
}
return $this->getItemsFromRequest($qb);
}
/**
* @param int $shareId
* @param FederatedUser|null $federatedUser
*
* @return ShareWrapper
* @throws ShareWrapperNotFoundException
* @throws RequestBuilderException
*/
public function getShareById(int $shareId, ?FederatedUser $federatedUser = null): ShareWrapper {
$qb = $this->getShareSelectSql();
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => true]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$qb->limitToId($shareId);
if (!is_null($federatedUser)) {
$qb->limitToInitiator(CoreQueryBuilder::SHARE, $federatedUser, 'share_with');
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE);
}
return $this->getItemFromRequest($qb);
}
/**
* @param string $token
* @param FederatedUser|null $federatedUser
*
* @return ShareWrapper
* @throws RequestBuilderException
* @throws ShareWrapperNotFoundException
*/
public function getShareByToken(string $token, ?FederatedUser $federatedUser = null): ShareWrapper {
$qb = $this->getShareSelectSql();
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => true]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$qb->limitToShareToken(CoreQueryBuilder::SHARE, $token);
if (!is_null($federatedUser)) {
$qb->limitToInitiator(CoreQueryBuilder::SHARE, $federatedUser, 'share_with');
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE);
}
return $this->getItemFromRequest($qb);
}
/**
* @param FederatedUser $federatedUser
* @param int $shareId
*
* @return ShareWrapper
* @throws ShareWrapperNotFoundException
*/
public function getChild(FederatedUser $federatedUser, int $shareId): ShareWrapper {
$qb = $this->getShareSelectSql();
$qb->limitToShareParent($shareId);
$qb->limitToShareWith($federatedUser->getSingleId());
return $this->getItemFromRequest($qb);
}
/**
* @param int $fileId
* @param bool $getData
*
* @return ShareWrapper[]
* @throws RequestBuilderException
*/
public function getSharesByFileId(int $fileId, bool $getData = false): array {
$qb = $this->getShareSelectSql();
$qb->limitToFileSource($fileId);
if ($getData) {
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => $getData]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
// $qb->leftJoinFileCache(CoreRequestBuilder::SHARE);
$qb->limitNull('parent', false);
$aliasMembership = $qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::MEMBERSHIPS);
$qb->leftJoinInheritedMembers(CoreQueryBuilder::SHARE, 'share_with');
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE);
}
return $this->getItemsFromRequest($qb);
}
/**
* @param FederatedUser $federatedUser
* @param int $nodeId
* @param int $offset
* @param int $limit
* @param bool $getData
*
* @return ShareWrapper[]
* @throws RequestBuilderException
*/
public function getSharedWith(
FederatedUser $federatedUser,
int $nodeId,
CircleProbe $probe
): array {
$qb = $this->getShareSelectSql();
$qb->setOptions(
[CoreQueryBuilder::SHARE],
array_merge(
$probe->getAsOptions(),
['getData' => true]
)
);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$aliasCircle = $qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::CIRCLE);
$qb->limitToFederatedUserMemberships(CoreQueryBuilder::SHARE, $aliasCircle, $federatedUser);
$qb->leftJoinFileCache(CoreQueryBuilder::SHARE);
$qb->limitNull('parent', false);
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE);
if ($nodeId > 0) {
$qb->limitToFileSource($nodeId);
}
$qb->chunk($probe->getItemsOffset(), $probe->getItemsLimit());
return $this->getItemsFromRequest($qb);
}
/**
* @param FederatedUser $federatedUser
* @param int $nodeId
* @param bool $reshares
* @param int $offset
* @param int $limit
* @param bool $getData
* @param bool $completeDetails
*
* @return ShareWrapper[]
* @throws RequestBuilderException
*/
public function getSharesBy(
FederatedUser $federatedUser,
int $nodeId,
bool $reshares,
int $limit,
int $offset,
bool $getData = false,
bool $completeDetails = false
): array {
$qb = $this->getShareSelectSql();
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => $getData]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$qb->limitToShareOwner(CoreQueryBuilder::SHARE, $federatedUser, $reshares);
$qb->limitNull('parent', false);
if ($nodeId > 0) {
$qb->limitToFileSource($nodeId);
}
if ($completeDetails) {
$aliasMembership = $qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::MEMBERSHIPS);
$qb->leftJoinInheritedMembers(CoreQueryBuilder::SHARE, 'share_with');
$qb->leftJoinFileCache(CoreQueryBuilder::SHARE);
$qb->leftJoinShareChild(CoreQueryBuilder::SHARE, $aliasMembership);
}
$qb->chunk($offset, $limit);
return $this->getItemsFromRequest($qb);
}
/**
* @param FederatedUser $federatedUser
* @param Folder $node
* @param bool $reshares
* @param bool $shallow Whether the method should stop at the first level, or look into sub-folders.
*
* @return ShareWrapper[]
* @throws RequestBuilderException
*/
public function getSharesInFolder(
FederatedUser $federatedUser,
Folder $node,
bool $reshares,
bool $shallow = true
): array {
$qb = $this->getShareSelectSql();
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$qb->limitToShareOwner(CoreQueryBuilder::SHARE, $federatedUser, $reshares);
$qb->leftJoinFileCache(CoreQueryBuilder::SHARE);
$aliasFileCache = $qb->generateAlias(CoreQueryBuilder::SHARE, CoreQueryBuilder::FILE_CACHE);
if ($shallow) {
$qb->limitInt('parent', $node->getId(), $aliasFileCache);
} else {
$qb->like('path', $node->getInternalPath() . '/%', $aliasFileCache);
}
$qb->limitNull('parent', false);
return $this->getItemsFromRequest($qb);
}
/**
* returns the SQL request to get a specific share from the fileId and circleId
*
* @param string $singleId
* @param int $fileId
*
* @return ShareWrapper
* @throws ShareWrapperNotFoundException
* @throws RequestBuilderException
*/
public function searchShare(string $singleId, int $fileId): ShareWrapper {
$qb = $this->getShareSelectSql();
$qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => true]);
$qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with');
$qb->limitNull('parent', false);
$qb->limitToShareWith($singleId);
$qb->limitToFileSource($fileId);
return $this->getItemFromRequest($qb);
}
/**
* @param int $shareId
*/
public function delete(int $shareId): void {
$qb = $this->getShareDeleteSql();
$qb->andWhere(
$qb->expr()->orX(
$qb->exprLimitInt('id', $shareId),
$qb->exprLimitInt('parent', $shareId),
)
);
$qb->execute();
}
/**
* @param string $circleId
* @param string $initiator
*/
public function deleteSharesToCircle(string $circleId, string $initiator = ''): void {
$qb = $this->getShareSelectSql();
$qb->limit('share_with', $circleId);
if ($initiator !== '') {
$qb->limit('uid_initiator', $initiator);
}
$ids = array_map(
function (ShareWrapper $share): string {
return $share->getId();
},
$this->getItemsFromRequest($qb)
);
$this->deleteSharesAndChild($ids);
}
public function removeOrphanShares(): void {
$qb = $this->getShareSelectSql();
$expr = $qb->expr();
$qb->leftJoin(
CoreQueryBuilder::SHARE, CoreRequestBuilder::TABLE_SHARE, 'p',
$expr->andX($expr->eq('p.id', CoreQueryBuilder::SHARE . '.parent'))
);
$qb->filterNull('parent');
$qb->limitNull('id', false, 'p');
$ids = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$ids[] = $data['id'];
}
$cursor->closeCursor();
$this->deleteSharesAndChild($ids);
}
/**
* @param array $ids
*/
private function deleteSharesAndChild(array $ids): void {
$qb = $this->getShareDeleteSql();
$qb->andWhere(
$qb->expr()->orX(
$qb->exprLimitInArray('id', $ids),
$qb->exprLimitInArray('parent', $ids)
)
);
$qb->execute();
}
/**
* Format IAttributes to database format (JSON string)
* based on OC\Share20\DefaultShareProvider::formatShareAttributes();
*/
private function formatShareAttributes(?IAttributes $attributes): ?string {
if (empty($attributes?->toArray())) {
return null;
}
$compressedAttributes = [];
foreach ($attributes->toArray() as $attribute) {
$compressedAttributes[] = [
$attribute['scope'],
$attribute['key'],
$attribute['enabled']
];
}
try {
return json_encode($compressedAttributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
return null;
}
}
}
@@ -0,0 +1,122 @@
<?php
declare(strict_types=1);
/**
* 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 2021
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Tools\Exceptions\RowNotFoundException;
use OCP\Share\IShare;
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\ShareWrapper;
/**
* Class ShareWrapperRequestBuilder
*
* @package OCA\Circles\Db
*/
class ShareWrapperRequestBuilder extends CoreRequestBuilder {
/**
* @return CoreQueryBuilder
*/
protected function getShareInsertSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->insert(self::TABLE_SHARE);
return $qb;
}
/**
* @return CoreQueryBuilder
*/
protected function getShareUpdateSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->update(self::TABLE_SHARE);
return $qb;
}
/**
* @param string $alias
*
* @return CoreQueryBuilder
*/
protected function getShareSelectSql(string $alias = CoreQueryBuilder::SHARE): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->generateSelect(self::TABLE_SHARE, self::$outsideTables[self::TABLE_SHARE], $alias)
->limitToShareType(IShare::TYPE_CIRCLE);
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return CoreQueryBuilder
*/
protected function getShareDeleteSql(): CoreQueryBuilder {
$qb = $this->getQueryBuilder();
$qb->delete(self::TABLE_SHARE)
->limitToShareType(IShare::TYPE_CIRCLE);
return $qb;
}
/**
* @param CoreQueryBuilder $qb
*
* @return ShareWrapper
* @throws ShareWrapperNotFoundException
*/
public function getItemFromRequest(CoreQueryBuilder $qb): ShareWrapper {
/** @var ShareWrapper $shareWrapper */
try {
$shareWrapper = $qb->asItem(ShareWrapper::class);
} catch (RowNotFoundException $e) {
throw new ShareWrapperNotFoundException();
}
return $shareWrapper;
}
/**
* @param CoreQueryBuilder $qb
*
* @return ShareWrapper[]
*/
public function getItemsFromRequest(CoreQueryBuilder $qb): array {
/** @var ShareWrapper[] $result */
return $qb->asItems(ShareWrapper::class);
}
}
@@ -0,0 +1,178 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCA\Circles\Exceptions\TokenDoesNotExistException;
use OCA\Circles\Model\DeprecatedMember;
use OCA\Circles\Model\SharesToken;
/**
* @deprecated
* Class TokensRequest
*
* @package OCA\Circles\Db
*/
class TokensRequest extends TokensRequestBuilder {
/**
* @param string $token
*
* @return SharesToken
* @throws TokenDoesNotExistException
*/
public function getByToken(string $token) {
$qb = $this->getTokensSelectSql();
$this->limitToToken($qb, $token);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new TokenDoesNotExistException('Unknown share token');
}
return $this->parseTokensSelectSql($data);
}
/**
* @param string $shareId
* @param string $circleId
* @param string $email
*
* @return SharesToken
* @throws TokenDoesNotExistException
*/
public function getTokenFromMember(string $shareId, string $circleId, string $email) {
$qb = $this->getTokensSelectSql();
$this->limitToShareId($qb, $shareId);
$this->limitToUserId($qb, $email);
$this->limitToCircleId($qb, $circleId);
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
throw new TokenDoesNotExistException('Unknown share token');
}
return $this->parseTokensSelectSql($data);
}
/**
* @param DeprecatedMember $member
*
* @return SharesToken[]
*/
public function getTokensFromMember(DeprecatedMember $member) {
$qb = $this->getTokensSelectSql();
$this->limitToUserId($qb, $member->getUserId());
$this->limitToCircleId($qb, $member->getCircleId());
$shares = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$shares[] = $this->parseTokensSelectSql($data);
}
$cursor->closeCursor();
return $shares;
}
/**
* @param DeprecatedMember $member
* @param int $shareId
* @param string $password
*
* @return SharesToken
* @throws TokenDoesNotExistException
*/
public function generateTokenForMember(DeprecatedMember $member, int $shareId, string $password = ''): SharesToken {
try {
$token = $this->miscService->token(15);
if ($password !== '') {
$hasher = \OC::$server->getHasher();
$password = $hasher->hash($password);
}
$qb = $this->getTokensInsertSql();
$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
->setValue('share_id', $qb->createNamedParameter($shareId))
->setValue('member_id', $qb->createNamedParameter($member->getMemberId()))
->setValue('token', $qb->createNamedParameter($token))
->setValue('password', $qb->createNamedParameter($password));
$qb->execute();
} catch (UniqueConstraintViolationException $e) {
}
return $this->getTokenFromMember($shareId, $member->getCircleId(), $member->getUserId());
}
/**
* @param int $shareId
*/
public function removeTokenByShareId(int $shareId) {
$qb = $this->getTokensDeleteSql();
$this->limitToShareId($qb, $shareId);
$qb->execute();
}
/**
* @param DeprecatedMember $member
*/
public function removeTokensFromMember(DeprecatedMember $member) {
$qb = $this->getTokensDeleteSql();
$this->limitToCircleId($qb, $member->getCircleId());
$this->limitToUserId($qb, $member->getUserId());
$qb->execute();
}
public function updateSinglePassword(string $circleId, string $password) {
$qb = $this->getTokensUpdateSql();
if ($password !== '') {
$hasher = \OC::$server->getHasher();
$password = $hasher->hash($password);
}
$this->limitToCircleId($qb, $circleId);
$qb->set('password', $qb->createNamedParameter($password));
$qb->execute();
}
}
@@ -0,0 +1,111 @@
<?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 2017
* @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/>.
*
*/
namespace OCA\Circles\Db;
use OCA\Circles\Model\SharesToken;
use OCA\Circles\Tools\Traits\TArrayTools;
use OCP\DB\QueryBuilder\IQueryBuilder;
/**
* @deprecated
* Class TokensRequestBuilder
*
* @package OCA\Circles\Db
*/
class TokensRequestBuilder extends DeprecatedRequestBuilder {
use TArrayTools;
/**
* Base of the Sql Insert request for Shares
*
* @return IQueryBuilder
*/
protected function getTokensInsertSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->insert(self::TABLE_TOKENS);
return $qb;
}
/**
* Base of the Sql Update request for Groups
*
* @return IQueryBuilder
*/
protected function getTokensUpdateSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->update(self::TABLE_TOKENS);
return $qb;
}
/**
* @return IQueryBuilder
*/
protected function getTokensSelectSql() {
$qb = $this->dbConnection->getQueryBuilder();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$qb->select('t.user_id', 't.circle_id', 't.member_id', 't.share_id', 't.token', 't.accepted')
->from(self::TABLE_TOKENS, 't');
$this->default_select_alias = 't';
return $qb;
}
/**
* Base of the Sql Delete request
*
* @return IQueryBuilder
*/
protected function getTokensDeleteSql() {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_TOKENS);
return $qb;
}
/**
* @param array $data
*
* @return SharesToken
*/
protected function parseTokensSelectSql($data) {
$sharesToken = new SharesToken();
$sharesToken->import($data);
return $sharesToken;
}
}