return array('install' => array('tables' => array('config' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'group', 'type' => 'string', 'length' => 30), (object) array('name' => 'key', 'type' => 'string', 'length' => 30), (object) array('name' => 'value', 'type' => 'text', 'nullable' => TRUE)), 'ipbans' => array((object) array('name' => 'ip', 'type' => 'string', 'length' => 50), (object) array('name' => 'ip', 'type' => 'primary')), 'main' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'urlkey', 'type' => 'string', 'length' => 9, 'default' => ''), (object) array('name' => 'urlkey', 'type' => 'index'), (object) array('name' => 'author_id', 'type' => 'integer', 'nullable' => TRUE, 'default' => NULL), (object) array('name' => 'author', 'type' => 'string', 'length' => 50, 'nullable' => TRUE, 'default' => ''), (object) array('name' => 'author', 'type' => 'index'), (object) array('name' => 'project', 'type' => 'string', 'length' => 50, 'nullable' => TRUE, 'default' => ''), (object) array('name' => 'project', 'type' => 'index'), (object) array('name' => 'timestamp', 'type' => 'integer'), (object) array('name' => 'expire', 'type' => 'integer'), (object) array('name' => 'title', 'type' => 'string', 'length' => 25, 'nullable' => TRUE, 'default' => ''), (object) array('name' => 'data', 'type' => 'longText'), (object) array('name' => 'language', 'type' => 'string', 'length' => 50, 'default' => 'text'), (object) array('name' => 'password', 'type' => 'string', 'length' => 60), (object) array('name' => 'salt', 'type' => 'string', 'length' => 5), (object) array('name' => 'private', 'type' => 'boolean', 'default' => 0), (object) array('name' => 'private', 'type' => 'index'), (object) array('name' => 'hash', 'type' => 'string', 'length' => 12), (object) array('name' => 'ip', 'type' => 'string', 'length' => 50), (object) array('name' => 'hits', 'type' => 'integer', 'default' => 0), (object) array('name' => 'flagged', 'type' => 'boolean', 'default' => 0), (object) array('name' => 'attachment', 'type' => 'boolean', 'default' => 0)), 'revisions' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'paste_id', 'type' => 'integer'), (object) array('name' => 'urlkey', 'type' => 'string', 'length' => 9), (object) array('name' => 'author', 'type' => 'string', 'length' => 50, 'nullable' => TRUE, 'default' => NULL), (object) array('name' => 'timestamp', 'type' => 'integer')), 'comments' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'paste_id', 'type' => 'integer'), (object) array('name' => 'data', 'type' => 'text'), (object) array('name' => 'author', 'type' => 'string', 'length' => 50, 'nullable' => TRUE, 'default' => NULL), (object) array('name' => 'timestamp', 'type' => 'integer')), 'users' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'username', 'type' => 'string', 'length' => 50), (object) array('name' => 'username', 'type' => 'index'), (object) array('name' => 'password', 'type' => 'string', 'length' => 60), (object) array('name' => 'salt', 'type' => 'string', 'length' => 5), (object) array('name' => 'remember_token', 'type' => 'string', 'length' => 60, 'default' => ''), (object) array('name' => 'email', 'type' => 'string', 'length' => 100), (object) array('name' => 'dispname', 'type' => 'string', 'length' => 100, 'nullable' => TRUE, 'default' => ''), (object) array('name' => 'admin', 'type' => 'boolean', 'default' => 0), (object) array('name' => 'type', 'type' => 'string', 'length' => 10, 'default' => 'db'), (object) array('name' => 'active', 'type' => 'boolean', 'default' => 1)), 'statistics' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'date', 'type' => 'date'), (object) array('name' => 'web', 'type' => 'integer', 'default' => 0), (object) array('name' => 'api', 'type' => 'integer', 'default' => 0))), 'closure' => function () { // Get the FQDN for the server $fqdn = getenv('SERVER_NAME'); // Generate user credentials $username = '******'; $password = str_random(8); // Save the user info to session Session::put('install.username', $username); Session::put('install.password', $password); // Create the admin user $user = new User(); $user->username = $username; $user->email = $username . '@' . $fqdn; $user->salt = str_random(5); $user->password = PHPass::make()->create($password, $user->salt); $user->admin = 1; $user->save(); // Insert fqdn and app version to site config Site::config('general', array('fqdn' => $fqdn, 'version' => Config::get('app.version'))); }), 'update' => array('0.4' => array('newTables' => array('config' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'group', 'type' => 'string', 'length' => 30), (object) array('name' => 'key', 'type' => 'string', 'length' => 30), (object) array('name' => 'value', 'type' => 'text', 'nullable' => TRUE)), 'revisions' => array((object) array('name' => 'id', 'type' => 'increments'), (object) array('name' => 'paste_id', 'type' => 'integer'), (object) array('name' => 'urlkey', 'type' => 'string', 'length' => 9), (object) array('name' => 'author', 'type' => 'string', 'length' => 50, 'nullable' => TRUE, 'default' => NULL), (object) array('name' => 'timestamp', 'type' => 'integer'))), 'modifyTables' => array('main' => array((object) array('name' => 'author_id', 'type' => 'integer', 'nullable' => TRUE, 'default' => NULL)), 'users' => array((object) array('name' => 'admin', 'type' => 'boolean', 'default' => 0), (object) array('name' => 'type', 'type' => 'string', 'length' => 10, 'default' => 'db'), (object) array('name' => 'active', 'type' => 'boolean', 'default' => 1), (object) array('name' => 'sid', 'type' => 'dropColumn'), (object) array('name' => 'lastlogin', 'type' => 'dropColumn'))), 'closure' => function () { // Get the table prefix $dbPrefix = DB::getTablePrefix(); // Change the hash datatype to VARCHAR(12) // A raw query is fine here as 0.4 supported MySQL only DB::update("ALTER TABLE {$dbPrefix}main MODIFY COLUMN hash VARCHAR(12) NOT NULL"); // Change the urlkey to VARCHAR(9), as we prepent 'p' now DB::update("ALTER TABLE {$dbPrefix}main MODIFY COLUMN urlkey VARCHAR(9) NOT NULL DEFAULT ''"); // Prepend 'p' to non-empty URL keys DB::update("UPDATE {$dbPrefix}main SET urlkey = CONCAT('p', urlkey) WHERE urlkey <> ''"); // Setup admin = true for all users because
/** * Handles the paste password submission * * @param string $urlkey * @param string $hash * @return \Illuminate\Support\Facades\Redirect|null */ public function postPassword($urlkey, $hash = '') { $paste = Paste::where('urlkey', $urlkey)->first(); if (!is_null($paste) and Input::has('password')) { $entered = Input::get('password'); if (PHPass::make()->check('Paste', $entered, $paste->salt, $paste->password)) { Session::put("paste.password{$paste->id}", TRUE); return Redirect::to("{$urlkey}/{$hash}"); } } // Something wrong here App::abort(401); }
/** * Creates a new paste with the data supplied * * @static * @param string $source * @param array $data * @return Illuminate\Database\Eloquent\Model */ public static function createNew($source, $data) { // Get the site's configuration $site = Site::config('general'); // Set the paste protected flag $protected = !empty($data['password']); // Set the private paste flag $private = !empty($data['private']); // We use an alphanumeric URL key to identify pastes // This is done so that users do not have access to the // actual primary key in the database and therefore, cannot // mass download all data $urlkey = static::makeUrlKey(); // This hash is used for identifying private pastes // Unless being opened by the paste author, sticky notes // makes passing this hass as a part of the URL mandatory // for private pastes $hash = static::getHash(); // Encrypt the password with a salt $password = ''; $salt = str_random(5); if (!empty($data['password'])) { $password = PHPass::make()->create($data['password'], $salt); } // Set the paste visibility based on the site's config switch ($site->pasteVisibility) { case 'public': $protected = $private = FALSE; $password = ''; break; case 'private': $private = TRUE; break; } // Set the paste author if (Auth::check()) { $user = Auth::user(); $authorId = $user->id; $author = $user->username; } else { $authorId = 0; $author = NULL; } // Set the paste expiration time default if (!isset($data['expire']) or $data['expire'] < 0) { $data['expire'] = $site->pasteAge; } // Check if we have an attachment if ($site->allowAttachment and isset($data['attachment']) and is_array($data['attachment'])) { $attachment = empty($data['attachment'][0]) ? 0 : 1; } else { $attachment = 0; } // Set up the new paste $paste = new Paste(); $paste->project = empty($data['project']) ? NULL : $data['project']; $paste->title = empty($data['title']) ? NULL : $data['title']; $paste->data = $data['data']; $paste->language = $data['language']; $paste->private = ($protected or $private) ? 1 : 0; $paste->password = $password; $paste->salt = $salt; $paste->hash = $hash; $paste->urlkey = $urlkey; $paste->author = $author; $paste->author_id = $authorId; $paste->timestamp = time(); $paste->expire = $data['expire'] > 0 ? time() + $data['expire'] : 0; $paste->ip = Request::getClientIp(); $paste->attachment = $attachment; $paste->hits = 0; $paste->flagged = 0; $paste->save(); // Insert paste count to the statistics table $stat = Statistics::firstOrNew(array('date' => date('Y-m-d'))); $stat->{$source}++; $stat->save(); // Return the created paste return $paste; }
/** * Handles POST actions for the user module * * @return \Illuminate\Support\Facades\Redirect */ public function postUser() { if (Input::has('_save')) { $id = Input::get('id'); // Define validation rules $validator = Validator::make(Input::all(), array('username' => 'required|max:50|alpha_dash|unique:users,username,' . $id . ',id,type,db', 'email' => 'required|max:100|email|unique:users,email,' . $id . ',id,type,db', 'dispname' => 'max:100', 'password' => empty($id) ? 'required|min:5' : 'min:5')); // Run the validator if ($validator->passes()) { // If ID is there, it is an update operation if (!empty($id)) { $user = User::findOrFail($id); $origUsername = $user->username; } else { $user = new User(); $origUsername = NULL; } $user->username = Input::get('username'); $user->email = Input::get('email'); $user->dispname = Input::get('dispname'); $user->salt = $user->salt ?: str_random(5); // The first user is always immutable $isFounder = $user->id == User::min('id'); $user->admin = $isFounder ?: Input::has('admin'); $user->active = $isFounder ?: Input::has('active'); if (Input::has('password')) { $user->password = PHPass::make()->create(Input::get('password'), $user->salt); } $user->save(); // Username is cached in the main, comment and revision tables, update them too if (!empty($id)) { Paste::where('author_id', $id)->update(array('author' => $user->username)); Revision::where('author', $origUsername)->update(array('author' => $user->username)); Comment::where('author', $origUsername)->update(array('author' => $user->username)); } Cache::flush(); Session::flash('messages.success', Lang::get('admin.user_saved')); return Redirect::to('admin/user'); } else { Session::flash('messages.error', $validator->messages()->all('<p>:message</p>')); return Redirect::to(URL::previous())->withInput(); } } else { if (Input::has('search')) { $username = Input::get('search'); return Redirect::to('admin/user/edit/' . urlencode($username)); } else { return Redirect::to('admin/user'); } } }
/** * Show a paste by its ID or key * * @access public * @param string $mode * @param string $urlkey * @param string $hash * @param string $password * @return \Illuminate\Support\Facades\View */ public function getShow($mode, $urlkey, $hash = '', $password = '') { $api = API::make($mode); $paste = Paste::where('urlkey', $urlkey)->first(); // The paste was not found if (is_null($paste)) { return $api->error('not_found', 404); } // Validate the hash for private pastes if ($paste->private and $paste->hash != $hash) { return $api->error('invalid_hash', 403); } // Validate the password for protected pastes if ($paste->password) { if (empty($password)) { return $api->error('password_required', 403); } else { if (!PHPass::make()->check('Paste', $password, $paste->salt, $paste->password)) { return $api->error('invalid_password', 403); } } } // Build the API data $data = $paste->toArray(); return $api->out('show', $data); }
/** * Handles POST requests on the user profile * * @access public * @return \Illuminate\Support\Facades\Redirect */ public function postProfile() { $user = Auth::user(); // Define validation rules $rules = array('username' => 'max:50|alpha_dash|unique:users,username,' . $user->id . ',id,type,db', 'email' => 'required|max:100|email|unique:users,email,' . $user->id . ',id,type,db', 'dispname' => 'max:100', 'password' => 'min:5'); $validator = Validator::make(Input::all(), $rules); // Run the validator if ($validator->passes()) { $origUsername = $user->username; $user->username = $user->admin ? Input::get('username') : $user->username; $user->email = Input::get('email'); $user->dispname = Input::get('dispname'); if (Input::has('password')) { $user->password = PHPass::make()->create(Input::get('password'), $user->salt); } $user->save(); // Update cached username in the main table Paste::where('author_id', $user->id)->update(array('author' => $user->username)); // Update cached username in the revisions table Revision::where('author', $origUsername)->update(array('author' => $user->username)); // Update cached username in the comments table Comment::where('author', $origUsername)->update(array('author' => $user->username)); Session::flash('messages.success', Lang::get('user.profile_saved')); return Redirect::to('user/profile'); } else { Session::flash('messages.error', $validator->messages()->all('<p>:message</p>')); return Redirect::to('user/profile')->withInput(); } }