add version 1.5

pull/3/head
Adrien Beudin 10 years ago
parent 69da6780e5
commit 1886f9b68d

@ -10,8 +10,7 @@ MAINTAINER Dan Callahan <dan.callahan@gmail.com>
# Base system setup # Base system setup
RUN DEBIAN_FRONTEND=noninteractive apt-get update \ RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
&& apt-get install --no-install-recommends -y \
vim locales \ vim locales \
&& apt-get clean && apt-get clean
@ -25,6 +24,7 @@ RUN useradd --create-home app
RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
ca-certificates \ ca-certificates \
curl \
build-essential \ build-essential \
libzmq-dev \ libzmq-dev \
python-dev \ python-dev \
@ -34,9 +34,11 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
USER app USER app
RUN mkdir -p /home/app/syncserver RUN mkdir -p /home/app/syncserver
ADD ./ /home/app/syncserver
WORKDIR /home/app/syncserver WORKDIR /home/app/syncserver
RUN curl -L https://github.com/mozilla-services/syncserver/tarball/master |\
tar xzf - --strip-components=1
RUN make build RUN make build
# Run the Sync server # Run the Sync server

@ -6,23 +6,18 @@ TOOLS := $(addprefix $(ENV)/bin/,flake8 nosetests)
# Hackety-hack around OSX system python bustage. # Hackety-hack around OSX system python bustage.
# The need for this should go away with a future osx/xcode update. # The need for this should go away with a future osx/xcode update.
ARCHFLAGS = -Wno-error=unused-command-line-argument-hard-error-in-future ARCHFLAGS = -Wno-error=unused-command-line-argument-hard-error-in-future
INSTALL = ARCHFLAGS=$(ARCHFLAGS) $(ENV)/bin/pip install
# Hackety-hack around errors duing compile of ultramemcached.
CFLAGS = -Wno-error
INSTALL = CFLAGS=$(CFLAGS) ARCHFLAGS=$(ARCHFLAGS) $(ENV)/bin/pip install
.PHONY: all .PHONY: all
all: build all: build
.PHONY: build .PHONY: build
build: | $(ENV)/COMPLETE build: | $(ENV)
$(ENV)/COMPLETE: requirements.txt $(ENV): requirements.txt
$(VIRTUALENV) --no-site-packages $(ENV) $(VIRTUALENV) --no-site-packages $(ENV)
$(INSTALL) -r requirements.txt $(INSTALL) -r requirements.txt
$(ENV)/bin/python ./setup.py develop $(ENV)/bin/python ./setup.py develop
touch $(ENV)/COMPLETE touch $(ENV)
.PHONY: test .PHONY: test
test: | $(TOOLS) test: | $(TOOLS)
@ -38,11 +33,11 @@ test: | $(TOOLS)
--use-token-server http://localhost:5000/token/1.0/sync/1.5; \ --use-token-server http://localhost:5000/token/1.0/sync/1.5; \
kill $$SERVER_PID kill $$SERVER_PID
$(TOOLS): | $(ENV)/COMPLETE $(TOOLS): | $(ENV)
$(INSTALL) nose flake8 $(INSTALL) nose flake8
.PHONY: serve .PHONY: serve
serve: | $(ENV)/COMPLETE serve: | $(ENV)
$(ENV)/bin/pserve ./syncserver.ini $(ENV)/bin/pserve ./syncserver.ini
.PHONY: clean .PHONY: clean

@ -1,81 +0,0 @@
FSyncMS
=======
PHP Sync Server für Firefox Sync
Eine Erweiterung des Weave-Minimal Server (dessen Support leider eingestellt wurde).
Die derzeit aktuelle Versionen,
sowie alte Versionen und Anleitungen sind hier:
https://www.ohnekontur.de/category/technik/sync/fsyncms/
zu finden.
Weitere Erweiterungen sind in Planung.
Stay tuned.
Visit http://www.ohnekontur.de/2011/07/24/how-to-install-fsyncms-firefox-sync-eigener-server/ for install instructions
Visit http://www.ohnekontur.de for the newest version
FSyncMS v013
======
Database upgrade
for more information and some migration notice see
http://www.ohnekontur.de/2013/07/05/fsyncms-version-0-13-database-upgrade/
FSyncMS v012
======
Compatibility update
FSyncMS v011
======
Added dedicated setup script, which will create the database and the config file: settings.php
If you want to create it by your own, just generate the settings.php with the following content
<?php
//you can disable registration to the firefox sync server here,
// by setting ENABLE_REGISTER to false
//
//
//define("ENABLE_REGISTER",false);
define("ENABLE_REGISTER", true);
//pleas set the URL where firefox clients find the root of
// firefox sync server
// this should end with a /
//
define("FSYNCMS_ROOT","https://DOMAIN.de/Folder_und_ggf_/index.php/");
//MYSQL Params
define("MYSQL_ENABLE", false);
define("MYSQL_HOST","localhost");
define("MYSQL_DB","databaseName");
define("MYSQL_USER", "databaseUserName");
define("MYSQL_PASSWORD", "databaseUserPW");
?>
FSyncMS v010
======
MYSQL Support
FSyncMS v 09
======
Change Password now supported
working with firefox 12 (and lower)
Changelog:
Added change Password feature
FSyncMS v 08
======
Should be working with firefox 11 and lower (tested with 11)
Changelog:
Fixed user registration process,
fixed some delete problems

