Disable ui elements if permissions are not sufficient
This commit is contained in:
@@ -34,6 +34,7 @@ return [
|
|||||||
['name' => 'board#read', 'url' => '/boards/{boardId}', 'verb' => 'GET'],
|
['name' => 'board#read', 'url' => '/boards/{boardId}', 'verb' => 'GET'],
|
||||||
['name' => 'board#update', 'url' => '/boards/{boardId}', 'verb' => 'PUT'],
|
['name' => 'board#update', 'url' => '/boards/{boardId}', 'verb' => 'PUT'],
|
||||||
['name' => 'board#delete', 'url' => '/boards/{boardId}', 'verb' => 'DELETE'],
|
['name' => 'board#delete', 'url' => '/boards/{boardId}', 'verb' => 'DELETE'],
|
||||||
|
['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'],
|
||||||
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||||
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
|
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
|
||||||
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
||||||
|
|||||||
@@ -25,4 +25,5 @@ app.controller('AppController', function ($scope, $location, $http, $route, $log
|
|||||||
show: false
|
show: false
|
||||||
};
|
};
|
||||||
$scope.sidebar = $rootScope.sidebar;
|
$scope.sidebar = $rootScope.sidebar;
|
||||||
|
$scope.user = oc_current_user;
|
||||||
});
|
});
|
||||||
@@ -113,6 +113,7 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
|||||||
|
|
||||||
// Handle initial Loading
|
// Handle initial Loading
|
||||||
BoardService.fetchOne($scope.id).then(function (data) {
|
BoardService.fetchOne($scope.id).then(function (data) {
|
||||||
|
BoardService.getPermissions();
|
||||||
$scope.statusservice.releaseWaiting();
|
$scope.statusservice.releaseWaiting();
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
$scope.statusservice.setError('Error occured', error);
|
$scope.statusservice.setError('Error occured', error);
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ app.controller('CardController', function ($scope, $rootScope, $routeParams, $lo
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.cardRenameShow = function() {
|
$scope.cardRenameShow = function() {
|
||||||
if($scope.archived)
|
if($scope.archived || !BoardService.canEdit())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
$scope.status.cardRename=true;
|
$scope.status.cardRename=true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$scope.cardEditDescriptionShow = function() {
|
$scope.cardEditDescriptionShow = function() {
|
||||||
if($scope.archived)
|
if($scope.archived || !BoardService.canEdit())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
$scope.status.cardEditDescription=true;
|
$scope.status.cardEditDescription=true;
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ app.controller('AppController', ["$scope", "$location", "$http", "$route", "$log
|
|||||||
show: false
|
show: false
|
||||||
};
|
};
|
||||||
$scope.sidebar = $rootScope.sidebar;
|
$scope.sidebar = $rootScope.sidebar;
|
||||||
|
$scope.user = oc_current_user;
|
||||||
}]);
|
}]);
|
||||||
app.controller('BoardController', ["$rootScope", "$scope", "$stateParams", "StatusService", "BoardService", "StackService", "CardService", "LabelService", "$state", "$transitions", "$filter", function ($rootScope, $scope, $stateParams, StatusService, BoardService, StackService, CardService, LabelService, $state, $transitions, $filter) {
|
app.controller('BoardController', ["$rootScope", "$scope", "$stateParams", "StatusService", "BoardService", "StackService", "CardService", "LabelService", "$state", "$transitions", "$filter", function ($rootScope, $scope, $stateParams, StatusService, BoardService, StackService, CardService, LabelService, $state, $transitions, $filter) {
|
||||||
|
|
||||||
@@ -207,6 +208,7 @@ app.controller('BoardController', ["$rootScope", "$scope", "$stateParams", "Stat
|
|||||||
|
|
||||||
// Handle initial Loading
|
// Handle initial Loading
|
||||||
BoardService.fetchOne($scope.id).then(function (data) {
|
BoardService.fetchOne($scope.id).then(function (data) {
|
||||||
|
BoardService.getPermissions();
|
||||||
$scope.statusservice.releaseWaiting();
|
$scope.statusservice.releaseWaiting();
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
$scope.statusservice.setError('Error occured', error);
|
$scope.statusservice.setError('Error occured', error);
|
||||||
@@ -361,14 +363,14 @@ app.controller('CardController', ["$scope", "$rootScope", "$routeParams", "$loca
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.cardRenameShow = function() {
|
$scope.cardRenameShow = function() {
|
||||||
if($scope.archived)
|
if($scope.archived || !BoardService.canEdit())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
$scope.status.cardRename=true;
|
$scope.status.cardRename=true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$scope.cardEditDescriptionShow = function() {
|
$scope.cardEditDescriptionShow = function() {
|
||||||
if($scope.archived)
|
if($scope.archived || !BoardService.canEdit())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
$scope.status.cardEditDescription=true;
|
$scope.status.cardEditDescription=true;
|
||||||
@@ -978,6 +980,46 @@ app.factory('BoardService', ["ApiService", "$http", "$q", function(ApiService, $
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BoardService.prototype.getPermissions = function() {
|
||||||
|
var board = this.getCurrent();
|
||||||
|
var deferred = $q.defer();
|
||||||
|
$http.get(this.baseUrl + '/' + board.id + '/permissions').then(function (response) {
|
||||||
|
board.permissions = response.data;
|
||||||
|
console.log(board.permissions);
|
||||||
|
deferred.resolve(response.data);
|
||||||
|
}, function (error) {
|
||||||
|
deferred.reject('Error fetching board permissions ' + board);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BoardService.prototype.canRead = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_READ'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canEdit = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_EDIT'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canManage = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_MANAGE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canShare = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_SHARE'];
|
||||||
|
}
|
||||||
|
|
||||||
service = new BoardService($http, 'boards', $q);
|
service = new BoardService($http, 'boards', $q);
|
||||||
return service;
|
return service;
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,46 @@ app.factory('BoardService', function(ApiService, $http, $q){
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BoardService.prototype.getPermissions = function() {
|
||||||
|
var board = this.getCurrent();
|
||||||
|
var deferred = $q.defer();
|
||||||
|
$http.get(this.baseUrl + '/' + board.id + '/permissions').then(function (response) {
|
||||||
|
board.permissions = response.data;
|
||||||
|
console.log(board.permissions);
|
||||||
|
deferred.resolve(response.data);
|
||||||
|
}, function (error) {
|
||||||
|
deferred.reject('Error fetching board permissions ' + board);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
BoardService.prototype.canRead = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_READ'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canEdit = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_EDIT'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canManage = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_MANAGE'];
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardService.prototype.canShare = function() {
|
||||||
|
if(!this.getCurrent() || !this.getCurrent().permissions) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getCurrent().permissions['PERMISSION_SHARE'];
|
||||||
|
}
|
||||||
|
|
||||||
service = new BoardService($http, 'boards', $q);
|
service = new BoardService($http, 'boards', $q);
|
||||||
return service;
|
return service;
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class Application extends App {
|
|||||||
$container->query('ControllerMethodReflector')
|
$container->query('ControllerMethodReflector')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
/** @noinspection PhpMethodOrClassCallIsNotCaseSensitiveInspection */
|
||||||
$container->registerMiddleware('SharingMiddleware');
|
$container->registerMiddleware('SharingMiddleware');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace OCA\Deck\Controller;
|
namespace OCA\Deck\Controller;
|
||||||
|
|
||||||
|
use OCA\Deck\Db\Acl;
|
||||||
use OCA\Deck\Service\BoardService;
|
use OCA\Deck\Service\BoardService;
|
||||||
|
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
@@ -121,6 +122,33 @@ class BoardController extends Controller {
|
|||||||
return $this->boardService->labels($boardId);
|
return $this->boardService->labels($boardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @RequireReadPermission
|
||||||
|
* @param $boardId
|
||||||
|
* @return array|bool
|
||||||
|
* @internal param $userId
|
||||||
|
*/
|
||||||
|
public function getUserPermissions($boardId) {
|
||||||
|
$board = $this->boardService->find($boardId);
|
||||||
|
if($this->userId === $board->getOwner()) {
|
||||||
|
return [
|
||||||
|
'PERMISSION_READ' => true,
|
||||||
|
'PERMISSION_EDIT' => true,
|
||||||
|
'PERMISSION_MANAGE' => true,
|
||||||
|
'PERMISSION_SHARE' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'PERMISSION_READ' => $this->boardService->getPermission($boardId, $this->userId, Acl::PERMISSION_READ),
|
||||||
|
'PERMISSION_EDIT' => $this->boardService->getPermission($boardId, $this->userId, Acl::PERMISSION_EDIT),
|
||||||
|
'PERMISSION_MANAGE' => $this->boardService->getPermission($boardId, $this->userId, Acl::PERMISSION_MANAGE),
|
||||||
|
'PERMISSION_SHARE' => $this->boardService->getPermission($boardId, $this->userId, Acl::PERMISSION_SHARE),
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @RequireManagePermission
|
* @RequireManagePermission
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
namespace OCA\Deck\Controller;
|
namespace OCA\Deck\Controller;
|
||||||
|
|
||||||
use OCA\Deck\Db\Acl;
|
use OCA\Deck\Db\Acl;
|
||||||
|
|
||||||
|
use OCA\Deck\Service\BoardService;
|
||||||
use OCP\IGroupManager;
|
use OCP\IGroupManager;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
@@ -31,20 +33,23 @@ use OCP\IUserManager;
|
|||||||
|
|
||||||
class ShareController extends Controller {
|
class ShareController extends Controller {
|
||||||
|
|
||||||
protected $userManager;
|
private $userManager;
|
||||||
protected $groupManager;
|
private $groupManager;
|
||||||
|
private $boardService;
|
||||||
private $userId;
|
private $userId;
|
||||||
|
|
||||||
public function __construct($appName,
|
public function __construct($appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
IUserManager $userManager,
|
IUserManager $userManager,
|
||||||
IGroupManager $groupManager,
|
IGroupManager $groupManager,
|
||||||
|
BoardService $boardService,
|
||||||
$userId
|
$userId
|
||||||
){
|
){
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
$this->groupManager = $groupManager;
|
$this->groupManager = $groupManager;
|
||||||
$this->userId = $userId;
|
$this->userId = $userId;
|
||||||
|
$this->boardService = $boardService;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,4 +86,8 @@ class ShareController extends Controller {
|
|||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,9 +42,11 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $id
|
* @param $id
|
||||||
|
* @param bool $withLabels
|
||||||
|
* @param bool $withAcl
|
||||||
* @return \OCP\AppFramework\Db\Entity if not found
|
* @return \OCP\AppFramework\Db\Entity if not found
|
||||||
*/
|
*/
|
||||||
public function find($id) {
|
public function find($id, $withLabels=false, $withAcl=false) {
|
||||||
$sql = 'SELECT id, title, owner, color, archived FROM `*PREFIX*deck_boards` ' .
|
$sql = 'SELECT id, title, owner, color, archived FROM `*PREFIX*deck_boards` ' .
|
||||||
'WHERE `id` = ?';
|
'WHERE `id` = ?';
|
||||||
$board = $this->findEntity($sql, [$id]);
|
$board = $this->findEntity($sql, [$id]);
|
||||||
@@ -95,13 +97,12 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
}
|
}
|
||||||
$sql = 'SELECT boards.id, title, owner, color, archived, 2 as shared FROM oc_deck_boards as boards ' .
|
$sql = 'SELECT boards.id, title, owner, color, archived, 2 as shared FROM oc_deck_boards as boards ' .
|
||||||
'INNER JOIN oc_deck_board_acl as acl ON boards.id=acl.board_id WHERE owner != ? AND type=\'group\' AND (';
|
'INNER JOIN oc_deck_board_acl as acl ON boards.id=acl.board_id WHERE owner != ? AND type=\'group\' AND (';
|
||||||
$countGroups = 0;
|
for($i=0;$i<count($groups);$i++) {
|
||||||
// FIXME: group unused?
|
$sql .= 'acl.participant = ? ';
|
||||||
foreach ($groups as $group) {
|
if(count($groups)>1 && $i<count($groups)-1) {
|
||||||
$sql .= 'acl.participant = ? ';
|
$sql .= ' OR ';
|
||||||
if(count($groups)>1 && $countGroups++<count($groups)-1)
|
}
|
||||||
$sql .= ' OR ';
|
}
|
||||||
}
|
|
||||||
$sql .= ');';
|
$sql .= ');';
|
||||||
$entries = $this->findEntities($sql, array_merge([$userId], $groups), $limit, $offset);
|
$entries = $this->findEntities($sql, array_merge([$userId], $groups), $limit, $offset);
|
||||||
/* @var Board $entry */
|
/* @var Board $entry */
|
||||||
@@ -112,7 +113,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
|||||||
return $entries;
|
return $entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(\OCP\AppFramework\Db\Entity $entity) {
|
public function delete(/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
|
||||||
|
\OCP\AppFramework\Db\Entity $entity) {
|
||||||
// delete acl
|
// delete acl
|
||||||
$acl = $this->aclMapper->findAll($entity->getId());
|
$acl = $this->aclMapper->findAll($entity->getId());
|
||||||
foreach ($acl as $item) {
|
foreach ($acl as $item) {
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ namespace OCA\Deck\Db;
|
|||||||
|
|
||||||
use OCP\AppFramework\Db\Entity;
|
use OCP\AppFramework\Db\Entity;
|
||||||
use OCP\IDb;
|
use OCP\IDb;
|
||||||
use OCP\AppFramework\Db\Mapper;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CardMapper extends DeckMapper implements IPermissionMapper {
|
class CardMapper extends DeckMapper implements IPermissionMapper {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ abstract class DeckMapper extends Mapper {
|
|||||||
|
|
||||||
protected function execute($sql, array $params = [], $limit = null, $offset = null) {
|
protected function execute($sql, array $params = [], $limit = null, $offset = null) {
|
||||||
// FIXME: remove on release
|
// FIXME: remove on release
|
||||||
|
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
|
||||||
|
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
|
||||||
\OCP\Util::writeLog('deck', "DeckMapper SQL: " . $sql . " with " . implode("|", $params), \OCP\Util::DEBUG);
|
\OCP\Util::writeLog('deck', "DeckMapper SQL: " . $sql . " with " . implode("|", $params), \OCP\Util::DEBUG);
|
||||||
return parent::execute($sql, $params, $limit, $offset);
|
return parent::execute($sql, $params, $limit, $offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace OCA\Deck\Db;
|
|||||||
|
|
||||||
use OCP\AppFramework\Db\Entity;
|
use OCP\AppFramework\Db\Entity;
|
||||||
use OCP\IDb;
|
use OCP\IDb;
|
||||||
use OCP\AppFramework\Db\Mapper;
|
|
||||||
|
|
||||||
|
|
||||||
class StackMapper extends DeckMapper implements IPermissionMapper {
|
class StackMapper extends DeckMapper implements IPermissionMapper {
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ use OCA\Deck\Controller\BoardController;
|
|||||||
use OCA\Deck\Controller\CardController;
|
use OCA\Deck\Controller\CardController;
|
||||||
use OCA\Deck\Controller\LabelController;
|
use OCA\Deck\Controller\LabelController;
|
||||||
use OCA\Deck\Controller\PageController;
|
use OCA\Deck\Controller\PageController;
|
||||||
use OCA\Deck\Controller\ShareController;
|
|
||||||
|
|
||||||
use OCA\Deck\NoPermissionException;
|
use OCA\Deck\NoPermissionException;
|
||||||
use OCA\Deck\NotFoundException;
|
use OCA\Deck\NotFoundException;
|
||||||
|
|
||||||
use \OCP\AppFramework\Middleware;
|
use \OCP\AppFramework\Middleware;
|
||||||
use OCP\IContainer;
|
use OCP\IContainer;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
@@ -47,6 +49,7 @@ class SharingMiddleware extends Middleware {
|
|||||||
private $reflector;
|
private $reflector;
|
||||||
private $groupManager;
|
private $groupManager;
|
||||||
private $aclMapper;
|
private $aclMapper;
|
||||||
|
private $boardService;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -61,6 +64,7 @@ class SharingMiddleware extends Middleware {
|
|||||||
$this->reflector = $reflector;
|
$this->reflector = $reflector;
|
||||||
$this->aclMapper = $this->container->query('OCA\Deck\Db\AclMapper');
|
$this->aclMapper = $this->container->query('OCA\Deck\Db\AclMapper');
|
||||||
$this->groupManager = $this->container->query('\OCP\IGroupManager');
|
$this->groupManager = $this->container->query('\OCP\IGroupManager');
|
||||||
|
$this->boardService = $this->container->query('OCA\Deck\Service\BoardService');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,8 +121,7 @@ class SharingMiddleware extends Middleware {
|
|||||||
$mapper = null;
|
$mapper = null;
|
||||||
$id = null;
|
$id = null;
|
||||||
|
|
||||||
// FIXME: ShareController#search should be limited to board users/groups
|
if ($controller instanceof BoardController) {
|
||||||
if ($controller instanceof BoardController or $controller instanceof ShareController) {
|
|
||||||
$mapper = $this->container->query('OCA\Deck\Db\BoardMapper');
|
$mapper = $this->container->query('OCA\Deck\Db\BoardMapper');
|
||||||
$id = $params['boardId'];
|
$id = $params['boardId'];
|
||||||
}
|
}
|
||||||
@@ -198,29 +201,12 @@ class SharingMiddleware extends Middleware {
|
|||||||
if ($mapper->isOwner($userId, $id)) {
|
if ($mapper->isOwner($userId, $id)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find related board
|
// find related board
|
||||||
$boardId = $mapper->findBoardId($id);
|
$boardId = $mapper->findBoardId($id);
|
||||||
if(!$boardId) {
|
if(!$boardId) {
|
||||||
throw new NotFoundException("Entity not found");
|
throw new NotFoundException("Entity not found");
|
||||||
}
|
}
|
||||||
// check if is in acl
|
return $this->boardService->getPermission($boardId, $userId, $permission);
|
||||||
|
|
||||||
$acls = $this->aclMapper->findAll($boardId);
|
|
||||||
// check for users
|
|
||||||
foreach ($acls as $acl) {
|
|
||||||
if ($acl->getType() === "user" && $acl->getParticipant() === $userId) {
|
|
||||||
return $acl->getPermission($permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check for groups
|
|
||||||
$hasGroupPermission = false;
|
|
||||||
foreach ($acls as $acl) {
|
|
||||||
if (!$hasGroupPermission && $acl->getType() === "group" && $this->groupManager->isInGroup($userId, $acl->getParticipant())) {
|
|
||||||
$hasGroupPermission = $acl->getPermission($permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $hasGroupPermission;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace OCA\Deck\Service;
|
|||||||
use OCA\Deck\Db\Acl;
|
use OCA\Deck\Db\Acl;
|
||||||
use OCA\Deck\Db\AclMapper;
|
use OCA\Deck\Db\AclMapper;
|
||||||
use OCA\Deck\Db\Label;
|
use OCA\Deck\Db\Label;
|
||||||
|
use OCP\IGroupManager;
|
||||||
use OCP\ILogger;
|
use OCP\ILogger;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ use OCP\IL10N;
|
|||||||
use \OCA\Deck\Db\Board;
|
use \OCA\Deck\Db\Board;
|
||||||
use \OCA\Deck\Db\BoardMapper;
|
use \OCA\Deck\Db\BoardMapper;
|
||||||
use \OCA\Deck\Db\LabelMapper;
|
use \OCA\Deck\Db\LabelMapper;
|
||||||
|
use OCP\IUserManager;
|
||||||
|
|
||||||
|
|
||||||
class BoardService {
|
class BoardService {
|
||||||
@@ -47,12 +49,16 @@ class BoardService {
|
|||||||
ILogger $logger,
|
ILogger $logger,
|
||||||
IL10N $l10n,
|
IL10N $l10n,
|
||||||
LabelMapper $labelMapper,
|
LabelMapper $labelMapper,
|
||||||
AclMapper $aclMapper) {
|
AclMapper $aclMapper,
|
||||||
|
IUserManager $userManager,
|
||||||
|
IGroupManager $groupManager) {
|
||||||
$this->boardMapper = $boardMapper;
|
$this->boardMapper = $boardMapper;
|
||||||
$this->labelMapper = $labelMapper;
|
$this->labelMapper = $labelMapper;
|
||||||
$this->aclMapper = $aclMapper;
|
$this->aclMapper = $aclMapper;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
|
$this->userManager = $userManager;
|
||||||
|
$this->groupManager = $groupManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findAll($userInfo) {
|
public function findAll($userInfo) {
|
||||||
@@ -127,4 +133,22 @@ class BoardService {
|
|||||||
$acl = $this->aclMapper->find($id);
|
$acl = $this->aclMapper->find($id);
|
||||||
return $this->aclMapper->delete($acl);
|
return $this->aclMapper->delete($acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPermission($boardId, $user, $permission) {
|
||||||
|
$acls = $this->aclMapper->findAll($boardId);
|
||||||
|
// check for users
|
||||||
|
foreach ($acls as $acl) {
|
||||||
|
if ($acl->getType() === "user" && $acl->getParticipant() === $user) {
|
||||||
|
return $acl->getPermission($permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check for groups
|
||||||
|
$hasGroupPermission = false;
|
||||||
|
foreach ($acls as $acl) {
|
||||||
|
if (!$hasGroupPermission && $acl->getType() === "group" && $this->groupManager->isInGroup($user, $acl->getParticipant())) {
|
||||||
|
$hasGroupPermission = $acl->getPermission($permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $hasGroupPermission;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
<div id="board-header"
|
<div id="board-header"
|
||||||
style="background-color: #{{boardservice.getCurrent().color }}; color: {{boardservice.getCurrent().color | textColorFilter }};">
|
style="background-color: #{{boardservice.getCurrent().color }}; color: {{boardservice.getCurrent().color | textColorFilter }};">
|
||||||
<h1>
|
<h1>
|
||||||
{{ boardservice.data[id].title }}
|
{{ boardservice.getCurrent().title }}
|
||||||
<div id="board-actions">
|
<div id="board-actions">
|
||||||
<div class="board-action-button" ng-if="filter!='archive'"><a ng-click="switchFilter('archive')" style="opacity:0.5;"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
|
<div class="board-action-button" ng-if="filter!='archive'"><a ng-click="switchFilter('archive')" style="opacity:0.5;" title="<?php p($l->t('Show archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
|
||||||
<div class="board-action-button" ng-if="filter=='archive'"><a ng-click="switchFilter('')"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
|
<div class="board-action-button" ng-if="filter=='archive'"><a ng-click="switchFilter('')" title="<?php p($l->t('Hide archived cards')); ?>"><i class="icon icon-archive{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a></div>
|
||||||
<div class="board-action-button"><a ui-sref="board.detail({ id: id })"><i class="icon icon-details{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a>
|
<div class="board-action-button"><a ui-sref="board.detail({ id: id })" title="<?php p($l->t('Board details')); ?>"><i class="icon icon-details{{ boardservice.getCurrent().color | iconWhiteFilter }}"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</h1>
|
</h1>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
ng-click="stackservice.delete(s.id)"></button>
|
ng-click="stackservice.delete(s.id)"></button>
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<ul data-as-sortable="sortOptions" is-disabled="filter==='archive'" data-ng-model="s.cards"
|
<ul data-as-sortable="sortOptions" is-disabled="!boardservice.canEdit() || filter==='archive'" data-ng-model="s.cards"
|
||||||
style="min-height: 40px;">
|
style="min-height: 40px;">
|
||||||
<li class="card as-sortable-item"
|
<li class="card as-sortable-item"
|
||||||
ng-repeat="c in s.cards"
|
ng-repeat="c in s.cards"
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<div class="app-popover-menu-utils">
|
<div class="app-popover-menu-utils">
|
||||||
<button class="card-options icon-more"
|
<button class="card-options icon-more"
|
||||||
ng-click="c.status.showMenu=!c.status.showMenu; $event.stopPropagation();"
|
ng-click="c.status.showMenu=!c.status.showMenu; $event.stopPropagation();"
|
||||||
ng-model="card"></button>
|
ng-model="card" ng-if="boardservice.canEdit()"></button>
|
||||||
<div class="popovermenu bubble hidden">
|
<div class="popovermenu bubble hidden">
|
||||||
<ul>
|
<ul>
|
||||||
<li ng-if="filter!=='archive'">
|
<li ng-if="filter!=='archive'">
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<!-- CREATE CARD //-->
|
<!-- CREATE CARD //-->
|
||||||
<div class="card create"
|
<div class="card create"
|
||||||
style="background-color:#{{ boardservice.getCurrent().color }};" ng-if="checkCanEdit() && filter!=='archive'">
|
style="background-color:#{{ boardservice.getCurrent().color }};" ng-if="boardservice.canEdit() && checkCanEdit() && filter!=='archive'">
|
||||||
<form ng-submit="createCard(s.id, newCard.title)">
|
<form ng-submit="createCard(s.id, newCard.title)">
|
||||||
<h3 ng-if="status.addCard[s.id]">
|
<h3 ng-if="status.addCard[s.id]">
|
||||||
<input type="text" autofocus-on-insert
|
<input type="text" autofocus-on-insert
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack" style="display: inline-block;" ng-if="checkCanEdit()">
|
<div class="stack" style="display: inline-block;" ng-if="boardservice.canEdit() && checkCanEdit()">
|
||||||
<form class="ng-pristine ng-valid" ng-submit="createStack()">
|
<form class="ng-pristine ng-valid" ng-submit="createStack()">
|
||||||
<h2>
|
<h2>
|
||||||
<input type="text" placeholder="Add a new stack"
|
<input type="text" placeholder="Add a new stack"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="tabsContainer">
|
<div class="tabsContainer">
|
||||||
<div id="commentsTabView" class="tab commentsTabView" ng-if="status.boardtab==0 || !status.boardtab">
|
<div id="commentsTabView" class="tab commentsTabView" ng-if="status.boardtab==0 || !status.boardtab">
|
||||||
|
|
||||||
<ui-select ng-model="status.addSharee" theme="bootstrap" style="width:100%;" title="Choose a user to assign" placeholder="Assign users ..." on-select="aclAdd(status.addSharee)">
|
<ui-select ng-if="boardservice.canShare()" ng-model="status.addSharee" theme="bootstrap" style="width:100%;" title="Choose a user to assign" placeholder="Assign users ..." on-select="aclAdd(status.addSharee)">
|
||||||
<ui-select-match placeholder="<?php p($l->t('Select users...')); ?>">
|
<ui-select-match placeholder="<?php p($l->t('Select users...')); ?>">
|
||||||
<span><i class="icon icon-{{$item.type}}"></i> {{ $item.participant }}</span>
|
<span><i class="icon icon-{{$item.type}}"></i> {{ $item.participant }}</span>
|
||||||
</ui-select-match>
|
</ui-select-match>
|
||||||
@@ -45,19 +45,19 @@
|
|||||||
|
|
||||||
<span class="has-tooltip username">
|
<span class="has-tooltip username">
|
||||||
{{ acl.participant }}</span>
|
{{ acl.participant }}</span>
|
||||||
<span class="shareOption">
|
<span class="shareOption" ng-if="boardservice.canManage()">
|
||||||
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-share" ng-model="acl.permissionInvite" ng-change="aclUpdate(acl)" />
|
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-share" ng-model="acl.permissionInvite" ng-change="aclUpdate(acl)" />
|
||||||
<label for="checkbox-permission-{{ acl.id }}-share"><?php p($l->t('Share')); ?></label>
|
<label for="checkbox-permission-{{ acl.id }}-share"><?php p($l->t('Share')); ?></label>
|
||||||
</span>
|
</span>
|
||||||
<span class="shareOption">
|
<span class="shareOption"ng-if="boardservice.canManage()">
|
||||||
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-edit" ng-model="acl.permissionWrite" ng-change="aclUpdate(acl)" />
|
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-edit" ng-model="acl.permissionWrite" ng-change="aclUpdate(acl)" />
|
||||||
<label for="checkbox-permission-{{ acl.id }}-edit"><?php p($l->t('Edit')); ?></label>
|
<label for="checkbox-permission-{{ acl.id }}-edit"><?php p($l->t('Edit')); ?></label>
|
||||||
</span>
|
</span>
|
||||||
<span class="shareOption">
|
<span class="shareOption"ng-if="boardservice.canManage()">
|
||||||
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-manage" ng-model="acl.permissionManage" ng-change="aclUpdate(acl)" />
|
<input type="checkbox" class="permissions checkbox" id="checkbox-permission-{{ acl.id }}-manage" ng-model="acl.permissionManage" ng-change="aclUpdate(acl)" />
|
||||||
<label for="checkbox-permission-{{ acl.id }}-manage"><?php p($l->t('Manage')); ?></label>
|
<label for="checkbox-permission-{{ acl.id }}-manage"><?php p($l->t('Manage')); ?></label>
|
||||||
</span>
|
</span>
|
||||||
<a class="unshare" ng-click="aclDelete(acl)"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually"><?php p($l->t('Discard share')); ?></span></a>
|
<a ng-if="boardservice.canManage()" class="unshare" ng-click="aclDelete(acl)"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually"><?php p($l->t('Discard share')); ?></span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
<ul class="labels">
|
<ul class="labels">
|
||||||
<li ng-repeat="label in boardservice.getCurrent().labels">
|
<li ng-repeat="label in boardservice.getCurrent().labels">
|
||||||
<span class="label-title" style="background-color:#{{label.color}}; color:{{ label.color|textColorFilter }};" ng-if="!label.edit" ng-click="label.edit=true">
|
<span class="label-title" style="background-color:#{{label.color}}; color:{{ label.color|textColorFilter }};" ng-if="!label.edit">
|
||||||
<span ng-if="label.title">{{ label.title }}</span><i ng-if="!label.title"><br /></i>
|
<span ng-if="label.title">{{ label.title }}</span><i ng-if="!label.title"><br /></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="label-title" style="background-color:#{{label.color}}; color:{{ textColor(label.color) }}; width:178px;" ng-if="label.edit">
|
<span class="label-title" style="background-color:#{{label.color}}; color:{{ textColor(label.color) }}; width:178px;" ng-if="label.edit">
|
||||||
@@ -77,9 +77,9 @@
|
|||||||
<div class="colorselect" ng-if="label.edit">
|
<div class="colorselect" ng-if="label.edit">
|
||||||
<div class="color" ng-repeat="c in defaultColors" style="background-color:#{{ c }};" ng-click="label.color=c" ng-class="{'selected': (c == label.color) }"><br /></div>
|
<div class="color" ng-repeat="c in defaultColors" style="background-color:#{{ c }};" ng-click="label.color=c" ng-class="{'selected': (c == label.color) }"><br /></div>
|
||||||
</div>
|
</div>
|
||||||
<a ng-click="labelDelete(label)" class="icon"><i class="icon icon-delete" ></i></a>
|
<a ng-if="boardservice.canManage()" ng-click="labelDelete(label)" class="icon"><i class="icon icon-delete" ></i></a>
|
||||||
<a ng-click="labelUpdate(label)" ng-if="label.edit" class="icon"><i class="icon icon-checkmark" ></i></a>
|
<a ng-if="boardservice.canManage() && label.edit" ng-click="labelUpdate(label)" class="icon"><i class="icon icon-checkmark" ></i></a>
|
||||||
<a ng-click="label.edit=true" ng-if="!label.edit" class="icon"><i class="icon icon-rename" ></i></a>
|
<a ng-if="boardservice.canManage() && !label.edit" ng-click="label.edit=true" class="icon"><i class="icon icon-rename" ></i></a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
<li ng-if="status.createLabel">
|
<li ng-if="status.createLabel">
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
<li ng-if="!status.createLabel" class="label-create">
|
<li ng-if="boardservice.canManage() && !status.createLabel" class="label-create">
|
||||||
<a ng-click="status.createLabel=true"><span class="icon icon-add"> </span> <?php p($l->t('Create a new label')); ?></a>
|
<a ng-click="status.createLabel=true"><span class="icon icon-add"> </span> <?php p($l->t('Create a new label')); ?></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
style="width:100%;" title="Choose a label"
|
style="width:100%;" title="Choose a label"
|
||||||
placeholder="Add a label"
|
placeholder="Add a label"
|
||||||
on-select="labelAssign($item, $model)"
|
on-select="labelAssign($item, $model)"
|
||||||
on-remove="labelRemove($item, $model)" ng-disabled="archived">
|
on-remove="labelRemove($item, $model)" ng-disabled="!boardservice.canEdit() || archived">
|
||||||
<ui-select-match placeholder="Select labels..."><span
|
<ui-select-match placeholder="Select labels..."><span
|
||||||
class="select-label"
|
class="select-label"
|
||||||
style="background-color:#{{$item.color}}">{{$item.title}} </span>
|
style="background-color:#{{$item.color}}">{{$item.title}} </span>
|
||||||
|
|||||||
@@ -7,18 +7,15 @@
|
|||||||
<a href="#/board/{{b.id}}/" ng-if="!b.status.edit">{{ b.title }}</a>
|
<a href="#/board/{{b.id}}/" ng-if="!b.status.edit">{{ b.title }}</a>
|
||||||
<div class="app-navigation-entry-utils" ng-show="!b.status.edit" style="position:absolute;">
|
<div class="app-navigation-entry-utils" ng-show="!b.status.edit" style="position:absolute;">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="app-navigation-entry-utils-menu-share svg" ng-show="b.shared>0"><i class="icon icon-share"> </i></li>
|
<li class="app-navigation-entry-utils-menu-share svg" ng-show="b.shared>0"><i class="icon icon-share" title="<?php p($l->t('Shared with you')); ?>"> </i></li>
|
||||||
<li class="app-navigation-entry-utils-menu-button svg"><button class="icon-more"></button></li>
|
<li class="app-navigation-entry-utils-menu-button svg"><button class="icon-more"></button></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-navigation-entry-menu app-navigation-noclose" ng-show="!b.status.edit">
|
<div class="app-navigation-entry-menu app-navigation-noclose" ng-show="!b.status.edit">
|
||||||
<ul>
|
<ul>
|
||||||
<!--
|
<li ng-show="b.owner===user"><button class="icon-rename svg" title="<?php p($l->t('edit')); ?>" ng-click="b.status.edit=true"></button></li>
|
||||||
TODO: Link to board sharing details
|
<li ng-show="b.owner===user"><button class="icon-delete svg" title="<?php p($l->t('delete')); ?>" ng-click="boardDelete(b)"></button></li>
|
||||||
<li><button class="icon-share svg" title="share"></button></li>
|
<li ng-show="b.owner!==user"><button class="icon-delete svg" title="<?php p($l->t('remove share')); ?>" ng-click="boardRemoveShare(b)"></button></li>
|
||||||
//-->
|
|
||||||
<li><button class="icon-rename svg" title="rename" ng-click="b.status.edit=true"></button></li>
|
|
||||||
<li><button class="icon-delete svg" title="delete" ng-click="boardDelete(b)"></button></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-navigation-entry-deleted" ng-show="false">
|
<div class="app-navigation-entry-deleted" ng-show="false">
|
||||||
@@ -36,7 +33,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Add new Board //-->
|
|
||||||
<li>
|
<li>
|
||||||
<a ng-click="status.addBoard=!status.addBoard" ng-show="!status.addBoard" class="icon-add app-navigation-noclose">
|
<a ng-click="status.addBoard=!status.addBoard" ng-show="!status.addBoard" class="icon-add app-navigation-noclose">
|
||||||
<?php p($l->t('Create a new board')); ?>
|
<?php p($l->t('Create a new board')); ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user