Convert AccessList

Signed-off-by: Jonas Rittershofer <jotoeri@users.noreply.github.com>
This commit is contained in:
Jonas Rittershofer 2020-04-09 18:21:59 +02:00
commit 68f2d9f2c6
8 changed files with 120 additions and 278 deletions

View file

@ -94,108 +94,6 @@ class ApiController extends Controller {
$this->logger = $logger;
}
/**
* Transforms a string with user and group names to an array
* of nextcloud users and groups
* @param string $item
* @return Array
*/
private function convertAccessList($item) : array {
$split = [];
if (strpos($item, 'user_') === 0) {
$user = $this->userManager->get(substr($item, 5));
$split = [
'id' => $user->getUID(),
'user' => $user->getUID(),
'type' => 'user',
'desc' => 'user',
'icon' => 'icon-user',
'displayName' => $user->getDisplayName(),
'avatarURL' => '',
'lastLogin' => $user->getLastLogin(),
'cloudId' => $user->getCloudId()
];
} elseif (strpos($item, 'group_') === 0) {
$group = substr($item, 6);
$group = $this->groupManager->get($group);
$split = [
'id' => $group->getGID(),
'user' => $group->getGID(),
'type' => 'group',
'desc' => 'group',
'icon' => 'icon-group',
'displayName' => $group->getDisplayName(),
'avatarURL' => '',
];
}
return($split);
}
/**
* Check if current user is in the access list
* @param Array $accessList
* @return Boolean
*/
private function checkUserAccess($accessList) {
foreach ($accessList as $accessItem ) {
if ($accessItem['type'] === 'user' && $accessItem['id'] === \OC::$server->getUserSession()->getUser()->getUID()) {
return true;
}
}
return false;
}
/**
* Check If current user is member of a group in the access list
* @param Array $accessList
* @return Boolean
*/
private function checkGroupAccess($accessList) {
foreach ($accessList as $accessItem ) {
if ($accessItem['type'] === 'group' && $this->groupManager->isInGroup(\OC::$server->getUserSession()->getUser()->getUID(),$accessItem['id'])) {
return true;
}
}
return false;
}
/**
* Set the access right of the current user for the form
* @param Array $form
* @param Array $shares
* @return String
*/
private function grantAccessAs($form, $shares) {
if (!\OC::$server->getUserSession()->getUser() instanceof IUser) {
$currentUser = '';
} else {
$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
}
$grantAccessAs = 'none';
if ($form['ownerId'] === $currentUser) {
$grantAccessAs = 'owner';
} elseif ($form['access'] === 'public') {
$grantAccessAs = 'public';
} elseif ($form['access'] === 'registered' && \OC::$server->getUserSession()->getUser() instanceof IUser) {
$grantAccessAs = 'registered';
} elseif ($form['access'] === 'hidden' && ($form['ownerId'] === \OC::$server->getUserSession()->getUser())) {
$grantAccessAs = 'hidden';
} elseif ($this->checkUserAccess($shares)) {
$grantAccessAs = 'userInvitation';
} elseif ($this->checkGroupAccess($shares)) {
$grantAccessAs = 'groupInvitation';
} elseif ($this->groupManager->isAdmin($currentUser)) {
$grantAccessAs = 'admin';
}
return $grantAccessAs;
}
/**
* Read an entire form based on form id
* @NoAdminRequired
@ -215,31 +113,6 @@ class ApiController extends Controller {
}
/**
* Read all shares (users and groups with access) of a form based on the form id
* @NoAdminRequired
* @param Integer $formId
* @return Array
*/
public function getShares($formId) {
$accessList = array();
try {
$form = $this->formMapper->find($formId);
if (!strpos('|public|hidden|registered', $form->getAccess())) {
$accessList = explode(';', $form->getAccess());
$accessList = array_filter($accessList);
$accessList = array_map(array($this, 'convertAccessList'), $accessList);
}
} catch (DoesNotExistException $e) {
// return silently
} finally {
return $accessList;
}
}
public function getQuestions($formId) : array {
$questionList = [];
try{
@ -310,10 +183,8 @@ class ApiController extends Controller {
$data = [
'id' => $form['id'],
'result' => $result,
'grantedAs' => $this->grantAccessAs($form, $shares),
'mode' => $mode,
'form' => $form,
'shares' => $shares,
'questions' => $this->getQuestions($form['id']),
];
} catch (DoesNotExistException $e) {
@ -335,7 +206,6 @@ class ApiController extends Controller {
'id' => $form->getId(),
'form' => $form->read(),
'mode' => 'edit',
'shares' => $this->getShares($form->getId()),
'questions' => $this->getQuestions($form->getId())
];
}
@ -394,19 +264,12 @@ class ApiController extends Controller {
$newForm->setIsAnonymous($form['isAnonymous']);
$newForm->setSubmitOnce($form['submitOnce']);
if ($form['access'] === 'select') {
$shareAccess = '';
foreach ($shares as $shareElement) {
if ($shareElement['type'] === 'user') {
$shareAccess = $shareAccess . 'user_' . $shareElement['id'] . ';';
} elseif ($shareElement['type'] === 'group') {
$shareAccess = $shareAccess . 'group_' . $shareElement['id'] . ';';
}
}
$newForm->setAccess(rtrim($shareAccess, ';'));
} else {
$newForm->setAccess($form['access']);
// Only write Users/Groups-Arrays if necessary.
if($form['access']['type'] !== 'selected') {
unset($form['access']['users']);
unset($form['access']['groups']);
}
$newForm->setAccess($form['access']);
if ($form['expires']) {
$newForm->setExpirationDate(date('Y-m-d H:i:s', strtotime($form['expirationDate'])));
@ -466,7 +329,9 @@ class ApiController extends Controller {
));
$form->setTitle('New form');
$form->setDescription('');
$form->setAccess('public');
$form->setAccess([
'type' => 'public'
]);
$this->formMapper->insert($form);

View file

@ -47,6 +47,7 @@ use OCP\AppFramework\Http\TemplateResponse;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IRequest;
use OCP\ILogger;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\User; //To do: replace according to API
@ -66,6 +67,9 @@ class PageController extends Controller {
private $userMgr;
private $groupManager;
/** @var ILogger */
private $logger;
public function __construct(
IRequest $request,
IUserManager $userMgr,
@ -77,7 +81,8 @@ class PageController extends Controller {
QuestionMapper $questionMapper,
OptionMapper $optionMapper,
SubmissionMapper $SubmissionMapper,
AnswerMapper $AnswerMapper
AnswerMapper $AnswerMapper,
ILogger $logger
) {
parent::__construct(Application::APP_ID, $request);
$this->userMgr = $userMgr;
@ -90,6 +95,7 @@ class PageController extends Controller {
$this->optionMapper = $optionMapper;
$this->submissionMapper = $SubmissionMapper;
$this->answerMapper = $AnswerMapper;
$this->logger = $logger;
}
/**
@ -304,131 +310,55 @@ class PageController extends Controller {
/**
* @NoAdminRequired
* @param string $searchTerm
* @param string $groups
* @param string $users
* @return array
*/
public function search($searchTerm, $groups, $users) {
return array_merge($this->searchForGroups($searchTerm, $groups), $this->searchForUsers($searchTerm, $users));
}
/**
* @NoAdminRequired
* @param string $searchTerm
* @param string $groups
* @return array
*/
public function searchForGroups($searchTerm, $groups) {
$selectedGroups = json_decode($groups);
$groups = $this->groupManager->search($searchTerm);
$gids = [];
$sgids = [];
foreach ($selectedGroups as $sg) {
$sgids[] = str_replace('group_', '', $sg);
}
foreach ($groups as $g) {
$gids[] = $g->getGID();
}
$diffGids = array_diff($gids, $sgids);
$gids = [];
foreach ($diffGids as $g) {
$gids[] = ['gid' => $g, 'isGroup' => true];
}
return $gids;
}
/**
* @NoAdminRequired
* @param string $searchTerm
* @param string $users
* @return array
*/
public function searchForUsers($searchTerm, $users) {
$selectedUsers = json_decode($users);
Util::writeLog('forms', print_r($selectedUsers, true), Util::ERROR);
$userNames = $this->userMgr->searchDisplayName($searchTerm);
$users = [];
$sUsers = [];
foreach ($selectedUsers as $su) {
$sUsers[] = str_replace('user_', '', $su);
}
foreach ($userNames as $u) {
$allreadyAdded = false;
foreach ($sUsers as &$su) {
if ($su === $u->getUID()) {
unset($su);
$allreadyAdded = true;
break;
}
}
if (!$allreadyAdded) {
$users[] = ['uid' => $u->getUID(), 'displayName' => $u->getDisplayName(), 'isGroup' => false];
} else {
continue;
}
}
return $users;
}
/**
* @return \OCP\IGroup[]
*/
private function getGroups() {
$groups = $this->groupManager->getUserGroups(\OC::$server->getUserSession()->getUser());
return array_map(function(IGroup $group) {
return $group->getGID();
}, $groups);
}
/**
* Check if user has access to this form
*
* @param Form $form
* @return bool
*/
private function hasUserAccess($form) {
private function hasUserAccess(Form $form): bool {
$access = $form->getAccess();
$ownerId = $form->getOwnerId();
if ($access === 'public' || $access === 'hidden') {
if ($access['type'] === 'public') {
return true;
}
// Refuse access, if not public and no user logged in.
if ($this->userId === null) {
return false;
}
if ($access === 'registered') {
if ($form->getSubmitOnce()) {
$participants = $this->submissionMapper->findParticipantsByForm($form->getId());
foreach($participants as $participant) {
// Don't allow access if user has already taken part
if ($participant->getUserId() === $this->userId) return false;
}
}
return true;
}
// Always grant access to owner.
if ($ownerId === $this->userId) {
return true;
}
Util::writeLog('forms', $this->userId, Util::ERROR);
$userGroups = $this->getGroups();
$arr = explode(';', $access);
foreach ($arr as $item) {
if (strpos($item, 'group_') === 0) {
$grp = substr($item, 6);
foreach ($userGroups as $userGroup) {
if ($userGroup === $grp) {
return true;
}
}
} else {
if (strpos($item, 'user_') === 0) {
$usr = substr($item, 5);
if ($usr === $this->userId) {
return true;
}
// Refuse access, if SubmitOnce is set and user already has taken part.
if ($form->getSubmitOnce()) {
$participants = $this->submissionMapper->findParticipantsByForm($form->getId());
foreach($participants as $participant) {
if ($participant === $this->userId) {
return false;
}
}
}
// Now all remaining users are allowed, if access-type 'registered'.
if ($access['type'] === 'registered') {
return true;
}
// Selected Access remains.
// Grant Access, if user is in users-Array.
if (in_array($this->userId, $access['users'])) {
return true;
}
// Check if access granted by group.
foreach ($access['groups'] as $group) {
if( $this->groupManager->isInGroup($this->userId, $group) ) {
return true;
}
}
// None of the possible access-options matched.
return false;
}
}