@ -1,7 +0,0 @@
== SOME TODOS ==
- Ein Präfix für die Tabellen, damit sie in eine vorhandene DB gelegt werden können.
- NOTIZ: Update der md5 Spalte der Usertabelle von length 64 auf length 124
- >ALTER TABLE `users` CHANGE `md5` `md5` VARCHAR( 124 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL

@ -1,154 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Weave Minimal Server
#
# The Initial Developer of the Original Code is
# Mozilla Labs.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Toby Elliott (telliott@mozilla.com)
# Luca Tettamanti
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#The datasets we might be dealing with here are too large for sticking it all into an array, so
#we need to define a direct-output method for the storage class to use. If we start producing multiples
#(unlikely), we can put them in their own class.
class WBOJsonOutput
{
private $_full = null;
private $_comma_flag = 0;
private $_output_format = 'json';
function __construct ($full = false)
{
$this->_full = $full;
if (array_key_exists('HTTP_ACCEPT', $_SERVER)
&& !preg_match('/\*\/\*/', $_SERVER['HTTP_ACCEPT'])
&& !preg_match('/application\/json/', $_SERVER['HTTP_ACCEPT']))
{
if (preg_match('/application\/whoisi/', $_SERVER['HTTP_ACCEPT']))
{
header("Content-type: application/whoisi");
$this->_output_format = 'whoisi';
}
elseif (preg_match('/application\/newlines/', $_SERVER['HTTP_ACCEPT']))
{
header("Content-type: application/newlines");
$this->_output_format = 'newlines';
}
}
}
function set_format($format)
{
$this->_output_format = $format;
}
function output($sth)
{
if (($rowcount = $sth->rowCount()) > 0)
{
header('X-Weave-Records: ' . $rowcount);
}
if ($this->_output_format == 'newlines')
{
return $this->output_newlines($sth);
}
elseif ($this->_output_format == 'whoisi')
{
return $this->output_whoisi($sth);
}
else
{
return $this->output_json($sth);
}
}
function output_json($sth)
{
echo '[';
while ($result = $sth->fetch(PDO::FETCH_ASSOC))
{
if ($this->_comma_flag) { echo ','; } else { $this->_comma_flag = 1; }
if ($this->_full)
{
$wbo = new wbo();
$wbo->populate($result);
echo $wbo->json();
}
else
echo json_encode($result{'id'});
}
echo ']';
return 1;
}
function output_whoisi($sth)
{
while ($result = $sth->fetch(PDO::FETCH_ASSOC))
{
if ($this->_full)
{
$wbo = new wbo();
$wbo->populate($result);
$output = $wbo->json();
}
else
$output = json_encode($result{'id'});
echo pack('N', mb_strlen($output, '8bit')) . $output;
}
return 1;
}
function output_newlines($sth)
{
while ($result = $sth->fetch(PDO::FETCH_ASSOC))
{
if ($this->_full)
{
$wbo = new wbo();
$wbo->populate($result);
echo preg_replace('/\n/', '\u000a', $wbo->json());
}
else
echo json_encode($result{'id'});
echo "\n";
}
return 1;
}
}
?>

@ -1,329 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Weave Minimal Server
#
# The Initial Developer of the Original Code is
# Mozilla Labs.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Toby Elliott (telliott@mozilla.com)
# Luca Tettamanti
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
if ( ! file_exists("settings.php") && file_exists("setup.php") ) {
require_once "setup.php";
exit;
} else if ( ! file_exists("settings.php") ) {
echo "<hr><h2>Maybe the setup is not completed, missing settings.php</h2><hr>";
exit;
} else if ( file_exists("setup.php") ) {
echo "<hr><h2>Maybe the setup is not completed, else please delete setup.php</h2><hr>";
exit;
}
require_once 'weave_storage.php';
require_once 'weave_basic_object.php';
require_once 'weave_utils.php';
require_once 'weave_hash.php';
require_once "WBOJsonOutput.php";
//header("Content-type: application/json");
$server_time = round(microtime(1), 2);
header("X-Weave-Timestamp: " . $server_time);
# Basic path extraction and validation. No point in going on if these are missing
$path = '/';
if (!empty($_SERVER['PATH_INFO']))
$path = $_SERVER['PATH_INFO'];
else if (!empty($_SERVER['ORIG_PATH_INFO']))
$path = $_SERVER['ORIG_PATH_INFO'];
else if (!empty($_SERVER["REQUEST_URI"]))
{
log_error("experimental path");
# this is kind of an experimental try, i needed it so i build it,
# but that doesent mean that it does work... well it works for me
# and it shouldnt break anything...
$path = $_SERVER["REQUEST_URI"];
$lastfolder = substr(FSYNCMS_ROOT,strrpos(FSYNCMS_ROOT, "/",-2));
$path = substr($path, (strpos($path,$lastfolder) + strlen($lastfolder)-1)); #chop the lead slash
if(strpos($path,'?') != false)
$path = substr($path, 0, strpos($path,'?')); //remove php arguments
log_error("path_exp:".$path);
}
else
report_problem("No path found", 404);
$path = substr($path, 1); #chop the lead slash
log_error("start request_____" . $path);
// ensure that we got a valid request
if ( !$path )
report_problem("Invalid request, this was not a firefox sync request!", 400);
// split path into parts and make sure that all values are properly initialized
list($version, $username, $function, $collection, $id) = array_pad(explode('/', $path.'///'), 5, '');
if($version == 'user' || $version == 'misc')
{
//asking for userApi -> user.php
$include = true;
require 'user.php';
exit(); // should not get here, but how knows
}
header("Content-type: application/json");
if ($version != '1.0' && $version != '1.1')
report_problem('Function not found', 404);
if ($function != "info" && $function != "storage")
report_problem(WEAVE_ERROR_FUNCTION_NOT_SUPPORTED, 400);
if (!validate_username($username))
report_problem(WEAVE_ERROR_INVALID_USERNAME, 400);
#only a delete has meaning without a collection
if ($collection)
{
if (!validate_collection($collection))
report_problem(WEAVE_ERROR_INVALID_COLLECTION, 400);
}
else if ($_SERVER['REQUEST_METHOD'] != 'DELETE')
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
#quick check to make sure that any non-storage function calls are just using GET
if ($function != 'storage' && $_SERVER['REQUEST_METHOD'] != 'GET')
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
#user passes preliminaries, connections made, onto actually getting the data
try
{
$db = new WeaveStorage($username);
#Auth the user
verify_user($username, $db);
#user passes preliminaries, connections made, onto actually getting the data
if ($_SERVER['REQUEST_METHOD'] == 'GET')
{
if ($function == 'info')
{
switch ($collection)
{
case 'quota':
exit(json_encode(array($db->get_storage_total())));
case 'collections':
exit(json_encode($db->get_collection_list_with_timestamps()));
case 'collection_counts':
exit(json_encode($db->get_collection_list_with_counts()));
case 'collection_usage':
$results = $db->get_collection_storage_totals();
foreach (array_keys($results) as $collection)
{
$results[$collection] = ceil($results[$collection] / 1024); #converting to k from bytes
}
exit(json_encode($results));
default:
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
}
}
elseif ($function == 'storage')
{
log_error("function storage");
if ($id) #retrieve a single record
{
$wbo = $db->retrieve_objects($collection, $id, 1); #get the full contents of one record
if (count($wbo) > 0)
{
$item = array_shift($wbo);
echo $item->json();
}
else
report_problem("record not found", 404);
}
else #retrieve a batch of records. Sadly, due to potential record sizes, have the storage object stream the output...
{
log_error("retrieve a batch");
$full = array_key_exists('full', $_GET) && $_GET['full'];
$outputter = new WBOJsonOutput($full);
$params = validate_search_params();
$ids = $db->retrieve_objects($collection, null, $full, $outputter,
$params['parentid'], $params['predecessorid'],
$params['newer'], $params['older'],
$params['sort'],
$params['limit'], $params['offset'],
$params['ids'],
$params['index_above'], $params['index_below'], $params['depth']
);
}
}
}
else if ($_SERVER['REQUEST_METHOD'] == 'PUT') #add a single record to the server
{
$wbo = new wbo();
if (!$wbo->extract_json(get_json()))
report_problem(WEAVE_ERROR_JSON_PARSE, 400);
check_quota($db);
check_timestamp($collection, $db);
#use the url if the json object doesn't have an id
if (!$wbo->id() && $id) { $wbo->id($id); }
$wbo->collection($collection);
$wbo->modified($server_time); #current microtime
if ($wbo->validate())
{
#if there's no payload (as opposed to blank), then update the metadata
if ($wbo->payload_exists())
$db->store_object($wbo);
else
$db->update_object($wbo);
}
else
{
report_problem(WEAVE_ERROR_INVALID_WBO, 400);
}
echo json_encode($server_time);
}
else if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$json = get_json();
check_quota($db);
check_timestamp($collection, $db);
$success_ids = array();
$failed_ids = array();
$db->begin_transaction();
foreach ($json as $wbo_data)
{
$wbo = new wbo();
if (!$wbo->extract_json($wbo_data))
{
$failed_ids[$wbo->id()] = $wbo->get_error();
continue;
}
$wbo->collection($collection);
$wbo->modified($server_time);
if ($wbo->validate())
{
#if there's no payload (as opposed to blank), then update the metadata
if ($wbo->payload_exists())
{
$db->store_object($wbo);
}
else
{
$db->update_object($wbo);
}
$success_ids[] = $wbo->id();
}
else
{
$failed_ids[$wbo->id()] = $wbo->get_error();
}
}
$db->commit_transaction();
echo json_encode(array('success' => $success_ids, 'failed' => $failed_ids));
}
else if ($_SERVER['REQUEST_METHOD'] == 'DELETE')
{
check_timestamp($collection, $db);
if ($id)
{
$db->delete_object($collection, $id);
}
else if ($collection)
{
$params = validate_search_params();
$db->delete_objects($collection, null,
$params['parentid'], $params['predecessorid'],
$params['newer'], $params['older'],
$params['sort'],
$params['limit'], $params['offset'],
$params['ids'],
$params['index_above'], $params['index_below']
);
}
else if($function == 'storage') // ich vermute mal storage reinigen
{
if (!array_key_exists('HTTP_X_CONFIRM_DELETE', $_SERVER))
report_problem(WEAVE_ERROR_NO_OVERWRITE, 412);
$db->delete_storage($username);
}
else
{
if (!array_key_exists('HTTP_X_CONFIRM_DELETE', $_SERVER))
report_problem(WEAVE_ERROR_NO_OVERWRITE, 412);
log_error("delete "."Server ".print_r( $_SERVER, true));
$db->delete_user($username);
}
echo json_encode($server_time);
}
else
{
#bad protocol. There are protocols left? HEAD, I guess.
report_problem(1, 400);
}
}
catch(Exception $e)
{
report_problem($e->getMessage(), $e->getCode());
}
#The datasets we might be dealing with here are too large for sticking it all into an array, so
#we need to define a direct-output method for the storage class to use. If we start producing multiples
#(unlikely), we can put them in their own class.
#include_once "WBOJsonOutput.php";
?>

@ -1,13 +1,9 @@
cornice==0.16.2 cornice==0.16.2
gunicorn==19.1.1
pyramid==1.5 pyramid==1.5
requests==2.2.1 requests==2.2.1
simplejson==3.4 simplejson==3.4
SQLAlchemy==0.9.4 SQLAlchemy==0.9.4
unittest2==0.5.1 unittest2==0.5.1
https://github.com/mozilla-services/mozservices/archive/e00e1b68130423ad98d0f6185655bde650443da8.zip http://github.com/mozilla-services/mozservices/archive/5fabece891bbd3bd2c9528cb3bf0562b3efb4af1.zip
https://github.com/mozilla-services/tokenserver/archive/d7e513e8a4f5c588b70d685a8df1d2e508c341c0.zip https://github.com/mozilla-services/tokenserver/archive/1.2.7.zip
http://github.com/mozilla-services/server-syncstorage/archive/1.5.5.zip http://github.com/mozilla-services/server-syncstorage/archive/1.5.5.zip
# Newer releases of configparser have b/w compat bug:
# https://github.com/mozilla-services/syncserver/issues/39
configparser==3.3.0r2

@ -1,399 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Weave Minimal Server
#
# The Initial Developer of the Original Code is
# Stefan Fischer
# Portions created by the Initial Developer are Copyright (C) 2012
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Daniel Triendl <daniel@pew.cc>
# balu
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
// --------------------------------------------
// variables start
// --------------------------------------------
$action = null;
$dbType = null;
$dbUser = null;
$dbName = null;
$dbPass = null;
$dbHost = null;
// --------------------------------------------
// variables end
// --------------------------------------------
// --------------------------------------------
// post handling start
// --------------------------------------------
if ( isset( $_POST['action'] ) ) {
$action = check_input($_POST['action']);
}
if ( isset( $_POST['dbType'] ) ) {
$dbType = check_input($_POST['dbType']);
}
if ( isset( $_POST['dbhost'] ) ) {
$dbHost = check_input($_POST['dbhost']);
}
if ( isset( $_POST['dbname'] ) ) {
$dbName = check_input($_POST['dbname']);
}
if ( isset( $_POST['dbuser'] ) ) {
$dbUser = check_input($_POST['dbuser']);
}
if ( isset( $_POST['dbpass'] ) ) {
$dbPass = check_input($_POST['dbpass']);
}
// --------------------------------------------
// post handling end
// --------------------------------------------
// --------------------------------------------
// functions start
// --------------------------------------------
/*
ensure that the input is not total waste
*/
function check_input( $data ) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
/*
create the config file with the database type
and the given connection credentials
*/
function write_config_file($dbt, $dbh, $dbn, $dbu, $dbp, $fsRoot) {
// construct the name of config file
//
$path = explode('/', $_SERVER['SCRIPT_FILENAME']);
array_pop($path);
array_push($path, 'settings.php');
$cfg_file_name = implode('/', $path);
if ( file_exists($cfg_file_name) && filesize( $cfg_file_name ) > 0 ) {
echo "<hr>The config file $cfg_file_name is already present</hr>";
return;
}
echo "Creating cfg file: " . $cfg_file_name;
// now build the content of the config file
//
$cfg_content = "<?php\n\n";
$cfg_content .= " // you can disable registration to the firefox sync server here,\n";
$cfg_content .= " // by setting ENABLE_REGISTER to false\n";
$cfg_content .= " // \n";
$cfg_content .= " define(\"ENABLE_REGISTER\", true);\n\n";
$cfg_content .= " // firefox sync server url, this should end with a /\n";
$cfg_content .= " // e.g. https://YourDomain.de/Folder_und_ggf_/index.php/\n";
$cfg_content .= " // \n";
$cfg_content .= " define(\"FSYNCMS_ROOT\", \"$fsRoot\");\n\n";
$cfg_content .= " // Database connection credentials\n";
$cfg_content .= " // \n";
$cfg_content .= " define(\"SQLITE_FILE\", \"weave_db\");\n";
if ( $dbt != "mysql" ) {
$cfg_content .= " define(\"MYSQL_ENABLE\", false);\n";
$cfg_content .= " define(\"MYSQL_HOST\", \"localhost\");\n";
$cfg_content .= " define(\"MYSQL_DB\", \"fsync\");\n";
$cfg_content .= " define(\"MYSQL_USER\", \"fsyncUserName\");\n";
$cfg_content .= " define(\"MYSQL_PASSWORD\", \"fsyncUserPassword\");\n";
} else {
$cfg_content .= " define(\"MYSQL_ENABLE\", true);\n";
$cfg_content .= " define(\"MYSQL_HOST\", \"$dbh\");\n";
$cfg_content .= " define(\"MYSQL_DB\", \"$dbn\");\n";
$cfg_content .= " define(\"MYSQL_USER\", \"$dbu\");\n";
$cfg_content .= " define(\"MYSQL_PASSWORD\", \"$dbp\");\n";
}
$cfg_content .= "\n";
$cfg_content .= " // Use bcrypt instead of MD5 for password hashing\n";
$cfg_content .= " define(\"BCRYPT\", true);\n";
$cfg_content .= " define(\"BCRYPT_ROUNDS\", 12);\n";
$cfg_content .= "\n?>\n";
// now write everything
//
$cfg_file = fopen($cfg_file_name, "a");
fputs($cfg_file, "$cfg_content");
fclose($cfg_file);
}
/*
print the html header for the form
*/
function print_header( $title ) {
if ( ! isset( $title ) ) {
$title = "";
}
print '<html><header><title>' . $title . '</title><body>
<h1>Setup FSyncMS</h1>
<form action="setup.php" method="post">';
}
/*
print the html footer
*/
function print_footer() {
print '</form></body></html>';
}
/*
print the html for for the mysql connection credentials
*/
function print_mysql_connection_form() {
print_header("MySQL database connection setup");
print 'MySQL database connection setup
<table>
<tr>
<td>Host</td>
<td><input type="text" name="dbhost" /></td>
</tr>
<tr>
<td>Instance name</td>
<td><input type="text" name="dbname" /></td>
</tr>
<tr>
<td>Username</td>
<td><input type="text" name="dbuser" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="dbpass" /></td>
</tr>
</table>
<input type="hidden" name="action" value="step2">
<input type="hidden" name="dbType" value="mysql">
<p><input type="submit" value="OK"></p>';
print_footer();
}
// --------------------------------------------
// functions end
// --------------------------------------------
// check if we have no configuration at the moment
//
if ( file_exists("settings.php") && filesize( "settings.php" ) > 0 ) {
echo "<hr><h2>The setup looks like it's completed, please delete settings.php</h2><hr>";
exit;
}
// inital page - select the database type
//
if ( ! $action ) {
// first check if we have pdo installed (untested)
//
if ( ! extension_loaded('PDO') ) {
print "ERROR - PDO is missing in the php installation!";
exit();
}
$validPdoDriver = 0;
print_header("Setup FSyncMS - DB Selection");
print 'Which database type should be used?<br>';
if ( extension_loaded('pdo_mysql') ) {
print '<input type="radio" name="dbType" value="mysql" /> MySQL <br>';
$validPdoDriver++;
} else {
print 'MySQL not possible (Driver missing) <br>';
}
if ( extension_loaded('pdo_sqlite') ) {
print '<input type="radio" name="dbType" value="sqlite" checked="checked" /> SQLite ';
$validPdoDriver++;
} else {
print 'SQLite not possible (Driver missing) <br>';
}
if ( $validPdoDriver < 1 ) {
print '<hr> No valid pdo driver found! Please install a valid pdo driver first <hr>';
} else {
print '<input type="hidden" name="action" value="step1">
<p><input type="submit" value="OK" /></p>';
}
// ensure we bail out at this point ;)
exit();
};
// step 2 (connection data) below
//
if ( $action == "step1" ) {
// now check if the database is in place
//
print_header("Setup FSyncMS - DB Setup: $dbType!");
switch ( $dbType ) {
case "sqlite":
$action = "step2";
break;
case "mysql":
print_mysql_connection_form();
break;
default:
print "ERROR - This type of database ($dbType) is not valid at the moment!";
exit();
break;
}
}
// now generate the database
//
if ( $action == "step2" ) {
$dbInstalled = false;
$dbHandle = null;
try {
if ( $dbType == "sqlite" ) {
$path = explode('/', $_SERVER['SCRIPT_FILENAME']);
$db_name = 'weave_db';
array_pop($path);
array_push($path, $db_name);
$db_name = implode('/', $path);
if ( file_exists($db_name) && filesize( $db_name ) > 0 ) {
$dbInstalled = true;
} else {
echo("Creating sqlite weave storage: ". $db_name ."<br>");
$dbHandle = new PDO('sqlite:' . $db_name);
$dbHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
} else if ( $dbType == "mysql" ) {
$dbHandle = new PDO("mysql:host=". $dbHost .";dbname=". $dbName, $dbUser, $dbPass);
$select_stmt = "show tables like 'wbo'";
$sth = $dbHandle->prepare($select_stmt);
$sth->execute();
$count = $sth->rowCount();
if ( $count > 0 ) {
$dbInstalled = true;
}
};
} catch ( PDOException $exception ) {
echo("database unavailable " . $exception->getMessage());
throw new Exception("Database unavailable " . $exception->getMessage() , 503);
}
if ( $dbInstalled ) {
echo "DB is already installed!<br>";
} else {
echo "Now going to install the new database! Type is: $dbType<br>";
try {
$create_statement = " create table wbo ( username varchar(100), id varchar(65), collection varchar(100),
parentid varchar(65), predecessorid int, modified real, sortindex int,
payload text, payload_size int, ttl int, primary key (username,collection,id))";
$create_statement2 = " create table users ( username varchar(255), md5 varchar(124), primary key (username)) ";
$index1 = 'create index parentindex on wbo (username, parentid)';
$index2 = 'create index predecessorindex on wbo (username, predecessorid)';
$index3 = 'create index modifiedindex on wbo (username, collection, modified)';
$sth = $dbHandle->prepare($create_statement);
$sth->execute();
$sth = $dbHandle->prepare($create_statement2);
$sth->execute();
$sth = $dbHandle->prepare($index1);
$sth->execute();
$sth = $dbHandle->prepare($index2);
$sth->execute();
$sth = $dbHandle->prepare($index3);
$sth->execute();
echo "Database created <br>";
} catch( PDOException $exception ) {
throw new Exception("Database unavailable", 503);
}
}
//guessing fsroot
// get the FSYNC_ROOT url
//
$fsRoot ="https://";
if ( ! isset($_SERVER['HTTPS']) ) {
$fsRoot = "http://";
}
$fsRoot .= $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . "/";
if( strpos( $_SERVER['REQUEST_URI'], 'index.php') !== 0 ) {
$fsRoot .= "index.php/";
}
// write settings.php, if not possible, display the needed contant
//
write_config_file($dbType, $dbHost, $dbName, $dbUser, $dbPass, $fsRoot);
echo "<hr><hr> Finished the setup, please delete setup.php and go on with the FFSync<hr><hr>";
echo <<<EOT
<hr><hr>
<h4>This script has guessed the Address of your installation, this might not be accurate,<br/>
Please check if this script can be reached by <a href="$fsRoot">$fsRoot</a> .<br/>
If thats not the case you have to ajust the settings.php<br />
</h4>
EOT;
}
?>

