Completed
Push — master ( be1af1...4b274a )
by Maxence
28:06
created
apps/files_external/lib/Service/BackendService.php 1 patch
Indentation   +314 added lines, -314 removed lines patch added patch discarded remove patch
@@ -25,318 +25,318 @@
 block discarded – undo
25 25
  */
26 26
 class BackendService {
27 27
 
28
-	/** Visibility constants for VisibilityTrait */
29
-	public const VISIBILITY_NONE = 0;
30
-	public const VISIBILITY_PERSONAL = 1;
31
-	public const VISIBILITY_ADMIN = 2;
32
-	//const VISIBILITY_ALIENS = 4;
33
-
34
-	public const VISIBILITY_DEFAULT = 3; // PERSONAL | ADMIN
35
-
36
-	/** Priority constants for PriorityTrait */
37
-	public const PRIORITY_DEFAULT = 100;
38
-
39
-	private ?bool $userMountingAllowed = null;
40
-	/** @var string[] */
41
-	private array $userMountingBackends = [];
42
-
43
-	/** @var Backend[] */
44
-	private $backends = [];
45
-
46
-	/** @var IBackendProvider[] */
47
-	private $backendProviders = [];
48
-
49
-	/** @var AuthMechanism[] */
50
-	private $authMechanisms = [];
51
-
52
-	/** @var IAuthMechanismProvider[] */
53
-	private $authMechanismProviders = [];
54
-
55
-	/** @var callable[] */
56
-	private $configHandlerLoaders = [];
57
-
58
-	private $configHandlers = [];
59
-
60
-	public function __construct(
61
-		protected readonly IAppConfig $appConfig,
62
-	) {
63
-	}
64
-
65
-	/**
66
-	 * Register a backend provider
67
-	 *
68
-	 * @since 9.1.0
69
-	 * @param IBackendProvider $provider
70
-	 */
71
-	public function registerBackendProvider(IBackendProvider $provider) {
72
-		$this->backendProviders[] = $provider;
73
-	}
74
-
75
-	private function callForRegistrations() {
76
-		static $eventSent = false;
77
-		if (!$eventSent) {
78
-			Server::get(IEventDispatcher::class)->dispatch(
79
-				'OCA\\Files_External::loadAdditionalBackends',
80
-				new GenericEvent()
81
-			);
82
-			$eventSent = true;
83
-		}
84
-	}
85
-
86
-	private function loadBackendProviders() {
87
-		$this->callForRegistrations();
88
-		foreach ($this->backendProviders as $provider) {
89
-			$this->registerBackends($provider->getBackends());
90
-		}
91
-		$this->backendProviders = [];
92
-	}
93
-
94
-	/**
95
-	 * Register an auth mechanism provider
96
-	 *
97
-	 * @since 9.1.0
98
-	 * @param IAuthMechanismProvider $provider
99
-	 */
100
-	public function registerAuthMechanismProvider(IAuthMechanismProvider $provider) {
101
-		$this->authMechanismProviders[] = $provider;
102
-	}
103
-
104
-	private function loadAuthMechanismProviders() {
105
-		$this->callForRegistrations();
106
-		foreach ($this->authMechanismProviders as $provider) {
107
-			$this->registerAuthMechanisms($provider->getAuthMechanisms());
108
-		}
109
-		$this->authMechanismProviders = [];
110
-	}
111
-
112
-	/**
113
-	 * Register a backend
114
-	 *
115
-	 * @deprecated 9.1.0 use registerBackendProvider()
116
-	 * @param Backend $backend
117
-	 */
118
-	public function registerBackend(Backend $backend) {
119
-		if (!$this->isAllowedUserBackend($backend)) {
120
-			$backend->removeVisibility(BackendService::VISIBILITY_PERSONAL);
121
-		}
122
-		foreach ($backend->getIdentifierAliases() as $alias) {
123
-			$this->backends[$alias] = $backend;
124
-		}
125
-	}
126
-
127
-	/**
128
-	 * @deprecated 9.1.0 use registerBackendProvider()
129
-	 * @param Backend[] $backends
130
-	 */
131
-	public function registerBackends(array $backends) {
132
-		foreach ($backends as $backend) {
133
-			$this->registerBackend($backend);
134
-		}
135
-	}
136
-	/**
137
-	 * Register an authentication mechanism
138
-	 *
139
-	 * @deprecated 9.1.0 use registerAuthMechanismProvider()
140
-	 * @param AuthMechanism $authMech
141
-	 */
142
-	public function registerAuthMechanism(AuthMechanism $authMech) {
143
-		if (!$this->isAllowedAuthMechanism($authMech)) {
144
-			$authMech->removeVisibility(BackendService::VISIBILITY_PERSONAL);
145
-		}
146
-		foreach ($authMech->getIdentifierAliases() as $alias) {
147
-			$this->authMechanisms[$alias] = $authMech;
148
-		}
149
-	}
150
-
151
-	/**
152
-	 * @deprecated 9.1.0 use registerAuthMechanismProvider()
153
-	 * @param AuthMechanism[] $mechanisms
154
-	 */
155
-	public function registerAuthMechanisms(array $mechanisms) {
156
-		foreach ($mechanisms as $mechanism) {
157
-			$this->registerAuthMechanism($mechanism);
158
-		}
159
-	}
160
-
161
-	/**
162
-	 * Get all backends
163
-	 *
164
-	 * @return Backend[]
165
-	 */
166
-	public function getBackends() {
167
-		$this->loadBackendProviders();
168
-		// only return real identifiers, no aliases
169
-		$backends = [];
170
-		foreach ($this->backends as $backend) {
171
-			$backends[$backend->getIdentifier()] = $backend;
172
-		}
173
-		return $backends;
174
-	}
175
-
176
-	/**
177
-	 * Get all available backends
178
-	 *
179
-	 * @return Backend[]
180
-	 */
181
-	public function getAvailableBackends() {
182
-		return array_filter($this->getBackends(), function ($backend) {
183
-			$missing = array_filter($backend->checkDependencies(), fn (MissingDependency $dependency) => !$dependency->isOptional());
184
-			return count($missing) === 0;
185
-		});
186
-	}
187
-
188
-	/**
189
-	 * @param string $identifier
190
-	 * @return Backend|null
191
-	 */
192
-	public function getBackend($identifier) {
193
-		$this->loadBackendProviders();
194
-		if (isset($this->backends[$identifier])) {
195
-			return $this->backends[$identifier];
196
-		}
197
-		return null;
198
-	}
199
-
200
-	/**
201
-	 * Get all authentication mechanisms
202
-	 *
203
-	 * @return AuthMechanism[]
204
-	 */
205
-	public function getAuthMechanisms() {
206
-		$this->loadAuthMechanismProviders();
207
-		// only return real identifiers, no aliases
208
-		$mechanisms = [];
209
-		foreach ($this->authMechanisms as $mechanism) {
210
-			$mechanisms[$mechanism->getIdentifier()] = $mechanism;
211
-		}
212
-		return $mechanisms;
213
-	}
214
-
215
-	/**
216
-	 * Get all authentication mechanisms for schemes
217
-	 *
218
-	 * @param string[] $schemes
219
-	 * @return AuthMechanism[]
220
-	 */
221
-	public function getAuthMechanismsByScheme(array $schemes) {
222
-		return array_filter($this->getAuthMechanisms(), function ($authMech) use ($schemes) {
223
-			return in_array($authMech->getScheme(), $schemes, true);
224
-		});
225
-	}
226
-
227
-	/**
228
-	 * @param string $identifier
229
-	 * @return AuthMechanism|null
230
-	 */
231
-	public function getAuthMechanism($identifier) {
232
-		$this->loadAuthMechanismProviders();
233
-		if (isset($this->authMechanisms[$identifier])) {
234
-			return $this->authMechanisms[$identifier];
235
-		}
236
-		return null;
237
-	}
238
-
239
-	/**
240
-	 * returns if user mounting is allowed.
241
-	 * also initiate the list of available backends.
242
-	 *
243
-	 * @psalm-assert bool $this->userMountingAllowed
244
-	 */
245
-	public function isUserMountingAllowed(): bool {
246
-		if ($this->userMountingAllowed === null) {
247
-			// Load config values
248
-			$this->userMountingAllowed = $this->appConfig->getValueBool(Application::APP_ID, ConfigLexicon::ALLOW_USER_MOUNTING);
249
-			$this->userMountingBackends = explode(',', $this->appConfig->getValueString(Application::APP_ID, ConfigLexicon::USER_MOUNTING_BACKENDS));
250
-
251
-			// if no backend is in the list an empty string is in the array and user mounting is disabled
252
-			if ($this->userMountingBackends === ['']) {
253
-				$this->userMountingAllowed = false;
254
-			}
255
-		}
256
-
257
-		return $this->userMountingAllowed;
258
-	}
259
-
260
-	/**
261
-	 * Check a backend if a user is allowed to mount it
262
-	 *
263
-	 * @param Backend $backend
264
-	 * @return bool
265
-	 */
266
-	protected function isAllowedUserBackend(Backend $backend): bool {
267
-		return ($this->isUserMountingAllowed() && array_intersect($backend->getIdentifierAliases(), $this->userMountingBackends));
268
-	}
269
-
270
-	/**
271
-	 * Check an authentication mechanism if a user is allowed to use it
272
-	 *
273
-	 * @param AuthMechanism $authMechanism
274
-	 * @return bool
275
-	 */
276
-	protected function isAllowedAuthMechanism(AuthMechanism $authMechanism) {
277
-		return true; // not implemented
278
-	}
279
-
280
-	/**
281
-	 * registers a configuration handler
282
-	 *
283
-	 * The function of the provided $placeholder is mostly to act a sorting
284
-	 * criteria, so longer placeholders are replaced first. This avoids
285
-	 * "$user" overwriting parts of "$userMail" and "$userLang", for example.
286
-	 * The provided value should not contain the $ prefix, only a-z0-9 are
287
-	 * allowed. Upper case letters are lower cased, the replacement is case-
288
-	 * insensitive.
289
-	 *
290
-	 * The configHandlerLoader should just instantiate the handler on demand.
291
-	 * For now all handlers are instantiated when a mount is loaded, independent
292
-	 * of whether the placeholder is present or not. This may change in future.
293
-	 *
294
-	 * @since 16.0.0
295
-	 */
296
-	public function registerConfigHandler(string $placeholder, callable $configHandlerLoader) {
297
-		$placeholder = trim(strtolower($placeholder));
298
-		if (!(bool)\preg_match('/^[a-z0-9]*$/', $placeholder)) {
299
-			throw new \RuntimeException(sprintf(
300
-				'Invalid placeholder %s, only [a-z0-9] are allowed', $placeholder
301
-			));
302
-		}
303
-		if ($placeholder === '') {
304
-			throw new \RuntimeException('Invalid empty placeholder');
305
-		}
306
-		if (isset($this->configHandlerLoaders[$placeholder]) || isset($this->configHandlers[$placeholder])) {
307
-			throw new \RuntimeException(sprintf('A handler is already registered for %s', $placeholder));
308
-		}
309
-		$this->configHandlerLoaders[$placeholder] = $configHandlerLoader;
310
-	}
311
-
312
-	protected function loadConfigHandlers():void {
313
-		$this->callForRegistrations();
314
-		$newLoaded = false;
315
-		foreach ($this->configHandlerLoaders as $placeholder => $loader) {
316
-			$handler = $loader();
317
-			if (!$handler instanceof IConfigHandler) {
318
-				throw new \RuntimeException(sprintf(
319
-					'Handler for %s is not an instance of IConfigHandler', $placeholder
320
-				));
321
-			}
322
-			$this->configHandlers[$placeholder] = $handler;
323
-			$newLoaded = true;
324
-		}
325
-		$this->configHandlerLoaders = [];
326
-		if ($newLoaded) {
327
-			// ensure those with longest placeholders come first,
328
-			// to avoid substring matches
329
-			uksort($this->configHandlers, function ($phA, $phB) {
330
-				return strlen($phB) <=> strlen($phA);
331
-			});
332
-		}
333
-	}
334
-
335
-	/**
336
-	 * @since 16.0.0
337
-	 */
338
-	public function getConfigHandlers() {
339
-		$this->loadConfigHandlers();
340
-		return $this->configHandlers;
341
-	}
28
+    /** Visibility constants for VisibilityTrait */
29
+    public const VISIBILITY_NONE = 0;
30
+    public const VISIBILITY_PERSONAL = 1;
31
+    public const VISIBILITY_ADMIN = 2;
32
+    //const VISIBILITY_ALIENS = 4;
33
+
34
+    public const VISIBILITY_DEFAULT = 3; // PERSONAL | ADMIN
35
+
36
+    /** Priority constants for PriorityTrait */
37
+    public const PRIORITY_DEFAULT = 100;
38
+
39
+    private ?bool $userMountingAllowed = null;
40
+    /** @var string[] */
41
+    private array $userMountingBackends = [];
42
+
43
+    /** @var Backend[] */
44
+    private $backends = [];
45
+
46
+    /** @var IBackendProvider[] */
47
+    private $backendProviders = [];
48
+
49
+    /** @var AuthMechanism[] */
50
+    private $authMechanisms = [];
51
+
52
+    /** @var IAuthMechanismProvider[] */
53
+    private $authMechanismProviders = [];
54
+
55
+    /** @var callable[] */
56
+    private $configHandlerLoaders = [];
57
+
58
+    private $configHandlers = [];
59
+
60
+    public function __construct(
61
+        protected readonly IAppConfig $appConfig,
62
+    ) {
63
+    }
64
+
65
+    /**
66
+     * Register a backend provider
67
+     *
68
+     * @since 9.1.0
69
+     * @param IBackendProvider $provider
70
+     */
71
+    public function registerBackendProvider(IBackendProvider $provider) {
72
+        $this->backendProviders[] = $provider;
73
+    }
74
+
75
+    private function callForRegistrations() {
76
+        static $eventSent = false;
77
+        if (!$eventSent) {
78
+            Server::get(IEventDispatcher::class)->dispatch(
79
+                'OCA\\Files_External::loadAdditionalBackends',
80
+                new GenericEvent()
81
+            );
82
+            $eventSent = true;
83
+        }
84
+    }
85
+
86
+    private function loadBackendProviders() {
87
+        $this->callForRegistrations();
88
+        foreach ($this->backendProviders as $provider) {
89
+            $this->registerBackends($provider->getBackends());
90
+        }
91
+        $this->backendProviders = [];
92
+    }
93
+
94
+    /**
95
+     * Register an auth mechanism provider
96
+     *
97
+     * @since 9.1.0
98
+     * @param IAuthMechanismProvider $provider
99
+     */
100
+    public function registerAuthMechanismProvider(IAuthMechanismProvider $provider) {
101
+        $this->authMechanismProviders[] = $provider;
102
+    }
103
+
104
+    private function loadAuthMechanismProviders() {
105
+        $this->callForRegistrations();
106
+        foreach ($this->authMechanismProviders as $provider) {
107
+            $this->registerAuthMechanisms($provider->getAuthMechanisms());
108
+        }
109
+        $this->authMechanismProviders = [];
110
+    }
111
+
112
+    /**
113
+     * Register a backend
114
+     *
115
+     * @deprecated 9.1.0 use registerBackendProvider()
116
+     * @param Backend $backend
117
+     */
118
+    public function registerBackend(Backend $backend) {
119
+        if (!$this->isAllowedUserBackend($backend)) {
120
+            $backend->removeVisibility(BackendService::VISIBILITY_PERSONAL);
121
+        }
122
+        foreach ($backend->getIdentifierAliases() as $alias) {
123
+            $this->backends[$alias] = $backend;
124
+        }
125
+    }
126
+
127
+    /**
128
+     * @deprecated 9.1.0 use registerBackendProvider()
129
+     * @param Backend[] $backends
130
+     */
131
+    public function registerBackends(array $backends) {
132
+        foreach ($backends as $backend) {
133
+            $this->registerBackend($backend);
134
+        }
135
+    }
136
+    /**
137
+     * Register an authentication mechanism
138
+     *
139
+     * @deprecated 9.1.0 use registerAuthMechanismProvider()
140
+     * @param AuthMechanism $authMech
141
+     */
142
+    public function registerAuthMechanism(AuthMechanism $authMech) {
143
+        if (!$this->isAllowedAuthMechanism($authMech)) {
144
+            $authMech->removeVisibility(BackendService::VISIBILITY_PERSONAL);
145
+        }
146
+        foreach ($authMech->getIdentifierAliases() as $alias) {
147
+            $this->authMechanisms[$alias] = $authMech;
148
+        }
149
+    }
150
+
151
+    /**
152
+     * @deprecated 9.1.0 use registerAuthMechanismProvider()
153
+     * @param AuthMechanism[] $mechanisms
154
+     */
155
+    public function registerAuthMechanisms(array $mechanisms) {
156
+        foreach ($mechanisms as $mechanism) {
157
+            $this->registerAuthMechanism($mechanism);
158
+        }
159
+    }
160
+
161
+    /**
162
+     * Get all backends
163
+     *
164
+     * @return Backend[]
165
+     */
166
+    public function getBackends() {
167
+        $this->loadBackendProviders();
168
+        // only return real identifiers, no aliases
169
+        $backends = [];
170
+        foreach ($this->backends as $backend) {
171
+            $backends[$backend->getIdentifier()] = $backend;
172
+        }
173
+        return $backends;
174
+    }
175
+
176
+    /**
177
+     * Get all available backends
178
+     *
179
+     * @return Backend[]
180
+     */
181
+    public function getAvailableBackends() {
182
+        return array_filter($this->getBackends(), function ($backend) {
183
+            $missing = array_filter($backend->checkDependencies(), fn (MissingDependency $dependency) => !$dependency->isOptional());
184
+            return count($missing) === 0;
185
+        });
186
+    }
187
+
188
+    /**
189
+     * @param string $identifier
190
+     * @return Backend|null
191
+     */
192
+    public function getBackend($identifier) {
193
+        $this->loadBackendProviders();
194
+        if (isset($this->backends[$identifier])) {
195
+            return $this->backends[$identifier];
196
+        }
197
+        return null;
198
+    }
199
+
200
+    /**
201
+     * Get all authentication mechanisms
202
+     *
203
+     * @return AuthMechanism[]
204
+     */
205
+    public function getAuthMechanisms() {
206
+        $this->loadAuthMechanismProviders();
207
+        // only return real identifiers, no aliases
208
+        $mechanisms = [];
209
+        foreach ($this->authMechanisms as $mechanism) {
210
+            $mechanisms[$mechanism->getIdentifier()] = $mechanism;
211
+        }
212
+        return $mechanisms;
213
+    }
214
+
215
+    /**
216
+     * Get all authentication mechanisms for schemes
217
+     *
218
+     * @param string[] $schemes
219
+     * @return AuthMechanism[]
220
+     */
221
+    public function getAuthMechanismsByScheme(array $schemes) {
222
+        return array_filter($this->getAuthMechanisms(), function ($authMech) use ($schemes) {
223
+            return in_array($authMech->getScheme(), $schemes, true);
224
+        });
225
+    }
226
+
227
+    /**
228
+     * @param string $identifier
229
+     * @return AuthMechanism|null
230
+     */
231
+    public function getAuthMechanism($identifier) {
232
+        $this->loadAuthMechanismProviders();
233
+        if (isset($this->authMechanisms[$identifier])) {
234
+            return $this->authMechanisms[$identifier];
235
+        }
236
+        return null;
237
+    }
238
+
239
+    /**
240
+     * returns if user mounting is allowed.
241
+     * also initiate the list of available backends.
242
+     *
243
+     * @psalm-assert bool $this->userMountingAllowed
244
+     */
245
+    public function isUserMountingAllowed(): bool {
246
+        if ($this->userMountingAllowed === null) {
247
+            // Load config values
248
+            $this->userMountingAllowed = $this->appConfig->getValueBool(Application::APP_ID, ConfigLexicon::ALLOW_USER_MOUNTING);
249
+            $this->userMountingBackends = explode(',', $this->appConfig->getValueString(Application::APP_ID, ConfigLexicon::USER_MOUNTING_BACKENDS));
250
+
251
+            // if no backend is in the list an empty string is in the array and user mounting is disabled
252
+            if ($this->userMountingBackends === ['']) {
253
+                $this->userMountingAllowed = false;
254
+            }
255
+        }
256
+
257
+        return $this->userMountingAllowed;
258
+    }
259
+
260
+    /**
261
+     * Check a backend if a user is allowed to mount it
262
+     *
263
+     * @param Backend $backend
264
+     * @return bool
265
+     */
266
+    protected function isAllowedUserBackend(Backend $backend): bool {
267
+        return ($this->isUserMountingAllowed() && array_intersect($backend->getIdentifierAliases(), $this->userMountingBackends));
268
+    }
269
+
270
+    /**
271
+     * Check an authentication mechanism if a user is allowed to use it
272
+     *
273
+     * @param AuthMechanism $authMechanism
274
+     * @return bool
275
+     */
276
+    protected function isAllowedAuthMechanism(AuthMechanism $authMechanism) {
277
+        return true; // not implemented
278
+    }
279
+
280
+    /**
281
+     * registers a configuration handler
282
+     *
283
+     * The function of the provided $placeholder is mostly to act a sorting
284
+     * criteria, so longer placeholders are replaced first. This avoids
285
+     * "$user" overwriting parts of "$userMail" and "$userLang", for example.
286
+     * The provided value should not contain the $ prefix, only a-z0-9 are
287
+     * allowed. Upper case letters are lower cased, the replacement is case-
288
+     * insensitive.
289
+     *
290
+     * The configHandlerLoader should just instantiate the handler on demand.
291
+     * For now all handlers are instantiated when a mount is loaded, independent
292
+     * of whether the placeholder is present or not. This may change in future.
293
+     *
294
+     * @since 16.0.0
295
+     */
296
+    public function registerConfigHandler(string $placeholder, callable $configHandlerLoader) {
297
+        $placeholder = trim(strtolower($placeholder));
298
+        if (!(bool)\preg_match('/^[a-z0-9]*$/', $placeholder)) {
299
+            throw new \RuntimeException(sprintf(
300
+                'Invalid placeholder %s, only [a-z0-9] are allowed', $placeholder
301
+            ));
302
+        }
303
+        if ($placeholder === '') {
304
+            throw new \RuntimeException('Invalid empty placeholder');
305
+        }
306
+        if (isset($this->configHandlerLoaders[$placeholder]) || isset($this->configHandlers[$placeholder])) {
307
+            throw new \RuntimeException(sprintf('A handler is already registered for %s', $placeholder));
308
+        }
309
+        $this->configHandlerLoaders[$placeholder] = $configHandlerLoader;
310
+    }
311
+
312
+    protected function loadConfigHandlers():void {
313
+        $this->callForRegistrations();
314
+        $newLoaded = false;
315
+        foreach ($this->configHandlerLoaders as $placeholder => $loader) {
316
+            $handler = $loader();
317
+            if (!$handler instanceof IConfigHandler) {
318
+                throw new \RuntimeException(sprintf(
319
+                    'Handler for %s is not an instance of IConfigHandler', $placeholder
320
+                ));
321
+            }
322
+            $this->configHandlers[$placeholder] = $handler;
323
+            $newLoaded = true;
324
+        }
325
+        $this->configHandlerLoaders = [];
326
+        if ($newLoaded) {
327
+            // ensure those with longest placeholders come first,
328
+            // to avoid substring matches
329
+            uksort($this->configHandlers, function ($phA, $phB) {
330
+                return strlen($phB) <=> strlen($phA);
331
+            });
332
+        }
333
+    }
334
+
335
+    /**
336
+     * @since 16.0.0
337
+     */
338
+    public function getConfigHandlers() {
339
+        $this->loadConfigHandlers();
340
+        return $this->configHandlers;
341
+    }
342 342
 }
Please login to merge, or discard this patch.