Passed
Push — master ( ec0305...fced73 )
by Roeland
09:53
created
core/Controller/ClientFlowLoginController.php 1 patch
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -50,336 +50,336 @@
 block discarded – undo
50 50
 use Symfony\Component\EventDispatcher\GenericEvent;
51 51
 
52 52
 class ClientFlowLoginController extends Controller {
53
-	/** @var IUserSession */
54
-	private $userSession;
55
-	/** @var IL10N */
56
-	private $l10n;
57
-	/** @var Defaults */
58
-	private $defaults;
59
-	/** @var ISession */
60
-	private $session;
61
-	/** @var IProvider */
62
-	private $tokenProvider;
63
-	/** @var ISecureRandom */
64
-	private $random;
65
-	/** @var IURLGenerator */
66
-	private $urlGenerator;
67
-	/** @var ClientMapper */
68
-	private $clientMapper;
69
-	/** @var AccessTokenMapper */
70
-	private $accessTokenMapper;
71
-	/** @var ICrypto */
72
-	private $crypto;
73
-	/** @var EventDispatcherInterface */
74
-	private $eventDispatcher;
75
-
76
-	const stateName = 'client.flow.state.token';
77
-
78
-	/**
79
-	 * @param string $appName
80
-	 * @param IRequest $request
81
-	 * @param IUserSession $userSession
82
-	 * @param IL10N $l10n
83
-	 * @param Defaults $defaults
84
-	 * @param ISession $session
85
-	 * @param IProvider $tokenProvider
86
-	 * @param ISecureRandom $random
87
-	 * @param IURLGenerator $urlGenerator
88
-	 * @param ClientMapper $clientMapper
89
-	 * @param AccessTokenMapper $accessTokenMapper
90
-	 * @param ICrypto $crypto
91
-	 * @param EventDispatcherInterface $eventDispatcher
92
-	 */
93
-	public function __construct($appName,
94
-								IRequest $request,
95
-								IUserSession $userSession,
96
-								IL10N $l10n,
97
-								Defaults $defaults,
98
-								ISession $session,
99
-								IProvider $tokenProvider,
100
-								ISecureRandom $random,
101
-								IURLGenerator $urlGenerator,
102
-								ClientMapper $clientMapper,
103
-								AccessTokenMapper $accessTokenMapper,
104
-								ICrypto $crypto,
105
-								EventDispatcherInterface $eventDispatcher) {
106
-		parent::__construct($appName, $request);
107
-		$this->userSession = $userSession;
108
-		$this->l10n = $l10n;
109
-		$this->defaults = $defaults;
110
-		$this->session = $session;
111
-		$this->tokenProvider = $tokenProvider;
112
-		$this->random = $random;
113
-		$this->urlGenerator = $urlGenerator;
114
-		$this->clientMapper = $clientMapper;
115
-		$this->accessTokenMapper = $accessTokenMapper;
116
-		$this->crypto = $crypto;
117
-		$this->eventDispatcher = $eventDispatcher;
118
-	}
119
-
120
-	/**
121
-	 * @return string
122
-	 */
123
-	private function getClientName() {
124
-		$userAgent = $this->request->getHeader('USER_AGENT');
125
-		return $userAgent !== '' ? $userAgent : 'unknown';
126
-	}
127
-
128
-	/**
129
-	 * @param string $stateToken
130
-	 * @return bool
131
-	 */
132
-	private function isValidToken($stateToken) {
133
-		$currentToken = $this->session->get(self::stateName);
134
-		if(!is_string($stateToken) || !is_string($currentToken)) {
135
-			return false;
136
-		}
137
-		return hash_equals($currentToken, $stateToken);
138
-	}
139
-
140
-	/**
141
-	 * @return StandaloneTemplateResponse
142
-	 */
143
-	private function stateTokenForbiddenResponse() {
144
-		$response = new StandaloneTemplateResponse(
145
-			$this->appName,
146
-			'403',
147
-			[
148
-				'message' => $this->l10n->t('State token does not match'),
149
-			],
150
-			'guest'
151
-		);
152
-		$response->setStatus(Http::STATUS_FORBIDDEN);
153
-		return $response;
154
-	}
155
-
156
-	/**
157
-	 * @PublicPage
158
-	 * @NoCSRFRequired
159
-	 * @UseSession
160
-	 *
161
-	 * @param string $clientIdentifier
162
-	 *
163
-	 * @return StandaloneTemplateResponse
164
-	 */
165
-	public function showAuthPickerPage($clientIdentifier = '') {
166
-		$clientName = $this->getClientName();
167
-		$client = null;
168
-		if($clientIdentifier !== '') {
169
-			$client = $this->clientMapper->getByIdentifier($clientIdentifier);
170
-			$clientName = $client->getName();
171
-		}
172
-
173
-		// No valid clientIdentifier given and no valid API Request (APIRequest header not set)
174
-		$clientRequest = $this->request->getHeader('OCS-APIREQUEST');
175
-		if ($clientRequest !== 'true' && $client === null) {
176
-			return new StandaloneTemplateResponse(
177
-				$this->appName,
178
-				'error',
179
-				[
180
-					'errors' =>
181
-					[
182
-						[
183
-							'error' => 'Access Forbidden',
184
-							'hint' => 'Invalid request',
185
-						],
186
-					],
187
-				],
188
-				'guest'
189
-			);
190
-		}
191
-
192
-		$stateToken = $this->random->generate(
193
-			64,
194
-			ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS
195
-		);
196
-		$this->session->set(self::stateName, $stateToken);
197
-
198
-		$csp = new Http\ContentSecurityPolicy();
199
-		$csp->addAllowedFormActionDomain('nc://*');
200
-
201
-		$response = new StandaloneTemplateResponse(
202
-			$this->appName,
203
-			'loginflow/authpicker',
204
-			[
205
-				'client' => $clientName,
206
-				'clientIdentifier' => $clientIdentifier,
207
-				'instanceName' => $this->defaults->getName(),
208
-				'urlGenerator' => $this->urlGenerator,
209
-				'stateToken' => $stateToken,
210
-				'serverHost' => $this->getServerPath(),
211
-				'oauthState' => $this->session->get('oauth.state'),
212
-			],
213
-			'guest'
214
-		);
215
-
216
-		$response->setContentSecurityPolicy($csp);
217
-		return $response;
218
-	}
219
-
220
-	/**
221
-	 * @NoAdminRequired
222
-	 * @NoCSRFRequired
223
-	 * @NoSameSiteCookieRequired
224
-	 * @UseSession
225
-	 *
226
-	 * @param string $stateToken
227
-	 * @param string $clientIdentifier
228
-	 * @return StandaloneTemplateResponse
229
-	 */
230
-	public function grantPage($stateToken = '',
231
-								 $clientIdentifier = '') {
232
-		if(!$this->isValidToken($stateToken)) {
233
-			return $this->stateTokenForbiddenResponse();
234
-		}
235
-
236
-		$clientName = $this->getClientName();
237
-		$client = null;
238
-		if($clientIdentifier !== '') {
239
-			$client = $this->clientMapper->getByIdentifier($clientIdentifier);
240
-			$clientName = $client->getName();
241
-		}
242
-
243
-		$csp = new Http\ContentSecurityPolicy();
244
-		$csp->addAllowedFormActionDomain('nc://*');
245
-
246
-		$response = new StandaloneTemplateResponse(
247
-			$this->appName,
248
-			'loginflow/grant',
249
-			[
250
-				'client' => $clientName,
251
-				'clientIdentifier' => $clientIdentifier,
252
-				'instanceName' => $this->defaults->getName(),
253
-				'urlGenerator' => $this->urlGenerator,
254
-				'stateToken' => $stateToken,
255
-				'serverHost' => $this->getServerPath(),
256
-				'oauthState' => $this->session->get('oauth.state'),
257
-			],
258
-			'guest'
259
-		);
260
-
261
-		$response->setContentSecurityPolicy($csp);
262
-		return $response;
263
-	}
264
-
265
-	/**
266
-	 * @NoAdminRequired
267
-	 * @UseSession
268
-	 *
269
-	 * @param string $stateToken
270
-	 * @param string $clientIdentifier
271
-	 * @return Http\RedirectResponse|Response
272
-	 */
273
-	public function generateAppPassword($stateToken,
274
-										$clientIdentifier = '') {
275
-		if(!$this->isValidToken($stateToken)) {
276
-			$this->session->remove(self::stateName);
277
-			return $this->stateTokenForbiddenResponse();
278
-		}
279
-
280
-		$this->session->remove(self::stateName);
281
-
282
-		try {
283
-			$sessionId = $this->session->getId();
284
-		} catch (SessionNotAvailableException $ex) {
285
-			$response = new Response();
286
-			$response->setStatus(Http::STATUS_FORBIDDEN);
287
-			return $response;
288
-		}
289
-
290
-		try {
291
-			$sessionToken = $this->tokenProvider->getToken($sessionId);
292
-			$loginName = $sessionToken->getLoginName();
293
-			try {
294
-				$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
295
-			} catch (PasswordlessTokenException $ex) {
296
-				$password = null;
297
-			}
298
-		} catch (InvalidTokenException $ex) {
299
-			$response = new Response();
300
-			$response->setStatus(Http::STATUS_FORBIDDEN);
301
-			return $response;
302
-		}
303
-
304
-		$clientName = $this->getClientName();
305
-		$client = false;
306
-		if($clientIdentifier !== '') {
307
-			$client = $this->clientMapper->getByIdentifier($clientIdentifier);
308
-			$clientName = $client->getName();
309
-		}
310
-
311
-		$token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
312
-		$uid = $this->userSession->getUser()->getUID();
313
-		$generatedToken = $this->tokenProvider->generateToken(
314
-			$token,
315
-			$uid,
316
-			$loginName,
317
-			$password,
318
-			$clientName,
319
-			IToken::PERMANENT_TOKEN,
320
-			IToken::DO_NOT_REMEMBER
321
-		);
322
-
323
-		if($client) {
324
-			$code = $this->random->generate(128, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
325
-			$accessToken = new AccessToken();
326
-			$accessToken->setClientId($client->getId());
327
-			$accessToken->setEncryptedToken($this->crypto->encrypt($token, $code));
328
-			$accessToken->setHashedCode(hash('sha512', $code));
329
-			$accessToken->setTokenId($generatedToken->getId());
330
-			$this->accessTokenMapper->insert($accessToken);
331
-
332
-			$redirectUri = sprintf(
333
-				'%s?state=%s&code=%s',
334
-				$client->getRedirectUri(),
335
-				urlencode($this->session->get('oauth.state')),
336
-				urlencode($code)
337
-			);
338
-			$this->session->remove('oauth.state');
339
-		} else {
340
-			$redirectUri = 'nc://login/server:' . $this->getServerPath() . '&user:' . urlencode($loginName) . '&password:' . urlencode($token);
341
-
342
-			// Clear the token from the login here
343
-			$this->tokenProvider->invalidateToken($sessionId);
344
-		}
345
-
346
-		$event = new GenericEvent($generatedToken);
347
-		$this->eventDispatcher->dispatch('app_password_created', $event);
348
-
349
-		return new Http\RedirectResponse($redirectUri);
350
-	}
351
-
352
-	/**
353
-	 * @PublicPage
354
-	 */
355
-	public function apptokenRedirect(string $stateToken, string $user, string $password) {
356
-		if (!$this->isValidToken($stateToken)) {
357
-			return $this->stateTokenForbiddenResponse();
358
-		}
359
-
360
-		$redirectUri = 'nc://login/server:' . $this->getServerPath() . '&user:' . urlencode($user) . '&password:' . urlencode($password);
361
-		return new Http\RedirectResponse($redirectUri);
362
-	}
363
-
364
-	private function getServerPath(): string {
365
-		$serverPostfix = '';
366
-
367
-		if (strpos($this->request->getRequestUri(), '/index.php') !== false) {
368
-			$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/index.php'));
369
-		} else if (strpos($this->request->getRequestUri(), '/login/flow') !== false) {
370
-			$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/flow'));
371
-		}
372
-
373
-		$protocol = $this->request->getServerProtocol();
374
-
375
-		if ($protocol !== "https") {
376
-			$xForwardedProto = $this->request->getHeader('X-Forwarded-Proto');
377
-			$xForwardedSSL = $this->request->getHeader('X-Forwarded-Ssl');
378
-			if ($xForwardedProto === 'https' || $xForwardedSSL === 'on') {
379
-				$protocol = 'https';
380
-			}
381
-		}
382
-
383
-		return $protocol . "://" . $this->request->getServerHost() . $serverPostfix;
384
-	}
53
+    /** @var IUserSession */
54
+    private $userSession;
55
+    /** @var IL10N */
56
+    private $l10n;
57
+    /** @var Defaults */
58
+    private $defaults;
59
+    /** @var ISession */
60
+    private $session;
61
+    /** @var IProvider */
62
+    private $tokenProvider;
63
+    /** @var ISecureRandom */
64
+    private $random;
65
+    /** @var IURLGenerator */
66
+    private $urlGenerator;
67
+    /** @var ClientMapper */
68
+    private $clientMapper;
69
+    /** @var AccessTokenMapper */
70
+    private $accessTokenMapper;
71
+    /** @var ICrypto */
72
+    private $crypto;
73
+    /** @var EventDispatcherInterface */
74
+    private $eventDispatcher;
75
+
76
+    const stateName = 'client.flow.state.token';
77
+
78
+    /**
79
+     * @param string $appName
80
+     * @param IRequest $request
81
+     * @param IUserSession $userSession
82
+     * @param IL10N $l10n
83
+     * @param Defaults $defaults
84
+     * @param ISession $session
85
+     * @param IProvider $tokenProvider
86
+     * @param ISecureRandom $random
87
+     * @param IURLGenerator $urlGenerator
88
+     * @param ClientMapper $clientMapper
89
+     * @param AccessTokenMapper $accessTokenMapper
90
+     * @param ICrypto $crypto
91
+     * @param EventDispatcherInterface $eventDispatcher
92
+     */
93
+    public function __construct($appName,
94
+                                IRequest $request,
95
+                                IUserSession $userSession,
96
+                                IL10N $l10n,
97
+                                Defaults $defaults,
98
+                                ISession $session,
99
+                                IProvider $tokenProvider,
100
+                                ISecureRandom $random,
101
+                                IURLGenerator $urlGenerator,
102
+                                ClientMapper $clientMapper,
103
+                                AccessTokenMapper $accessTokenMapper,
104
+                                ICrypto $crypto,
105
+                                EventDispatcherInterface $eventDispatcher) {
106
+        parent::__construct($appName, $request);
107
+        $this->userSession = $userSession;
108
+        $this->l10n = $l10n;
109
+        $this->defaults = $defaults;
110
+        $this->session = $session;
111
+        $this->tokenProvider = $tokenProvider;
112
+        $this->random = $random;
113
+        $this->urlGenerator = $urlGenerator;
114
+        $this->clientMapper = $clientMapper;
115
+        $this->accessTokenMapper = $accessTokenMapper;
116
+        $this->crypto = $crypto;
117
+        $this->eventDispatcher = $eventDispatcher;
118
+    }
119
+
120
+    /**
121
+     * @return string
122
+     */
123
+    private function getClientName() {
124
+        $userAgent = $this->request->getHeader('USER_AGENT');
125
+        return $userAgent !== '' ? $userAgent : 'unknown';
126
+    }
127
+
128
+    /**
129
+     * @param string $stateToken
130
+     * @return bool
131
+     */
132
+    private function isValidToken($stateToken) {
133
+        $currentToken = $this->session->get(self::stateName);
134
+        if(!is_string($stateToken) || !is_string($currentToken)) {
135
+            return false;
136
+        }
137
+        return hash_equals($currentToken, $stateToken);
138
+    }
139
+
140
+    /**
141
+     * @return StandaloneTemplateResponse
142
+     */
143
+    private function stateTokenForbiddenResponse() {
144
+        $response = new StandaloneTemplateResponse(
145
+            $this->appName,
146
+            '403',
147
+            [
148
+                'message' => $this->l10n->t('State token does not match'),
149
+            ],
150
+            'guest'
151
+        );
152
+        $response->setStatus(Http::STATUS_FORBIDDEN);
153
+        return $response;
154
+    }
155
+
156
+    /**
157
+     * @PublicPage
158
+     * @NoCSRFRequired
159
+     * @UseSession
160
+     *
161
+     * @param string $clientIdentifier
162
+     *
163
+     * @return StandaloneTemplateResponse
164
+     */
165
+    public function showAuthPickerPage($clientIdentifier = '') {
166
+        $clientName = $this->getClientName();
167
+        $client = null;
168
+        if($clientIdentifier !== '') {
169
+            $client = $this->clientMapper->getByIdentifier($clientIdentifier);
170
+            $clientName = $client->getName();
171
+        }
172
+
173
+        // No valid clientIdentifier given and no valid API Request (APIRequest header not set)
174
+        $clientRequest = $this->request->getHeader('OCS-APIREQUEST');
175
+        if ($clientRequest !== 'true' && $client === null) {
176
+            return new StandaloneTemplateResponse(
177
+                $this->appName,
178
+                'error',
179
+                [
180
+                    'errors' =>
181
+                    [
182
+                        [
183
+                            'error' => 'Access Forbidden',
184
+                            'hint' => 'Invalid request',
185
+                        ],
186
+                    ],
187
+                ],
188
+                'guest'
189
+            );
190
+        }
191
+
192
+        $stateToken = $this->random->generate(
193
+            64,
194
+            ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS
195
+        );
196
+        $this->session->set(self::stateName, $stateToken);
197
+
198
+        $csp = new Http\ContentSecurityPolicy();
199
+        $csp->addAllowedFormActionDomain('nc://*');
200
+
201
+        $response = new StandaloneTemplateResponse(
202
+            $this->appName,
203
+            'loginflow/authpicker',
204
+            [
205
+                'client' => $clientName,
206
+                'clientIdentifier' => $clientIdentifier,
207
+                'instanceName' => $this->defaults->getName(),
208
+                'urlGenerator' => $this->urlGenerator,
209
+                'stateToken' => $stateToken,
210
+                'serverHost' => $this->getServerPath(),
211
+                'oauthState' => $this->session->get('oauth.state'),
212
+            ],
213
+            'guest'
214
+        );
215
+
216
+        $response->setContentSecurityPolicy($csp);
217
+        return $response;
218
+    }
219
+
220
+    /**
221
+     * @NoAdminRequired
222
+     * @NoCSRFRequired
223
+     * @NoSameSiteCookieRequired
224
+     * @UseSession
225
+     *
226
+     * @param string $stateToken
227
+     * @param string $clientIdentifier
228
+     * @return StandaloneTemplateResponse
229
+     */
230
+    public function grantPage($stateToken = '',
231
+                                    $clientIdentifier = '') {
232
+        if(!$this->isValidToken($stateToken)) {
233
+            return $this->stateTokenForbiddenResponse();
234
+        }
235
+
236
+        $clientName = $this->getClientName();
237
+        $client = null;
238
+        if($clientIdentifier !== '') {
239
+            $client = $this->clientMapper->getByIdentifier($clientIdentifier);
240
+            $clientName = $client->getName();
241
+        }
242
+
243
+        $csp = new Http\ContentSecurityPolicy();
244
+        $csp->addAllowedFormActionDomain('nc://*');
245
+
246
+        $response = new StandaloneTemplateResponse(
247
+            $this->appName,
248
+            'loginflow/grant',
249
+            [
250
+                'client' => $clientName,
251
+                'clientIdentifier' => $clientIdentifier,
252
+                'instanceName' => $this->defaults->getName(),
253
+                'urlGenerator' => $this->urlGenerator,
254
+                'stateToken' => $stateToken,
255
+                'serverHost' => $this->getServerPath(),
256
+                'oauthState' => $this->session->get('oauth.state'),
257
+            ],
258
+            'guest'
259
+        );
260
+
261
+        $response->setContentSecurityPolicy($csp);
262
+        return $response;
263
+    }
264
+
265
+    /**
266
+     * @NoAdminRequired
267
+     * @UseSession
268
+     *
269
+     * @param string $stateToken
270
+     * @param string $clientIdentifier
271
+     * @return Http\RedirectResponse|Response
272
+     */
273
+    public function generateAppPassword($stateToken,
274
+                                        $clientIdentifier = '') {
275
+        if(!$this->isValidToken($stateToken)) {
276
+            $this->session->remove(self::stateName);
277
+            return $this->stateTokenForbiddenResponse();
278
+        }
279
+
280
+        $this->session->remove(self::stateName);
281
+
282
+        try {
283
+            $sessionId = $this->session->getId();
284
+        } catch (SessionNotAvailableException $ex) {
285
+            $response = new Response();
286
+            $response->setStatus(Http::STATUS_FORBIDDEN);
287
+            return $response;
288
+        }
289
+
290
+        try {
291
+            $sessionToken = $this->tokenProvider->getToken($sessionId);
292
+            $loginName = $sessionToken->getLoginName();
293
+            try {
294
+                $password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
295
+            } catch (PasswordlessTokenException $ex) {
296
+                $password = null;
297
+            }
298
+        } catch (InvalidTokenException $ex) {
299
+            $response = new Response();
300
+            $response->setStatus(Http::STATUS_FORBIDDEN);
301
+            return $response;
302
+        }
303
+
304
+        $clientName = $this->getClientName();
305
+        $client = false;
306
+        if($clientIdentifier !== '') {
307
+            $client = $this->clientMapper->getByIdentifier($clientIdentifier);
308
+            $clientName = $client->getName();
309
+        }
310
+
311
+        $token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
312
+        $uid = $this->userSession->getUser()->getUID();
313
+        $generatedToken = $this->tokenProvider->generateToken(
314
+            $token,
315
+            $uid,
316
+            $loginName,
317
+            $password,
318
+            $clientName,
319
+            IToken::PERMANENT_TOKEN,
320
+            IToken::DO_NOT_REMEMBER
321
+        );
322
+
323
+        if($client) {
324
+            $code = $this->random->generate(128, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
325
+            $accessToken = new AccessToken();
326
+            $accessToken->setClientId($client->getId());
327
+            $accessToken->setEncryptedToken($this->crypto->encrypt($token, $code));
328
+            $accessToken->setHashedCode(hash('sha512', $code));
329
+            $accessToken->setTokenId($generatedToken->getId());
330
+            $this->accessTokenMapper->insert($accessToken);
331
+
332
+            $redirectUri = sprintf(
333
+                '%s?state=%s&code=%s',
334
+                $client->getRedirectUri(),
335
+                urlencode($this->session->get('oauth.state')),
336
+                urlencode($code)
337
+            );
338
+            $this->session->remove('oauth.state');
339
+        } else {
340
+            $redirectUri = 'nc://login/server:' . $this->getServerPath() . '&user:' . urlencode($loginName) . '&password:' . urlencode($token);
341
+
342
+            // Clear the token from the login here
343
+            $this->tokenProvider->invalidateToken($sessionId);
344
+        }
345
+
346
+        $event = new GenericEvent($generatedToken);
347
+        $this->eventDispatcher->dispatch('app_password_created', $event);
348
+
349
+        return new Http\RedirectResponse($redirectUri);
350
+    }
351
+
352
+    /**
353
+     * @PublicPage
354
+     */
355
+    public function apptokenRedirect(string $stateToken, string $user, string $password) {
356
+        if (!$this->isValidToken($stateToken)) {
357
+            return $this->stateTokenForbiddenResponse();
358
+        }
359
+
360
+        $redirectUri = 'nc://login/server:' . $this->getServerPath() . '&user:' . urlencode($user) . '&password:' . urlencode($password);
361
+        return new Http\RedirectResponse($redirectUri);
362
+    }
363
+
364
+    private function getServerPath(): string {
365
+        $serverPostfix = '';
366
+
367
+        if (strpos($this->request->getRequestUri(), '/index.php') !== false) {
368
+            $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/index.php'));
369
+        } else if (strpos($this->request->getRequestUri(), '/login/flow') !== false) {
370
+            $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/flow'));
371
+        }
372
+
373
+        $protocol = $this->request->getServerProtocol();
374
+
375
+        if ($protocol !== "https") {
376
+            $xForwardedProto = $this->request->getHeader('X-Forwarded-Proto');
377
+            $xForwardedSSL = $this->request->getHeader('X-Forwarded-Ssl');
378
+            if ($xForwardedProto === 'https' || $xForwardedSSL === 'on') {
379
+                $protocol = 'https';
380
+            }
381
+        }
382
+
383
+        return $protocol . "://" . $this->request->getServerHost() . $serverPostfix;
384
+    }
385 385
 }
Please login to merge, or discard this patch.