@ -26,10 +26,3 @@ public_url = http://localhost:5000/
# Set this to "false" to disable new-user signups on the server. # Set this to "false" to disable new-user signups on the server.
# Only request by existing accounts will be honoured. # Only request by existing accounts will be honoured.
# allow_new_users = false # allow_new_users = false
# Uncomment and edit the following to use a local BrowserID verifier
# rather than posing assertions to the mozilla-hosted verifier.
# Audiences should be set to your public_url without a trailing slash.
#[browserid]
#backend = tokenserver.verifiers.LocalVerifier
#audiences = https://localhost:5000

@ -11,10 +11,6 @@ from pyramid.events import NewRequest, subscriber
import mozsvc.config import mozsvc.config
from tokenserver.util import _JSONError
logger = logging.getLogger("syncserver")
def includeme(config): def includeme(config):
"""Install SyncServer application into the given Pyramid configurator.""" """Install SyncServer application into the given Pyramid configurator."""
@ -97,36 +93,18 @@ def includeme(config):
@subscriber(NewRequest) @subscriber(NewRequest)
def reconcile_wsgi_environ_with_public_url(event): def fixup_script_name(event):
"""Event-listener that checks and tweaks WSGI environ based on public_url. """Event-listener to fix up SCRIPT_NAME based on public_url setting.
This is a simple trick to help ensure that the configured public_url
matches the actual deployed address. It fixes fixes parts of the WSGI
environ where it makes sense (e.g. SCRIPT_NAME) and warns about any parts
that seem obviously mis-configured (e.g. http:// versus https://).
It's very important to get public_url and WSGI environ matching exactly, This is a simple little trick to avoid futzing with configuration in
since they're used for browserid audience checking and HAWK signature multiple places. The public_url setting tells us exactly what the root
validation, so mismatches can easily cause strange and cryptic errors. URL of the app should be, so we can use it to infer the proper value of
SCRIPT_NAME without depending on it being configured in the WSGI server.
""" """
request = event.request request = event.request
public_url = request.registry.settings["syncserver.public_url"] public_url = request.registry.settings["syncserver.public_url"]
p_public_url = urlparse(public_url)
# If we don't have a SCRIPT_NAME, take it from the public_url.
# This is often the case if we're behind e.g. an nginx proxy that
# is serving us at some sub-path.
if not request.script_name: if not request.script_name:
request.script_name = p_public_url.path.rstrip("/") request.script_name = urlparse(public_url).path.rstrip("/")
# Log a noisy error if the application url is different to what we'd
# expect based on public_url setting.
application_url = request.application_url
if public_url != application_url:
msg = "The public_url setting does not match the application url.\n"
msg += "This will almost certainly cause authentication failures!\n"
msg += " public_url setting is: %s\n" % (public_url,)
msg += " application url is: %s\n" % (application_url,)
logger.error(msg)
raise _JSONError([msg], status_code=500)
def get_configurator(global_config, **settings): def get_configurator(global_config, **settings):

@ -1,59 +0,0 @@
<?php
define("BCRYPT", true);
define("BCRYPT_ROUNDS", 12);
require_once __DIR__ . '/../weave_hash.php';
$pwd = "asdfASDFghjkGHJK2134$%&";
try {
$hash = WeaveHashFactory::factory();
$time_start = microtime(true);
echo $hash->hash($pwd) . "\n";
$time = microtime(true) - $time_start;
echo "Hashing took " . $time . " seconds\n";
if (!$hash->verify($pwd, '$2a$12$O2Bn6lDUYS5NDIJ1uCZjGezSI/jeGTD7Ow0bd3PFMRBcGIqfqI4Oi')) {
throw new Exception("bcrypt hash compare failed");
}
if (!$hash->needsUpdate(md5($pwd))) {
throw new Exception("bcrypt hash needs update.");
}
if ($hash->needsUpdate('$2a$12$O2Bn6lDUYS5NDIJ1uCZjGezSI/jeGTD7Ow0bd3PFMRBcGIqfqI4Oi')) {
throw new Exception("bcrypt hash doesn't needs update.");
}
if (!$hash->verify($pwd, 'a96b71c678b01b98b9f7a0d8ec4b633b')) {
throw new Exception("bcrypt hash compare with md5 failed");
}
$hash2 = new WeaveHashBCrypt(6);
if (!$hash2->needsUpdate('$2a$12$O2Bn6lDUYS5NDIJ1uCZjGezSI/jeGTD7Ow0bd3PFMRBcGIqfqI4Oi')) {
throw new Exception("bcrypt hash needs update because of different rounds.");
}
$hashmd5 = new WeaveHashMD5();
if (!$hashmd5->verify($pwd, 'a96b71c678b01b98b9f7a0d8ec4b633b')) {
throw new Exception("md5 hash compare failed");
}
if (!$hashmd5->needsUpdate('$2a$12$O2Bn6lDUYS5NDIJ1uCZjGezSI/jeGTD7Ow0bd3PFMRBcGIqfqI4Oi')) {
throw new Exception("md5 hash needs update.");
}
if ($hashmd5->needsUpdate(md5($pwd))) {
throw new Exception("md5 hash doesn't need update.");
}
echo "all tests ok\n";
exit(0);
} catch(Exception $e) {
echo $e->getMessage() . "\n";
exit(1);
}
?>

@ -1,275 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Initial Developer of the Original Code is balu
#
# Portions created by the Initial Developer are Copyright (C) 2012
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
/*
## DESCRIPTION: Implementation of user api v1.0
##
## AUTHOR: balu
##
## DATE: 20.02.2012
##
## VERSION: 0.1
*/
require_once 'weave_utils.php';
if(!$include) //file should only be used in context of index.php
{
log_error("include error");
report_problem('Function not found', 404);
}
require_once "settings.php";
// basic path extraction and validation. No point in going on if these are missing
$path = '/';
if (!empty($_SERVER['PATH_INFO']))
$path = $_SERVER['PATH_INFO'];
else if (!empty($_SERVER['ORIG_PATH_INFO']))
$path = $_SERVER['ORIG_PATH_INFO'];
else if (!empty($_SERVER["REQUEST_URI"]))
{
// improved path handling to prevent invalid server url error message in Firefox
log_error("experimental path");
// this is kind of an experimental try, i needed it so i build it,
// but that doesent mean that it does work... well it works for me
// and it shouldnt break anything...
$path = $_SERVER["REQUEST_URI"];
$lastfolder = substr(FSYNCMS_ROOT,strrpos(FSYNCMS_ROOT, "/",-2));
$path = substr($path, (strpos($path,$lastfolder) + strlen($lastfolder)-1)); // chop the lead slash
if(strpos($path,'?') != false)
$path = substr($path, 0, strpos($path,'?')); // remove php arguments
log_error("path_exp:".$path);
}
else
{
log_error("user.php: No path found");
report_problem("No path found", 404);
}
$path = substr($path, 1); #chop the lead slash
// split path into parts and make sure that all values are properly initialized
list($preinstr, $version, $username, $function, $collection, $id) = array_pad(explode('/', $path.'///'), 6, '');
log_error("Pfad:".$path);
if( $preinstr != 'user' && $preinstr != 'misc' )
report_problem('Function not found', 404);
if ($version != '1.0')
report_problem('Function not found', 404);
//if captcha
if(($preinstr =='misc') && ($_SERVER['REQUEST_METHOD'] == 'GET') && ($username =='captcha_html'))
{
if(ENABLE_REGISTER)
exit("And click to the next page");
else
exit("Register to this Server is not permitted, sorry");
}
//probably no need but...
header("Content-type: application/json");
//if ($function != "info" && $function != "storage")
// report_problem(WEAVE_ERROR_FUNCTION_NOT_SUPPORTED, 400);
if (!validate_username($username))
{
log_error( "invalid user");
report_problem(WEAVE_ERROR_INVALID_USERNAME, 400);
}
#user passes preliminaries, connections made, onto actually getting the data
try
{
if ($_SERVER['REQUEST_METHOD'] == 'GET')
{
$db = new WeaveStorage($username);
log_error("user.php: GET");
if($function == 'node' && $collection == 'weave') //client fragt node an
{
// reply node server for user
//to be compatible with users how use /index.php/ in their path
/*$index ="https://";
if (!isset($_SERVER['HTTPS']))
$index = "http://";
$index .= $_SERVER['SERVER_NAME']. dirname($_SERVER['SCRIPT_NAME']) . "/";
if(strpos($_SERVER['REQUEST_URI'],'index.php') !== 0)
$index .= "index.php/";
*/
// modification to support iPhone/iPod Touch devices
// check http://www.rfkd.de/?p=974 for further details
if (isset($_SERVER['HTTPS'])) {
exit("https://" . parse_url(FSYNCMS_ROOT, PHP_URL_HOST) . parse_url(FSYNCMS_ROOT, PHP_URL_PATH));
} else {
// allow http requests because use of self-signed certificates
// on iPhone/iPod Touch devices doesn't work
exit("http://" . parse_url(FSYNCMS_ROOT, PHP_URL_HOST) . parse_url(FSYNCMS_ROOT, PHP_URL_PATH));
}
}
else if($function == 'password_reset')
{
//email mit neuem pw senden
/*
Possible errors:
503: problems with looking up the user or sending the email
400: 12 (No email address on file)
400: 3 (Incorrect or missing username)
400: 2 (Incorrect or missing captcha)
*/
report_problem(WEAVE_ERROR_NO_EMAIL, 400);
}
//node/weave
else if($function == '' && $collection == '' && $id =='') //frage nach freiem usernamen
//User exists
{
//$db = new WeaveStorage($username);
if(exists_user($db))
exit(json_encode(1));
else
exit(json_encode(0));
}
else
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
}
else if($_SERVER['REQUEST_METHOD'] == 'PUT')
{
if(ENABLE_REGISTER)
{
$db = new WeaveStorage(null);
//Requests that an account be created for username.
/*
The JSON payload should include
Field Description
password The password to be associated with the account.
email Email address associated with the account
captcha-challenge The challenge string from the captcha (see miscellaneous functions below)
captcha-response The response to the captcha. Only required if WEAVE_REGISTER_USE_CAPTCHA is set
*/
log_error("PUT");
$data = get_json();
log_error(print_r($data,true));
//werte vorhanden
if($data == NULL)
report_problem(WEAVE_ERROR_JSON_PARSE, 400);
$name = $username;
$pwd = fix_utf8_encoding($data['password']);
$email = $data['email'];
if($email == '')
{
log_error('create user datenfehler');
report_problem(WEAVE_ERROR_NO_EMAIL, 400);
}
else if ( $pwd == '' )
{
log_error('create user datenfehler');
report_problem(WEAVE_ERROR_MISSING_PASSWORD, 400);
}
if($name == '' || $pwd == '' || $email == '')
{
log_error('create user datenfehler');
report_problem(WEAVE_ERROR_JSON_PARSE, 400);
}
log_error("create user ".$name." pw : ".$pwd);
try{
if ($db->create_user($name, $pwd))
{
log_error("successfully created user");
exit(json_encode(strtolower($name)));
}
else
{
log_error("create user failed");
report_problem(WEAVE_ERROR_NO_OVERWRITE, 503);
}
}
catch(Exception $e)
{
log_error("db exception create user");
header("X-Weave-Backoff: 1800");
report_problem($e->getMessage(), $e->getCode());
}
}
else
{
log_error("register not enabled");
report_problem(WEAVE_ERROR_FUNCTION_NOT_SUPPORTED,400);
}
} // ende put
else if($_SERVER['REQUEST_METHOD'] == 'POST')
{
if($username == '')
{
log_error("user.php : Post no username");
report_problem(WEAVE_ERROR_INVALID_USERNAME, 400);
}
$db = new WeaveStorage($username);
log_error("user.php: POST");
if($function == "password")
{
#Auth the user
verify_user($username, $db);
$new_pwd = get_phpinput();
log_error("user.php: POST password ");
//to do
// change pw in db
if($db->change_password($new_pwd))
exit("success");
else
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 503); //server db messed up somehow
// return success
// report_problem(7, 400);
}
else if($function == "email")
{
//change email adr
}
else
{
report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
}
// exit('success');
}
}
catch(Exception $e)
{
report_problem($e->getMessage(), $e->getCode());
}
#The datasets we might be dealing with here are too large for sticking it all into an array, so
#we need to define a direct-output method for the storage class to use. If we start producing multiples
#(unlikely), we can put them in their own class.
#include_once "WBOJsonOutput.php";
?>

