Compare commits

...

33 Commits

Author SHA1 Message Date
Daniel Martinez f8557c909f fix new location for elasticsearch 2018-07-24 02:25:42 -04:00
Patrick Höhn ada97d6309 Update add_user 2017-07-30 22:50:54 +02:00
Patrick Höhn d781dd02d2 Update add_user 2017-07-30 22:48:34 +02:00
Patrick Höhn 1a7a003137 corrected database name 2017-07-30 22:33:11 +02:00
Patrick Höhn 1c042627bb Update change_password
change password hashing from password_hash to md5
2017-07-30 22:13:40 +02:00
Patrick Höhn f1cce1dec1 Update add_user
change password crash creation from password_hash to md5
2017-07-30 22:11:34 +02:00
Patrick Höhn 5e0ec55f92 set shell to bash 2015-03-14 20:05:52 +01:00
Patrick Höhn d5bb496955 bug fix 2015-03-14 20:01:46 +01:00
Patrick Höhn d84037ecd5 syntax corrections 2015-03-14 18:58:36 +01:00
Patrick Höhn a1f56311e7 minor syntax improvements 2015-03-14 14:51:42 +01:00
Patrick Höhn ba05694f4d add possibility to install zotero without SSL
add CACert root certificate when needed

add option to either generate or use custom SSL certificates

patch AWS-SDK to use custom S3 servers
2015-03-14 14:17:23 +01:00
Patrick Höhn 6b3d67b731 add password.php to gain compatibility of the Zotero password code by backported changes to php 5.5 2015-03-12 17:39:32 +01:00
Patrick Höhn 6f2c641053 corrected path of files in script 2015-02-08 01:00:48 +01:00
Patrick Höhn 226afff236 adjusted repository for elastic search because of updated URL 2015-02-08 00:41:07 +01:00
Patrick Höhn 91ec2c012f temporarly deactivated wheezy-back ports repository, potentially not required any more 2014-11-20 15:53:04 +01:00
Patrick Höhn 74496231e3 add as installation method again, as it seems difficult to replace composer installation files with native packages
remove installation of aws-php-sdk and php-doctrine-cache packages
2014-11-20 15:49:37 +01:00
Patrick Höhn dda227e98b completed fix for UTF-8 2014-11-19 03:30:19 +01:00
Patrick Höhn a9f8c009d8 added repository for elastic search and install elastic serach package
added wheezy backports repository
added script file to change password of user
fixed problems regarding special characters (UTF-8)
2014-11-19 03:27:07 +01:00
Patrick Höhn 349eb346ee change to swedish debian mirror 2014-10-31 22:25:32 +01:00
Patrick Höhn 8c7831db29 add wheezy-backports repository during the installation process
add php packages to avoid using composer for installing aws-php-sdk and php-doctrine-cache
2014-10-31 21:40:51 +01:00
Patrick Höhn 1e7f2bec8e corrected help text 2014-10-31 20:06:12 +01:00
Patrick Höhn 6ab96c3d86 corrected typo 2014-10-31 19:55:43 +01:00
Patrick Höhn f8abc4616c patch master.sql to create an automatic storage expiration of 10 years after account creation
add patching master.sql to install_zotero.sh
2014-10-30 16:21:37 +01:00
Patrick Höhn fb19bcb1ff added script for adding of user to zotero
modified install_zotero.sh to include the newly added_script
2014-10-30 15:59:38 +01:00
Patrick Höhn 1440f927e8 another update of the schema for the zotero_www database.
introduces references between tables
2014-10-29 19:12:34 +01:00
Patrick Höhn b6bbde73a2 hopefully final www.sql file
Adjustments in install_zotero.sh for adding values to LUM_Role table in zotero_www
2014-10-28 19:44:51 +01:00
Patrick Höhn 4615155a52 add preliminary scheme for zotero_www database 2014-10-28 06:18:11 +01:00
Patrick Höhn 2d83459c89 added path for www.sql, assuming it will be in the same directory as the installation script 2014-10-28 06:13:26 +01:00
Patrick Höhn 5b691aa37d first hopefully complete version for vanilla data server
needs further testing for debugging
2014-10-28 06:01:57 +01:00
Patrick Höhn c94902fb64 added comment about shift from sualk fork of zotero dataserver to vanilla zotero dataserver 2014-10-27 14:09:37 +01:00
Patrick Höhn d2592ef84e Merge branch 'master' of https://github.com/hoehnp/zotero_installation 2014-10-27 14:01:08 +01:00
Patrick Höhn f5340ede89 work in progress adjusting the installation script for vanilla zotero dataserver 2014-10-27 13:57:55 +01:00
Patrick Höhn 4f3144918d bug fixing 2014-09-30 16:46:53 +02:00
7 changed files with 1156 additions and 86 deletions

View File

@ -3,4 +3,4 @@ zotero_installation
installation script for zotero dataserver
It automates the installation steps provided by sualk in his github repository for the zotero data server.
It automates the installation steps provided by sualk in his github repository for the zotero data server. New versions will focus on installing the vanilla zotero dataserver.

50
add_user Normal file
View File

