diff --git a/appinfo/info.xml b/appinfo/info.xml index cfc6e9eb..d84a930a 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -26,6 +26,9 @@ + + + OCA\ScienceMesh\Settings OCA\ScienceMesh\Settings\SciencemeshSettingsAdmin diff --git a/appinfo/routes.php b/appinfo/routes.php index 6707021d..a11a7f45 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -94,8 +94,16 @@ ["name" => "settings#get_settings", "url" => "/ajax/settings", "verb" => "GET"], ["name" => "settings#get_sciencemesh_settings", "url" => "/sciencemesh_settings", "verb" => "GET"], ["name" => "settings#save_sciencemesh_settings", "url" => "/ajax/sciencemesh_settings/save", "verb" => "GET"], - ["name" => "settings#check_connection_settings", "url" => "/ajax/check_connection_settings", "verb" => "GET"] - + ["name" => "settings#check_connection_settings", "url" => "/ajax/check_connection_settings", "verb" => "GET"], + + // API Routes + ["name" => "api#add_token", "url" => "/api/v1/add_token/{initiator}", "verb" => "POST"], + ["name" => "api#get_token", "url" => "/api/v1/get_token", "verb" => "GET"], + ["name" => "api#tokens_list", "url" => "/api/v1/tokens_list/{initiator}", "verb" => "GET"], + ["name" => "api#add_remote_user", "url" => "/api/v1/add_remote_user/{initiator}", "verb" => "POST"], + ["name" => "api#get_remote_user", "url" => "/api/v1/get_remote_user/{initiator}", "verb" => "GET"], + ["name" => "api#find_remote_user", "url" => "/api/v1/find_remote_user/{initiator}", "verb" => "GET"] + ] ]; diff --git a/js/contacts.js b/js/contacts.js index 1b4e3bb4..01dc328d 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -1,5 +1,6 @@ document.addEventListener("DOMContentLoaded", function(event) { //Everything will be for working with contacts + loadData(""); var baseUrl = OC.generateUrl('/apps/sciencemesh'); $('#test_error').hide(); $.ajax({ diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php new file mode 100644 index 00000000..6a382270 --- /dev/null +++ b/lib/Controller/ApiController.php @@ -0,0 +1,333 @@ +serverConfig = new \OCA\ScienceMesh\ServerConfig($sciencemeshConfig); + + $this->urlGenerator = $urlGenerator; + $this->logger = $logger; + $this->config = $config; + $this->sciencemeshConfig = $sciencemeshConfig; + $this->db = $db; + $this->request = $request; + } + + /** + * Check if the request is authenticated by comparing the request's API key with the stored inviteManagerApikey. + * + * + * @PublicPage + * @param IRequest $request + * @return bool + */ + public function authentication($request) + { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from('appconfig') + ->where( + $qb->expr()->eq('appid', $qb->createNamedParameter('sciencemesh', IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('configkey', $qb->createNamedParameter('inviteManagerApikey', IQueryBuilder::PARAM_STR)) + ); + + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + if ($row[0]['configvalue'] == $this->request->getHeader('apikey')) { + return true; + } else { + return false; + } + } + + /** + * + * @PublicPage + * @NoCSRFRequired + */ + public function addToken($initiator, $request){ + if(!$this->authentication($this->request)) return new DataResponse((['message' => 'Authentication failed!','status' => 412, 'data' => null]), Http::STATUS_INTERNAL_SERVER_ERROR); + + if(!$this->request->getParam('token') and !$initiator and !$this->request->getParam('expiration') and !$this->request->getParam('description')){ + return new DataResponse(['message' => 'values are not provided properly!','status' => 412, 'data' => null], Http::STATUS_OK); + } + + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from('ocm_tokens') + ->where( + $qb->expr()->eq('initiator', $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('token', $qb->createNamedParameter($this->request->getParam('token'), IQueryBuilder::PARAM_STR)) + ); + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + $expiration = $this->request->getParam('expiration'); + + if(empty($row)){ + $qb->insert('ocm_tokens') + ->values( + array( + 'token' => $qb->createNamedParameter($this->request->getParam('token'), IQueryBuilder::PARAM_STR), + 'initiator' => $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR), + 'expiration' => $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_STR), + 'description' => $qb->createNamedParameter($this->request->getParam('description'), IQueryBuilder::PARAM_STR) + ) + ); + $cursor = $qb->execute(); + }else{ + $cursor = 0; + } + + if($cursor) + return new DataResponse((['message' => 'Token added!','status' => 200, 'data' => $cursor]), Http::STATUS_OK); + else if($cursor == 0) + return new DataResponse((['message' => 'Token already exists!','status' => 204, 'data' => 0]), Http::STATUS_BAD_REQUEST); + else + return new DataResponse((['message' => 'Token added failed!','status' => 400, 'data' => 0]), Http::STATUS_BAD_REQUEST); + } + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function getToken($initiator){ + + if(!$this->authentication($this->request)) return new DataResponse((['message' => 'Authentication failed!','status' => 412, 'data' => null]), Http::STATUS_INTERNAL_SERVER_ERROR); + + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from('ocm_tokens') + ->where( + $qb->expr()->eq('token', $qb->createNamedParameter($this->request->getParam('token'), IQueryBuilder::PARAM_STR)) + ); + + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + if(empty($row)){ + return new DataResponse((['message' => 'No Token found!','status' => 201, 'data' => '']), Http::STATUS_BAD_REQUEST); + }else{ + return new DataResponse(($row[0]), Http::STATUS_OK); + } + + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function tokensList($initiator){ + + if(!$this->authentication($this->request)) return new DataResponse((['message' => 'Authentication failed!','status' => 412, 'data' => null]), Http::STATUS_INTERNAL_SERVER_ERROR); + + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->where( + $qb->expr()->eq('initiator', $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR)) + ) + ->from('ocm_tokens'); + + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + return new DataResponse(($row), Http::STATUS_OK); + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function addRemoteUser($initiator){ + + if(!$this->authentication($this->request)) return new DataResponse((['message' => 'Authentication failed!','status' => 412, 'data' => null]), Http::STATUS_INTERNAL_SERVER_ERROR); + + if(!$this->request->getParam('opaqueUserId') and !$this->request->getParam('idp') and !$this->request->getParam('email') and !$this->request->getParam('displayName')){ + return new DataResponse((['message' => 'values are not provided properly!','status' => 412, 'data' => null]), Http::STATUS_OK); + } + + $qb = $this->db->getQueryBuilder(); + + + $qb->select('*') + ->from('ocm_remote_users') + ->where( + $qb->expr()->eq('opaque_user_id', $qb->createNamedParameter($this->request->getParam('opaqueUserId'), IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('idp', $qb->createNamedParameter($this->request->getParam('idp'), IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('email', $qb->createNamedParameter($this->request->getParam('email'), IQueryBuilder::PARAM_STR)) + ); + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + if(empty($row)){ + $qb->insert('ocm_remote_users') + ->values( + array( + 'initiator' => $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR), + 'opaque_user_id' => $qb->createNamedParameter($this->request->getParam('opaqueUserId'), IQueryBuilder::PARAM_STR), + 'idp' => $qb->createNamedParameter($this->request->getParam('idp'), IQueryBuilder::PARAM_STR), + 'email' => $qb->createNamedParameter($this->request->getParam('email'), IQueryBuilder::PARAM_STR), + 'display_name' => $qb->createNamedParameter($this->request->getParam('displayName'), IQueryBuilder::PARAM_STR) + ) + ); + $cursor = $qb->execute(); + }else{ + $cursor = 0; + } + + if($cursor || !empty($row)) + if(!empty($row)) + return new DataResponse((['message' => 'User exists!','status' => 400, 'data' => $row]), Http::STATUS_BAD_REQUEST); + if($cursor) + return new DataResponse((['message' => 'User added!','status' => 200, 'data' => $cursor]), Http::STATUS_OK); + else + return new DataResponse((['message' => 'User does not added!','status' => 500, 'data' => 0]), Http::STATUS_INTERNAL_SERVER_ERROR); + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function getRemoteUser($initiator){ + + if(!$this->authentication($this->request)) return new DataResponse((['message' => 'Authentication failed!','status' => 412, 'data' => null]), Http::STATUS_INTERNAL_SERVER_ERROR); + + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from('ocm_remote_users') + ->where( + $qb->expr()->eq('initiator', $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('idp', $qb->createNamedParameter($this->request->getParam('idp'), IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('opaque_user_id', $qb->createNamedParameter($this->request->getParam('opaqueUserId'), IQueryBuilder::PARAM_STR)) + ); + + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + if(empty($row)){ + return new DataResponse((['message' => 'User not found!','status' => 201, 'data' => '']), Http::STATUS_BAD_REQUEST); + }else{ + return new DataResponse(($this->CastToRevaUser($row[0])), Http::STATUS_OK); + } + + } + + + /** + * @PublicPage + * @NoCSRFRequired + */ + public function findRemoteUser($initiator){ + + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from('ocm_remote_users') + ->where( + $qb->expr()->eq('initiator', $qb->createNamedParameter($initiator, IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->orX( + $qb->expr()->like('opaque_user_id', $qb->createNamedParameter($this->request->getParam('search'), IQueryBuilder::PARAM_STR)), + $qb->expr()->like('idp', $qb->createNamedParameter($this->request->getParam('search'), IQueryBuilder::PARAM_STR)), + $qb->expr()->like('email', $qb->createNamedParameter($this->request->getParam('search'), IQueryBuilder::PARAM_STR)), + $qb->expr()->like('display_name', $qb->createNamedParameter($this->request->getParam('search'), IQueryBuilder::PARAM_STR)) + ) + ); + + $cursor = $qb->execute(); + $row = $cursor->fetchAll(); + + if(empty($row)){ + return new DataResponse(([ ]), Http::STATUS_OK); + }else{ + $result = []; + foreach($row as $item){ + $result[] = $this->CastToRevaUser($item); + } + return new DataResponse(($result), Http::STATUS_OK); + } + + } + + private function CastToRevaUser($user){ + return array( + 'opaqueUserId' => $user['opaque_user_id'], + 'idp' => $user['idp'], + 'email' => $user['email'], + 'displayName' => $user['display_name'] + ); + } +} \ No newline at end of file diff --git a/lib/Controller/AppController.php b/lib/Controller/AppController.php index 10e677d4..9c329ecb 100644 --- a/lib/Controller/AppController.php +++ b/lib/Controller/AppController.php @@ -125,6 +125,9 @@ public function invitationsGenerate() { $recipient = $this->request->getParam('email'); $invitationsData = $this->httpClient->generateTokenFromReva($this->userId, $recipient); $inviteLinkStr = $invitationsData["invite_link"]; + $iopUrl = $invitationsData["user_id"]["idp"]; + $iopDomain = parse_url($iopUrl)["host"]; + // $meshDirectoryUrl = "https://sciencemesh.cesnet.cz/iop/meshdir/"; $meshDirectoryUrl = $this->config->getAppValue('sciencemesh', 'meshDirectoryUrl', 'https://sciencemesh.cesnet.cz/iop/meshdir/'); if (!$inviteLinkStr) { return new TextPlainResponse("Unexpected response from Reva", Http::STATUS_INTERNAL_SERVER_ERROR); diff --git a/lib/Migration/Version0001Date202305082200.php b/lib/Migration/Version0001Date202305082200.php new file mode 100644 index 00000000..da7e4ea3 --- /dev/null +++ b/lib/Migration/Version0001Date202305082200.php @@ -0,0 +1,68 @@ +hasTable('ocm_tokens')) { + $table = $schema->createTable("ocm_tokens"); + $table->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table->addColumn('token', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('expiration', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('description', 'string', ['length' => 255, 'notnull' => true]); + $table->setPrimaryKey(['id']); + } + + + if (!$schema->hasTable('ocm_remote_users')) { + $table1 = $schema->createTable("ocm_remote_users"); + $table1->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table1->addColumn('opaque_user_id', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('idp', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('email', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('display_name', 'string', ['length' => 255, 'notnull' => true]); + $table1->setPrimaryKey(['id']); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } +} diff --git a/lib/Migration/Version0001Date202305101500.php b/lib/Migration/Version0001Date202305101500.php new file mode 100644 index 00000000..9b2e6074 --- /dev/null +++ b/lib/Migration/Version0001Date202305101500.php @@ -0,0 +1,68 @@ +hasTable('ocm_tokens')) { + $table = $schema->createTable("ocm_tokens"); + $table->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table->addColumn('token', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('expiration', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('description', 'string', ['length' => 255, 'notnull' => true]); + $table->setPrimaryKey(['id']); + } + + + if (!$schema->hasTable('ocm_remote_users')) { + $table1 = $schema->createTable("ocm_remote_users"); + $table1->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table1->addColumn('opaque_user_id', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('idp', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('email', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('display_name', 'string', ['length' => 255, 'notnull' => true]); + $table1->setPrimaryKey(['id']); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } +} diff --git a/lib/Migration/Version0001Date202305101530.php b/lib/Migration/Version0001Date202305101530.php new file mode 100644 index 00000000..1adb01bc --- /dev/null +++ b/lib/Migration/Version0001Date202305101530.php @@ -0,0 +1,68 @@ +hasTable('ocm_tokens')) { + $table = $schema->createTable("ocm_tokens"); + $table->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table->addColumn('token', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('expiration', 'string', ['length' => 255, 'notnull' => true]); + $table->addColumn('description', 'string', ['length' => 255, 'notnull' => true]); + $table->setPrimaryKey(['id']); + } + + + if (!$schema->hasTable('ocm_remote_users')) { + $table1 = $schema->createTable("ocm_remote_users"); + $table1->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]); + $table1->addColumn('opaque_user_id', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('idp', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('email', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('initiator', 'string', ['length' => 255, 'notnull' => true]); + $table1->addColumn('display_name', 'string', ['length' => 255, 'notnull' => true]); + $table1->setPrimaryKey(['id']); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } +}