Skip to content

Commit

Permalink
Apply changes for PR suuplied by Maxcence
Browse files Browse the repository at this point in the history
Signed-off-by: Micke Nordin <kano@sunet.se>
Co-authored-by: Maxcence Lange maxence@artificial-owl.com
  • Loading branch information
mickenordin committed May 14, 2024
1 parent d0d95fc commit 56765b6
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 70 deletions.
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<name>Global Site Selector</name>
<summary>Nextcloud Portal to redirect users to the right instance</summary>
<description>The Global Site Selector allows you to run multiple small Nextcloud instances and redirect users to the right server</description>
<version>2.3.1</version>
<version>2.5.0-beta1</version>
<licence>agpl</licence>
<author>Bjoern Schiessle</author>
<author>Maxence Lange</author>
Expand Down
83 changes: 39 additions & 44 deletions lib/Controller/SlaveController.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php

/**
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
*
Expand Down Expand Up @@ -78,32 +77,6 @@ public function __construct(
parent::__construct($appName, $request);
}

private function modifyRedirectUriForClient() {

$requestUri = $this->request->getRequestUri();
// check for both possible direct webdav end-points
$isDirectWebDavAccess = strpos($requestUri, 'remote.php/webdav') !== false || strpos($requestUri, 'remote.php/dav') !== false;
// direct webdav access with old client or general purpose webdav clients
if ($isDirectWebDavAccess) {
$this->logger->debug('redirectUser: client direct webdav request');
$redirectUrl = $target . '/remote.php/webdav/';
} else {
$this->logger->debug('redirectUser: client request generating apptoken');
$data = $this->createAppToken($jwt)->getData();
if (!isset($data['token'])) {
$info = 'getAppToken - data doesn\'t contain token: ' . json_encode($data);
throw new \Exception($info);
}
$appToken = $data['token'];

$redirectUrl =
'nc://login/server:' . $requestUri . '&user:' . urlencode($uid) . '&password:' . urlencode(
$appToken
);
}
return $redirectUrl;
}

/**
* @PublicPage
* @NoCSRFRequired
Expand Down Expand Up @@ -134,7 +107,7 @@ public function autoLogin(string $jwt): RedirectResponse {
list($uid, $password, $options) = $this->decodeJwt($jwt);
$this->logger->debug('uid: ' . $uid . ', options: ' . json_encode($options));

$target = $options['target'];
$target = (string) $options['target'];
if (($options['backend'] ?? '') === 'saml') {
$this->logger->debug('saml enabled');
$this->autoprovisionIfNeeded($uid, $options);
Expand Down Expand Up @@ -170,7 +143,6 @@ public function autoLogin(string $jwt): RedirectResponse {
return new RedirectResponse($masterUrl);
} catch (\Exception $e) {
$this->logger->warning('issue during login process', ['exception' => $e]);

return new RedirectResponse($masterUrl);
}

Expand All @@ -182,30 +154,25 @@ public function autoLogin(string $jwt): RedirectResponse {

$user = $this->userManager->get($uid);
if ($user instanceof IUser) {
$this->logger->debug('emiting AfterLoginOnSlaveEvent event');
$this->eventDispatcher->dispatchTyped(
new AfterLoginOnSlaveEvent($user)
);
$this->logger->debug('emitting AfterLoginOnSlaveEvent event');
$this->eventDispatcher->dispatchTyped(new AfterLoginOnSlaveEvent($user));
}
$redirectUrl = $this->urlGenerator->getAbsoluteURL($target);

/* see if we need to handle client login */
$clientFeatureEnabled = filter_var($this->config->getAppValue('globalsiteselector', 'client_feature_enabled', 'false'), FILTER_VALIDATE_BOOLEAN);
if ($clientFeatureEnabled) {
$this->logger->debug('Client redirect feature enabled');

$isClient = $this->request->isUserAgent(
$clientFeatureEnabled = ($this->config->getAppValue(Application::APP_ID, 'client_feature_enabled', 'false') === 'true');
if ($clientFeatureEnabled
&& $this->request->isUserAgent(
[
IRequest::USER_AGENT_CLIENT_IOS,
IRequest::USER_AGENT_CLIENT_ANDROID,
IRequest::USER_AGENT_CLIENT_DESKTOP,
'/^.*\(Android\)$/'
]
);
}

if ($isClient) {
$redirectUrl = $this->modifyRedirectUriForClient();
)) {
$this->logger->debug('managing request as emerging from client');
$redirectUrl = $this->modifyRedirectUriForClient($uid, $target, $jwt);
} else {
$redirectUrl = $this->urlGenerator->getAbsoluteURL($target);
}

$this->logger->debug('redirecting to ' . $redirectUrl);
Expand Down Expand Up @@ -295,4 +262,32 @@ protected function autoprovisionIfNeeded($uid, $options) {
$this->userBackend->createUserIfNotExists($uid);
$this->userBackend->updateAttributes($uid, $options);
}


private function modifyRedirectUriForClient(
string $uid,
string $target,
string $jwt
): string {
$requestUri = $this->request->getRequestUri();
$isDirectWebDavAccess = str_contains($requestUri, 'remote.php/webdav') || str_contains($requestUri, 'remote.php/dav');

// direct webdav access with old client or general purpose webdav clients
if ($isDirectWebDavAccess) {
$this->logger->debug('redirectUser: client direct webdav request to ' . $target);
$redirectUrl = $target . '/remote.php/webdav/';
} else {
$this->logger->debug('redirectUser: client request generating apptoken');
$data = $this->createAppToken($jwt)->getData();
if (!isset($data['token'])) {
throw new \Exception('getAppToken - data missing token: ' . json_encode($data));
}
$appToken = $data['token'];

$redirectUrl = 'nc://login/server:' . $requestUri . '&user:' . urlencode($uid) . '&password:' . urlencode($appToken);
}

$this->logger->debug('generated client redirect url: ' . $redirectUrl);
return $redirectUrl;
}
}
15 changes: 7 additions & 8 deletions lib/Events/AfterLoginOnSlaveEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@
* This event is triggered after GSS login is finalized on the slave.
**/
class AfterLoginOnSlaveEvent extends Event {
public function __construct(private IUser $user)
{
parent::__construct();
}
public function getUser(): IUser
{
return $this->user;
}
public function __construct(private IUser $user) {
parent::__construct();
}

public function getUser(): IUser {
return $this->user;
}
}
32 changes: 15 additions & 17 deletions lib/Master.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,33 +234,31 @@ protected function redirectUser($uid, $password, $location, array $options = [])
$this->logger->debug('redirectUser: direct login so forward to target node');
$jwt = $this->createJwt($uid, $password, $options);
$redirectUrl = $location . '/index.php/apps/globalsiteselector/autologin?jwt=' . $jwt;

$clientFeatureEnabled = filter_var($this->config->getAppValue('globalsiteselector', 'client_feature_enabled', 'false'), FILTER_VALIDATE_BOOLEAN);
if (!$clientFeatureEnabled) {
$isClient = $this->request->isUserAgent(
[
IRequest::USER_AGENT_CLIENT_IOS,
IRequest::USER_AGENT_CLIENT_ANDROID,
IRequest::USER_AGENT_CLIENT_DESKTOP,
'/^.*\(Android\)$/'
]
);

$clientFeatureEnabled = ($this->config->getAppValue(Application::APP_ID, 'client_feature_enabled', 'false') === 'true');
$isClient = $this->request->isUserAgent(
[
IRequest::USER_AGENT_CLIENT_IOS,
IRequest::USER_AGENT_CLIENT_ANDROID,
IRequest::USER_AGENT_CLIENT_DESKTOP,
'/^.*\(Android\)$/'
]
);

$this->logger->debug('redirectUser client checks: ' . json_encode(['enabled' => $clientFeatureEnabled, 'isClient' => $isClient]));
if (!$clientFeatureEnabled && $isClient) {
$requestUri = $this->request->getRequestUri();
// check for both possible direct webdav end-points
$isDirectWebDavAccess = strpos($requestUri, 'remote.php/webdav') !== false;
$isDirectWebDavAccess = $isDirectWebDavAccess || strpos($requestUri, 'remote.php/dav') !== false;
// direct webdav access with old client or general purpose webdav clients
if ($isClient && $isDirectWebDavAccess) {
if ($isDirectWebDavAccess) {
$this->logger->debug('redirectUser: client direct webdav request');
$redirectUrl = $location . '/remote.php/webdav/';
} elseif ($isClient && !$isDirectWebDavAccess) {
} else {
$this->logger->debug('redirectUser: client request generating apptoken');
$appToken = $this->getAppToken($location, $uid, $password, $options);
$redirectUrl =
'nc://login/server:' . $location . '&user:' . urlencode($uid) . '&password:' . urlencode(
$appToken
);
$redirectUrl = 'nc://login/server:' . $location . '&user:' . urlencode($uid) . '&password:' . urlencode($appToken);
}
}

Expand Down

0 comments on commit 56765b6

Please sign in to comment.