Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl 2019-03-05 18:52:54 +01:00
Родитель a842fd6d26
Коммит ed3991b7bd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4C614C6ED2CDE6DF
12 изменённых файлов: 155 добавлений и 7 удалений

Просмотреть файл

@ -56,6 +56,7 @@
@if mixin-exists('icon-black-white') {
@include icon-black-white('deck', 'deck', 1);
@include icon-black-white('archive', 'deck', 1);
@include icon-black-white('circles', 'deck', 1);
.icon-toggle-compact-collapsed {
@include icon-color('toggle-view-expand', 'deck', $color-black);
@ -68,3 +69,12 @@
@include icon-color('activity-dark', 'activity', $color-black);
}
}
.avatardiv.circles {
background: var(--color-primary);
}
.icon-circles {
opacity: 1;
background-size: 20px;
background-position: center center;
}

Просмотреть файл

@ -1292,7 +1292,7 @@ input.input-inline {
width: 32px;
height: 32px;
.icon-group {
.icon-group, .icon {
padding: 16px;
opacity: 0.5;
}

1
img/circles.svg Normal file
Просмотреть файл

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58 58" width="512" height="512"><g fill="#000"><path d="M54.319 37.839C54.762 35.918 55 33.96 55 32c0-9.095-4.631-17.377-12.389-22.153a1 1 0 1 0-1.049 1.703C48.724 15.96 53 23.604 53 32c0 1.726-.2 3.451-.573 5.147A6.992 6.992 0 0 0 51 37c-3.86 0-7 3.141-7 7s3.14 7 7 7 7-3.141 7-7a7.006 7.006 0 0 0-3.681-6.161zM38.171 54.182A23.867 23.867 0 0 1 29 56a24.047 24.047 0 0 1-17.017-7.092A6.974 6.974 0 0 0 14 44c0-3.859-3.14-7-7-7s-7 3.141-7 7 3.14 7 7 7a6.952 6.952 0 0 0 3.381-.875C15.26 55.136 21.994 58 29 58c3.435 0 6.778-.663 9.936-1.971.51-.211.753-.796.542-1.307a1.001 1.001 0 0 0-1.307-.54zM4 31.213a1 1 0 0 0 1.068-.927c.712-10.089 7.586-18.52 17.22-21.314C23.142 11.874 25.825 14 29 14c3.86 0 7-3.141 7-7s-3.14-7-7-7c-3.851 0-6.985 3.127-6.999 6.975C11.42 9.922 3.851 19.12 3.073 30.146A.999.999 0 0 0 4 31.213z"/></g></svg>

После

Ширина:  |  Высота:  |  Размер: 885 B

Просмотреть файл

@ -403,6 +403,8 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
return 'user';
case OC.Share.SHARE_TYPE_GROUP:
return 'group';
case OC.Share.SHARE_TYPE_CIRCLE:
return 'circles';
default:
return '';
}

Просмотреть файл

@ -20,7 +20,7 @@
*
*/
import app from '../app/App.js';
/* global app OC */
/* global app OC angular */
app.factory('BoardService', function (ApiService, $http, $q) {
var BoardService = function ($http, ep, $q) {
ApiService.call(this, $http, ep, $q);
@ -59,7 +59,7 @@ app.factory('BoardService', function (ApiService, $http, $q) {
var searchData = {
format: 'json',
perPage: 4,
itemType: [0, 1]
itemType: [0, 1, 7]
};
if (search !== "") {
searchData.search = search;
@ -79,6 +79,7 @@ app.factory('BoardService', function (ApiService, $http, $q) {
var users = response.ocs.data.exact.users.concat(response.ocs.data.users.slice(0, 4));
var groups = response.ocs.data.exact.groups.concat(response.ocs.data.groups.slice(0, 4));
var circles = response.ocs.data.exact.groups.concat(response.ocs.data.circles.slice(0, 4));
// filter out everyone who is already in the share list
angular.forEach(users, function (item) {
@ -105,6 +106,18 @@ app.factory('BoardService', function (ApiService, $http, $q) {
self.sharees.push(acl);
}
});
angular.forEach(circles, function (item) {
var acl = self.generateAcl(OC.Share.SHARE_TYPE_CIRCLE, item);
var exists = false;
angular.forEach(self.getCurrent().acl, function (acl) {
if (acl.participant.primaryKey === item.value.shareWith) {
exists = true;
}
});
if (!exists) {
self.sharees.push(acl);
}
});
deferred.resolve(self.sharees);
}, function () {

Просмотреть файл

@ -32,6 +32,7 @@ class Acl extends RelationalEntity {
const PERMISSION_TYPE_USER = 0;
const PERMISSION_TYPE_GROUP = 1;
const PERMISSION_TYPE_CIRCLE = 7;
protected $participant;
protected $type;

Просмотреть файл

@ -24,6 +24,7 @@
namespace OCA\Deck\Db;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\QueryException;
use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\IGroupManager;
@ -36,6 +37,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
private $userManager;
private $groupManager;
private $circlesEnabled;
public function __construct(
IDBConnection $db,
LabelMapper $labelMapper,
@ -50,6 +53,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$this->stackMapper = $stackMapper;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles');
}
@ -136,6 +141,35 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
return $entries;
}
public function findAllByCircles($userId, $limit = null, $offset = null) {
if (!$this->circlesEnabled) {
return [];
}
$circles = array_map(function($circle) {
return $circle->getUniqueId();
}, \OCA\Circles\Api\v1\Circles::joinedCircles('', true));
if (count($circles) === 0) {
return [];
}
$sql = 'SELECT boards.id, title, owner, color, archived, deleted_at, 2 as shared, last_modified FROM `*PREFIX*deck_boards` as boards ' .
'INNER JOIN `*PREFIX*deck_board_acl` as acl ON boards.id=acl.board_id WHERE owner != ? AND type=? AND (';
for ($i = 0, $iMax = count($circles); $i < $iMax; $i++) {
$sql .= 'acl.participant = ? ';
if (count($circles) > 1 && $i < count($circles) - 1) {
$sql .= ' OR ';
}
}
$sql .= ');';
$entries = $this->findEntities($sql, array_merge([$userId, Acl::PERMISSION_TYPE_CIRCLE], $circles), $limit, $offset);
/* @var Board $entry */
foreach ($entries as $entry) {
$acl = $this->aclMapper->findAll($entry->id);
$entry->setAcl($acl);
}
return $entries;
}
public function findAll() {
$sql = 'SELECT id from *PREFIX*deck_boards;';
return $this->findEntities($sql);
@ -200,6 +234,20 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
\OC::$server->getLogger()->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
return null;
}
// TODO: get circles list
if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
try {
$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($acl->getParticipant());
if ($circle) {
return new Circle($circle);
}
} catch (QueryException $e) {
} catch (\Exception $e) {
// TODO catch not found
}
return null;
}
// TODO: get circles list
throw new \Exception('Unknown permission type for mapping Acl');
});
}

45
lib/Db/Circle.php Normal file
Просмотреть файл

@ -0,0 +1,45 @@
<?php
/**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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\Deck\Db;
class Circle extends RelationalObject {
/** @var \OCA\Circles\Model\Circle */
protected $object;
public function __construct(\OCA\Circles\Model\Circle $circle) {
$primaryKey = $circle->getUniqueId();
parent::__construct($primaryKey, $circle);
}
public function getObjectSerialization() {
return [
'uid' => $this->object->getUniqueId(),
'displayname' => $this->object->getName(),
'typeString' => $this->object->getTypeString(),
'circleOwner' => $this->object->getOwner()
];
}
}

Просмотреть файл

@ -97,7 +97,8 @@ class BoardService {
$userInfo = $this->getBoardPrerequisites();
$userBoards = $this->boardMapper->findAllByUser($userInfo['user'], null, null, $since);
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups'],null, null, $since);
$complete = array_merge($userBoards, $groupBoards);
$circleBoards = $this->boardMapper->findAllByCircles($userInfo['user'], null, null, $since);
$complete = array_merge($userBoards, $groupBoards, $circleBoards);
$result = [];
/** @var Board $item */
foreach ($complete as &$item) {

Просмотреть файл

@ -33,6 +33,7 @@ use OCA\Deck\NoPermissionException;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\Entity;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\AppFramework\QueryException;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\ILogger;
@ -61,6 +62,8 @@ class PermissionService {
/** @var array */
private $users = [];
private $circlesEnabled = false;
public function __construct(
ILogger $logger,
AclMapper $aclMapper,
@ -79,6 +82,8 @@ class PermissionService {
$this->shareManager = $shareManager;
$this->config = $config;
$this->userId = $userId;
$this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles');
}
/**
@ -182,6 +187,16 @@ class PermissionService {
if ($acl->getType() === Acl::PERMISSION_TYPE_USER && $acl->getParticipant() === $this->userId) {
return $acl->getPermission($permission);
}
if ($this->circlesEnabled && $acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
try {
\OCA\Circles\Api\v1\Circles::getMember($acl->getParticipant(), $this->userId, 1);
return $acl->getPermission($permission);
} catch (\Exception $e) {
// TODO: getMember doesn't work for personal circles
$this->logger->info('Member not found in circle that was accessed. This should not happen.');
}
}
}
// check for groups
$hasGroupPermission = false;

Просмотреть файл

@ -33,6 +33,10 @@
<span class="has-tooltip username" ng-if="sharee.type==OC.Share.SHARE_TYPE_GROUP">
{{ sharee.participant.displayname }} (<?php p($l->t('Group')); ?>)
</span>
<div class="avatardiv circles" ng-if="sharee.type==OC.Share.SHARE_TYPE_CIRCLE"><i class="icon icon-circles icon-white"></i></div>
<span class="has-tooltip username" ng-if="sharee.type==OC.Share.SHARE_TYPE_CIRCLE">
{{ sharee.participant.displayname }} (<?php p($l->t('Circle')); ?>)
</span>
<span class="has-tooltip username" ng-if="sharee.type==OC.Share.SHARE_TYPE_USER">
{{ sharee.participant.displayname }}
</span>
@ -53,13 +57,17 @@
<li ng-repeat="acl in boardservice.getCurrent().acl track by acl.participant.primaryKey">
<span class="icon-loading-small" style="display:none;" title="<?php p($l->t('Loading')); ?>"></span>
<div class="avatardiv" avatar data-contactsmenu="true" data-user="{{ acl.participant.uid }}" data-displayname="{{ acl.participant.displayname }}" ng-if="acl.type==OC.Share.SHARE_TYPE_USER"></div>
<div class="avatardiv" ng-if="acl.type==OC.Share.SHARE_TYPE_GROUP"><i class="icon icon-{{aclTypeString(acl)}}" ></i></div>
<div class="avatardiv" ng-if="acl.type!=OC.Share.SHARE_TYPE_USER"><i class="icon icon-{{aclTypeString(acl)}}" ></i></div>
<span class="has-tooltip username" ng-if="acl.type==OC.Share.SHARE_TYPE_USER">
{{ acl.participant.displayname }}
</span>
<span class="has-tooltip username" ng-if="acl.type==OC.Share.SHARE_TYPE_GROUP">
{{ acl.participant.displayname }} (<?php p($l->t('Group')); ?>)
</span>
<span class="has-tooltip username" ng-if="acl.type==OC.Share.SHARE_TYPE_USER">
{{ acl.participant.displayname }}
<span class="has-tooltip username" ng-if="acl.type==OC.Share.SHARE_TYPE_CIRCLE">
{{ acl.participant.displayname }} (<?php p($l->t('Circle')); ?> {{ acl.participant.typeString }})
<div>{{ acl.participant.circleOwner.display_name }}</div>
</span>
<span class="sharingOptionsGroup">

Просмотреть файл

@ -123,6 +123,10 @@ class BoardServiceTest extends TestCase {
->method('findAllByGroups')
->with('admin', ['a', 'b', 'c'])
->willReturn([$b2, $b3]);
$this->boardMapper->expects($this->once())
->method('findAllByCircles')
->with('admin')
->willReturn([]);
$user = $this->createMock(IUser::class);
$this->groupManager->method('getUserGroupIds')
->willReturn(['a', 'b', 'c']);