Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bollu <cyrpub@bollu.be>2022-02-05 22:49:17 +0300
committerCyrille Bollu <cyrpub@bollu.be>2022-04-11 22:58:24 +0300
commitc6a5c07041d2e5d20771409aede8b755d28372ac (patch)
tree71051efd25c16bed5a419eb1670477f1f5471933 /apps/files_sharing/lib
parent60f946aba5862102a81100b09e26b37b6d59a3fa (diff)
Adds a "Request password" button to the public share authentication page for shares
of type TYPE_EMAIL, when the "video verification" checkbox isn't checked. Users accessing non-anonymous public shares (TYPE_EMAIL shares) can now request a temporary password themselves. - Creates a migration step for the files_sharing app to add the 'password_expiration_time' attribute to the oc_shares table. - Makes share temporary passwords' expiration time configurable via a system value. - Adds a system config value to allow permanent share passwords -Fixes a typo in a comment in apps/files_sharing/src/components/SharingEntryLink.vue See https://github.com/nextcloud/server/issues/31005 Signed-off-by: Cyrille Bollu <cyrpub@bollu.be>
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php37
-rw-r--r--apps/files_sharing/lib/Controller/ShareController.php113
-rw-r--r--apps/files_sharing/lib/Migration/Version24000Date20220208195521.php51
3 files changed, 155 insertions, 46 deletions
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index 069cba42bb6..d324af3e9f2 100644
--- a/apps/files_sharing/lib/Controller/ShareAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareAPIController.php
@@ -279,6 +279,7 @@ class ShareAPIController extends OCSController {
} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
$result['share_with'] = $share->getSharedWith();
$result['password'] = $share->getPassword();
+ $result['password_expiration_time'] = $share->getPasswordExpirationTime();
$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
$result['token'] = $share->getToken();
@@ -570,6 +571,10 @@ class ShareAPIController extends OCSController {
// Set password
if ($password !== '') {
$share->setPassword($password);
+ // Shares shared by email have temporary passwords by default
+ if ($shareType === IShare::TYPE_EMAIL) {
+ $this->setSharePasswordExpirationTime($share);
+ }
}
// Only share by mail have a recipient
@@ -1177,6 +1182,9 @@ class ShareAPIController extends OCSController {
$share->setPassword(null);
} elseif ($password !== null) {
$share->setPassword($password);
+ if ($share->getShareType() === IShare::TYPE_EMAIL) {
+ $this->setSharePasswordExpirationTime($share);
+ }
}
if ($label !== null) {
@@ -1514,6 +1522,35 @@ class ShareAPIController extends OCSController {
}
/**
+ * Set the share's password expiration time
+ */
+ private function setSharePasswordExpirationTime(IShare $share): void {
+ if ($this->config->getSystemValue('allow_mail_share_permanent_password')) {
+ // Sets password expiration date to NULL
+ $share->setPasswordExpirationTime();
+ return;
+ }
+ // Sets password expiration date
+ $expirationTime = null;
+ try {
+ $now = new \DateTime();
+ $expirationInterval = $this->config->getSystemValue('share_temporary_password_expiration_interval');
+ if ($expirationInterval === '' || is_null($expirationInterval)) {
+ $expirationInterval = 'P0DT15M';
+ }
+ $expirationTime = $now->add(new \DateInterval($expirationInterval));
+ } catch (\Exception $e) {
+ // Catches invalid format for system value 'share_temporary_password_expiration_interval'
+ \OC::$server->getLogger()->logException($e, [
+ 'message' => 'The \'share_temporary_password_expiration_interval\' system setting does not respect the DateInterval::__construct() format. Setting it to \'P0DT15M\''
+ ]);
+ $expirationTime = $now->add(new \DateInterval('P0DT15M'));
+ } finally {
+ $share->setPasswordExpirationTime($expirationTime);
+ }
+ }
+
+ /**
* Since we have multiple providers but the OCS Share API v1 does
* not support this we need to check all backends.
*
diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php
index 411873c9c86..a12878e6de2 100644
--- a/apps/files_sharing/lib/Controller/ShareController.php
+++ b/apps/files_sharing/lib/Controller/ShareController.php
@@ -72,6 +72,7 @@ use OCP\ISession;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
+use OCP\Security\ISecureRandom;
use OCP\Share;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager as ShareManager;
@@ -84,53 +85,21 @@ use OCP\Template;
* @package OCA\Files_Sharing\Controllers
*/
class ShareController extends AuthPublicShareController {
+ protected IConfig $config;
+ protected IUserManager $userManager;
+ protected ILogger $logger;
+ protected \OCP\Activity\IManager $activityManager;
+ protected IPreview $previewManager;
+ protected IRootFolder $rootFolder;
+ protected FederatedShareProvider $federatedShareProvider;
+ protected IAccountManager $accountManager;
+ protected IEventDispatcher $eventDispatcher;
+ protected IL10N $l10n;
+ protected Defaults $defaults;
+ protected ShareManager $shareManager;
+ protected ISecureRandom $secureRandom;
+ protected ?Share\IShare $share = null;
- /** @var IConfig */
- protected $config;
- /** @var IUserManager */
- protected $userManager;
- /** @var ILogger */
- protected $logger;
- /** @var \OCP\Activity\IManager */
- protected $activityManager;
- /** @var IPreview */
- protected $previewManager;
- /** @var IRootFolder */
- protected $rootFolder;
- /** @var FederatedShareProvider */
- protected $federatedShareProvider;
- /** @var IAccountManager */
- protected $accountManager;
- /** @var IEventDispatcher */
- protected $eventDispatcher;
- /** @var IL10N */
- protected $l10n;
- /** @var Defaults */
- protected $defaults;
- /** @var ShareManager */
- protected $shareManager;
-
- /** @var Share\IShare */
- protected $share;
-
- /**
- * @param string $appName
- * @param IRequest $request
- * @param IConfig $config
- * @param IURLGenerator $urlGenerator
- * @param IUserManager $userManager
- * @param ILogger $logger
- * @param \OCP\Activity\IManager $activityManager
- * @param \OCP\Share\IManager $shareManager
- * @param ISession $session
- * @param IPreview $previewManager
- * @param IRootFolder $rootFolder
- * @param FederatedShareProvider $federatedShareProvider
- * @param IAccountManager $accountManager
- * @param IEventDispatcher $eventDispatcher
- * @param IL10N $l10n
- * @param Defaults $defaults
- */
public function __construct(string $appName,
IRequest $request,
IConfig $config,
@@ -146,6 +115,7 @@ class ShareController extends AuthPublicShareController {
IAccountManager $accountManager,
IEventDispatcher $eventDispatcher,
IL10N $l10n,
+ ISecureRandom $secureRandom,
Defaults $defaults) {
parent::__construct($appName, $request, $session, $urlGenerator);
@@ -159,6 +129,7 @@ class ShareController extends AuthPublicShareController {
$this->accountManager = $accountManager;
$this->eventDispatcher = $eventDispatcher;
$this->l10n = $l10n;
+ $this->secureRandom = $secureRandom;
$this->defaults = $defaults;
$this->shareManager = $shareManager;
}
@@ -209,6 +180,56 @@ class ShareController extends AuthPublicShareController {
return $response;
}
+ /**
+ * The template to show after user identification
+ */
+ protected function showIdentificationResult(bool $success = false): TemplateResponse {
+ $templateParameters = ['share' => $this->share, 'identityOk' => $success];
+
+ $this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
+
+ $response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
+ if ($this->share->getSendPasswordByTalk()) {
+ $csp = new ContentSecurityPolicy();
+ $csp->addAllowedConnectDomain('*');
+ $csp->addAllowedMediaDomain('blob:');
+ $response->setContentSecurityPolicy($csp);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Validate the identity token of a public share
+ *
+ * @param ?string $identityToken
+ * @return bool
+ */
+ protected function validateIdentity(?string $identityToken = null): bool {
+
+ if ($this->share->getShareType() !== IShare::TYPE_EMAIL) {
+ return false;
+ }
+
+ if ($identityToken === null || $this->share->getSharedWith() === null) {
+ return false;
+ }
+
+ return $identityToken === $this->share->getSharedWith();
+ }
+
+ /**
+ * Generates a password for the share, respecting any password policy defined
+ */
+ protected function generatePassword(): void {
+ $event = new \OCP\Security\Events\GenerateSecurePasswordEvent();
+ $this->eventDispatcher->dispatchTyped($event);
+ $password = $event->getPassword() ?? $this->secureRandom->generate(20);
+
+ $this->share->setPassword($password);
+ $this->shareManager->updateShare($this->share);
+ }
+
protected function verifyPassword(string $password): bool {
return $this->shareManager->checkPassword($this->share, $password);
}
diff --git a/apps/files_sharing/lib/Migration/Version24000Date20220208195521.php b/apps/files_sharing/lib/Migration/Version24000Date20220208195521.php
new file mode 100644
index 00000000000..d5f938dde6d
--- /dev/null
+++ b/apps/files_sharing/lib/Migration/Version24000Date20220208195521.php
@@ -0,0 +1,51 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2022 Vincent Petry <vincent@nextloud.com>
+ *
+ * @author Vincent Petry <vincent@nextcloud.com>
+ *
+ * @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\Files_Sharing\Migration;
+
+use Closure;
+use OCP\DB\Types;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version24000Date20220208195521 extends SimpleMigrationStep {
+
+ /**
+ * @param IOutput $output
+ * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
+ * @param array $options
+ * @return null|ISchemaWrapper
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+ $schema = $schemaClosure();
+ $table = $schema->getTable('share');
+ $table->addColumn('password_expiration_time', Types::DATETIME, [
+ 'notnull' => false,
+ ]);
+ return $schema;
+ }
+
+}