mirror of
https://github.com/YunoHost-Apps/ffsync_ynh.git
synced 2024-09-03 18:26:38 +02:00
add version 1.5
This commit is contained in:
parent
69da6780e5
commit
1886f9b68d
16 changed files with 20 additions and 2901 deletions
|
@ -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
|
This is a simple little trick to avoid futzing with configuration in
|
||||||
matches the actual deployed address. It fixes fixes parts of the WSGI
|
multiple places. The public_url setting tells us exactly what the root
|
||||||
environ where it makes sense (e.g. SCRIPT_NAME) and warns about any parts
|
URL of the app should be, so we can use it to infer the proper value of
|
||||||
that seem obviously mis-configured (e.g. http:// versus https://).
|
SCRIPT_NAME without depending on it being configured in the WSGI server.
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
"""
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
275
sources/user.php
275
sources/user.php
|
@ -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…
Reference in a new issue