Passed
Push — master ( bbb39c...5026d2 )
by Christoph
27:34 queued 12:27
created
lib/public/Files.php 1 patch
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -49,73 +49,73 @@
 block discarded – undo
49 49
  * @deprecated 14.0.0
50 50
  */
51 51
 class Files {
52
-	/**
53
-	 * Recusive deletion of folders
54
-	 * @return bool
55
-	 * @since 5.0.0
56
-	 * @deprecated 14.0.0
57
-	 */
58
-	public static function rmdirr($dir) {
59
-		return \OC_Helper::rmdirr($dir);
60
-	}
52
+    /**
53
+     * Recusive deletion of folders
54
+     * @return bool
55
+     * @since 5.0.0
56
+     * @deprecated 14.0.0
57
+     */
58
+    public static function rmdirr($dir) {
59
+        return \OC_Helper::rmdirr($dir);
60
+    }
61 61
 
62
-	/**
63
-	 * Get the mimetype form a local file
64
-	 * @param string $path
65
-	 * @return string
66
-	 * does NOT work for ownClouds filesystem, use OC_FileSystem::getMimeType instead
67
-	 * @since 5.0.0
68
-	 * @deprecated 14.0.0
69
-	 */
70
-	public static function getMimeType($path) {
71
-		return \OC::$server->getMimeTypeDetector()->detect($path);
72
-	}
62
+    /**
63
+     * Get the mimetype form a local file
64
+     * @param string $path
65
+     * @return string
66
+     * does NOT work for ownClouds filesystem, use OC_FileSystem::getMimeType instead
67
+     * @since 5.0.0
68
+     * @deprecated 14.0.0
69
+     */
70
+    public static function getMimeType($path) {
71
+        return \OC::$server->getMimeTypeDetector()->detect($path);
72
+    }
73 73
 
74
-	/**
75
-	 * Search for files by mimetype
76
-	 * @param string $mimetype
77
-	 * @return array
78
-	 * @since 6.0.0
79
-	 * @deprecated 14.0.0
80
-	 */
81
-	public static function searchByMime($mimetype) {
82
-		return \OC\Files\Filesystem::searchByMime($mimetype);
83
-	}
74
+    /**
75
+     * Search for files by mimetype
76
+     * @param string $mimetype
77
+     * @return array
78
+     * @since 6.0.0
79
+     * @deprecated 14.0.0
80
+     */
81
+    public static function searchByMime($mimetype) {
82
+        return \OC\Files\Filesystem::searchByMime($mimetype);
83
+    }
84 84
 
85
-	/**
86
-	 * Copy the contents of one stream to another
87
-	 * @param resource $source
88
-	 * @param resource $target
89
-	 * @return int the number of bytes copied
90
-	 * @since 5.0.0
91
-	 * @deprecated 14.0.0
92
-	 */
93
-	public static function streamCopy($source, $target) {
94
-		[$count, ] = \OC_Helper::streamCopy($source, $target);
95
-		return $count;
96
-	}
85
+    /**
86
+     * Copy the contents of one stream to another
87
+     * @param resource $source
88
+     * @param resource $target
89
+     * @return int the number of bytes copied
90
+     * @since 5.0.0
91
+     * @deprecated 14.0.0
92
+     */
93
+    public static function streamCopy($source, $target) {
94
+        [$count, ] = \OC_Helper::streamCopy($source, $target);
95
+        return $count;
96
+    }
97 97
 
98
-	/**
99
-	 * Adds a suffix to the name in case the file exists
100
-	 * @param string $path
101
-	 * @param string $filename
102
-	 * @return string
103
-	 * @since 5.0.0
104
-	 * @deprecated 14.0.0 use getNonExistingName of the OCP\Files\Folder object
105
-	 */
106
-	public static function buildNotExistingFileName($path, $filename) {
107
-		return \OC_Helper::buildNotExistingFileName($path, $filename);
108
-	}
98
+    /**
99
+     * Adds a suffix to the name in case the file exists
100
+     * @param string $path
101
+     * @param string $filename
102
+     * @return string
103
+     * @since 5.0.0
104
+     * @deprecated 14.0.0 use getNonExistingName of the OCP\Files\Folder object
105
+     */
106
+    public static function buildNotExistingFileName($path, $filename) {
107
+        return \OC_Helper::buildNotExistingFileName($path, $filename);
108
+    }
109 109
 
110
-	/**
111
-	 * Gets the Storage for an app - creates the needed folder if they are not
112
-	 * existent
113
-	 * @param string $app
114
-	 * @return \OC\Files\View
115
-	 * @since 5.0.0
116
-	 * @deprecated 14.0.0 use IAppData instead
117
-	 */
118
-	public static function getStorage($app) {
119
-		return \OC_App::getStorage($app);
120
-	}
110
+    /**
111
+     * Gets the Storage for an app - creates the needed folder if they are not
112
+     * existent
113
+     * @param string $app
114
+     * @return \OC\Files\View
115
+     * @since 5.0.0
116
+     * @deprecated 14.0.0 use IAppData instead
117
+     */
118
+    public static function getStorage($app) {
119
+        return \OC_App::getStorage($app);
120
+    }
121 121
 }
Please login to merge, or discard this patch.
core/Command/L10n/CreateJs.php 1 patch
Indentation   +131 added lines, -131 removed lines patch added patch discarded remove patch
@@ -36,135 +36,135 @@
 block discarded – undo
36 36
 use UnexpectedValueException;
37 37
 
38 38
 class CreateJs extends Command implements CompletionAwareInterface {
39
-	protected function configure() {
40
-		$this
41
-			->setName('l10n:createjs')
42
-			->setDescription('Create javascript translation files for a given app')
43
-			->addArgument(
44
-				'app',
45
-				InputOption::VALUE_REQUIRED,
46
-				'name of the app'
47
-			)
48
-			->addArgument(
49
-				'lang',
50
-				InputOption::VALUE_OPTIONAL,
51
-				'name of the language'
52
-			);
53
-	}
54
-
55
-	protected function execute(InputInterface $input, OutputInterface $output): int {
56
-		$app = $input->getArgument('app');
57
-		$lang = $input->getArgument('lang');
58
-
59
-		$path = \OC_App::getAppPath($app);
60
-		if ($path === false) {
61
-			$output->writeln("The app <$app> is unknown.");
62
-			return 1;
63
-		}
64
-		$languages = $lang;
65
-		if (empty($lang)) {
66
-			$languages = $this->getAllLanguages($path);
67
-		}
68
-
69
-		foreach ($languages as $lang) {
70
-			$this->writeFiles($app, $path, $lang, $output);
71
-		}
72
-		return 0;
73
-	}
74
-
75
-	private function getAllLanguages($path) {
76
-		$result = [];
77
-		foreach (new DirectoryIterator("$path/l10n") as $fileInfo) {
78
-			if ($fileInfo->isDot()) {
79
-				continue;
80
-			}
81
-			if ($fileInfo->isDir()) {
82
-				continue;
83
-			}
84
-			if ($fileInfo->getExtension() !== 'php') {
85
-				continue;
86
-			}
87
-			$result[] = substr($fileInfo->getBasename(), 0, -4);
88
-		}
89
-
90
-		return $result;
91
-	}
92
-
93
-	private function writeFiles($app, $path, $lang, OutputInterface $output) {
94
-		[$translations, $plurals] = $this->loadTranslations($path, $lang);
95
-		$this->writeJsFile($app, $path, $lang, $output, $translations, $plurals);
96
-		$this->writeJsonFile($path, $lang, $output, $translations, $plurals);
97
-	}
98
-
99
-	private function writeJsFile($app, $path, $lang, OutputInterface $output, $translations, $plurals) {
100
-		$jsFile = "$path/l10n/$lang.js";
101
-		if (file_exists($jsFile)) {
102
-			$output->writeln("File already exists: $jsFile");
103
-			return;
104
-		}
105
-		$content = "OC.L10N.register(\n    \"$app\",\n    {\n    ";
106
-		$jsTrans = [];
107
-		foreach ($translations as $id => $val) {
108
-			if (is_array($val)) {
109
-				$val = '[ ' . implode(',', $val) . ']';
110
-			}
111
-			$jsTrans[] = "\"$id\" : \"$val\"";
112
-		}
113
-		$content .= implode(",\n    ", $jsTrans);
114
-		$content .= "\n},\n\"$plurals\");\n";
115
-
116
-		file_put_contents($jsFile, $content);
117
-		$output->writeln("Javascript translation file generated: $jsFile");
118
-	}
119
-
120
-	private function writeJsonFile($path, $lang, OutputInterface $output, $translations, $plurals) {
121
-		$jsFile = "$path/l10n/$lang.json";
122
-		if (file_exists($jsFile)) {
123
-			$output->writeln("File already exists: $jsFile");
124
-			return;
125
-		}
126
-		$content = ['translations' => $translations, 'pluralForm' => $plurals];
127
-		file_put_contents($jsFile, json_encode($content));
128
-		$output->writeln("Json translation file generated: $jsFile");
129
-	}
130
-
131
-	private function loadTranslations($path, $lang) {
132
-		$phpFile = "$path/l10n/$lang.php";
133
-		$TRANSLATIONS = [];
134
-		$PLURAL_FORMS = '';
135
-		if (!file_exists($phpFile)) {
136
-			throw new UnexpectedValueException("PHP translation file <$phpFile> does not exist.");
137
-		}
138
-		require $phpFile;
139
-
140
-		return [$TRANSLATIONS, $PLURAL_FORMS];
141
-	}
142
-
143
-	/**
144
-	 * Return possible values for the named option
145
-	 *
146
-	 * @param string $optionName
147
-	 * @param CompletionContext $context
148
-	 * @return string[]
149
-	 */
150
-	public function completeOptionValues($optionName, CompletionContext $context) {
151
-		return [];
152
-	}
153
-
154
-	/**
155
-	 * Return possible values for the named argument
156
-	 *
157
-	 * @param string $argumentName
158
-	 * @param CompletionContext $context
159
-	 * @return string[]
160
-	 */
161
-	public function completeArgumentValues($argumentName, CompletionContext $context) {
162
-		if ($argumentName === 'app') {
163
-			return \OC_App::getAllApps();
164
-		} elseif ($argumentName === 'lang') {
165
-			$appName = $context->getWordAtIndex($context->getWordIndex() - 1);
166
-			return $this->getAllLanguages(\OC_App::getAppPath($appName));
167
-		}
168
-		return [];
169
-	}
39
+    protected function configure() {
40
+        $this
41
+            ->setName('l10n:createjs')
42
+            ->setDescription('Create javascript translation files for a given app')
43
+            ->addArgument(
44
+                'app',
45
+                InputOption::VALUE_REQUIRED,
46
+                'name of the app'
47
+            )
48
+            ->addArgument(
49
+                'lang',
50
+                InputOption::VALUE_OPTIONAL,
51
+                'name of the language'
52
+            );
53
+    }
54
+
55
+    protected function execute(InputInterface $input, OutputInterface $output): int {
56
+        $app = $input->getArgument('app');
57
+        $lang = $input->getArgument('lang');
58
+
59
+        $path = \OC_App::getAppPath($app);
60
+        if ($path === false) {
61
+            $output->writeln("The app <$app> is unknown.");
62
+            return 1;
63
+        }
64
+        $languages = $lang;
65
+        if (empty($lang)) {
66
+            $languages = $this->getAllLanguages($path);
67
+        }
68
+
69
+        foreach ($languages as $lang) {
70
+            $this->writeFiles($app, $path, $lang, $output);
71
+        }
72
+        return 0;
73
+    }
74
+
75
+    private function getAllLanguages($path) {
76
+        $result = [];
77
+        foreach (new DirectoryIterator("$path/l10n") as $fileInfo) {
78
+            if ($fileInfo->isDot()) {
79
+                continue;
80
+            }
81
+            if ($fileInfo->isDir()) {
82
+                continue;
83
+            }
84
+            if ($fileInfo->getExtension() !== 'php') {
85
+                continue;
86
+            }
87
+            $result[] = substr($fileInfo->getBasename(), 0, -4);
88
+        }
89
+
90
+        return $result;
91
+    }
92
+
93
+    private function writeFiles($app, $path, $lang, OutputInterface $output) {
94
+        [$translations, $plurals] = $this->loadTranslations($path, $lang);
95
+        $this->writeJsFile($app, $path, $lang, $output, $translations, $plurals);
96
+        $this->writeJsonFile($path, $lang, $output, $translations, $plurals);
97
+    }
98
+
99
+    private function writeJsFile($app, $path, $lang, OutputInterface $output, $translations, $plurals) {
100
+        $jsFile = "$path/l10n/$lang.js";
101
+        if (file_exists($jsFile)) {
102
+            $output->writeln("File already exists: $jsFile");
103
+            return;
104
+        }
105
+        $content = "OC.L10N.register(\n    \"$app\",\n    {\n    ";
106
+        $jsTrans = [];
107
+        foreach ($translations as $id => $val) {
108
+            if (is_array($val)) {
109
+                $val = '[ ' . implode(',', $val) . ']';
110
+            }
111
+            $jsTrans[] = "\"$id\" : \"$val\"";
112
+        }
113
+        $content .= implode(",\n    ", $jsTrans);
114
+        $content .= "\n},\n\"$plurals\");\n";
115
+
116
+        file_put_contents($jsFile, $content);
117
+        $output->writeln("Javascript translation file generated: $jsFile");
118
+    }
119
+
120
+    private function writeJsonFile($path, $lang, OutputInterface $output, $translations, $plurals) {
121
+        $jsFile = "$path/l10n/$lang.json";
122
+        if (file_exists($jsFile)) {
123
+            $output->writeln("File already exists: $jsFile");
124
+            return;
125
+        }
126
+        $content = ['translations' => $translations, 'pluralForm' => $plurals];
127
+        file_put_contents($jsFile, json_encode($content));
128
+        $output->writeln("Json translation file generated: $jsFile");
129
+    }
130
+
131
+    private function loadTranslations($path, $lang) {
132
+        $phpFile = "$path/l10n/$lang.php";
133
+        $TRANSLATIONS = [];
134
+        $PLURAL_FORMS = '';
135
+        if (!file_exists($phpFile)) {
136
+            throw new UnexpectedValueException("PHP translation file <$phpFile> does not exist.");
137
+        }
138
+        require $phpFile;
139
+
140
+        return [$TRANSLATIONS, $PLURAL_FORMS];
141
+    }
142
+
143
+    /**
144
+     * Return possible values for the named option
145
+     *
146
+     * @param string $optionName
147
+     * @param CompletionContext $context
148
+     * @return string[]
149
+     */
150
+    public function completeOptionValues($optionName, CompletionContext $context) {
151
+        return [];
152
+    }
153
+
154
+    /**
155
+     * Return possible values for the named argument
156
+     *
157
+     * @param string $argumentName
158
+     * @param CompletionContext $context
159
+     * @return string[]
160
+     */
161
+    public function completeArgumentValues($argumentName, CompletionContext $context) {
162
+        if ($argumentName === 'app') {
163
+            return \OC_App::getAllApps();
164
+        } elseif ($argumentName === 'lang') {
165
+            $appName = $context->getWordAtIndex($context->getWordIndex() - 1);
166
+            return $this->getAllLanguages(\OC_App::getAppPath($appName));
167
+        }
168
+        return [];
169
+    }
170 170
 }
