public static function initCapsule() { $credentials = Tool::getConfig()['db_settings']; self::$capsule = new Capsule(); self::$capsule->addConnection($credentials); self::$capsule->setEventDispatcher(new Dispatcher(new Container())); self::$capsule->setAsGlobal(); self::$capsule->bootEloquent(); if (Tool::getConfig()['log_queries']) { self::$capsule->getEventDispatcher()->listen('illuminate.query', function ($query, $params) { $log = fopen(__DIR__ . '/../../../misc/illuminate_queries.log', 'a+'); fwrite($log, date('Y/m/d H:i:s') . ' [QUERY] : ' . $query); fwrite($log, ' [with params '); $afterFirst = false; foreach ($params as $param) { if ($afterFirst) { fwrite($log, ', '); } fwrite($log, $param); if (!$afterFirst) { $afterFirst = true; } } fwrite($log, "]\n"); fclose($log); }); } }
public function sendMail($template, $to, $subject, $values, $replyTo = null) { $template = $this->renderer->loadTemplate($template); $values['client_url'] = Tool::getConfig()['client_url']; $values['subject'] = $subject; $mailBody = $template->render($values); $message = \Swift_Message::newInstance(Tool::getConfig()['msg_alerts']['subject_prefix'] . " " . $subject)->setFrom(Tool::getConfig()['msg_alerts']['from'])->setTo($to)->setBody($mailBody, 'text/html'); if ($replyTo) { $message->setReplyTo($replyTo); } $this->mailer->send($message); }
case 'subject': if (gettype($body->contact->subject) != 'string' || strlen($body->contact->subject) > 280) { throw new InvalidField('subject'); } break; case 'message': if (gettype($body->contact->message) != 'string' || strlen($body->contact->message) > 16000) { throw new InvalidField('message'); } break; } } } // Sending mail $mailer = new Mailer(); $mailer->sendMail('user_message.html', Tool::getConfig()['msg_alerts']['local_admins'], '[MSG] ' . $body->contact->subject, ['firstname' => $body->contact->firstname, 'lastname' => $body->contact->lastname, 'email' => $body->contact->email, 'message' => $body->contact->message], [$body->contact->email => $body->contact->firstname . ' ' . $body->contact->lastname]); // also saving message in database $message = new Message(); $message->first_name = $body->contact->firstname; $message->last_name = $body->contact->lastname; $message->email = $body->contact->email; $message->subject = $body->contact->subject; $message->message = $body->contact->message; $message->sent = DB::raw('NOW()'); $message->save(); Tool::endWithJson(["success" => true]); }); // HTTP REST Map $app->post('/message', $send); $app->options('/message', function () { });
*/ use API\Core\Tool; use API\Model\Plugin; use API\Model\PluginDownload; use Illuminate\Database\Capsule\Manager as DB; use API\OAuthServer\OAuthHelper; $download = Tool::makeEndpoint(function ($key) use($app) { $plugin = Plugin::where('key', '=', $key)->first(); $plugin->download_count = DB::raw('download_count + 1'); $plugin->save(); $plugin_download = new PluginDownload(); $plugin_download->downloaded_at = DB::raw('NOW()'); $plugin_download->plugin_id = $plugin->id; $plugin_download->save(); /** * @MonkeyPatch * @todo remove this as soon as possible once * all our famous, star, since-day-one * contributors took the time * to update their XML file. */ $indepnetFixSearchPattern = '/https:\\/\\/forge\\.indepnet\\.net/'; if (preg_match($indepnetFixSearchPattern, $plugin->download_url)) { $plugin->download_url = preg_replace($indepnetFixSearchPattern, 'https://forge.glpi-project.org', $plugin->download_url); } $app->redirect($plugin->download_url, 301); }); // HTTP Rest Map $app->get('/plugin/:key/download', $download); $app->options('/plugin/:key/download', function ($key) { });
private function alertWatchers($plugin) { $client_url = Tool::getConfig()['client_url']; foreach ($plugin->watchers()->get() as $watch) { $user = $watch->user; $mailer = new Mailer(); $mailer->sendMail('plugin_updated.html', [$user->email => $user->username], 'Plugin update "' . $plugin->name . '"', ['plugin' => $plugin, 'user' => $user, 'client_url' => Tool::getConfig()['client_url']]); } }
public function log() { global $resourceServer; global $app; $accessToken = null; $userId = null; $url = null; try { $url = $app->request->getResourceUri(); } catch (\Exception $e) { } try { $resourceServer->isValidRequest(); $_accessToken = $resourceServer->getAccessToken(); $accessToken = $_accessToken->getId(); $userId = $_accessToken->getSession()->getOwnerId(); } catch (\Exception $e) { } Tool::log(($accessToken && !$userId ? '[anonymous]' : '') . ($accessToken ? '[' . $accessToken . '] ' : '') . ($userId ? '(' . $userId . ') ' : '') . ($url ? '[' . $app->request->getMethod() . ' ' . $url . '] ' : '') . $this->getRepresentation() . ($this->parent ? ' because of ' . get_class($this->parent) . ' thrown at ' . $this->parent->getFile() . ' line ' . $this->parent->getLine() : '')); }
$all = Tool::paginateCollection(\API\Model\Author::mostActive()->contributorsOnly()); Tool::endWithJson($all); }; $top = function () use($app) { $top = \API\Model\Author::mostActive(10)->get(); Tool::endWithJson($top); }; $single = function ($id) use($app) { $single = \API\Model\Author::withPluginCount()->find($id); Tool::endWithJson($single); }; $author_plugins = function ($id) use($app) { $author_plugins = \API\Model\Author::find($id); if (!$author_plugins) { return Tool::endWithJson(["error" => "Cannot find author"]); } Tool::endWithJson(Tool::paginateCollection(\API\Model\Plugin::with('versions', 'authors')->short()->withDownloads()->withAverageNote()->descWithLang(Tool::getRequestLang())->whereAuthor($author_plugins->id))); }; // HTTP REST Map $app->get('/author', $all); $app->get('/author/top', $top); $app->get('/author/:id', $single); $app->get('/author/:id/plugin', $author_plugins); $app->options('/author', function () { }); $app->options('/author/top', function () { }); $app->options('/author/:id', function ($id) { }); $app->options('/author/:id/plugin', function ($id) { });
$user = User::where('id', '=', $user_id)->first(); // We ensure the recatpcha_response // is provided as a string if (!isset($body->recaptcha_response) || gettype($body->recaptcha_response) != 'string') { throw new InvalidRecaptcha(); } // and we verify it with recaptcha Tool::assertRecaptchaValid($body->recaptcha_response); if (!isset($body->author) || gettype($body->author) != 'string' || strlen($body->author) > 90) { throw new InvalidField('author'); } if (!($author = Author::where('name', '=', $body->author)->first())) { throw new ResourceNotFound('Author', $body->author); } $mailer = new Mailer(); $mailer->sendMail('authorship_claim.html', Tool::getConfig()['msg_alerts']['local_admins'], 'User ' . $user->username . ' claim authorship', ['user' => $user->toArray(), 'author' => $author->toArray()]); $app->halt(200); }); // HTTP REST Map $app->get('/author', $all); $app->get('/author/top', $top); $app->get('/author/:id', $single); $app->get('/author/:id/plugin', $author_plugins); $app->post('/claimauthorship', $claim_authorship); $app->options('/author', function () { }); $app->options('/author/top', function () { }); $app->options('/author/:id', function ($id) { }); $app->options('/author/:id/plugin', function ($id) {
public function updatePlugin($plugin, $xml, $new_crc) { if (strlen($plugin->name) == 0) { echo "first time update, found name \"" . $xml->name . "\"..."; $firstTimeUpdate = true; } else { if ($plugin->name != $xml->name) { echo "\"" . $plugin->name . "\" going to become \"" . $xml->name . "\" ..."; } else { echo "\"" . $xml->name . "\" going to be updated ..."; } } // Updating basic infos $plugin->logo_url = $xml->logo; $plugin->name = $xml->name; $plugin->key = $xml->key; $plugin->homepage_url = $xml->homepage; $plugin->download_url = $xml->download; $plugin->issues_url = $xml->issues; $plugin->readme_url = $xml->readme; $plugin->license = $xml->license; // reading descriptions, // mapping type=>lang relation to lang=>type $descriptions = []; foreach ($xml->description->children() as $type => $descs) { if (in_array($type, ['short', 'long'])) { foreach ($descs->children() as $_lang => $content) { $descriptions[$_lang][$type] = (string) $content; } } } // Delete current descriptions $plugin->descriptions()->delete(); // Refreshing descriptions foreach ($descriptions as $lang => $_type) { $description = new PluginDescription(); $description->lang = $lang; foreach ($_type as $type => $html) { $description[$type . '_description'] = $html; } $description->plugin_id = $plugin->id; $description->save(); } // Refreshing authors $plugin->authors()->detach(); $clean_authors = []; foreach ($xml->authors->children() as $author) { $_clean_authors = $this->fixParseAuthors((string) $author); foreach ($_clean_authors as $author) { $clean_authors[] = $author; } } foreach ($clean_authors as $_author) { $found = Author::where('name', '=', $_author)->first(); if (sizeof($found) < 1) { $author = new Author(); $author->name = $_author; $author->save(); } else { $author = $found; } if (!$plugin->authors->find($author->id)) { $plugin->authors()->attach($author); } } // Refreshing versions $plugin->versions()->delete(); foreach ($xml->versions->children() as $_version) { foreach ($_version->compatibility as $compat) { $version = new PluginVersion(); $version->num = trim((string) $_version->num); $version->compatibility = trim((string) $compat); $version->plugin_id = $plugin->id; $version->save(); } } // Refreshing screenshots if (isset($xml->screenshots)) { $plugin->screenshots()->delete(); foreach ($xml->screenshots->children() as $url) { $screenshot = new PluginScreenshot(); $screenshot->url = (string) $url; $screenshot->plugin_id = $plugin->id; $screenshot->save(); } } // Reassociating plugin to tags $plugin->tags()->detach(); foreach ($xml->tags->children() as $lang => $tags) { foreach ($tags->children() as $_tag) { $found = Tag::where('tag', '=', (string) $_tag)->where('lang', '=', $lang)->first(); if (sizeof($found) < 1) { $tag = new Tag(); $tag->tag = (string) $_tag; $tag->lang = $lang; $tag->key = Tool::getUrlSlug((string) $_tag); $tag->save(); } else { $tag = $found; } $tag->plugins()->attach($plugin); } } // new crc $plugin->xml_crc = $new_crc; // new timestamp if (!isset($firstTimeUpdate)) { $plugin->date_updated = DB::raw('NOW()'); } $plugin->save(); echo " OK\n"; }
<?php /** * Search * * This REST module hooks on * following URLs * * /search */ use API\Core\Tool; use Illuminate\Database\Capsule\Manager as DB; // Minimal length of search string $search_min_length = 2; $search = function () use($app) { global $search_min_length, $allowed_languages; $body = Tool::getBody(); if ($body == NULL || !isset($body->query_string) || strlen($body->query_string) < $search_min_length) { return Tool::endWithJson(["error" => "Your search string needs to " . "have at least " . $search_min_length . " chars"], 400); } $query_string = $body->query_string; $_search = Tool::paginateCollection(\API\Model\Plugin::short()->with('authors', 'versions', 'descriptions')->withDownloads()->withAverageNote()->descWithLang(Tool::getRequestLang())->where('name', 'LIKE', "%{$query_string}%")->orWhere('plugin_description.short_description', 'LIKE', "%{$query_string}%")->orWhere('plugin_description.long_description', 'LIKE', "%{$query_string}%")); Tool::endWithJson($_search); }; $app->post('/search', $search); $app->options('/search', function () { });
\API\Core\DB::initCapsule(); use API\Core\Tool; $app = new \Slim\Slim(); // Loading all REST modules // with their endpoints like that: // inside 'src/endoints' $dir_endpoints = opendir('src/endpoints'); while ($ent = readdir($dir_endpoints)) { // For each .php file if (preg_match('/^(.*)\\.php$/', $ent, $m)) { $endpoint = $m[0]; // Read the file with PHP require 'src/endpoints/' . $endpoint; } } closedir($dir_endpoints); // Logs to error_log specified in virtualhost $app->error(function (\Exception $e) { Tool::endWithJson(["error" => "Server error"], 500); Tool::log($e->getMessage()); }); // JSON 404 response $app->notFound(function () { Tool::endWithJson(["error" => "invalid endpoint"], 404); }); // Welcoming browsers when they reach /api $app->get('/', function () use($app) { echo file_get_contents(__DIR__ . '/welcome.html'); }); // Ready to serve with Slim $app->run();
<?php require __DIR__ . '/../api/vendor/autoload.php'; /** * This is the crontab script. */ \API\Core\DB::initCapsule(); $taskDispatcher = new \API\Core\BackgroundTasks(["plugin_max_consecutive_xml_fetch_fails" => \API\Core\Tool::getConfig()['plugin_max_consecutive_xml_fetch_fails']]); $options = getopt('i:k:t:'); // If the user at the command line specify // no known options, there is the default // set of tasks that runs. if (sizeof($options) == 0) { $taskDispatcher->foreachPlugin(['update', 'alert_watchers', 'alert_plugin_team_on_xml_state_change']); $taskDispatcher->foreachAccessToken(['delete_AT_if_expired']); $taskDispatcher->foreachRefreshToken(['delete_lonely_RT']); $taskDispatcher->foreachSession(['delete_lonely_session']); } else { $key = null; $tasks = []; if (isset($options['t']) && in_array(gettype($options['t']), ['string', 'array'])) { $tasks = gettype($options['t']) == 'array' ? $options['t'] : [$options['t']]; } if (isset($options['k']) && gettype($options['k']) == 'string') { $taskDispatcher->wherePluginKeyIs($options['k'], $tasks); } elseif (isset($options['i']) && gettype($options['i'] == 'string')) { $taskDispatcher->wherePluginIdIs($options['i'], $tasks); } }
use API\OAuthServer\OAuthHelper; // Initialisation of Database (Illuminate) // and webapp global object \API\Core\DB::initCapsule(); $app = new \Slim\Slim(); // Instantiating the Resource Server $resourceServer = new \League\OAuth2\Server\ResourceServer(OAuthHelper::getSessionStorage(), OAuthHelper::getAccessTokenStorage(), OAuthHelper::getClientStorage(), OAuthHelper::getScopeStorage()); // Loading all REST modules // with their endpoints like that: // inside 'src/endpoints' $dir_endpoints = opendir('src/endpoints'); while ($ent = readdir($dir_endpoints)) { // For each .php file if (preg_match('/^(.*)\\.php$/', $ent, $m)) { $endpoint = $m[0]; // Read the file with PHP require 'src/endpoints/' . $endpoint; } } closedir($dir_endpoints); // JSON 404 response $app->notFound(Tool::makeEndpoint(function () { throw new \API\Exception\InvalidEndpoint(); })); // Welcoming browsers when they reach /api $app->get('/', function () use($app) { $app->halt(200); //echo file_get_contents(__DIR__.'/welcome.html'); }); // Ready to serve with Slim $app->run();
<?php use Illuminate\Database\Capsule\Manager as DB; use API\Core\Tool; use API\Model\Plugin; use API\OAuthServer\OAuthHelper; $version_plugins = Tool::makeEndpoint(function ($version) { OAuthHelper::needsScopes(['version', 'plugins']); $plugins = Tool::paginateCollection(Plugin::short()->with('authors', 'versions', 'descriptions')->withAverageNote()->descWithLang(Tool::getRequestLang())->withGlpiVersion($version)); Tool::endWithJson($plugins); }); $app->get('/version/:version/plugin', $version_plugins); $app->options('/version/:version/plugin', function () { });
$user_app->homepage_url = $body->homepage_url; } } if (isset($body->description)) { if (gettype($body->description) != 'string' || !App::isValidDescription($body->description)) { throw new InvalidField('description'); } else { $user_app->description = $body->description; } } $user_app->save(); Tool::endWithJson($user_app); }); $user_delete_app = Tool::makeEndpoint(function ($id) use($app, $resourceServer) { OAuthHelper::needsScopes(['user', 'user:apps']); $body = Tool::getBody(); $user_id = $resourceServer->getAccessToken()->getSession()->getOwnerId(); $user = User::where('id', '=', $user_id)->first(); $user_app = $user->apps()->find($id); if ($user_app) { $user_app->delete(); $app->halt(200); } else { throw new ResourceNotFound('App', $id); } }); // HTTP REST Map $app->get('/user/apps', $user_apps); $app->get('/user/apps/:id', $user_app); $app->put('/user/apps/:id', $user_edit_app); $app->delete('/user/apps/:id', $user_delete_app);
/** * This is used in endpoints to ask recaptcha * to validate a specific recaptcha response */ public static function assertRecaptchaValid($recaptcha_response) { $recaptcha = new ReCaptcha(Tool::getConfig()['recaptcha_secret']); if (!$recaptcha->verify($recaptcha_response)->isSuccess()) { throw new InvalidRecaptcha(); } }
* Returns the complete list of emails * that are available through the * external accounts */ $oauth_external_emails = Tool::makeEndpoint(function () use($app, $resourceServer) { OAuthHelper::needsScopes(['user']); $user = OAuthHelper::currentlyAuthed(); $externalAccounts = $user->externalAccounts()->get(); $emails = []; foreach ($externalAccounts as $externalAccount) { $oAuth = new OAuthClient($externalAccount->service); $_emails = $oAuth->getEmails($externalAccount->token); foreach ($_emails as $email) { $emails[] = ["email" => $email, "service" => $externalAccount->service]; } } Tool::endWithJson($emails); }); $app->get('/user/external_accounts', $user_external_accounts); $app->delete('/user/external_accounts/:id', $user_delete_external_account); $app->get('/oauth/available_emails', $oauth_external_emails); $app->get('/oauth/associate/:service', $user_associate_external_account); $app->post('/oauth/authorize', $authorize); $app->options('/user/external_accounts', function () { }); $app->options('/oauth/available_emails', function () { }); $app->options('/oauth/authorize', function () { }); $app->options('/oauth/associate/:service', function () { });