Skip to content
Snippets Groups Projects
Commit 4f5cc759 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Started work on rewrite

parent 71ea4b86
No related branches found
No related tags found
No related merge requests found
Showing with 649 additions and 193 deletions
.idea
*.iml
qrs_config.php
# quassel-rest-search # Quassel RESTSearch
This is just a simple Proof-of-Concept, don’t use it in production yet. This is a websearch frontend for a quassel database.
How to use It offers both a simple HTTP API for search, and a normal website for the same purpose.
----------
First, you have to have PostgreSQL Setting up search backends
--------------------------
Second, create an index over your messages column like ####pgsql-smart
First, add a new column to the backlog table:
```sql
ALTER TABLE public.backlog ADD COLUMN tsv tsvector;
```
Second, add the two new indices:
```sql ```sql
CREATE INDEX backlog_idx ON backlog USING gin(to_tsvector('simple', message)); CREATE INDEX backlog_tsv_idx
ON public.backlog
USING gin(tsv);
``` ```
Third, install this and set it up via config.ini ```sql
CREATE INDEX backlog_tsv_filtered_idx
ON public.backlog
USING gin(tsv)
WHERE (type & 23559) > 0;
```
Third, set up a trigger to populate the `tsv` column:
```sql
CREATE TRIGGER tsvectorupdate
BEFORE INSERT OR UPDATE
ON public.backlog
FOR EACH ROW
EXECUTE PROCEDURE tsvector_update_trigger('tsv', 'pg_catalog.english', 'message');
```
Fourth, populate the `tsv` column:
```sql
UPDATE public.backlog SET public.backlog.messageid = public.backlog.messageid;
```
Setting up the search
---------------------
First, rename the file `qrs_config.default.php` to `qrs_config.php`.
Then configure the database access, backend (currently only `pgsql-smart` is available), and the prefix of the path.
License and Credits
-------------------
The error image is from [xiprox/ErrorView](https://github.com/xiprox/ErrorView) and under Apache2. The error image is from [xiprox/ErrorView](https://github.com/xiprox/ErrorView) and under Apache2.
This project uses the "Material Icons" font from Google, available under Apache2.
The rest of this project is available under LGPLv2.1 or later. The rest of this project is available under LGPLv2.1 or later.
<?php
namespace QuasselRestSearch;
require_once '../../qrs_config.php';
require_once '../../backend/Database.php';
require_once '../../backend/helper/RendererHelper.php';
require_once '../../backend/helper/SessionHelper.php';
$config = Config::createFromGlobals();
$renderer = new RendererHelper($config);
$backend = Backend::createFromConfig($config);
try {
$backend->authenticateFromHeader($_SERVER['HTTP_AUTHORIZATION'] ?: "");
$renderer->renderJson($backend->context($_GET['anchor'] ?: 0, $_GET['buffer'] ?: 0, $_GET['before'], $_GET['after']));
} catch (\Exception $e) {
$renderer->renderError($e);
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once '../../qrs_config.php';
require_once '../../backend/Database.php';
require_once '../../backend/helper/RendererHelper.php';
require_once '../../backend/helper/SessionHelper.php';
$config = Config::createFromGlobals();
$renderer = new RendererHelper($config);
$backend = Backend::createFromConfig($config);
try {
$backend->authenticateFromHeader($_SERVER['HTTP_AUTHORIZATION'] ?: "");
$renderer->renderJson($backend->findBuffers($_GET['q'] ?: ""));
} catch (\Exception $e) {
$renderer->renderError($e);
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once '../../qrs_config.php';
require_once '../../backend/Database.php';
require_once '../../backend/helper/RendererHelper.php';
require_once '../../backend/helper/SessionHelper.php';
$config = Config::createFromGlobals();
$renderer = new RendererHelper($config);
$backend = Backend::createFromConfig($config);
try {
$backend->authenticateFromHeader($_SERVER['HTTP_AUTHORIZATION'] ?: "");
$renderer->renderJson($backend->findInBuffer($_GET['q'] ?: "", $_GET['buffer'] ?: 0, $_GET['offset'] ?: 0));
} catch (\Exception $e) {
$renderer->renderError($e);
}
\ No newline at end of file
<?php
//
// Quassel Backlog Search - classes
// developed 2009 by m4yer <m4yer@minad.de> under a Creative Commons Licence by-nc-sa 3.0
//
// password hashing improvements developed 2015 by mamarley
//
function initialAuthenticateUser($plainPassword,$dbHashedPassword,$hashVersion){
switch($hashVersion){
case null:
case 0:
return initialCheckHashedPasswordSha1($plainPassword,$dbHashedPassword);
break;
case 1:
return initialCheckHashedPasswordSha2_512($plainPassword,$dbHashedPassword);
break;
default:
return false;
break;
}
}
function initialCheckHashedPasswordSha1($plainPassword,$dbHashedPassword){
$calculatedPasswordHash=hash("sha1",$plainPassword);
if($calculatedPasswordHash==$dbHashedPassword){
return $calculatedPasswordHash;
}
return false;
}
function initialCheckHashedPasswordSha2_512($plainPassword,$dbHashedPassword){
$dbHashedPasswordArray=explode(":",$dbHashedPassword);
if(count($dbHashedPasswordArray)==2){
$calculatedPasswordHash=hash("sha512",$plainPassword . $dbHashedPasswordArray[1]);
if($calculatedPasswordHash==$dbHashedPasswordArray[0]){
return $dbHashedPasswordArray[0];
}
}
return false;
}
?>
\ No newline at end of file
<?php
require_once('auth_functions.php');
class Backend {
private $dbh;
private $user;
public function connect($configfile) {
$config = parse_ini_file($configfile);
if ($config['local']) {
$this->dbh = new PDO('pgsql:dbname='.$config['dbname'].' user='.$config['user'].' password='.$config['password']);
} else {
$this->dbh = new PDO('pgsql:host='.$config['host'].' port='.$config['port'].' dbname='.$config['dbname'].' user='.$config['user'].' password='.$config['password']);
}
}
public function auth($username, $password) {
if (!isset($username) || !isset($password))
return false;
$stmt = $this->dbh->prepare("SELECT * FROM quasseluser WHERE username = ?");
$stmt->execute(array($_POST['username']));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($rows) !== 1)
return false;
$row = $rows[0];
if (!initialAuthenticateUser($_POST['password'], $row['password'], $row['hashversion']))
return false;
$this->user = array(
'id' => $row['userid'],
'name' => $row['username']
);
return true;
}
public function find_buffers($arg_query, $arg_limit, $arg_offset) {
$sql = "SELECT DISTINCT backlog.bufferid FROM backlog JOIN buffer ON backlog.bufferid = buffer.bufferid, to_tsquery('simple', ?) query WHERE type = 1 AND buffer.userid = ? AND to_tsvector('simple', message) @@ query LIMIT ? OFFSET ?;";
$stmt = $this->dbh->prepare($sql);
$limit = max(min($arg_limit, 20), 5);
$offset = max(0, $arg_offset);
$stmt->execute(array($arg_query, $this->user['id'], $limit, $offset));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function search($arg_query, $arg_limit, $arg_offset, $arg_limit_each) {
$buffers = $this->find_buffers($arg_query, $arg_limit, $arg_offset);
$data = array();
foreach ($buffers as $buffer) {
$data = array_merge($data, $this->search_buffer($arg_query, $buffer['bufferid'], 4, 0));
}
return $data;
}
public function search_buffer($arg_query, $arg_buffer, $arg_limit, $arg_offset) {
$sql = "SELECT backlog.messageid, backlog.bufferid, buffer.buffername, sender.sender, backlog.\"time\", network.networkname, ts_headline(backlog.message, query) AS message FROM backlog JOIN sender ON backlog.senderid = sender.senderid JOIN buffer ON backlog.bufferid = buffer.bufferid JOIN network ON buffer.networkid = network.networkid, to_tsquery('simple', ?) query WHERE type = 1 AND buffer.userid = ? AND backlog.bufferid = ? AND to_tsvector('simple', message) @@ query ORDER BY messageid DESC LIMIT ? OFFSET ?;";
$stmt = $this->dbh->prepare($sql);
$limit = max(min($arg_limit, 50), 1);
$offset = max(0, $arg_offset);
$stmt->execute(array($arg_query, $this->user['id'], $arg_buffer, $limit, $offset));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function after($arg_id, $arg_buffer, $arg_limit) {
$sql = "SELECT backlog.messageid, backlog.bufferid, buffer.buffername, sender.sender, backlog.\"time\", network.networkname, backlog.message FROM backlog JOIN sender ON backlog.senderid = sender.senderid JOIN buffer ON backlog.bufferid = buffer.bufferid JOIN network ON buffer.networkid = network.networkid WHERE buffer.userid = ? AND backlog.bufferid = ? AND messageid >= ? ORDER BY messageid ASC LIMIT ?;";
$stmt = $this->dbh->prepare($sql);
$limit = max(min($arg_limit+1, 50), 1);
$stmt->execute(array($this->user['id'], $arg_buffer, $arg_id, $limit));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function before($arg_id, $arg_buffer, $arg_limit) {
$sql = "SELECT backlog.messageid, backlog.bufferid, buffer.buffername, sender.sender, backlog.\"time\", network.networkname, backlog.message FROM backlog JOIN sender ON backlog.senderid = sender.senderid JOIN buffer ON backlog.bufferid = buffer.bufferid JOIN network ON buffer.networkid = network.networkid WHERE buffer.userid = ? AND backlog.bufferid = ? AND messageid < ? ORDER BY messageid DESC LIMIT ?;";
$stmt = $this->dbh->prepare($sql);
$limit = max(min($arg_limit, 50), 0);
$stmt->execute(array($this->user['id'], $arg_buffer, $arg_id, $limit));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function context($arg_id, $arg_buffer, $arg_before, $arg_after) {
return array_merge(array_reverse($this->before($arg_id, $arg_buffer, $arg_before)), $this->after($arg_id, $arg_buffer, $arg_after));
}
}
?>
\ No newline at end of file
<?php
namespace QuasselRestSearch;
class Config {
public $database_connector;
public $username;
public $password;
public $page_prefix;
public function __construct(string $page_prefix, string $database_connector, string $username, string $password) {
$this->database_connector = $database_connector;
$this->username = $username;
$this->password = $password;
$this->page_prefix = $page_prefix;
}
public static function createFromGlobals() {
return new Config(page_prefix, 'pgsql:host=' . db_host . ';port=' . db_port . ';dbname=' . db_name . '', db_user, db_pass);
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once 'User.php';
require_once 'Config.php';
require_once 'helper/AuthHelper.php';
class Backend {
private $storedFindBuffers;
private $storedFindInBuffer;
private $loadBefore;
private $loadAfter;
private $findUser;
private $user;
private function __construct(string $database_connector, string $username, string $password) {
$db = new \PDO($database_connector, $username, $password);
$this->storedFindBuffers = $db->prepare("
SELECT backlog.bufferid,
buffer.buffername,
network.networkname
FROM backlog
JOIN buffer ON backlog.bufferid = buffer.bufferid
JOIN network ON buffer.networkid = network.networkid,
plainto_tsquery('english'::REGCONFIG, :query) query
WHERE (backlog.type & 23559) > 0
AND buffer.userid = :userid
AND backlog.tsv @@ query
GROUP BY backlog.bufferid,
buffer.buffername,
network.networkname
ORDER BY MIN((1 + log(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - TIME)))) * (1 - ts_rank(tsv, query, 32)) * (1 + ln(backlog.type))) ASC;
");
$this->storedFindInBufferMultiple = $db->prepare("
SELECT tmp.bufferid,
tmp.messageid,
sender.sender,
tmp.time,
tmp.message,
ts_headline(replace(replace(tmp.message, '<', '&lt;'), '>', '&gt;'), query) AS preview
FROM
(SELECT backlog.messageid,
backlog.bufferid,
backlog.senderid,
backlog.time,
backlog.message,
query,
rank() OVER(PARTITION BY backlog.bufferid
ORDER BY (1 + log(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - TIME)))) * (1 - ts_rank(tsv, query, 32)) * (1 + ln(backlog.type)) ASC
) AS rank
FROM backlog
JOIN buffer ON backlog.bufferid = buffer.bufferid,
plainto_tsquery('english'::REGCONFIG, :query) query
WHERE (backlog.type & 23559) > 0
AND buffer.userid = :userid
AND backlog.tsv @@ query
ORDER BY (1 + log(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - TIME)))) * (1 - ts_rank(tsv, query, 32)) * (1 + ln(backlog.type)) ASC
) tmp
JOIN sender ON tmp.senderid = sender.senderid
WHERE tmp.rank <= :limit;
");
$this->storedFindInBuffer = $db->prepare("
SELECT backlog.messageid,
sender.sender,
backlog.time,
backlog.message,
ts_headline(replace(replace(backlog.message, '<', '&lt;'), '>', '&gt;'), query) AS preview
FROM backlog
JOIN sender ON backlog.senderid = sender.senderid
JOIN buffer ON backlog.bufferid = buffer.bufferid,
plainto_tsquery('english'::REGCONFIG, :query) query
WHERE (backlog.type & 23559) > 0
AND buffer.userid = :userid
AND backlog.bufferid = :bufferid
AND backlog.tsv @@ query
ORDER BY (1 + log(EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - TIME)))) * (1 - ts_rank(tsv, query, 32)) * ( 1 + ln(backlog.type)) ASC
LIMIT :limit OFFSET :offset;
");
$this->loadAfter = $db->prepare("
SELECT backlog.messageid,
backlog.bufferid,
buffer.buffername,
sender.sender,
backlog.time,
network.networkname,
backlog.message
FROM backlog
JOIN sender ON backlog.senderid = sender.senderid
JOIN buffer ON backlog.bufferid = buffer.bufferid
JOIN network ON buffer.networkid = network.networkid
WHERE buffer.userid = :userid
AND backlog.bufferid = :bufferid
AND backlog.messageid >= :anchor
ORDER BY backlog.messageid ASC
LIMIT :limit;
");
$this->loadBefore = $db->prepare("
SELECT backlog.messageid,
backlog.bufferid,
buffer.buffername,
sender.sender,
backlog.time,
network.networkname,
backlog.message
FROM backlog
JOIN sender ON backlog.senderid = sender.senderid
JOIN buffer ON backlog.bufferid = buffer.bufferid
JOIN network ON buffer.networkid = network.networkid
WHERE buffer.userid = :userid
AND backlog.bufferid = :bufferid
AND backlog.messageid < :anchor
ORDER BY backlog.messageid DESC
LIMIT :limit;
");
$this->findUser = $db->prepare("
SELECT *
FROM quasseluser
WHERE quasseluser.username = :username
");
}
public static function createFromOptions(string $database_connector, string $username, string $password) : Backend {
return new Backend($database_connector, $username, $password);
}
public static function createFromConfig(Config $config) : Backend {
return new Backend($config->database_connector, $config->username, $config->password);
}
public function authenticateFromHeader(string $header) : bool {
$parsedHeader = AuthHelper::parseAuthHeader($header);
return $this->authenticate($parsedHeader['username'], $parsedHeader['password']);
}
public function authenticate(string $username, string $password) : bool {
if (!isset($username) || !isset($password))
return false;
$this->findUser->bindParam(":username", $username);
$this->findUser->execute();
$result = $this->findUser->fetch(\PDO::FETCH_ASSOC);
if ($result === FALSE)
return false;
$user = new User($result);
if (!AuthHelper::initialAuthenticateUser($password, $user->password, $user->hashversion))
return false;
$this->user = $user;
return true;
}
public function find(string $query, int $limitPerBuffer = 4) : array {
$truncatedLimit = max(min($limitPerBuffer, 10), 0);
$buffers = $this->findBuffers($query);
$messages = $this->findInBufferMultiple($query, $truncatedLimit);
$buffermap = [];
foreach ($buffers as &$buffer) {
$buffermap[$buffer['bufferid']] = &$buffer;
$buffermap[$buffer['bufferid']]['messages'] = [];
}
foreach ($messages as $message) {
$buffer = $buffermap[$message['bufferid']];
$messages1 = $buffer['messages'];
array_push($messages1, $message);
$buffer['messages'] = $messages1;
$buffermap[$buffer['bufferid']] = $buffer;
}
return array_values($buffermap);
}
public function findBuffers(string $query) : array {
$this->storedFindBuffers->bindParam(':userid', $this->user->userid);
$this->storedFindBuffers->bindParam(':query', $query);
$this->storedFindBuffers->execute();
return $this->storedFindBuffers->fetchAll(\PDO::FETCH_ASSOC);
}
public function findInBufferMultiple(string $query, int $limit = 4) : array {
$this->storedFindInBufferMultiple->bindParam(':userid', $this->user->userid);
$this->storedFindInBufferMultiple->bindParam(':query', $query);
$this->storedFindInBufferMultiple->bindParam(':limit', $limit);
$this->storedFindInBufferMultiple->execute();
return $this->storedFindInBufferMultiple->fetchAll(\PDO::FETCH_ASSOC);
}
public function findInBuffer(string $query, int $bufferid, int $offset = 0, int $limit = 20) : array {
$truncatedLimit = max(min($limit, 50), 0);
$this->storedFindInBuffer->bindParam(':userid', $this->user->userid);
$this->storedFindInBuffer->bindParam(':bufferid', $bufferid);
$this->storedFindInBuffer->bindParam(':query', $query);
$this->storedFindInBuffer->bindParam(':limit', $truncatedLimit);
$this->storedFindInBuffer->bindParam(':offset', $offset);
$this->storedFindInBuffer->execute();
return $this->storedFindInBuffer->fetchAll(\PDO::FETCH_ASSOC);
}
public function context(int $anchor, int $buffer, int $loadBefore, int $loadAfter) : array {
return array_merge(array_reverse($this->before($anchor, $buffer, $loadBefore)), $this->after($anchor, $buffer, $loadAfter));
}
public function before(int $anchor, int $buffer, int $limit) : array {
$truncatedLimit = max(min($limit, 50), 0);
$this->loadBefore->bindParam(":userid", $this->user->userid);
$this->loadBefore->bindParam(":bufferid", $buffer);
$this->loadBefore->bindParam(":anchor", $anchor);
$this->loadBefore->bindParam(":limit", $truncatedLimit);
$this->loadBefore->execute();
return $this->loadBefore->fetchAll(\PDO::FETCH_ASSOC);
}
public function after(int $anchor, int $buffer, int $limit) : array {
$truncatedLimit = max(min($limit + 1, 50), 1);
$this->loadAfter->bindParam(":userid", $this->user->userid);
$this->loadAfter->bindParam(":bufferid", $buffer);
$this->loadAfter->bindParam(":anchor", $anchor);
$this->loadAfter->bindParam(":limit", $truncatedLimit);
$this->loadAfter->execute();
return $this->loadAfter->fetchAll(\PDO::FETCH_ASSOC);
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
class User {
public $userid;
public $username;
public $password;
public $hashversion;
public function __construct(array $userArray) {
$this->userid = $userArray['userid'];
$this->username = $userArray['username'];
$this->password = $userArray['password'];
$this->hashversion = $userArray['hashversion'];
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
class AuthHelper {
public static function initialAuthenticateUser($plainPassword, $dbHashedPassword, $hashVersion) {
switch ($hashVersion) {
case null:
case 0:
return AuthHelper::initialCheckHashedPasswordSha1($plainPassword, $dbHashedPassword);
break;
case 1:
return AuthHelper::initialCheckHashedPasswordSha2_512($plainPassword, $dbHashedPassword);
break;
default:
return false;
break;
}
}
public static function initialCheckHashedPasswordSha1($plainPassword, $dbHashedPassword) {
$calculatedPasswordHash = hash("sha1", $plainPassword);
if ($calculatedPasswordHash == $dbHashedPassword) {
return $calculatedPasswordHash;
}
return false;
}
public static function initialCheckHashedPasswordSha2_512($plainPassword, $dbHashedPassword) {
$dbHashedPasswordArray = explode(":", $dbHashedPassword);
if (count($dbHashedPasswordArray) == 2) {
$calculatedPasswordHash = hash("sha512", $plainPassword . $dbHashedPasswordArray[1]);
if ($calculatedPasswordHash == $dbHashedPasswordArray[0]) {
return $dbHashedPasswordArray[0];
}
}
return false;
}
public static function parseAuthHeader($authHeader) : array {
$arr = explode(':', base64_decode($authHeader));
if (count($arr) != 2) {
throw new \Exception("Can’t parse authentication header");
} else {
return [
'username' => base64_decode($arr[0]),
'password' => base64_decode($arr[1])
];
}
}
public static function generateAuthHeader(string $password, string $username) : string {
return base64_encode(base64_encode($username) . ":" . base64_encode($password));
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once 'ViewHelper.php';
class RendererHelper {
private $config;
public function __construct(Config $config) {
$this->config = $config;
}
public function renderError($e) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
header('Status: 403 Forbidden');
echo 'Error 403: Forbidden' . "\n";
echo $e . "\n";
}
public function renderJsonError($json) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
header('Status: 403 Forbidden');
echo 'Error 403: Forbidden' . "\n";
header('Content-Type: application/json');
echo json_encode($json) . "\n";
}
public function renderJson($json) {
header('Content-Type: application/json');
echo json_encode($json) . "\n";
}
public function renderPage(string $template, array $vars = null) {
$viewHelper = new ViewHelper($vars);
$viewHelper->render($template);
}
public function redirect(string $page, string $flash = null) {
header('Location: ' . $this->config->page_prefix . $page);
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
class SessionHelper {
const SESSION_STARTED = TRUE;
const SESSION_NOT_STARTED = FALSE;
private static $instance;
private $sessionState = self::SESSION_NOT_STARTED;
private function __construct() {
}
public static function getInstance() : SessionHelper {
if (!isset(self::$instance)) {
self::$instance = new self;
}
self::$instance->startSession();
return self::$instance;
}
public function startSession() : bool {
if ($this->sessionState == self::SESSION_NOT_STARTED) {
$this->sessionState = session_start();
}
return $this->sessionState;
}
public function __get(string $name) {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return null;
}
}
public function __set(string $name, $value) {
$_SESSION[$name] = $value;
}
public function __isset(string $name) : bool {
return isset($_SESSION[$name]);
}
public function __unset(string $name) {
unset($_SESSION[$name]);
}
public function destroy() : bool {
if ($this->sessionState == self::SESSION_STARTED) {
$this->sessionState = !session_destroy();
unset($_SESSION);
return !$this->sessionState;
}
return !$this->sessionState;
}
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
class ViewHelper {
protected $template_dir;
protected $vars = [];
public function __construct($vars = null) {
$this->setPath('../../templates/');
if ($vars !== null) {
$this->vars = $vars;
}
}
public function setPath(string $path) {
$this->template_dir = realpath(dirname(__FILE__) . '/' . $path);
}
public function render($template_file) {
$path = $this->template_dir . '/' . $template_file . '.phtml';
if (file_exists($path)) {
include $path;
} else {
throw new \Exception('Template ' . $path . ' not found ');
}
}
public function __get($name) {
return $this->vars[$name];
}
public function __set($name, $value) {
$this->vars[$name] = $value;
}
}
\ No newline at end of file
local=false
dbname=quassel
user=quassel
password=supersecurepassword
host=example.org
port=5436
<?php
require_once('backend.php');
$backend = new Backend();
$backend->connect('config.ini');
if (!$backend->auth($_POST['username'], $_POST['password'])) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
header('Status: 403 Forbidden');
exit;
}
header('Content-Type: application/json');
echo json_encode($backend->context(intval($_GET['msg']),intval($_GET['buffer']),intval($_GET['before']),intval($_GET['after'])))."\n";
?>
\ No newline at end of file
<!DOCTYPE html>
<meta charset="utf-8">
<title>Quassel Search</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<nav>
<div id="searchbar">
<input type="text" name="q" id="q" placeholder="Search">
<div id="searchicon" class="icon">search</div>
</div>
</nav>
<section id="results">
<button id="login">Login</button> <button id="logout">Logout</button>
</section>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="script.js"></script>
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once 'qrs_config.php';
require_once 'backend/Database.php';
require_once 'backend/helper/RendererHelper.php';
require_once 'backend/helper/SessionHelper.php';
$session = SessionHelper::getInstance();
$config = Config::createFromGlobals();
$renderer = new RendererHelper($config);
$backend = Backend::createFromConfig($config);
if (!$backend->authenticate($session->username ?: '', $session->password ?: '')) {
$session->destroy();
$renderer->redirect('/login.php');
} else {
$renderer->renderPage('search', ['username' => $session->username]);
}
\ No newline at end of file
<?php
namespace QuasselRestSearch;
require_once 'qrs_config.php';
require_once 'backend/Database.php';
require_once 'backend/helper/RendererHelper.php';
require_once 'backend/helper/SessionHelper.php';
$session = SessionHelper::getInstance();
$config = Config::createFromGlobals();
$renderer = new RendererHelper($config);
$backend = Backend::createFromConfig($config);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_GET['action'] === 'login') {
$username = $_POST['username'] ?: '';
$password = $_POST['password'] ?: '';
if ($backend->authenticate($username, $password)) {
$session->username = $username;
$session->password = $password;
$renderer->redirect('/');
}
} elseif ($_GET['action'] === 'logout') {
$session->destroy();
$renderer->redirect('/login.php');
} else if ($backend->authenticate($session->username ?: '', $session->password ?: '')) {
$renderer->redirect('/');
} else {
$renderer->renderPage('login');
}
\ No newline at end of file
<?php
define('db_host', 'example.com');
define('db_port', 5432);
define('db_name', 'quassel');
define('db_user', 'quassel');
define('db_pass', 'password');
define('backend', 'pgsql-smart');
define('path_prefix', '/');
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment