Initial import

This commit is contained in:
Latif Khalifa
2013-10-03 07:31:47 +02:00
parent 9d83e533c0
commit d54d4c277a
29 changed files with 2258 additions and 1 deletions

1
htdocs/.htaccess Normal file
View File

@@ -0,0 +1 @@
php_flag display_errors on

59
htdocs/account.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
if ($S->isAnonymous())
{
$S->loginRedirect();
}
$user = $S->user;
if (isset($_POST["user_id"]))
{
$user->name = $_POST["name"];
$msg = $user->update() ? "Information updated" : "Update failed";
http::redirect("/account.php?msg=" . urlencode($msg));
}
Layout::header();
?>
<h3>Account Details</h3>
<?php if (isset($_GET["msg"])): ?>
<strong><?php echo htmlentities($_GET["msg"]); ?></strong>
<?php endif ?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="user_id" value="<?php echo (int)$user->user_id; ?>" />
<table>
<tr>
<td>Name</td>
<td><input type="text" name="name" size="30" value="<?php echo htmlentities($user->name); ?>" />&nbsp;<input type="submit" name="save_name" value="Save" /></td>
</tr>
<tr>
<td>Email</td>
<td><?php echo htmlentities($user->email); ?></td>
</tr>
<tr>
<td>Access Granted</td>
<td><?php echo $user->isAllowed() ? "yes" : "no" ?></td>
</tr>
<tr>
<td>Admin Privileges</td>
<td><?php echo $user->isAdmin() ? "yes" : "no" ?></td>
</tr>
</table>
</form>
<?php
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

23
htdocs/crashes.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$S->requireUser();
Layout::header();
?>
<strong>Not implemented</strong>
<?php
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

BIN
htdocs/images/body-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

BIN
htdocs/images/dl.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

BIN
htdocs/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

38
htdocs/index.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
Layout::header();
?>
<p>This application is used for analyzing crash reports and statitstics for the Singularity
Viewer project.</p>
<p>Access to this tool is granted to the members of the development team.
The main goal is to identify the most common problems and improve the expierience
for the users of Singularity Viewer.</p>
<?php
if (!$S->isAnonymous())
{
if ($S->user->isAllowed())
{
print '<p><strong>Your account has been granted access.</strong></p>';
}
else
{
print '<p><strong>Your account has no access to the system at this time.</strong></p>';
}
}
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

1
htdocs/lib/.htaccess Normal file
View File

@@ -0,0 +1 @@
deny from all

185
htdocs/lib/DBH.php Normal file
View File

