Skip to content

Commit

Permalink
Added support for openproject as exx app through proxy
Browse files Browse the repository at this point in the history
Signed-off-by: Sagar <[email protected]>
  • Loading branch information
SagarGi committed Sep 16, 2024
1 parent 6ffe669 commit 16a36ef
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 13 deletions.
1 change: 1 addition & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
class Application extends App implements IBootstrap {
public const APP_ID = 'integration_openproject';
public const OPEN_PROJECT_ENTITIES_NAME = 'OpenProject';
public const APP_ID_PROXY_OPENPROJECT = 'openproject-nextcloud-app';
/**
* @var mixed
*/
Expand Down
6 changes: 5 additions & 1 deletion lib/Controller/ConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -485,14 +485,18 @@ public function oauthRedirect(string $code = '', string $state = ''): RedirectRe

if ($clientID && $validClientSecret && $validCodeVerifier && $configState !== '' && $configState === $state) {
$openprojectUrl = $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url');
$options = [];
if($this->openprojectAPIService->isOpenProjectRunningAsExApp($openprojectUrl)) {
$options = $this->openprojectAPIService->setHeadersForProxy($this->userId, $options);
}
$result = $this->openprojectAPIService->requestOAuthAccessToken($openprojectUrl, [
'client_id' => $clientID,
'client_secret' => $clientSecret,
'code' => $code,
'redirect_uri' => openprojectAPIService::getOauthRedirectUrl($this->urlGenerator),
'grant_type' => 'authorization_code',
'code_verifier' => $codeVerifier
], 'POST');
], 'POST', $options);
if (isset($result['access_token']) && isset($result['refresh_token'])) {
$accessToken = $result['access_token'];
$this->config->setUserValue($this->userId, Application::APP_ID, 'token', $accessToken);
Expand Down
1 change: 0 additions & 1 deletion lib/Controller/DirectUploadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ public function prepareDirectUpload(int $folder_id): DataResponse {
/**
* direct upload
*
* @CORS
* @NoCSRFRequired
* @NoAdminRequired
* @PublicPage
Expand Down
8 changes: 7 additions & 1 deletion lib/Controller/OpenProjectAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use OCP\IConfig;
use OCP\IRequest;
use OCP\IURLGenerator;
use phpDocumentor\Reflection\Types\This;
use Psr\Log\LoggerInterface;

class OpenProjectAPIController extends Controller {
Expand Down Expand Up @@ -549,10 +550,15 @@ public function isValidOpenProjectInstance(string $url): DataResponse {
);
return new DataResponse(['result' => 'invalid']);
}
$options = [];
if($this->openprojectAPIService->isOpenProjectRunningAsExApp($url)) {
$options = $this->openprojectAPIService->setHeadersForProxy($this->userId, $options);
}
$options['allow_redirects'] = false;
try {
$response = $this->openprojectAPIService->rawRequest(
'', $url, '', [], 'GET',
['allow_redirects' => false]
$options
);
$statusCode = $response->getStatusCode();
if ($statusCode >= 300 && $statusCode <= 399) {
Expand Down
44 changes: 34 additions & 10 deletions lib/Service/OpenProjectAPIService.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
use OCP\PreConditionNotMetException;
use OCP\Security\ISecureRandom;
use OCP\Server;
use phpDocumentor\Reflection\Types\Self_;
use Psr\Log\LoggerInterface;
use OCA\AppAPI\Service\ExAppService;

define('CACHE_TTL', 3600);

Expand Down Expand Up @@ -130,6 +132,7 @@ class OpenProjectAPIService {
private ISecureRandom $random;
private IEventDispatcher $eventDispatcher;
private AuditLogger $auditLogger;
private ExAppService $exAppService;

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable28, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.2)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.3)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable29, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 135 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable27, 8)

UndefinedClass

lib/Service/OpenProjectAPIService.php:135:10: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

public function __construct(
string $appName,
Expand All @@ -150,6 +153,7 @@ public function __construct(
ISubAdmin $subAdminManager,
IDBConnection $db,
ILogFactory $logFactory,
ExAppService $exAppService,

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable28, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.2)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.3)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable29, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 156 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable27, 8)

UndefinedClass

lib/Service/OpenProjectAPIService.php:156:3: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)
) {
$this->appName = $appName;
$this->avatarManager = $avatarManager;
Expand All @@ -169,6 +173,7 @@ public function __construct(
$this->eventDispatcher = $eventDispatcher;
$this->db = $db;
$this->logFactory = $logFactory;
$this->exAppService = $exAppService;
}

/**
Expand Down Expand Up @@ -316,9 +321,13 @@ public function getOpenProjectAvatar(
$this->config->getAppValue(Application::APP_ID, 'openproject_client_id');
$this->config->getAppValue(Application::APP_ID, 'openproject_client_secret');
$openprojectUrl = $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url');
$options = [];
if($this->isOpenProjectRunningAsExApp($openprojectUrl)) {
$options = $this->setHeadersForProxy($nextcloudUserId, $options);
}
try {
$response = $this->rawRequest(
$accessToken, $openprojectUrl, 'users/'.$openprojectUserId.'/avatar'
$accessToken, $openprojectUrl, 'users/'.$openprojectUserId.'/avatar', [], 'GET', $options
);
$imageMimeType = $response->getHeader('Content-Type');
$imageData = $response->getBody();
Expand Down Expand Up @@ -362,6 +371,21 @@ public function getOpenProjectAvatar(
}
}

public function isOpenProjectRunningAsExApp(string $openprojectUrl) : bool {
return str_ends_with($openprojectUrl, '/proxy/openproject-nextcloud-app');
}

public function setHeadersForProxy(string $nextcloudUser, array $options): array {
$options = [];
$exAppconfigInformation = $this->exAppService->getExApp(Application::APP_ID_PROXY_OPENPROJECT);

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable28, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.2)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable30, 8.3)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable29, 8.1)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)

Check failure on line 380 in lib/Service/OpenProjectAPIService.php

View workflow job for this annotation

GitHub Actions / builds / unit tests and linting (stable27, 8)

UndefinedClass

lib/Service/OpenProjectAPIService.php:380:29: UndefinedClass: Class, interface or enum named OCA\AppAPI\Service\ExAppService does not exist (see https://psalm.dev/019)
$authorizationAppAPI = base64_encode($nextcloudUser . ":" . $exAppconfigInformation->getSecret());
$options['headers']['host'] = $exAppconfigInformation->getHost() . ":" . $exAppconfigInformation->getPort();
$options['headers']['ex-app-id'] = $exAppconfigInformation->getAppid();
$options['headers']['authorization-app-api'] = $authorizationAppAPI;
$options['headers']['ex-app-version'] = $exAppconfigInformation->getVersion();
return $options;
}

/**
* @param string $accessToken
* @param string $openprojectUrl
Expand Down Expand Up @@ -443,8 +467,12 @@ public function request(string $userId,
if (!$openprojectUrl || !OpenProjectAPIService::validateURL($openprojectUrl)) {
return ['error' => 'OpenProject URL is invalid', 'statusCode' => 500];
}
$options = [];
if($this->isOpenProjectRunningAsExApp($openprojectUrl)) {
$options = $this->setHeadersForProxy($userId, $options);
}
try {
$response = $this->rawRequest($accessToken, $openprojectUrl, $endPoint, $params, $method);
$response = $this->rawRequest($accessToken, $openprojectUrl, $endPoint, $params, $method, $options);
if (($method === 'DELETE' || $method === 'POST') &&
$response->getStatusCode() === Http::STATUS_NO_CONTENT
) {
Expand All @@ -464,7 +492,7 @@ public function request(string $userId,
'client_secret' => $clientSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
], 'POST');
], 'POST', $options);
if (isset($result['refresh_token'])) {
$refreshToken = $result['refresh_token'];
$this->config->setUserValue(
Expand Down Expand Up @@ -517,17 +545,13 @@ public function request(string $userId,
* @param string $url
* @param array<mixed> $params passed to `http_build_query` for GET requests, else send as body
* @param string $method
* @param array<mixed> $options
* @return array<mixed>
*/
public function requestOAuthAccessToken(string $url, array $params = [], string $method = 'GET'): array {
public function requestOAuthAccessToken(string $url, array $params = [], string $method = 'GET', array $options = []): array {
try {
$url = $url . '/oauth/token';
$options = [
'headers' => [
'User-Agent' => 'Nextcloud OpenProject integration',
]
];

$options ['headers']['User-Agent'] = 'Nextcloud OpenProject integration';
if (count($params) > 0) {
if ($method === 'GET') {
$paramsContent = http_build_query($params);
Expand Down

0 comments on commit 16a36ef

Please sign in to comment.