Please login to merge, or discard this patch.
core/Command/TwoFactorAuth/State.php 1 patch
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -35,74 +35,74 @@
 block discarded – undo
35 35
 
36 36
 class State extends Base {
37 37
 
38
-	/** @var IRegistry */
39
-	private $registry;
40
-
41
-	public function __construct(IRegistry $registry, IUserManager $userManager) {
42
-		parent::__construct('twofactorauth:state');
43
-
44
-		$this->registry = $registry;
45
-		$this->userManager = $userManager;
46
-	}
47
-
48
-	protected function configure() {
49
-		parent::configure();
50
-
51
-		$this->setName('twofactorauth:state');
52
-		$this->setDescription('Get the two-factor authentication (2FA) state of a user');
53
-		$this->addArgument('uid', InputArgument::REQUIRED);
54
-	}
55
-
56
-	protected function execute(InputInterface $input, OutputInterface $output): int {
57
-		$uid = $input->getArgument('uid');
58
-		$user = $this->userManager->get($uid);
59
-		if (is_null($user)) {
60
-			$output->writeln("<error>Invalid UID</error>");
61
-			return 1;
62
-		}
63
-
64
-		$providerStates = $this->registry->getProviderStates($user);
65
-		$filtered = $this->filterEnabledDisabledUnknownProviders($providerStates);
66
-		[$enabled, $disabled] = $filtered;
67
-
68
-		if (!empty($enabled)) {
69
-			$output->writeln("Two-factor authentication is enabled for user $uid");
70
-		} else {
71
-			$output->writeln("Two-factor authentication is not enabled for user $uid");
72
-		}
73
-
74
-		$output->writeln("");
75
-		$this->printProviders("Enabled providers", $enabled, $output);
76
-		$this->printProviders("Disabled providers", $disabled, $output);
77
-
78
-		return 0;
79
-	}
80
-
81
-	private function filterEnabledDisabledUnknownProviders(array $providerStates): array {
82
-		$enabled = [];
83
-		$disabled = [];
84
-
85
-		foreach ($providerStates as $providerId => $isEnabled) {
86
-			if ($isEnabled) {
87
-				$enabled[] = $providerId;
88
-			} else {
89
-				$disabled[] = $providerId;
90
-			}
91
-		}
92
-
93
-		return [$enabled, $disabled];
94
-	}
95
-
96
-	private function printProviders(string $title, array $providers,
97
-									OutputInterface $output) {
98
-		if (empty($providers)) {
99
-			// Ignore and don't print anything
100
-			return;
101
-		}
102
-
103
-		$output->writeln($title . ":");
104
-		foreach ($providers as $provider) {
105
-			$output->writeln("- " . $provider);
106
-		}
107
-	}
38
+    /** @var IRegistry */
39
+    private $registry;
40
+
41
+    public function __construct(IRegistry $registry, IUserManager $userManager) {
42
+        parent::__construct('twofactorauth:state');
43
+
44
+        $this->registry = $registry;
45
+        $this->userManager = $userManager;
46
+    }
47
+
48
+    protected function configure() {
49
+        parent::configure();
50
+
51
+        $this->setName('twofactorauth:state');
52
+        $this->setDescription('Get the two-factor authentication (2FA) state of a user');
53
+        $this->addArgument('uid', InputArgument::REQUIRED);
54
+    }
55
+
56
+    protected function execute(InputInterface $input, OutputInterface $output): int {
57
+        $uid = $input->getArgument('uid');
58
+        $user = $this->userManager->get($uid);
59
+        if (is_null($user)) {
60
+            $output->writeln("<error>Invalid UID</error>");
61
+            return 1;
62
+        }
63
+
64
+        $providerStates = $this->registry->getProviderStates($user);
65
+        $filtered = $this->filterEnabledDisabledUnknownProviders($providerStates);
66
+        [$enabled, $disabled] = $filtered;
67
+
68
+        if (!empty($enabled)) {
69
+            $output->writeln("Two-factor authentication is enabled for user $uid");
70
+        } else {
71
+            $output->writeln("Two-factor authentication is not enabled for user $uid");
72
+        }
73
+
74
+        $output->writeln("");
75
+        $this->printProviders("Enabled providers", $enabled, $output);
76
+        $this->printProviders("Disabled providers", $disabled, $output);
77
+
78
+        return 0;
79
+    }
80
+
81
+    private function filterEnabledDisabledUnknownProviders(array $providerStates): array {
82
+        $enabled = [];
83
+        $disabled = [];
84
+
85
+        foreach ($providerStates as $providerId => $isEnabled) {
86
+            if ($isEnabled) {
87
+                $enabled[] = $providerId;
88
+            } else {
89
+                $disabled[] = $providerId;
90
+            }
91
+        }
92
+
93
+        return [$enabled, $disabled];
94
+    }
95
+
96
+    private function printProviders(string $title, array $providers,
97
+                                    OutputInterface $output) {
98
+        if (empty($providers)) {
99
+            // Ignore and don't print anything
100
+            return;
101
+        }
102
+
103
+        $output->writeln($title . ":");
104
+        foreach ($providers as $provider) {
105
+            $output->writeln("- " . $provider);
106
+        }
107
+    }
108 108
 }
Please login to merge, or discard this patch.
core/Controller/TwoFactorChallengeController.php 1 patch
Indentation   +207 added lines, -207 removed lines patch added patch discarded remove patch
@@ -43,239 +43,239 @@
 block discarded – undo
43 43
 
44 44
 class TwoFactorChallengeController extends Controller {
45 45
 
46
-	/** @var Manager */
47
-	private $twoFactorManager;
46
+    /** @var Manager */
47
+    private $twoFactorManager;
48 48
 
49
-	/** @var IUserSession */
50
-	private $userSession;
49
+    /** @var IUserSession */
50
+    private $userSession;
51 51
 
52
-	/** @var ISession */
53
-	private $session;
52
+    /** @var ISession */
53
+    private $session;
54 54
 
55
-	/** @var IURLGenerator */
56
-	private $urlGenerator;
55
+    /** @var IURLGenerator */
56
+    private $urlGenerator;
57 57
 
58
-	/**
59
-	 * @param string $appName
60
-	 * @param IRequest $request
61
-	 * @param Manager $twoFactorManager
62
-	 * @param IUserSession $userSession
63
-	 * @param ISession $session
64
-	 * @param IURLGenerator $urlGenerator
65
-	 */
66
-	public function __construct($appName, IRequest $request, Manager $twoFactorManager, IUserSession $userSession,
67
-		ISession $session, IURLGenerator $urlGenerator) {
68
-		parent::__construct($appName, $request);
69
-		$this->twoFactorManager = $twoFactorManager;
70
-		$this->userSession = $userSession;
71
-		$this->session = $session;
72
-		$this->urlGenerator = $urlGenerator;
73
-	}
58
+    /**
59
+     * @param string $appName
60
+     * @param IRequest $request
61
+     * @param Manager $twoFactorManager
62
+     * @param IUserSession $userSession
63
+     * @param ISession $session
64
+     * @param IURLGenerator $urlGenerator
65
+     */
66
+    public function __construct($appName, IRequest $request, Manager $twoFactorManager, IUserSession $userSession,
67
+        ISession $session, IURLGenerator $urlGenerator) {
68
+        parent::__construct($appName, $request);
69
+        $this->twoFactorManager = $twoFactorManager;
70
+        $this->userSession = $userSession;
71
+        $this->session = $session;
72
+        $this->urlGenerator = $urlGenerator;
73
+    }
74 74
 
75
-	/**
76
-	 * @return string
77
-	 */
78
-	protected function getLogoutUrl() {
79
-		return OC_User::getLogoutUrl($this->urlGenerator);
80
-	}
75
+    /**
76
+     * @return string
77
+     */
78
+    protected function getLogoutUrl() {
79
+        return OC_User::getLogoutUrl($this->urlGenerator);
80
+    }
81 81
 	
82
-	/**
83
-	 * @param IProvider[] $providers
84
-	 */
85
-	private function splitProvidersAndBackupCodes(array $providers): array {
86
-		$regular = [];
87
-		$backup = null;
88
-		foreach ($providers as $provider) {
89
-			if ($provider->getId() === 'backup_codes') {
90
-				$backup = $provider;
91
-			} else {
92
-				$regular[] = $provider;
93
-			}
94
-		}
82
+    /**
83
+     * @param IProvider[] $providers
84
+     */
85
+    private function splitProvidersAndBackupCodes(array $providers): array {
86
+        $regular = [];
87
+        $backup = null;
88
+        foreach ($providers as $provider) {
89
+            if ($provider->getId() === 'backup_codes') {
90
+                $backup = $provider;
91
+            } else {
92
+                $regular[] = $provider;
93
+            }
94
+        }
95 95
 
96
-		return [$regular, $backup];
97
-	}
96
+        return [$regular, $backup];
97
+    }
98 98
 
99
-	/**
100
-	 * @NoAdminRequired
101
-	 * @NoCSRFRequired
102
-	 * @TwoFactorSetUpDoneRequired
103
-	 *
104
-	 * @param string $redirect_url
105
-	 * @return StandaloneTemplateResponse
106
-	 */
107
-	public function selectChallenge($redirect_url) {
108
-		$user = $this->userSession->getUser();
109
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
110
-		$allProviders = $providerSet->getProviders();
111
-		[$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
112
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
99
+    /**
100
+     * @NoAdminRequired
101
+     * @NoCSRFRequired
102
+     * @TwoFactorSetUpDoneRequired
103
+     *
104
+     * @param string $redirect_url
105
+     * @return StandaloneTemplateResponse
106
+     */
107
+    public function selectChallenge($redirect_url) {
108
+        $user = $this->userSession->getUser();
109
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
110
+        $allProviders = $providerSet->getProviders();
111
+        [$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
112
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
113 113
 
114
-		$data = [
115
-			'providers' => $providers,
116
-			'backupProvider' => $backupProvider,
117
-			'providerMissing' => $providerSet->isProviderMissing(),
118
-			'redirect_url' => $redirect_url,
119
-			'logout_url' => $this->getLogoutUrl(),
120
-			'hasSetupProviders' => !empty($setupProviders),
121
-		];
122
-		return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
123
-	}
114
+        $data = [
115
+            'providers' => $providers,
116
+            'backupProvider' => $backupProvider,
117
+            'providerMissing' => $providerSet->isProviderMissing(),
118
+            'redirect_url' => $redirect_url,
119
+            'logout_url' => $this->getLogoutUrl(),
120
+            'hasSetupProviders' => !empty($setupProviders),
121
+        ];
122
+        return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
123
+    }
124 124
 
125
-	/**
126
-	 * @NoAdminRequired
127
-	 * @NoCSRFRequired
128
-	 * @UseSession
129
-	 * @TwoFactorSetUpDoneRequired
130
-	 *
131
-	 * @param string $challengeProviderId
132
-	 * @param string $redirect_url
133
-	 * @return StandaloneTemplateResponse|RedirectResponse
134
-	 */
135
-	public function showChallenge($challengeProviderId, $redirect_url) {
136
-		$user = $this->userSession->getUser();
137
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
138
-		$provider = $providerSet->getProvider($challengeProviderId);
125
+    /**
126
+     * @NoAdminRequired
127
+     * @NoCSRFRequired
128
+     * @UseSession
129
+     * @TwoFactorSetUpDoneRequired
130
+     *
131
+     * @param string $challengeProviderId
132
+     * @param string $redirect_url
133
+     * @return StandaloneTemplateResponse|RedirectResponse
134
+     */
135
+    public function showChallenge($challengeProviderId, $redirect_url) {
136
+        $user = $this->userSession->getUser();
137
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
138
+        $provider = $providerSet->getProvider($challengeProviderId);
139 139
 
140
-		if (is_null($provider)) {
141
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
142
-		}
140
+        if (is_null($provider)) {
141
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
142
+        }
143 143
 
144
-		$backupProvider = $providerSet->getProvider('backup_codes');
145
-		if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
146
-			// Don't show the backup provider link if we're already showing that provider's challenge
147
-			$backupProvider = null;
148
-		}
144
+        $backupProvider = $providerSet->getProvider('backup_codes');
145
+        if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
146
+            // Don't show the backup provider link if we're already showing that provider's challenge
147
+            $backupProvider = null;
148
+        }
149 149
 
150
-		$errorMessage = '';
151
-		$error = false;
152
-		if ($this->session->exists('two_factor_auth_error')) {
153
-			$this->session->remove('two_factor_auth_error');
154
-			$error = true;
155
-			$errorMessage = $this->session->get("two_factor_auth_error_message");
156
-			$this->session->remove('two_factor_auth_error_message');
157
-		}
158
-		$tmpl = $provider->getTemplate($user);
159
-		$tmpl->assign('redirect_url', $redirect_url);
160
-		$data = [
161
-			'error' => $error,
162
-			'error_message' => $errorMessage,
163
-			'provider' => $provider,
164
-			'backupProvider' => $backupProvider,
165
-			'logout_url' => $this->getLogoutUrl(),
166
-			'redirect_url' => $redirect_url,
167
-			'template' => $tmpl->fetchPage(),
168
-		];
169
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
170
-		if ($provider instanceof IProvidesCustomCSP) {
171
-			$response->setContentSecurityPolicy($provider->getCSP());
172
-		}
173
-		return $response;
174
-	}
150
+        $errorMessage = '';
151
+        $error = false;
152
+        if ($this->session->exists('two_factor_auth_error')) {
153
+            $this->session->remove('two_factor_auth_error');
154
+            $error = true;
155
+            $errorMessage = $this->session->get("two_factor_auth_error_message");
156
+            $this->session->remove('two_factor_auth_error_message');
157
+        }
158
+        $tmpl = $provider->getTemplate($user);
159
+        $tmpl->assign('redirect_url', $redirect_url);
160
+        $data = [
161
+            'error' => $error,
162
+            'error_message' => $errorMessage,
163
+            'provider' => $provider,
164
+            'backupProvider' => $backupProvider,
165
+            'logout_url' => $this->getLogoutUrl(),
166
+            'redirect_url' => $redirect_url,
167
+            'template' => $tmpl->fetchPage(),
168
+        ];
169
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
170
+        if ($provider instanceof IProvidesCustomCSP) {
171
+            $response->setContentSecurityPolicy($provider->getCSP());
172
+        }
173
+        return $response;
174
+    }
175 175
 
176
-	/**
177
-	 * @NoAdminRequired
178
-	 * @NoCSRFRequired
179
-	 * @UseSession
180
-	 * @TwoFactorSetUpDoneRequired
181
-	 *
182
-	 * @UserRateThrottle(limit=5, period=100)
183
-	 *
184
-	 * @param string $challengeProviderId
185
-	 * @param string $challenge
186
-	 * @param string $redirect_url
187
-	 * @return RedirectResponse
188
-	 */
189
-	public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
190
-		$user = $this->userSession->getUser();
191
-		$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
192
-		if (is_null($provider)) {
193
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
194
-		}
176
+    /**
177
+     * @NoAdminRequired
178
+     * @NoCSRFRequired
179
+     * @UseSession
180
+     * @TwoFactorSetUpDoneRequired
181
+     *
182
+     * @UserRateThrottle(limit=5, period=100)
183
+     *
184
+     * @param string $challengeProviderId
185
+     * @param string $challenge
186
+     * @param string $redirect_url
187
+     * @return RedirectResponse
188
+     */
189
+    public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
190
+        $user = $this->userSession->getUser();
191
+        $provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
192
+        if (is_null($provider)) {
193
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
194
+        }
195 195
 
196
-		try {
197
-			if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
198
-				if (!is_null($redirect_url)) {
199
-					return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
200
-				}
201
-				return new RedirectResponse(OC_Util::getDefaultPageUrl());
202
-			}
203
-		} catch (TwoFactorException $e) {
204
-			/*
196
+        try {
197
+            if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
198
+                if (!is_null($redirect_url)) {
199
+                    return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
200
+                }
201
+                return new RedirectResponse(OC_Util::getDefaultPageUrl());
202
+            }
203
+        } catch (TwoFactorException $e) {
204
+            /*
205 205
 			 * The 2FA App threw an TwoFactorException. Now we display more
206 206
 			 * information to the user. The exception text is stored in the
207 207
 			 * session to be used in showChallenge()
208 208
 			 */
209
-			$this->session->set('two_factor_auth_error_message', $e->getMessage());
210
-		}
209
+            $this->session->set('two_factor_auth_error_message', $e->getMessage());
210
+        }
211 211
 
