/** * Constructor class for Language */ public function __construct() { if (!$this->getData('language')) { $this->language = isset($_COOKIE['pp_language']) && !empty($_COOKIE['pp_language']) ? $_COOKIE['pp_language'] : Settings::config()->default_language; } else { $this->language = $this->getData('language'); } if (!file_exists(APP_DIR . 'languages/' . $this->language . '.json')) { throw new Exception('Unable to load the required language file! ' . APP_DIR . 'languages/' . $this->language . '.json'); } $this->loaded = json_decode(file_get_contents(APP_DIR . 'languages/' . $this->language . '.json'), true); }
/** * Handles updating a user password for the router. Can also be used outside of the router if needed. * * @param string $new * @return bool */ public function updatePassword($new) { $new_password = $this->hash($new); $this->account = ORM::forTable('users')->findOne($this->_user->getData('id')); if (!$this->account) { return false; } $this->account->password = $new_password; $this->account->session_id = null; $this->account->session_ip = null; $this->account->save(); $this->buildEmail('password_changed', array('IP_ADDRESS' => $_SERVER['REMOTE_ADDR'], 'GETHOSTBY_IP_ADDRESS' => gethostbyaddr($_SERVER['REMOTE_ADDR'])))->dispatch($this->_user->getData('email'), Settings::config()->company_name . ' - Password Change Notification'); return true; }
/** * Handles adding a new subuser to a server. * * @return bool */ public function addSubuser(\Klein\DataCollection\DataCollection $data) { if (is_null($data->permissions) || !$data->permissions) { $data->permissions = array('console.view'); } $registerToken = $this->keygen(32); $daemon_permissionSecret = $this->generateUniqueUUID('servers', 'daemon_secret'); $data->permissions = self::_rebuildUserPermissions($data->permissions); ORM::get_db()->beginTransaction(); try { $user = ORM::forTable('users')->where('email', $data->email)->findOne(); $checkUserExists = $user ? true : false; if (!$checkUserExists) { $user = ORM::forTable('users')->create()->set(array('uuid' => $this->generateUniqueUUID('users', 'uuid'), 'username' => null, 'email' => $data->email, 'password' => null, 'language' => Settings::config('default_language'), 'register_time' => time())); $user->save(); ORM::forTable('account_change')->create()->set(array('user_id' => $user->id, 'type' => 'user_register', 'content' => $data->email, 'key' => $registerToken, 'time' => time()))->save(); } ORM::forTable('subusers')->create()->set(array('user' => $user->id, 'server' => $this->server->getData('id'), 'daemon_secret' => $daemon_permissionSecret, 'daemon_permissions' => json_encode(self::_buildDaemonPermissions($data->permissions))))->save(); $email = null; foreach (self::_rebuildUserPermissions($data->permissions) as $id => $permission) { ORM::forTable('permissions')->create()->set(array('user' => $user->id, 'server' => $this->server->getData('id'), 'permission' => $permission))->save(); } if ($checkUserExists) { $email = $this->buildEmail('new_subuser', array('SERVER' => $this->server->getData('name'), 'EMAIL' => $data->email)); } else { $email = $this->buildEmail('new_subuser_createaccount', array('REGISTER_TOKEN' => $registerToken, 'URLENCODE_TOKEN' => urlencode($registerToken), 'SERVER' => $this->server->getData('name'), 'EMAIL' => $data->email)); } $unirest = Unirest\Request::put("https://" . $this->server->nodeData('fqdn') . ":" . $this->server->nodeData('daemon_listen') . "/server", array("X-Access-Token" => $this->server->nodeData('daemon_secret'), "X-Access-Server" => $this->server->getData('hash')), array("json" => json_encode(array($daemon_permissionSecret => self::_buildDaemonPermissions($data->permissions))), "object" => "keys", "overwrite" => false)); if ($unirest->code !== 204) { throw new \Exception("Error with communication to Scales:" . $unirest->code); } $email->dispatch($data->email, Settings::config()->company_name . ' - You\'ve Been Invited to Manage a Server'); ORM::get_db()->commit(); return true; } catch (\Exception $e) { \Tracy\Debugger::log($e); self::_setError("An error occured when trying to update the server information on the daemon."); ORM::get_db()->rollBack(); return false; } }
/** * Reads an email template and compiles the necessary data into it. * * @param string $tpl The email template to use. * @param array $data * @return Email */ public function buildEmail($tpl, array $data) { $this->message = str_replace(array('{{ HOST_NAME }}', '{{ MASTER_URL }}', '{{ DATE }}'), array(Settings::config()->company_name, Settings::config()->master_url, date('j/F/Y H:i', time())), $this->_readTemplate($tpl)); foreach ($data as $key => $val) { $this->message = str_replace('{{ ' . $key . ' }}', $val, $this->message); } return $this; }
$klein->respond('POST', '/auth/remote/install-progress', function ($request, $response) use($core) { // Server is done Installing if (!$request->param('server')) { $response->code(404)->body('No server variable passed to this request.')->send(); return; } $server = ORM::forTable('servers')->where(array('hash' => $request->param('server'), 'installed' => 0))->findOne(); if (!$server) { $response->code(404)->body('No server found in the system.')->send(); return; } $node = ORM::forTable('nodes')->findOne($server->node); $user = ORM::forTable('users')->findOne($server->owner_id); $server->installed = 1; $server->save(); $core->email->buildEmail('admin_new_server', array('NAME' => $server->name, 'SFTP' => $node->fqdn . ':' . $node->daemon_sftp, 'SERVER_CONN' => $server->server_ip . ':' . $server->server_port, 'USER' => $server->sftp_user, 'PASS' => 'You need to set your SFTP password in the panel after logging in.'))->dispatch($user->email, Settings::config()->company_name . ' - New Server Added'); $response->code(204)->body("")->send(); }); $klein->respond('GET', '/auth/remote/deploy/[:key]', function ($request, $response) use($core) { $deploy = ORM::forTable('autodeploy')->where('code', $request->param('key'))->where_gt('expires', time())->findOne(); if (!$deploy) { $response->code(404)->body('echo "The requested URL does not exist."; exit 1')->send(); return; } $node = ORM::forTable('nodes')->findOne($deploy->node); if (!$node) { $response->code(404)->body('404 Node')->send(); return; } // Check Access IP here $response->header('Content-Type', 'text/plain');
the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ namespace PufferPanel\Core; use ORM; $klein->respond(array('POST', 'GET'), '/node/users/[*]?', function ($request, $response, $service, $app, $klein) use($core) { if (Settings::config('allow_subusers') != 1 || !$core->permissions->has('users.view')) { $response->code(403); $response->body($core->twig->render('node/403.html'))->send(); $klein->skipRemaining(); } }); $klein->respond('GET', '/node/users', function ($request, $response, $service) use($core) { $select = ORM::forTable('subusers')->raw_query("SELECT subusers.*, users.email, users.username, GROUP_CONCAT(permissions.permission SEPARATOR ', ') as user_permissions FROM subusers LEFT JOIN permissions ON subusers.user = permissions.user AND subusers.server = permissions.server LEFT JOIN users ON subusers.user = users.id WHERE subusers.server = :server GROUP BY subusers.id", array('server' => $core->server->getData('id')))->findArray(); $response->body($core->twig->render('node/users/index.html', array('flash' => $service->flashes(), 'users' => $select, 'server' => $core->server->getData(), 'node' => $core->server->nodeData())))->send(); }); $klein->respond('GET', '/node/users/[:action]/[:email]?', function ($request, $response, $service) use($core) { if ($request->param('action') == 'add') { $response->body($core->twig->render('node/users/add.html', array('flash' => $service->flashes(), 'xsrf' => $core->auth->XSRF(), 'server' => $core->server->getData(), 'node' => $core->server->nodeData())))->send(); } else { if ($request->param('action') == 'edit' && $request->param('email')) { $user = ORM::forTable('subusers')->raw_query("SELECT subusers.*, users.email, users.id as user_id, GROUP_CONCAT(permissions.permission) as user_permissions FROM subusers\n\t\t\t\tLEFT JOIN users ON subusers.user = users.id\n\t\t\t\tLEFT JOIN permissions ON subusers.user = permissions.user AND subusers.server = permissions.server\n\t\t\t\tWHERE users.email = :email AND subusers.server = :server\n\t\t\t\tGROUP BY subusers.id", array("email" => $request->param('email'), "server" => $core->server->getData('id')))->findOne();
$core->auth = new Authentication(); $core->user = new User(); $core->server = new Server(); $core->email = new Email(); $core->log = new Log(); $core->daemon = new Daemon(); $core->files = new Files(); $core->twig = new Twig_Environment(new Twig_Loader_Filesystem(APP_DIR . 'views/')); $core->language = new Language(); $core->permissions = new Permissions($core->server->getData('id')); /* * Twig Setup */ $core->twig->addGlobal('l', $core->language); // @TODO Change this to addGlobal('language', $core->language) to allow access as {{ language.render('template') }} $core->twig->addGlobal('settings', Settings::config()); $core->twig->addGlobal('permission', $core->permissions); $core->twig->addGlobal('fversion', trim(file_get_contents(SRC_DIR . 'versions/current'))); $core->twig->addGlobal('admin', (bool) $core->user->getData('root_admin')); $core->twig->addGlobal('version', Version::get()); //Check if panel is completely installed. //If no settings are found, then we should load configuration setup and skip anything else if (ORM::for_table("acp_settings")->count() == 0) { include BASE_DIR . 'install/configure.php'; $klein->dispatch(); return; } $klein->respond('!@^(/auth/|/language/|/api/|/assets/)', function ($request, $response, $service, $app, $klein) use($core) { if (!$core->auth->isLoggedIn()) { if (!strpos($request->pathname(), "/ajax/")) { $service->flash('<div class="alert alert-danger">You must be logged in to access that page.</div>');
} try { $unirest = Request::post('https://' . $core->server->nodeData('fqdn') . ':' . $core->server->nodeData('daemon_listen') . '/server/reset-password', array("X-Access-Token" => $core->server->nodeData('daemon_secret'), "X-Access-Server" => $core->server->getData('hash')), array("password" => $request->param('sftp_pass'))); if ($unirest->code !== 204) { $service->flash('<div class="alert alert-danger">Scales returned an error when trying to process your request. Scales said: ' . $unirest->raw_body . ' [HTTP/1.1 ' . $unirest->code . ']</div>'); $response->redirect('/admin/server/view/' . $request->param('id'))->send(); return; } } catch (Exception $e) { Debugger::log($e); $service->flash('<div class="alert alert-danger">An error occured while trying to connect to the remote node. Please check that Scales is running and try again.</div>'); $response->redirect('/admin/server/view/' . $request->param('id'))->send(); return; } if ($request->param('email_user')) { $core->email->buildEmail('admin_new_ftppass', array('PASS' => $request->param('sftp_pass'), 'SERVER' => $core->server->getData('name')))->dispatch($core->user->getData('email'), Settings::config()->company_name . ' - Your SFTP Password was Reset'); } $service->flash('<div class="alert alert-success">The SFTP password for this server has been successfully reset.</div>'); $response->redirect('/admin/server/view/' . $request->param('id') . '?tab=sftp_sett')->send(); }); $klein->respond('POST', '/admin/server/view/[i:id]/reset-token', function ($request, $response) use($core) { $secret = $core->auth->generateUniqueUUID('servers', 'daemon_secret'); ORM::get_db()->beginTransaction(); $server = ORM::forTable('servers')->findOne($core->server->getData('id')); $server->daemon_secret = $secret; $server->save(); try { $unirest = Request::put('https://' . $core->server->nodeData('fqdn') . ':' . $core->server->nodeData('daemon_listen') . "/server", array("X-Access-Token" => $core->server->nodeData('daemon_secret'), "X-Access-Server" => $core->server->getData('hash')), array("json" => json_encode(array($core->server->getData('daemon_secret') => array(), $secret => array("s:ftp", "s:get", "s:power", "s:files", "s:files:get", "s:files:put", "s:query", "s:console", "s:console:send"))), "object" => "keys", "overwrite" => false)); if ($unirest->code != 204) { $response->body("Error trying to update token. Scales said: {$unirest->raw_body} [HTTP/1.1 {$unirest->code}]")->send(); return;
} $response->redirect('/admin/settings/email')->send(); } // Update URLs if ($request->param('page') == "urls" && $request->param('action') == "update") { $urls = array(); foreach (array('main_url' => $request->param('main_url'), 'master_url' => $request->param('master_url'), 'assets_url' => $request->param('assets_url')) as $id => $val) { $url = parse_url($val); if (!isset($url['host'])) { $service->flash('<div class="alert alert-danger">At least one of the URLs provided was invalid and could not be processed.</div>'); $response->redirect('/admin/settings/urls')->send(); return; } $url['path'] = isset($url['path']) ? $url['path'] : null; if ($id != "assets_url") { $urls[$id] = Settings::config()->https == 1 ? 'https://' . $url['host'] . $url['path'] : 'http://' . $url['host'] . $url['path']; } else { $urls[$id] = "//" . $url['host'] . $url['path']; } $urls[$id] = rtrim($urls[$id], '/') . '/'; } try { ORM::forTable('acp_settings')->rawExecute("UPDATE acp_settings SET setting_val = CASE setting_ref\n WHEN 'main_website' THEN :main_url\n WHEN 'master_url' THEN :master_url\n WHEN 'assets_url' THEN :assets_url\n ELSE setting_val\n END", array('main_url' => $urls['main_url'], 'master_url' => $urls['master_url'], 'assets_url' => $urls['assets_url'])); $service->flash('<div class="alert alert-success">Your URL settings have been updated.</div>'); } catch (\Exception $e) { Debugger::log($e); $service->flash('<div class="alert alert-danger">An error occured while trying to perform this MySQL command.</div>'); } $response->redirect('/admin/settings/urls')->send(); } });
$service->flash('<div class="alert alert-danger">A user with that ID could not be found in the system.</div>'); $response->redirect('/admin/account')->send(); return; } if ($request->param('action') == 'update') { if (!filter_var($request->param('email'), FILTER_VALIDATE_EMAIL)) { $service->flash('<div class="alert alert-danger">The email provided was not valid.</div>'); $response->redirect('/admin/account/view/' . $request->param('id'))->send(); return; } $user = ORM::forTable('users')->findOne($request->param('id')); $user->set(array('email' => $request->param('email'), 'root_admin' => $request->param('root_admin'))); $user->save(); $service->flash('<div class="alert alert-success">Account has been updated.</div>'); $response->redirect('/admin/account/view/' . $request->param('id'))->send(); } if ($request->param('action') == 'password') { $user = ORM::forTable('users')->findOne($request->param('id')); $user->password = $core->auth->hash($request->param('pass')); if ($request->param('email_user')) { $core->email->buildEmail('new_password_admin', array('NEW_PASS' => $request->param('pass'), 'EMAIL' => $user->email))->dispatch($user->email, Settings::config()->company_name . ' - An Admin has Reset Your Password'); } if ($request->param('clear_session')) { $user->session_id = null; $user->session_ip = null; } $user->save(); $service->flash('<div class="alert alert-success">Account password has been updated.</div>'); $response->redirect('/admin/account/view/' . $request->param('id'))->send(); } });
$response->redirect('/admin/account/new')->send(); return; } $query = ORM::forTable('users')->where_any_is(array(array('username' => $_POST['username']), array('email' => $_POST['email'])))->findOne(); if ($query) { $service->flash('<div class="alert alert-danger">An account with that username or email already exists in the system.</div>'); $response->redirect('/admin/account/new')->send(); return; } $user = ORM::forTable('users')->create(); $user->set(array('uuid' => $core->auth->gen_UUID(), 'username' => $request->param('username'), 'email' => $request->param('email'), 'password' => $core->auth->hash($request->param('pass')), 'language' => Settings::config()->default_language, 'register_time' => time())); $user->save(); /* * Send Email */ $core->email->buildEmail('admin_newaccount', array('PASS' => $request->param('pass'), 'EMAIL' => $request->param('email')))->dispatch($request->param('email'), Settings::config()->company_name . ' - Account Created'); $service->flash('<div class="alert alert-success">Account has been successfully created.</div>'); $response->redirect('/admin/account/view/' . $user->id())->send(); }); $klein->respond('POST', '/api/server/view/[i:id]/delete/[:force]?', function ($request, $response, $service) use($core) { if ($request->param('apikey') != "T=7tREs#Uku@razudutU6uruph3yucEc") { return 'error'; } // Start Transaction so if the daemon errors we can rollback changes ORM::get_db()->beginTransaction(); $node = ORM::forTable('nodes')->findOne($core->server->getData('node')); $ports = json_decode($node->ports, true); $ips = json_decode($node->ips, true); $ports[$core->server->getData('server_ip')][$core->server->getData('server_port')]++; $ips[$core->server->getData('server_ip')]['ports_free']++; $node->ips = json_encode($ips);