diff --git a/sources/Dockerfile b/sources/Dockerfile index 53208bc..2dd65e1 100644 --- a/sources/Dockerfile +++ b/sources/Dockerfile @@ -10,8 +10,7 @@ MAINTAINER Dan Callahan # Base system setup -RUN DEBIAN_FRONTEND=noninteractive apt-get update \ - && apt-get install --no-install-recommends -y \ +RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ vim locales \ && apt-get clean @@ -25,6 +24,7 @@ RUN useradd --create-home app RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ ca-certificates \ + curl \ build-essential \ libzmq-dev \ python-dev \ @@ -34,9 +34,11 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ USER app RUN mkdir -p /home/app/syncserver -ADD ./ /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 the Sync server diff --git a/sources/Makefile b/sources/Makefile index e9c0d63..52adba5 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -6,23 +6,18 @@ TOOLS := $(addprefix $(ENV)/bin/,flake8 nosetests) # Hackety-hack around OSX system python bustage. # The need for this should go away with a future osx/xcode update. ARCHFLAGS = -Wno-error=unused-command-line-argument-hard-error-in-future - -# Hackety-hack around errors duing compile of ultramemcached. -CFLAGS = -Wno-error - -INSTALL = CFLAGS=$(CFLAGS) ARCHFLAGS=$(ARCHFLAGS) $(ENV)/bin/pip install - +INSTALL = ARCHFLAGS=$(ARCHFLAGS) $(ENV)/bin/pip install .PHONY: all all: build .PHONY: build -build: | $(ENV)/COMPLETE -$(ENV)/COMPLETE: requirements.txt +build: | $(ENV) +$(ENV): requirements.txt $(VIRTUALENV) --no-site-packages $(ENV) $(INSTALL) -r requirements.txt $(ENV)/bin/python ./setup.py develop - touch $(ENV)/COMPLETE + touch $(ENV) .PHONY: test test: | $(TOOLS) @@ -38,11 +33,11 @@ test: | $(TOOLS) --use-token-server http://localhost:5000/token/1.0/sync/1.5; \ kill $$SERVER_PID -$(TOOLS): | $(ENV)/COMPLETE +$(TOOLS): | $(ENV) $(INSTALL) nose flake8 .PHONY: serve -serve: | $(ENV)/COMPLETE +serve: | $(ENV) $(ENV)/bin/pserve ./syncserver.ini .PHONY: clean diff --git a/sources/README.md b/sources/README.md deleted file mode 100644 index bdec77e..0000000 --- a/sources/README.md +++ /dev/null @@ -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 - - - - -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 diff --git a/sources/TODO b/sources/TODO deleted file mode 100644 index b22ef93..0000000 --- a/sources/TODO +++ /dev/null @@ -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 diff --git a/sources/WBOJsonOutput.php b/sources/WBOJsonOutput.php deleted file mode 100644 index 01139d5..0000000 --- a/sources/WBOJsonOutput.php +++ /dev/null @@ -1,154 +0,0 @@ -_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; - } -} -?> diff --git a/sources/index.php b/sources/index.php deleted file mode 100644 index e59d393..0000000 --- a/sources/index.php +++ /dev/null @@ -1,329 +0,0 @@ -

Maybe the setup is not completed, missing settings.php


"; - exit; - - } else if ( file_exists("setup.php") ) { - echo "

Maybe the setup is not completed, else please delete setup.php


"; - 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"; -?> diff --git a/sources/requirements.txt b/sources/requirements.txt index 39b7025..4fce41d 100644 --- a/sources/requirements.txt +++ b/sources/requirements.txt @@ -1,13 +1,9 @@ cornice==0.16.2 -gunicorn==19.1.1 pyramid==1.5 requests==2.2.1 simplejson==3.4 SQLAlchemy==0.9.4 unittest2==0.5.1 -https://github.com/mozilla-services/mozservices/archive/e00e1b68130423ad98d0f6185655bde650443da8.zip -https://github.com/mozilla-services/tokenserver/archive/d7e513e8a4f5c588b70d685a8df1d2e508c341c0.zip +http://github.com/mozilla-services/mozservices/archive/5fabece891bbd3bd2c9528cb3bf0562b3efb4af1.zip +https://github.com/mozilla-services/tokenserver/archive/1.2.7.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 diff --git a/sources/setup.php b/sources/setup.php deleted file mode 100644 index 27916d1..0000000 --- a/sources/setup.php +++ /dev/null @@ -1,399 +0,0 @@ - -# 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 "
The config file $cfg_file_name is already present"; - return; - } - - echo "Creating cfg file: " . $cfg_file_name; - - // now build the content of the config file - // - $cfg_content = "\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 '
' . $title . ' -