@ -1,249 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Weave Basic Object Server
#
# The Initial Developer of the Original Code is
# Mozilla Labs.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Toby Elliott (telliott@mozilla.com)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
class wbo
{
var $wbo_hash = array();
var $_collection;
var $_error = array();
function extract_json(&$json)
{
$extracted = is_string($json) ? json_decode($json, true) : $json;
#need to check the json was valid here...
if ($extracted === null)
{
$this->_error[] = "unable to extract from json";
return false;
}
#must have an id, or all sorts of badness happens. However, it can be added later
if (array_key_exists('id', $extracted))
{
$this->id($extracted['id']);
}
if (array_key_exists('parentid', $extracted))
{
$this->parentid($extracted['parentid']);
}
if (array_key_exists('predecessorid', $extracted))
{
$this->predecessorid($extracted['predecessorid']);
}
if (array_key_exists('sortindex', $extracted))
{
# Due to complicated logic in the getter, we need to validate
# the value space of sortindex here.
if (!is_numeric($extracted['sortindex'])) {
$this->_error[] = "invalid sortindex";
return false;
}
$this->sortindex($extracted['sortindex']);
}
if (array_key_exists('payload', $extracted))
{
$this->payload($extracted['payload']);
}
return true;
}
function populate(&$datahash)
{
if (array_key_exists('id', $datahash))
$this->id($datahash['id']);
if (array_key_exists('collection', $datahash))
$this->collection($datahash['collection']);
if (array_key_exists('parentid', $datahash))
$this->parentid($datahash['parentid']);
if (array_key_exists('modified', $datahash))
$this->modified($datahash['modified']);
if (array_key_exists('predecessorid', $datahash))
$this->predecessorid($datahash['predecessorid']);
if (array_key_exists('sortindex', $datahash))
$this->sortindex($datahash['sortindex']);
if (array_key_exists('payload', $datahash))
$this->payload($datahash['payload']);
}
function id($id = null)
{
if (!is_null($id)) { $this->wbo_hash['id'] = (string)$id; }
return array_key_exists('id', $this->wbo_hash) ? $this->wbo_hash['id'] : null;
}
function collection($collection = null)
{
if (!is_null($collection)){ $this->_collection = $collection; }
return $this->_collection;
}
function parentid($parentid = null)
{
if (!is_null($parentid)){ $this->wbo_hash['parentid'] = (string)$parentid; }
return array_key_exists('parentid', $this->wbo_hash) ? $this->wbo_hash['parentid'] : null;
}
function parentid_exists()
{
return array_key_exists('parentid', $this->wbo_hash);
}
function predecessorid($predecessorid = null)
{
if (!is_null($predecessorid)){ $this->wbo_hash['predecessorid'] = (string)$predecessorid; }
return array_key_exists('predecessorid', $this->wbo_hash) ? $this->wbo_hash['predecessorid'] : null;
}
function predecessorid_exists()
{
return array_key_exists('predecessorid', $this->wbo_hash);
}
function modified($modified = null)
{
if (!is_null($modified)){ $this->wbo_hash['modified'] = round((float)$modified, 2); }
return array_key_exists('modified', $this->wbo_hash) ? $this->wbo_hash['modified'] : null;
}
function modified_exists()
{
return array_key_exists('modified', $this->wbo_hash);
}
function payload($payload = null)
{
if (!is_null($payload)){ $this->wbo_hash['payload'] = $payload; }
return array_key_exists('payload', $this->wbo_hash) ? $this->wbo_hash['payload'] : null;
}
function payload_exists()
{
return array_key_exists('payload', $this->wbo_hash);
}
function payload_size()
{
return mb_strlen($this->wbo_hash['payload'], '8bit');
}
function sortindex($index = null)
{
if (!is_null($index)){
$this->wbo_hash['sortindex'] = (int)($index);
}
return array_key_exists('sortindex', $this->wbo_hash) ? $this->wbo_hash['sortindex'] : null;
}
function sortindex_exists()
{
return array_key_exists('sortindex', $this->wbo_hash);
}
function validate()
{
if (!$this->id() || mb_strlen($this->id(), '8bit') > 64 || strpos($this->id(), '/') !== false)
{ $this->_error[] = "invalid id"; }
if ($this->parentid_exists() && mb_strlen($this->parentid(), '8bit') > 64)
{ $this->_error[] = "invalid parentid"; }
if ($this->predecessorid_exists() && mb_strlen($this->predecessorid(), '8bit') > 64)
{ $this->_error[] = "invalid predecessorid"; }
if (!is_numeric($this->modified()))
{ $this->_error[] = "invalid modified date"; }
if (!$this->modified())
{ $this->_error[] = "no modification date"; }
if (!$this->_collection || mb_strlen($this->_collection, '8bit') > 64)
{ $this->_error[] = "invalid collection"; }
if ($this->sortindex_exists() &&
(!is_numeric($this->wbo_hash['sortindex']) ||
intval($this->sortindex()) > 999999999 ||
intval($this->sortindex()) < -999999999 ))
{ $this->_error[] = "invalid sortindex"; }
if ($this->payload_exists())
{
if (!is_string($this->wbo_hash['payload']))
{ $this->_error[] = "payload needs to be json-encoded"; }
}
return !$this->get_error();
}
function get_error()
{
return $this->_error;
}
function clear_error()
{
$this->_error = array();
}
function raw_hash()
{
return $this->wbo_hash;
}
function json()
{
return json_encode($this->wbo_hash);
}
}
?>

@ -1,191 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is http://stackoverflow.com/a/6337021/833893
#
# Contributor(s):
# Daniel Triendl <daniel@pew.cc>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
interface WeaveHash {
public function hash($input);
public function verify($input, $existingHash);
public function needsUpdate($existingHash);
}
class WeaveHashMD5 implements WeaveHash {
public function hash($input) {
return md5($input);
}
public function verify($input, $existingHash) {
return $this->hash($input) == $existingHash;
}
public function needsUpdate($existingHash) {
return substr($existingHash, 0, 4) == "$2a$";
}
}
class WeaveHashBCrypt implements WeaveHash {
private $_rounds;
public function __construct($rounds = 12) {
if(CRYPT_BLOWFISH != 1) {
throw new Exception("bcrypt not available");
}
$this->_rounds = $rounds;
}
public function hash($input) {
$hash = crypt($input, $this->getSalt());
if (strlen($hash) <= 13) {
throw new Exception("error while generating hash");
}
return $hash;
}
public function verify($input, $existingHash) {
if ($this->isMD5($existingHash)) {
$md5 = new WeaveHashMD5();
return $md5->verify($input, $existingHash);
}
$hash = crypt($input, $existingHash);
return $hash === $existingHash;
}
public function needsUpdate($existingHash) {
$identifier = $this->getIdentifier();
return substr($existingHash, 0, strlen($identifier)) != $identifier;
}
private function isMD5($existingHash) {
return substr($existingHash, 0, 4) != "$2a$";
}
private function getSalt() {
$salt = $this->getIdentifier();
$bytes = $this->getRandomBytes(16);
$salt .= $this->encodeBytes($bytes);
return $salt;
}
private function getIdentifier() {
return sprintf("$2a$%02d$", $this->_rounds);
}
private $randomState;
private function getRandomBytes($count) {
$bytes = '';
if(function_exists('openssl_random_pseudo_bytes') &&
(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL slow on Win
$bytes = openssl_random_pseudo_bytes($count);
}
if($bytes === '' && is_readable('/dev/urandom') &&
($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
$bytes = fread($hRand, $count);
fclose($hRand);
}
if(strlen($bytes) < $count) {
$bytes = '';
if($this->randomState === null) {
$this->randomState = microtime();
if(function_exists('getmypid')) {
$this->randomState .= getmypid();
}
}
for($i = 0; $i < $count; $i += 16) {
$this->randomState = md5(microtime() . $this->randomState);
if (PHP_VERSION >= '5') {
$bytes .= md5($this->randomState, true);
} else {
$bytes .= pack('H*', md5($this->randomState));
}
}
$bytes = substr($bytes, 0, $count);
}
return $bytes;
}
private function encodeBytes($input) {
// The following is code from the PHP Password Hashing Framework
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (1);
return $output;
}
}
class WeaveHashFactory {
public static function factory() {
if (defined("BCRYPT") && BCRYPT) {
return new WeaveHashBCrypt(BCRYPT_ROUNDS);
} else {
return new WeaveHashMD5();
}
}
}
?>

@ -1,815 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Weave Basic Object Server
#
# The Initial Developer of the Original Code is
# Mozilla Labs.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Toby Elliott (telliott@mozilla.com)
# balu
# Daniel Triendl <daniel@pew.cc>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
require_once 'weave_basic_object.php';
require_once 'weave_utils.php';
require_once 'settings.php';
class WeaveStorage
{
private $_username;
private $_dbh;
function __construct($username)
{
$this->_username = $username;
log_error("Initalizing DB connecion!");
try
{
if ( ! MYSQL_ENABLE )
{
$path = explode('/', $_SERVER['SCRIPT_FILENAME']);
$db_name = SQLITE_FILE;
array_pop($path);
array_push($path, $db_name);
$db_name = implode('/', $path);
if ( ! file_exists($db_name) )
{
log_error("The required sqllite database is not present! $db_name");
}
log_error("Starting SQLite connection");
$this->_dbh = new PDO('sqlite:' . $db_name);
$this->_dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
else if ( MYSQL_ENABLE )
{
log_error("Starting MySQL connection");
$this->_dbh = new PDO("mysql:host=". MYSQL_HOST .";dbname=". MYSQL_DB, MYSQL_USER, MYSQL_PASSWORD);
}
}
catch( PDOException $exception )
{
log_error("database unavailable " . $exception->getMessage());
throw new Exception("Database unavailable " . $exception->getMessage() , 503);
}
}
function get_connection()
{
return $this->_dbh;
}
function begin_transaction()
{
try
{
$this->_dbh->beginTransaction();
}
catch( PDOException $exception )
{
error_log("begin_transaction: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return 1;
}
function commit_transaction()
{
$this->_dbh->commit();
return 1;
}
function get_max_timestamp($collection)
{
if (!$collection)
{
return 0;
}
try
{
$select_stmt = 'select max(modified) from wbo where username = :username and collection = :collection';
$sth = $this->_dbh->prepare($select_stmt);
$sth->bindParam(':username', $this->_username);
$sth->bindParam(':collection', $collection);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_max_timestamp: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$result = $sth->fetchColumn();
return round((float)$result, 2);
}
function get_collection_list()
{
try
{
$select_stmt = 'select distinct(collection) from wbo where username = :username';
$sth = $this->_dbh->prepare($select_stmt);
$sth->bindParam(':username', $this->_username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_collection_list: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$collections = array();
while ($result = $sth->fetchColumn())
{
$collections[] = $result;
}
return $collections;
}
function get_collection_list_with_timestamps()
{
try
{
$select_stmt = 'select collection, max(modified) as timestamp from wbo where username = :username group by collection';
$sth = $this->_dbh->prepare($select_stmt);
$sth->bindParam(':username', $this->_username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_collection_list: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$collections = array();
while ($result = $sth->fetch(PDO::FETCH_NUM))
{
$collections[$result[0]] = (float)$result[1];
}
return $collections;
}
function get_collection_list_with_counts()
{
try
{
$select_stmt = 'select collection, count(*) as ct from wbo where username = :username group by collection';
$sth = $this->_dbh->prepare($select_stmt);
$sth->bindParam(':username', $this->_username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_collection_list_with_counts: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$collections = array();
while ($result = $sth->fetch(PDO::FETCH_NUM))
{
$collections[$result[0]] = (int)$result[1];
}
return $collections;
}
function store_object(&$wbo)
{
try
{
$insert_stmt = 'replace into wbo (username, id, collection, parentid, predecessorid, sortindex, modified, payload, payload_size)
values (:username, :id, :collection, :parentid, :predecessorid, :sortindex, :modified, :payload, :payload_size)';
$sth = $this->_dbh->prepare($insert_stmt);
$username = $this->_username;
$id = $wbo->id();
$collection = $wbo->collection();
$parentid = $wbo->parentid();
$predecessorid = $wbo->predecessorid();
$sortindex = $wbo->sortindex();
$modified = $wbo->modified();
$payload = $wbo->payload();
$payload_size = $wbo->payload_size();
$sth->bindParam(':username', $username);
$sth->bindParam(':id', $id);
$sth->bindParam(':collection', $collection);
$sth->bindParam(':parentid', $parentid);
$sth->bindParam(':predecessorid', $predecessorid);
$sth->bindParam(':sortindex', $sortindex);
$sth->bindParam(':modified', $modified);
$sth->bindParam(':payload', $payload);
$sth->bindParam(':payload_size', $payload_size);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("store_object: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return 1;
}
function update_object(&$wbo)
{
$update = "update wbo set ";
$params = array();
$update_list = array();
#make sure we have an id and collection. No point in continuing otherwise
if (!$wbo->id() || !$wbo->collection())
{
error_log('Trying to update without a valid id or collection!');
return 0;
}
if ($wbo->parentid_exists())
{
$update_list[] = "parentid = ?";
$params[] = $wbo->parentid();
}
if ($wbo->predecessorid_exists())
{
$update_list[] = "predecessorid = ?";
$params[] = $wbo->predecessorid();
}
if ($wbo->sortindex_exists())
{
$update_list[] = "sortindex = ?";
$params[] = $wbo->sortindex();
}
if ($wbo->payload_exists())
{
$update_list[] = "payload = ?";
$update_list[] = "payload_size = ?";
$params[] = $wbo->payload();
$params[] = $wbo->payload_size();
}
# Don't modify the timestamp on a non-payload/non-parent change change
if ($wbo->parentid_exists() || $wbo->payload_exists())
{
#better make sure we have a modified date. Should have been handled earlier
if (!$wbo->modified_exists())
{
error_log("Called update_object with no defined timestamp. Please check");
$wbo->modified(microtime(1));
}
$update_list[] = "modified = ?";
$params[] = $wbo->modified();
}
if (count($params) == 0)
{
return 0;
}
$update .= join($update_list, ",");
$update .= " where username = ? and collection = ? and id = ?";
$params[] = $this->_username;
$params[] = $wbo->collection();
$params[] = $wbo->id();
try
{
$sth = $this->_dbh->prepare($update);
$sth->execute($params);
}
catch( PDOException $exception )
{
error_log("update_object: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return 1;
}
function delete_object($collection, $id)
{
try
{
$delete_stmt = 'delete from wbo where username = :username and collection = :collection and id = :id';
$sth = $this->_dbh->prepare($delete_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->bindParam(':collection', $collection);
$sth->bindParam(':id', $id);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("delete_object: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return 1;
}
function delete_objects($collection, $id = null, $parentid = null, $predecessorid = null, $newer = null,
$older = null, $sort = null, $limit = null, $offset = null, $ids = null,
$index_above = null, $index_below = null)
{
$params = array();
$select_stmt = '';
if ($limit || $offset || $sort)
{
#sqlite can't do sort or limit deletes without special compiled versions
#so, we need to grab the set, then delete it manually.
$params = $this->retrieve_objects($collection, $id, 0, 0, $parentid, $predecessorid, $newer, $older, $sort, $limit, $offset, $ids, $index_above, $index_below);
if (!count($params))
{
return 1; #nothing to delete
}
$paramqs = array();
$select_stmt = "delete from wbo where username = ? and collection = ? and id in (" . join(", ", array_pad($paramqs, count($params), '?')) . ")";
array_unshift($params, $collection);
array_unshift($params, $username);
}
else
{
$select_stmt = "delete from wbo where username = ? and collection = ?";
$params[] = $this->_username;
$params[] = $collection;
if ($id)
{
$select_stmt .= " and id = ?";
$params[] = $id;
}
if ($ids && count($ids) > 0)
{
$qmarks = array();
$select_stmt .= " and id in (";
foreach ($ids as $temp)
{
$params[] = $temp;
$qmarks[] = '?';
}
$select_stmt .= implode(",", $qmarks);
$select_stmt .= ')';
}
if ($parentid)
{
$select_stmt .= " and parentid = ?";
$params[] = $parentid;
}
if ($predecessorid)
{
$select_stmt .= " and predecessorid = ?";
$params[] = $parentid;
}
if ($index_above)
{
$select_stmt .= " and sortindex > ?";
$params[] = $parentid;
}
if ($index_below)
{
$select_stmt .= " and sortindex < ?";
$params[] = $parentid;
}
if ($newer)
{
$select_stmt .= " and modified > ?";
$params[] = $newer;
}
if ($older)
{
$select_stmt .= " and modified < ?";
$params[] = $older;
}
if ($sort == 'index')
{
$select_stmt .= " order by sortindex desc";
}
else if ($sort == 'newest')
{
$select_stmt .= " order by modified desc";
}
else if ($sort == 'oldest')
{
$select_stmt .= " order by modified";
}
}
try
{
$sth = $this->_dbh->prepare($select_stmt);
$sth->execute($params);
}
catch( PDOException $exception )
{
error_log("delete_objects: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return 1;
}
function retrieve_object($collection, $id)
{
try
{
$select_stmt = 'select * from wbo where username = :username and collection = :collection and id = :id';
$sth = $this->_dbh->prepare($select_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->bindParam(':collection', $collection);
$sth->bindParam(':id', $id);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("retrieve_object: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$result = $sth->fetch(PDO::FETCH_ASSOC);
$wbo = new wbo();
$wbo->populate($result);
return $wbo;
}
function retrieve_objects($collection, $id = null, $full = null, $direct_output = null, $parentid = null,
$predecessorid = null, $newer = null, $older = null, $sort = null,
$limit = null, $offset = null, $ids = null,
$index_above = null, $index_below = null)
{
$full_list = $full ? '*' : 'id';
$select_stmt = "select $full_list from wbo where username = ? and collection = ?";
$params[] = $this->_username;
$params[] = $collection;
if ($id)
{
$select_stmt .= " and id = ?";
$params[] = $id;
}
if ($ids && count($ids) > 0)
{
$qmarks = array();
$select_stmt .= " and id in (";
foreach ($ids as $temp)
{
$params[] = $temp;
$qmarks[] = '?';
}
$select_stmt .= implode(",", $qmarks);
$select_stmt .= ')';
}
if ($parentid)
{
$select_stmt .= " and parentid = ?";
$params[] = $parentid;
}
if ($predecessorid)
{
$select_stmt .= " and predecessorid = ?";
$params[] = $predecessorid;
}
if ($index_above)
{
$select_stmt .= " and sortindex > ?";
$params[] = $parentid;
}
if ($index_below)
{
$select_stmt .= " and sortindex < ?";
$params[] = $parentid;
}
if ($newer)
{
$select_stmt .= " and modified > ?";
$params[] = $newer;
}
if ($older)
{
$select_stmt .= " and modified < ?";
$params[] = $older;
}
if ($sort == 'index')
{
$select_stmt .= " order by sortindex desc";
}
else if ($sort == 'newest')
{
$select_stmt .= " order by modified desc";
}
else if ($sort == 'oldest')
{
$select_stmt .= " order by modified";
}
if ($limit)
{
$select_stmt .= " limit " . intval($limit);
if ($offset)
{
$select_stmt .= " offset " . intval($offset);
}
}
try
{
$sth = $this->_dbh->prepare($select_stmt);
$sth->execute($params);
}
catch( PDOException $exception )
{
error_log("retrieve_collection: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
if ($direct_output)
return $direct_output->output($sth);
$ids = array();
while ($result = $sth->fetch(PDO::FETCH_ASSOC))
{
if ($full)
{
$wbo = new wbo();
$wbo->populate($result);
$ids[] = $wbo;
}
else
$ids[] = $result{'id'};
}
return $ids;
}
function get_storage_total()
{
try
{
$select_stmt = 'select round(sum(length(payload))/1024) from wbo where username = :username';
$sth = $this->_dbh->prepare($select_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_storage_total: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
return (int)$sth->fetchColumn();
}
function get_collection_storage_totals()
{
try
{
$select_stmt = 'select collection, sum(payload_size) from wbo where username = :username group by collection';
$sth = $this->_dbh->prepare($select_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_storage_total (" . $this->connection_details_string() . "): " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$results = $sth->fetchAll(PDO::FETCH_NUM);
$sth->closeCursor();
$collections = array();
foreach ($results as $result)
{
$collections[$result[0]] = (int)$result[1];
}
return $collections;
}
function get_user_quota()
{
return null;
}
function delete_storage($username)
{
log_error("delete storage");
if (!$username)
{
throw new Exception("3", 404);
}
try
{
$delete_stmt = 'delete from wbo where username = :username';
$sth = $this->_dbh->prepare($delete_stmt);
$sth->bindParam(':username', $username);
$sth->execute();
$sth->closeCursor();
}
catch( PDOException $exception )
{
error_log("delete_user: " . $exception->getMessage());
return 0;
}
return 1;
}
function delete_user($username)
{
log_error("delete User");
if (!$username)
{
throw new Exception("3", 404);
}
try
{
$delete_stmt = 'delete from users where username = :username';
$sth = $this->_dbh->prepare($delete_stmt);
$sth->bindParam(':username', $username);
$sth->execute();
$sth->closeCursor();
$delete_wbo_stmt = 'delete from wbo where username = :username';
$sth = $this->_dbh->prepare($delete_wbo_stmt);
$sth->bindParam(':username', $username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("delete_user: " . $exception->getMessage());
return 0;
}
return 1;
}
function create_user($username, $password)
{
log_error("Create User - Username: ".$username."|".$password);
try
{
$create_statement = "insert into users values (:username, :md5)";
$sth = $this->_dbh->prepare($create_statement);
$hash = WeaveHashFactory::factory();
$password = $hash->hash($password);
$sth->bindParam(':username', $username);
$sth->bindParam(':md5', $password);
$sth->execute();
}
catch( PDOException $exception )
{
log_error("create_user:" . $exception->getMessage());
error_log("create_user:" . $exception->getMessage());
return 0;
}
return 1;
}
function change_password($hash)
{
try
{
$update_statement = "update users set md5 = :md5 where username = :username";
$sth = $this->_dbh->prepare($update_statement);
$sth->bindParam(':username', $this->_username);
$sth->bindParam(':md5', $hash);
$sth->execute();
}
catch( PDOException $exception )
{
log_error("change_password:" . $exception->getMessage());
return 0;
}
return 1;
}
#function checks if user exists
function exists_user()
{
try
{
$select_stmt = 'select username from users where username = :username';
$sth = $this->_dbh->prepare($select_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("exists_user: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
if (!$result = $sth->fetch(PDO::FETCH_ASSOC))
{
return null;
}
return 1;
}
function get_password_hash()
{
log_error("auth-user: " . $this->_username);
try
{
$select_stmt = 'select md5 from users where username = :username';
$sth = $this->_dbh->prepare($select_stmt);
$username = $this->_username;
$sth->bindParam(':username', $username);
$sth->execute();
}
catch( PDOException $exception )
{
error_log("get_password_hash: " . $exception->getMessage());
throw new Exception("Database unavailable", 503);
}
$result = $sth->fetchColumn();
if ($result === FALSE) $result = "";
return $result;
}
}
?>

@ -1,286 +0,0 @@
<?php
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Initial Developer of the Original Code is balu
#
# Portions created by the Initial Developer are Copyright (C) 2012
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Daniel Triendl <daniel@pew.cc>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#Error constants
define ('WEAVE_ERROR_INVALID_PROTOCOL', 1);
define ('WEAVE_ERROR_INCORRECT_CAPTCHA', 2);
define ('WEAVE_ERROR_INVALID_USERNAME', 3);
define ('WEAVE_ERROR_NO_OVERWRITE', 4);
define ('WEAVE_ERROR_USERID_PATH_MISMATCH', 5);
define ('WEAVE_ERROR_JSON_PARSE', 6);
define ('WEAVE_ERROR_MISSING_PASSWORD', 7);
define ('WEAVE_ERROR_INVALID_WBO', 8);
define ('WEAVE_ERROR_BAD_PASSWORD_STRENGTH', 9);
define ('WEAVE_ERROR_INVALID_RESET_CODE', 10);
define ('WEAVE_ERROR_FUNCTION_NOT_SUPPORTED', 11);
define ('WEAVE_ERROR_NO_EMAIL', 12);
define ('WEAVE_ERROR_INVALID_COLLECTION', 13);
define ('LOG_THE_ERROR', 0);
function log_error($msg)
{
if ( LOG_THE_ERROR == 1 )
{
$datei = fopen("/tmp/FSyncMS-error.txt","a");
$fmsg = sprintf("$msg\n");
fputs($datei,$fmsg);
fputs($datei,"Server ".print_r( $_SERVER, true));
fclose($datei);
}
}
function report_problem($message, $code = 503)
{
$headers = array('400' => '400 Bad Request',
'401' => '401 Unauthorized',
'403' => '403 Forbidden',
'404' => '404 Not Found',
'412' => '412 Precondition Failed',
'503' => '503 Service Unavailable');
header('HTTP/1.1 ' . $headers{$code},true,$code);
if ($code == 401)
{
header('WWW-Authenticate: Basic realm="Weave"');
}
log_error($message);
exit(json_encode($message));
}
function fix_utf8_encoding($string)
{
if(mb_detect_encoding($string . " ", 'UTF-8,ISO-8859-1') == 'UTF-8')
return $string;
else
return utf8_encode($string);
}
function get_phpinput()
{
#stupid php being helpful with input data...
$putdata = fopen("php://input", "r");
$string = '';
while ($data = fread($putdata,2048)) {$string .= $data;} //hier will man ein limit einbauen
return $string;
}
function get_json()
{
$jsonstring = get_phpinput();
$json = json_decode(fix_utf8_encoding($jsonstring), true);
if ($json === null)
report_problem(WEAVE_ERROR_JSON_PARSE, 400);
return $json;
}
function validate_username($username)
{
if (!$username)
return false;
if (strlen($username) > 32)
return false;
return preg_match('/[^A-Z0-9._-]/i', $username) ? false : true;
}
function validate_collection($collection)
{
if (!$collection)
return false;
if (strlen($collection) > 32)
return false;
// allow characters '?' and '=' in the collection string which e.g.
// appear if the following request is send from firefox:
// http://<server>/weave/1.1/<user>/storage/clients?full=1
return preg_match('/[^A-Z0-9?=._-]/i', $collection) ? false : true;
}
#user exitsts
function exists_user( $db)
{
#$user = strtolower($user);
try{
if(!$db->exists_user())
return 0;
return 1;
}
catch(Exception $e)
{
header("X-Weave-Backoff: 1800");
report_problem($e->getMessage(), $e->getCode());
}
}
# Gets the username and password out of the http headers, and checks them against the auth
function verify_user($url_user, $db)
{
if (!$url_user || !preg_match('/^[A-Z0-9._-]+$/i', $url_user))
report_problem(WEAVE_ERROR_INVALID_USERNAME, 400);
$auth_user = array_key_exists('PHP_AUTH_USER', $_SERVER) ? $_SERVER['PHP_AUTH_USER'] : null;
$auth_pw = array_key_exists('PHP_AUTH_PW', $_SERVER) ? $_SERVER['PHP_AUTH_PW'] : null;
if (is_null($auth_user) || is_null($auth_pw))
{
/* CGI/FCGI auth workarounds */
$auth_str = null;
if (array_key_exists('Authorization', $_SERVER))
/* Standard fastcgi configuration */
$auth_str = $_SERVER['Authorization'];
else if (array_key_exists('AUTHORIZATION', $_SERVER))
/* Alternate fastcgi configuration */
$auth_str = $_SERVER['AUTHORIZATION'];
else if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER))
/* IIS/ISAPI and newer (yet to be released) fastcgi */
$auth_str = $_SERVER['HTTP_AUTHORIZATION'];
else if (array_key_exists('REDIRECT_HTTP_AUTHORIZATION', $_SERVER))
/* mod_rewrite - per-directory internal redirect */
$auth_str = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
if (!is_null($auth_str))
{
/* Basic base64 auth string */
if (preg_match('/Basic\s+(.*)$/', $auth_str))
{
$auth_str = substr($auth_str, 6);
$auth_str = base64_decode($auth_str, true);
if ($auth_str != FALSE) {
$tmp = explode(':', $auth_str);
if (count($tmp) == 2)
{
$auth_user = $tmp[0];
$auth_pw = $tmp[1];
}
}
}
}
}
if ( ! $auth_user || ! $auth_pw) #do this first to avoid the cryptic error message if auth is missing
{
log_error("Auth failed 1 {");
log_error(" User pw: ". $auth_user ." | ". $auth_pw);
log_error(" Url_user: ". $url_user);
log_error("}");
report_problem('Authentication failed', '401');
}
$url_user = strtolower($url_user);
if (strtolower($auth_user) != $url_user)
{
log_error("(140) Missmatch:".strtolower($auth_user)."|".$url_user);
report_problem(WEAVE_ERROR_USERID_PATH_MISMATCH, 400);
}
try
{
$existingHash = $db->get_password_hash();
$hash = WeaveHashFactory::factory();
if ( ! $hash->verify(fix_utf8_encoding($auth_pw), $existingHash) )
{
log_error("Auth failed 2 {");
log_error(" User pw: ". $auth_user ."|".$auth_pw ."|md5:". md5($auth_pw) ."|fix:". fix_utf8_encoding($auth_pw) ."|fix md5 ". md5(fix_utf8_encoding($auth_pw)));
log_error(" Url_user: ".$url_user);
log_error(" Existing hash: ".$existingHash);
log_error("}");
report_problem('Authentication failed', '401');
} else {
if ( $hash->needsUpdate($existingHash) ) {
$db->change_password($hash->hash(fix_utf8_encoding($auth_pw)));
}
}
}
catch(Exception $e)
{
header("X-Weave-Backoff: 1800");
log_error($e->getMessage(), $e->getCode());
report_problem($e->getMessage(), $e->getCode());
}
return true;
}
function check_quota(&$db)
{
return;
}
function check_timestamp($collection, &$db)
{
if (array_key_exists('HTTP_X_IF_UNMODIFIED_SINCE', $_SERVER)
&& $db->get_max_timestamp($collection) > $_SERVER['HTTP_X_IF_UNMODIFIED_SINCE'])
report_problem(WEAVE_ERROR_NO_OVERWRITE, 412);
}
function validate_search_params()
{
$params = array();
$params['parentid'] = (array_key_exists('parentid', $_GET) && mb_strlen($_GET['parentid'], '8bit') <= 64 && strpos($_GET['parentid'], '/') === false) ? $_GET['parentid'] : null;
$params['predecessorid'] = (array_key_exists('predecessorid', $_GET) && mb_strlen($_GET['predecessorid'], '8bit') <= 64 && strpos($_GET['predecessorid'], '/') === false) ? $_GET['predecessorid'] : null;
$params['newer'] = (array_key_exists('newer', $_GET) && is_numeric($_GET['newer'])) ? round($_GET['newer'],2) : null;
$params['older'] = (array_key_exists('older', $_GET) && is_numeric($_GET['older'])) ? round($_GET['older'],2) : null;
$params['sort'] = (array_key_exists('sort', $_GET) && ($_GET['sort'] == 'oldest' || $_GET['sort'] == 'newest' || $_GET['sort'] == 'index')) ? $_GET['sort'] : null;
$params['limit'] = (array_key_exists('limit', $_GET) && is_numeric($_GET['limit']) && $_GET['limit'] > 0) ? (int)$_GET['limit'] : null;
$params['offset'] = (array_key_exists('offset', $_GET) && is_numeric($_GET['offset']) && $_GET['offset'] > 0) ? (int)$_GET['offset'] : null;
$params['ids'] = null;
if (array_key_exists('ids', $_GET))
{
$params['ids'] = array();
foreach(explode(',', $_GET['ids']) as $id)
{
if (mb_strlen($id, '8bit') <= 64 && strpos($id, '/') === false)
$params['ids'][] = $id;
}
}
$params['index_above'] = (array_key_exists('index_above', $_GET) && is_numeric($_GET['index_above']) && $_GET['index_above'] > 0) ? (int)$_GET['index_above'] : null;
$params['index_below'] = (array_key_exists('index_below', $_GET) && is_numeric($_GET['index_below']) && $_GET['index_below'] > 0) ? (int)$_GET['index_below'] : null;
$params['depth'] = (array_key_exists('depth', $_GET) && is_numeric($_GET['depth']) && $_GET['depth'] > 0) ? (int)$_GET['depth'] : null;
return $params;
}
?>
Loading…
Cancel
Save