@ -0,0 +1,50 @@
#!/usr/local/bin/php
<?
set_include_path("../include");
require("header.inc.php");
if (empty($argv[1]) || empty($argv[2]) || empty($argv[3]) || empty($argv[4])) {
die("Usage: $argv[0] " . '$username $email $password $real_user_name' . "\n");
}
$username = $argv[1];
$email = $argv[2];
$password = $argv[3];
$real_user = $argv[4];
echo "Adding new user $username\n";
$passwordhash = md5($password);
#$libraryID = Zotero_Libraries::add('user', 1);
Zotero_DB::beginTransaction();
$sql = "INSERT INTO zotero_www_test.users (username, password) VALUES (?,?)";
Zotero_DB::query($sql, array( $username,$passwordhash));
$sql = "SELECT userID FROM zotero_www_test.users WHERE username=?";
$userID = Zotero_DB::valueQuery($sql, $username);
# $sql = "INSERT INTO zotero_master.users (userID, libraryID, username) VALUES (?,?)";
# Zotero_DB::query($sql, array($userID, $libraryID, $username));
# $sql = "INSERT INTO zotero_master.storageAccounts (userID, quota, expiration) VALUES (?,?,?);";
# Zotero_DB::query($sql,array($userID, '10000', '2020-12-31 00:00:00'));
$sql = "INSERT INTO zotero_www_test.users_email (userID, email) VALUES (?,?);";
Zotero_DB::query($sql,array($userID, $email));
$sql = "INSERT INTO zotero_www_test.LUM_User (RoleID, UserID) VALUES (3,?);";
Zotero_DB::query($sql,array($userID));
$sql = "INSERT INTO zotero_www_test.users_meta (userID, metaKey, metaValue) VALUES (?,'profile_realname',?);";
Zotero_DB::query($sql,array($userID,$real_user));
Zotero_DB::commit();
?>

38
change_password Normal file
View File

@ -0,0 +1,38 @@
#!/usr/local/bin/php
<?
set_include_path("../include");
require("header.inc.php");
if (empty($argv[1])) {
die("Usage: $argv[0] " . '$username $password' . "\n");
}
$username = $argv[1];
$password = $argv[2];
$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
echo $docRoot;
echo "changing password for user $username\n";
$passwordhash = md5($password, PASSWORD_DEFAULT);
Zotero_DB::beginTransaction();
$sql = "SET NAMES UTF8;";
Zotero_DB::query($sql);
$sql = "UPDATE zotero_www.users SET password=? WHERE username=?";
Zotero_DB::query($sql, array($passwordhash,$username));
Zotero_DB::commit();
?>

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
echo "######################################################"
echo "######################################################"
@ -12,32 +12,62 @@ echo "######################################################"
echo "install required packages"
echo "add key for elasticsearch repository"
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "add debian wheezy backports repository"
echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list
echo "update package cache"
apt-get update
echo "dependencies for dataserver"
apt-get install -y apache2 libapache2-mod-php5 mysql-server memcached zendframework php5-cli php5-memcache php5-mysql php5-curl
echo "dependencies for zss"
apt-get install -y uwsgi uwsgi-plugin-psgi libplack-perl libdigest-hmac-perl libjson-xs-perl libfile-util-perl libapache2-mod-uwsgi
apt-get install -y apache2 libapache2-mod-php5 mysql-server memcached zendframework php5-cli php5-memcache php5-mysql php5-curl php5-memcached
echo "general dependencies"
apt-get install -y git gnutls-bin runit
apt-get install -y git gnutls-bin runit libapache2-modsecurity curl elasticsearch openjdk-7-jre
echo "created required directories"
# fuck DEBIAN
#mkdir -p /srv/zotero/{dataserver,zss,storage}
mkdir -p /srv/zotero/dataserver
mkdir -p /srv/zotero/zss
mkdir -p /srv/zotero/storage
# fuck DEBIAN
#mkdir -p /srv/zotero/log/{download,upload,error}
mkdir -p /srv/zotero/log/download
mkdir -p /srv/zotero/log/upload
mkdir -p /srv/zotero/log/error
# save current directory
cur_dir=$(pwd)
echo "setting elasticsearch to be started during booting"
update-rc.d elasticsearch defaults 95 10
echo "starting elasticsearch"
/etc/init.d/elasticsearch start
echo "download source code of dataserver"
git clone git://github.com/sualk/dataserver.git /srv/zotero/dataserver
git clone git://github.com/zotero/dataserver.git /srv/zotero/dataserver
echo "download source code of Elastica"
git clone git://github.com/ruflin/Elastica.git /srv/zotero/dataserver/include/Elastica
cd /srv/zotero/dataserver/include/Elastica
git checkout fc607170ab2ca751097648d48a5d38e15e9d5f6a
echo "install composer"
cd /srv/zotero/dataserver
curl -sS https://getcomposer.org/installer | php
echo "install dependencies"
php composer.phar install
echo "remove composer"
rm composer.phar
echo "install add_user script"
cp "$cur_dir/add_user" /srv/zotero/dataserver/admin
echo "install change_password script"
cp "$cur_dir/change_password" /srv/zotero/dataserver/admin
echo "patch master.sql"
cp "$cur_dir/master.sql" /srv/zotero/dataserver/misc
echo "prepare directory rights"
chown www-data:www-data /srv/zotero/dataserver/tmp
@ -47,47 +77,76 @@ cd /srv/zotero/dataserver/include
rm -r Zend
ln -s /usr/share/php/Zend/
echo "generate SSL key and cert"
certtool -p --sec-param high --outfile /etc/apache2/zotero.key
certtool -s --load-privkey /etc/apache2/zotero.key --outfile /etc/apache2/zotero.cert
read -p "Do you want to use SSL certificates for Zotero server? (y/n)" SSL
if [ $SSL=y ] ;
then
read -p "Do you want to generate SSL certificates now? (y/n)" gen_SSL
if [ $gen_SSL=y ];
then
echo "generate SSL key and cert"
certtool -p --sec-param high --outfile /etc/apache2/zotero.key
certtool -s --load-privkey /etc/apache2/zotero.key --outfile /etc/apache2/zotero.cert
else
cp "$cur_dir/zotero.key" /etc/apache2/zotero.key
cp "$cur_dir/zotero.cert" /etc/apache2/zotero.cert
fi
fi
echo "enable ssl support for apache2 server"
a2enmod ssl
read -p "Do you want to use SSL certificates for LibreS3? (y/n)" SSL_LibreS3
if [ $SSL_LibreS3=y ] ;
then
cat "$cur_dir/sx.cert" >> /srv/zotero/dataserver/vendor/guzzle/guzzle/src/Guzzle/Http/Resources/cacert.pem
fi
echo "enable rewrite support for apache2 server"
a2enmod rewrite
echo "create available site for zotero"
echo "<VirtualHost *:443>
DocumentRoot /srv/zotero/dataserver/htdocs
SSLEngine on
SSLCertificateFile /etc/apache2/zotero.cert
SSLCertificateKeyFile /etc/apache2/zotero.key
if [ $SSL=y ] ;
then
echo "enable ssl support for apache2 server"
a2enmod ssl
<Location /zotero/>
SetHandler uwsgi-handler
uWSGISocket /var/run/uwsgi/app/zss/socket
uWSGImodifier1 5
</Location>
echo "create available site for zotero"
echo "<VirtualHost *:443>
DocumentRoot /srv/zotero/dataserver/htdocs
SSLEngine on
SSLCertificateFile /etc/apache2/zotero.cert
SSLCertificateKeyFile /etc/apache2/zotero.key
<Directory "/srv/zotero/dataserver/htdocs/">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
<Directory "/srv/zotero/dataserver/htdocs/">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /srv/zotero/error.log
CustomLog /srv/zotero/access.log common
</VirtualHost>" > /etc/apache2/sites-available/zotero
ErrorLog /srv/zotero/error.log
CustomLog /srv/zotero/access.log common
</VirtualHost>" > /etc/apache2/sites-available/zotero
else
echo "create available site for zotero"
echo "<VirtualHost *:80>
DocumentRoot /srv/zotero/dataserver/htdocs
<Directory "/srv/zotero/dataserver/htdocs/">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /srv/zotero/error.log
CustomLog /srv/zotero/access.log common
</VirtualHost>" > /etc/apache2/sites-available/zotero
fi
echo "activate site for zotero"
a2ensite zotero
echo "change .htaccess"
sed -i '3i RewriteCond %{REQUEST_URI} !^/zotero' /srv/zotero/dataserver/htdocs/.htaccess
echo "restart apache2"
echo "restart apache2"[5~
service apache2 reload
echo "###############"
@ -102,27 +161,76 @@ default-time-zone = '+0:00'" > /etc/mysql/conf.d/zotero.cnf
/etc/init.d/mysql restart
echo -n "root Password for MySQL: "
read password
sed -i "s/PW/${password}/g" /srv/zotero/dataserver/misc/setup_db
echo -n "password for zotero database user: "
read zotero_password
sed -i "s/foobar/${zotero_password}/g" /srv/zotero/dataserver/misc/setup_db
cd /srv/zotero/dataserver/misc/
./setup_db
cd /srv/zotero/dataserver/misc
DB="mysql -h 127.0.0.1 -P 3306 -u root -p${password}"
echo "DROP DATABASE IF EXISTS zotero_master" | $DB
echo "DROP DATABASE IF EXISTS zotero_shards" | $DB
echo "DROP DATABASE IF EXISTS zotero_ids" | $DB
echo "DROP DATABASE IF EXISTS zotero_www" | $DB
echo "CREATE DATABASE zotero_master" | $DB
echo "CREATE DATABASE zotero_shards" | $DB
echo "CREATE DATABASE zotero_ids" | $DB
echo "CREATE DATABASE zotero_www" | $DB
echo "DROP USER IF EXISTS zotero@localhost;" | $DB
echo "CREATE USER zotero@localhost IDENTIFIED BY '${zotero_password}';" | $DB
echo "GRANT SELECT, INSERT, UPDATE, DELETE ON zotero_master.* TO zotero@localhost;" | $DB
echo "GRANT SELECT, INSERT, UPDATE, DELETE ON zotero_shards.* TO zotero@localhost;" | $DB
echo "GRANT SELECT,INSERT,DELETE ON zotero_ids.* TO zotero@localhost;" | $DB
echo "GRANT SELECT,INSERT,DELETE ON zotero_www.* TO zotero@localhost;" | $DB
echo "Load in master schema"
$DB zotero_master < master.sql
$DB zotero_master < coredata.sql
$DB zotero_master < fulltext.sql
echo "Set up shard info"
echo "INSERT INTO shardHosts VALUES (1, '127.0.0.1', 3306, 'up');" | $DB zotero_master
echo "INSERT INTO shards VALUES (1, 1, 'zotero_shards', 'up', 0);" | $DB zotero_master
echo Load in shard schema
cat shard.sql | $DB zotero_shards
cat triggers.sql | $DB zotero_shards
echo "Load in schema on id server"
cat ids.sql | $DB zotero_ids
echo "Load in www schema"
$DB zotero_www < $(cur_dir)www.sql
echo "Setup roleIDs"
echo "INSERT INTO LUM_ROLE VALUES ('Deleted', 1);" | $DB zotero_www
echo "INSERT INTO LUM_ROLE VALUES ('Invalid', 2);" | $DB zotero_www
echo "INSERT INTO LUM_ROLE VALUES ('Valid', 3);" | $DB zotero_www
echo "#################################"
echo "Configuration database connection"
echo "#################################"
# add code to also configure other databases
cp /srv/zotero/dataserver/include/config/dbconnect.inc.php-sample /srv/zotero/dataserver/include/config/dbconnect.inc.php
echo -n "hostname for database: "
read hostname
sed -i "s/localhost/${hostname}/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/host\ =\ ''/host\ =\ '${hostname}'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/host\ =\ false/host\ =\ '${hostname}'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/port\ =\ ''/port\ =\ 3306/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/port\ =\ false/port\ =\ 3306/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/user\ =\ ''/user\ =\ 'zotero'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/user\ =\ false/user\ =\ 'zotero'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/pass\ =\ ''/pass\ =\ '${zotero_password}'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "4s/host\ =\ ''/host\ =\ 'localhost'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "6s/db\ =\ ''/db\ =\ 'zotero_master'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "18s/host\ =\ ''/host\ =\ 'localhost'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "25s/host\ =\ ''/host\ =\ 'localhost'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/pass\ =\ false/pass\ =\ '${zotero_password}'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "8s/db\ =\ ''/db\ =\ 'zotero_master'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "15s/db\ =\ false/db\ =\ 'zotero_shards'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "22s/db\ =\ false/db\ =\ 'zotero_master'/" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/ids/zotero_ids/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
sed -i "s/'www'/'zotero_www'/g" /srv/zotero/dataserver/include/config/dbconnect.inc.php
echo "###################################"
echo "General configuration of dataserver"
@ -146,15 +254,21 @@ sed -i "s/API_SUPER_USERNAME\ =\ ''/API_SUPER_USERNAME\ =\ '${API_SUPER_USERNAME
echo -n "api super password: "
read API_SUPER_PASSWORD
sed -i "s/API_SUPER_PASSWORD\ =\ ''/API_SUPER_PASSWORD\ =\ '${API_SUPER_PASSWORD}'/" /srv/zotero/dataserver/include/config/config.inc.php
echo -n "aws access key: "
read AWS_ACCESS_KEY
sed -i "s/AWS_ACCESS_KEY\ =\ ''/AWS_ACCESS_KEY\ =\ '${AWS_ACCESS_KEY}'/" /srv/zotero/dataserver/include/config/config.inc.php
echo -n "aws secret key: "
read AWS_SECRET_KEY
sed -i "s/AWS_SECRET_KEY\ =\ ''/AWS_SECRET_KEY\ =\ '${AWS_SECRET_KEY}'/" /srv/zotero/dataserver/include/config/config.inc.php
echo -n "s3_bucket: "
read S3_BUCKET
sed -i "s/S3_BUCKET\ =\ ''/S3_BUCKET\ =\ '${S3_BUCKET}'/" /srv/zotero/dataserver/include/config/config.inc.php
sed -i "s/us-east-1/custom/" /srv/zotero/dataserver/include/config/config.inc.php
echo -n "s3 endpoint url: "
read S3_ENDPOINT
sed -i "s/S3_ENDPOINT\ =\ 's3.amazonaws.com'/S3_ENDPOINT\ =\ '${S3_ENDPOINT}'/" /srv/zotero/dataserver/include/config/config.inc.php
read AWS_HOST
sed -i "27a\ \ \ \ \ \ \ \ public static \$AWS_HOST\ =\ '${AWS_HOST};'" /srv/zotero/dataserver/include/config/config.inc.php
sed -i "30i\ \ \ \ \ \ \ \ public static \$URI_PREFIX_DOMAIN_MAP = array(" /srv/zotero/dataserver/include/config/config.inc.php
sed -i "31i\ \ \ \ \ \ \ \ \ \ '\/sync\/' => 'sync'" /srv/zotero/dataserver/include/config/config.inc.php
@ -167,25 +281,23 @@ sed -i "s/'memcached1.localdomain:11211:2',\ 'memcached2.localdomain:11211:1'/'$
echo "Configure document root folder"
sed -i "s/var\/www\/dataserver/srv\/zotero\/dataserver/" /srv/zotero/dataserver/include/config/config.inc.php
# echo "configuring zotero start up scripts"
# sed -i "s/processor/dataserver\/processor/" /srv/zotero/dataserver/misc/zotero_download.init
# sed -i "s/processor/dataserver\/processor/" /srv/zotero/dataserver/misc/zotero_error.init
# sed -i "s/processor/dataserver\/processor/" /srv/zotero/dataserver/misc/zotero_upload.init
#
# echo "configuring start up of zotero scripts"!
# cp /srv/zotero/dataserver/misc/zotero_download.init /etc/init.d/zotero_download
# cp /srv/zotero/dataserver/misc/zotero_error.init /etc/init.d/zotero_error
# cp /srv/zotero/dataserver/misc/zotero_upload.init /etc/init.d/zotero_upload
#
# echo "add zotero scripts to autostart"
# update-rc.d zotero_download defaults
# update-rc.d zotero_error defaults
# update-rc.d zotero_upload defaults
#
# echo "start zotero services"
# /etc/init.d/zotero_download start
# /etc/init.d/zotero_error start
# /etc/init.d/zotero_upload start
echo "##############################################################"
echo "patch header.inc.php for including host name for using own AWS"
echo "##############################################################"
sed -i "225a \$awsconfig['base_url']\ =\ \"http://\" . ZCONFIG::\$AWS_HOST;" /srv/zotero/dataserver/include/header.inc.php
echo "###############################################################################"
echo "patch Storage.inc.php for using custom host name for generating base Upload URL"
echo "###############################################################################"
sed -i "s,\".s3.amazonaws.com/\",\ \".\" . Z_CONFIG::$AWS_HOST" /srv/zotero/dataserver/model/Storage.inc.php
echo "#####################################"
echo "patch AWS-SDK to use custom S3 server"
echo "#####################################"
sed -i "s,{service}.{region}.amazonaws.com,s3.drossenhausen.de.vu" /srv/zotero/dataserver/vendor/aws/aws-sdk-php/src/Aws/Common/Resources/public-endpoints.php
echo "###############"
echo "Configure runit"
echo "###############"
@ -236,23 +348,3 @@ ln -s ../sv/zotero-download /etc/service/
ln -s ../sv/zotero-upload /etc/service/
ln -s ../sv/zotero-error /etc/service/
echo "#############"
echo ZSS
echo "#############"
echo "download source code for ZSS"
git clone git://github.com/sualk/zss.git /srv/zotero/zss
echo "adjust path for ZSS.pm"
sed -i "s/path\/to/srv\/zss/" /srv/zotero/zss/zss.psgi
echo "adjust properties in ZSS.pm"
sed -i "s/yoursecretkey/${AWS_SECRET_KEY}/" /srv/zotero/zss/ZSS.pm
sed -i "s/path\/to/srv\/zss/" /srv/zotero/zss/ZSS.pm
echo "configure uwsgi"
echo "uwsgi:
plugin: psgi
psgi: /srv/zotero/zss/zss.psgi" > /etc/uwsgi/apps-available/zss.yaml
ln -s /etc/uwsgi/apps-available/zss.yaml /etc/uwsgi/apps-enabled/zss.yaml
/etc/init.d/uwsgi restart

530
master.sql Normal file
View File

@ -0,0 +1,530 @@
-- ***** BEGIN LICENSE BLOCK *****
--
-- This file is part of the Zotero Data Server.
--
-- Copyright © 2010 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
-- http://zotero.org
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ***** END LICENSE BLOCK *****
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE `abstractCreators` (
`creatorID` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `abstractItems` (
`itemID` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`itemID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `baseFieldMappings` (
`itemTypeID` smallint(5) unsigned NOT NULL,
`baseFieldID` smallint(5) unsigned NOT NULL,
`fieldID` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`itemTypeID`,`baseFieldID`,`fieldID`),
KEY `baseFieldID` (`baseFieldID`),
KEY `fieldID` (`fieldID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `charsets` (
`charsetID` tinyint(3) unsigned NOT NULL,
`charset` varchar(50) NOT NULL,
PRIMARY KEY (`charsetID`),
KEY `charset` (`charset`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `creatorTypes` (
`creatorTypeID` smallint(5) unsigned NOT NULL,
`creatorTypeName` varchar(50) NOT NULL,
`custom` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`creatorTypeID`),
UNIQUE KEY `creatorTypeName` (`creatorTypeName`),
KEY `custom` (`custom`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `fields` (
`fieldID` smallint(5) unsigned NOT NULL,
`fieldName` varchar(50) NOT NULL,
`fieldFormatID` tinyint(3) unsigned DEFAULT NULL,
`custom` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`fieldID`),
UNIQUE KEY `fieldName` (`fieldName`),
KEY `custom` (`custom`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `groups` (
`groupID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`libraryID` int(10) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`slug` varchar(255) DEFAULT NULL,
`type` enum('PublicOpen','PublicClosed','Private') NOT NULL DEFAULT 'Private',
`libraryEditing` enum('admins','members') NOT NULL DEFAULT 'admins',
`libraryReading` enum('members','all') NOT NULL DEFAULT 'all',
`fileEditing` enum('none','admins','members') NOT NULL DEFAULT 'admins',
`description` text NOT NULL,
`url` varchar(255) NOT NULL,
`hasImage` tinyint(1) unsigned NOT NULL DEFAULT '0',
`dateAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`dateModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`version` tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`groupID`),
UNIQUE KEY `libraryID` (`libraryID`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `groupUsers` (
`groupID` int(10) unsigned NOT NULL,
`userID` int(10) unsigned NOT NULL,
`role` enum('owner','admin','member') NOT NULL DEFAULT 'member',
`joined` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`lastUpdated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`groupID`,`userID`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `itemTypeCreatorTypes` (
`itemTypeID` smallint(5) unsigned NOT NULL,
`creatorTypeID` smallint(5) unsigned NOT NULL,
`primaryField` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`itemTypeID`,`creatorTypeID`),
KEY `creatorTypeID` (`creatorTypeID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `itemTypeFields` (
`itemTypeID` smallint(5) unsigned NOT NULL,
`fieldID` smallint(5) unsigned NOT NULL,
`hide` tinyint(3) unsigned NOT NULL DEFAULT '0',
`orderIndex` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`itemTypeID`,`fieldID`),
KEY `fieldID` (`fieldID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `itemTypes` (
`itemTypeID` smallint(5) unsigned NOT NULL,
`itemTypeName` varchar(50) NOT NULL,
`custom` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`itemTypeID`),
UNIQUE KEY `itemTypeName` (`itemTypeName`),
KEY `custom` (`custom`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `keyAccessLog` (
`keyID` int(10) unsigned NOT NULL,
`ipAddress` int(10) unsigned NOT NULL DEFAULT '0',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`keyID`,`ipAddress`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `keyPermissions` (
`keyID` int(10) unsigned NOT NULL,
`libraryID` int(10) unsigned NOT NULL,
`permission` enum('library','notes','write') NOT NULL,
`granted` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`keyID`,`libraryID`,`permission`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `keys` (
`keyID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`key` char(24) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`userID` int(10) unsigned NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`dateAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`lastUsed` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`keyID`),
UNIQUE KEY `key` (`key`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `libraries` (
`libraryID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`libraryType` enum('user','group') NOT NULL,
`lastUpdated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`version` int(10) unsigned NOT NULL DEFAULT '0',
`shardID` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`libraryID`),
KEY `libraryType` (`libraryType`),
KEY `shardID` (`shardID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `processorDaemons` (
`mode` enum('download','upload','error','index') NOT NULL,
`addr` int(10) unsigned NOT NULL,
`port` smallint(5) unsigned NOT NULL,
`lastSeen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`mode`,`addr`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `sessions` (
`sessionID` char(32) CHARACTER SET ascii NOT NULL,
`userID` int(10) unsigned NOT NULL,
`ipAddress` int(10) unsigned DEFAULT NULL,
`exclusive` tinyint(1) unsigned NOT NULL DEFAULT '0',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`sessionID`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `shardHosts` (
`shardHostID` tinyint(3) unsigned NOT NULL,
`address` varchar(15) NOT NULL,
`port` smallint(5) unsigned NOT NULL DEFAULT 3306,
`state` enum('up','readonly','down') NOT NULL,
PRIMARY KEY (`shardHostID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `shards` (
`shardID` smallint(5) unsigned NOT NULL,
`shardHostID` tinyint(3) unsigned NOT NULL,
`db` varchar(20) NOT NULL,
`state` enum('up','readonly','down') NOT NULL,
`items` mediumint(8) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`shardID`),
KEY `shardHostID` (`shardHostID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageAccounts` (
`userID` int(10) unsigned NOT NULL,
`quota` mediumint(8) unsigned DEFAULT 10000 NOT NULL,
`expiration` timestamp NULL DEFAULT DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 10 YEARS),
PRIMARY KEY (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageDownloadLog` (
`ownerUserID` int(10) unsigned NOT NULL,
`downloadUserID` int(10) unsigned DEFAULT NULL,
`ipAddress` int(10) unsigned NULL,
`storageFileID` int(10) unsigned NOT NULL,
`filename` varchar(1024) NOT NULL,
`size` int(10) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageFiles` (
`storageFileID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hash` char(32) NOT NULL,
`filename` varchar(255) NOT NULL,
`size` int(10) unsigned NOT NULL,
`zip` tinyint(1) unsigned NOT NULL,
`lastAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`storageFileID`),
UNIQUE KEY `hash` (`hash`,`filename`,`zip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageFilesExisting` (
`storageFileID` int(10) unsigned NOT NULL,
PRIMARY KEY (`storageFileID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageLastSync` (
`userID` int(10) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageUploadLog` (
`ownerUserID` int(10) unsigned NOT NULL,
`uploadUserID` int(10) unsigned NOT NULL,
`ipAddress` int(10) unsigned NULL,
`storageFileID` int(10) unsigned NOT NULL,
`filename` varchar(1024) NOT NULL,
`size` int(10) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storageUploadQueue` (
`uploadKey` char(32) NOT NULL,
`userID` int(10) unsigned NOT NULL,
`hash` char(32) NOT NULL,
`filename` varchar(1024) NOT NULL,
`zip` tinyint(1) unsigned NOT NULL,
`size` int(10) unsigned NOT NULL,
`mtime` bigint(13) unsigned NOT NULL,
`contentType` varchar(75) DEFAULT NULL,
`charset` varchar(25) DEFAULT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`uploadKey`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncDownloadProcessLog` (
`userID` int(10) unsigned NOT NULL,
`lastsync` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`objects` int(10) unsigned NOT NULL,
`ipAddress` int(10) unsigned NOT NULL,
`processorHost` int(10) unsigned NOT NULL,
`processDuration` float(6,2) NOT NULL,
`totalDuration` smallint(5) unsigned NOT NULL,
`error` tinyint(4) NOT NULL DEFAULT '0',
`finished` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
KEY `finished` (`finished`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncDownloadQueue` (
`syncDownloadQueueID` int(10) unsigned NOT NULL,
`processorHost` int(10) unsigned DEFAULT NULL,
`userID` int(10) unsigned NOT NULL,
`sessionID` char(32) CHARACTER SET ascii NOT NULL,
`lastsync` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`lastsyncMS` smallint(5) unsigned NOT NULL DEFAULT '0',
`version` smallint(5) unsigned NOT NULL,
`params` mediumtext NOT NULL,
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`objects` int(10) unsigned NOT NULL,
`lastCheck` timestamp NULL DEFAULT NULL,
`tries` smallint(5) unsigned NOT NULL DEFAULT '0',
`started` timestamp NULL DEFAULT NULL,
`syncDownloadProcessID` int(10) unsigned DEFAULT NULL,
`finished` timestamp NULL DEFAULT NULL,
`finishedMS` smallint(5) unsigned NOT NULL DEFAULT '0',
`xmldata` longtext,
`errorCode` int(10) unsigned DEFAULT NULL,
`errorMessage` text,
PRIMARY KEY (`syncDownloadQueueID`),
KEY `userID` (`userID`),
KEY `sessionID` (`sessionID`),
KEY `started` (`started`),
KEY `syncDownloadProcessID` (`syncDownloadProcessID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncProcesses` (
`syncProcessID` int(10) unsigned NOT NULL,
`userID` int(10) unsigned NOT NULL,
`started` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`syncProcessID`),
UNIQUE KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncProcessLocks` (
`syncProcessID` int(10) unsigned NOT NULL,
`libraryID` int(10) unsigned NOT NULL,
PRIMARY KEY (`syncProcessID`,`libraryID`),
KEY `libraryID` (`libraryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncUploadQueue` (
`syncUploadQueueID` int(10) unsigned NOT NULL,
`processorHost` int(10) unsigned DEFAULT NULL,
`xmldata` longtext NOT NULL,
`dataLength` int(10) unsigned NOT NULL DEFAULT '0',
`hasCreator` tinyint(3) unsigned NOT NULL DEFAULT '0',
`userID` int(10) unsigned NOT NULL,
`sessionID` char(32) CHARACTER SET ascii NOT NULL,
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`errorCheck` tinyint(1) unsigned NOT NULL DEFAULT '0',
`tries` smallint(5) unsigned NOT NULL DEFAULT '0',
`started` timestamp NULL DEFAULT NULL,
`startedMS` smallint(5) unsigned NOT NULL DEFAULT '0',
`syncProcessID` int(10) unsigned DEFAULT NULL,
`finished` timestamp NULL DEFAULT NULL,
`finishedMS` smallint(5) unsigned NOT NULL DEFAULT '0',
`errorCode` int(10) unsigned DEFAULT NULL,
`errorMessage` mediumtext,
PRIMARY KEY (`syncUploadQueueID`),
UNIQUE KEY `sessionID` (`sessionID`),
UNIQUE KEY `syncProcessID` (`syncProcessID`),
KEY `userID` (`userID`),
KEY `started` (`started`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncUploadQueueLocks` (
`syncUploadQueueID` int(10) unsigned NOT NULL,
`libraryID` int(10) unsigned NOT NULL,
PRIMARY KEY (`syncUploadQueueID`,`libraryID`),
KEY `libraryID` (`libraryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncUploadProcessLog` (
`userID` int(10) unsigned NOT NULL,
`dataLength` int(10) unsigned NOT NULL,
`processorHost` int(10) unsigned NOT NULL,
`processDuration` float(6,2) NOT NULL,
`totalDuration` smallint(5) unsigned NOT NULL,
`error` tinyint(4) NOT NULL DEFAULT '0',
`finished` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
KEY `finished` (`finished`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `syncUploadQueuePostWriteLog` (
`syncUploadQueueID` int(10) unsigned NOT NULL,
`objectType` enum('group','groupUser') NOT NULL,
`ids` varchar(30) NOT NULL,
`action` enum('update','delete') NOT NULL,
PRIMARY KEY (`syncUploadQueueID`,`objectType`,`ids`,`action`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`userID` int(10) unsigned NOT NULL,
`libraryID` int(10) unsigned NOT NULL,
`username` varchar(255) NOT NULL,
`joined` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`lastSyncTime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`userID`),
UNIQUE KEY `libraryID` (`libraryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `baseFieldMappings`
ADD CONSTRAINT `baseFieldMappings_ibfk_1` FOREIGN KEY (`itemTypeID`) REFERENCES `itemTypes` (`itemTypeID`),
ADD CONSTRAINT `baseFieldMappings_ibfk_2` FOREIGN KEY (`baseFieldID`) REFERENCES `fields` (`fieldID`),
ADD CONSTRAINT `baseFieldMappings_ibfk_3` FOREIGN KEY (`fieldID`) REFERENCES `fields` (`fieldID`);
ALTER TABLE `groups`
ADD CONSTRAINT `groups_ibfk_1` FOREIGN KEY (`libraryID`) REFERENCES `libraries` (`libraryID`) ON DELETE CASCADE;
ALTER TABLE `groupUsers`
ADD CONSTRAINT `groupUsers_ibfk_1` FOREIGN KEY (`groupID`) REFERENCES `groups` (`groupID`) ON DELETE CASCADE,
ADD CONSTRAINT `groupUsers_ibfk_2` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE,
ADD CONSTRAINT `groupUsers_ibfk_3` FOREIGN KEY (`groupID`) REFERENCES `groups` (`groupID`) ON DELETE CASCADE,
ADD CONSTRAINT `groupUsers_ibfk_4` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE;
ALTER TABLE `itemTypeCreatorTypes`
ADD CONSTRAINT `itemTypeCreatorTypes_ibfk_1` FOREIGN KEY (`itemTypeID`) REFERENCES `itemTypes` (`itemTypeID`),
ADD CONSTRAINT `itemTypeCreatorTypes_ibfk_2` FOREIGN KEY (`creatorTypeID`) REFERENCES `creatorTypes` (`creatorTypeID`);
ALTER TABLE `itemTypeFields`
ADD CONSTRAINT `itemTypeFields_ibfk_1` FOREIGN KEY (`itemTypeID`) REFERENCES `itemTypes` (`itemTypeID`),
ADD CONSTRAINT `itemTypeFields_ibfk_2` FOREIGN KEY (`fieldID`) REFERENCES `fields` (`fieldID`);
ALTER TABLE `keys`
ADD CONSTRAINT `keys_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE;
ALTER TABLE `keyPermissions`
ADD CONSTRAINT `keyPermissions_ibfk_1` FOREIGN KEY (`keyID`) REFERENCES `keys` (`keyID`) ON DELETE CASCADE;
ALTER TABLE `libraries`
ADD CONSTRAINT `libraries_ibfk_1` FOREIGN KEY (`shardID`) REFERENCES `shards` (`shardID`);
ALTER TABLE `sessions`
ADD CONSTRAINT `sessions_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE;
ALTER TABLE `shards`
ADD CONSTRAINT `shards_ibfk_1` FOREIGN KEY (`shardHostID`) REFERENCES `shardHosts` (`shardHostID`);
ALTER TABLE `storageAccounts`
ADD CONSTRAINT `storageAccounts_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `storageLastSync`
ADD CONSTRAINT `storageLastSync_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `storageUploadQueue`
ADD CONSTRAINT `storageUploadQueue_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `syncDownloadQueue`
ADD CONSTRAINT `syncDownloadQueue_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `syncDownloadQueue_ibfk_3` FOREIGN KEY (`sessionID`) REFERENCES `sessions` (`sessionID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `syncProcesses`
ADD CONSTRAINT `syncProcesses_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`);
ALTER TABLE `syncProcessLocks`
ADD CONSTRAINT `syncProcessLocks_ibfk_1` FOREIGN KEY (`syncProcessID`) REFERENCES `syncProcesses` (`syncProcessID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `syncProcessLocks_ibfk_2` FOREIGN KEY (`libraryID`) REFERENCES `libraries` (`libraryID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `syncUploadQueue`
ADD CONSTRAINT `syncUploadQueue_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `syncUploadQueue_ibfk_2` FOREIGN KEY (`syncProcessID`) REFERENCES `syncProcesses` (`syncProcessID`) ON DELETE SET NULL,
ADD CONSTRAINT `syncUploadQueue_ibfk_3` FOREIGN KEY (`sessionID`) REFERENCES `sessions` (`sessionID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `syncUploadQueueLocks`
ADD CONSTRAINT `syncUploadQueueLocks_ibfk_1` FOREIGN KEY (`syncUploadQueueID`) REFERENCES `syncUploadQueue` (`syncUploadQueueID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `syncUploadQueueLocks_ibfk_2` FOREIGN KEY (`libraryID`) REFERENCES `libraries` (`libraryID`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `syncUploadQueuePostWriteLog`
ADD CONSTRAINT `syncUploadQueuePostWriteLog_ibfk_1` FOREIGN KEY (`syncUploadQueueID`) REFERENCES `syncUploadQueue` (`syncUploadQueueID`) ON DELETE CASCADE;
ALTER TABLE `users`
ADD CONSTRAINT `users_ibfk_1` FOREIGN KEY (`libraryID`) REFERENCES `libraries` (`libraryID`) ON DELETE CASCADE;
CREATE EVENT sessionGC ON SCHEDULE EVERY 5 MINUTE DO
DELETE S FROM sessions S LEFT JOIN syncUploadQueue USING (sessionID) WHERE timestamp<DATE_SUB(NOW(), INTERVAL 1 HOUR) AND (syncUploadQueue.sessionID IS NULL OR finished IS NOT NULL);

279
password.php Normal file
View File

@ -0,0 +1,279 @@
<?php
/**
* A Compatibility library with PHP 5.5's simplified password hashing API.
*
* @author Anthony Ferrara <ircmaxell@php.net>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2012 The Authors
*/
namespace {
if (!defined('PASSWORD_DEFAULT')) {
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
/**
* Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array()) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
return null;
}
$resultLength = 0;
switch ($algo) {
case PASSWORD_BCRYPT:
// Note that this is a C constant, but not exposed to PHP, so we don't define it here.
$cost = 10;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
// The expected length of the final crypt() output
$resultLength = 60;
break;
default:
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
return null;
}
$salt_requires_encoding = false;
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt_requires_encoding = true;
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && @is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = PasswordCompat\binary\_strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = PasswordCompat\binary\_strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
$bl = PasswordCompat\binary\_strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = $buffer;
$salt_requires_encoding = true;
}
if ($salt_requires_encoding) {
// encode string with the Base64 variant used by crypt
$base64_digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$bcrypt64_digits =
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$base64_string = base64_encode($salt);
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
}
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
$hash = $hash_format . $salt;
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
return false;
}
return $ret;
}
/**
* Get information about the password hash. Returns an array of the information
* that was used to generate the password hash.
*
* array(
* 'algo' => 1,
* 'algoName' => 'bcrypt',
* 'options' => array(
* 'cost' => 10,
* ),
* )
*
* @param string $hash The password hash to extract info from
*
* @return array The array of information about the hash.
*/
function password_get_info($hash) {
$return = array(
'algo' => 0,
'algoName' => 'unknown',
'options' => array(),
);
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
$return['algo'] = PASSWORD_BCRYPT;
$return['algoName'] = 'bcrypt';
list($cost) = sscanf($hash, "$2y$%d$");
$return['options']['cost'] = $cost;
}
return $return;
}
/**
* Determine if the password hash needs to be rehashed according to the options provided
*
* If the answer is true, after validating the password using password_verify, rehash it.
*
* @param string $hash The hash to test
* @param int $algo The algorithm used for new password hashes
* @param array $options The options array passed to password_hash
*
* @return boolean True if the password needs to be rehashed.
*/
function password_needs_rehash($hash, $algo, array $options = array()) {
$info = password_get_info($hash);
if ($info['algo'] != $algo) {
return true;
}
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = isset($options['cost']) ? $options['cost'] : 10;
if ($cost != $info['options']['cost']) {
return true;
}
break;
}
return false;
}
/**
* Verify a password against a hash using a timing attack resistant approach
*
* @param string $password The password to verify
* @param string $hash The hash to verify against
*
* @return boolean If the password matches the hash
*/
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
return false;
}
$status = 0;
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
}
}
namespace PasswordCompat\binary {
/**
* Count the number of bytes in a string
*
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
* sequence of bytes might be regarded as a single multibyte character.
*
* @param string $binary_string The input string
*
* @internal
* @return int The number of bytes
*/
function _strlen($binary_string) {
if (function_exists('mb_strlen')) {
return mb_strlen($binary_string, '8bit');
}
return strlen($binary_string);
}
/**
* Get a substring based on byte limits
*
* @see _strlen()
*
* @param string $binary_string The input string
* @param int $start
* @param int $length
*
* @internal
* @return string The substring
*/
function _substr($binary_string, $start, $length) {
if (function_exists('mb_substr')) {
return mb_substr($binary_string, $start, $length, '8bit');
}
return substr($binary_string, $start, $length);
}
}

81
www.sql Normal file
View File

@ -0,0 +1,81 @@
-- ***** BEGIN LICENSE BLOCK *****
--
-- This file is part of the fork of the vanilla Zotero Data Server.
--
-- Copyright © 2014 Patrick Höhn
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- ***** END LICENSE BLOCK *****
CREATE TABLE `sessions` (
`userID` mediumint unsigned NOT NULL,
`id` int(10) unsigned NOT NULL,
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`lifetime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`userID`, `id`),
FOREIGN KEY (`userID`) REFERENCES `users` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users_email` (
`userID` mediumint unsigned NOT NULL,
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`userID`),
UNIQUE KEY (`email`),
FOREIGN KEY (`userID`) REFERENCES `users` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storage_institutions` (
`storageQuota` mediumintt(8) unsigned NOT NULL,
`domain` varchar(255) NOT NULL,
`institutionID` int(10) unsigned NOT NULL,
PRIMARY KEY (`institutionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `storage_institution_email` (
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`institutionID` int(10) unsigned NOT NULL,
PRIMARY KEY (`institutionID`),
FOREIGN KEY (`institutionID`) REFERENCES `storage_institutions` (`institutionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`userID` mediumint unsigned auto_increment NULL,
`username` varchar(40) NOT NULL,
`password` char(61) NOT NULL,
PRIMARY KEY (`username`, `userID`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users_meta` (
`userID` mediumint unsigned NOT NULL,
`metaKey` enum('profile_realname', 'publishLibrary', 'publishNotes') NOT NULL,
`metaValue` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
FOREIGN KEY (`userID`) REFERENCES `users` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `LUM_User` (
`UserID` int(10) unsigned NOT NULL,
`RoleID` int(10) unsigned NOT NULL,
PRIMARY KEY (`UserID`, `RoleID`),
FOREIGN KEY (`RoleID`) REFERENCES `LUM_Role` (`RoleID`),
FOREIGN KEY (`UserID`) REFERENCES `users` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `LUM_Role` (
`RoleID` int(10) unsigned NOT NULL,
`Name` enum('Deleted','Invalid','Valid') NOT NULL,
PRIMARY KEY (`RoleID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;