Setup FSyncMS

-
'; -} - - -/* - print the html footer -*/ -function print_footer() { - print '
'; -} - - -/* - 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 - - - - - - - - - - - - - - - - - -
Host
Instance name
Username
Password
- - - -

'; - print_footer(); -} -// -------------------------------------------- -// functions end -// -------------------------------------------- - -// check if we have no configuration at the moment -// -if ( file_exists("settings.php") && filesize( "settings.php" ) > 0 ) { - echo "

The setup looks like it's completed, please delete settings.php


"; - 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?
'; - if ( extension_loaded('pdo_mysql') ) { - print ' MySQL
'; - $validPdoDriver++; - } else { - print 'MySQL not possible (Driver missing)
'; - } - - if ( extension_loaded('pdo_sqlite') ) { - print ' SQLite '; - $validPdoDriver++; - } else { - print 'SQLite not possible (Driver missing)
'; - } - - if ( $validPdoDriver < 1 ) { - print '
No valid pdo driver found! Please install a valid pdo driver first
'; - } else { - print ' -

'; - } - - // 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 ."
"); - $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!
"; - - } else { - echo "Now going to install the new database! Type is: $dbType
"; - - 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
"; - - } 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 "

Finished the setup, please delete setup.php and go on with the FFSync

"; - echo <<
-

This script has guessed the Address of your installation, this might not be accurate,
- Please check if this script can be reached by $fsRoot .
- If thats not the case you have to ajust the settings.php
-

-EOT; -} - -?> diff --git a/sources/syncserver.ini b/sources/syncserver.ini index 63cb2d5..de9c7da 100644 --- a/sources/syncserver.ini +++ b/sources/syncserver.ini @@ -26,10 +26,3 @@ public_url = http://localhost:5000/ # Set this to "false" to disable new-user signups on the server. # Only request by existing accounts will be honoured. # 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 diff --git a/sources/syncserver/__init__.py b/sources/syncserver/__init__.py index eb90f6a..465bf62 100644 --- a/sources/syncserver/__init__.py +++ b/sources/syncserver/__init__.py @@ -11,10 +11,6 @@ from pyramid.events import NewRequest, subscriber import mozsvc.config -from tokenserver.util import _JSONError - -logger = logging.getLogger("syncserver") - def includeme(config): """Install SyncServer application into the given Pyramid configurator.""" @@ -97,36 +93,18 @@ def includeme(config): @subscriber(NewRequest) -def reconcile_wsgi_environ_with_public_url(event): - """Event-listener that checks and tweaks WSGI environ based on public_url. - - 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://). +def fixup_script_name(event): + """Event-listener to fix up SCRIPT_NAME based on public_url setting. - It's very important to get public_url and WSGI environ matching exactly, - since they're used for browserid audience checking and HAWK signature - validation, so mismatches can easily cause strange and cryptic errors. + This is a simple little trick to avoid futzing with configuration in + multiple places. The public_url setting tells us exactly what the root + 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 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: - request.script_name = p_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) + request.script_name = urlparse(public_url).path.rstrip("/") def get_configurator(global_config, **settings): diff --git a/sources/test/hash.php b/sources/test/hash.php deleted file mode 100644 index a7652b3..0000000 --- a/sources/test/hash.php +++ /dev/null @@ -1,59 +0,0 @@ -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); -} - -?> \ No newline at end of file diff --git a/sources/user.php b/sources/user.php deleted file mode 100644 index 4c8e905..0000000 --- a/sources/user.php +++ /dev/null @@ -1,275 +0,0 @@ -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"; - -?> diff --git a/sources/weave_basic_object.php b/sources/weave_basic_object.php deleted file mode 100644 index 305dfd5..0000000 --- a/sources/weave_basic_object.php +++ /dev/null @@ -1,249 +0,0 @@ -_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); - } -} - - -?> \ No newline at end of file diff --git a/sources/weave_hash.php b/sources/weave_hash.php deleted file mode 100644 index fc951a5..0000000 --- a/sources/weave_hash.php +++ /dev/null @@ -1,191 +0,0 @@ - -# -# 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(); - } - } -} - -?> \ No newline at end of file diff --git a/sources/weave_storage.php b/sources/weave_storage.php deleted file mode 100644 index 9afaa9a..0000000 --- a/sources/weave_storage.php +++ /dev/null @@ -1,815 +0,0 @@ - -# -# 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; - } - -} - - -?> diff --git a/sources/weave_utils.php b/sources/weave_utils.php deleted file mode 100644 index a2b1047..0000000 --- a/sources/weave_utils.php +++ /dev/null @@ -1,286 +0,0 @@ - -# -# 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:///weave/1.1//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; - } - -?>