-
-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #940 from nextcloud/public-page
Public page for MyMaps
- Loading branch information
Showing
35 changed files
with
2,141 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
<?php | ||
|
||
/** | ||
* Nextcloud - maps | ||
* | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. See the COPYING file. | ||
* | ||
* @author Julien Veyssier <eneiluj@posteo.net> | ||
* @copyright Julien Veyssier 2019 | ||
*/ | ||
|
||
namespace OCA\Maps\Controller; | ||
|
||
use OC\Files\Node\Node; | ||
use OCP\EventDispatcher\IEventDispatcher; | ||
use OCP\Files\IRootFolder; | ||
use OCP\Files\NotFoundException; | ||
use OCP\Files\NotPermittedException; | ||
use OCP\IConfig; | ||
use OCP\IInitialStateService; | ||
use OCP\IRequest; | ||
use OCP\IAvatarManager; | ||
use OCP\AppFramework\Http\DataDisplayResponse; | ||
use OCP\AppFramework\Http\DataResponse; | ||
use OCP\IDBConnection; | ||
use OCP\AppFramework\Controller; | ||
use OCP\Contacts\IManager; | ||
use OCA\Maps\Service\AddressService; | ||
use \OCP\DB\QueryBuilder\IQueryBuilder; | ||
use \OCA\DAV\CardDAV\CardDavBackend; | ||
use OCP\ISession; | ||
use OCP\IURLGenerator; | ||
use OCP\IUserManager; | ||
use OCP\Share\Exceptions\ShareNotFound; | ||
use OCP\Share\IManager as ShareManager; | ||
use \Sabre\VObject\Property\Text; | ||
use \Sabre\VObject\Reader; | ||
|
||
class PublicContactsController extends PublicPageController { | ||
protected IManager $contactsManager; | ||
protected AddressService $addressService; | ||
protected IQueryBuilder $qb; | ||
protected CardDavBackend $cdBackend; | ||
protected IAvatarManager $avatarManager; | ||
protected IRootFolder $root; | ||
|
||
/** | ||
* @param $appName | ||
* @param IRequest $request | ||
* @param IEventDispatcher $eventDispatcher | ||
* @param IConfig $config | ||
* @param IInitialStateService $initialStateService | ||
* @param IURLGenerator $urlGenerator | ||
* @param ShareManager $shareManager | ||
* @param IUserManager $userManager | ||
* @param ISession $session | ||
* @param IDBConnection $dbconnection | ||
* @param IManager $contactsManager | ||
* @param AddressService $addressService | ||
* @param CardDavBackend $cdBackend | ||
* @param IAvatarManager $avatarManager | ||
* @param IRootFolder $root | ||
*/ | ||
public function __construct($appName, | ||
IRequest $request, | ||
IEventDispatcher $eventDispatcher, | ||
IConfig $config, | ||
IInitialStateService $initialStateService, | ||
IURLGenerator $urlGenerator, | ||
ShareManager $shareManager, | ||
IUserManager $userManager, | ||
ISession $session, | ||
IManager $contactsManager, | ||
IDBConnection $dbconnection, | ||
AddressService $addressService, | ||
CardDavBackend $cdBackend, | ||
IAvatarManager $avatarManager, | ||
IRootFolder $root){ | ||
parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); | ||
$this->avatarManager = $avatarManager; | ||
$this->contactsManager = $contactsManager; | ||
$this->addressService = $addressService; | ||
$this->qb = $dbconnection->getQueryBuilder(); | ||
$this->cdBackend = $cdBackend; | ||
$this->root = $root; | ||
} | ||
|
||
/** | ||
* Validate the permissions of the share | ||
* | ||
* @param Share\IShare $share | ||
* @return bool | ||
*/ | ||
private function validateShare(\OCP\Share\IShare $share) { | ||
// If the owner is disabled no access to the link is granted | ||
$owner = $this->userManager->get($share->getShareOwner()); | ||
if ($owner === null || !$owner->isEnabled()) { | ||
return false; | ||
} | ||
|
||
// If the initiator of the share is disabled no access is granted | ||
$initiator = $this->userManager->get($share->getSharedBy()); | ||
if ($initiator === null || !$initiator->isEnabled()) { | ||
return false; | ||
} | ||
|
||
return $share->getNode()->isReadable() && $share->getNode()->isShareable(); | ||
} | ||
|
||
/** | ||
* @return \OCP\Share\IShare | ||
* @throws NotFoundException | ||
*/ | ||
private function getShare() { | ||
// Check whether share exists | ||
try { | ||
$share = $this->shareManager->getShareByToken($this->getToken()); | ||
} catch (ShareNotFound $e) { | ||
// The share does not exists, we do not emit an ShareLinkAccessedEvent | ||
throw new NotFoundException(); | ||
} | ||
|
||
if (!$this->validateShare($share)) { | ||
throw new NotFoundException(); | ||
} | ||
return $share; | ||
} | ||
|
||
/** | ||
* @return \OCP\Files\File|\OCP\Files\Folder | ||
* @throws NotFoundException | ||
*/ | ||
private function getShareNode() { | ||
\OC_User::setIncognitoMode(true); | ||
|
||
$share = $this->getShare(); | ||
|
||
return $share->getNode(); | ||
} | ||
|
||
/** | ||
* @PublicPage | ||
* | ||
* @return DataResponse | ||
* @throws NotFoundException | ||
* @throws NotPermittedException | ||
* @throws \OCP\Files\InvalidPathException | ||
*/ | ||
public function getContacts(): DataResponse { | ||
$share = $this->getShare(); | ||
$permissions = $share->getPermissions(); | ||
$folder = $this->getShareNode(); | ||
$isReadable = (bool) ($permissions & (1 << 0)); | ||
if ($isReadable) { | ||
//Fixme add contacts for my-maps | ||
$result = []; | ||
$files = $folder->search('.vcf'); | ||
foreach ($files as $file) { | ||
// $cards = explode("END:VCARD\r\n", $file->getContent()); | ||
$cards = [$file->getContent()]; | ||
foreach ($cards as $card) { | ||
$vcard = Reader::read($card."END:VCARD\r\n"); | ||
if (isset($vcard->GEO)) { | ||
$geo = $vcard->GEO; | ||
if (is_string($geo->getValue()) && strlen($geo->getValue()) > 1) { | ||
$result[] = $this->vCardToArray($permissions, $file, $vcard, $geo->getValue()); | ||
} elseif (is_countable($geo) && count($geo)>0 && is_iterable($geo)) { | ||
foreach ($geo as $g) { | ||
if (strlen($g->getValue()) > 1) { | ||
$result[] = $this->vCardToArray($permissions, $file, $vcard, $g->getValue()); | ||
} | ||
} | ||
} | ||
} | ||
if (isset($vcard->ADR) && count($vcard->ADR) > 0) { | ||
foreach ($vcard->ADR as $adr) { | ||
$geo = $this->addressService->addressToGeo($adr->getValue(), $file->getId()); | ||
//var_dump($adr->parameters()['TYPE']->getValue()); | ||
$adrtype = ''; | ||
if (isset($adr->parameters()['TYPE'])) { | ||
$adrtype = $adr->parameters()['TYPE']->getValue(); | ||
} | ||
if (is_string($geo) && strlen($geo) > 1) { | ||
$result[] = $this->vCardToArray($permissions, $file, $vcard, $geo, $adrtype, $adr->getValue(), $file->getId()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return new DataResponse($result); | ||
} else { | ||
throw new NotPermittedException(); | ||
} | ||
} | ||
|
||
/** | ||
* @param int $sharePermissions | ||
* @param Node $file | ||
* @param \Sabre\VObject\Document $vcard | ||
* @param string $geo | ||
* @param string|null $adrtype | ||
* @param string|null $adr | ||
* @param int|null $fileId | ||
* @return array | ||
* @throws NotFoundException | ||
* @throws \OCP\Files\InvalidPathException | ||
*/ | ||
private function vCardToArray(int $sharePermissions, Node $file, \Sabre\VObject\Document $vcard, string $geo, ?string $adrtype=null, ?string $adr=null, ?int $fileId = null): array { | ||
$FNArray = $vcard->FN ? $vcard->FN->getJsonValue() : []; | ||
$fn = array_shift($FNArray); | ||
$NArray = $vcard->N ? $vcard->N->getJsonValue() : []; | ||
$n = array_shift($NArray); | ||
if (!is_null($n)) { | ||
if (is_array($n)) { | ||
$n = $this->N2FN(array_shift($n)); | ||
} elseif (is_string($n)) { | ||
$n = $this->N2FN($n); | ||
} | ||
|
||
} | ||
$UIDArray = $vcard->UID->getJsonValue(); | ||
$uid = array_shift($UIDArray); | ||
$groups = $vcard->CATEGORIES; | ||
if (!is_null($groups)) { | ||
$groups = $groups->getValue(); | ||
} else { | ||
$groups = ''; | ||
} | ||
$result = [ | ||
'FN' => $fn ?? $n ?? '???', | ||
'UID' => $uid, | ||
'HAS_PHOTO' => (isset($vcard->PHOTO) && $vcard->PHOTO !== null), | ||
'FILEID' => $fileId, | ||
'ADR' => $adr ?? '', | ||
'ADRTYPE' => $adrtype ?? '', | ||
'PHOTO' => $vcard->PHOTO ?? '', | ||
'GEO' => $geo, | ||
'GROUPS' => $groups, | ||
'isReadable' => $file->isReadable() && ($sharePermissions & (1 << 0)), | ||
'isDeletable' => $file->isDeletable() && ($sharePermissions & (1 << 1)), | ||
'isUpdateable' => $file->isUpdateable() && ($sharePermissions & (1 << 3)), | ||
]; | ||
return $result; | ||
} | ||
|
||
/** | ||
* @param string $n | ||
* @return string|null | ||
*/ | ||
private function N2FN(string $n): ?string { | ||
if ($n) { | ||
$spl = explode($n, ';'); | ||
if (count($spl) >= 4) { | ||
return $spl[3] . ' ' . $spl[1] . ' ' . $spl[0]; | ||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
|
||
|
||
/** | ||
* @PublicPage | ||
* @NoCSRFRequired | ||
* | ||
* @param string $name | ||
* @return DataDisplayResponse | ||
* @throws NotFoundException | ||
* @throws NotPermittedException | ||
*/ | ||
public function getContactLetterAvatar(string $name): DataDisplayResponse { | ||
$av = $this->avatarManager->getGuestAvatar($name); | ||
$avatarContent = $av->getFile(64)->getContent(); | ||
return new DataDisplayResponse($avatarContent); | ||
} | ||
} |
Oops, something went wrong.