/** * {@inheritDoc} */ public function getCredentials(Request $request) { $inputData = new JsonArray($request->getContent()); if (!($inputData->has('username') && $inputData->has('password'))) { // post data? Return null and no other methods will be called return null; } // What you return here will be passed to getUser() as $credentials return (object) ['username' => $inputData->get('username'), 'password' => $inputData->get('password')]; }
/** * Test that values are found by path. * * @return void */ public function testPath() { $json = new JsonArray(['foo' => ['bar' => 'baz']]); $json->set('bar/bar\\/baz', 'foo'); $this->assertFalse($json->has('foo\\/bar')); $this->assertTrue($json->has('foo/bar')); $this->assertFalse($json->has('foo/bar/baz')); $this->assertEquals('baz', $json->get('foo/bar')); $this->assertNull($json->get('foo\\/bar')); $this->assertTrue($json->has('bar/bar\\/baz')); $this->assertEquals('foo', $json->get('bar/bar\\/baz')); $this->assertEquals(['bar/baz' => 'foo'], $json->get('bar')); }
/** * Task constructor. * * @param JsonArray $file The json file to write to. */ public function __construct(JsonArray $file) { $this->file = $file; if ($this->file->has('log')) { $this->logFile = $this->file->get('log'); } }
/** * Try to validate the version constraint. * * @param Request $request The request. * * @return JsonResponse * * @throws \RuntimeException For invalid user classes. * * @ApiDoc( * section="misc", * statusCodes = { * 200 = "When everything worked out ok", * 400 = "When the request payload was invalid." * }, * authentication = true, * authenticationRoles = { * "ROLE_NONE" * } * ) * @ApiDescription( * request={ * "constraint" = { * "description" = "The constraint to test.", * "dataType" = "string", * "required" = true * } * }, * response={ * "status" = { * "dataType" = "choice", * "description" = "OK or ERROR", * "format" = "['OK', 'ERROR']", * }, * "error" = { * "dataType" = "string", * "description" = "The error message (if any).", * } * } * ) */ public function checkVersionConstraintAction(Request $request) { try { $inputData = new JsonArray($request->getContent()); } catch (\Exception $exception) { return new JsonResponse(['status' => 'ERROR', 'error' => 'invalid payload'], JsonResponse::HTTP_BAD_REQUEST); } $versionParser = new VersionParser(); if (!$inputData->has('constraint')) { return new JsonResponse(['status' => 'ERROR', 'error' => 'invalid payload'], JsonResponse::HTTP_BAD_REQUEST); } try { $versionParser->parseConstraints($inputData->get('constraint')); } catch (\Exception $exception) { return new JsonResponse(['status' => 'ERROR', 'error' => $exception->getMessage()], JsonResponse::HTTP_OK); } return new JsonResponse(['status' => 'OK'], JsonResponse::HTTP_OK); }
/** * {@inheritDoc} */ public function has($path) { return $this->data->has($path); }
/** * Update the information of a package in the composer.json. * * Note that the payload name of the package must match the vendor and package passed as parameter. * * @param string $vendor The name of the vendor. * * @param string $package The name of the package. * * @param Request $request The request to process. * * @return JsonResponse * * @throws NotAcceptableHttpException When the passed payload is invalid. * @throws NotFoundHttpException When the package has not been found. * * @ApiDoc( * section="package", * statusCodes = { * 200 = "When everything worked out ok" * }, * authentication = true, * authenticationRoles = { * "ROLE_MANIPULATE_REQUIREMENTS" * } * ) * * @ApiDescription( * request={ * "name" = { * "dataType" = "string", * "description" = "The name of the package", * "required" = true * }, * "constraint" = { * "dataType" = "string", * "description" = "The constraint of the package (when package is installed)", * "required" = true * }, * "locked" = { * "dataType" = "string", * "description" = "Flag if the package has been locked for updates", * "required" = true * }, * }, * response={ * "name" = { * "dataType" = "string", * "description" = "The name of the package" * }, * "version" = { * "dataType" = "string", * "description" = "The version of the package" * }, * "constraint" = { * "dataType" = "string", * "description" = "The constraint of the package (when package is installed)" * }, * "type" = { * "dataType" = "string", * "description" = "The noted package type" * }, * "locked" = { * "dataType" = "string", * "description" = "Flag if the package has been locked for updates" * }, * "time" = { * "dataType" = "datetime", * "description" = "The release date" * }, * "upgrade_version" = { * "dataType" = "string", * "description" = "The version available for upgrade (optional, if any)" * }, * "description" = { * "dataType" = "string", * "description" = "The package description" * }, * "license" = { * "actualType" = "collection", * "subType" = "string", * "description" = "The licenses" * }, * "keywords" = { * "actualType" = "collection", * "subType" = "string", * "description" = "The keywords" * }, * "homepage" = { * "dataType" = "string", * "description" = "The support website (optional, if any)" * }, * "authors" = { * "actualType" = "collection", * "subType" = "object", * "description" = "The authors", * "children" = { * "name" = { * "dataType" = "string", * "description" = "Full name of the author (optional, if any)" * }, * "homepage" = { * "dataType" = "string", * "description" = "Email address of the author (optional, if any)" * }, * "email" = { * "dataType" = "string", * "description" = "Homepage URL for the author (optional, if any)" * }, * "role" = { * "dataType" = "string", * "description" = "Author's role in the project (optional, if any)" * } * } * }, * "support" = { * "actualType" = "collection", * "subType" = "object", * "description" = "The support options", * "children" = { * "email" = { * "dataType" = "string", * "description" = "Email address for support (optional, if any)" * }, * "issues" = { * "dataType" = "string", * "description" = "URL to the issue tracker (optional, if any)" * }, * "forum" = { * "dataType" = "string", * "description" = "URL to the forum (optional, if any)" * }, * "wiki" = { * "dataType" = "string", * "description" = "URL to the wiki (optional, if any)" * }, * "irc" = { * "dataType" = "string", * "description" = "IRC channel for support, as irc://server/channel (optional, if any)" * }, * "source" = { * "dataType" = "string", * "description" = "URL to browse or download the sources (optional, if any)" * }, * "docs" = { * "dataType" = "string", * "description" = "URL to the documentation (optional, if any)" * }, * } * }, * "abandoned" = { * "dataType" = "boolean", * "description" = "Flag if this package is abandoned" * }, * "replacement" = { * "dataType" = "string", * "description" = "Replacement for this package (optional, if any)" * } * } * ) */ public function putPackageAction($vendor, $package, Request $request) { $packageName = $vendor . '/' . $package; $info = new JsonArray($request->getContent()); $name = $info->get('name'); if (!($info->has('name') && $info->has('locked') && $info->has('constraint'))) { throw new NotAcceptableHttpException('Invalid package information.'); } if ($name !== $packageName) { throw new NotAcceptableHttpException('Package name mismatch ' . $packageName . ' vs. ' . $name . '.'); } $composer = $this->getComposer(); $json = $this->get('tenside.composer_json'); $package = $this->findPackage($name, $composer->getRepositoryManager()->getLocalRepository()); if (null === $package) { throw new NotFoundHttpException('Package ' . $packageName . ' not found.'); } $json->setLock($package, $info->get('locked')); return $this->forward('TensideCoreBundle:Package:getPackage'); }
/** * Determine the life time for the token. * * This examines the GET parameters if a field "ttl" has been set. * If not, it examines the JSON post data for a field named ttl. * * @param Request $request The request. * * @return int|null */ private function determineLifeTime(Request $request) { if ($lifetime = $request->query->getInt('ttl')) { return $this->revertToNullOnMinusOne($lifetime); } try { $inputData = new JsonArray($request->getContent()); if ($inputData->has('ttl')) { return $this->revertToNullOnMinusOne(intval($inputData->get('ttl'))); } } catch (\Exception $e) { // Swallow exception, we need to return a defined result. } return 3600; }
/** * Search for packages. * * @param Request $request The search request. * * @return JsonResponse * * @ApiDoc( * section="search", * statusCodes = { * 200 = "When everything worked out ok" * }, * authentication = true, * authenticationRoles = { * "ROLE_MANIPULATE_REQUIREMENTS" * } * ) * @ApiDescription( * request={ * "keywords" = { * "dataType" = "string", * "description" = "The name of the project to search or any other keyword.", * "required" = true * }, * "type" = { * "dataType" = "choice", * "description" = "The type of package to search (optional, default: all).", * "format" = "['installed', 'contao', 'all']", * "required" = false * }, * "threshold" = { * "dataType" = "int", * "description" = "The amount of results after which the search shall be stopped (optional, default: 20).", * "required" = false * } * }, * response={ * "package name 1...n" = { * "actualType" = "object", * "subType" = "object", * "description" = "The content of the packages", * "children" = { * "name" = { * "dataType" = "string", * "description" = "The name of the package" * }, * "version" = { * "dataType" = "string", * "description" = "The version of the package" * }, * "constraint" = { * "dataType" = "string", * "description" = "The constraint of the package (when package is installed)" * }, * "type" = { * "dataType" = "string", * "description" = "The noted package type" * }, * "locked" = { * "dataType" = "string", * "description" = "Flag if the package has been locked for updates" * }, * "time" = { * "dataType" = "datetime", * "description" = "The release date" * }, * "upgrade_version" = { * "dataType" = "string", * "description" = "The version available for upgrade (optional, if any)" * }, * "description" = { * "dataType" = "string", * "description" = "The package description" * }, * "license" = { * "actualType" = "collection", * "subType" = "string", * "description" = "The licenses" * }, * "keywords" = { * "actualType" = "collection", * "subType" = "string", * "description" = "The keywords" * }, * "homepage" = { * "dataType" = "string", * "description" = "The support website (optional, if any)" * }, * "authors" = { * "actualType" = "collection", * "subType" = "object", * "description" = "The authors", * "children" = { * "name" = { * "dataType" = "string", * "description" = "Full name of the author (optional, if any)" * }, * "homepage" = { * "dataType" = "string", * "description" = "Email address of the author (optional, if any)" * }, * "email" = { * "dataType" = "string", * "description" = "Homepage URL for the author (optional, if any)" * }, * "role" = { * "dataType" = "string", * "description" = "Author's role in the project (optional, if any)" * } * } * }, * "support" = { * "actualType" = "collection", * "subType" = "object", * "description" = "The support options", * "children" = { * "email" = { * "dataType" = "string", * "description" = "Email address for support (optional, if any)" * }, * "issues" = { * "dataType" = "string", * "description" = "URL to the issue tracker (optional, if any)" * }, * "forum" = { * "dataType" = "string", * "description" = "URL to the forum (optional, if any)" * }, * "wiki" = { * "dataType" = "string", * "description" = "URL to the wiki (optional, if any)" * }, * "irc" = { * "dataType" = "string", * "description" = "IRC channel for support, as irc://server/channel (optional, if any)" * }, * "source" = { * "dataType" = "string", * "description" = "URL to browse or download the sources (optional, if any)" * }, * "docs" = { * "dataType" = "string", * "description" = "URL to the documentation (optional, if any)" * }, * } * }, * "abandoned" = { * "dataType" = "boolean", * "description" = "Flag if this package is abandoned" * }, * "replacement" = { * "dataType" = "string", * "description" = "Replacement for this package (optional, if any)" * }, * "installed" = { * "dataType" = "int", * "description" = "Amount of installations" * }, * "downloads" = { * "dataType" = "int", * "description" = "Amount of downloads" * }, * "favers" = { * "dataType" = "int", * "description" = "Amount of favers" * }, * } * } * } * ) */ public function searchAction(Request $request) { $composer = $this->getComposer(); $data = new JsonArray($request->getContent()); $keywords = $data->get('keywords'); $type = $data->get('type'); $threshold = $data->has('threshold') ? $data->get('threshold') : 20; $localRepository = $composer->getRepositoryManager()->getLocalRepository(); $searcher = $this->getRepositorySearch($keywords, $type, $composer, $threshold); $results = $searcher->searchAndDecorate($keywords, $this->getFilters($type)); $responseData = []; $rootPackage = $composer->getPackage(); $converter = new PackageConverter($rootPackage); foreach ($results as $versionedResult) { /** @var VersionedPackage $versionedResult */ // Might have no version matching the current stability setting. if (null === ($latestVersion = $versionedResult->getLatestVersion())) { continue; } $package = $converter->convertPackageToArray($latestVersion); $package->set('installed', $this->getInstalledVersion($localRepository, $versionedResult->getName()))->set('downloads', $versionedResult->getMetaData('downloads'))->set('favers', $versionedResult->getMetaData('favers')); $responseData[$package->get('name')] = $package->getData(); } return JsonResponse::create($responseData)->setEncodingOptions(JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_FORCE_OBJECT); }
/** * Configure tenside. * * NOTE: This method will become inaccessible after the first successful call. * * @param Request $request The request. * * @return JsonResponse * * @throws NotAcceptableHttpException When the configuration is already complete. * * @ApiDoc( * section="install", * statusCodes = { * 201 = "When everything worked out ok", * 406 = "When the configuration is already complete" * } * ) * @ApiDescription( * request={ * "credentials" = { * "description" = "The credentials of the admin user.", * "children" = { * "secret" = { * "dataType" = "string", * "description" = "The secret to use for encryption and signing.", * "required" = true * }, * "username" = { * "dataType" = "string", * "description" = "The name of the admin user.", * "required" = true * }, * "password" = { * "dataType" = "string", * "description" = "The password to use for the admin.", * "required" = false * } * } * }, * "configuration" = { * "description" = "The application configuration.", * "children" = { * "php_cli" = { * "dataType" = "string", * "description" = "The PHP interpreter to run on command line." * }, * "php_cli_arguments" = { * "dataType" = "string", * "description" = "Command line arguments to add." * }, * "github_oauth_token" = { * "dataType" = "string", * "description" = "Github OAuth token.", * "required" = false * } * } * } * }, * response={ * "token" = { * "dataType" = "string", * "description" = "The API token for the created user" * } * } * ) */ public function configureAction(Request $request) { if ($this->get('tenside.status')->isTensideConfigured()) { throw new NotAcceptableHttpException('Already configured.'); } $inputData = new JsonArray($request->getContent()); $secret = bin2hex(random_bytes(40)); if ($inputData->has('credentials/secret')) { $secret = $inputData->get('credentials/secret'); } // Add tenside configuration. $tensideConfig = $this->get('tenside.config'); $tensideConfig->set('secret', $secret); if ($inputData->has('configuration')) { $this->handleConfiguration($inputData->get('configuration', true)); } $user = $this->createUser($inputData->get('credentials/username'), $inputData->get('credentials/password')); return new JsonResponse(['status' => 'OK', 'token' => $this->get('tenside.jwt_authenticator')->getTokenForData($user)], JsonResponse::HTTP_CREATED); }
/** * Convert the information of all packages in a repository to an array used by json API. * * @param RepositoryInterface $repository The repository holding the packages to convert. * * @param bool $requiredOnly If true, return only the packages added to the root package as require. * * @param null|JsonArray $upgradeList The package version to show as upgradable to. * * @return JsonArray */ public function convertRepositoryToArray(RepositoryInterface $repository, $requiredOnly = false, JsonArray $upgradeList = null) { $requires = $requiredOnly ? $this->rootPackage->getRequires() : false; $packages = new JsonArray(); /** @var \Composer\Package\PackageInterface $package */ foreach ($repository->getPackages() as $package) { $name = $package->getPrettyName(); $esc = $packages->escape($name); if (false === $requires || isset($requires[$name])) { $upgradeVersion = null; if ($upgradeList && $upgradeList->has($esc)) { $upgradeVersion = $upgradeList->get($esc); } $packages->set($esc, $this->convertPackageToArray($package, $upgradeVersion)->getData()); } } return $packages; }
/** * Ensure the home path has been set in the passed meta data. * * @param JsonArray $metaData The meta data to examine. * * @return void */ private function ensureHomePath(JsonArray $metaData) { if ($metaData->has(AbstractPackageManipulatingTask::SETTING_HOME)) { return; } $metaData->set(AbstractPackageManipulatingTask::SETTING_HOME, $this->home->homeDir()); }
/** * Ensure the home path has been set in the passed meta data. * * @param JsonArray $metaData The meta data to examine. * * @return void */ private function ensureHomePath(JsonArray $metaData) { if ($metaData->has(RequirePackageTask::SETTING_HOME)) { return; } $metaData->set(RequirePackageTask::SETTING_HOME, $this->home->homeDir()); }
/** * Queue a task in the list. * * @param Request $request The request. * * @return JsonResponse * * @throws NotAcceptableHttpException When the payload is invalid. * * @ApiDoc( * section="tasks", * statusCodes = { * 201 = "When everything worked out ok", * 406 = "When the payload is invalid" * }, * authentication = true, * authenticationRoles = { * "ROLE_MANIPULATE_REQUIREMENTS" * }, * ) * @ApiDescription( * response={ * "status" = { * "dataType" = "string", * "description" = "OK on success" * }, * "task" = { * "id" = { * "dataType" = "string", * "description" = "The task id." * }, * "status" = { * "dataType" = "string", * "description" = "The task status." * }, * "type" = { * "dataType" = "string", * "description" = "The type of the task." * }, * "user_data" = { * "dataType" = "object", * "description" = "The user submitted additional data." * }, * "created_at" = { * "dataType" = "string", * "description" = "The date the task was created in ISO 8601 format." * } * } * } * ) */ public function addTaskAction(Request $request) { $metaData = null; $content = $request->getContent(); if (empty($content)) { throw new NotAcceptableHttpException('Invalid payload'); } $metaData = new JsonArray($content); if (!$metaData->has('type')) { throw new NotAcceptableHttpException('Invalid payload'); } try { $taskId = $this->getTensideTasks()->queue($metaData->get('type'), $metaData); } catch (\InvalidArgumentException $exception) { throw new NotAcceptableHttpException($exception->getMessage()); } return $this->createJsonResponse([$this->convertTaskToArray($this->getTensideTasks()->getTask($taskId))], false, 'OK', JsonResponse::HTTP_CREATED); }