Skip to content

Commit efa9ce0

Browse files
committed
Added support for openproject as exx app through proxy
Signed-off-by: Sagar <[email protected]>
1 parent 12fa75c commit efa9ce0

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

lib/AppInfo/Application.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
class Application extends App implements IBootstrap {
5454
public const APP_ID = 'integration_openproject';
5555
public const OPEN_PROJECT_ENTITIES_NAME = 'OpenProject';
56+
public const APP_ID_PROXY_OPENPROJECT = 'openproject-nextcloud-app';
5657
/**
5758
* @var mixed
5859
*/

lib/Controller/ConfigController.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,18 @@ public function oauthRedirect(string $code = '', string $state = ''): RedirectRe
485485

486486
if ($clientID && $validClientSecret && $validCodeVerifier && $configState !== '' && $configState === $state) {
487487
$openprojectUrl = $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url');
488+
$options = [];
489+
if($this->openprojectAPIService->isOpenProjectRunningAsExApp($openprojectUrl)) {
490+
$options = $this->openprojectAPIService->setHeadersForProxy($this->userId, $options);
491+
}
488492
$result = $this->openprojectAPIService->requestOAuthAccessToken($openprojectUrl, [
489493
'client_id' => $clientID,
490494
'client_secret' => $clientSecret,
491495
'code' => $code,
492496
'redirect_uri' => openprojectAPIService::getOauthRedirectUrl($this->urlGenerator),
493497
'grant_type' => 'authorization_code',
494498
'code_verifier' => $codeVerifier
495-
], 'POST');
499+
], 'POST', $options);
496500
if (isset($result['access_token']) && isset($result['refresh_token'])) {
497501
$accessToken = $result['access_token'];
498502
$this->config->setUserValue($this->userId, Application::APP_ID, 'token', $accessToken);

lib/Controller/OpenProjectAPIController.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use OCP\IConfig;
3333
use OCP\IRequest;
3434
use OCP\IURLGenerator;
35+
use phpDocumentor\Reflection\Types\This;
3536
use Psr\Log\LoggerInterface;
3637

3738
class OpenProjectAPIController extends Controller {
@@ -549,10 +550,15 @@ public function isValidOpenProjectInstance(string $url): DataResponse {
549550
);
550551
return new DataResponse(['result' => 'invalid']);
551552
}
553+
$options = [];
554+
if($this->openprojectAPIService->isOpenProjectRunningAsExApp($url)) {
555+
$options = $this->openprojectAPIService->setHeadersForProxy($this->userId, $options);
556+
}
557+
$options['allow_redirects'] = false;
552558
try {
553559
$response = $this->openprojectAPIService->rawRequest(
554560
'', $url, '', [], 'GET',
555-
['allow_redirects' => false]
561+
$options
556562
);
557563
$statusCode = $response->getStatusCode();
558564
if ($statusCode >= 300 && $statusCode <= 399) {

lib/Service/OpenProjectAPIService.php

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@
5555
use OCP\PreConditionNotMetException;
5656
use OCP\Security\ISecureRandom;
5757
use OCP\Server;
58+
use phpDocumentor\Reflection\Types\Self_;
5859
use Psr\Log\LoggerInterface;
60+
use OCA\AppAPI\Service\ExAppService;
5961

6062
define('CACHE_TTL', 3600);
6163

@@ -130,6 +132,7 @@ class OpenProjectAPIService {
130132
private ISecureRandom $random;
131133
private IEventDispatcher $eventDispatcher;
132134
private AuditLogger $auditLogger;
135+
private ExAppService $exAppService;
133136

134137
public function __construct(
135138
string $appName,
@@ -150,6 +153,7 @@ public function __construct(
150153
ISubAdmin $subAdminManager,
151154
IDBConnection $db,
152155
ILogFactory $logFactory,
156+
ExAppService $exAppService,
153157
) {
154158
$this->appName = $appName;
155159
$this->avatarManager = $avatarManager;
@@ -169,6 +173,7 @@ public function __construct(
169173
$this->eventDispatcher = $eventDispatcher;
170174
$this->db = $db;
171175
$this->logFactory = $logFactory;
176+
$this->exAppService = $exAppService;
172177
}
173178

174179
/**
@@ -316,9 +321,13 @@ public function getOpenProjectAvatar(
316321
$this->config->getAppValue(Application::APP_ID, 'openproject_client_id');
317322
$this->config->getAppValue(Application::APP_ID, 'openproject_client_secret');
318323
$openprojectUrl = $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url');
324+
$options = [];
325+
if($this->isOpenProjectRunningAsExApp($openprojectUrl)) {
326+
$options = $this->setHeadersForProxy($nextcloudUserId, $options);
327+
}
319328
try {
320329
$response = $this->rawRequest(
321-
$accessToken, $openprojectUrl, 'users/'.$openprojectUserId.'/avatar'
330+
$accessToken, $openprojectUrl, 'users/'.$openprojectUserId.'/avatar', [], 'GET', $options
322331
);
323332
$imageMimeType = $response->getHeader('Content-Type');
324333
$imageData = $response->getBody();
@@ -362,6 +371,21 @@ public function getOpenProjectAvatar(
362371
}
363372
}
364373

374+
public function isOpenProjectRunningAsExApp(string $openprojectUrl) : bool {
375+
return str_ends_with($openprojectUrl, '/proxy/openproject-nextcloud-app');
376+
}
377+
378+
public function setHeadersForProxy(string $nextcloudUser, array $options): array {
379+
$options = [];
380+
$exAppconfigInformation = $this->exAppService->getExApp(Application::APP_ID_PROXY_OPENPROJECT);
381+
$authorizationAppAPI = base64_encode($nextcloudUser . ":" . $exAppconfigInformation->getSecret());
382+
$options['headers']['host'] = $exAppconfigInformation->getHost() . ":" . $exAppconfigInformation->getPort();
383+
$options['headers']['ex-app-id'] = $exAppconfigInformation->getAppid();
384+
$options['headers']['authorization-app-api'] = $authorizationAppAPI;
385+
$options['headers']['ex-app-version'] = $exAppconfigInformation->getVersion();
386+
return $options;
387+
}
388+
365389
/**
366390
* @param string $accessToken
367391
* @param string $openprojectUrl
@@ -443,8 +467,12 @@ public function request(string $userId,
443467
if (!$openprojectUrl || !OpenProjectAPIService::validateURL($openprojectUrl)) {
444468
return ['error' => 'OpenProject URL is invalid', 'statusCode' => 500];
445469
}
470+
$options = [];
471+
if($this->isOpenProjectRunningAsExApp($openprojectUrl)) {
472+
$options = $this->setHeadersForProxy($userId, $options);
473+
}
446474
try {
447-
$response = $this->rawRequest($accessToken, $openprojectUrl, $endPoint, $params, $method);
475+
$response = $this->rawRequest($accessToken, $openprojectUrl, $endPoint, $params, $method, $options);
448476
if (($method === 'DELETE' || $method === 'POST') &&
449477
$response->getStatusCode() === Http::STATUS_NO_CONTENT
450478
) {
@@ -464,7 +492,7 @@ public function request(string $userId,
464492
'client_secret' => $clientSecret,
465493
'grant_type' => 'refresh_token',
466494
'refresh_token' => $refreshToken,
467-
], 'POST');
495+
], 'POST', $options);
468496
if (isset($result['refresh_token'])) {
469497
$refreshToken = $result['refresh_token'];
470498
$this->config->setUserValue(
@@ -517,17 +545,13 @@ public function request(string $userId,
517545
* @param string $url
518546
* @param array<mixed> $params passed to `http_build_query` for GET requests, else send as body
519547
* @param string $method
548+
* @param array<mixed> $options
520549
* @return array<mixed>
521550
*/
522-
public function requestOAuthAccessToken(string $url, array $params = [], string $method = 'GET'): array {
551+
public function requestOAuthAccessToken(string $url, array $params = [], string $method = 'GET', array $options = []): array {
523552
try {
524553
$url = $url . '/oauth/token';
525-
$options = [
526-
'headers' => [
527-
'User-Agent' => 'Nextcloud OpenProject integration',
528-
]
529-
];
530-
554+
$options ['headers']['User-Agent'] = 'Nextcloud OpenProject integration';
531555
if (count($params) > 0) {
532556
if ($method === 'GET') {
533557
$paramsContent = http_build_query($params);

0 commit comments

Comments
 (0)