212
-		$this->session->set('two_factor_auth_error', true);
213
-		return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
214
-			'challengeProviderId' => $provider->getId(),
215
-			'redirect_url' => $redirect_url,
216
-		]));
217
-	}
212
+        $this->session->set('two_factor_auth_error', true);
213
+        return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
214
+            'challengeProviderId' => $provider->getId(),
215
+            'redirect_url' => $redirect_url,
216
+        ]));
217
+    }
218 218
 
219
-	/**
220
-	 * @NoAdminRequired
221
-	 * @NoCSRFRequired
222
-	 */
223
-	public function setupProviders() {
224
-		$user = $this->userSession->getUser();
225
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
219
+    /**
220
+     * @NoAdminRequired
221
+     * @NoCSRFRequired
222
+     */
223
+    public function setupProviders() {
224
+        $user = $this->userSession->getUser();
225
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
226 226
 
227
-		$data = [
228
-			'providers' => $setupProviders,
229
-			'logout_url' => $this->getLogoutUrl(),
230
-		];
227
+        $data = [
228
+            'providers' => $setupProviders,
229
+            'logout_url' => $this->getLogoutUrl(),
230
+        ];
231 231
 
232
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
233
-		return $response;
234
-	}
232
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
233
+        return $response;
234
+    }
235 235
 
236
-	/**
237
-	 * @NoAdminRequired
238
-	 * @NoCSRFRequired
239
-	 */
240
-	public function setupProvider(string $providerId) {
241
-		$user = $this->userSession->getUser();
242
-		$providers = $this->twoFactorManager->getLoginSetupProviders($user);
236
+    /**
237
+     * @NoAdminRequired
238
+     * @NoCSRFRequired
239
+     */
240
+    public function setupProvider(string $providerId) {
241
+        $user = $this->userSession->getUser();
242
+        $providers = $this->twoFactorManager->getLoginSetupProviders($user);
243 243
 
244
-		$provider = null;
245
-		foreach ($providers as $p) {
246
-			if ($p->getId() === $providerId) {
247
-				$provider = $p;
248
-				break;
249
-			}
250
-		}
244
+        $provider = null;
245
+        foreach ($providers as $p) {
246
+            if ($p->getId() === $providerId) {
247
+                $provider = $p;
248
+                break;
249
+            }
250
+        }
251 251
 
252
-		if ($provider === null) {
253
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
254
-		}
252
+        if ($provider === null) {
253
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
254
+        }
255 255
 
256
-		/** @var IActivatableAtLogin $provider */
257
-		$tmpl = $provider->getLoginSetup($user)->getBody();
258
-		$data = [
259
-			'provider' => $provider,
260
-			'logout_url' => $this->getLogoutUrl(),
261
-			'template' => $tmpl->fetchPage(),
262
-		];
263
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
264
-		return $response;
265
-	}
256
+        /** @var IActivatableAtLogin $provider */
257
+        $tmpl = $provider->getLoginSetup($user)->getBody();
258
+        $data = [
259
+            'provider' => $provider,
260
+            'logout_url' => $this->getLogoutUrl(),
261
+            'template' => $tmpl->fetchPage(),
262
+        ];
263
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
264
+        return $response;
265
+    }
266 266
 
267
-	/**
268
-	 * @NoAdminRequired
269
-	 * @NoCSRFRequired
270
-	 *
271
-	 * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
272
-	 */
273
-	public function confirmProviderSetup(string $providerId) {
274
-		return new RedirectResponse($this->urlGenerator->linkToRoute(
275
-			'core.TwoFactorChallenge.showChallenge',
276
-			[
277
-				'challengeProviderId' => $providerId,
278
-			]
279
-		));
280
-	}
267
+    /**
268
+     * @NoAdminRequired
269
+     * @NoCSRFRequired
270
+     *
271
+     * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
272
+     */
273
+    public function confirmProviderSetup(string $providerId) {
274
+        return new RedirectResponse($this->urlGenerator->linkToRoute(
275
+            'core.TwoFactorChallenge.showChallenge',
276
+            [
277
+                'challengeProviderId' => $providerId,
278
+            ]
279
+        ));
280
+    }
281 281
 }
Please login to merge, or discard this patch.
core/Controller/OCSController.php 1 patch
Indentation   +110 added lines, -110 removed lines patch added patch discarded remove patch
@@ -37,125 +37,125 @@
 block discarded – undo
37 37
 
38 38
 class OCSController extends \OCP\AppFramework\OCSController {
39 39
 
40
-	/** @var CapabilitiesManager */
41
-	private $capabilitiesManager;
42
-	/** @var IUserSession */
43
-	private $userSession;
44
-	/** @var IUserManager */
45
-	private $userManager;
46
-	/** @var Manager */
47
-	private $keyManager;
40
+    /** @var CapabilitiesManager */
41
+    private $capabilitiesManager;
42
+    /** @var IUserSession */
43
+    private $userSession;
44
+    /** @var IUserManager */
45
+    private $userManager;
46
+    /** @var Manager */
47
+    private $keyManager;
48 48
 
49
-	/**
50
-	 * OCSController constructor.
51
-	 *
52
-	 * @param string $appName
53
-	 * @param IRequest $request
54
-	 * @param CapabilitiesManager $capabilitiesManager
55
-	 * @param IUserSession $userSession
56
-	 * @param IUserManager $userManager
57
-	 * @param Manager $keyManager
58
-	 */
59
-	public function __construct($appName,
60
-								IRequest $request,
61
-								CapabilitiesManager $capabilitiesManager,
62
-								IUserSession $userSession,
63
-								IUserManager $userManager,
64
-								Manager $keyManager) {
65
-		parent::__construct($appName, $request);
66
-		$this->capabilitiesManager = $capabilitiesManager;
67
-		$this->userSession = $userSession;
68
-		$this->userManager = $userManager;
69
-		$this->keyManager = $keyManager;
70
-	}
49
+    /**
50
+     * OCSController constructor.
51
+     *
52
+     * @param string $appName
53
+     * @param IRequest $request
54
+     * @param CapabilitiesManager $capabilitiesManager
55
+     * @param IUserSession $userSession
56
+     * @param IUserManager $userManager
57
+     * @param Manager $keyManager
58
+     */
59
+    public function __construct($appName,
60
+                                IRequest $request,
61
+                                CapabilitiesManager $capabilitiesManager,
62
+                                IUserSession $userSession,
63
+                                IUserManager $userManager,
64
+                                Manager $keyManager) {
65
+        parent::__construct($appName, $request);
66
+        $this->capabilitiesManager = $capabilitiesManager;
67
+        $this->userSession = $userSession;
68
+        $this->userManager = $userManager;
69
+        $this->keyManager = $keyManager;
70
+    }
71 71
 
72
-	/**
73
-	 * @PublicPage
74
-	 *
75
-	 * @return DataResponse
76
-	 */
77
-	public function getConfig() {
78
-		$data = [
79
-			'version' => '1.7',
80
-			'website' => 'Nextcloud',
81
-			'host' => $this->request->getServerHost(),
82
-			'contact' => '',
83
-			'ssl' => 'false',
84
-		];
72
+    /**
73
+     * @PublicPage
74
+     *
75
+     * @return DataResponse
76
+     */
77
+    public function getConfig() {
78
+        $data = [
79
+            'version' => '1.7',
80
+            'website' => 'Nextcloud',
81
+            'host' => $this->request->getServerHost(),
82
+            'contact' => '',
83
+            'ssl' => 'false',
84
+        ];
85 85
 
86
-		return new DataResponse($data);
87
-	}
86
+        return new DataResponse($data);
87
+    }
88 88
 
89
-	/**
90
-	 * @PublicPage
91
-	 *
92
-	 * @return DataResponse
93
-	 */
94
-	public function getCapabilities() {
95
-		$result = [];
96
-		[$major, $minor, $micro] = \OCP\Util::getVersion();
97
-		$result['version'] = [
98
-			'major' => $major,
99
-			'minor' => $minor,
100
-			'micro' => $micro,
101
-			'string' => \OC_Util::getVersionString(),
102
-			'edition' => '',
103
-			'extendedSupport' => \OCP\Util::hasExtendedSupport()
104
-		];
89
+    /**
90
+     * @PublicPage
91
+     *
92
+     * @return DataResponse
93
+     */
94
+    public function getCapabilities() {
95
+        $result = [];
96
+        [$major, $minor, $micro] = \OCP\Util::getVersion();
97
+        $result['version'] = [
98
+            'major' => $major,
99
+            'minor' => $minor,
100
+            'micro' => $micro,
101
+            'string' => \OC_Util::getVersionString(),
102
+            'edition' => '',
103
+            'extendedSupport' => \OCP\Util::hasExtendedSupport()
104
+        ];
105 105
 
106
-		if ($this->userSession->isLoggedIn()) {
107
-			$result['capabilities'] = $this->capabilitiesManager->getCapabilities();
108
-		} else {
109
-			$result['capabilities'] = $this->capabilitiesManager->getCapabilities(true);
110
-		}
106
+        if ($this->userSession->isLoggedIn()) {
107
+            $result['capabilities'] = $this->capabilitiesManager->getCapabilities();
108
+        } else {
109
+            $result['capabilities'] = $this->capabilitiesManager->getCapabilities(true);
110
+        }
111 111
 
112
-		$response = new DataResponse($result);
113
-		$response->setETag(md5(json_encode($result)));
114
-		return $response;
115
-	}
112
+        $response = new DataResponse($result);
113
+        $response->setETag(md5(json_encode($result)));
114
+        return $response;
115
+    }
116 116
 
117
-	/**
118
-	 * @PublicPage
119
-	 * @BruteForceProtection(action=login)
120
-	 *
121
-	 * @param string $login
122
-	 * @param string $password
123
-	 * @return DataResponse
124
-	 */
125
-	public function personCheck($login = '', $password = '') {
126
-		if ($login !== '' && $password !== '') {
127
-			if ($this->userManager->checkPassword($login, $password)) {
128
-				return new DataResponse([
129
-					'person' => [
130
-						'personid' => $login
131
-					]
132
-				]);
133
-			}
117
+    /**
118
+     * @PublicPage
119
+     * @BruteForceProtection(action=login)
120
+     *
121
+     * @param string $login
122
+     * @param string $password
123
+     * @return DataResponse
124
+     */
125
+    public function personCheck($login = '', $password = '') {
126
+        if ($login !== '' && $password !== '') {
127
+            if ($this->userManager->checkPassword($login, $password)) {
128
+                return new DataResponse([
129
+                    'person' => [
130
+                        'personid' => $login
131
+                    ]
132
+                ]);
133
+            }
134 134
 
135
-			$response = new DataResponse([], 102);
136
-			$response->throttle();
137
-			return $response;
138
-		}
139
-		return new DataResponse([], 101);
140
-	}
135
+            $response = new DataResponse([], 102);
136
+            $response->throttle();
137
+            return $response;
138
+        }
139
+        return new DataResponse([], 101);
140
+    }
141 141
 
142
-	/**
143
-	 * @PublicPage
144
-	 *
145
-	 * @param string $cloudId
146
-	 * @return DataResponse
147
-	 */
148
-	public function getIdentityProof($cloudId) {
149
-		$userObject = $this->userManager->get($cloudId);
142
+    /**
143
+     * @PublicPage
144
+     *
145
+     * @param string $cloudId
146
+     * @return DataResponse
147
+     */
148
+    public function getIdentityProof($cloudId) {
149
+        $userObject = $this->userManager->get($cloudId);
150 150
 
151
-		if ($userObject !== null) {
152
-			$key = $this->keyManager->getKey($userObject);
153
-			$data = [
154
-				'public' => $key->getPublic(),
155
-			];
156
-			return new DataResponse($data);
157
-		}
151
+        if ($userObject !== null) {
152
+            $key = $this->keyManager->getKey($userObject);
153
+            $data = [
154
+                'public' => $key->getPublic(),
155
+            ];
156
+            return new DataResponse($data);
157
+        }
158 158
 
159
-		return new DataResponse(['User not found'], 404);
160
-	}
159
+        return new DataResponse(['User not found'], 404);
160
+    }
161 161
 }
Please login to merge, or discard this patch.
core/Controller/LoginController.php 1 patch
Indentation   +317 added lines, -317 removed lines patch added patch discarded remove patch
@@ -58,321 +58,321 @@
 block discarded – undo
58 58
 use OCP\Util;
59 59
 
60 60
 class LoginController extends Controller {
61
-	public const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword';
62
-	public const LOGIN_MSG_USERDISABLED = 'userdisabled';
63
-
64
-	/** @var IUserManager */
65
-	private $userManager;
66
-	/** @var IConfig */
67
-	private $config;
68
-	/** @var ISession */
69
-	private $session;
70
-	/** @var IUserSession|Session */
71
-	private $userSession;
72
-	/** @var IURLGenerator */
73
-	private $urlGenerator;
74
-	/** @var ILogger */
75
-	private $logger;
76
-	/** @var Defaults */
77
-	private $defaults;
78
-	/** @var Throttler */
79
-	private $throttler;
80
-	/** @var Chain */
81
-	private $loginChain;
82
-	/** @var IInitialStateService */
83
-	private $initialStateService;
84
-	/** @var WebAuthnManager */
85
-	private $webAuthnManager;
86
-
87
-	public function __construct(?string $appName,
88
-								IRequest $request,
89
-								IUserManager $userManager,
90
-								IConfig $config,
91
-								ISession $session,
92
-								IUserSession $userSession,
93
-								IURLGenerator $urlGenerator,
94
-								ILogger $logger,
95
-								Defaults $defaults,
96
-								Throttler $throttler,
97
-								Chain $loginChain,
98
-								IInitialStateService $initialStateService,
99
-								WebAuthnManager $webAuthnManager) {
100
-		parent::__construct($appName, $request);
101
-		$this->userManager = $userManager;
102
-		$this->config = $config;
103
-		$this->session = $session;
104
-		$this->userSession = $userSession;
105
-		$this->urlGenerator = $urlGenerator;
106
-		$this->logger = $logger;
107
-		$this->defaults = $defaults;
108
-		$this->throttler = $throttler;
109
-		$this->loginChain = $loginChain;
110
-		$this->initialStateService = $initialStateService;
111
-		$this->webAuthnManager = $webAuthnManager;
112
-	}
113
-
114
-	/**
115
-	 * @NoAdminRequired
116
-	 * @UseSession
117
-	 *
118
-	 * @return RedirectResponse
119
-	 */
120
-	public function logout() {
121
-		$loginToken = $this->request->getCookie('nc_token');
122
-		if (!is_null($loginToken)) {
123
-			$this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
124
-		}
125
-		$this->userSession->logout();
126
-
127
-		$response = new RedirectResponse($this->urlGenerator->linkToRouteAbsolute(
128
-			'core.login.showLoginForm',
129
-			['clear' => true] // this param the the code in login.js may be removed when the "Clear-Site-Data" is working in the browsers
130
-		));
131
-
132
-		$this->session->set('clearingExecutionContexts', '1');
133
-		$this->session->close();
134
-
135
-		if (!$this->request->isUserAgent([Request::USER_AGENT_CHROME, Request::USER_AGENT_ANDROID_MOBILE_CHROME])) {
136
-			$response->addHeader('Clear-Site-Data', '"cache", "storage"');
137
-		}
138
-
139
-		return $response;
140
-	}
141
-
142
-	/**
143
-	 * @PublicPage
144
-	 * @NoCSRFRequired
145
-	 * @UseSession
146
-	 *
147
-	 * @param string $user
148
-	 * @param string $redirect_url
149
-	 *
150
-	 * @return TemplateResponse|RedirectResponse
151
-	 */
152
-	public function showLoginForm(string $user = null, string $redirect_url = null): Http\Response {
153
-		if ($this->userSession->isLoggedIn()) {
154
-			return new RedirectResponse(OC_Util::getDefaultPageUrl());
155
-		}
156
-
157
-		$loginMessages = $this->session->get('loginMessages');
158
-		if (is_array($loginMessages)) {
159
-			[$errors, $messages] = $loginMessages;
160
-			$this->initialStateService->provideInitialState('core', 'loginMessages', $messages);
161
-			$this->initialStateService->provideInitialState('core', 'loginErrors', $errors);
162
-		}
163
-		$this->session->remove('loginMessages');
164
-
165
-		if ($user !== null && $user !== '') {
166
-			$this->initialStateService->provideInitialState('core', 'loginUsername', $user);
167
-		} else {
168
-			$this->initialStateService->provideInitialState('core', 'loginUsername', '');
169
-		}
170
-
171
-		$this->initialStateService->provideInitialState(
172
-			'core',
173
-			'loginAutocomplete',
174
-			$this->config->getSystemValue('login_form_autocomplete', true) === true
175
-		);
176
-
177
-		if (!empty($redirect_url)) {
178
-			[$url, ] = explode('?', $redirect_url);
179
-			if ($url !== $this->urlGenerator->linkToRoute('core.login.logout')) {
180
-				$this->initialStateService->provideInitialState('core', 'loginRedirectUrl', $redirect_url);
181
-			}
182
-		}
183
-
184
-		$this->initialStateService->provideInitialState(
185
-			'core',
186
-			'loginThrottleDelay',
187
-			$this->throttler->getDelay($this->request->getRemoteAddress())
188
-		);
189
-
190
-		$this->setPasswordResetInitialState($user);
191
-
192
-		$this->initialStateService->provideInitialState('core', 'webauthn-available', $this->webAuthnManager->isWebAuthnAvailable());
193
-
194
-		// OpenGraph Support: http://ogp.me/
195
-		Util::addHeader('meta', ['property' => 'og:title', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
196
-		Util::addHeader('meta', ['property' => 'og:description', 'content' => Util::sanitizeHTML($this->defaults->getSlogan())]);
197
-		Util::addHeader('meta', ['property' => 'og:site_name', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
198
-		Util::addHeader('meta', ['property' => 'og:url', 'content' => $this->urlGenerator->getAbsoluteURL('/')]);
199
-		Util::addHeader('meta', ['property' => 'og:type', 'content' => 'website']);
200
-		Util::addHeader('meta', ['property' => 'og:image', 'content' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-touch.png'))]);
201
-
202
-		$parameters = [
203
-			'alt_login' => OC_App::getAlternativeLogIns(),
204
-		];
205
-		return new TemplateResponse(
206
-			$this->appName, 'login', $parameters, 'guest'
207
-		);
208
-	}
209
-
210
-	/**
211
-	 * Sets the password reset state
212
-	 *
213
-	 * @param string $username
214
-	 */
215
-	private function setPasswordResetInitialState(?string $username): void {
216
-		if ($username !== null && $username !== '') {
217
-			$user = $this->userManager->get($username);
218
-		} else {
219
-			$user = null;
220
-		}
221
-
222
-		$passwordLink = $this->config->getSystemValue('lost_password_link', '');
223
-
224
-		$this->initialStateService->provideInitialState(
225
-			'core',
226
-			'loginResetPasswordLink',
227
-			$passwordLink
228
-		);
229
-
230
-		$this->initialStateService->provideInitialState(
231
-			'core',
232
-			'loginCanResetPassword',
233
-			$this->canResetPassword($passwordLink, $user)
234
-		);
235
-	}
236
-
237
-	/**
238
-	 * @param string|null $passwordLink
239
-	 * @param IUser|null $user
240
-	 *
241
-	 * Users may not change their passwords if:
242
-	 * - The account is disabled
243
-	 * - The backend doesn't support password resets
244
-	 * - The password reset function is disabled
245
-	 *
246
-	 * @return bool
247
-	 */
248
-	private function canResetPassword(?string $passwordLink, ?IUser $user): bool {
249
-		if ($passwordLink === 'disabled') {
250
-			return false;
251
-		}
252
-
253
-		if (!$passwordLink && $user !== null) {
254
-			return $user->canChangePassword();
255
-		}
256
-
257
-		if ($user !== null && $user->isEnabled() === false) {
258
-			return false;
259
-		}
260
-
261
-		return true;
262
-	}
263
-
264
-	private function generateRedirect(?string $redirectUrl): RedirectResponse {
265
-		if ($redirectUrl !== null && $this->userSession->isLoggedIn()) {
266
-			$location = $this->urlGenerator->getAbsoluteURL($redirectUrl);
267
-			// Deny the redirect if the URL contains a @
268
-			// This prevents unvalidated redirects like ?redirect_url=:[email protected]
269
-			if (strpos($location, '@') === false) {
270
-				return new RedirectResponse($location);
271
-			}
272
-		}
273
-		return new RedirectResponse(OC_Util::getDefaultPageUrl());
274
-	}
275
-
276
-	/**
277
-	 * @PublicPage
278
-	 * @UseSession
279
-	 * @NoCSRFRequired
280
-	 * @BruteForceProtection(action=login)
281
-	 *
282
-	 * @param string $user
283
-	 * @param string $password
284
-	 * @param string $redirect_url
285
-	 * @param string $timezone
286
-	 * @param string $timezone_offset
287
-	 *
288
-	 * @return RedirectResponse
289
-	 */
290
-	public function tryLogin(string $user,
291
-							 string $password,
292
-							 string $redirect_url = null,
293
-							 string $timezone = '',
294
-							 string $timezone_offset = ''): RedirectResponse {
295
-		// If the user is already logged in and the CSRF check does not pass then
296
-		// simply redirect the user to the correct page as required. This is the
297
-		// case when an user has already logged-in, in another tab.
298
-		if (!$this->request->passesCSRFCheck()) {
299
-			return $this->generateRedirect($redirect_url);
300
-		}
301
-
302
-		$data = new LoginData(
303
-			$this->request,
304
-			trim($user),
305
-			$password,
306
-			$redirect_url,
307
-			$timezone,
308
-			$timezone_offset
309
-		);
310
-		$result = $this->loginChain->process($data);
311
-		if (!$result->isSuccess()) {
312
-			return $this->createLoginFailedResponse(
313
-				$data->getUsername(),
314
-				$user,
315
-				$redirect_url,
316
-				$result->getErrorMessage()
317
-			);
318
-		}
319
-
320
-		if ($result->getRedirectUrl() !== null) {
321
-			return new RedirectResponse($result->getRedirectUrl());
322
-		}
323
-		return $this->generateRedirect($redirect_url);
324
-	}
325
-
326
-	/**
327
-	 * Creates a login failed response.
328
-	 *
329
-	 * @param string $user
330
-	 * @param string $originalUser
331
-	 * @param string $redirect_url
332
-	 * @param string $loginMessage
333
-	 *
334
-	 * @return RedirectResponse
335
-	 */
336
-	private function createLoginFailedResponse(
337
-		$user, $originalUser, $redirect_url, string $loginMessage) {
338
-		// Read current user and append if possible we need to
339
-		// return the unmodified user otherwise we will leak the login name
340
-		$args = $user !== null ? ['user' => $originalUser, 'direct' => 1] : [];
341
-		if ($redirect_url !== null) {
342
-			$args['redirect_url'] = $redirect_url;
343
-		}
344
-		$response = new RedirectResponse(
345
-			$this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)
346
-		);
347
-		$response->throttle(['user' => substr($user, 0, 64)]);
348
-		$this->session->set('loginMessages', [
349
-			[$loginMessage], []
350
-		]);
351
-		return $response;
352
-	}
353
-
354
-	/**
355
-	 * @NoAdminRequired
356
-	 * @UseSession
357
-	 * @BruteForceProtection(action=sudo)
358
-	 *
359
-	 * @param string $password
360
-	 *
361
-	 * @return DataResponse
362
-	 * @license GNU AGPL version 3 or any later version
363
-	 *
364
-	 */
365
-	public function confirmPassword($password) {
366
-		$loginName = $this->userSession->getLoginName();
367
-		$loginResult = $this->userManager->checkPassword($loginName, $password);
368
-		if ($loginResult === false) {
369
-			$response = new DataResponse([], Http::STATUS_FORBIDDEN);
370
-			$response->throttle();
371
-			return $response;
372
-		}
373
-
374
-		$confirmTimestamp = time();
375
-		$this->session->set('last-password-confirm', $confirmTimestamp);
376
-		return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
377
-	}
61
+    public const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword';
62
+    public const LOGIN_MSG_USERDISABLED = 'userdisabled';
63
+
64
+    /** @var IUserManager */
65
+    private $userManager;
66
+    /** @var IConfig */
67
+    private $config;
68
+    /** @var ISession */
69
+    private $session;
70
+    /** @var IUserSession|Session */
71
+    private $userSession;
72
+    /** @var IURLGenerator */
73
+    private $urlGenerator;
74
+    /** @var ILogger */
75
+    private $logger;
76
+    /** @var Defaults */
77
+    private $defaults;
78
+    /** @var Throttler */
79
+    private $throttler;
80
+    /** @var Chain */
81
+    private $loginChain;
82
+    /** @var IInitialStateService */
83
+    private $initialStateService;
84
+    /** @var WebAuthnManager */
85
+    private $webAuthnManager;
86
+
87
+    public function __construct(?string $appName,
88
+                                IRequest $request,
89
+                                IUserManager $userManager,
90
+                                IConfig $config,
91
+                                ISession $session,
92
+                                IUserSession $userSession,
93
+                                IURLGenerator $urlGenerator,
94
+                                ILogger $logger,
95
+                                Defaults $defaults,
96
+                                Throttler $throttler,
97
+                                Chain $loginChain,
98
+                                IInitialStateService $initialStateService,
99
+                                WebAuthnManager $webAuthnManager) {
100
+        parent::__construct($appName, $request);
101
+        $this->userManager = $userManager;
102
+        $this->config = $config;
103
+        $this->session = $session;
104
+        $this->userSession = $userSession;
105
+        $this->urlGenerator = $urlGenerator;
106
+        $this->logger = $logger;
107
+        $this->defaults = $defaults;
108
+        $this->throttler = $throttler;
109
+        $this->loginChain = $loginChain;
110
+        $this->initialStateService = $initialStateService;
111
+        $this->webAuthnManager = $webAuthnManager;
112
+    }
113
+
114
+    /**
115
+     * @NoAdminRequired
116
+     * @UseSession
117
+     *
118
+     * @return RedirectResponse
119
+     */
120
+    public function logout() {
121
+        $loginToken = $this->request->getCookie('nc_token');
122
+        if (!is_null($loginToken)) {
123
+            $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
124
+        }
125
+        $this->userSession->logout();
126
+
127
+        $response = new RedirectResponse($this->urlGenerator->linkToRouteAbsolute(
128
+            'core.login.showLoginForm',
129
+            ['clear' => true] // this param the the code in login.js may be removed when the "Clear-Site-Data" is working in the browsers
130
+        ));
131
+
132
+        $this->session->set('clearingExecutionContexts', '1');
133
+        $this->session->close();
134
+
135
+        if (!$this->request->isUserAgent([Request::USER_AGENT_CHROME, Request::USER_AGENT_ANDROID_MOBILE_CHROME])) {
136
+            $response->addHeader('Clear-Site-Data', '"cache", "storage"');
137
+        }
138
+
139
+        return $response;
140
+    }
141
+
142
+    /**
143
+     * @PublicPage
144
+     * @NoCSRFRequired
145
+     * @UseSession
146
+     *
147
+     * @param string $user
148
+     * @param string $redirect_url
149
+     *
150
+     * @return TemplateResponse|RedirectResponse
151
+     */
152
+    public function showLoginForm(string $user = null, string $redirect_url = null): Http\Response {
153
+        if ($this->userSession->isLoggedIn()) {
154
+            return new RedirectResponse(OC_Util::getDefaultPageUrl());
155
+        }
156
+
157
+        $loginMessages = $this->session->get('loginMessages');
158
+        if (is_array($loginMessages)) {
159
+            [$errors, $messages] = $loginMessages;
160
+            $this->initialStateService->provideInitialState('core', 'loginMessages', $messages);
161
+            $this->initialStateService->provideInitialState('core', 'loginErrors', $errors);
162
+        }
163
+        $this->session->remove('loginMessages');
164
+
165
+        if ($user !== null && $user !== '') {
166
+            $this->initialStateService->provideInitialState('core', 'loginUsername', $user);
167
+        } else {
168
+            $this->initialStateService->provideInitialState('core', 'loginUsername', '');
169
+        }
170
+
171
+        $this->initialStateService->provideInitialState(
172
+            'core',
173
+            'loginAutocomplete',
174
+            $this->config->getSystemValue('login_form_autocomplete', true) === true
175
+        );
176
+
177
+        if (!empty($redirect_url)) {
178
+            [$url, ] = explode('?', $redirect_url);
179
+            if ($url !== $this->urlGenerator->linkToRoute('core.login.logout')) {
180
+                $this->initialStateService->provideInitialState('core', 'loginRedirectUrl', $redirect_url);
181
+            }
182
+        }
183
+
184
+        $this->initialStateService->provideInitialState(
185
+            'core',
186
+            'loginThrottleDelay',
187
+            $this->throttler->getDelay($this->request->getRemoteAddress())
188
+        );
189
+
190
+        $this->setPasswordResetInitialState($user);
191
+
192
+        $this->initialStateService->provideInitialState('core', 'webauthn-available', $this->webAuthnManager->isWebAuthnAvailable());
193
+
194
+        // OpenGraph Support: http://ogp.me/
195
+        Util::addHeader('meta', ['property' => 'og:title', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
196
+        Util::addHeader('meta', ['property' => 'og:description', 'content' => Util::sanitizeHTML($this->defaults->getSlogan())]);
197
+        Util::addHeader('meta', ['property' => 'og:site_name', 'content' => Util::sanitizeHTML($this->defaults->getName())]);
198
+        Util::addHeader('meta', ['property' => 'og:url', 'content' => $this->urlGenerator->getAbsoluteURL('/')]);
199
+        Util::addHeader('meta', ['property' => 'og:type', 'content' => 'website']);
200
+        Util::addHeader('meta', ['property' => 'og:image', 'content' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-touch.png'))]);
201
+
202
+        $parameters = [
203
+            'alt_login' => OC_App::getAlternativeLogIns(),
204
+        ];
205
+        return new TemplateResponse(
206
+            $this->appName, 'login', $parameters, 'guest'
207
+        );
208
+    }
209
+
210
+    /**
211
+     * Sets the password reset state
212
+     *
213
+     * @param string $username
214
+     */
215
+    private function setPasswordResetInitialState(?string $username): void {
216
+        if ($username !== null && $username !== '') {
217
+            $user = $this->userManager->get($username);
218
+        } else {
219
+            $user = null;
220
+        }
221
+
222
+        $passwordLink = $this->config->getSystemValue('lost_password_link', '');
223
+
224
+        $this->initialStateService->provideInitialState(
225
+            'core',
226
+            'loginResetPasswordLink',
227
+            $passwordLink
228
+        );
229
+
230
+        $this->initialStateService->provideInitialState(
231
+            'core',
232
+            'loginCanResetPassword',
233
+            $this->canResetPassword($passwordLink, $user)
234
+        );
235
+    }
236
+
237
+    /**
238
+     * @param string|null $passwordLink
239
+     * @param IUser|null $user
240
+     *
241
+     * Users may not change their passwords if:
242
+     * - The account is disabled
243
+     * - The backend doesn't support password resets
244
+     * - The password reset function is disabled
245
+     *
246
+     * @return bool
247
+     */
248
+    private function canResetPassword(?string $passwordLink, ?IUser $user): bool {
249
+        if ($passwordLink === 'disabled') {
250
+            return false;
251
+        }
252
+
253
+        if (!$passwordLink && $user !== null) {
254
+            return $user->canChangePassword();
255
+        }
256
+
257
+        if ($user !== null && $user->isEnabled() === false) {
258
+            return false;
259
+        }
260
+
261
+        return true;
262
+    }
263
+
264
+    private function generateRedirect(?string $redirectUrl): RedirectResponse {
265
+        if ($redirectUrl !== null && $this->userSession->isLoggedIn()) {
266
+            $location = $this->urlGenerator->getAbsoluteURL($redirectUrl);
267
+            // Deny the redirect if the URL contains a @
268
+            // This prevents unvalidated redirects like ?redirect_url=:[email protected]
269
+            if (strpos($location, '@') === false) {
270
+                return new RedirectResponse($location);
271
+            }
272
+        }
273
+        return new RedirectResponse(OC_Util::getDefaultPageUrl());
274
+    }
275
+
276
+    /**
277
+     * @PublicPage
278
+     * @UseSession
279
+     * @NoCSRFRequired
280
+     * @BruteForceProtection(action=login)
281
+     *
282
+     * @param string $user
283
+     * @param string $password
284
+     * @param string $redirect_url
285
+     * @param string $timezone
286
+     * @param string $timezone_offset
287
+     *
288
+     * @return RedirectResponse
289
+     */
290
+    public function tryLogin(string $user,
291
+                                string $password,
292
+                                string $redirect_url = null,
293
+                                string $timezone = '',
294
+                                string $timezone_offset = ''): RedirectResponse {
295
+        // If the user is already logged in and the CSRF check does not pass then
296
+        // simply redirect the user to the correct page as required. This is the
297
+        // case when an user has already logged-in, in another tab.
298
+        if (!$this->request->passesCSRFCheck()) {
299
+            return $this->generateRedirect($redirect_url);
300
+        }
301
+
302
+        $data = new LoginData(
303
+            $this->request,
304
+            trim($user),
305
+            $password,
306
+            $redirect_url,
307
+            $timezone,
308
+            $timezone_offset
309
+        );
310
+        $result = $this->loginChain->process($data);
311
+        if (!$result->isSuccess()) {
312
+            return $this->createLoginFailedResponse(
313
+                $data->getUsername(),
314
+                $user,
315
+                $redirect_url,
316
+                $result->getErrorMessage()
317
+            );
318
+        }
319
+
320
+        if ($result->getRedirectUrl() !== null) {
321
+            return new RedirectResponse($result->getRedirectUrl());
322
+        }
323
+        return $this->generateRedirect($redirect_url);
324
+    }
325
+
326
+    /**
327
+     * Creates a login failed response.
328
+     *
329
+     * @param string $user
330
+     * @param string $originalUser
331
+     * @param string $redirect_url
332
+     * @param string $loginMessage
333
+     *
334
+     * @return RedirectResponse
335
+     */
336
+    private function createLoginFailedResponse(
337
+        $user, $originalUser, $redirect_url, string $loginMessage) {
338
+        // Read current user and append if possible we need to
339
+        // return the unmodified user otherwise we will leak the login name
340
+        $args = $user !== null ? ['user' => $originalUser, 'direct' => 1] : [];
341
+        if ($redirect_url !== null) {
342
+            $args['redirect_url'] = $redirect_url;
343
+        }
344
+        $response = new RedirectResponse(
345
+            $this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)
346
+        );
347
+        $response->throttle(['user' => substr($user, 0, 64)]);
348
+        $this->session->set('loginMessages', [
349
+            [$loginMessage], []
350
+        ]);
351
+        return $response;
352
+    }
353
+
354
+    /**
355
+     * @NoAdminRequired
356
+     * @UseSession
357
+     * @BruteForceProtection(action=sudo)
358
+     *
359
+     * @param string $password
360
+     *
361
+     * @return DataResponse
362
+     * @license GNU AGPL version 3 or any later version
363
+     *
364
+     */
365
+    public function confirmPassword($password) {
366
+        $loginName = $this->userSession->getLoginName();
367
+        $loginResult = $this->userManager->checkPassword($loginName, $password);
368
+        if ($loginResult === false) {
369
+            $response = new DataResponse([], Http::STATUS_FORBIDDEN);
370
+            $response->throttle();
371
+            return $response;
372
+        }
373
+
374
+        $confirmTimestamp = time();
375
+        $this->session->set('last-password-confirm', $confirmTimestamp);
376
+        return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
377
+    }
378 378
 }
Please login to merge, or discard this patch.
apps/comments/lib/Notification/Notifier.php 2 patches
Indentation   +191 added lines, -191 removed lines patch added patch discarded remove patch
@@ -39,195 +39,195 @@
 block discarded – undo
39 39
 
40 40
 class Notifier implements INotifier {
41 41
 
42
-	/** @var IFactory */
43
-	protected $l10nFactory;
44
-
45
-	/** @var IRootFolder  */
46
-	protected $rootFolder;
47
-
48
-	/** @var ICommentsManager  */
49
-	protected $commentsManager;
50
-
51
-	/** @var IURLGenerator */
52
-	protected $url;
53
-
54
-	/** @var IUserManager */
55
-	protected $userManager;
56
-
57
-	public function __construct(
58
-		IFactory $l10nFactory,
59
-		IRootFolder $rootFolder,
60
-		ICommentsManager $commentsManager,
61
-		IURLGenerator $url,
62
-		IUserManager $userManager
63
-	) {
64
-		$this->l10nFactory = $l10nFactory;
65
-		$this->rootFolder = $rootFolder;
66
-		$this->commentsManager = $commentsManager;
67
-		$this->url = $url;
68
-		$this->userManager = $userManager;
69
-	}
70
-
71
-	/**
72
-	 * Identifier of the notifier, only use [a-z0-9_]
73
-	 *
74
-	 * @return string
75
-	 * @since 17.0.0
76
-	 */
77
-	public function getID(): string {
78
-		return 'comments';
79
-	}
80
-
81
-	/**
82
-	 * Human readable name describing the notifier
83
-	 *
84
-	 * @return string
85
-	 * @since 17.0.0
86
-	 */
87
-	public function getName(): string {
88
-		return $this->l10nFactory->get('comments')->t('Comments');
89
-	}
90
-
91
-	/**
92
-	 * @param INotification $notification
93
-	 * @param string $languageCode The code of the language that should be used to prepare the notification
94
-	 * @return INotification
95
-	 * @throws \InvalidArgumentException When the notification was not prepared by a notifier
96
-	 * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted
97
-	 * @since 9.0.0
98
-	 */
99
-	public function prepare(INotification $notification, string $languageCode): INotification {
100
-		if ($notification->getApp() !== 'comments') {
101
-			throw new \InvalidArgumentException();
102
-		}
103
-		try {
104
-			$comment = $this->commentsManager->get($notification->getObjectId());
105
-		} catch (NotFoundException $e) {
106
-			// needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all
107
-			throw new \InvalidArgumentException('Comment not found', 0, $e);
108
-		}
109
-		$l = $this->l10nFactory->get('comments', $languageCode);
110
-		$displayName = $comment->getActorId();
111
-		$isDeletedActor = $comment->getActorType() === ICommentsManager::DELETED_USER;
112
-		if ($comment->getActorType() === 'users') {
113
-			$commenter = $this->userManager->get($comment->getActorId());
114
-			if ($commenter instanceof IUser) {
115
-				$displayName = $commenter->getDisplayName();
116
-			}
117
-		}
118
-
119
-		switch ($notification->getSubject()) {
120
-			case 'mention':
121
-				$parameters = $notification->getSubjectParameters();
122
-				if ($parameters[0] !== 'files') {
123
-					throw new \InvalidArgumentException('Unsupported comment object');
124
-				}
125
-				$userFolder = $this->rootFolder->getUserFolder($notification->getUser());
126
-				$nodes = $userFolder->getById((int)$parameters[1]);
127
-				if (empty($nodes)) {
128
-					throw new AlreadyProcessedException();
129
-				}
130
-				$node = $nodes[0];
131
-
132
-				$path = rtrim($node->getPath(), '/');
133
-				if (strpos($path, '/' . $notification->getUser() . '/files/') === 0) {
134
-					// Remove /user/files/...
135
-					$fullPath = $path;
136
-					[,,, $path] = explode('/', $fullPath, 4);
137
-				}
138
-				$subjectParameters = [
139
-					'file' => [
140
-						'type' => 'file',
141
-						'id' => $comment->getObjectId(),
142
-						'name' => $node->getName(),
143
-						'path' => $path,
144
-						'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $comment->getObjectId()]),
145
-					],
146
-				];
147
-
148
-				if ($isDeletedActor) {
149
-					$subject = $l->t('You were mentioned on “{file}”, in a comment by a user that has since been deleted');
150
-				} else {
151
-					$subject = $l->t('{user} mentioned you in a comment on “{file}”');
152
-					$subjectParameters['user'] = [
153
-						'type' => 'user',
154
-						'id' => $comment->getActorId(),
155
-						'name' => $displayName,
156
-					];
157
-				}
158
-				[$message, $messageParameters] = $this->commentToRichMessage($comment);
159
-				$notification->setRichSubject($subject, $subjectParameters)
160
-					->setParsedSubject($this->richToParsed($subject, $subjectParameters))
161
-					->setRichMessage($message, $messageParameters)
162
-					->setParsedMessage($this->richToParsed($message, $messageParameters))
163
-					->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.svg')))
164
-					->setLink($this->url->linkToRouteAbsolute(
165
-						'comments.Notifications.view',
166
-						['id' => $comment->getId()])
167
-					);
168
-
169
-				return $notification;
170
-				break;
171
-
172
-			default:
173
-				throw new \InvalidArgumentException('Invalid subject');
174
-		}
175
-	}
176
-
177
-	public function commentToRichMessage(IComment $comment): array {
178
-		$message = $comment->getMessage();
179
-		$messageParameters = [];
180
-		$mentionTypeCount = [];
181
-		$mentions = $comment->getMentions();
182
-		foreach ($mentions as $mention) {
183
-			if ($mention['type'] === 'user') {
184
-				$user = $this->userManager->get($mention['id']);
185
-				if (!$user instanceof IUser) {
186
-					continue;
187
-				}
188
-			}
189
-			if (!array_key_exists($mention['type'], $mentionTypeCount)) {
190
-				$mentionTypeCount[$mention['type']] = 0;
191
-			}
192
-			$mentionTypeCount[$mention['type']]++;
193
-			// To keep a limited character set in parameter IDs ([a-zA-Z0-9-])
194
-			// the mention parameter ID does not include the mention ID (which
195
-			// could contain characters like '@' for user IDs) but a one-based
196
-			// index of the mentions of that type.
197
-			$mentionParameterId = 'mention-' . $mention['type'] . $mentionTypeCount[$mention['type']];
198
-			$message = str_replace('@"' . $mention['id'] . '"', '{' . $mentionParameterId . '}', $message);
199
-			if (strpos($mention['id'], ' ') === false && strpos($mention['id'], 'guest/') !== 0) {
200
-				$message = str_replace('@' . $mention['id'], '{' . $mentionParameterId . '}', $message);
201
-			}
202
-
203
-			try {
204
-				$displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']);
205
-			} catch (\OutOfBoundsException $e) {
206
-				// There is no registered display name resolver for the mention
207
-				// type, so the client decides what to display.
208
-				$displayName = '';
209
-			}
210
-			$messageParameters[$mentionParameterId] = [
211
-				'type' => $mention['type'],
212
-				'id' => $mention['id'],
213
-				'name' => $displayName
214
-			];
215
-		}
216
-		return [$message, $messageParameters];
217
-	}
218
-
219
-	public function richToParsed(string $message, array $parameters): string {
220
-		$placeholders = $replacements = [];
221
-		foreach ($parameters as $placeholder => $parameter) {
222
-			$placeholders[] = '{' . $placeholder . '}';
223
-			if ($parameter['type'] === 'user') {
224
-				$replacements[] = '@' . $parameter['name'];
225
-			} elseif ($parameter['type'] === 'file') {
226
-				$replacements[] = $parameter['path'];
227
-			} else {
228
-				$replacements[] = $parameter['name'];
229
-			}
230
-		}
231
-		return str_replace($placeholders, $replacements, $message);
232
-	}
42
+    /** @var IFactory */
43
+    protected $l10nFactory;
44
+
45
+    /** @var IRootFolder  */
46
+    protected $rootFolder;
47
+
48
+    /** @var ICommentsManager  */
49
+    protected $commentsManager;
50
+
51
+    /** @var IURLGenerator */
52
+    protected $url;
53
+
54
+    /** @var IUserManager */
55
+    protected $userManager;
56
+
57
+    public function __construct(
58
+        IFactory $l10nFactory,
59
+        IRootFolder $rootFolder,
60
+        ICommentsManager $commentsManager,
61
+        IURLGenerator $url,
62
+        IUserManager $userManager
63
+    ) {
64
+        $this->l10nFactory = $l10nFactory;
65
+        $this->rootFolder = $rootFolder;
66
+        $this->commentsManager = $commentsManager;
67
+        $this->url = $url;
68
+        $this->userManager = $userManager;
69
+    }
70
+
71
+    /**
72
+     * Identifier of the notifier, only use [a-z0-9_]
73
+     *
74
+     * @return string
75
+     * @since 17.0.0
76
+     */
77
+    public function getID(): string {
78
+        return 'comments';
79
+    }
80
+
81
+    /**
82
+     * Human readable name describing the notifier
83
+     *
84
+     * @return string
85
+     * @since 17.0.0
86
+     */
87
+    public function getName(): string {
88
+        return $this->l10nFactory->get('comments')->t('Comments');
89
+    }
90
+
91
+    /**
92
+     * @param INotification $notification
93
+     * @param string $languageCode The code of the language that should be used to prepare the notification
94
+     * @return INotification
95
+     * @throws \InvalidArgumentException When the notification was not prepared by a notifier
96
+     * @throws AlreadyProcessedException When the notification is not needed anymore and should be deleted
97
+     * @since 9.0.0
98
+     */
99
+    public function prepare(INotification $notification, string $languageCode): INotification {
100
+        if ($notification->getApp() !== 'comments') {
101
+            throw new \InvalidArgumentException();
102
+        }
103
+        try {
104
+            $comment = $this->commentsManager->get($notification->getObjectId());
105
+        } catch (NotFoundException $e) {
106
+            // needs to be converted to InvalidArgumentException, otherwise none Notifications will be shown at all
107
+            throw new \InvalidArgumentException('Comment not found', 0, $e);
108
+        }
109
+        $l = $this->l10nFactory->get('comments', $languageCode);
110
+        $displayName = $comment->getActorId();
111
+        $isDeletedActor = $comment->getActorType() === ICommentsManager::DELETED_USER;
112
+        if ($comment->getActorType() === 'users') {
113
+            $commenter = $this->userManager->get($comment->getActorId());
114
+            if ($commenter instanceof IUser) {
115
+                $displayName = $commenter->getDisplayName();
116
+            }
117
+        }
118
+
119
+        switch ($notification->getSubject()) {
120
+            case 'mention':
121
+                $parameters = $notification->getSubjectParameters();
122
+                if ($parameters[0] !== 'files') {
123
+                    throw new \InvalidArgumentException('Unsupported comment object');
124
+                }
125
+                $userFolder = $this->rootFolder->getUserFolder($notification->getUser());
126
+                $nodes = $userFolder->getById((int)$parameters[1]);
127
+                if (empty($nodes)) {
128
+                    throw new AlreadyProcessedException();
129
+                }
130
+                $node = $nodes[0];
131
+
132
+                $path = rtrim($node->getPath(), '/');
133
+                if (strpos($path, '/' . $notification->getUser() . '/files/') === 0) {
134
+                    // Remove /user/files/...
135
+                    $fullPath = $path;
136
+                    [,,, $path] = explode('/', $fullPath, 4);
137
+                }
138
+                $subjectParameters = [
139
+                    'file' => [
140
+                        'type' => 'file',
141
+                        'id' => $comment->getObjectId(),
142
+                        'name' => $node->getName(),
143
+                        'path' => $path,
144
+                        'link' => $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $comment->getObjectId()]),
145
+                    ],
146
+                ];
147
+
148
+                if ($isDeletedActor) {
149
+                    $subject = $l->t('You were mentioned on “{file}”, in a comment by a user that has since been deleted');
150
+                } else {
151
+                    $subject = $l->t('{user} mentioned you in a comment on “{file}”');
152
+                    $subjectParameters['user'] = [
153
+                        'type' => 'user',
154
+                        'id' => $comment->getActorId(),
155
+                        'name' => $displayName,
156
+                    ];
157
+                }
158
+                [$message, $messageParameters] = $this->commentToRichMessage($comment);
159
+                $notification->setRichSubject($subject, $subjectParameters)
160
+                    ->setParsedSubject($this->richToParsed($subject, $subjectParameters))
161
+                    ->setRichMessage($message, $messageParameters)
162
+                    ->setParsedMessage($this->richToParsed($message, $messageParameters))
163
+                    ->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.svg')))
164
+                    ->setLink($this->url->linkToRouteAbsolute(
165
+                        'comments.Notifications.view',
166
+                        ['id' => $comment->getId()])
167
+                    );
168
+
169
+                return $notification;
170
+                break;
171
+
172
+            default:
173
+                throw new \InvalidArgumentException('Invalid subject');
174
+        }
175
+    }
176
+
177
+    public function commentToRichMessage(IComment $comment): array {
178
+        $message = $comment->getMessage();
179
+        $messageParameters = [];
180
+        $mentionTypeCount = [];
181
+        $mentions = $comment->getMentions();
182
+        foreach ($mentions as $mention) {
183
+            if ($mention['type'] === 'user') {
184
+                $user = $this->userManager->get($mention['id']);
185
+                if (!$user instanceof IUser) {
186
+                    continue;
187
+                }
188
+            }
189
+            if (!array_key_exists($mention['type'], $mentionTypeCount)) {
190
+                $mentionTypeCount[$mention['type']] = 0;
191
+            }
192
+            $mentionTypeCount[$mention['type']]++;
193
+            // To keep a limited character set in parameter IDs ([a-zA-Z0-9-])
194
+            // the mention parameter ID does not include the mention ID (which
195
+            // could contain characters like '@' for user IDs) but a one-based
196
+            // index of the mentions of that type.
197
+            $mentionParameterId = 'mention-' . $mention['type'] . $mentionTypeCount[$mention['type']];
198
+            $message = str_replace('@"' . $mention['id'] . '"', '{' . $mentionParameterId . '}', $message);
199
+            if (strpos($mention['id'], ' ') === false && strpos($mention['id'], 'guest/') !== 0) {
200
+                $message = str_replace('@' . $mention['id'], '{' . $mentionParameterId . '}', $message);
201
+            }
202
+
203
+            try {
204
+                $displayName = $this->commentsManager->resolveDisplayName($mention['type'], $mention['id']);
205
+            } catch (\OutOfBoundsException $e) {
206
+                // There is no registered display name resolver for the mention
207
+                // type, so the client decides what to display.
208
+                $displayName = '';
209
+            }
210
+            $messageParameters[$mentionParameterId] = [
211
+                'type' => $mention['type'],
212
+                'id' => $mention['id'],
213
+                'name' => $displayName
214
+            ];
215
+        }
216
+        return [$message, $messageParameters];
217
+    }
218
+
219
+    public function richToParsed(string $message, array $parameters): string {
220
+        $placeholders = $replacements = [];
221
+        foreach ($parameters as $placeholder => $parameter) {
222
+            $placeholders[] = '{' . $placeholder . '}';
223
+            if ($parameter['type'] === 'user') {
224
+                $replacements[] = '@' . $parameter['name'];
225
+            } elseif ($parameter['type'] === 'file') {
226
+                $replacements[] = $parameter['path'];
227
+            } else {
228
+                $replacements[] = $parameter['name'];
229
+            }
230
+        }
231
+        return str_replace($placeholders, $replacements, $message);
232
+    }
233 233
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -123,14 +123,14 @@  discard block
 block discarded – undo
123 123
 					throw new \InvalidArgumentException('Unsupported comment object');
124 124
 				}
125 125
 				$userFolder = $this->rootFolder->getUserFolder($notification->getUser());
126
-				$nodes = $userFolder->getById((int)$parameters[1]);
126
+				$nodes = $userFolder->getById((int) $parameters[1]);
127 127
 				if (empty($nodes)) {
128 128
 					throw new AlreadyProcessedException();
129 129
 				}
130 130
 				$node = $nodes[0];
131 131
 
132 132
 				$path = rtrim($node->getPath(), '/');
133
-				if (strpos($path, '/' . $notification->getUser() . '/files/') === 0) {
133
+				if (strpos($path, '/'.$notification->getUser().'/files/') === 0) {
134 134
 					// Remove /user/files/...
135 135
 					$fullPath = $path;
136 136
 					[,,, $path] = explode('/', $fullPath, 4);
@@ -194,10 +194,10 @@  discard block
 block discarded – undo
194 194
 			// the mention parameter ID does not include the mention ID (which
195 195
 			// could contain characters like '@' for user IDs) but a one-based
196 196
 			// index of the mentions of that type.
197
-			$mentionParameterId = 'mention-' . $mention['type'] . $mentionTypeCount[$mention['type']];
198
-			$message = str_replace('@"' . $mention['id'] . '"', '{' . $mentionParameterId . '}', $message);
197
+			$mentionParameterId = 'mention-'.$mention['type'].$mentionTypeCount[$mention['type']];
198
+			$message = str_replace('@"'.$mention['id'].'"', '{'.$mentionParameterId.'}', $message);
199 199
 			if (strpos($mention['id'], ' ') === false && strpos($mention['id'], 'guest/') !== 0) {
200
-				$message = str_replace('@' . $mention['id'], '{' . $mentionParameterId . '}', $message);
200
+				$message = str_replace('@'.$mention['id'], '{'.$mentionParameterId.'}', $message);
201 201
 			}
202 202
 
203 203
 			try {
@@ -219,9 +219,9 @@  discard block
 block discarded – undo
219 219
 	public function richToParsed(string $message, array $parameters): string {
220 220
 		$placeholders = $replacements = [];
221 221
 		foreach ($parameters as $placeholder => $parameter) {
222
-			$placeholders[] = '{' . $placeholder . '}';
222
+			$placeholders[] = '{'.$placeholder.'}';
223 223
 			if ($parameter['type'] === 'user') {
224
-				$replacements[] = '@' . $parameter['name'];
224
+				$replacements[] = '@'.$parameter['name'];
225 225
 			} elseif ($parameter['type'] === 'file') {
226 226
 				$replacements[] = $parameter['path'];
227 227
 			} else {
Please login to merge, or discard this patch.
apps/files_sharing/lib/External/Cache.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -27,44 +27,44 @@
 block discarded – undo
27 27
 use OCP\Federation\ICloudId;
28 28
 
29 29
 class Cache extends \OC\Files\Cache\Cache {
30
-	/** @var ICloudId */
31
-	private $cloudId;
32
-	private $remote;
33
-	private $remoteUser;
34
-	private $storage;
30
+    /** @var ICloudId */
31
+    private $cloudId;
32
+    private $remote;
33
+    private $remoteUser;
34
+    private $storage;
35 35
 
36
-	/**
37
-	 * @param \OCA\Files_Sharing\External\Storage $storage
38
-	 * @param ICloudId $cloudId
39
-	 */
40
-	public function __construct($storage, ICloudId $cloudId) {
41
-		$this->cloudId = $cloudId;
42
-		$this->storage = $storage;
43
-		[, $remote] = explode('://', $cloudId->getRemote(), 2);
44
-		$this->remote = $remote;
45
-		$this->remoteUser = $cloudId->getUser();
46
-		parent::__construct($storage);
47
-	}
36
+    /**
37
+     * @param \OCA\Files_Sharing\External\Storage $storage
38
+     * @param ICloudId $cloudId
39
+     */
40
+    public function __construct($storage, ICloudId $cloudId) {
41
+        $this->cloudId = $cloudId;
42
+        $this->storage = $storage;
43
+        [, $remote] = explode('://', $cloudId->getRemote(), 2);
44
+        $this->remote = $remote;
45
+        $this->remoteUser = $cloudId->getUser();
46
+        parent::__construct($storage);
47
+    }
48 48
 
49
-	public function get($file) {
50
-		$result = parent::get($file);
51
-		if (!$result) {
52
-			return false;
53
-		}
54
-		$result['displayname_owner'] = $this->cloudId->getDisplayId();
55
-		if (!$file || $file === '') {
56
-			$result['is_share_mount_point'] = true;
57
-			$mountPoint = rtrim($this->storage->getMountPoint());
58
-			$result['name'] = basename($mountPoint);
59
-		}
60
-		return $result;
61
-	}
49
+    public function get($file) {
50
+        $result = parent::get($file);
51
+        if (!$result) {
52
+            return false;
53
+        }
54
+        $result['displayname_owner'] = $this->cloudId->getDisplayId();
55
+        if (!$file || $file === '') {
56
+            $result['is_share_mount_point'] = true;
57
+            $mountPoint = rtrim($this->storage->getMountPoint());
58
+            $result['name'] = basename($mountPoint);
59
+        }
60
+        return $result;
61
+    }
62 62
 
63
-	public function getFolderContentsById($id) {
64
-		$results = parent::getFolderContentsById($id);
65
-		foreach ($results as &$file) {
66
-			$file['displayname_owner'] = $this->cloudId->getDisplayId();
67
-		}
68
-		return $results;
69
-	}
63
+    public function getFolderContentsById($id) {
64
+        $results = parent::getFolderContentsById($id);
65
+        foreach ($results as &$file) {
66
+            $file['displayname_owner'] = $this->cloudId->getDisplayId();
67
+        }
68
+        return $results;
69
+    }
70 70
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/External/Storage.php 1 patch
Indentation   +378 added lines, -378 removed lines patch added patch discarded remove patch
@@ -47,382 +47,382 @@
 block discarded – undo
47 47
 use OCP\Files\StorageNotAvailableException;
48 48
 
49 49
 class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage {
50
-	/** @var ICloudId */
51
-	private $cloudId;
52
-	/** @var string */
53
-	private $mountPoint;
54
-	/** @var string */
55
-	private $token;
56
-	/** @var \OCP\ICacheFactory */
57
-	private $memcacheFactory;
58
-	/** @var \OCP\Http\Client\IClientService */
59
-	private $httpClient;
60
-	/** @var bool */
61
-	private $updateChecked = false;
62
-
63
-	/**
64
-	 * @var \OCA\Files_Sharing\External\Manager
65
-	 */
66
-	private $manager;
67
-
68
-	public function __construct($options) {
69
-		$this->memcacheFactory = \OC::$server->getMemCacheFactory();
70
-		$this->httpClient = $options['HttpClientService'];
71
-
72
-		$this->manager = $options['manager'];
73
-		$this->cloudId = $options['cloudId'];
74
-		$discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
75
-
76
-		[$protocol, $remote] = explode('://', $this->cloudId->getRemote());
77
-		if (strpos($remote, '/')) {
78
-			[$host, $root] = explode('/', $remote, 2);
79
-		} else {
80
-			$host = $remote;
81
-			$root = '';
82
-		}
83
-		$secure = $protocol === 'https';
84
-		$federatedSharingEndpoints = $discoveryService->discover($this->cloudId->getRemote(), 'FEDERATED_SHARING');
85
-		$webDavEndpoint = isset($federatedSharingEndpoints['webdav']) ? $federatedSharingEndpoints['webdav'] : '/public.php/webdav';
86
-		$root = rtrim($root, '/') . $webDavEndpoint;
87
-		$this->mountPoint = $options['mountpoint'];
88
-		$this->token = $options['token'];
89
-
90
-		parent::__construct([
91
-			'secure' => $secure,
92
-			'host' => $host,
93
-			'root' => $root,
94
-			'user' => $options['token'],
95
-			'password' => (string)$options['password']
96
-		]);
97
-	}
98
-
99
-	public function getWatcher($path = '', $storage = null) {
100
-		if (!$storage) {
101
-			$storage = $this;
102
-		}
103
-		if (!isset($this->watcher)) {
104
-			$this->watcher = new Watcher($storage);
105
-			$this->watcher->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE);
106
-		}
107
-		return $this->watcher;
108
-	}
109
-
110
-	public function getRemoteUser() {
111
-		return $this->cloudId->getUser();
112
-	}
113
-
114
-	public function getRemote() {
115
-		return $this->cloudId->getRemote();
116
-	}
117
-
118
-	public function getMountPoint() {
119
-		return $this->mountPoint;
120
-	}
121
-
122
-	public function getToken() {
123
-		return $this->token;
124
-	}
125
-
126
-	public function getPassword() {
127
-		return $this->password;
128
-	}
129
-
130
-	/**
131
-	 * @brief get id of the mount point
132
-	 * @return string
133
-	 */
134
-	public function getId() {
135
-		return 'shared::' . md5($this->token . '@' . $this->getRemote());
136
-	}
137
-
138
-	public function getCache($path = '', $storage = null) {
139
-		if (is_null($this->cache)) {
140
-			$this->cache = new Cache($this, $this->cloudId);
141
-		}
142
-		return $this->cache;
143
-	}
144
-
145
-	/**
146
-	 * @param string $path
147
-	 * @param \OC\Files\Storage\Storage $storage
148
-	 * @return \OCA\Files_Sharing\External\Scanner
149
-	 */
150
-	public function getScanner($path = '', $storage = null) {
151
-		if (!$storage) {
152
-			$storage = $this;
153
-		}
154
-		if (!isset($this->scanner)) {
155
-			$this->scanner = new Scanner($storage);
156
-		}
157
-		return $this->scanner;
158
-	}
159
-
160
-	/**
161
-	 * check if a file or folder has been updated since $time
162
-	 *
163
-	 * @param string $path
164
-	 * @param int $time
165
-	 * @throws \OCP\Files\StorageNotAvailableException
166
-	 * @throws \OCP\Files\StorageInvalidException
167
-	 * @return bool
168
-	 */
169
-	public function hasUpdated($path, $time) {
170
-		// since for owncloud webdav servers we can rely on etag propagation we only need to check the root of the storage
171
-		// because of that we only do one check for the entire storage per request
172
-		if ($this->updateChecked) {
173
-			return false;
174
-		}
175
-		$this->updateChecked = true;
176
-		try {
177
-			return parent::hasUpdated('', $time);
178
-		} catch (StorageInvalidException $e) {
179
-			// check if it needs to be removed
180
-			$this->checkStorageAvailability();
181
-			throw $e;
182
-		} catch (StorageNotAvailableException $e) {
183
-			// check if it needs to be removed or just temp unavailable
184
-			$this->checkStorageAvailability();
185
-			throw $e;
186
-		}
187
-	}
188
-
189
-	public function test() {
190
-		try {
191
-			return parent::test();
192
-		} catch (StorageInvalidException $e) {
193
-			// check if it needs to be removed
194
-			$this->checkStorageAvailability();
195
-			throw $e;
196
-		} catch (StorageNotAvailableException $e) {
197
-			// check if it needs to be removed or just temp unavailable
198
-			$this->checkStorageAvailability();
199
-			throw $e;
200
-		}
201
-	}
202
-
203
-	/**
204
-	 * Check whether this storage is permanently or temporarily
205
-	 * unavailable
206
-	 *
207
-	 * @throws \OCP\Files\StorageNotAvailableException
208
-	 * @throws \OCP\Files\StorageInvalidException
209
-	 */
210
-	public function checkStorageAvailability() {
211
-		// see if we can find out why the share is unavailable
212
-		try {
213
-			$this->getShareInfo();
214
-		} catch (NotFoundException $e) {
215
-			// a 404 can either mean that the share no longer exists or there is no Nextcloud on the remote
216
-			if ($this->testRemote()) {
217
-				// valid Nextcloud instance means that the public share no longer exists
218
-				// since this is permanent (re-sharing the file will create a new token)
219
-				// we remove the invalid storage
220
-				$this->manager->removeShare($this->mountPoint);
221
-				$this->manager->getMountManager()->removeMount($this->mountPoint);
222
-				throw new StorageInvalidException();
223
-			} else {
224
-				// Nextcloud instance is gone, likely to be a temporary server configuration error
225
-				throw new StorageNotAvailableException();
226
-			}
227
-		} catch (ForbiddenException $e) {
228
-			// auth error, remove share for now (provide a dialog in the future)
229
-			$this->manager->removeShare($this->mountPoint);
230
-			$this->manager->getMountManager()->removeMount($this->mountPoint);
231
-			throw new StorageInvalidException();
232
-		} catch (\GuzzleHttp\Exception\ConnectException $e) {
233
-			throw new StorageNotAvailableException();
234
-		} catch (\GuzzleHttp\Exception\RequestException $e) {
235
-			throw new StorageNotAvailableException();
236
-		} catch (\Exception $e) {
237
-			throw $e;
238
-		}
239
-	}
240
-
241
-	public function file_exists($path) {
242
-		if ($path === '') {
243
-			return true;
244
-		} else {
245
-			return parent::file_exists($path);
246
-		}
247
-	}
248
-
249
-	/**
250
-	 * check if the configured remote is a valid federated share provider
251
-	 *
252
-	 * @return bool
253
-	 */
254
-	protected function testRemote() {
255
-		try {
256
-			return $this->testRemoteUrl($this->getRemote() . '/ocs-provider/index.php')
257
-				|| $this->testRemoteUrl($this->getRemote() . '/ocs-provider/')
258
-				|| $this->testRemoteUrl($this->getRemote() . '/status.php');
259
-		} catch (\Exception $e) {
260
-			return false;
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * @param string $url
266
-	 * @return bool
267
-	 */
268
-	private function testRemoteUrl($url) {
269
-		$cache = $this->memcacheFactory->createDistributed('files_sharing_remote_url');
270
-		if ($cache->hasKey($url)) {
271
-			return (bool)$cache->get($url);
272
-		}
273
-
274
-		$client = $this->httpClient->newClient();
275
-		try {
276
-			$result = $client->get($url, [
277
-				'timeout' => 10,
278
-				'connect_timeout' => 10,
279
-			])->getBody();
280
-			$data = json_decode($result);
281
-			$returnValue = (is_object($data) && !empty($data->version));
282
-		} catch (ConnectException $e) {
283
-			$returnValue = false;
284
-		} catch (ClientException $e) {
285
-			$returnValue = false;
286
-		} catch (RequestException $e) {
287
-			$returnValue = false;
288
-		}
289
-
290
-		$cache->set($url, $returnValue, 60 * 60 * 24);
291
-		return $returnValue;
292
-	}
293
-
294
-	/**
295
-	 * Whether the remote is an ownCloud/Nextcloud, used since some sharing features are not
296
-	 * standardized. Let's use this to detect whether to use it.
297
-	 *
298
-	 * @return bool
299
-	 */
300
-	public function remoteIsOwnCloud() {
301
-		if (defined('PHPUNIT_RUN') || !$this->testRemoteUrl($this->getRemote() . '/status.php')) {
302
-			return false;
303
-		}
304
-		return true;
305
-	}
306
-
307
-	/**
308
-	 * @return mixed
309
-	 * @throws ForbiddenException
310
-	 * @throws NotFoundException
311
-	 * @throws \Exception
312
-	 */
313
-	public function getShareInfo() {
314
-		$remote = $this->getRemote();
315
-		$token = $this->getToken();
316
-		$password = $this->getPassword();
317
-
318
-		// If remote is not an ownCloud do not try to get any share info
319
-		if (!$this->remoteIsOwnCloud()) {
320
-			return ['status' => 'unsupported'];
321
-		}
322
-
323
-		$url = rtrim($remote, '/') . '/index.php/apps/files_sharing/shareinfo?t=' . $token;
324
-
325
-		// TODO: DI
326
-		$client = \OC::$server->getHTTPClientService()->newClient();
327
-		try {
328
-			$response = $client->post($url, [
329
-				'body' => ['password' => $password],
330
-				'timeout' => 10,
331
-				'connect_timeout' => 10,
332
-			]);
333
-		} catch (\GuzzleHttp\Exception\RequestException $e) {
334
-			if ($e->getCode() === Http::STATUS_UNAUTHORIZED || $e->getCode() === Http::STATUS_FORBIDDEN) {
335
-				throw new ForbiddenException();
336
-			}
337
-			if ($e->getCode() === Http::STATUS_NOT_FOUND) {
338
-				throw new NotFoundException();
339
-			}
340
-			// throw this to be on the safe side: the share will still be visible
341
-			// in the UI in case the failure is intermittent, and the user will
342
-			// be able to decide whether to remove it if it's really gone
343
-			throw new StorageNotAvailableException();
344
-		}
345
-
346
-		return json_decode($response->getBody(), true);
347
-	}
348
-
349
-	public function getOwner($path) {
350
-		return $this->cloudId->getDisplayId();
351
-	}
352
-
353
-	public function isSharable($path) {
354
-		if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
355
-			return false;
356
-		}
357
-		return ($this->getPermissions($path) & Constants::PERMISSION_SHARE);
358
-	}
359
-
360
-	public function getPermissions($path) {
361
-		$response = $this->propfind($path);
362
-		// old federated sharing permissions
363
-		if (isset($response['{http://open-collaboration-services.org/ns}share-permissions'])) {
364
-			$permissions = $response['{http://open-collaboration-services.org/ns}share-permissions'];
365
-		} elseif (isset($response['{http://open-cloud-mesh.org/ns}share-permissions'])) {
366
-			// permissions provided by the OCM API
367
-			$permissions = $this->ocmPermissions2ncPermissions($response['{http://open-collaboration-services.org/ns}share-permissions'], $path);
368
-		} else {
369
-			// use default permission if remote server doesn't provide the share permissions
370
-			$permissions = $this->getDefaultPermissions($path);
371
-		}
372
-
373
-		return $permissions;
374
-	}
375
-
376
-	public function needsPartFile() {
377
-		return false;
378
-	}
379
-
380
-	/**
381
-	 * translate OCM Permissions to Nextcloud permissions
382
-	 *
383
-	 * @param string $ocmPermissions json encoded OCM permissions
384
-	 * @param string $path path to file
385
-	 * @return int
386
-	 */
387
-	protected function ocmPermissions2ncPermissions($ocmPermissions, $path) {
388
-		try {
389
-			$ocmPermissions = json_decode($ocmPermissions);
390
-			$ncPermissions = 0;
391
-			foreach ($ocmPermissions as $permission) {
392
-				switch (strtolower($permission)) {
393
-					case 'read':
394
-						$ncPermissions += Constants::PERMISSION_READ;
395
-						break;
396
-					case 'write':
397
-						$ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
398
-						break;
399
-					case 'share':
400
-						$ncPermissions += Constants::PERMISSION_SHARE;
401
-						break;
402
-					default:
403
-						throw new \Exception();
404
-				}
405
-			}
406
-		} catch (\Exception $e) {
407
-			$ncPermissions = $this->getDefaultPermissions($path);
408
-		}
409
-
410
-		return $ncPermissions;
411
-	}
412
-
413
-	/**
414
-	 * calculate default permissions in case no permissions are provided
415
-	 *
416
-	 * @param $path
417
-	 * @return int
418
-	 */
419
-	protected function getDefaultPermissions($path) {
420
-		if ($this->is_dir($path)) {
421
-			$permissions = Constants::PERMISSION_ALL;
422
-		} else {
423
-			$permissions = Constants::PERMISSION_ALL & ~Constants::PERMISSION_CREATE;
424
-		}
425
-
426
-		return $permissions;
427
-	}
50
+    /** @var ICloudId */
51
+    private $cloudId;
52
+    /** @var string */
53
+    private $mountPoint;
54
+    /** @var string */
55
+    private $token;
56
+    /** @var \OCP\ICacheFactory */
57
+    private $memcacheFactory;
58
+    /** @var \OCP\Http\Client\IClientService */
59
+    private $httpClient;
60
+    /** @var bool */
61
+    private $updateChecked = false;
62
+
63
+    /**
64
+     * @var \OCA\Files_Sharing\External\Manager
65
+     */
66
+    private $manager;
67
+
68
+    public function __construct($options) {
69
+        $this->memcacheFactory = \OC::$server->getMemCacheFactory();
70
+        $this->httpClient = $options['HttpClientService'];
71
+
72
+        $this->manager = $options['manager'];
73
+        $this->cloudId = $options['cloudId'];
74
+        $discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
75
+
76
+        [$protocol, $remote] = explode('://', $this->cloudId->getRemote());
77
+        if (strpos($remote, '/')) {
78
+            [$host, $root] = explode('/', $remote, 2);
79
+        } else {
80
+            $host = $remote;
81
+            $root = '';
82
+        }
83
+        $secure = $protocol === 'https';
84
+        $federatedSharingEndpoints = $discoveryService->discover($this->cloudId->getRemote(), 'FEDERATED_SHARING');
85
+        $webDavEndpoint = isset($federatedSharingEndpoints['webdav']) ? $federatedSharingEndpoints['webdav'] : '/public.php/webdav';
86
+        $root = rtrim($root, '/') . $webDavEndpoint;
87
+        $this->mountPoint = $options['mountpoint'];
88
+        $this->token = $options['token'];
89
+
90
+        parent::__construct([
91
+            'secure' => $secure,
92
+            'host' => $host,
93
+            'root' => $root,
94
+            'user' => $options['token'],
95
+            'password' => (string)$options['password']
96
+        ]);
97
+    }
98
+
99
+    public function getWatcher($path = '', $storage = null) {
100
+        if (!$storage) {
101
+            $storage = $this;
102
+        }
103
+        if (!isset($this->watcher)) {
104
+            $this->watcher = new Watcher($storage);
105
+            $this->watcher->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE);
106
+        }
107
+        return $this->watcher;
108
+    }
109
+
110
+    public function getRemoteUser() {
111
+        return $this->cloudId->getUser();
112
+    }
113
+
114
+    public function getRemote() {
115
+        return $this->cloudId->getRemote();
116
+    }
117
+
118
+    public function getMountPoint() {
119
+        return $this->mountPoint;
120
+    }
121
+
122
+    public function getToken() {
123
+        return $this->token;
124
+    }
125
+
126
+    public function getPassword() {
127
+        return $this->password;
128
+    }
129
+
130
+    /**
131
+     * @brief get id of the mount point
132
+     * @return string
133
+     */
134
+    public function getId() {
135
+        return 'shared::' . md5($this->token . '@' . $this->getRemote());
136
+    }
137
+
138
+    public function getCache($path = '', $storage = null) {
139
+        if (is_null($this->cache)) {
140
+            $this->cache = new Cache($this, $this->cloudId);
141
+        }
142
+        return $this->cache;
143
+    }
144
+
145
+    /**
146
+     * @param string $path
147
+     * @param \OC\Files\Storage\Storage $storage
148
+     * @return \OCA\Files_Sharing\External\Scanner
149
+     */
150
+    public function getScanner($path = '', $storage = null) {
151
+        if (!$storage) {
152
+            $storage = $this;
153
+        }
154
+        if (!isset($this->scanner)) {
155
+            $this->scanner = new Scanner($storage);
156
+        }
157
+        return $this->scanner;
158
+    }
159
+
160
+    /**
161
+     * check if a file or folder has been updated since $time
162
+     *
163
+     * @param string $path
164
+     * @param int $time
165
+     * @throws \OCP\Files\StorageNotAvailableException
166
+     * @throws \OCP\Files\StorageInvalidException
167
+     * @return bool
168
+     */
169
+    public function hasUpdated($path, $time) {
170
+        // since for owncloud webdav servers we can rely on etag propagation we only need to check the root of the storage
171
+        // because of that we only do one check for the entire storage per request
172
+        if ($this->updateChecked) {
173
+            return false;
174
+        }
175
+        $this->updateChecked = true;
176
+        try {
177
+            return parent::hasUpdated('', $time);
178
+        } catch (StorageInvalidException $e) {
179
+            // check if it needs to be removed
180
+            $this->checkStorageAvailability();
181
+            throw $e;
182
+        } catch (StorageNotAvailableException $e) {
183
+            // check if it needs to be removed or just temp unavailable
184
+            $this->checkStorageAvailability();
185
+            throw $e;
186
+        }
187
+    }
188
+
189
+    public function test() {
190
+        try {
191
+            return parent::test();
192
+        } catch (StorageInvalidException $e) {
193
+            // check if it needs to be removed
194
+            $this->checkStorageAvailability();
195
+            throw $e;
196
+        } catch (StorageNotAvailableException $e) {
197
+            // check if it needs to be removed or just temp unavailable
198
+            $this->checkStorageAvailability();
199
+            throw $e;
200
+        }
201
+    }
202
+
203
+    /**
204
+     * Check whether this storage is permanently or temporarily
205
+     * unavailable
206
+     *
207
+     * @throws \OCP\Files\StorageNotAvailableException
208
+     * @throws \OCP\Files\StorageInvalidException
209
+     */
210
+    public function checkStorageAvailability() {
211
+        // see if we can find out why the share is unavailable
212
+        try {
213
+            $this->getShareInfo();
214
+        } catch (NotFoundException $e) {
215
+            // a 404 can either mean that the share no longer exists or there is no Nextcloud on the remote
216
+            if ($this->testRemote()) {
217
+                // valid Nextcloud instance means that the public share no longer exists
218
+                // since this is permanent (re-sharing the file will create a new token)
219
+                // we remove the invalid storage
220
+                $this->manager->removeShare($this->mountPoint);
221
+                $this->manager->getMountManager()->removeMount($this->mountPoint);
222
+                throw new StorageInvalidException();
223
+            } else {
224
+                // Nextcloud instance is gone, likely to be a temporary server configuration error
225
+                throw new StorageNotAvailableException();
226
+            }
227
+        } catch (ForbiddenException $e) {
228
+            // auth error, remove share for now (provide a dialog in the future)
229
+            $this->manager->removeShare($this->mountPoint);
230
+            $this->manager->getMountManager()->removeMount($this->mountPoint);
231
+            throw new StorageInvalidException();
232
+        } catch (\GuzzleHttp\Exception\ConnectException $e) {
233
+            throw new StorageNotAvailableException();
234
+        } catch (\GuzzleHttp\Exception\RequestException $e) {
235
+            throw new StorageNotAvailableException();
236
+        } catch (\Exception $e) {
237
+            throw $e;
238
+        }
239
+    }
240
+
241
+    public function file_exists($path) {
242
+        if ($path === '') {
243
+            return true;
244
+        } else {
245
+            return parent::file_exists($path);
246
+        }
247
+    }
248
+
249
+    /**
250
+     * check if the configured remote is a valid federated share provider
251
+     *
252
+     * @return bool
253
+     */
254
+    protected function testRemote() {
255
+        try {
256
+            return $this->testRemoteUrl($this->getRemote() . '/ocs-provider/index.php')
257
+                || $this->testRemoteUrl($this->getRemote() . '/ocs-provider/')
258
+                || $this->testRemoteUrl($this->getRemote() . '/status.php');
259
+        } catch (\Exception $e) {
260
+            return false;
261
+        }
262
+    }
263
+
264
+    /**
265
+     * @param string $url
266
+     * @return bool
267
+     */
268
+    private function testRemoteUrl($url) {
269
+        $cache = $this->memcacheFactory->createDistributed('files_sharing_remote_url');
270
+        if ($cache->hasKey($url)) {
271
+            return (bool)$cache->get($url);
272
+        }
273
+
274
+        $client = $this->httpClient->newClient();
275
+        try {
276
+            $result = $client->get($url, [
277
+                'timeout' => 10,
278
+                'connect_timeout' => 10,
279
+            ])->getBody();
280
+            $data = json_decode($result);
281
+            $returnValue = (is_object($data) && !empty($data->version));
282
+        } catch (ConnectException $e) {
283
+            $returnValue = false;
284
+        } catch (ClientException $e) {
285
+            $returnValue = false;
286
+        } catch (RequestException $e) {
287
+            $returnValue = false;
288
+        }
289
+
290
+        $cache->set($url, $returnValue, 60 * 60 * 24);
291
+        return $returnValue;
292
+    }
293
+
294
+    /**
295
+     * Whether the remote is an ownCloud/Nextcloud, used since some sharing features are not
296
+     * standardized. Let's use this to detect whether to use it.
297
+     *
298
+     * @return bool
299
+     */
300
+    public function remoteIsOwnCloud() {
301
+        if (defined('PHPUNIT_RUN') || !$this->testRemoteUrl($this->getRemote() . '/status.php')) {
302
+            return false;
303
+        }
304
+        return true;
305
+    }
306
+
307
+    /**
308
+     * @return mixed
309
+     * @throws ForbiddenException
310
+     * @throws NotFoundException
311
+     * @throws \Exception
312
+     */
313
+    public function getShareInfo() {
314
+        $remote = $this->getRemote();
315
+        $token = $this->getToken();
316
+        $password = $this->getPassword();
317
+
318
+        // If remote is not an ownCloud do not try to get any share info
319
+        if (!$this->remoteIsOwnCloud()) {
320
+            return ['status' => 'unsupported'];
321
+        }
322
+
323
+        $url = rtrim($remote, '/') . '/index.php/apps/files_sharing/shareinfo?t=' . $token;
324
+
325
+        // TODO: DI
326
+        $client = \OC::$server->getHTTPClientService()->newClient();
327
+        try {
328
+            $response = $client->post($url, [
329
+                'body' => ['password' => $password],
330
+                'timeout' => 10,
331
+                'connect_timeout' => 10,
332
+            ]);
333
+        } catch (\GuzzleHttp\Exception\RequestException $e) {
334
+            if ($e->getCode() === Http::STATUS_UNAUTHORIZED || $e->getCode() === Http::STATUS_FORBIDDEN) {
335
+                throw new ForbiddenException();
336
+            }
337
+            if ($e->getCode() === Http::STATUS_NOT_FOUND) {
338
+                throw new NotFoundException();
339
+            }
340
+            // throw this to be on the safe side: the share will still be visible
341
+            // in the UI in case the failure is intermittent, and the user will
342
+            // be able to decide whether to remove it if it's really gone
343
+            throw new StorageNotAvailableException();
344
+        }
345
+
346
+        return json_decode($response->getBody(), true);
347
+    }
348
+
349
+    public function getOwner($path) {
350
+        return $this->cloudId->getDisplayId();
351
+    }
352
+
353
+    public function isSharable($path) {
354
+        if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
355
+            return false;
356
+        }
357
+        return ($this->getPermissions($path) & Constants::PERMISSION_SHARE);
358
+    }
359
+
360
+    public function getPermissions($path) {
361
+        $response = $this->propfind($path);
362
+        // old federated sharing permissions
363
+        if (isset($response['{http://open-collaboration-services.org/ns}share-permissions'])) {
364
+            $permissions = $response['{http://open-collaboration-services.org/ns}share-permissions'];
365
+        } elseif (isset($response['{http://open-cloud-mesh.org/ns}share-permissions'])) {
366
+            // permissions provided by the OCM API
367
+            $permissions = $this->ocmPermissions2ncPermissions($response['{http://open-collaboration-services.org/ns}share-permissions'], $path);
368
+        } else {
369
+            // use default permission if remote server doesn't provide the share permissions
370
+            $permissions = $this->getDefaultPermissions($path);
371
+        }
372
+
373
+        return $permissions;
374
+    }
375
+
376
+    public function needsPartFile() {
377
+        return false;
378
+    }
379
+
380
+    /**
381
+     * translate OCM Permissions to Nextcloud permissions
382
+     *
383
+     * @param string $ocmPermissions json encoded OCM permissions
384
+     * @param string $path path to file
385
+     * @return int
386
+     */
387
+    protected function ocmPermissions2ncPermissions($ocmPermissions, $path) {
388
+        try {
389
+            $ocmPermissions = json_decode($ocmPermissions);
390
+            $ncPermissions = 0;
391
+            foreach ($ocmPermissions as $permission) {
392
+                switch (strtolower($permission)) {
393
+                    case 'read':
394
+                        $ncPermissions += Constants::PERMISSION_READ;
395
+                        break;
396
+                    case 'write':
397
+                        $ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
398
+                        break;
399
+                    case 'share':
400
+                        $ncPermissions += Constants::PERMISSION_SHARE;
401
+                        break;
402
+                    default:
403
+                        throw new \Exception();
404
+                }
405
+            }
406
+        } catch (\Exception $e) {
407
+            $ncPermissions = $this->getDefaultPermissions($path);
408
+        }
409
+
410
+        return $ncPermissions;
411
+    }
412
+
413
+    /**
414
+     * calculate default permissions in case no permissions are provided
415
+     *
416
+     * @param $path
417
+     * @return int
418
+     */
419
+    protected function getDefaultPermissions($path) {
420
+        if ($this->is_dir($path)) {
421
+            $permissions = Constants::PERMISSION_ALL;
422
+        } else {
423
+            $permissions = Constants::PERMISSION_ALL & ~Constants::PERMISSION_CREATE;
424
+        }
425
+
426
+        return $permissions;
427
+    }
428 428
 }
Please login to merge, or discard this patch.