@@ -0,0 +1,185 @@
<?php
/* $Id$ */
class DBH
{
public
$db_name,
$db_pass,
$db_user,
$db_host,
$dbh,
$last_error = "";
function log($line)
{
static $f = false;
static $failed = false;
if ($failed) {
return false;
}
if (!$f) {
$f = @fopen(SITE_ROOT.'/lib/logs/sql.log', 'a');
}
if (!$f) {
$failed = true;
return false;
}
@fwrite($f, "[".date('Y-m-d H:i')."] ".$line."\n");
}
function connect($db_name, $db_host, $db_user, $db_pass)
{
$this->db_name = $db_name;
$this->db_pass = $db_pass;
$this->db_user = $db_user;
$this->db_host = $db_host;
$this->dbh = @mysql_connect($db_host, $db_user, $db_pass);
if (!$this->dbh) {
DBH::log("[error] connection to database failed");
DBH::log("[error] connection string used '$conn_str'");
return false;
}
if (!mysql_select_db($db_name)) {
DBH::log("[error] database {$db_name} dose not exist");
return false;
}
$this->query("SET SQL_MODE='TRADITIONAL'");
$this->query("SET NAMES 'utf8'");
return true;
}
function query($q)
{
$res = @mysql_query($q, $this->dbh);
if (!$res) {
DBH::log("[error] ".$q);
DBH::log("[error_msg] " . mysql_error($this->dbh));
$this->last_error = mysql_error($this->dbh);
$e = debug_backtrace();
$c = count($e);
$btr = "";
for ($i=0; $i<$c; $i++) {
$btr .= "{$e[$i]['class']}::{$e[$i]['function']} {$e[$i]['file']}({$e[$i]['line']})\n";
}
DBH::log("[backtrace]\n".$btr);
return false;
} else {
if ($res !== TRUE) {
$result_id = (int)$res;
if (!isset($this->field_desc[$result_id])) {
$nf = mysql_num_fields($res);
for ($i=0; $i<$nf; $i++) {
$this->field_desc[$result_id][mysql_field_name($res, $i)] = mysql_field_type($res, $i);
}
}
}
DBH::log("[success] ".$q);
return $res;
}
}
function loadFromDbRow(&$obj, $res, $row)
{
foreach ($row as $symbolicName => $nativeName){
if ($nativeName && ($this->field_desc[(int)$res][$symbolicName] == "timestamp" ||
$this->field_desc[(int)$res][$symbolicName] == "date" ||
$this->field_desc[(int)$res][$symbolicName] == "datetime")) {
$obj->{$symbolicName} = strtotime($nativeName);
} else {
$obj->{$symbolicName} = $nativeName;
}
}
return true;
}
function insertID()
{
return @mysql_insert_id($this->dbh);
}
function numRows($res)
{
return @mysql_num_rows($res);
}
function affectedRows()
{
return @mysql_affected_rows($this->dbh);
}
function fieldName($res, $num)
{
return @mysql_field_name($res, $num);
}
function numFields($res)
{
return @mysql_num_fields($res);
}
function fetchRow($res)
{
return @mysql_fetch_assoc($res);
}
function begin()
{
return $this->query('begin');
}
function rollback()
{
return $this->query('rollback');
}
function commit()
{
return $this->query('commit');
}
/* FIXME: port from postgres */
function nextId($seq)
{
$res = $this->query("select nextval('$seq') as n");
if (!$res || !$row = $this->fetchRow($res)) {
return false;
} else {
return (int)$row['n'];
}
}
/* Date time conversion */
function db2unix($s)
{
return strtotime($s);
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

478
htdocs/lib/GoogleOpenID.php Normal file
View File

@@ -0,0 +1,478 @@
<?php
/****************************************************************************
* The GoogleOpenID class
*
* This class implements a gateway to the Google OpenID federated login API
*
* By Andrew Peace (http://www.andrewpeace.com)
* December 6, 2008
* Contact me at http://www.andrewpeace.com/contact.html
*
*
* Usage:
*
* To redirect users to a Google login page, simply create a GoogleOpenID:
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/check.php",
* "ABCDEFG",
* true);
*
* The first argument is the URL you want Google to redirect to when it sends
* its response
*
* The second argument is the association handle you've obtained from Google.
* This parameter is OPTIONAL and can be set to null. However, if it is not
* given or it is set to null, GoogleOpenID will automatically request an
* association handle when it is constructed. This is wastefull! Association
* handles last for two weeks. So, it is better to get and save an association
* handle on your own using GoogleOpenID::getAssociationHandle().
*
* The third argument should be set to true if you want the response to include
* the user's email address. It is optional.
*
* Example:
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/checkauth.php", "ABCDEFG", true);
* $googleGateway->redirect();
*
* OR
*
* $handle = GoogleOpenID::getAssociationHandle(); // <--save this! valid for two weeks!
*
* $googleGateway = GoogleOpenID::createRequest("http://www.mydomain.com/checkauth.php", $handle, true);
* $googleGateway->redirect();
*
*
* When you want to recieve a Google OpenID response, simply pass the given
* parameters to GoogleOpenID::create(). In most cases, you should just be able
* to pass the $_GET variable.
*
* To continue the previous example, the following code would go in checkauth.php
*
* $googleResponse = GoogleOpenID::create($_GET);
* $sucess = $googleResponse->success();//true or false
* $user_identity = $googleResponse->identity();//the user's ID
* $user_email = $googleResponse->email();//the user's email
*
* OR, even easier
*
* $googleResponse = GoogleOpenID::getResponse(); // <-- automatically reads $_GET
*
* Advanced users can create a slightly more customized request using the create
* method. It accepts an associative array of openid parameters and sets those
* that it deems appropriate to set (mostly, the parameters that don't have a
* definite value when interacting with Google)
*
*
* Full class signature:
*
* public static createRequest(String, [String], [Boolean])
* public static getResponse()
* public static create(Array)
* public static getAssociationHandle([String])
* public static getEndPoint()
* public redirect()
* public getArray()
* public endPoint()
* public success()
* public assoc_handle()
* public email()
* public identity()
*
* Features to implement:
*
* -In constructor, fix relative->absolute URL conversion (it is messy/buggy)
* -In getAssociationHandle(), use encryption
* -Verify Google's response with signed, sig etc
****************************************************************************/
class GoogleOpenID{
//the google discover url
const google_discover_url = "https://www.google.com/accounts/o8/id";
//some constant parameters
const openid_ns = "http://specs.openid.net/auth/2.0";
//required for email attribute exchange
const openid_ns_ext1 = "http://openid.net/srv/ax/1.0";
const openid_ext1_mode = "fetch_request";
const openid_ext1_type_email = "http://schema.openid.net/contact/email";
const openid_ext1_required = "email";
//parameters set by constructor
private $mode;//the mode (checkid_setup, id_res, or cancel)
private $response_nonce;
private $return_to;//return URL
private $realm;//the realm that the user is being asked to trust
private $assoc_handle;//the association handle between this service and Google
private $claimed_id;//the id claimed by the user
private $identity;//for google, this is the same as claimed_id
private $signed;
private $sig;
private $email;//the user's email address
//if true, fetch email address
private $require_email;
//private constructor
private function GoogleOpenID($mode, $op_endpoint, $response_nonce, $return_to, $realm, $assoc_handle, $claimed_id, $signed, $sig, $email, $require_email){
//if assoc_handle is null, fetch one
if(is_null($assoc_handle))
$assoc_handle = GoogleOpenID::getAssociationHandle();
//if return_to is a relative URL, make it absolute
if(stripos($return_to, "http://")!==0 &&
stripos($return_to, "https://")!==0){
//if the first character is a slash, delete it
if(substr($return_to, 0, 1)=="/")
$return_to = substr($return_to, 1);
//get the position of server_name
$server_name_pos = stripos($return_to, $_SERVER['SERVER_NAME']);
//if server_name is already at position zero
if($server_name_pos != false && $server_name_pos==0){
$return_to = "http://".$return_to;
} else {
$return_to = "http://".$_SERVER['SERVER_NAME']."/".$return_to;
}//else (server name not at position zero)
}//if return_to is relative
//if realm is null, attempt to set it via return_to
if(is_null($realm)){
//if return_to is set
if(!is_null($return_to)){
$pieces = parse_url($return_to);
$realm = $pieces['scheme']."://".$pieces['host'];
}//if return_to set
}//if realm null
$this->mode = $mode;
$this->op_endpoint = $op_endpoint;
$this->response_nonce = $response_nonce;
$this->return_to = $return_to;
$this->realm = $realm;
$this->assoc_handle = $assoc_handle;
$this->claimed_id = $claimed_id;
$this->identity = $claimed_id;
$this->signed = $signed;
$this->sig = $sig;
$this->email = $email;
$this->require_email = ($require_email) ? true : false;
}//GoogleOpenID
//static creator that accepts only a return_to URL
//this creator should be used when creating a GoogleOpenID for a redirect
public static function createRequest($return_to, $assoc_handle=null, $require_email=false){
return new GoogleOpenID("checkid_setup", null, null, $return_to, null, $assoc_handle, "http://specs.openid.net/auth/2.0/identifier_select", null, null, null, $require_email);
}//createRequest
//static creator that accepts an associative array of parameters and
//sets only the setable attributes (does not overwrite constants)
public static function create($params){
//loop through each parameter
foreach($params as $param => $value){
switch($param){
case "openid_mode":
//check validity of mode
if($value=="checkid_setup" ||
$value=="id_res" ||
$value=="cancel")
$mode = $value;
else
$mode = "cancel";
continue 2;
case "openid_op_endpoint":
$op_endpoint = $value;
continue 2;
case "openid_response_nonce":
$response_nonce = $value;
continue 2;
case "openid_return_to":
$return_to = $value;
continue 2;
case "openid_realm":
$realm = $value;
continue 2;
case "openid_assoc_handle":
$assoc_handle = $value;
continue 2;
case "openid_claimed_id":
$claimed_id = $value;
continue 2;
case "openid_identity":
$claimed_id = $value;
continue 2;
case "openid_signed":
$signed = $value;
continue 2;
case "openid_sig":
$sig = $value;
continue 2;
case "openid_ext1_value_email":
$email = $value;
continue 2;
case "require_email":
$require_email = $value;
continue 2;
default:
continue 2;
}//switch param
}//loop through params
//if require email is not set, set it to false
if(!is_bool($require_email))
$require_email = false;
//if mode is not set, set to default for redirection
if(is_null($mode))
$mode = "checkid_setup";
//if return_to is not set and mode is checkid_setup, throw an error
if(is_null($return_to) && $mode=="checkid_setup")
throw new Exception("GoogleOpenID.create() needs parameter openid.return_to");
//return a new GoogleOpenID with the given parameters
return new GoogleOpenID($mode, $op_endpoint, $response_nonce, $return_to, $realm, $assoc_handle, $claimed_id, $signed, $sig, $email, $require_email);
}//create
//creates and returns a GoogleOpenID from the $_GET variable
public static function getResponse(){
return GoogleOpenID::create($_GET);
}//getResponse
//fetches an association handle from google. association handles are valid
//for two weeks, so coders should do their best to save association handles
//externally and pass them to createRequest()
//NOTE: This function does not use encryption, but it SHOULD! At the time
//I wrote this I wanted it done fast, and I couldn't seem to find a good
//two-way SHA-1 or SHA-256 library for PHP. Encryption is not my thing, so
//it remains unimplemented.
public static function getAssociationHandle($endpoint=null){
//if no endpoint given
if(is_null($endpoint))
//fetch one from Google
$request_url = GoogleOpenID::getEndPoint();
//if endpoint given, set it
else
$request_url = $endpoint;
//append parameters (these never change)
$request_url .= "?openid.ns=".urlencode(GoogleOpenID::openid_ns);
$request_url .= "&openid.mode=associate";
$request_url .= "&openid.assoc_type=HMAC-SHA1";
$request_url .= "&openid.session_type=no-encryption";
//create a CURL session with the request URL
$c = curl_init($request_url);
//set a few options
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
//get the contents of request URL
$request_contents = curl_exec($c);
//close the CURL session
curl_close($c);
//a handle to be returned
$assoc_handle = null;
//split the response into lines
$lines = explode("\n", $request_contents);
//loop through each line
foreach($lines as $line){
//if this line is assoc_handle
if(substr($line, 0, 13)=="assoc_handle:"){
//save the assoc handle
$assoc_handle = substr($line, 13);
//exit the loop
break;
}//if this line is assoc_handle
}//loop through lines
//return the handle
return $assoc_handle;
}//getAssociationHandle
//fetches an endpoint from Google
public static function getEndPoint(){
//fetch the request URL
$request_url = GoogleOpenID::google_discover_url;
//create a CURL session with the request URL
$c = curl_init($request_url);
//set a few options
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
//fetch the contents of the request URL
$request_contents = curl_exec($c);
//close the CURL session
curl_close($c);
//create a DOM document so we can extract the URI element
$domdoc = new DOMDocument();
$domdoc->loadXML($request_contents);
//fetch the contents of the URI element
$uri = $domdoc->getElementsByTagName("URI");
$uri = $uri->item(0)->nodeValue;
//return the given URI
return $uri;
}//getEndPoint
//returns an associative array of all openid parameters for this openid
//session. the array contains all the GET attributes that would be sent
//or that have been recieved, meaning:
//
//if mode = "cancel" returns only the mode and ns attributes
//if mode = "id_res" returns all attributes that are not null
//if mode = "checkid_setup" returns only attributes that need to be sent
// in the HTTP request
public function getArray(){
//an associative array to return
$ret = array();
$ret['openid.ns'] = GoogleOpenID::openid_ns;
//if mode is cancel, return only ns and mode
if($this->mode=="cancel"){
$ret['openid.mode'] = "cancel";
return $ret;
}//if cancel
//set attributes that are returned for all cases
if(!is_null($this->claimed_id)){
$ret['openid.claimed_id'] = $this->claimed_id;
$ret['openid.identity'] = $this->claimed_id;
}
if(!is_null($this->return_to))
$ret['openid.return_to'] = $this->return_to;
if(!is_null($this->realm))
$ret['openid.realm'] = $this->realm;
if(!is_null($this->assoc_handle))
$ret['openid.assoc_handle'] = $this->assoc_handle;
if(!is_null($this->mode))
$ret['openid.mode'] = $this->mode;
//set attributes that are returned only if this is a request
//and if getting email is required OR if this is a response and the
//email is given
if(($this->mode=="checkid_setup" AND $this->require_email) OR
($this->mode=="id_res" AND !is_null($this->email))){
$ret['openid.ns.ext1'] = GoogleOpenID::openid_ns_ext1;
$ret['openid.ext1.mode'] = GoogleOpenID::openid_ext1_mode;
$ret['openid.ext1.type.email'] = GoogleOpenID::openid_ext1_type_email;
$ret['openid.ext1.required'] = GoogleOpenID::openid_ext1_required;
if(!is_null($this->email))
$ret['openid.ext1.value.email'] = $this->email;
}//if redirect and get email
//set attributes that are returned only if this is a response
if($this->mode=="id_res"){
$ret['openid.op_endpoint'] = $this->op_endpoint;
if(!is_null($this->response_nonce))
$ret['openid.response_nonce'] = $this->response_nonce;
if(!is_null($this->signed))
$ret['openid.signed'] = $this->signed;
if(!is_null($this->sig))
$ret['openid.sig'] = $this->sig;
}
//return the array
return $ret;
}//getArray
//sends a request to google and fetches the url to which google is asking
//us to redirect (unless the endpoint is already known, in which case the
//function simply returns it)
public function endPoint(){
//if we know the value of op_endpoint already
if(!is_null($this->op_endpoint))
return $this->op_endpoint;
//fetch the endpoint from Google
$endpoint = GoogleOpenID::getEndPoint();
//save it
$this->op_endpoint = $endpoint;
//return the endpoint
return $endpoint;
}//getedPoint
//returns the URL to which we should send a request (including all GET params)
public function getRequestURL(){
//get all parameters
$params = $this->getArray();
//the base URL
$url = $this->endPoint();
//flag indicating whether to set a '?' or an '&'
$first_attribute = true;
//loop through all params
foreach($params as $param => $value){
//if first attribute print a ?, else print a &
if($first_attribute){
$url .= "?";
$first_attribute = false;
} else {
$url .= "&";
}//else (not first attribute)
$url .= urlencode($param) . "=" . urlencode($value);
}//loop through params
//return the URL
return $url;
}//getRequestURL
//redirects the browser to the appropriate request URL
public function redirect(){
header("Location: ".$this->getRequestURL());
}//redirect
//returns true if the response was a success
public function success(){
return ($this->mode=="id_res");
}//success
//returns the identity given in the response
public function identity(){
if($this->mode!="id_res")
return null;
else
return $this->claimed_id;
}//identity
//returns the email given in the response
public function email(){
if($this->mode!="id_res")
return null;
else
return $this->email;
}//email
//returns the assoc_handle
public function assoc_handle(){
return $this->assoc_handle();
}//assoc_handle
}//class GoogleOpenID
?>

157
htdocs/lib/Layout.php Normal file
View File

@@ -0,0 +1,157 @@
<?php
/**
* Layout.php
* Common html for all pages
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Layout
{
function since($since)
{
$since = time() - $since;
$chunks = array(
array(60 * 60 * 24 * 365 , 'year'),
array(60 * 60 * 24 * 30 , 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24 , 'day'),
array(60 * 60 , 'hour'),
array(60 , 'minute'),
array(1 , 'second')
);
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = ($count == 1) ? '1 '.$name : "$count {$name}s";
return $print;
}
function header()
{
global $S;
$menu = array();
if ($S->isAnonymous())
{
$item = new stdClass;
$item->label = "Login";
$item->link = "/login.php";
$menu[] = $item;
}
else
{
if ($S->user->isAllowed())
{
$item = new stdClass;
$item->label = "Crash reports";
$item->link = "/crashes.php";
$menu[] = $item;
$item = new stdClass;
$item->label = "Statistics";
$item->link = "/statistics.php";
$menu[] = $item;
}
if ($S->user->isAdmin())
{
$item = new stdClass;
$item->label = "Users";
$item->link = "/users.php";
$menu[] = $item;
}
$item = new stdClass;
$item->label = "My Account ({$S->user->email})";
$item->link = "/account.php";
$menu[] = $item;
$item = new stdClass;
$item->label = "Logout";
$item->link = "/logout.php";
$menu[] = $item;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" type="text/css" href="<?php print URL_ROOT ?>/singularity.css"/>
<link rel="shortcut icon" href="<?php print IMG_ROOT ?>/favicon.ico" type="image/x-icon" />
<title>Singularity Viewer Automated Build System</title>
<!--script type="text/javascript">
//<![CDATA[
//]]>
</script-->
</head>
<body>
<div id="everything">
<div id="page-wrapper">
<div id="header"></div>
<div class="container"><a href="<?php print URL_ROOT ?>" style="font-size: 20px;">Automated Crash Report Processing System</a><br/>
<?php for ($i=count($menu) - 1; $i>=0; $i--): ?>
<div class="menuitem"><a href="<?php echo $menu[$i]->link; ?>"><?php echo htmlspecialchars($menu[$i]->label) ?></a></div>
<?php endfor ?>
<br/><br/>
<?php
}
function footer()
{
{ ?>
</div><!-- container -->
<div class="container">
<table style="width: 100%; border: none; padding: 0;"><tr>
<td class="bottom-links"><a href="http://www.singularityviewer.org/">Singularity Main Site</a></td>
<td class="bottom-links"><a href="http://www.singularityviewer.org/about">About</a></td>
<td class="bottom-links"><a href="http://code.google.com/p/singularity-viewer/issues/">Issue Tracker</a></td>
<td class="bottom-links"><a href="https://github.com/singularity-viewer/SingularityViewer">Source Tracker</a></td>
<td width="50%" style="text-align: right;">&copy; 2013 Singularity Viewer Project</td>
</tr></table>
</div>
</div><!-- everything -->
</div><!-- page-wrapper -->
</body>
</html>
<?php
}
}
}

93
htdocs/lib/Option.php Normal file
View File

@@ -0,0 +1,93 @@
<?php
/**
* Option.php
* Simple key-value store for various options
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Option
{
private static $optionArray = array();
/**
* Inits the option class. Must be called before any other method.
*/
public static function init()
{
global $DB;
if(!$result = $DB->query("SELECT * FROM options")) {
return false;
} else {
while ($row = $DB->fetchRow($result)) {
self::$optionArray[$row['name']] = $row['value'];
}
return true;
}
}
/**
* Updates an option.
*
* @param string $name Name of the option
* @param string $value New value for the option
* @return boolean
*/
public static function update($name, $value)
{
global $DB;
$result = $DB->query(kl_str_sql("DELETE FROM options WHERE name=!s", $name));
$result = $DB->query(kl_str_sql("INSERT INTO options (name, value) VALUES(!s,!s)", $name,$value ));
self::$optionArray[$name] = $value;
return $result;
}
/**
* Gets an option.
*
* @param string $name Name of the option
* @return string Value of the option
*/
public static function get($name)
{
if (!isset(self::$optionArray[$name])) {
return NULL;
}
return self::$optionArray[$name];
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

283
htdocs/lib/Session.php Normal file
View File

@@ -0,0 +1,283 @@
<?php
/**
* Session.php
* This class handles sessions
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class Session
{
private $cookie;
public $timeout;
public $authenticated;
public $validsession;
/**
* User object containing info about the user.
*
* @var User
*/
public $user;
function __construct()
{
$this->timeout = 604800; // 7 days
$this->authenticated = false;
$this->validsession = false;
$this->cookie = "singularity_sid";
$this->user = new User;
register_shutdown_function(array(&$this, 'shutdown'));
}
function shutdown()
{
if ($this->persist || $this->ser_persist) {
$ser=serialize($this->persist);
if ($ser !== $this->ser_persist) {
$this->ser_persist = $ser == 'N;' ? '' : $ser;
$this->expires=time()+$this->timeout;
$this->update();
}
}
}
function add()
{
global $DB;
$this->sid = md5(uniqid(rand()));
$this->expires=time() + $this->timeout;
$DB->query(kl_str_sql("DELETE from session where sid=!s", $this->sid));
$q = kl_str_sql("INSERT into session (sid, user_id, authenticated, expires, persist) ".
"values (!s, !i, !i, !t, !s)",
$this->sid,
$this->user->user_id,
$this->authenticated,
$this->expires,
$this->ser_persist
);
if ($DB->query($q)) {
setcookie($this->cookie, $this->sid, NULL, '/' . REL_DIR);
return true;
} else {
return false;
}
}
function update()
{
global $DB;
$q = kl_str_sql('UPDATE session SET user_id=!i, authenticated=!i, expires=!t, persist=!s WHERE sid=!s',
$this->user->user_id, $this->authenticated, $this->expires, $this->ser_persist, $this->sid);
if (($res = $DB->query($q)) && $DB->affectedRows()) {
return true;
} else {
return $this->add();
}
}
function remove($sid = false)
{
global $DB;
if (!$sid) {
$sid = $this->sid;
}
$this->sid = NULL;
$this->validsession = false;
$this->authenticated = 0;
$this->user = new User;
$this->persist = NULL;
$this->ser_persist = NULL;
$DB->query(kl_str_sql("DELETE from session where sid=!s", $sid));
setcookie($this->cookie, '', 0, '/' . REL_DIR);
}
function check()
{
global $DB;
if (isset($_GET[$this->cookie])) {
$this->sid = $_GET[$this->cookie];
} else {
$this->sid = $_COOKIE[$this->cookie];
}
$error = true;
if (!$this->sid) {
// No session id. Is anonymous access allowed?
if (Option::get('allow_anon_access') == '1') {
$this->user = new User();
$this->user_id = $this->user->user_id;
$this->add();
} else {
$this->user_id = NULL;
$this->add();
}
$error = false;
} else {
$res = $DB->query(kl_str_sql('SELECT * from session where sid=!s', $this->sid));
if ($res AND $row = $DB->fetchRow($res)) {
$this->authenticated = (int)$row['authenticated'];
$this->expires = strtotime($row['expires']);
$this->ser_persist = $row['persist'];
$this->user_id = (int)$row['user_id'];
if (!$this->user_id) {
$this->user_id = NULL;
}
if ($this->ser_persist) {
$this->persist=@unserialize($this->ser_persist);
}
if ($this->expires >= time()) {
$error = false;
$this->validsession=true;
if (!$this->user = User::get($this->user_id)) {
$error = true;
}
}
if ($this->expires-time() < $this->timeout/2) {
$this->expires=time() + $this->timeout;
setcookie($this->cookie, $this->sid, NULL, '/' . REL_DIR);
if (!$this->update()) {
$error = true;
}
}
}
if ($error) {
if ($this->sid) {
$this->remove($this->sid);
}
$this->add();
}
}
} // End function check
function authenticate($username, $password)
{
$user = User::getByUsername($username);
if ($user AND $user->password === $password) {
$this->user = $user;
$this->user_id = $user->user_id;
$this->authenticated = true;
$this->persist->active_order = null;
$this->update();
return true;
}
return false;
}
function loginRedirect()
{
if ($l = strlen(REL_DIR)) {
$eatchars = $l + 2;
} else {
$eatchars = $l + 1;
}
$caller='/' . substr($_SERVER['PHP_SELF'], $eatchars);
$callerarg = array();
if ($nc = count($_GET)) {
foreach($_GET as $key => $value) {
$callerarg[] = urlencode($key) . '=' . urlencode($value);
}
$callerarg = implode('&', $callerarg);
}
$redirect = '/login.php?caller=' . urlencode($caller);
if ($callerarg) {
$redirect .= "&callerarg=" . urlencode($callerarg);
}
http::redirect($redirect);
}
public function requireUser()
{
if ((Option::get('allow_anon_access') == '0' && $this->isAnonymous())
|| $this->user->isAnonymous()) {
$this->loginRedirect();
} else if (!$this->user->isAllowed()) {
$this->remove($this->sid);
$this->loginRedirect();
}
}
/**
* Returns true if the user is anonymous.
*
* @return boolean
*/
public function isAnonymous()
{
if ($this->authenticated == 0) {
return true;
} else {
return false;
}
}
/**
* Redirects the user to a login screen if he's not logged in as admin.
*/
public function requireAdmin()
{
if ($this->isAdmin() != true) {
$this->remove($this->sid);
$this->loginRedirect();
}
}
/**
* Returns true if user is admin. False if not.
*
* @return boolean
*/
public function isAdmin()
{
return ($this->authenticated && $this->user->isAdmin());
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

205
htdocs/lib/User.php Normal file
View File

@@ -0,0 +1,205 @@
<?php
class User
{
/**
* Returns true if the user has a valid email, false if not.
*
* @return boolean
*/
public function hasValidEmail()
{
return (preg_match(
'/^[-!#$%&\'*+\\.\/0-9=?A-Z^_`{|}~]+'. // the user name
'@'. // the ubiquitous at-sign
'([-0-9A-Z]+\.)+' . // host, sub-, and domain names
'([0-9A-Z]){2,4}$/i', // top-level domain (TLD)
trim($this->email)));
}
/**
* Save the user as a new user.
*
* @return boolean
*/
public function save()
{
global $DB;
$query = kl_str_sql('INSERT INTO users(
name,
email,
login,
password,
is_admin,
is_allowed
) VALUES (!s,!s,!s,!s,!i,!i)',
$this->name,
$this->email,
$this->login,
$this->password,
$this->is_admin,
$this->is_allowed
);
if (!$res = $DB->query($query)) {
return false;
} else {
$this->user_id = $DB->insertID();
return $this->user_id;
}
}
public function update()
{
global $DB;
$query = kl_str_sql('
UPDATE users SET
name=!s,
email=!s,
login=!s,
password=!s,
is_admin=!i,
is_allowed=!i
WHERE user_id=!i',
$this->name,
$this->email,
$this->login,
$this->password,
$this->is_admin,
$this->is_allowed,
$this->user_id
);
//echo $query;
if (!$DB->query($query)) {
return false;
} else {
return true;
}
}
/**
* Get user by id.
*
* @param integer $id
* @return User
*/
public static function get($id)
{
global $DB;
if (is_null($id)) {
return new User();
}
$query = kl_str_sql("SELECT * FROM users WHERE user_id=!i",$id);
if(!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
public function isAnonymous()
{
return !$this->user_id;
}
public function isAdmin()
{
return $this->is_admin;
}
public function isAllowed()
{
return $this->is_allowed;
}
/**
* Get a user by username.
*
* @param string $username
* @return User
*/
public static function getByLogin($username)
{
global $DB;
$query = kl_str_sql('SELECT * FROM users WHERE login=!s', $username);
if(!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
/**
* Get an user by email.
*
* @param string $email
* @return User
*/
public static function getByEmail($email)
{
global $DB;
$query = kl_str_sql('SELECT * FROM users WHERE cust_id!=1 AND email=!s', $email);
if (!$res = $DB->query($query) OR !$row = $DB->fetchRow($res)) {
return false;
} else {
$user = new User();
$DB->loadFromDbRow($user, $res, $row);
return $user;
}
}
/**
* Get all users.
*
* @return array Array of User
*/
public static function getAll()
{
global $DB;
$query = kl_str_sql('SELECT * FROM users ORDER BY is_admin DESC, is_allowed DESC, user_id ASC');
if(!$res = $DB->query($query)) {
return false;
} else {
$retval=array();
while($row = $DB->fetchRow($res)) {
$tmp = new User();
$DB->loadFromDbRow($tmp, $res, $row);
$retval[] = $tmp;
}
return $retval;
}
}
function delete(){
global $DB;
$query=kl_str_sql("DELETE FROM users WHERE user_id=!i",$this->user_id);
//echo $query;
if(!$res=$DB->query($query)){
return false;
}
else{
return true;
}
}
public function setImportArray($array)
{
$this->name = $array['name'];
$this->email = $array['email'];
$this->login = $array['login'];
$this->password = $array['password'];
$this->is_admin = $array['is_admin'];
$this->is_allowed = $array['is_allowed'];
}
}
?>

34
htdocs/lib/db_init.sql Normal file
View File

@@ -0,0 +1,34 @@
drop table if exists raw_reports;
drop table if exists users;
drop table if exists options;
drop table if exists session;
create table session(
sid varchar(128) not null primary key,
user_id integer,
authenticated tinyint,
expires datetime,
persist text
);
create table options(
name varchar(128),
value text
);
create table users(
user_id integer not null auto_increment primary key,
name varchar(255),
email varchar(255),
login varchar(255),
password varchar(255),
is_admin tinyint,
is_allowed tinyint
);
create table raw_reports(
report_id integer not null auto_increment primary key,
reported timestamp not null default current_timestamp,
processed integer not null default 0,
raw_data longtext
);

115
htdocs/lib/ext_kl.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
/* $Id$ */
$php_str_sql_options_array = array(
"str_sql_date_format" => "Y-m-d",
"str_sql_datetime_format" => "Y-m-d H:i:s",
"str_sql_quote_func" => "mysql_real_escape_string");
/**
* This method validates the sql insert string must always be used in conjunction with an insert to the db
* @return string
*/
function kl_str_sql()
{
GLOBAL $php_str_sql_options_array;
$f = $php_str_sql_options_array['str_sql_quote_func'];
$narg = func_num_args();
$args = func_get_args();
if ($narg<1) {
trigger_error("At least one parameter required", E_USER_WARNING);
return "";
}
$offset = 0;
$flen = strlen($args[0]);
$res = "";
$narg = 1;
while ($offset < $flen) {
if (false !== ($pos = strpos($args[0],"!", $offset))) {
$res .= substr($args[0], $offset, $pos-$offset);
switch ($args[0][$pos+1]) {
case 's':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".$f($args[$narg])."'";
}
$narg++;
break;
case 'b':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".$f($args[$narg])."'";
}
$narg++;
break;
case 'i':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= (int)($args[$narg]);
}
$narg++;
break;
case 'f':
if (is_null($args[$narg])) {
$res .= 'NULL';
} else {
$res .= (double)($args[$narg]);
}
$narg++;
break;
case 'd':
if (!($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".date($php_str_sql_options_array['str_sql_date_format'], $args[$narg])."'";
}
$narg++;
break;
case 't':
if (!($args[$narg])) {
$res .= 'NULL';
} else {
$res .= "'".date($php_str_sql_options_array['str_sql_datetime_format'], $args[$narg])."'";
}
$narg++;
break;
default:
$res .= "!".$args[0][$pos+1];
}
$offset = $pos + 2;
} else {
$res .= substr($args[0], $offset);
$offset = $flen;
}
}
return $res;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

132
htdocs/lib/http.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* http.php
* Common http operations such as redirects, etc.
*
* Description
* @package Singularity Crash Processor
* @author Latif Khalifa <latifer@streamgrid.net>
* @copyright Copyright &copy; 2012, Latif Khalifa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* - The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
class http
{
public static function redirectAbsolute($url)
{
Header("Location: $url");
Header("HTTP/1.0 302 Found");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>302 Found</TITLE>
</HEAD><BODY>
<H1>Found</H1>
The document was found <A HREF=\"$url\">here</A>.<P>
</BODY></HTML>
";
exit;
}
public static function redirect($url)
{
http::redirectAbsolute(URL_ROOT . $url);
}
public static function notFound()
{
header("HTTP/1.1 404 Not Found");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL was not found on this server.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function notAllowed()
{
header("HTTP/1.1 405 Method Not Allowed");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>405 Method Not Allowed</TITLE>
</HEAD><BODY>
<H1>Method Not Allowed</H1>
The requested HTTP method is not allowed for this URL.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function notModified()
{
header("HTTP/1.1 304 Not Modified");
print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>304 Not Modified</TITLE>
</HEAD><BODY>
<H1>Not Modified</H1>
The requested URL has not been modified.<P>
<HR>
<ADDRESS>{$_SERVER['SERVER_SIGNATURE']}</ADDRESS>
</BODY></HTML>
";
exit;
}
public static function noCache()
{
header("Expires: Mon, 21 Jan 1980 06:01:01 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
}
/**
* Send data for download.
*
* @param string $filename
* @param string $data
*/
public static function sendDownload($filename, $data)
{
header('Content-disposition: attachment; filename=' . urlencode($filename));
echo $data;
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

88
htdocs/lib/init.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
if (!defined('SITE_ROOT')) {
exit(1);
}
error_reporting(E_ALL ^ E_NOTICE);
ini_set('display_errors',1);
if (!extension_loaded('kl')) {
require_once SITE_ROOT.'/lib/ext_kl.php';
}
function __autoload($class)
{
require_once(SITE_ROOT . '/lib/' . $class . '.php');
}
/* Directory relative to server root
* No leading or trailing slash.
* Example: http://www.example.com/applications/app1/
*/
define('REL_DIR', '');
if (!defined('URL_ROOT')) {
$init_port = "";
$init_ssl = strlen($_SERVER["HTTPS"]) > 0 ? true:false;
define('USE_SSL', $init_ssl);
$init_url = $init_ssl ? "https://" : "http://";
if ($init_ssl && $_SERVER['PORT']!=443) {
$init_port = $_SERVER['PORT'];
}
if (!$init_ssl && $_SERVER['PORT']!=80) {
$init_port = $_SERVER['PORT'];
}
$init_url .= $_SERVER['HTTP_HOST'];
if ($init_port) {
$init_url .= ":" . $init_port;
}
if (defined('REL_DIR') && strlen(REL_DIR)) {
$init_url .= '/' . REL_DIR;
}
define ('URL_ROOT', $init_url);
}
if (!defined('IMG_ROOT')) {
define('IMG_ROOT', URL_ROOT . '/images');
}
$DB = new DBH();
$DB_NAME = "singucrash";
$DB_USER = 'singucrash';
$DB_PASS = '-*-secrit-*-';
$DB_HOST = 'localhost';
if (!$DB->connect($DB_NAME, $DB_HOST, $DB_USER, $DB_PASS)) {
echo "System is down for mantainence. Please try again later.";
die();
}
Option::init();
$S = new Session();
if (!defined('NO_SESSION') && PHP_SAPI != "cli") {
$S->check();
}
/* Prevent XSS attacks via PHP_SELF */
$_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF']);
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
?>

38
htdocs/login.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$assoc_handle_expires = (int)Option::get('assoc_handle_expires');
$now = time();
$assoc_handle = Option::get("assoc_handle");
if (!$assoc_handle || $assoc_handle_expires < $now)
{
$assoc_handle_expires = time() + 604800;
$assoc_handle = GoogleOpenID::getAssociationHandle();
if ($assoc_handle)
{
Option::update("assoc_handle_expires", $assoc_handle_expires);
Option::update("assoc_handle", $assoc_handle);
}
}
$google_gateway = GoogleOpenID::createRequest(URL_ROOT . "/process_login.php", $handle, true);
Layout::header();
?>
<p>Please use your <a href="<?php echo $google_gateway->getRequestURL(); ?>">Google Account</a> to login.</p>
<?php
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

20
htdocs/login_failed.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
Layout::header();
print "<strong>Login Failed</strong>";
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

15
htdocs/logout.php Normal file
View File

@@ -0,0 +1,15 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$S->remove();
http::redirect("/");
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

49
htdocs/process_login.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$google_response = GoogleOpenID::getResponse();
$success = $google_response->success();//true or false
if (!$success)
{
http::redirect("/login_failed.php");
}
$user_identity = $google_response->identity();//the user's ID
$user_email = $google_response->email();//the user's email
$user = User::getByLogin($user_identity);
if (!$user)
{
$user = new User();
$user->email = $user_email;
$user->is_admin = 0;
$user->is_allowed = 0;
$user->login = $user_identity;
if (!$user->save())
{
http::redirect("/login_failed.php");
}
}
$S->user = $user;
$S->user_id = $user->user_id;
$S->authenticated = 1;
$S->update();
if (isset($_GET['caller']))
{
http::redirect($_GET['caller']);
}
http::redirect('/');
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

32
htdocs/report.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
define("NO_SESSION", 1);
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
if ($_SERVER["REQUEST_METHOD"] !== "POST")
{
http::notAllowed();
}
$report_id = 0;
$report = file_get_contents("php://input");
if (strlen($report))
{
$query = kl_str_sql('insert into raw_reports(raw_data) values (!s)', $report);
if ($res = $DB->query($query))
{
$report_id = $DB->insertID();
}
}
header("Content-Type: application/llsd+xml");
print '<?xml version="1.0" ?><llsd><map><key>message</key><string>Report saved with report_id=' . $report_id . '</string><key>success</key><boolean>true</boolean></map></llsd>';
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

109
htdocs/singularity.css Normal file
View File

@@ -0,0 +1,109 @@
html {
padding: 0;
margin: 0;
background-color: #1e1e1e;
}
image {
border: none;
}
body, select {
padding: 0;
margin: 0;
background-color: #1e1e1e;
font: normal 10pt "Lucida Grande","Lucida Sans Unicode",sans-serif;
color: #a0a0a0;
}
div {
display: block;
padding: 0;
margin: 0;
}
#everything {
background: url(images/body-bg.png) top repeat-x;
min-height: 100%;
}
#page-wrapper {
margin: 0 auto;
width: 960px;
}
#header {
margin-bottom: 10px;
width: 100%;
height: 144px;
background: url(images/singularity_logo.gif) left top no-repeat;
border-bottom: solid 2px black;
}
.container {
padding: 5px;
margin-bottom: 10px;
background: url(images/container-bg.gif) top repeat-x;
border-bottom: solid 2px black;
background-color: #1b1b1b;
}
input {
color: #a0a0a0;
background-color: #2C3737;
border: none;
border-bottom: solid 1px black;
padding: 2px 6px 2px 6px;
}
input:hover {
background-color: #445A5E;
}
a, a:link, a:hover, a:visited, a:active {
text-decoration: none;
color: #e0e0e0;
}
.bottom-links {
text-align: center;
}
td, th {
text-align: left;
margin: 0;
padding: 3px 20px 3px 3px;
vertical-align: top;
display: table-cell;
border: none;
}
th {
border-bottom: solid 1px #404040;
background: url(images/container-bg.gif) top repeat-x;
}
tr.rowhighlight:hover {
background-color: #2C3737;
}
.menuitem {
float: right;
padding: 3px 15px 3px 15px;
margin-top: 15px;
margin-left: 2px;
background-color: #2C3737;
border-bottom: 1px solid #101010;
/* border: 1px solid red; */
}
.menuitem:hover {
background-color: #445A5E;
}
pre {
font-family: monospace;
font-size: 8pt;
white-space: pre-wrap;
word-wrap: break-word;
}

23
htdocs/statistics.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$S->requireUser();
Layout::header();
?>
<strong>Not implemented</strong>
<?php
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

79
htdocs/users.php Normal file
View File

@@ -0,0 +1,79 @@
<?php
define("SITE_ROOT", realpath(dirname(__file__)));
require_once SITE_ROOT . "/lib/init.php";
$S->requireAdmin();
$users = User::getAll();
if (isset($_REQUEST["action"]))
{
$action = $_REQUEST["action"];
$user_id = (int)$_REQUEST["id"];
$user = User::get($user_id);
if ($user && !$user->isAdmin())
{
switch ($action)
{
case "grant":
$user->is_allowed = 1;
$user->update();
break;
case "revoke":
$user->is_allowed = 0;
$user->update();
break;
case "remove":
$user->delete();
break;
}
}
http::redirect("/users.php");
}
Layout::header();
?>
<h3>User Accounts</h3>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Access</th>
<th>Actions</th>
</tr>
<?php for ($i=0; $i<count($users); $i++): ?>
<tr class="rowhighlight">
<td><?php echo (int)$users[$i]->user_id ?></td>
<td><?php echo htmlentities($users[$i]->name); ?></td>
<td><?php echo htmlentities($users[$i]->email); ?></td>
<td><?php echo $users[$i]->isAdmin() ? "Admin" : ($users[$i]->isAllowed() ? "Granted" : "No"); ?></td>
<td>
<?php
if (!$users[$i]->isAdmin())
{
$action = $users[$i]->isAllowed() ? "revoke" : "grant";
$url = URL_ROOT . "/users.php?action=$action&id=" . (int)$users[$i]->user_id;
$delete = URL_ROOT . "/users.php?action=remove&id=" . (int)$users[$i]->user_id;
print "<a href=\"{$url}\">{$action}&nbsp;access</a>,&nbsp;&nbsp;";
print "<a href=\"{$delete}\" title=\"Caution: completely deletes information about this user.\" onclick=\"return confirm('Are you sure you want to completely remove this account? Just revoking access works too, and they can create it again by logging with their Google credentials.');\">delete account</a>";
}
?>
</td>
</tr>
<?php endfor ?>
</table>
<?php
Layout::footer();
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/