summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJakob Sack <mail@jakobsack.de>2011-03-01 23:20:16 +0100
committerJakob Sack <mail@jakobsack.de>2011-03-01 23:20:16 +0100
commit132695ceb1d7ab0e4bfbb141e9e9639111dd25b5 (patch)
treef53fabcefd89a1e5bbeda9a2c2d2fff6683139d4 /lib
parent1fd39a52fa750878e7d70fba63c099f252095762 (diff)
downloadnextcloud-server-132695ceb1d7ab0e4bfbb141e9e9639111dd25b5.tar.gz
nextcloud-server-132695ceb1d7ab0e4bfbb141e9e9639111dd25b5.zip
Start of the refactoring. Commit is quite big because I forgot to use git right from the beginning. Sorry.
Diffstat (limited to 'lib')
-rw-r--r--lib/HTTP/WebDAV/Server/Filesystem.php760
-rw-r--r--lib/User/backend.php161
-rw-r--r--lib/User/database.php428
-rw-r--r--lib/appconfig.php45
-rw-r--r--lib/base.php807
-rw-r--r--lib/config.php392
-rw-r--r--lib/connect.php300
-rw-r--r--lib/fileobserver.php82
-rw-r--r--lib/files.php399
-rw-r--r--lib/filestorage.php432
-rw-r--r--lib/filesystem.php380
-rw-r--r--lib/log.php78
-rw-r--r--lib/ocs.php592
-rw-r--r--lib/plugin.php381
-rw-r--r--lib/remotestorage.php353
-rw-r--r--lib/template.php197
-rw-r--r--lib/user.php249
17 files changed, 6036 insertions, 0 deletions
diff --git a/lib/HTTP/WebDAV/Server/Filesystem.php b/lib/HTTP/WebDAV/Server/Filesystem.php
new file mode 100644
index 00000000000..0615c600e07
--- /dev/null
+++ b/lib/HTTP/WebDAV/Server/Filesystem.php
@@ -0,0 +1,760 @@
+<?php
+/*
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
+ | All rights reserved |
+ | |
+ | Redistribution and use in source and binary forms, with or without |
+ | modification, are permitted provided that the following conditions |
+ | are met: |
+ | |
+ | 1. Redistributions of source code must retain the above copyright |
+ | notice, this list of conditions and the following disclaimer. |
+ | 2. Redistributions in binary form must reproduce the above copyright |
+ | notice, this list of conditions and the following disclaimer in |
+ | the documentation and/or other materials provided with the |
+ | distribution. |
+ | 3. The names of the authors may not be used to endorse or promote |
+ | products derived from this software without specific prior |
+ | written permission. |
+ | |
+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
+ | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
+ | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
+ | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
+ | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
+ | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
+ | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
+ | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
+ | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
+ | POSSIBILITY OF SUCH DAMAGE. |
+ +----------------------------------------------------------------------+
+ --- modified for ownCloud ---
+*/
+ require_once("lib/base.php");
+ oc_require_once("HTTP/WebDAV/Server.php");
+ oc_require_once("System.php");
+
+ /**
+ * Filesystem access using WebDAV
+ *
+ * @access public
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @version @package-version@
+ */
+ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
+ {
+ /**
+ * Root directory for WebDAV access
+ *
+ * Defaults to webserver document root (set by ServeRequest)
+ *
+ * @access private
+ * @var string
+ */
+ var $base = "";
+
+ /**
+ * Serve a webdav request
+ *
+ * @access public
+ * @param string
+ */
+ function ServeRequest($base = false)
+ {
+ // special treatment for litmus compliance test
+ // reply on its identifier header
+ // not needed for the test itself but eases debugging
+ if (isset($this->_SERVER['HTTP_X_LITMUS'])) {
+ error_log("Litmus test ".$this->_SERVER['HTTP_X_LITMUS']);
+ header("X-Litmus-reply: ".$this->_SERVER['HTTP_X_LITMUS']);
+ }
+
+ // set root directory, defaults to webserver document root if not set
+ if ($base) {
+ $this->base = realpath($base); // TODO throw if not a directory
+ } else if (!$this->base) {
+ $this->base = $this->_SERVER['DOCUMENT_ROOT'];
+ }
+
+ // let the base class do all the work
+ parent::ServeRequest();
+ }
+
+ /**
+ * No authentication is needed here
+ *
+ * @access private
+ * @param string HTTP Authentication type (Basic, Digest, ...)
+ * @param string Username
+ * @param string Password
+ * @return bool true on successful authentication
+ */
+ function check_auth($type, $user, $pass)
+ {
+ return true;
+ }
+
+
+ /**
+ * PROPFIND method handler
+ *
+ * @param array general parameter passing array
+ * @param array return array for file properties
+ * @return bool true on success
+ */
+ function PROPFIND(&$options, &$files)
+ {
+ // get absolute fs path to requested resource
+ $fspath = $options["path"];
+
+ // sanity check
+ if (!OC_FILESYSTEM::file_exists($fspath)) {
+ return false;
+ }
+
+ // prepare property array
+ $files["files"] = array();
+ // store information for the requested path itself
+ $files["files"][] = $this->fileinfo($options["path"]);
+ // information for contained resources requested?
+ if (!empty($options["depth"]) && OC_FILESYSTEM::is_dir($fspath) && OC_FILESYSTEM::is_readable($fspath)) {
+ // make sure path ends with '/'
+ $options["path"] = $this->_slashify($options["path"]);
+
+ // try to open directory
+ $handle = @OC_FILESYSTEM::opendir($fspath);
+
+ if ($handle) {
+ // ok, now get all its contents
+ while ($filename = readdir($handle)) {
+ if ($filename != "." && $filename != "..") {
+ $files["files"][] = $this->fileinfo($options["path"].$filename);
+ }
+ }
+ // TODO recursion needed if "Depth: infinite"
+ }
+ }
+
+ // ok, all done
+ return true;
+ }
+
+ /**
+ * Get properties for a single file/resource
+ *
+ * @param string resource path
+ * @return array resource properties
+ */
+ function fileinfo($path)
+ {
+ global $CONFIG_DBTABLEPREFIX;
+
+ // map URI path to filesystem path
+ $fspath =$path;
+
+ // create result array
+ $info = array();
+ // TODO remove slash append code when base clase is able to do it itself
+ $info["path"] = OC_FILESYSTEM::is_dir($fspath) ? $this->_slashify($path) : $path;
+ $info["props"] = array();
+ // no special beautified displayname here ...
+ $info["props"][] = $this->mkprop("displayname", strtoupper($path));
+
+ // creation and modification time
+ $info["props"][] = $this->mkprop("creationdate", OC_FILESYSTEM::filectime($fspath));
+ $info["props"][] = $this->mkprop("getlastmodified", OC_FILESYSTEM::filemtime($fspath));
+ // Microsoft extensions: last access time and 'hidden' status
+ $info["props"][] = $this->mkprop("lastaccessed", OC_FILESYSTEM::fileatime($fspath));
+ $info["props"][] = $this->mkprop("ishidden", ('.' === substr(basename($fspath), 0, 1)));
+ // type and size (caller already made sure that path exists)
+ if ( OC_FILESYSTEM::is_dir($fspath)) {
+ // directory (WebDAV collection)
+ $info["props"][] = $this->mkprop("resourcetype", "collection");
+ $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
+ } else {
+ // plain file (WebDAV resource)
+ $info["props"][] = $this->mkprop("resourcetype", "");
+ if ( OC_FILESYSTEM::is_readable($fspath)) {
+ $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath));
+ } else {
+ $info["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable");
+ }
+ $info["props"][] = $this->mkprop("getcontentlength", OC_FILESYSTEM::filesize($fspath));
+ }
+ // get additional properties from database
+ $query = "SELECT ns, name, value FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$path'";
+ $res = OC_DB::select($query);
+ foreach($res as $row){
+ $info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]);
+ }
+ return $info;
+ }
+
+ /**
+ * try to detect the mime type of a file
+ *
+ * @param string file path
+ * @return string guessed mime type
+ */
+ function _mimetype($fspath)
+ {
+ return OC_FILESYSTEM::getMimeType($fspath);
+ }
+
+ /**
+ * HEAD method handler
+ *
+ * @param array parameter passing array
+ * @return bool true on success
+ */
+ function HEAD(&$options)
+ {
+ // get absolute fs path to requested resource
+ $fspath = $options["path"];
+
+ // sanity check
+ if (! OC_FILESYSTEM::file_exists($fspath)) return false;
+
+ // detect resource type
+ $options['mimetype'] = $this->_mimetype($fspath);
+
+ // detect modification time
+ // see rfc2518, section 13.7
+ // some clients seem to treat this as a reverse rule
+ // requiering a Last-Modified header if the getlastmodified header was set
+ $options['mtime'] = OC_FILESYSTEM::filemtime($fspath);
+
+ // detect resource size
+ $options['size'] = OC_FILESYSTEM::filesize($fspath);
+
+ return true;
+ }
+
+ /**
+ * GET method handler
+ *
+ * @param array parameter passing array
+ * @return bool true on success
+ */
+ function GET(&$options)
+ {
+ // get absolute fs path to requested resource)
+ $fspath = $options["path"];
+ // is this a collection?
+ if (OC_FILESYSTEM::is_dir($fspath)) {
+ return $this->GetDir($fspath, $options);
+ }
+
+ // the header output is the same as for HEAD
+ if (!$this->HEAD($options)) {
+ return false;
+ }
+
+ // no need to check result here, it is handled by the base class
+ $options['stream'] = OC_FILESYSTEM::fopen($fspath, "r");
+
+ return true;
+ }
+
+ /**
+ * GET method handler for directories
+ *
+ * This is a very simple mod_index lookalike.
+ * See RFC 2518, Section 8.4 on GET/HEAD for collections
+ *
+ * @param string directory path
+ * @return void function has to handle HTTP response itself
+ */
+ function GetDir($fspath, &$options)
+ {
+ $path = $this->_slashify($options["path"]);
+ if ($path != $options["path"]) {
+ header("Location: ".$this->base_uri.$path);
+ exit;
+ }
+
+ // fixed width directory column format
+ $format = "%15s %-19s %-s\n";
+
+ if (!OC_FILESYSTEM::is_readable($fspath)) {
+ return false;
+ }
+
+ $handle = OC_FILESYSTEM::opendir($fspath);
+ if (!$handle) {
+ return false;
+ }
+
+ echo "<html><head><title>Index of ".htmlspecialchars($options['path'])."</title></head>\n";
+
+ echo "<h1>Index of ".htmlspecialchars($options['path'])."</h1>\n";
+
+ echo "<pre>";
+ printf($format, "Size", "Last modified", "Filename");
+ echo "<hr>";
+
+ while ($filename = readdir($handle)) {
+ if ($filename != "." && $filename != "..") {
+ $fullpath = $fspath."/".$filename;
+ $name = htmlspecialchars($filename);
+ printf($format,
+ number_format(filesize($fullpath)),
+ strftime("%Y-%m-%d %H:%M:%S", filemtime($fullpath)),
+ "<a href='$name'>$name</a>");
+ }
+ }
+
+ echo "</pre>";
+
+ closedir($handle);
+
+ echo "</html>\n";
+
+ exit;
+ }
+
+ /**
+ * PUT method handler
+ *
+ * @param array parameter passing array
+ * @return bool true on success
+ */
+ function PUT(&$options)
+ {
+ $fspath = $options["path"];
+ $dir = dirname($fspath);
+ if (!OC_FILESYSTEM::file_exists($dir) || !OC_FILESYSTEM::is_dir($dir)) {
+ return "409 Conflict"; // TODO right status code for both?
+ }
+
+ $options["new"] = ! OC_FILESYSTEM::file_exists($fspath);
+
+ if ($options["new"] && !OC_FILESYSTEM::is_writeable($dir)) {
+ return "403 Forbidden";
+ }
+ if (!$options["new"] && !OC_FILESYSTEM::is_writeable($fspath)) {
+ return "403 Forbidden";
+ }
+ if (!$options["new"] && OC_FILESYSTEM::is_dir($fspath)) {
+ return "403 Forbidden";
+ }
+ $fp = OC_FILESYSTEM::fopen($fspath, "w");
+
+ return $fp;
+ }
+
+
+ /**
+ * MKCOL method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function MKCOL($options)
+ {
+ $path = $options["path"];
+ $parent = dirname($path);
+ $name = basename($path);
+ if (!OC_FILESYSTEM::file_exists($parent)) {
+ return "409 Conflict";
+ }
+
+ if (!OC_FILESYSTEM::is_dir($parent)) {
+ return "403 Forbidden";
+ }
+
+ if ( OC_FILESYSTEM::file_exists($parent."/".$name) ) {
+ return "405 Method not allowed";
+ }
+
+ if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
+ return "415 Unsupported media type";
+ }
+
+ $stat = OC_FILESYSTEM::mkdir($parent."/".$name, 0777);
+ if (!$stat) {
+ return "403 Forbidden";
+ }
+
+ return ("201 Created");
+ }
+
+
+ /**
+ * DELETE method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function DELETE($options)
+ {
+ global $CONFIG_DBTABLEPREFIX;
+ $path =$options["path"];
+ if (!OC_FILESYSTEM::file_exists($path)) {
+ return "404 Not found";
+ }
+ $lock=self::checkLock($path);
+ if(is_array($lock)){
+ $owner=$options['owner'];
+ $lockOwner=$lock['owner'];
+ if($owner==$lockOwner){
+ return "423 Locked";
+ }
+ }
+ if (OC_FILESYSTEM::is_dir($path)) {
+ $query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path LIKE '".$this->_slashify($options["path"])."%'";
+ OC_DB::query($query);
+ OC_FILESYSTEM::delTree($path);
+ } else {
+ OC_FILESYSTEM::unlink($path);
+ }
+ $query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$options[path]'";
+ OC_DB::query($query);
+
+ return "204 No Content";
+ }
+
+
+ /**
+ * MOVE method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function MOVE($options)
+ {
+ return $this->COPY($options, true);
+ }
+
+ /**
+ * COPY method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function COPY($options, $del=false)
+ {
+ // TODO Property updates still broken (Litmus should detect this?)
+ global $CONFIG_DBTABLEPREFIX;
+
+ if (!empty($this->_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
+ return "415 Unsupported media type";
+ }
+
+ // no copying to different WebDAV Servers yet
+ if (isset($options["dest_url"])) {
+ return "502 bad gateway";
+ }
+
+ $source = $options["path"];
+ if (!OC_FILESYSTEM::file_exists($source)) {
+ return "404 Not found";
+ }
+
+ if (OC_FILESYSTEM::is_dir($source)) { // resource is a collection
+ switch ($options["depth"]) {
+ case "infinity": // valid
+ break;
+ case "0": // valid for COPY only
+ if ($del) { // MOVE?
+ return "400 Bad request";
+ }
+ break;
+ case "1": // invalid for both COPY and MOVE
+ default:
+ return "400 Bad request";
+ }
+ }
+
+ $dest = $options["dest"];
+ $destdir = dirname($dest);
+
+ if (!OC_FILESYSTEM::file_exists($destdir) || !OC_FILESYSTEM::is_dir($destdir)) {
+ return "409 Conflict";
+ }
+
+
+ $new = !OC_FILESYSTEM::file_exists($dest);
+ $existing_col = false;
+
+ if (!$new) {
+ if ($del && OC_FILESYSTEM::is_dir($dest)) {
+ if (!$options["overwrite"]) {
+ return "412 precondition failed";
+ }
+ $dest .= basename($source);
+ if (OC_FILESYSTEM::file_exists($dest)) {
+ $options["dest"] .= basename($source);
+ } else {
+ $new = true;
+ $existing_col = true;
+ }
+ }
+ }
+
+ if (!$new) {
+ if ($options["overwrite"]) {
+ $stat = $this->DELETE(array("path" => $options["dest"]));
+ if (($stat{0} != "2") && (substr($stat, 0, 3) != "404")) {
+ return $stat;
+ }
+ } else {
+ return "412 precondition failed";
+ }
+ }
+
+ if ($del) {
+ if (!OC_FILESYSTEM::rename($source, $dest)) {
+ return "500 Internal server error";
+ }
+ $destpath = $this->_unslashify($options["dest"]);
+ if (is_dir($source)) {
+ $dpath=OC_DB::escape($destpath);
+ $path=OC_DB::escape($options["path"]);
+ $query = "UPDATE {$CONFIG_DBTABLEPREFIX}properties
+ SET path = REPLACE(path, '$path', '$dpath')
+ WHERE path LIKE '$path%'";
+ OC_DB::query($query);
+ }
+
+ $query = "UPDATE {$CONFIG_DBTABLEPREFIX}properties
+ SET path = '$dpath'
+ WHERE path = '$path'";
+ OC_DB::query($query);
+ } else {
+ if (OC_FILESYSTEM::is_dir($source)) {
+ $files = OC_FILESYSTEM::getTree($source);
+ } else {
+ $files = array($source);
+ }
+
+ if (!is_array($files) || empty($files)) {
+ return "500 Internal server error";
+ }
+
+
+ foreach ($files as $file) {
+ if (OC_FILESYSTEM::is_dir($file)) {
+ $file = $this->_slashify($file);
+ }
+ $destfile = str_replace($source, $dest, $file);
+
+ if (OC_FILESYSTEM::is_dir($file)) {
+ if (!OC_FILESYSTEM::file_exists($destfile)) {
+ if (!OC_FILESYSTEM::is_writeable(dirname($destfile))) {
+ return "403 Forbidden";
+ }
+ if (!OC_FILESYSTEM::mkdir($destfile)) {
+ return "409 Conflict";
+ }
+ } else if (!OC_FILESYSTEM::is_dir($destfile)) {
+ return "409 Conflict";
+ }
+ } else {
+ if (!OC_FILESYSTEM::copy($file, $destfile)) {
+ return "409 Conflict($source) $file --> $destfile ".implode('::',$files);
+ }
+ }
+ }
+ }
+ return ($new && !$existing_col) ? "201 Created" : "204 No Content";
+ }
+
+ /**
+ * PROPPATCH method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function PROPPATCH(&$options)
+ {
+ global $prefs, $tab;
+ global $CONFIG_DBTABLEPREFIX;
+
+ $msg = "";
+ $path = $options["path"];
+ $dir = dirname($path)."/";
+ $base = basename($path);
+
+ foreach ($options["props"] as $key => $prop) {
+ if ($prop["ns"] == "DAV:") {
+ $options["props"][$key]['status'] = "403 Forbidden";
+ } else {
+ $path=OC_DB::escape($options['path']);
+ $name=OC_DB::escape($prop['name']);
+ $ns=OC_DB::escape($prop['ns']);
+ $val=OC_DB::escape($prop['val']);
+ if (isset($prop["val"])) {
+ $query = "REPLACE INTO {$CONFIG_DBTABLEPREFIX}properties (path,name,ns,value) VALUES('$path','$name','$ns','$val')";
+ } else {
+ $query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}properties WHERE path = '$path' AND name = '$name' AND ns = '$ns'";
+ }
+ OC_DB::query($query);
+ }
+ }
+
+ return "";
+ }
+
+
+ /**
+ * LOCK method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function LOCK(&$options)
+ {
+ global $CONFIG_DBTABLEPREFIX;
+
+ // get absolute fs path to requested resource
+ $fspath = $options["path"];
+ // TODO recursive locks on directories not supported yet
+ // makes litmus test "32. lock_collection" fail
+ if (OC_FILESYSTEM::is_dir($fspath) && !empty($options["depth"])) {
+ switch($options["depth"]){
+ case 'infinity':
+ $recursion=1;
+ break;
+ case '0':
+ $recursion=0;
+ break;
+ }
+ }else{
+ $recursion=0;
+ }
+
+ $options["timeout"] = time()+300; // 5min. hardcoded
+
+ if (isset($options["update"])) { // Lock Update
+ $where = "WHERE path = '$options[path]' AND token = '$options[update]'";
+
+ $query = "SELECT owner, exclusivelock FROM {$CONFIG_DBTABLEPREFIX}locks $where";
+ $res = OC_DB::select($query);
+
+ if (is_array($res) and isset($res[0])) {
+ $row=$res[0];
+ $query = "UPDATE `{$CONFIG_DBTABLEPREFIX}locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
+ OC_DB::query($query);
+
+ $options['owner'] = $row['owner'];
+ $options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared";
+ $options['type'] = $row["exclusivelock"] ? "write" : "read";
+
+ return true;
+ } else {//check for indirect refresh
+ $query = "SELECT *
+ FROM {$CONFIG_DBTABLEPREFIX}locks
+ WHERE recursive = 1
+ ";
+ $res = OC_DB::select($query);
+ foreach($res as $row){
+ if(strpos($options['path'],$row['path'])==0){//are we a child of a folder with an recursive lock
+ $where = "WHERE path = '$row[path]' AND token = '$options[update]'";
+ $query = "UPDATE `{$CONFIG_DBTABLEPREFIX}locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where";
+ OC_DB::query($query);
+ $options['owner'] = $row['owner'];
+ $options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared";
+ $options['type'] = $row["exclusivelock"] ? "write" : "read";
+ return true;
+ }
+ }
+ }
+ }
+
+ $locktoken=OC_DB::escape($options['locktoken']);
+ $path=OC_DB::escape($options['path']);
+ $time=time();
+ $owner=OC_DB::escape($options['owner']);
+ $timeout=OC_DB::escape($options['timeout']);
+ $exclusive=($options['scope'] === "exclusive" ? "1" : "0");
+ $query = "INSERT INTO `{$CONFIG_DBTABLEPREFIX}locks`
+(`token`,`path`,`created`,`modified`,`owner`,`expires`,`exclusivelock`,`recursive`)
+VALUES ('$locktoken','$path',$time,$time,'$owner','timeout',$exclusive,$recursion)";
+ OC_DB::query($query);
+ $rows=OC_DB::affected_rows();
+ if(!OC_FILESYSTEM::file_exists($fspath) and $rows>0) {
+ return "201 Created";
+ }
+ return OC_DB::affected_rows($rows) ? "200 OK" : "409 Conflict";
+ }
+
+ /**
+ * UNLOCK method handler
+ *
+ * @param array general parameter passing array
+ * @return bool true on success
+ */
+ function UNLOCK(&$options)
+ {
+ global $CONFIG_DBTABLEPREFIX;
+ $query = "DELETE FROM {$CONFIG_DBTABLEPREFIX}locks
+ WHERE path = '$options[path]'
+ AND token = '$options[token]'";
+ OC_DB::query($query);
+
+ return OC_DB::affected_rows() ? "204 No Content" : "409 Conflict";
+ }
+
+ /**
+ * checkLock() helper
+ *
+ * @param string resource path to check for locks
+ * @return bool true on success
+ */
+ function checkLock($path)
+ {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $result = false;
+ $query = "SELECT *
+ FROM {$CONFIG_DBTABLEPREFIX}locks
+ WHERE path = '$path'
+ ";
+ $res = OC_DB::select($query);
+ if (is_array($res) and isset($res[0])) {
+ $row=$res[0];
+
+ if ($row) {
+ $result = array( "type" => "write",
+ "scope" => $row["exclusivelock"] ? "exclusive" : "shared",
+ "depth" => 0,
+ "owner" => $row['owner'],
+ "token" => $row['token'],
+ "created" => $row['created'],
+ "modified" => $row['modified'],
+ "expires" => $row['expires'],
+ "recursive" => $row['recursive']
+ );
+ }
+ }else{
+ //check for recursive locks;
+ $query = "SELECT *
+ FROM {$CONFIG_DBTABLEPREFIX}locks
+ WHERE recursive = 1
+ ";
+ $res = OC_DB::select($query);
+ foreach($res as $row){
+ if(strpos($path,$row['path'])==0){//are we a child of a folder with an recursive lock
+ $result = array( "type" => "write",
+ "scope" => $row["exclusivelock"] ? "exclusive" : "shared",
+ "depth" => 0,
+ "owner" => $row['owner'],
+ "token" => $row['token'],
+ "created" => $row['created'],
+ "modified" => $row['modified'],
+ "expires" => $row['expires'],
+ "recursive" => $row['recursive']
+ );
+ }
+ }
+ }
+
+ return $result;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/lib/User/backend.php b/lib/User/backend.php
new file mode 100644
index 00000000000..a486ea1cbcc
--- /dev/null
+++ b/lib/User/backend.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+
+/**
+ * Base class for user management
+ *
+ */
+abstract class OC_USER_BACKEND {
+
+ /**
+ * Check if the login button is pressed and log the user in
+ *
+ */
+ abstract public static function loginListener();
+
+ /**
+ * Try to create a new user
+ *
+ * @param string $username The username of the user to create
+ * @param string $password The password of the new user
+ */
+ abstract public static function createUser($username, $password);
+
+ /**
+ * Try to login a user
+ *
+ * @param string $username The username of the user to log in
+ * @param string $password The password of the user
+ */
+ abstract public static function login($username, $password);
+
+ /**
+ * Check if the logout button is pressed and logout the user
+ *
+ */
+ abstract public static function logoutListener();
+
+ /**
+ * Check if some user is logged in
+ *
+ */
+ abstract public static function isLoggedIn();
+
+ /**
+ * Try to create a new group
+ *
+ * @param string $groupName The name of the group to create
+ */
+ abstract public static function createGroup($groupName);
+
+ /**
+ * Get the ID of a user
+ *
+ * @param string $username Name of the user to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ abstract public static function getUserId($username, $noCache=false);
+
+ /**
+ * Get the ID of a group
+ *
+ * @param string $groupName Name of the group to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ abstract public static function getGroupId($groupName, $noCache=false);
+
+ /**
+ * Get the name of a group
+ *
+ * @param string $groupId ID of the group
+ * @param boolean $noCache If false the cache is used to find the name of the group
+ */
+ abstract public static function getGroupName($groupId, $noCache=false);
+
+ /**
+ * Check if a user belongs to a group
+ *
+ * @param string $username Name of the user to check
+ * @param string $groupName Name of the group
+ */
+ abstract public static function inGroup($username, $groupName);
+
+ /**
+ * Add a user to a group
+ *
+ * @param string $username Name of the user to add to group
+ * @param string $groupName Name of the group in which add the user
+ */
+ abstract public static function addToGroup($username, $groupName);
+
+ /**
+ * Remove a user from a group
+ *
+ * @param string $username Name of the user to remove from group
+ * @param string $groupName Name of the group from which remove the user
+ */
+ abstract public static function removeFromGroup($username,$groupName);
+
+ /**
+ * Generate a random password
+ */
+ abstract public static function generatePassword();
+
+ /**
+ * Get all groups the user belongs to
+ *
+ * @param string $username Name of the user
+ */
+ abstract public static function getUserGroups($username);
+
+ /**
+ * Set the password of a user
+ *
+ * @param string $username User who password will be changed
+ * @param string $password The new password for the user
+ */
+ abstract public static function setPassword($username, $password);
+
+ /**
+ * Check if the password of the user is correct
+ *
+ * @param string $username Name of the user
+ * @param string $password Password of the user
+ */
+ abstract public static function checkPassword($username, $password);
+
+
+ /**
+ * get a list of all users
+ *
+ */
+ abstract public static function getUsers();
+
+ /**
+ * get a list of all groups
+ *
+ */
+ abstract public static function getGroups();
+}
diff --git a/lib/User/database.php b/lib/User/database.php
new file mode 100644
index 00000000000..defaf7f8f40
--- /dev/null
+++ b/lib/User/database.php
@@ -0,0 +1,428 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+oc_require_once('User/backend.php');
+
+
+
+/**
+ * Class for user management in a SQL Database (e.g. MySQL, SQLite)
+ *
+ */
+class OC_USER_DATABASE extends OC_USER_BACKEND {
+ static private $userGroupCache=array();
+
+ /**
+ * Check if the login button is pressed and log the user in
+ *
+ */
+ public static function loginListener(){
+ if ( isset($_POST['loginbutton']) AND isset($_POST['password']) AND isset($_POST['login']) ) {
+ if ( OC_USER::login($_POST['login'], $_POST['password']) ) {
+ echo 1;
+ OC_LOG::event($_SESSION['username'], 1, '');
+ echo 2;
+ if ( (isset($CONFIG_HTTPFORCESSL) AND $CONFIG_HTTPFORCESSL)
+ OR (isset($_SERVER['HTTPS']) AND ('on' == $_SERVER['HTTPS'])) ) {
+ $url = 'https://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
+ } else {
+ $url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
+ }
+ header("Location: $url");
+ die();
+ } else {
+ return('error');
+ }
+ }
+ return('');
+ }
+
+ /**
+ * Try to create a new user
+ *
+ * @param string $username The username of the user to create
+ * @param string $password The password of the new user
+ */
+ public static function createUser($username, $password) {
+ self::clearCache();
+ global $CONFIG_DBTABLEPREFIX;
+ // Check if the user already exists
+ if ( 0 != OC_USER::getUserId($username, true) ) {
+ return false;
+ } else {
+ $usernameClean = strToLower($username);
+ $password = sha1($password);
+ $username = OC_DB::escape($username);
+ $usernameClean = OC_DB::escape($usernameClean);
+ $query = "INSERT INTO `{$CONFIG_DBTABLEPREFIX}users` (`user_name` ,`user_name_clean` ,`user_password`) "
+ . "VALUES ('$username', '$usernameClean', '$password')";
+ $result = OC_DB::query($query);
+ return $result ? true : false;
+ }
+ }
+
+ /**
+ * Try to login a user
+ *
+ * @param string $username The username of the user to log in
+ * @param string $password The password of the user
+ */
+ public static function login($username,$password){
+ global $CONFIG_DBTABLEPREFIX;
+
+ $password = sha1($password);
+ $usernameClean = strtolower($username);
+ $username = OC_DB::escape($username);
+ $usernameClean = OC_DB::escape($usernameClean);
+ $query = "SELECT user_id FROM {$CONFIG_DBTABLEPREFIX}users "
+ . "WHERE user_name_clean = '$usernameClean' AND user_password = '$password' LIMIT 1";
+ $result = OC_DB::select($query);
+ if ( isset($result[0]) AND isset($result[0]['user_id']) ) {
+ $_SESSION['user_id'] = $result[0]['user_id'];
+ $_SESSION['username'] = $username;
+ $_SESSION['username_clean'] = $usernameClean;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if the logout button is pressed and logout the user
+ *
+ */
+ public static function logoutListener() {
+ global $WEBROOT;
+ if ( isset($_GET['logoutbutton']) AND isset($_SESSION['username']) ) {
+ OC_LOG::event($_SESSION['username'], 2, '');
+ $_SESSION['user_id'] = false;
+ $_SESSION['username'] = '';
+ $_SESSION['username_clean'] = '';
+
+ header("location: $WEBROOT");
+ }
+ }
+
+ /**
+ * Kick the user
+ *
+ */
+ public static function logout() {
+ OC_LOG::event($_SESSION['username'], 2, '');
+ $_SESSION['user_id'] = false;
+ $_SESSION['username'] = '';
+ $_SESSION['username_clean'] = '';
+ }
+
+ /**
+ * Check if the user is logged in
+ *
+ */
+ public static function isLoggedIn() {
+ if ( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Try to create a new group
+ *
+ * @param string $groupName The name of the group to create
+ */
+ public static function createGroup($groupName) {
+ self::clearCache();
+ global $CONFIG_DBTABLEPREFIX;
+ if (0 == OC_USER::getGroupId($groupName) ) {
+ $groupName = OC_DB::escape($groupName);
+ $query = "INSERT INTO `{$CONFIG_DBTABLEPREFIX}groups` (`group_name`) VALUES ('$groupName')";
+ $result = OC_DB::query($query);
+ return $result ? true : false;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the ID of a user
+ *
+ * @param string $username Name of the user to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ public static function getUserId($username, $noCache=false) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $usernameClean = strToLower($username);
+ // Try to use cached value to avoid an SQL query
+ if ( !$noCache AND isset($_SESSION['user_id_cache'][$usernameClean]) ) {
+ return $_SESSION['user_id_cache'][$usernameClean];
+ }
+ $usernameClean = OC_DB::escape($usernameClean);
+ $query = "SELECT user_id FROM {$CONFIG_DBTABLEPREFIX}users WHERE user_name_clean = '$usernameClean'";
+ $result = OC_DB::select($query);
+ if ( !is_array($result) ) {
+ return 0;
+ }
+ if ( isset($result[0]) AND isset($result[0]['user_id']) ) {
+ $_SESSION['user_id_cache'][$usernameClean] = $result[0]['user_id'];
+ return $result[0]['user_id'];
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Get the ID of a group
+ *
+ * @param string $groupName Name of the group to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ public static function getGroupId($groupName, $noCache=false) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ // Try to use cached value to avoid an SQL query
+ if ( !$noCache AND isset($_SESSION['group_id_cache'][$groupName]) ) {
+ return $_SESSION['group_id_cache'][$groupName];
+ }
+ $groupName = OC_DB::escape($groupName);
+ $query = "SELECT group_id FROM {$CONFIG_DBTABLEPREFIX}groups WHERE group_name = '$groupName'";
+ $result = OC_DB::select($query);
+ if ( !is_array($result) ) {
+ return 0;
+ }
+ if ( isset($result[0]) AND isset($result[0]['group_id']) ){
+ $_SESSION['group_id_cache'][$groupName] = $result[0]['group_id'];
+ return $result[0]['group_id'];
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Get the name of a group
+ *
+ * @param string $groupId ID of the group
+ * @param boolean $noCache If false the cache is used to find the name of the group
+ */
+ public static function getGroupName($groupId, $noCache=false) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ // Try to use cached value to avoid an sql query
+ if ( !$noCache AND ($name = array_search($groupId, $_SESSION['group_id_cache'])) ) {
+ return $name;
+ }
+ $groupId = (integer)$groupId;
+ $query = "SELECT group_name FROM {$CONFIG_DBTABLEPREFIX}groups WHERE group_id = '$groupId' LIMIT 1";
+ $result = OC_DB::select($query);
+ if ( isset($result[0]) AND isset($result[0]['group_name']) ) {
+ return $result[0]['group_name'];
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Check if a user belongs to a group
+ *
+ * @param string $username Name of the user to check
+ * @param string $groupName Name of the group
+ */
+ public static function inGroup($username,$groupName) {
+ global $CONFIG_DBTABLEPREFIX;
+ $userId = OC_USER::getUserId($username);
+ $groupId = OC_USER::getGroupId($groupName);
+ self::getUserGroups($username);
+ $groups=self::$userGroupCache[$userId];
+ return (array_search($groupId,$groups)!==false);
+ }
+
+ /**
+ * Add a user to a group
+ *
+ * @param string $username Name of the user to add to group
+ * @param string $groupName Name of the group in which add the user
+ */
+ public static function addToGroup($username, $groupName) {
+ global $CONFIG_DBTABLEPREFIX;
+ self::clearCache();
+ if ( !OC_USER::inGroup($username, $groupName) ) {
+ $userId = OC_USER::getUserId($username,true);
+ $groupId = OC_USER::getGroupId($groupName,true);
+ if ( (0 != $groupId) AND (0 != $userId) ) {
+ $query = "INSERT INTO `{$CONFIG_DBTABLEPREFIX}user_group` (`user_id` ,`group_id`) VALUES ('$userId', '$groupId');";
+ $result = OC_DB::query($query);
+ if ( $result ) {
+ self::clearCache();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Remove a user from a group
+ *
+ * @param string $username Name of the user to remove from group
+ * @param string $groupName Name of the group from which remove the user
+ */
+ public static function removeFromGroup($username,$groupName){
+ global $CONFIG_DBTABLEPREFIX;
+ self::clearCache();
+ if (OC_USER::inGroup($username, $groupName) ) {
+ $userId = OC_USER::getUserId($username,true);
+ $groupId = OC_USER::getGroupId($groupName,true);
+ if ( (0 != $groupId) AND (0 != $userId) ) {
+ $query="DELETE FROM `{$CONFIG_DBTABLEPREFIX}user_group` WHERE `group_id` =$groupId AND `user_id`=$userId";
+ $result = OC_DB::query($query);
+ if ( $result ) {
+ self::clearCache();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Generate a random password
+ */
+ public static function generatePassword(){
+ return uniqId();
+ }
+
+ /**
+ * Get all groups the user belongs to
+ *
+ * @param string $username Name of the user
+ */
+ public static function getUserGroups($username) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $userId = OC_USER::getUserId($username);
+ if(!isset(self::$userGroupCache[$userId])){
+ $query = "SELECT group_id FROM {$CONFIG_DBTABLEPREFIX}user_group WHERE user_id = '$userId'";
+ $result = OC_DB::select($query);
+ $groupsId = array();
+ if ( is_array($result) ) {
+ foreach ( $result as $group ) {
+ $groupId = $group['group_id'];
+ $groupsId[]=$groupId;
+ }
+ }
+ self::$userGroupCache[$userId]=$groupsId;
+ return $groupsId;
+ }else{
+ return self::$userGroupCache[$userId];
+ }
+ }
+
+ /**
+ * Set the password of a user
+ *
+ * @param string $username User who password will be changed
+ * @param string $password The new password for the user
+ */
+ public static function setPassword($username, $password) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $password = sha1($password);
+ $userId = OC_USER::getUserId($username);
+ $query = "UPDATE {$CONFIG_DBTABLEPREFIX}users SET user_password = '$password' WHERE user_id ='$userId'";
+ $result = OC_DB::query($query);
+ if ( $result ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if the password of the user is correct
+ *
+ * @param string $username Name of the user
+ * @param string $password Password of the user
+ */
+ public static function checkPassword($username, $password) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $password = sha1($password);
+ $usernameClean = strToLower($username);
+ $usernameClean = OC_DB::escape($usernameClean);
+ $username = OC_DB::escape($username);
+ $query = "SELECT user_id FROM `{$CONFIG_DBTABLEPREFIX}users` "
+ . "WHERE user_name_clean = '$usernameClean' AND user_password = '$password' LIMIT 1";
+ $result = OC_DB::select($query);
+ if ( isset($result[0]) AND isset($result[0]['user_id']) AND ($result[0]['user_id'] > 0) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * get a list of all users
+ *
+ */
+ public static function getUsers() {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $query = "SELECT user_name FROM `{$CONFIG_DBTABLEPREFIX}users`";
+ $result = OC_DB::select($query);
+ $users=array();
+ foreach($result as $user){
+ $users[]=$user['user_name'];
+ }
+ return $users;
+ }
+
+ /**
+ * get a list of all groups
+ *
+ */
+ public static function getGroups() {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $query = "SELECT group_name FROM `{$CONFIG_DBTABLEPREFIX}groups`";
+ $result = OC_DB::select($query);
+ $groups=array();
+ foreach($result as $group){
+ $groups[]=$group['group_name'];
+ }
+ return $groups;
+ }
+
+ private static function clearCache(){
+ self::$userGroupCache=array();
+ $_SESSION['user_id_cache']=array();
+ $_SESSION['group_id_cache']=array();
+ }
+}
diff --git a/lib/appconfig.php b/lib/appconfig.php
new file mode 100644
index 00000000000..f1bccc0a250
--- /dev/null
+++ b/lib/appconfig.php
@@ -0,0 +1,45 @@
+<?php
+class OC_APPCONFIG{
+ static public $forms=array();
+
+ /**
+ * add a form to the settings page
+ * @param string name
+ * @param string url
+ */
+ public static function addForm($name,$url){
+ self::$forms[$name]=$url;
+ }
+
+ /**
+ * Get the available keys for an application
+ * @param string application
+ */
+ public static function getKeys( $application ){
+ // OC_DB::query( $query);
+ return array();
+ }
+
+ /**
+ * Get the config value
+ * @param string application
+ * @param string key
+ * @param string default
+ */
+ public static function getValue( $application, $key, $default ){
+ // OC_DB::query( $query);
+ return $default;
+ }
+
+ /**
+ * Set the config value
+ * @param string application
+ * @param string key
+ * @param string value
+ */
+ public static function setValue( $application, $name, $url ){
+ // OC_DB::query( $query);
+ return true;
+ }
+}
+?>
diff --git a/lib/base.php b/lib/base.php
new file mode 100644
index 00000000000..4694f826a52
--- /dev/null
+++ b/lib/base.php
@@ -0,0 +1,807 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+// set some stuff
+ob_start();
+// error_reporting(E_ALL | E_STRICT);
+error_reporting( E_ERROR | E_PARSE | E_WARNING ); // MDB2 gives loads of strict error, disabling for now
+
+date_default_timezone_set('Europe/Berlin');
+ini_set('arg_separator.output','&amp;');
+ini_set('session.cookie_httponly','1;');
+session_start();
+// calculate the documentroot
+$SERVERROOT=substr(__FILE__,0,-13);
+$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']);
+$SERVERROOT=str_replace("\\",'/',$SERVERROOT);
+$SUBURI=substr(realpath($_SERVER["SCRIPT_FILENAME"]),strlen($SERVERROOT));
+$WEBROOT=substr($_SERVER["SCRIPT_NAME"],0,strlen($_SERVER["SCRIPT_NAME"])-strlen($SUBURI));
+
+
+
+if($WEBROOT!='' and $WEBROOT[0]!=='/'){
+ $WEBROOT='/'.$WEBROOT;
+}
+
+// set the right include path
+// set_include_path(get_include_path().PATH_SEPARATOR.$SERVERROOT.PATH_SEPARATOR.$SERVERROOT.'/inc'.PATH_SEPARATOR.$SERVERROOT.'/config');
+
+// define default config values
+$CONFIG_INSTALLED=false;
+$CONFIG_DATADIRECTORY=$SERVERROOT.'/data';
+$CONFIG_BACKUPDIRECTORY=$SERVERROOT.'/backup';
+$CONFIG_HTTPFORCESSL=false;
+$CONFIG_ENABLEBACKUP=false;
+$CONFIG_DATEFORMAT='j M Y G:i';
+$CONFIG_DBNAME='owncloud';
+$CONFIG_DBTYPE='sqlite';
+$CONFIG_FILESYSTEM=array();
+
+// include the generated configfile
+@include_once($SERVERROOT.'/config/config.php');
+
+
+$CONFIG_DATADIRECTORY_ROOT=$CONFIG_DATADIRECTORY;// store this in a seperate variable so we can change the data directory to jail users.
+// redirect to https site if configured
+if(isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL){
+ if(!isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] != 'on') {
+ $url = "https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
+ header("Location: $url");
+ exit;
+ }
+}
+
+// load core libs
+oc_require_once('files.php');
+oc_require_once('filesystem.php');
+oc_require_once('filestorage.php');
+oc_require_once('fileobserver.php');
+oc_require_once('log.php');
+oc_require_once('config.php');
+oc_require_once('user.php');
+oc_require_once('ocs.php');
+oc_require_once('connect.php');
+oc_require_once('remotestorage.php');
+oc_require_once('plugin.php');
+
+OC_PLUGIN::loadPlugins();
+
+if(!isset($CONFIG_BACKEND)){
+ $CONFIG_BACKEND='database';
+}
+OC_USER::setBackend($CONFIG_BACKEND);
+
+OC_UTIL::setupFS();
+
+oc_startup();
+
+
+
+// check if the server is correctly configured for ownCloud
+OC_UTIL::checkserver();
+
+// listen for login or logout actions
+OC_USER::logoutlistener();
+$loginresult=OC_USER::loginlistener();
+
+/**
+ * Class for utility functions
+ *
+ */
+class OC_UTIL {
+ public static $scripts=array();
+ public static $styles=array();
+ public static $adminpages = array();
+ public static $applications = array();
+ public static $navigation = array();
+ public static $personalmenu = array();
+ private static $fsSetup=false;
+
+ public static function setupFS(){// configure the initial filesystem based on the configuration
+ if(self::$fsSetup){//setting up the filesystem twice can only lead to trouble
+ return false;
+ }
+ global $SERVERROOT;
+ global $CONFIG_DATADIRECTORY_ROOT;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_BACKUPDIRECTORY;
+ global $CONFIG_ENABLEBACKUP;
+ global $CONFIG_FILESYSTEM;
+ if(!is_dir($CONFIG_DATADIRECTORY_ROOT)){
+ @mkdir($CONFIG_DATADIRECTORY_ROOT) or die("Can't create data directory ($CONFIG_DATADIRECTORY_ROOT), you can usually fix this by setting the owner of '$SERVERROOT' to the user that the web server uses (www-data for debian/ubuntu)");
+ }
+ if(OC_USER::isLoggedIn()){ //if we aren't logged in, there is no use to set up the filesystem
+ //first set up the local "root" storage and the backupstorage if needed
+ $rootStorage=OC_FILESYSTEM::createStorage('local',array('datadir'=>$CONFIG_DATADIRECTORY));
+ if($CONFIG_ENABLEBACKUP){
+ if(!is_dir($CONFIG_BACKUPDIRECTORY)){
+ mkdir($CONFIG_BACKUPDIRECTORY);
+ }
+ if(!is_dir($CONFIG_BACKUPDIRECTORY.'/'.$_SESSION['username_clean'])){
+ mkdir($CONFIG_BACKUPDIRECTORY.'/'.$_SESSION['username_clean']);
+ }
+ $backupStorage=OC_FILESYSTEM::createStorage('local',array('datadir'=>$CONFIG_BACKUPDIRECTORY));
+ $backup=new OC_FILEOBSERVER_BACKUP(array('storage'=>$backupStorage));
+ $rootStorage->addObserver($backup);
+ }
+ OC_FILESYSTEM::mount($rootStorage,'/');
+
+ $CONFIG_DATADIRECTORY=$CONFIG_DATADIRECTORY_ROOT.'/'.$_SESSION['username_clean'];
+ if(!is_dir($CONFIG_DATADIRECTORY)){
+ mkdir($CONFIG_DATADIRECTORY);
+ }
+
+ //set up the other storages according to the system settings
+ foreach($CONFIG_FILESYSTEM as $storageConfig){
+ if(OC_FILESYSTEM::hasStorageType($storageConfig['type'])){
+ $arguments=$storageConfig;
+ unset($arguments['type']);
+ unset($arguments['mountpoint']);
+ $storage=OC_FILESYSTEM::createStorage($storageConfig['type'],$arguments);
+ if($storage){
+ OC_FILESYSTEM::mount($storage,$storageConfig['mountpoint']);
+ }
+ }
+ }
+
+ //jail the user into his "home" directory
+ OC_FILESYSTEM::chroot('/'.$_SESSION['username_clean']);
+ self::$fsSetup=true;
+ }
+ }
+
+ /**
+ * get the current installed version of ownCloud
+ * @return array
+ */
+ public static function getVersion(){
+ return array(1,2,0);
+ }
+
+ /**
+ * Create an url
+ *
+ * @param string $application
+ * @param string $file
+ */
+ public static function linkTo( $application, $file = null ){
+ global $WEBROOT;
+ if( is_null( $file )){
+ $file = $application;
+ $application = "";
+ }
+ return "$WEBROOT/$application/$file";
+ }
+
+ /**
+ * Create an image link
+ *
+ * @param string $application
+ * @param string $file
+ */
+ public static function imagePath( $application, $file = null ){
+ global $WEBROOT;
+ if( is_null( $file )){
+ $file = $application;
+ $application = "";
+ }
+ return "$WEBROOT/$application/img/$file";
+ }
+
+ /**
+ * add a javascript file
+ *
+ * @param url $url
+ */
+ public static function addScript( $application, $file = null ){
+ if( is_null( $file )){
+ $file = $application;
+ $application = "";
+ }
+ self::$scripts[] = "$application/js/$file";
+ }
+
+ /**
+ * add a css file
+ *
+ * @param url $url
+ */
+ public static function addStyle( $application, $file = null ){
+ if( is_null( $file )){
+ $file = $application;
+ $application = "";
+ }
+ self::$styles[] = "$application/css/$file";
+ }
+
+ /**
+ * add an entry to the main navigation
+ *
+ * @param array $entry
+ */
+ public static function addNavigationEntry( $entry){
+ OC_UTIL::$navigation[] = $entry;
+ }
+
+ /**
+ * add administration pages
+ *
+ * @param array $entry
+ */
+ public static function addAdminPage( $entry){
+ OC_UTIL::$adminpages[] = $entry;
+ }
+
+ /**
+ * add application
+ *
+ * @param array $entry
+ */
+ public static function addApplication( $entry){
+ OC_UTIL::$applications[] = $entry;
+ }
+
+ /**
+ * add an entry to the personal menu
+ *
+ * @param array $entry
+ */
+ public static function addPersonalMenuEntry( $entry){
+ OC_UTIL::$personalmenu[] = $entry;
+ }
+
+ /**
+ * check if the current server configuration is suitable for ownCloud
+ *
+ */
+ public static function checkServer(){
+ global $SERVERROOT;
+ global $CONFIG_DATADIRECTORY_ROOT;
+ global $CONFIG_BACKUPDIRECTORY;
+ global $CONFIG_ENABLEBACKUP;
+ global $CONFIG_INSTALLED;
+ $error='';
+ if(!is_callable('sqlite_open') and !is_callable('mysql_connect')){
+ $error.='No database drivers (sqlite or mysql) installed.<br/>';
+ }
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DBNAME;
+ if(!stristr(PHP_OS, 'WIN')){
+ if($CONFIG_DBTYPE=='sqlite'){
+ $file=$SERVERROOT.'/'.$CONFIG_DBNAME;
+ if(file_exists($file)){
+ $prems=substr(decoct(fileperms($file)),-3);
+ if(substr($prems,2,1)!='0'){
+ @chmod($file,0660);
+ clearstatcache();
+ $prems=substr(decoct(fileperms($file)),-3);
+ if(substr($prems,2,1)!='0'){
+ $error.='SQLite database file ('.$file.') is readable from the web<br/>';
+ }
+ }
+ }
+ }
+ $prems=substr(decoct(fileperms($CONFIG_DATADIRECTORY_ROOT)),-3);
+ if(substr($prems,-1)!='0'){
+ chmodr($CONFIG_DATADIRECTORY_ROOT,0770);
+ clearstatcache();
+ $prems=substr(decoct(fileperms($CONFIG_DATADIRECTORY_ROOT)),-3);
+ if(substr($prems,2,1)!='0'){
+ $error.='Data directory ('.$CONFIG_DATADIRECTORY_ROOT.') is readable from the web<br/>';
+ }
+ }
+ if($CONFIG_ENABLEBACKUP){
+ $prems=substr(decoct(fileperms($CONFIG_BACKUPDIRECTORY)),-3);
+ if(substr($prems,-1)!='0'){
+ chmodr($CONFIG_BACKUPDIRECTORY,0770);
+ clearstatcache();
+ $prems=substr(decoct(fileperms($CONFIG_BACKUPDIRECTORY)),-3);
+ if(substr($prems,2,1)!='0'){
+ $error.='Data directory ('.$CONFIG_BACKUPDIRECTORY.') is readable from the web<br/>';
+ }
+ }
+ }
+ }else{
+ //TODO: premisions checks for windows hosts
+ }
+ if($error){
+ die($error);
+ }
+ }
+
+ /**
+ * check if we need to use the layout optimized for smaller screen, currently only checks for iPhone/Android
+ * @return bool
+ */
+ public static function hasSmallScreen(){
+ $userAgent=strtolower($_SERVER['HTTP_USER_AGENT']);
+ if(strpos($userAgent,'android') or strpos($userAgent,'iphone') or strpos($userAgent,'ipod')){//todo, add support for more devices
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * show an icon for a filetype
+ *
+ */
+ public static function showIcon($filetype){
+ global $WEBROOT;
+ if($filetype=='dir'){ echo('<td><img src="'.$WEBROOT.'/img/icons/folder.png" width="16" height="16"></td>');
+ }elseif($filetype=='foo'){ echo('<td>foo</td>');
+ }else{ echo('<td><img src="'.$WEBROOT.'/img/icons/other.png" width="16" height="16"></td>');
+ }
+ }
+}
+
+
+/**
+ * Class for database access
+ *
+ */
+class OC_DB {
+ static private $DBConnection=false;
+ static private $schema=false;
+ static private $affected=0;
+ static private $result=false;
+ /**
+ * connect to the datbase if not already connected
+ */
+ public static function connect(){
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $DOCUMENTROOT;
+ global $SERVERROOT;
+ @oc_require_once('MDB2.php');
+ if(!self::$DBConnection){
+ $options = array(
+ 'portability' => MDB2_PORTABILITY_ALL,
+ 'log_line_break' => '<br>',
+ 'idxname_format' => '%s',
+ 'debug' => true,
+ 'quote_identifier' => true,
+ );
+ if($CONFIG_DBTYPE=='sqlite'){
+ $dsn = array(
+ 'phptype' => 'sqlite',
+ 'database' => $SERVERROOT.'/'.$CONFIG_DBNAME,
+ 'mode' => '0644',
+ );
+ }elseif($CONFIG_DBTYPE=='mysql'){
+ $dsn = array(
+ 'phptype' => 'mysql',
+ 'username' => $CONFIG_DBUSER,
+ 'password' => $CONFIG_DBPASSWORD,
+ 'hostspec' => $CONFIG_DBHOST,
+ 'database' => $CONFIG_DBNAME,
+ );
+ }elseif($CONFIG_DBTYPE=='pgsql'){
+ $dsn = array(
+ 'phptype' => 'pgsql',
+ 'username' => $CONFIG_DBUSER,
+ 'password' => $CONFIG_DBPASSWORD,
+ 'hostspec' => $CONFIG_DBHOST,
+ 'database' => $CONFIG_DBNAME,
+ );
+ }
+ self::$DBConnection=MDB2::factory($dsn,$options);
+
+ if (PEAR::isError(self::$DBConnection)) {
+ echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
+ $error=self::$DBConnection->getMessage();
+ error_log("$error");
+ error_log(self::$DBConnection->getUserInfo());
+ die($error);
+ }
+ self::$DBConnection->setFetchMode(MDB2_FETCHMODE_ASSOC);
+ }
+ }
+
+ public static function connectScheme(){
+ self::connect();
+ @oc_require_once('MDB2/Schema.php');
+ if(!self::$schema){
+ self::$schema=&MDB2_Schema::factory(self::$DBConnection);
+ }
+ }
+
+ /**
+ * executes a query on the database
+ *
+ * @param string $cmd
+ * @return result-set
+ */
+ static function query($cmd){
+ global $CONFIG_DBTYPE;
+ if(!trim($cmd)){
+ return false;
+ }
+ OC_DB::connect();
+ //fix differences between sql versions
+
+ //differences in escaping of table names (` for mysql)
+ if($CONFIG_DBTYPE=='sqlite'){
+ $cmd=str_replace('`','\'',$cmd);
+ }elseif($CONFIG_DBTYPE=='pgsql'){
+ $cmd=str_replace('`','"',$cmd);
+ }
+ $result=self::$DBConnection->exec($cmd);
+ if (PEAR::isError($result)) {
+ $entry='DB Error: "'.$result->getMessage().'"<br />';
+ $entry.='Offending command was: '.$cmd.'<br />';
+ error_log($entry);
+ die($entry);
+ }else{
+ self::$affected=$result;
+ }
+ self::$result=$result;
+ return $result;
+ }
+
+ /**
+ * executes a query on the database and returns the result in an array
+ *
+ * @param string $cmd
+ * @return result-set
+ */
+ static function select($cmd){
+ OC_DB::connect();
+ global $CONFIG_DBTYPE;
+ //fix differences between sql versions
+
+ //differences in escaping of table names (` for mysql)
+ if($CONFIG_DBTYPE=='sqlite'){
+ $cmd=str_replace('`','\'',$cmd);
+ }elseif($CONFIG_DBTYPE=='pgsql'){
+ $cmd=str_replace('`','"',$cmd);
+ }
+ $result=self::$DBConnection->queryAll($cmd);
+ if (PEAR::isError($result)){
+ $entry='DB Error: "'.$result->getMessage().'"<br />';
+ $entry.='Offending command was: '.$cmd.'<br />';
+ die($entry);
+ }
+ return $result;
+ }
+
+ /**
+ * executes multiply queries on the database
+ *
+ * @param string $cmd
+ * @return result-set
+ */
+ static function multiquery($cmd) {
+ $queries=explode(';',$cmd);
+ foreach($queries as $query){
+ OC_DB::query($query);
+ }
+ return true;
+ }
+
+
+ /**
+ * closing a db connection
+ *
+ * @return bool
+ */
+ static function close() {
+ self::$DBConnection->disconnect();
+ self::$DBConnection=false;
+ }
+
+
+ /**
+ * Returning primarykey if last statement was an insert.
+ *
+ * @return primarykey
+ */
+ static function insertid() {
+ $id=self::$DBConnection->lastInsertID();
+ return $id;
+ }
+
+ /**
+ * Returning number of rows in a result
+ *
+ * @param resultset $result
+ * @return int
+ */
+ static function numrows($result) {
+ $result->numRows();
+ }
+ /**
+ * Returning number of affected rows
+ *
+ * @return int
+ */
+ static function affected_rows() {
+ return self::$affected;
+ }
+
+ /**
+ * get a field from the resultset
+ *
+ * @param resultset $result
+ * @param int $i
+ * @param int $field
+ * @return unknown
+ */
+ static function result($result, $i, $field) {
+ $tmp=$result->fetchRow(MDB2_FETCHMODE_ASSOC,$i);
+ $tmp=$tmp[$field];
+ return($tmp);
+ }
+
+ /**
+ * get data-array from resultset
+ *
+ * @param resultset $result
+ * @return data
+ */
+ static function fetch_assoc($result){
+ return $result->fetchRow(MDB2_FETCHMODE_ASSOC);
+ }
+
+ /**
+ * Freeing resultset (performance)
+ *
+ * @param unknown_type $result
+ * @return bool
+ */
+ static function free_result() {
+ if(self::$result){
+ self::$result->free();
+ self::$result=false;
+ }
+ }
+
+ static public function disconnect(){
+ if(self::$DBConnection){
+ self::$DBConnection->disconnect();
+ self::$DBConnection=false;
+ }
+ }
+
+ /**
+ * escape strings so they can be used in queries
+ *
+ * @param string string
+ * @return string
+ */
+ static function escape($string){
+ OC_DB::connect();
+ return self::$DBConnection->escape($string);
+ }
+
+ static function getDbStructure($file){
+ OC_DB::connectScheme();
+ $definition = self::$schema->getDefinitionFromDatabase();
+ $dump_options = array(
+ 'output_mode' => 'file',
+ 'output' => $file,
+ 'end_of_line' => "\n"
+ );
+ self::$schema->dumpDatabase($definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE);
+ }
+
+ static function createDbFromStructure($file){
+ OC_DB::connectScheme();
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBTABLEPREFIX;
+ $content=file_get_contents($file);
+ $file2=tempnam(sys_get_temp_dir(),'oc_db_scheme_');
+ $content=str_replace('*dbname*',$CONFIG_DBNAME,$content);
+ $content=str_replace('*dbprefix*',$CONFIG_DBTABLEPREFIX,$content);
+ file_put_contents($file2,$content);
+ $definition=@self::$schema->parseDatabaseDefinitionFile($file2);
+ unlink($file2);
+ if($definition instanceof MDB2_Schema_Error){
+ die($definition->getMessage() . ': ' . $definition->getUserInfo());
+ }
+ $ret=@self::$schema->createDatabase($definition);
+ if($ret instanceof MDB2_Error) {
+ die ($ret->getMessage() . ': ' . $ret->getUserInfo());
+ }else{
+ return true;
+ }
+ }
+}
+
+
+//custom require/include functions because not all hosts allow us to set the include path
+function oc_require($file){
+ global $SERVERROOT;
+ global $DOCUMENTROOT;
+ global $WEBROOT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_INSTALLED;
+
+ if(is_file($file)){
+ return require($file);
+ }
+ elseif(is_file($SERVERROOT.'/'.$file)){
+ return require($SERVERROOT.'/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/lib/'.$file)){
+ return require($SERVERROOT.'/lib/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/3dparty/'.$file)){
+ return require($SERVERROOT.'/3dparty/'.$file);
+ }
+}
+
+function oc_require_once($file){
+ global $SERVERROOT;
+ global $DOCUMENTROOT;
+ global $WEBROOT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_INSTALLED;
+
+ if(is_file($file)){
+ return require_once($file);
+ }
+ elseif(is_file($SERVERROOT.'/'.$file)){
+ return require_once($SERVERROOT.'/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/lib/'.$file)){
+ return require_once($SERVERROOT.'/lib/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/3dparty/'.$file)){
+ return require_once($SERVERROOT.'/3dparty/'.$file);
+ }
+}
+
+function oc_include($file){
+ global $SERVERROOT;
+ global $DOCUMENTROOT;
+ global $WEBROOT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_INSTALLED;
+
+ if(is_file($file)){
+ return include($file);
+ }
+ elseif(is_file($SERVERROOT.'/'.$file)){
+ return include($SERVERROOT.'/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/lib/'.$file)){
+ return include($SERVERROOT.'/lib/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/3dparty/'.$file)){
+ return include($SERVERROOT.'/3dparty/'.$file);
+ }
+}
+
+function oc_include_once($file){
+ global $SERVERROOT;
+ global $DOCUMENTROOT;
+ global $WEBROOT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_INSTALLED;
+
+ if(is_file($file)){
+ return include_once($file);
+ }
+ elseif(is_file($SERVERROOT.'/'.$file)){
+ return include_once($SERVERROOT.'/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/lib/'.$file)){
+ return include_once($SERVERROOT.'/lib/'.$file);
+ }
+ elseif(is_file($SERVERROOT.'/3dparty/'.$file)){
+ return include_once($SERVERROOT.'/3dparty/'.$file);
+ }
+}
+
+function chmodr($path, $filemode) {
+// echo "$path<br/>";
+ if (!is_dir($path))
+ return chmod($path, $filemode);
+ $dh = opendir($path);
+ while (($file = readdir($dh)) !== false) {
+ if($file != '.' && $file != '..') {
+ $fullpath = $path.'/'.$file;
+ if(is_link($fullpath))
+ return FALSE;
+ elseif(!is_dir($fullpath) && !chmod($fullpath, $filemode))
+ return FALSE;
+ elseif(!chmodr($fullpath, $filemode))
+ return FALSE;
+ }
+ }
+ closedir($dh);
+ if(chmod($path, $filemode))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+function oc_startup(){
+ global $SERVERROOT;
+ global $DOCUMENTROOT;
+ global $WEBROOT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_INSTALLED;
+
+ // Add the stuff we need always
+ OC_UTIL::addPersonalMenuEntry( array( "file" => "index.php?logout=1", "name" => "Logout" ));
+ OC_UTIL::addScript( "jquery-1.5.min" );
+ OC_UTIL::addScript( "jquery-ui-1.8.10.custom.min" );
+ OC_UTIL::addScript( "js" );
+ OC_UTIL::addStyle( "jquery-ui-1.8.10.custom" );
+ OC_UTIL::addStyle( "styles" );
+
+ // Require all appinfo.php
+ $dir = opendir( $SERVERROOT );
+ while( false !== ( $filename = readdir( $dir ))){
+ if( substr( $filename, 0, 1 ) != '.' ){
+ if( file_exists( "$SERVERROOT/$filename/appinfo.php" )){
+ oc_require( "$filename/appinfo.php" );
+ }
+ }
+ }
+ closedir( $dir );
+
+ // Everything done
+ return true;
+}
+
+?>
diff --git a/lib/config.php b/lib/config.php
new file mode 100644
index 00000000000..75ddaafc316
--- /dev/null
+++ b/lib/config.php
@@ -0,0 +1,392 @@
+<?php
+class OC_CONFIG{
+ static public $forms=array();
+
+ /**
+ * add a form to the settings page
+ * @param string name
+ * @param string url
+ */
+ public static function addForm($name,$url){
+ self::$forms[$name]=$url;
+ }
+
+ /**
+ * settings page
+ *
+ */
+ public static function showSettings(){
+ oc_require('templates/settings.php');
+ }
+
+ /**
+ * show the configform
+ *
+ */
+ public static function showAdminForm(){
+ global $CONFIG_ADMINLOGIN;
+ global $CONFIG_ADMINPASSWORD;
+ global $CONFIG_DATADIRECTORY;
+ global $CONFIG_HTTPFORCESSL;
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBTABLEPREFIX;
+ global $CONFIG_INSTALLED;
+ $allow=false;
+ if(!$CONFIG_INSTALLED){
+ $allow=true;
+ }elseif(OC_USER::isLoggedIn()){
+ if(OC_USER::ingroup($_SESSION['username'],'admin')){
+ $allow=true;
+ }
+ }
+ if($allow){
+ oc_require('templates/adminform.php');
+ }
+ }
+
+ public static function createUserListener(){
+ if(OC_USER::isLoggedIn()){
+ if(OC_USER::ingroup($_SESSION['username'],'admin')){
+ if(isset($_POST['new_username']) and isset($_POST['new_password'])){
+ if(OC_USER::createuser($_POST['new_username'],$_POST['new_password'])){
+ return 'user successfully created';
+ }else{
+ return 'error while trying to create user';
+ }
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ }
+ }
+
+ public static function createGroupListener(){
+ if(OC_USER::isLoggedIn()){
+ if(isset($_POST['creategroup']) and $_POST['creategroup']==1){
+ if(OC_USER::creategroup($_POST['groupname'])){
+ return 'group successfully created';
+ }else{
+ return 'error while trying to create group';
+ }
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ }
+
+
+ /**
+ * listen for configuration changes
+ *
+ */
+ public static function configListener(){
+ if(OC_USER::isLoggedIn()){
+ if(isset($_POST['config']) and $_POST['config']==1){
+ $error='';
+ if(!OC_USER::checkpassword($_SESSION['username'],$_POST['currentpassword'])){
+ $error.='wrong password<br />';
+ }else{
+ if(isset($_POST['changepass']) and $_POST['changepass']==1){
+ if(!isset($_POST['password']) or empty($_POST['password'])) $error.='password not set<br />';
+ if(!isset($_POST['password2']) or empty($_POST['password2'])) $error.='retype password not set<br />';
+ if($_POST['password']<>$_POST['password2'] ) $error.='passwords are not the same<br />';
+ if(empty($error)){
+ if(!OC_USER::setpassword($_SESSION['username'],$_POST['password'])){
+ $error.='error while trying to set password<br />';
+ }
+ }
+ }
+ }
+ return $error;
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * Write the configuration to the `config.php` file
+ *
+ * $configuration contains key/value pairs
+ * - the key is the option name without the 'CONFIG_' prefix
+ * - the value is a string, a boolean or a number
+ *
+ * @param array $configuration is an associative array
+ */
+ protected static function saveConfiguration($configuration) {
+ global $SERVERROOT;
+
+ $configContent = '<?php';
+ foreach ( $configuration as $key => $value ) {
+ if ( is_string($value) ) {
+ $configContent .= "\n\$CONFIG_$key = '$value';"; // e.g. $CONFIG_DBTYPE = 'mysql';
+ } else if ( is_bool($value) ) {
+ $value = $value ? 'true' : 'false';
+ $configContent .= "\n\$CONFIG_$key = $value;"; // e.g. $CONFIG_INSTALLED = true;
+ } else if ( is_numeric($value) ) {
+ $configContent .= "\n\$CONFIG_$key = $value;"; // e.g. $CONFIG_PI = 3.14;
+ }
+ }
+ $configContent .= "\n?>";
+ $filename = "$SERVERROOT/config/config.php";
+ file_put_contents($filename, $configContent);
+ }
+
+ /**
+ * listen for admin configuration changes and write it to the file
+ *4bd0be1185e76
+ */
+ public static function writeAdminListener(){
+ global $CONFIG_INSTALLED;
+ $allow=false;
+ if(!$CONFIG_INSTALLED){
+ $allow=true;
+ }elseif(OC_USER::isLoggedIn()){
+ if(OC_USER::ingroup($_SESSION['username'],'admin')){
+ $allow=true;
+ }
+ }
+ if($allow){
+ global $DOCUMENTROOT;
+ global $SERVERROOT;
+ global $WEBROOT;
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBTABLEPREFIX;
+ global $CONFIG_INSTALLED;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPASSWORD;
+ global $CONFIG_DBTYPE;
+ global $CONFIG_ADMINLOGIN;
+ global $CONFIG_ADMINPASSWORD;
+ if(isset($_POST['set_config'])){
+ //checkdata
+ $error='';
+ $FIRSTRUN=!$CONFIG_INSTALLED;
+ if(!$FIRSTRUN){
+ if(!OC_USER::login($_SESSION['username'],$_POST['currentpassword'])){
+ $error.='wrong password<br />';
+ }
+ }
+
+ if((!isset($_POST['adminlogin']) or empty($_POST['adminlogin'])) and $FIRSTRUN) $error.='admin login not set<br />';
+ if((!isset($_POST['adminpassword']) or empty($_POST['adminpassword'])) and $FIRSTRUN) $error.='admin password not set<br />';
+ if((!isset($_POST['adminpassword2']) or empty($_POST['adminpassword2'])) and $FIRSTRUN) $error.='retype admin password not set<br />';
+ if((!isset($_POST['datadirectory']) or empty($_POST['datadirectory'])) and $FIRSTRUN) $error.='data directory not set<br />';
+ if(!isset($_POST['dateformat']) or empty($_POST['dateformat'])) $error.='dateformat not set<br />';
+ if((!isset($_POST['dbname']) or empty($_POST['dbname'])) and $FIRSTRUN) $error.='databasename not set<br />';
+ if($FIRSTRUN and $_POST['adminpassword']<>$_POST['adminpassword2'] ) $error.='admin passwords are not the same<br />';
+ $dbtype=(isset($_POST['dbtype']))?$_POST['dbtype']:$CONFIG_DBTYPE;
+ if($dbtype=='mysql'){
+ if(!isset($_POST['dbhost']) or empty($_POST['dbhost'])) $error.='database host not set<br />';
+ if(!isset($_POST['dbuser']) or empty($_POST['dbuser'])) $error.='database user not set<br />';
+ if($_POST['dbpassword']<>$_POST['dbpassword2'] ) $error.='database passwords are not the same<br />';
+
+ }
+ if(isset($_POST['enablebackup']) and $_POST['enablebackup']==1){
+ if(!isset($_POST['backupdirectory']) or empty($_POST['backupdirectory'])) $error.='backup directory not set<br />';
+ }
+ if(!$FIRSTRUN){
+ if(!isset($_POST['adminpassword']) or empty($_POST['adminpassword'])){
+ $_POST['adminpassword']=$CONFIG_ADMINPASSWORD;
+ }
+ if(!isset($_POST['dbpassword']) or empty($_POST['dbpassword'])){
+ $_POST['dbpassword']=$CONFIG_DBPASSWORD;
+ }
+ }else{
+ if(!is_dir($_POST['datadirectory'])){
+ try{
+ mkdir($_POST['datadirectory']);
+ }catch(Exception $e){
+ $error.='error while trying to create data directory<br/>';
+ }
+ }
+ }
+ if(empty($error)) {
+ if($CONFIG_DBTYPE!=$dbtype or $FIRSTRUN){
+ //create/fill database
+ $CONFIG_DBTYPE=$dbtype;
+ $CONFIG_DBNAME=$_POST['dbname'];
+ if($dbtype!='sqlite'){
+ $CONFIG_DBTABLEPREFIX=$_POST['dbtableprefix'];
+ $CONFIG_DBHOST=$_POST['dbhost'];
+ $CONFIG_DBUSER=$_POST['dbuser'];
+ $CONFIG_DBPASSWORD=$_POST['dbpassword'];
+ }else{
+ $_POST['dbtableprefix']='';
+ $CONFIG_DBTABLEPREFIX='';
+ }
+ try{
+ if(isset($_POST['createdatabase']) and $CONFIG_DBTYPE!='sqlite'){
+ self::createdatabase($_POST['dbadminuser'],$_POST['dbadminpwd']);
+ }
+ }catch(Exception $e){
+ $error.='error while trying to create the database<br/>';
+ }
+ if($CONFIG_DBTYPE=='sqlite'){
+ $f=@fopen($SERVERROOT.'/'.$CONFIG_DBNAME,'a+');
+ if(!$f){
+ $error.='path of sqlite database not writable by server<br/>';
+ }
+ OC_DB::disconnect();
+ unlink($SERVERROOT.'/'.$CONFIG_DBNAME);
+ }
+ try{
+ if(isset($_POST['filldb'])){
+ self::filldatabase();
+ }
+ }catch(Exception $e){
+ $error.='error while trying to fill the database<br/>';
+ }
+ if($CONFIG_DBTYPE=='sqlite'){
+ OC_DB::disconnect();
+ }
+ }
+ if($FIRSTRUN){
+ if(!OC_USER::createuser($_POST['adminlogin'],$_POST['adminpassword']) && !OC_USER::login($_POST['adminlogin'],$_POST['adminpassword'])){
+ $error.='error while trying to create the admin user<br/>';
+ }
+ if(OC_USER::getgroupid('admin',true)==0){
+ if(!OC_USER::creategroup('admin')){
+ $error.='error while trying to create the admin group<br/>';
+ }
+ }
+ if(!OC_USER::addtogroup($_POST['adminlogin'],'admin')){
+ $error.='error while trying to add the admin user to the admin group<br/>';
+ }
+ }
+ // Build the configuration array
+ $config = array();
+ $config['INSTALLED'] = true;
+ $config['DATADIRECTORY'] = $_POST['datadirectory'];
+ $config['HTTPFORCESSL'] = isset($_POST['forcessl']);
+ // Backup configuration
+ $config['ENABLEBACKUP'] = isset($_POST['enablebackup']);
+ if ( $config['ENABLEBACKUP'] AND (1 == $_POST['enablebackup']) )
+ $config['BACKUPDIRECTORY'] = $_POST['backupdirectory'];
+ $config['DATEFORMAT'] = $_POST['dateformat'];
+ // DB Configuration
+ $config['DBTYPE'] = $dbtype;
+ $config['DBNAME'] = $_POST['dbname'];
+ $config['DBTABLEPREFIX'] = $_POST['dbtableprefix'];
+ if ( 'sqlite' != $dbtype ) {
+ $config['DBHOST'] = $_POST['dbhost'];
+ $config['DBUSER'] = $_POST['dbuser'];
+ $config['DBPASSWORD'] = $_POST['dbpassword'];
+ }
+
+ if( empty($error) ) {
+ header("Location: $WEBROOT/");
+ try {
+ // Write the configuration array to `/config/config.php`
+ self::saveConfiguration($config);
+ } catch ( Exception $e ) {
+ $error.='error while trying to save the configuration file<br/>';
+ return $error;
+ }
+ } else {
+ return $error;
+ }
+ }
+ return($error);
+ }
+ }
+ }
+
+ /**
+ * Fills the database with the initial tables
+ * Note: while the AUTO_INCREMENT function is not supported by SQLite
+ * the same effect can be achieved by accessing the SQLite pseudo-column
+ * "rowid"
+ */
+ private static function fillDatabase(){
+ global $SERVERROOT;
+ OC_DB::createDBFromStructure($SERVERROOT.'/db_structure.xml');
+ }
+
+ /**
+ * Create the database and user
+ * @param string adminUser
+ * @param string adminPwd
+ *
+ */
+ private static function createDatabase($adminUser,$adminPwd){
+ global $CONFIG_DBHOST;
+ global $CONFIG_DBNAME;
+ global $CONFIG_DBUSER;
+ global $CONFIG_DBPWD;
+ global $CONFIG_DBTYPE;
+ //we cant user OC_BD functions here because we need to connect as the administrative user.
+ if($CONFIG_DBTYPE=='mysql'){
+ $connection=mysql_connect($CONFIG_DBHOST, $adminUser, $adminPwd);
+ if(!$connection) {
+ @ob_end_clean();
+ echo('<html><head></head><body bgcolor="#F0F0F0"><br /><br /><center><b>can not connect to database as administrative user.</center></body></html>');
+ exit();
+ }
+ $query="SELECT user FROM mysql.user WHERE user='{$_POST['dbuser']}'";
+ $result = mysql_query($query,$connection);
+ if (!$result) {
+ $entry='DB Error: "'.mysql_error($connection).'"<br />';
+ $entry.='Offending command was: '.$query.'<br />';
+ echo($entry);
+ }
+ if(mysql_num_rows($result)==0){
+ $pwd=$_POST['dbpassword'];
+ //we need to create 2 accounts, one for global use and one for local user. if we don't speccify the local one,
+ // the anonymous user would take precedence when there is one.
+ $query="CREATE USER '{$_POST['dbuser']}'@'localhost' IDENTIFIED BY '$pwd'";
+ $result = mysql_query($query,$connection);
+ if (!$result) {
+ $entry='DB Error: "'.mysql_error($connection).'"<br />';
+ $entry.='Offending command was: '.$query.'<br />';
+ echo($entry);
+ }
+ $query="CREATE USER '{$_POST['dbuser']}'@'%' IDENTIFIED BY '$pwd'";
+ $result = mysql_query($query,$connection);
+ if (!$result) {
+ $entry='DB Error: "'.mysql_error($connection).'"<br />';
+ $entry.='Offending command was: '.$query.'<br />';
+ echo($entry);
+ }
+ }
+ $query="CREATE DATABASE IF NOT EXISTS `{$_POST['dbname']}`";
+ $result = mysql_query($query,$connection);
+ if (!$result) {
+ $entry='DB Error: "'.mysql_error($connection).'"<br />';
+ $entry.='Offending command was: '.$query.'<br />';
+ echo($entry);
+ }
+ $query="GRANT ALL PRIVILEGES ON `{$_POST['dbname']}` . * TO '{$_POST['dbuser']}'";
+ $result = mysql_query($query,$connection);
+ if (!$result) {
+ $entry='DB Error: "'.mysql_error($connection).'"<br />';
+ $entry.='Offending command was: '.$query.'<br />';
+ echo($entry);
+ }
+ mysql_close($connection);
+ }elseif($CONFIG_DBTYPE=='pgsql'){
+ $connection = pg_connect("user='$adminUser' host='$CONFIG_DBHOST' password='$adminPwd'");
+ $query="CREATE USER {$_POST['dbuser']} WITH PASSWORD '{$_POST['dbpassword']}' CREATEDB;";
+ $result = pg_exec($connection, $query);
+ $query="select count(*) from pg_catalog.pg_database where datname = '{$_POST['dbname']}';";
+ $result = pg_exec($connection, $query);
+ if(pg_result($result,0,0)==0){
+ $query="CREATE DATABASE {$_POST['dbname']};";
+ $result = pg_exec($connection, $query);
+ $query="ALTER DATABASE {$_POST['dbname']} OWNER TO {$_POST['dbuser']};";
+ $result = pg_exec($connection, $query);
+ }
+ }
+ }
+}
+?>
+
+
diff --git a/lib/connect.php b/lib/connect.php
new file mode 100644
index 00000000000..695ae482451
--- /dev/null
+++ b/lib/connect.php
@@ -0,0 +1,300 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Class for connecting multiply ownCloud installations
+ *
+ */
+class OC_CONNECT{
+ static private $clouds=array();
+
+ static function connect($path,$user,$password){
+ $cloud=new OC_REMOTE_CLOUD($path,$user,$password);
+ if($cloud->connected){
+ self::$clouds[$path]=$cloud;
+ return $cloud;
+ }else{
+ return false;
+ }
+ }
+}
+
+
+/**
+ * Class for connection to a remote owncloud installation
+ *
+ */
+class OC_REMOTE_CLOUD{
+ private $path;
+ private $connected=false;
+ private $cookiefile=false;
+
+ /**
+ * make an api call to the remote cloud
+ * @param string $action
+ * @param array parameters
+ * @param bool assoc when set to true, the result will be parsed as associative array
+ *
+ */
+ private function apiCall($action,$parameters=false,$assoc=false){
+ if(!$this->cookiefile){
+ $this->cookiefile=sys_get_temp_dir().'/remoteCloudCookie'.uniqid();
+ }
+ $url=$this->path.='/files/api.php';
+ $fields_string="action=$action&";
+ if(is_array($parameters)){
+ foreach($parameters as $key=>$value){
+ $fields_string.=$key.'='.$value.'&';
+ }
+ rtrim($fields_string,'&');
+ }
+ $ch=curl_init();
+ curl_setopt($ch,CURLOPT_URL,$url);
+ curl_setopt($ch,CURLOPT_POST,count($parameters));
+ curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
+ curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
+ curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
+ curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
+ $result=curl_exec($ch);
+ $result=trim($result);
+ $info=curl_getinfo($ch);
+ $httpCode=$info['http_code'];
+ curl_close($ch);
+ if($httpCode==200 or $httpCode==0){
+ return json_decode($result,$assoc);
+ }else{
+ return false;
+ }
+ }
+
+ public function __construct($path,$user,$password){
+ $this->path=$path;
+ $this->connected=$this->apiCall('login',array('username'=>$user,'password'=>$password));
+ }
+
+ /**
+ * check if we are stull logged in on the remote cloud
+ *
+ */
+ public function isLoggedIn(){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('checklogin');
+ }
+
+ public function __get($name){
+ switch($name){
+ case 'connected':
+ return $this->connected;
+ }
+ }
+
+ /**
+ * disconnect from the remote cloud
+ *
+ */
+ public function disconnect(){
+ $this->connected=false;
+ if(is_file($this->cookiefile)){
+ unlink($this->cookiefile);
+ }
+ $this->cookiefile=false;
+ }
+
+ /**
+ * create a new file or directory
+ * @param string $dir
+ * @param string $name
+ * @param string $type
+ */
+ public function newFile($dir,$name,$type){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('new',array('dir'=>$dir,'name'=>$name,'type'=>$type),true);
+ }
+
+ /**
+ * deletes a file or directory
+ * @param string $dir
+ * @param string $file
+ */
+ public function delete($dir,$name){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('delete',array('dir'=>$dir,'file'=>$name),true);
+ }
+
+ /**
+ * moves a file or directory
+ * @param string $sorceDir
+ * @param string $sorceFile
+ * @param string $targetDir
+ * @param string $targetFile
+ */
+ public function move($sourceDir,$sourceFile,$targetDir,$targetFile){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('move',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
+ }
+
+ /**
+ * copies a file or directory
+ * @param string $sorceDir
+ * @param string $sorceFile
+ * @param string $targetDir
+ * @param string $targetFile
+ */
+ public function copy($sourceDir,$sourceFile,$targetDir,$targetFile){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('copy',array('sourcedir'=>$sourceDir,'source'=>$sourceFile,'targetdir'=>$targetDir,'target'=>$targetFile),true);
+ }
+
+ /**
+ * get a file tree
+ * @param string $dir
+ */
+ public function getTree($dir){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('gettree',array('dir'=>$dir),true);
+ }
+
+ /**
+ * get the files inside a directory of the remote cloud
+ * @param string $dir
+ */
+ public function getFiles($dir){
+ if(!$this->connected){
+ return false;
+ }
+ return $this->apiCall('getfiles',array('dir'=>$dir),true);
+ }
+
+ /**
+ * get a remove file and save it in a temporary file and return the path of the temporary file
+ * @param string $dir
+ * @param string $file
+ * @return string
+ */
+ public function getFile($dir, $file){
+ if(!$this->connected){
+ return false;
+ }
+ $ch=curl_init();
+ if(!$this->cookiefile){
+ $this->cookiefile=sys_get_temp_dir().'/remoteCloudCookie'.uniqid();
+ }
+ $tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
+ $fp=fopen($tmpfile,'w+');
+ $url=$this->path.="/files/api.php?action=get&dir=$dir&file=$file";
+ curl_setopt($ch,CURLOPT_URL,$url);
+ curl_setopt($ch, CURLOPT_COOKIEFILE,$this->cookiefile);
+ curl_setopt($ch, CURLOPT_COOKIEJAR,$this->cookiefile);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+ curl_exec($ch);
+ fclose($fp);
+ curl_close($ch);
+ return $tmpfile;
+ }
+
+ public function sendFile($sourceDir,$sourceFile,$targetDir,$targetFile){
+ global $WEBROOT;
+ $source=$sourceDir.'/'.$sourceFile;
+ $tmp=OC_FILESYSTEM::toTmpFile($source);
+ return $this->sendTmpFile($tmp,$targetDir,$targetFile);
+ }
+
+ public function sendTmpFile($tmp,$targetDir,$targetFile){
+ $token=sha1(uniqid().$tmp);
+ global $WEBROOT;
+ $file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token;
+ rename($tmp,$file);
+ if((isset($CONFIG_HTTPFORCESSL) and $CONFIG_HTTPFORCESSL) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
+ $url = "https://". $_SERVER['SERVER_NAME'] . $WEBROOT;
+ }else{
+ $url = "http://". $_SERVER['SERVER_NAME'] . $WEBROOT;
+ }
+ return $this->apiCall('pull',array('dir'=>$targetDir,'file'=>$targetFile,'token'=>$token,'source'=>$url),true);
+ }
+}
+
+function OC_CONNECT_TEST($path,$user,$password){
+ echo 'connecting...';
+ $remote=OC_CONNECT::connect($path,$user,$password);
+ if($remote->connected){
+ echo 'done<br/>';
+ if($remote->isLoggedIn()){
+ echo 'logged in, session working<br/>';
+ echo 'trying to get remote files...';
+ $files=$remote->getFiles('');
+ if($files){
+ echo count($files).' files found:<br/>';
+ foreach($files as $file){
+ echo "{$file['type']} {$file['name']}: {$file['size']} bytes<br/>";
+ }
+ echo 'getting file "'.$file['name'].'"...';
+ $size=$file['size'];
+ $file=$remote->getFile('',$file['name']);
+ if(file_exists($file)){
+ $newSize=filesize($file);
+ if($size!=$newSize){
+ echo "fail<br/>Error: $newSize bytes received, $size expected.";
+ echo '<br/><br/>Recieved file:<br/>';
+ readfile($file);
+ unlink($file);
+ return;
+ }
+ OC_FILESYSTEM::fromTmpFile($file,'/remoteFile');
+ echo 'done<br/>';
+ echo 'sending file "burning_avatar.png"...';
+ $res=$remote->sendFile('','burning_avatar.png','','burning_avatar.png');
+ if($res){
+ echo 'done<br/>';
+ }else{
+ echo 'fail<br/>';
+ }
+ }else{
+ echo 'fail<br/>';
+ }
+ }else{
+ echo 'fail<br/>';
+ }
+ }else{
+ echo 'no longer logged in, session fail<br/>';
+ }
+ }else{
+ echo 'fail<br/>';
+ }
+ $remote->disconnect();
+ die();
+}
+
+
+?>
diff --git a/lib/fileobserver.php b/lib/fileobserver.php
new file mode 100644
index 00000000000..08a67521f03
--- /dev/null
+++ b/lib/fileobserver.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+define('OC_FILEACTION_WRITE',2);
+define('OC_FILEACTION_READ',4);
+define('OC_FILEACTION_DELETE',8);
+define('OC_FILEACTION_CREATE',16);
+define('OC_FILEACTION_RENAME',32);
+
+/**
+ * base class for file observers
+ */
+class OC_FILEOBSERVER{
+ private $mask;
+
+ public function __construct($arguments){}
+
+ public function __get($name){
+ switch($name){
+ case 'mask':
+ return $this->mask;
+ }
+ }
+
+ public function notify($path,$action){}
+}
+
+/**
+ * observer that makes automatic backups
+ */
+class OC_FILEOBSERVER_BACKUP extends OC_FILEOBSERVER{
+ private $storage;
+
+ public function __construct($arguments){
+ $this->mask=OC_FILEACTION_WRITE+OC_FILEACTION_DELETE+OC_FILEACTION_CREATE+OC_FILEACTION_RENAME;
+ $this->storage=$arguments['storage'];
+ }
+
+ public function notify($path,$action,$storage){
+ switch($action){
+ case OC_FILEACTION_DELETE:
+ if($storage->is_dir($path)){
+ $this->storage->delTree($path);
+ }else{
+ $this->storage->unlink($path);
+ }
+ break;
+ case OC_FILEACTION_CREATE:
+ if($storage->is_dir($path)){
+ $this->storage->mkdir($path);
+ break;
+ }
+ case OC_FILEACTION_WRITE:
+ $tmpFile=$storage->toTmpFile($path);
+ $this->storage->fromTmpFile($tmpFile,$path);
+ break;
+ case OC_FILEACTION_RENAME:
+ list($source,$target)=explode('->',$path);
+ $this->storage->rename($source,$target);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/lib/files.php b/lib/files.php
new file mode 100644
index 00000000000..bf629a59d44
--- /dev/null
+++ b/lib/files.php
@@ -0,0 +1,399 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+oc_require_once("log.php");
+
+
+/**
+ * Class for fileserver access
+ *
+ */
+class OC_FILES {
+ static $tmpFiles=array();
+ /**
+ * show a web GUI filebrowser
+ *
+ * @param basedir $basedir
+ * @param dir $dir
+ */
+ public static function showBrowser($basedir,$dir){
+ echo '<div id="content"></div>';
+ }
+
+ /**
+ * get the content of a directory
+ * @param dir $directory
+ */
+ public static function getDirectoryContent($directory){
+ global $CONFIG_DATADIRECTORY;
+ if(strpos($directory,$CONFIG_DATADIRECTORY)===0){
+ $directory=substr($directory,strlen($CONFIG_DATADIRECTORY));
+ }
+ $filesfound=true;
+ $content=array();
+ $dirs=array();
+ $file=array();
+ $files=array();
+ if(OC_FILESYSTEM::is_dir($directory)) {
+ if ($dh = OC_FILESYSTEM::opendir($directory)) {
+ while (($filename = readdir($dh)) !== false) {
+ if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){
+ $file=array();
+ $filesfound=true;
+ $file['name']=$filename;
+ $file['directory']=$directory;
+ $stat=OC_FILESYSTEM::stat($directory.'/'.$filename);
+ $file=array_merge($file,$stat);
+ $file['mime']=OC_FILES::getMimeType($directory .'/'. $filename);
+ $file['readable']=OC_FILESYSTEM::is_readable($directory .'/'. $filename);
+ $file['writeable']=OC_FILESYSTEM::is_writeable($directory .'/'. $filename);
+ $file['type']=OC_FILESYSTEM::filetype($directory .'/'. $filename);
+ if($file['type']=='dir'){
+ $dirs[$file['name']]=$file;
+ }else{
+ $files[$file['name']]=$file;
+ }
+ }
+ }
+ closedir($dh);
+ }
+ }
+ ksort($dirs);
+ ksort($files);
+ $content=array_merge($dirs,$files);
+ if($filesfound){
+ return $content;
+ }else{
+ return false;
+ }
+ }
+
+
+
+ /**
+ * return the content of a file or return a zip file containning multiply files
+ *
+ * @param dir $dir
+ * @param file $file
+ */
+ public static function get($dir,$files){
+ if(strpos($files,';')){
+ $files=explode(';',$files);
+ }
+ if(is_array($files)){
+ $zip = new ZipArchive();
+ $filename = sys_get_temp_dir()."/ownCloud.zip";
+ if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
+ exit("cannot open <$filename>\n");
+ }
+ foreach($files as $file){
+ $file=$dir.'/'.$file;
+ if(OC_FILESYSTEM::is_file($file)){
+ $tmpFile=OC_FILESYSTEM::toTmpFile($file);
+ self::$tmpFiles[]=$tmpFile;
+ $zip->addFile($tmpFile,basename($file));
+ }elseif(OC_FILESYSTEM::is_dir($file)){
+ zipAddDir($file,$zip);
+ }
+ }
+ $zip->close();
+ }elseif(OC_FILESYSTEM::is_dir($dir.'/'.$files)){
+ $zip = new ZipArchive();
+ $filename = sys_get_temp_dir()."/ownCloud.zip";
+ if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
+ exit("cannot open <$filename>\n");
+ }
+ $file=$dir.'/'.$files;
+ zipAddDir($file,$zip);
+ $zip->close();
+ }else{
+ $zip=false;
+ $filename=$dir.'/'.$files;
+ }
+ if($zip or OC_FILESYSTEM::is_readable($filename)){
+ header('Content-Disposition: attachment; filename="'.basename($filename).'"');
+ header('Content-Transfer-Encoding: binary');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Pragma: public');
+ if($zip){
+ header('Content-Type: application/zip');
+ header('Content-Length: ' . filesize($filename));
+ }else{
+ header('Content-Type: ' . OC_FILESYSTEM::getMimeType($filename));
+ header('Content-Length: ' . OC_FILESYSTEM::filesize($filename));
+ }
+ }elseif($zip or !OC_FILESYSTEM::file_exists($filename)){
+ header("HTTP/1.0 404 Not Found");
+ die('404 Not Found');
+ }else{
+ header("HTTP/1.0 403 Forbidden");
+ die('403 Forbidden');
+ }
+ ob_end_clean();
+ OC_LOG::event($_SESSION['username'],3,"$dir/$files");
+ if($zip){
+ readfile($filename);
+ unlink($filename);
+ }else{
+ OC_FILESYSTEM::readfile($filename);
+ }
+ foreach(self::$tmpFiles as $tmpFile){
+ if(file_exists($tmpFile) and is_file($tmpFile)){
+ unlink($tmpFile);
+ }
+ }
+ }
+
+ /**
+ * move a file or folder
+ *
+ * @param dir $sourceDir
+ * @param file $source
+ * @param dir $targetDir
+ * @param file $target
+ */
+ public static function move($sourceDir,$source,$targetDir,$target){
+ if(OC_USER::isLoggedIn()){
+ $targetFile=$targetDir.'/'.$target;
+ $sourceFile=$sourceDir.'/'.$source;
+ return OC_FILESYSTEM::rename($sourceFile,$targetFile);
+ }
+ }
+
+ /**
+ * copy a file or folder
+ *
+ * @param dir $sourceDir
+ * @param file $source
+ * @param dir $targetDir
+ * @param file $target
+ */
+ public static function copy($sourceDir,$source,$targetDir,$target){
+ if(OC_USER::isLoggedIn()){
+ $targetFile=$targetDir.'/'.$target;
+ $sourceFile=$sourceDir.'/'.$source;
+ return OC_FILESYSTEM::copy($sourceFile,$targetFile);
+ }
+ }
+
+ /**
+ * create a new file or folder
+ *
+ * @param dir $dir
+ * @param file $name
+ * @param type $type
+ */
+ public static function newFile($dir,$name,$type){
+ if(OC_USER::isLoggedIn()){
+ $file=$dir.'/'.$name;
+ if($type=='dir'){
+ return OC_FILESYSTEM::mkdir($file);
+ }elseif($type=='file'){
+ $fileHandle=OC_FILESYSTEM::fopen($file, 'w');
+ if($fileHandle){
+ fclose($fileHandle);
+ OC_LOG::event($_SESSION['username'],4,"$dir/$name");
+ return true;
+ }else{
+ return false;
+ }
+ }
+ }
+ }
+
+ /**
+ * deletes a file or folder
+ *
+ * @param dir $dir
+ * @param file $name
+ */
+ public static function delete($dir,$file){
+ if(OC_USER::isLoggedIn()){
+ $file=$dir.'/'.$file;
+ if(OC_FILESYSTEM::is_file($file)){
+ return OC_FILESYSTEM::unlink($file);
+ }elseif(OC_FILESYSTEM::is_dir($file)){
+ return OC_FILESYSTEM::delTree($file);
+ }
+ }
+ }
+
+ /**
+ * try to detect the mime type of a file
+ *
+ * @param string path
+ * @return string guessed mime type
+ */
+ static function getMimeType($path){
+ return OC_FILESYSTEM::getMimeType($path);
+ }
+
+ /**
+ * get a file tree
+ *
+ * @param string path
+ * @return array
+ */
+ static function getTree($path){
+ return OC_FILESYSTEM::getTree($path);
+ }
+
+ /**
+ * pull a file from a remote server
+ * @param string source
+ * @param string token
+ * @param string dir
+ * @param string file
+ * @return string guessed mime type
+ */
+ static function pull($source,$token,$dir,$file){
+ $tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
+ $fp=fopen($tmpfile,'w+');
+ $url=$source.="/files/pull.php?token=$token";
+ $ch=curl_init();
+ curl_setopt($ch,CURLOPT_URL,$url);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+ curl_exec($ch);
+ fclose($fp);
+ $info=curl_getinfo($ch);
+ $httpCode=$info['http_code'];
+ curl_close($ch);
+ if($httpCode==200 or $httpCode==0){
+ OC_FILESYSTEM::fromTmpFile($tmpfile,$dir.'/'.$file);
+ return true;
+ }else{
+ return false;
+ }
+ }
+}
+
+function zipAddDir($dir,$zip,$internalDir=''){
+ $dirname=basename($dir);
+ $zip->addEmptyDir($internalDir.$dirname);
+ $internalDir.=$dirname.='/';
+ $files=OC_FILES::getdirectorycontent($dir);
+ foreach($files as $file){
+ $filename=$file['name'];
+ $file=$dir.'/'.$filename;
+ if(OC_FILESYSTEM::is_file($file)){
+ $tmpFile=OC_FILESYSTEM::toTmpFile($file);
+ OC_FILES::$tmpFiles[]=$tmpFile;
+ $zip->addFile($tmpFile,$internalDir.$filename);
+ }elseif(OC_FILESYSTEM::is_dir($file)){
+ zipAddDir($file,$zip,$internalDir);
+ }
+ }
+}
+
+//remove a dir and it's content
+function delTree($dir) {
+ if (!file_exists($dir)) return true;
+ if (!is_dir($dir) || is_link($dir)) return unlink($dir);
+ foreach (scandir($dir) as $item) {
+ if ($item == '.' || $item == '..') continue;
+ if(is_file($dir.'/'.$item)){
+ unlink($dir.'/'.$item);
+ }elseif(is_dir($dir.'/'.$item)){
+ if (!delTree($dir. "/" . $item)){
+ return false;
+ };
+ }
+ }
+ $return=rmdir($dir);
+ return $return;
+}
+
+if(!function_exists('sys_get_temp_dir')) {
+ function sys_get_temp_dir() {
+ if( $temp=getenv('TMP') ) return $temp;
+ if( $temp=getenv('TEMP') ) return $temp;
+ if( $temp=getenv('TMPDIR') ) return $temp;
+ $temp=tempnam(__FILE__,'');
+ if (file_exists($temp)) {
+ unlink($temp);
+ return dirname($temp);
+ }
+ return null;
+ }
+}
+
+function recursive_copy($src,$dst) {
+ $dir = opendir($src);
+ @mkdir($dst);
+ while(false !== ( $file = readdir($dir)) ) {
+ if (( $file != '.' ) && ( $file != '..' )) {
+ if ( is_dir($src . '/' . $file) ) {
+ recursive_copy($src . '/' . $file,$dst . '/' . $file);
+ }
+ else {
+ copy($src . '/' . $file,$dst . '/' . $file);
+ }
+ }
+ }
+ closedir($dir);
+}
+
+global $FAKEDIRS;
+$FAKEDIRS=array();
+
+class fakeDirStream{
+ private $name;
+ private $data;
+ private $index;
+
+ public function dir_opendir($path,$options){
+ global $FAKEDIRS;
+ $url=parse_url($path);
+ $this->name=substr($path,strlen('fakedir://'));
+ $this->index=0;
+ if(isset($FAKEDIRS[$this->name])){
+ $this->data=$FAKEDIRS[$this->name];
+ }else{
+ $this->data=array();
+ }
+ return true;
+ }
+
+ public function dir_readdir(){
+ if($this->index>=count($this->data)){
+ return false;
+ }
+ $filename=$this->data[$this->index];
+ $this->index++;
+ return $filename;
+ }
+
+ public function dir_closedir() {
+ $this->data=false;
+ $this->name='';
+ return true;
+ }
+
+ public function dir_rewinddir() {
+ $this->index=0;
+ return true;
+ }
+}
+stream_wrapper_register("fakedir", "fakeDirStream");
+?> \ No newline at end of file
diff --git a/lib/filestorage.php b/lib/filestorage.php
new file mode 100644
index 00000000000..06ce26f0d23
--- /dev/null
+++ b/lib/filestorage.php
@@ -0,0 +1,432 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * Privde a common interface to all different storage options
+ */
+class OC_FILESTORAGE{
+ private $observers=array();
+ /**
+ * add an observer to the list
+ * @param OC_FILEOBERSER observer
+ */
+ public function addObserver($observer){
+ $this->observers[]=$observer;
+ }
+ /**
+ * notify the observers about an action
+ * @param int action a combination of OC_FILEACTION_WRITE and OC_FILEACTION_READ
+ * @param string path relative path of the file
+ */
+ public function notifyObservers($path,$action){
+ foreach($this->observers as $observer){
+ if($observer->mask & $action){
+ $observer->notify($path,$action,$this);
+ }
+ }
+ }
+
+ public function __construct($parameters){}
+ public function mkdir($path){}
+ public function rmdir($path){}
+ public function opendir($path){}
+ public function is_dir($path){}
+ public function is_file($path){}
+ public function stat($path){}
+ public function filetype($path){}
+ public function filesize($path){}
+ public function is_readable($path){}
+ public function is_writeable($path){}
+ public function file_exists($path){}
+ public function readfile($path){}
+ public function filectime($path){}
+ public function filemtime($path){}
+ public function fileatime($path){}
+ public function file_get_contents($path){}
+ public function file_put_contents($path,$data){}
+ public function unlink($path){}
+ public function rename($path1,$path2){}
+ public function copy($path1,$path2){}
+ public function fopen($path,$mode){}
+ public function toTmpFile($path){}//copy the file to a temporary file, used for cross-storage file actions
+ public function fromTmpFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions
+ public function getMimeType($path){}
+ public function delTree($path){}
+ public function find($path){}
+ public function getTree($path){}
+}
+
+
+OC_FILESYSTEM::registerStorageType('local','OC_FILESTORAGE_LOCAL',array('datadir'=>'string'));
+/**
+ * for local filestore, we only have to map the paths
+ */
+class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{
+ private $datadir;
+ public function __construct($arguments){
+ $this->datadir=$arguments['datadir'];
+ if(substr($this->datadir,-1)!=='/'){
+ $this->datadir.='/';
+ }
+ }
+ public function mkdir($path){
+ if($return=mkdir($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_CREATE);
+ }
+ return $return;
+ }
+ public function rmdir($path){
+ if($return=rmdir($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+ public function opendir($path){
+ if($return=opendir($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ }
+ return $return;
+ }
+ public function is_dir($path){
+ return (is_dir($this->datadir.$path) or substr($path,-1)=='/');
+ }
+ public function is_file($path){
+ return is_file($this->datadir.$path);
+ }
+ public function stat($path){
+ return stat($this->datadir.$path);
+ }
+ public function filetype($path){
+ $filetype=filetype($this->datadir.$path);
+ if($filetype=='link'){
+ $filetype=filetype(readlink($this->datadir.$path));
+ }
+ return $filetype;
+ }
+ public function filesize($path){
+ return filesize($this->datadir.$path);
+ }
+ public function is_readable($path){
+ return is_readable($this->datadir.$path);
+ }
+ public function is_writeable($path){
+ return is_writeable($this->datadir.$path);
+ }
+ public function file_exists($path){
+ return file_exists($this->datadir.$path);
+ }
+ public function readfile($path){
+ if($return=readfile($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ }
+ return $return;
+ }
+ public function filectime($path){
+ return filectime($this->datadir.$path);
+ }
+ public function filemtime($path){
+ return filemtime($this->datadir.$path);
+ }
+ public function fileatime($path){
+ return fileatime($this->datadir.$path);
+ }
+ public function file_get_contents($path){
+ if($return=file_get_contents($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ }
+ return $return;
+ }
+ public function file_put_contents($path,$data){
+ if($return=file_put_contents($this->datadir.$path,$data)){
+ $this->notifyObservers($path,OC_FILEACTION_WRITE);
+ }
+ }
+ public function unlink($path){
+ if($return=unlink($this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+ public function rename($path1,$path2){
+ if($return=rename($this->datadir.$path1,$this->datadir.$path2)){
+ $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
+ }
+ return $return;
+ }
+ public function copy($path1,$path2){
+ if($this->is_dir($path2)){
+ if(!$this->file_exists($path2)){
+ $this->mkdir($path2);
+ }
+ $source=substr($path1,strrpos($path1,'/')+1);
+ $path2.=$source;
+ }
+ if($return=copy($this->datadir.$path1,$this->datadir.$path2)){
+ $this->notifyObservers($path2,OC_FILEACTION_CREATE);
+ }
+ return $return;
+ }
+ public function fopen($path,$mode){
+ if($return=fopen($this->datadir.$path,$mode)){
+ switch($mode){
+ case 'r':
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ break;
+ case 'r+':
+ case 'w+':
+ case 'x+':
+ case 'a+':
+ $this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE);
+ break;
+ case 'w':
+ case 'x':
+ case 'a':
+ $this->notifyObservers($path,OC_FILEACTION_WRITE);
+ break;
+ }
+ }
+ return $return;
+ }
+
+ public function getMimeType($fspath){
+ if($this->is_readable($fspath)){
+ if (@is_dir($this->datadir.$fspath)) {
+ // directories are easy
+ return "httpd/unix-directory";
+ }elseif (function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){
+ $mimeType =strtolower(finfo_file($finfo,$this->datadir.$fspath));
+ $mimeType=substr($mimeType,0,strpos($mimeType,';'));
+ finfo_close($finfo);
+ return $mimeType;
+ } else if (function_exists("mime_content_type")) {
+ // use mime magic extension if available
+ $mime_type = mime_content_type($this->datadir.$fspath);
+ } else if (self::canExecute("file")) {
+ // it looks like we have a 'file' command,
+ // lets see it it does have mime support
+ $fp = popen("file -i -b '{$this->datadir}$fspath' 2>/dev/null", "r");
+ $reply = fgets($fp);
+ pclose($fp);
+
+ //trim the character set from the end of the response
+ $mime_type=substr($reply,0,strrpos($reply,' '));
+ }
+ if (empty($mime_type)) {
+ // Fallback solution: try to guess the type by the file extension
+ // TODO: add more ...
+ switch (strtolower(strrchr(basename($fspath), "."))) {
+ case '.css':
+ $mime_type = 'text/css';
+ break;
+ case '.flac':
+ $mime_type = 'audio/flac';
+ break;
+ case '.gif':
+ $mime_type = 'image/gif';
+ break;
+ case '.gzip':
+ case '.gz':
+ $mime_type = 'application/x-gzip';
+ break;
+ case '.htm':
+ case '.html':
+ $mime_type = 'text/html';
+ break;
+ case '.jpeg':
+ case '.jpg':
+ $mime_type = 'image/jpeg';
+ break;
+ case '.js':
+ $mime_type = 'application/x-javascript';
+ break;
+ case '.oga':
+ case '.ogg':
+ $mime_type = 'audio/ogg';
+ break;
+ case '.ogv':
+ $mime_type = 'video/ogg';
+ break;
+ case '.pdf':
+ $mime_type = 'application/pdf';
+ break;
+ case '.png':
+ $mime_type = 'image/png';
+ break;
+ case '.svg':
+ $mime_type = 'image/svg+xml';
+ break;
+ case '.tar':
+ $mime_type = 'application/x-tar';
+ break;
+ case '.tgz':
+ $mime_type = 'application/x-compressed';
+ break;
+ case '.tif':
+ case '.tiff':
+ $mime_type = 'image/tiff';
+ break;
+ case '.txt':
+ $mime_type = 'text/plain';
+ break;
+ case '.zip':
+ $mime_type = 'application/zip';
+ break;
+ default:
+ $mime_type = 'application/octet-stream';
+ break;
+ }
+ }
+
+ return $mime_type;
+ }
+ }
+
+ /**
+ * detect if a given program is found in the search PATH
+ *
+ * helper function used by _mimetype() to detect if the
+ * external 'file' utility is available
+ *
+ * @param string program name
+ * @param string optional search path, defaults to $PATH
+ * @return bool true if executable program found in path
+ */
+ private function canExecute($name, $path = false)
+ {
+ // path defaults to PATH from environment if not set
+ if ($path === false) {
+ $path = getenv("PATH");
+ }
+
+ // check method depends on operating system
+ if (!strncmp(PHP_OS, "WIN", 3)) {
+ // on Windows an appropriate COM or EXE file needs to exist
+ $exts = array(".exe", ".com");
+ $check_fn = "file_exists";
+ } else {
+ // anywhere else we look for an executable file of that name
+ $exts = array("");
+ $check_fn = "is_executable";
+ }
+
+ // Default check will be done with $path directories :
+ $dirs = explode(PATH_SEPARATOR, $path);
+
+ // WARNING : We have to check if open_basedir is enabled :
+ $obd = ini_get('open_basedir');
+
+ if($obd != "none")
+ $obd_values = explode(PATH_SEPARATOR, $obd);
+
+ if(count($obd_values) > 0)
+ {
+ // open_basedir is in effect !
+ // We need to check if the program is in one of these dirs :
+ $dirs = $obd_values;
+ }
+
+ foreach($dirs as $dir)
+ {
+ foreach($exts as $ext)
+ {
+ if($check_fn("$dir/$name".$ext))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function toTmpFile($path){
+ $tmpFolder=sys_get_temp_dir();
+ $filename=tempnam($tmpFolder,'OC_TEMP_FILE_'.substr($path,strrpos($path,'.')));
+ if(copy($this->datadir.$path,$filename)){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ return $filename;
+ }else{
+ return false;
+ }
+ }
+
+ public function fromTmpFile($tmpFile,$path){
+ if(rename($tmpFile,$this->datadir.$path)){
+ $this->notifyObservers($path,OC_FILEACTION_CREATE);
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ public function delTree($dir) {
+ $dirRelative=$dir;
+ $dir=$this->datadir.$dir;
+ if (!file_exists($dir)) return true;
+ if (!is_dir($dir) || is_link($dir)) return unlink($dir);
+ foreach (scandir($dir) as $item) {
+ if ($item == '.' || $item == '..') continue;
+ if(is_file($dir.'/'.$item)){
+ if(unlink($dir.'/'.$item)){
+ $this->notifyObservers($dir.'/'.$item,OC_FILEACTION_DELETE);
+ }
+ }elseif(is_dir($dir.'/'.$item)){
+ if (!$this->delTree($dirRelative. "/" . $item)){
+ return false;
+ };
+ }
+ }
+ if($return=rmdir($dir)){
+ $this->notifyObservers($dir,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+
+ public function find($path){
+ $return=System::find($this->datadir.$path);
+ foreach($return as &$file){
+ $file=str_replace($file,$this->datadir,'');
+ }
+ return $return;
+ }
+
+ public function getTree($dir) {
+ if(substr($dir,-1,1)=='/'){
+ $dir=substr($dir,0,-1);
+ }
+ $tree=array();
+ $tree[]=$dir;
+ $dirRelative=$dir;
+ $dir=$this->datadir.$dir;
+ if (!file_exists($dir)) return true;
+ foreach (scandir($dir) as $item) {
+ if ($item == '.' || $item == '..') continue;
+ if(is_file($dir.'/'.$item)){
+ $tree[]=$dirRelative.'/'.$item;
+ }elseif(is_dir($dir.'/'.$item)){
+ if ($subTree=$this->getTree($dirRelative. "/" . $item)){
+ $tree=array_merge($tree,$subTree);
+ }
+ }
+ }
+ return $tree;
+ }
+}
+?> \ No newline at end of file
diff --git a/lib/filesystem.php b/lib/filesystem.php
new file mode 100644
index 00000000000..26a0066aa74
--- /dev/null
+++ b/lib/filesystem.php
@@ -0,0 +1,380 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+/**
+ * Class for abstraction of filesystem functions
+ * This class won't call any filesystem functions for itself but but will pass them to the correct OC_FILESTORAGE object
+ * this class should also handle all the file premission related stuff
+ */
+class OC_FILESYSTEM{
+ static private $storages=array();
+ static private $fakeRoot='';
+ static private $storageTypes=array();
+
+
+ /**
+ * register a storage type
+ * @param string type
+ * @param string classname
+ * @param array arguments an associative array in the form of name=>type (eg array('datadir'=>'string'))
+ */
+ static public function registerStorageType($type,$classname,$arguments){
+ self::$storageTypes[$type]=array('type'=>$type,'classname'=>$classname,'arguments'=>$arguments);
+ }
+
+ /**
+ * check if the filesystem supports a specific storagetype
+ * @param string type
+ * @return bool
+ */
+ static public function hasStorageType($type){
+ return isset(self::$storageTypes[$type]);
+ }
+
+ /**
+ * get the list of names of storagetypes that the filesystem supports
+ * @return array
+ */
+ static public function getStorageTypeNames(){
+ return array_keys(self::$storageTypes);
+ }
+
+ /**
+ * create a new storage of a specific type
+ * @param string type
+ * @param array arguments
+ * @return OC_FILESTORAGE
+ */
+ static public function createStorage($type,$arguments){
+ if(!self::hasStorageType($type)){
+ return false;
+ }
+ $className=self::$storageTypes[$type]['classname'];
+ if(class_exists($className)){
+ return new $className($arguments);
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * change the root to a fake toor
+ * @param string fakeRoot
+ * @return bool
+ */
+ static public function chroot($fakeRoot){
+ if($fakeRoot[0]!=='/'){
+ $fakeRoot='/'.$fakeRoot;
+ }
+ self::$fakeRoot=$fakeRoot;
+ }
+
+ /**
+ * get the part of the path relative to the mountpoint of the storage it's stored in
+ * @param string path
+ * @return bool
+ */
+ static public function getInternalPath($path){
+ $mountPoint=self::getMountPoint($path);
+ $path=self::$fakeRoot.$path;
+ $internalPath=substr($path,strlen($mountPoint));
+ return $internalPath;
+ }
+
+ /**
+ * check if the current users has the right premissions to read a file
+ * @param string path
+ * @return bool
+ */
+ static private function canRead($path){
+ if(substr($path,0,1)!=='/'){
+ $path='/'.$path;
+ }
+ if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
+ return false;
+ }
+ return true;//dummy untill premissions are correctly implemented, also the correcty value because for now users are locked in their seperate data dir and can read/write everything in there
+ }
+ /**
+ * check if the current users has the right premissions to write a file
+ * @param string path
+ * @return bool
+ */
+ static private function canWrite($path){
+ if(substr($path,0,1)!=='/'){
+ $path='/'.$path;
+ }
+ if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
+ return false;
+ }
+ return true;//dummy untill premissions are correctly implemented, also the correcty value because for now users are locked in their seperate data dir and can read/write everything in there
+ }
+
+ /**
+ * mount an OC_FILESTORAGE in our virtual filesystem
+ * @param OC_FILESTORAGE storage
+ * @param string mountpoint
+ */
+ static public function mount($storage,$mountpoint){
+ if(substr($mountpoint,0,1)!=='/'){
+ $mountpoint='/'.$mountpoint;
+ }
+ self::$storages[self::$fakeRoot.$mountpoint]=$storage;
+ }
+
+ /**
+ * get the storage object for a path
+ * @param string path
+ * @return OC_FILESTORAGE
+ */
+ static private function getStorage($path){
+ $mountpoint=self::getMountPoint($path);
+ if($mountpoint){
+ return self::$storages[$mountpoint];
+ }
+ }
+
+ /**
+ * get the mountpoint of the storage object for a path
+ ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
+ *
+ * @param string path
+ * @return string
+ */
+ static private function getMountPoint($path){
+ if(!$path){
+ $path='/';
+ }
+ if(substr($path,0,1)!=='/'){
+ $path='/'.$path;
+ }
+ if(substr($path,-1)!=='/'){
+ $path=$path.'/';
+ }
+ $path=self::$fakeRoot.$path;
+ $foundMountPoint='';
+ foreach(self::$storages as $mountpoint=>$storage){
+ if(substr($mountpoint,-1)!=='/'){
+ $mountpoint=$mountpoint.'/';
+ }
+ if($mountpoint==$path){
+ return $mountpoint;
+ }
+ if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)){
+ $foundMountPoint=$mountpoint;
+ }
+ }
+ return $foundMountPoint;
+ }
+
+ static public function mkdir($path){
+ $parent=substr($path,0,strrpos($path,'/'));
+ if(self::canWrite($parent) and $storage=self::getStorage($path)){
+ return $storage->mkdir(self::getInternalPath($path));
+ }
+ }
+ static public function rmdir($path){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->rmdir(self::getInternalPath($path));
+ }
+ }
+ static public function opendir($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->opendir(self::getInternalPath($path));
+ }
+ }
+ static public function is_dir($path){
+ if($path=='/'){
+ return true;
+ }
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->is_dir(self::getInternalPath($path));
+ }
+ }
+ static public function is_file($path){
+ if($path=='/'){
+ return false;
+ }
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->is_file(self::getInternalPath($path));
+ }
+ }
+ static public function stat($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->stat(self::getInternalPath($path));
+ }
+ }
+ static public function filetype($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->filetype(self::getInternalPath($path));
+ }
+ }
+ static public function filesize($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->filesize(self::getInternalPath($path));
+ }
+ }
+ static public function readfile($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->readfile(self::getInternalPath($path));
+ }
+ }
+ static public function is_readable($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->is_readable(self::getInternalPath($path));
+ }
+ return false;
+ }
+ static public function is_writeable($path){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->is_writeable(self::getInternalPath($path));
+ }
+ return false;
+ }
+ static public function file_exists($path){
+ if($path=='/'){
+ return true;
+ }
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->file_exists(self::getInternalPath($path));
+ }
+ return false;
+ }
+ static public function filectime($path){
+ if($storage=self::getStorage($path)){
+ return $storage->filectime(self::getInternalPath($path));
+ }
+ }
+ static public function filemtime($path){
+ if($storage=self::getStorage($path)){
+ return $storage->filemtime(self::getInternalPath($path));
+ }
+ }
+ static public function fileatime($path){
+ if($storage=self::getStorage($path)){
+ return $storage->fileatime(self::getInternalPath($path));
+ }
+ }
+ static public function file_get_contents($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->file_get_contents(self::getInternalPath($path));
+ }
+ }
+ static public function file_put_contents($path,$data){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->file_put_contents(self::getInternalPath($path),$data);
+ }
+ }
+ static public function unlink($path){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->unlink(self::getInternalPath($path));
+ }
+ }
+ static public function rename($path1,$path2){
+ if(self::canWrite($path1) and self::canWrite($path2)){
+ $mp1=self::getMountPoint($path1);
+ $mp2=self::getMountPoint($path2);
+ if($mp1==$mp2){
+ if($storage=self::getStorage($path1)){
+ return $storage->rename(self::getInternalPath($path1),self::getInternalPath($path2));
+ }
+ }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){
+ $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1));
+ $result=$storage2->fromTmpFile(self::getInternalPath($path2));
+ $storage1->unlink(self::getInternalPath($path1));
+ return $result;
+ }
+ }
+ }
+ static public function copy($path1,$path2){
+ if(self::canRead($path1) and self::canWrite($path2)){
+ $mp1=self::getMountPoint($path1);
+ $mp2=self::getMountPoint($path2);
+ if($mp1==$mp2){
+ if($storage=self::getStorage($path1)){
+ return $storage->copy(self::getInternalPath($path1),self::getInternalPath($path2));
+ }
+ }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){
+ $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1));
+ return $storage2->fromTmpFile(self::getInternalPath($path2));
+ }
+ }
+ }
+ static public function fopen($path,$mode){
+ $allowed=((strpos($path,'r')===false and strpos($path,'r+')!==false and self::canRead) or self::canWrite($path));
+ if($allowed){
+ if($storage=self::getStorage($path)){
+ return $storage->fopen(self::getInternalPath($path),$mode);
+ }
+ }
+ }
+ static public function toTmpFile($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->toTmpFile(self::getInternalPath($path));
+ }
+ }
+ static public function fromTmpFile($tmpFile,$path){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->fromTmpFile($tmpFile,self::getInternalPath($path));
+ }
+ }
+ static public function getMimeType($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ return $storage->getMimeType(self::getInternalPath($path));
+ }
+ }
+ static public function delTree($path){
+ if(self::canWrite($path) and $storage=self::getStorage($path)){
+ return $storage->delTree(self::getInternalPath($path));
+ }
+ }
+ static public function find($path){
+ if($storage=self::getStorage($path)){
+ $mp=self::getMountPoint($path);
+ $return=$storage->find(self::getInternalPath($path));
+ foreach($return as &$file){
+ $file=$mp.$file;
+ }
+ }
+ return $return;
+ }
+ static public function getTree($path){
+ if(self::canRead($path) and $storage=self::getStorage($path)){
+ $mp=self::getMountPoint($path);
+ $return=$storage->getTree(self::getInternalPath($path));
+ foreach($return as &$file){
+ if(substr($file,0,1)=='/'){
+ $file=substr($file,1);
+ }
+ $file=$mp.$file;
+ $file=substr($file,strlen(self::$fakeRoot));
+ if($file === '' || $file === false){
+ $file = '/';
+ }
+ }
+ return $return;
+ }
+ }
+}
+?>
diff --git a/lib/log.php b/lib/log.php
new file mode 100644
index 00000000000..f2f935b466b
--- /dev/null
+++ b/lib/log.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+/**
+ * Class for logging features
+ *
+ */
+class OC_LOG {
+
+ /**
+ * array to define different log types
+ *
+ */
+ public static $TYPE = array (
+ 1=>'login',
+ 2=>'logout',
+ 3=>'read',
+ 4=>'write' );
+
+
+ /**
+ * log an event
+ *
+ * @param username $user
+ * @param type $type
+ * @param message $message
+ */
+ public static function event($user,$type,$message){
+ global $CONFIG_DBTABLEPREFIX;
+ $result = OC_DB::query('INSERT INTO `' . $CONFIG_DBTABLEPREFIX . 'log` (`timestamp`,`user`,`type`,`message`) VALUES ('.time().',\''.addslashes($user).'\','.addslashes($type).',\''.addslashes($message).'\');');
+ }
+
+
+ /**
+ * get log entries
+ */
+ public static function get(){
+ global $CONFIG_DATEFORMAT;
+ global $CONFIG_DBTABLEPREFIX;
+
+ $result;
+
+ if(OC_USER::ingroup($_SESSION['username_clean'],'admin')){
+ $result = OC_DB::select('select `timestamp`,`user`,`type`,`message` from '.$CONFIG_DBTABLEPREFIX.'log order by timestamp desc limit 20');
+ }
+ else{
+ $user=$_SESSION['username_clean'];
+ $result = OC_DB::select('select `timestamp`,`user`,`type`,`message` from '.$CONFIG_DBTABLEPREFIX.'log where user=\''.$user.'\' order by timestamp desc limit 20');
+ }
+
+ return $result;
+ }
+}
+
+
+
+?>
diff --git a/lib/ocs.php b/lib/ocs.php
new file mode 100644
index 00000000000..08b4b79ae91
--- /dev/null
+++ b/lib/ocs.php
@@ -0,0 +1,592 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+
+/**
+ * Class to handle open collaboration services API requests
+ *
+ */
+class OC_OCS {
+
+ /**
+ * reads input date from get/post/cookies and converts the date to a special data-type
+ *
+ * @param variable $key
+ * @param variable-type $type
+ * @param priority $getpriority
+ * @param default $default
+ * @return data
+ */
+ public static function readData($key,$type='raw',$getpriority=false,$default='') {
+ if($getpriority) {
+ if(isset($_GET[$key])) {
+ $data=$_GET[$key];
+ } elseif(isset($_POST[$key])) {
+ $data=$_POST[$key];
+ } else {
+ if($default=='') {
+ if(($type=='int') or ($type=='float')) $data=0; else $data='';
+ } else {
+ $data=$default;
+ }
+ }
+ } else {
+ if(isset($_POST[$key])) {
+ $data=$_POST[$key];
+ } elseif(isset($_GET[$key])) {
+ $data=$_GET[$key];
+ } elseif(isset($_COOKIE[$key])) {
+ $data=$_COOKIE[$key];
+ } else {
+ if($default=='') {
+ if(($type=='int') or ($type=='float')) $data=0; else $data='';
+ } else {
+ $data=$default;
+ }
+ }
+ }
+
+ if($type=='raw') return($data);
+ elseif($type=='text') return(addslashes(strip_tags($data)));
+ elseif($type=='int') { $data = (int) $data; return($data); }
+ elseif($type=='float') { $data = (float) $data; return($data); }
+ elseif($type=='array') { $data = $data; return($data); }
+ }
+
+
+ /**
+ main function to handle the REST request
+ **/
+ public static function handle() {
+
+ // overwrite the 404 error page returncode
+ header("HTTP/1.0 200 OK");
+
+
+ if($_SERVER['REQUEST_METHOD'] == 'GET') {
+ $method='get';
+ }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
+ $method='put';
+ parse_str(file_get_contents("php://input"),$put_vars);
+ }elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
+ $method='post';
+ }else{
+ echo('internal server error: method not supported');
+ exit();
+ }
+
+ // preprocess url
+ $url=$_SERVER['REQUEST_URI'];
+ if(substr($url,(strlen($url)-1))<>'/') $url.='/';
+ $ex=explode('/',$url);
+ $paracount=count($ex);
+
+ // eventhandler
+ // CONFIG
+ // apiconfig - GET - CONFIG
+ if(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php') and (strtolower($ex[$paracount-2])=='config')){
+ $format=OC_OCS::readdata('format','text');
+ OC_OCS::apiconfig($format);
+
+ // PERSON
+ // personcheck - POST - PERSON/CHECK
+ }elseif(($method=='post') and (strtolower($ex[$paracount-4])=='v1.php') and (strtolower($ex[$paracount-3])=='person') and (strtolower($ex[$paracount-2])=='check')){
+ $format=OC_OCS::readdata('format','text');
+ $login=OC_OCS::readdata('login','text');
+ $passwd=OC_OCS::readdata('password','text');
+ OC_OCS::personcheck($format,$login,$passwd);
+
+ // ACTIVITY
+ // activityget - GET ACTIVITY page,pagesize als urlparameter
+ }elseif(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){
+ $format=OC_OCS::readdata('format','text');
+ $page=OC_OCS::readdata('page','int');
+ $pagesize=OC_OCS::readdata('pagesize','int');
+ if($pagesize<1 or $pagesize>100) $pagesize=10;
+ OC_OCS::activityget($format,$page,$pagesize);
+
+ // activityput - POST ACTIVITY
+ }elseif(($method=='post') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){
+ $format=OC_OCS::readdata('format','text');
+ $message=OC_OCS::readdata('message','text');
+ OC_OCS::activityput($format,$message);
+
+ // PRIVATEDATA
+ // get - GET DATA
+ }elseif(($method=='get') and (strtolower($ex[$paracount-4])=='v1.php')and (strtolower($ex[$paracount-2])=='getattribute')){
+ $format=OC_OCS::readdata('format','text');
+ OC_OCS::privateDataGet($format);
+
+ }elseif(($method=='get') and (strtolower($ex[$paracount-5])=='v1.php')and (strtolower($ex[$paracount-3])=='getattribute')){
+ $format=OC_OCS::readdata('format','text');
+ $app=$ex[$paracount-2];
+ OC_OCS::privateDataGet($format, $app);
+ }elseif(($method=='get') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='getattribute')){
+ $format=OC_OCS::readdata('format','text');
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ OC_OCS::privateDataGet($format, $app,$key);
+
+ // set - POST DATA
+ }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='setattribute')){
+ $format=OC_OCS::readdata('format','text');
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ $value=OC_OCS::readdata('value','text');
+ OC_OCS::privatedataset($format, $app, $key, $value);
+ // delete - POST DATA
+ }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='deleteattribute')){
+ $format=OC_OCS::readdata('format','text');
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ OC_OCS::privatedatadelete($format, $app, $key);
+
+ }else{
+ $format=OC_OCS::readdata('format','text');
+ $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
+ $txt.=OC_OCS::getdebugoutput();
+ echo(OC_OCS::generatexml($format,'failed',999,$txt));
+ }
+ exit();
+ }
+
+ /**
+ * generated some debug information to make it easier to find faild API calls
+ * @return debug data string
+ */
+ private static function getDebugOutput() {
+ $txt='';
+ $txt.="debug output:\n";
+ if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n";
+ if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n";
+ if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n";
+ if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
+ return($txt);
+ }
+
+ /**
+ * checks if the user is authenticated
+ * checks the IP whitlist, apikeys and login/password combination
+ * if $forceuser is true and the authentication failed it returns an 401 http response.
+ * if $forceuser is false and authentification fails it returns an empty username string
+ * @param bool $forceuser
+ * @return username string
+ */
+ private static function checkPassword($forceuser=true) {
+ //valid user account ?
+ if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
+ if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
+
+ if(empty($authuser)) {
+ if($forceuser){
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }else{
+ $identifieduser='';
+ }
+ }else{
+ if(!OC_USER::login($authuser,$authpw)){
+ if($forceuser){
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }else{
+ $identifieduser='';
+ }
+ }else{
+ $identifieduser=$authuser;
+ }
+ }
+
+ return($identifieduser);
+ }
+
+
+ /**
+ * generates the xml or json response for the API call from an multidimenional data array.
+ * @param string $format
+ * @param string $status
+ * @param string $statuscode
+ * @param string $message
+ * @param array $data
+ * @param string $tag
+ * @param string $tagattribute
+ * @param int $dimension
+ * @param int $itemscount
+ * @param int $itemsperpage
+ * @return string xml/json
+ */
+ private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') {
+ if($format=='json') {
+
+ $json=array();
+ $json['status']=$status;
+ $json['statuscode']=$statuscode;
+ $json['message']=$message;
+ $json['totalitems']=$itemscount;
+ $json['itemsperpage']=$itemsperpage;
+ $json['data']=$data;
+ return(json_encode($json));
+
+
+ }else{
+ $txt='';
+ $writer = xmlwriter_open_memory();
+ xmlwriter_set_indent( $writer, 2 );
+ xmlwriter_start_document($writer );
+ xmlwriter_start_element($writer,'ocs');
+ xmlwriter_start_element($writer,'meta');
+ xmlwriter_write_element($writer,'status',$status);
+ xmlwriter_write_element($writer,'statuscode',$statuscode);
+ xmlwriter_write_element($writer,'message',$message);
+ if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount);
+ if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage);
+ xmlwriter_end_element($writer);
+ if($dimension=='0') {
+ // 0 dimensions
+ xmlwriter_write_element($writer,'data',$data);
+
+ }elseif($dimension=='1') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $key=>$entry) {
+ xmlwriter_write_element($writer,$key,$entry);
+ }
+ xmlwriter_end_element($writer);
+
+ }elseif($dimension=='2') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $entry) {
+ xmlwriter_start_element($writer,$tag);
+ if(!empty($tagattribute)) {
+ xmlwriter_write_attribute($writer,'details',$tagattribute);
+ }
+ foreach($entry as $key=>$value) {
+ if(is_array($value)){
+ foreach($value as $k=>$v) {
+ xmlwriter_write_element($writer,$k,$v);
+ }
+ } else {
+ xmlwriter_write_element($writer,$key,$value);
+ }
+ }
+ xmlwriter_end_element($writer);
+ }
+ xmlwriter_end_element($writer);
+
+ }elseif($dimension=='3') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $entrykey=>$entry) {
+ xmlwriter_start_element($writer,$tag);
+ if(!empty($tagattribute)) {
+ xmlwriter_write_attribute($writer,'details',$tagattribute);
+ }
+ foreach($entry as $key=>$value) {
+ if(is_array($value)){
+ xmlwriter_start_element($writer,$entrykey);
+ foreach($value as $k=>$v) {
+ xmlwriter_write_element($writer,$k,$v);
+ }
+ xmlwriter_end_element($writer);
+ } else {
+ xmlwriter_write_element($writer,$key,$value);
+ }
+ }
+ xmlwriter_end_element($writer);
+ }
+ xmlwriter_end_element($writer);
+ }elseif($dimension=='dynamic') {
+ xmlwriter_start_element($writer,'data');
+ OC_OCS::toxml($writer,$data,'comment');
+ xmlwriter_end_element($writer);
+ }
+
+ xmlwriter_end_element($writer);
+
+ xmlwriter_end_document( $writer );
+ $txt.=xmlwriter_output_memory( $writer );
+ unset($writer);
+ return($txt);
+ }
+ }
+
+ public static function toXml($writer,$data,$node) {
+ foreach($data as $key => $value) {
+ if (is_numeric($key)) {
+ $key = $node;
+ }
+ if (is_array($value)){
+ xmlwriter_start_element($writer,$key);
+ OC_OCS::toxml($writer,$value,$node);
+ xmlwriter_end_element($writer);
+ }else{
+ xmlwriter_write_element($writer,$key,$value);
+ }
+
+ }
+ }
+
+
+
+
+ /**
+ * return the config data of this server
+ * @param string $format
+ * @return string xml/json
+ */
+ private static function apiConfig($format) {
+ $user=OC_OCS::checkpassword(false);
+ $url=substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).'';
+
+ $xml['version']='1.5';
+ $xml['website']='ownCloud';
+ $xml['host']=$_SERVER['HTTP_HOST'];
+ $xml['contact']='';
+ $xml['ssl']='false';
+ echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1));
+ }
+
+
+ /**
+ * check if the provided login/apikey/password is valid
+ * @param string $format
+ * @param string $login
+ * @param string $passwd
+ * @return string xml/json
+ */
+ private static function personCheck($format,$login,$passwd) {
+ if($login<>''){
+ if(OC_USER::login($login,$passwd)){
+ $xml['person']['personid']=$login;
+ echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2));
+ }else{
+ echo(OC_OCS::generatexml($format,'failed',102,'login not valid'));
+ }
+ }else{
+ echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields'));
+ }
+ }
+
+
+
+ // ACTIVITY API #############################################
+
+ /**
+ * get my activities
+ * @param string $format
+ * @param string $page
+ * @param string $pagesize
+ * @return string xml/json
+ */
+ private static function activityGet($format,$page,$pagesize) {
+ global $CONFIG_DBTABLEPREFIX;
+
+ $user=OC_OCS::checkpassword();
+
+ $result = OC_DB::query("select count(*) as co from {$CONFIG_DBTABLEPREFIX}log");
+ $entry=$result->fetchRow();
+ $totalcount=$entry['co'];
+ OC_DB::free_result($result);
+
+ $result = OC_DB::select("select id,timestamp,user,type,message from {$CONFIG_DBTABLEPREFIX}log order by timestamp desc limit " . ($page*$pagesize) . ",$pagesize");
+ $itemscount=count($result);
+
+ $url='http://'.substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).'';
+ $xml=array();
+ foreach($result as $i=>$log) {
+ $xml[$i]['id']=$log['id'];
+ $xml[$i]['personid']=$log['user'];
+ $xml[$i]['firstname']=$log['user'];
+ $xml[$i]['lastname']='';
+ $xml[$i]['profilepage']=$url;
+
+ $pic=$url.'/img/owncloud-icon.png';
+ $xml[$i]['avatarpic']=$pic;
+
+ $xml[$i]['timestamp']=date('c',$log['timestamp']);
+ $xml[$i]['type']=1;
+ $xml[$i]['message']=OC_LOG::$TYPE[$log['type']].' '.strip_tags($log['message']);
+ $xml[$i]['link']=$url;
+ }
+
+ $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
+ echo($txt);
+ }
+
+ /**
+ * submit a activity
+ * @param string $format
+ * @param string $message
+ * @return string xml/json
+ */
+ private static function activityPut($format,$message) {
+ // not implemented in ownCloud
+ $user=OC_OCS::checkpassword();
+ echo(OC_OCS::generatexml($format,'ok',100,''));
+ }
+
+ // PRIVATEDATA API #############################################
+
+ /**
+ * get private data and create the xml for ocs
+ * @param string $format
+ * @param string $app
+ * @param string $key
+ * @return string xml/json
+ */
+ private static function privateDataGet($format,$app="",$key="") {
+ $user=OC_OCS::checkpassword();
+ $result=OC_OCS::getData($user,$app,$key);
+ $xml=array();
+ foreach($result as $i=>$log) {
+ $xml[$i]['key']=$log['key'];
+ $xml[$i]['app']=$log['app'];
+ $xml[$i]['value']=$log['value'];
+ $xml[$i]['timestamp']=$log['timestamp'];
+ }
+
+
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
+ echo($txt);
+ }
+
+ /**
+ * set private data referenced by $key to $value and generate the xml for ocs
+ * @param string $format
+ * @param string $app
+ * @param string $key
+ * @param string $value
+ * @return string xml/json
+ */
+ private static function privateDataSet($format, $app, $key, $value) {
+ $user=OC_OCS::checkpassword();
+ if(OC_OCS::setData($user,$app,$key,$value)){
+ echo(OC_OCS::generatexml($format,'ok',100,''));
+ }
+ }
+
+ /**
+ * delete private data referenced by $key and generate the xml for ocs
+ * @param string $format
+ * @param string $app
+ * @param string $key
+ * @return string xml/json
+ */
+ private static function privateDataDelete($format, $app, $key) {
+ if($key=="" or $app==""){
+ return; //key and app are NOT optional here
+ }
+ $user=OC_OCS::checkpassword();
+ if(OC_OCS::deleteData($user,$app,$key)){
+ echo(OC_OCS::generatexml($format,'ok',100,''));
+ }
+ }
+
+ /**
+ * get private data
+ * @param string $user
+ * @param string $app
+ * @param string $key
+ * @return array
+ */
+ public static function getData($user,$app="",$key="") {
+ global $CONFIG_DBTABLEPREFIX;
+ $user=OC_DB::escape($user);
+ $key=OC_DB::escape($key);
+ $app=OC_DB::escape($app);
+ $key="$user::$key";//ugly hack for the sake of keeping database scheme compatibiliy
+ if($app){
+ if (!trim($key)) {
+ $result = OC_DB::select("select app, `key`,value,`timestamp` from {$CONFIG_DBTABLEPREFIX}privatedata where app='$app' order by `timestamp` desc");
+ } else {
+ $result = OC_DB::select("select app, `key`,value,`timestamp` from {$CONFIG_DBTABLEPREFIX}privatedata where app='$app' and `key` ='$key' order by `timestamp` desc");
+ }
+ }else{
+ if (!trim($key)) {
+ $result = OC_DB::select("select app, `key`,value,`timestamp` from {$CONFIG_DBTABLEPREFIX}privatedata order by `timestamp` desc");
+ } else {
+ $result = OC_DB::select("select app, `key`,value,`timestamp` from {$CONFIG_DBTABLEPREFIX}privatedata where `key` ='$key' order by `timestamp` desc");
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * set private data referenced by $key to $value
+ * @param string $user
+ * @param string $app
+ * @param string $key
+ * @param string $value
+ * @return bool
+ */
+ public static function setData($user, $app, $key, $value) {
+ global $CONFIG_DBTABLEPREFIX;
+ $app=OC_DB::escape($app);
+ $key=OC_DB::escape($key);
+ $user=OC_DB::escape($user);
+ $value=OC_DB::escape($value);
+ $key="$user::$key";//ugly hack for the sake of keeping database scheme compatibiliy
+ //TODO: prepared statements, locking tables, fancy stuff, error checking/handling
+ $result=OC_DB::select("select count(*) as co from {$CONFIG_DBTABLEPREFIX}privatedata where `key` = '$key' and app = '$app'");
+ $totalcount=$result[0]['co'];
+ if ($totalcount != 0) {
+ $result = OC_DB::query("update {$CONFIG_DBTABLEPREFIX}privatedata set value='$value', `timestamp` = now() where `key` = '$key' and app = '$app'");
+ } else {
+ $result = OC_DB::query("insert into {$CONFIG_DBTABLEPREFIX}privatedata(app, `key`, value, `timestamp`) values('$app', '$key', '$value', now())");
+ }
+ if (PEAR::isError($result)){
+ $entry='DB Error: "'.$result->getMessage().'"<br />';
+ error_log($entry);
+ return false;
+ }else{
+ return true;
+ }
+ }
+
+ /**
+ * delete private data referenced by $key
+ * @param string $user
+ * @param string $app
+ * @param string $key
+ * @return string xml/json
+ */
+ public static function deleteData($user, $app, $key) {
+ global $CONFIG_DBTABLEPREFIX;
+ $app=OC_DB::escape($app);
+ $key=OC_DB::escape($key);
+ $user=OC_DB::escape($user);
+ $key="$user::$key";//ugly hack for the sake of keeping database scheme compatibiliy
+ //TODO: prepared statements, locking tables, fancy stuff, error checking/handling
+ $result = OC_DB::query("delete from {$CONFIG_DBTABLEPREFIX}privatedata where `key` = '$key' and app = '$app'");
+ if (PEAR::isError($result)){
+ $entry='DB Error: "'.$result->getMessage().'"<br />';
+ error_log($entry);
+ return false;
+ }else{
+ return true;
+ }
+ }
+}
+
+?>
diff --git a/lib/plugin.php b/lib/plugin.php
new file mode 100644
index 00000000000..0cec329ea35
--- /dev/null
+++ b/lib/plugin.php
@@ -0,0 +1,381 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+class OC_PLUGIN{
+ static private $blacklist=array();
+
+ /**
+ * load the plugin with the given id
+ * @param string id
+ * @return bool
+ */
+ static public function load($id){
+ global $SERVERROOT;
+ $data=self::getPluginData($id);
+ if($data){
+ if(isset($data['info']['require'])){
+ $minVersion=explode('.',$data['info']['require']);
+ $version=OC_UTIL::getVersion();
+ $roundTo=count($minVersion);
+ while(count($version)>$roundTo){
+ if($version[count($version)-1]>=50){
+ $version[count($version)-2]++;
+ }
+ unset($version[count($version)-1]);
+ }
+ for($i=0;$i<count($minVersion);$i++){
+ if($version[$i]<$minVersion[$i]){
+ return false;
+ }
+ }
+ }
+ //check for uninstalled db's
+ if(isset($data['install']) and isset($data['install']['database'])){
+ foreach($data['install']['database'] as $db){
+ if(!$data['install']['database_installed'][$db]){
+ self::installDB($id);
+ break;
+ }
+ }
+ }
+
+ if(isset($data['runtime'])){
+ foreach($data['runtime'] as $include){
+ include($SERVERROOT.'/plugins/'.$id.'/'.$include);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get a list of all installed plugins
+ */
+ public static function listPlugins() {
+ global $SERVERROOT;
+ $plugins = array();
+ $fd = opendir($SERVERROOT . '/plugins');
+ while ( false !== ($filename = readdir($fd)) ) {
+ if ( $filename<>'.' AND $filename<>'..' AND ('.' != substr($filename, 0, 1))) {
+ if(file_exists($SERVERROOT . '/plugins/'.$filename.'/plugin.xml')){
+ $plugins[]=$filename;
+ }
+ }
+ }
+ closedir($fd);
+ return $plugins;
+ }
+
+ /**
+ * Load all plugins that aren't blacklisted
+ */
+ public static function loadPlugins() {
+ global $CONFIG_INSTALLED;
+ if($CONFIG_INSTALLED){
+ global $SERVERROOT;
+ $plugins = self::listPlugins();
+ $blacklist=self::loadBlacklist();
+ foreach($plugins as $plugin){
+ if (array_search($plugin,$blacklist)===false) {
+ self::load($plugin);
+ }
+ }
+ }
+ }
+
+ /**
+ * load the blacklist from blacklist.txt
+ * @return array
+ */
+ public static function loadBlacklist(){
+ global $SERVERROOT;
+ if(count(self::$blacklist)>0){
+ return self::$blacklist;
+ }
+ $blacklist=array();
+ if(is_file($SERVERROOT.'/plugins/blacklist.txt')){
+ $file=file_get_contents($SERVERROOT.'/plugins/blacklist.txt');
+ $lines=explode("\n",$file);
+ foreach($lines as $line){
+ $id=trim($line);
+ if($id!='' and is_dir($SERVERROOT.'/plugins/'.$id)){
+ $blacklist[]=$id;
+ }
+ }
+ }
+ self::$blacklist=$blacklist;
+ return $blacklist;
+ }
+
+ /**
+ * save a blacklist to blacklist.txt
+ * @param array blacklist
+ */
+ private static function saveBlacklist($blacklist){
+ global $SERVERROOT;
+ $file='';
+ foreach($blacklist as $item){
+ $file.="$item\n";
+ }
+ self::$blacklist=$blacklist;
+ file_put_contents($SERVERROOT.'/plugins/blacklist.txt',$file);
+ }
+
+ /**
+ * add a plugin to the blacklist
+ * @param string id
+ */
+ public static function addToBlacklist($id){
+ $blacklist=self::loadBlacklist();
+ if(array_search($id,$blacklist)===false){
+ $blacklist[]=$id;
+ self::$blacklist=$blacklist;
+ self::saveBlacklist($blacklist);
+ }
+ }
+
+ /**
+ * remove a plugin to the blacklist
+ * @param string id
+ */
+ public static function removeFromBlacklist($id){
+ $blacklist=self::loadBlacklist();
+ $index=array_search($id,$blacklist);
+ if($index!==false){
+ unset($blacklist[$index]);
+ self::$blacklist=$blacklist;
+ self::saveBlacklist($blacklist);
+ }
+ }
+
+ /**
+ * Load data from the plugin.xml of a plugin, either identified by the plugin or the path of the plugin.xml file
+ * @param string id
+ * @return array
+ */
+ public static function getPluginData($id){
+ global $SERVERROOT;
+ if(is_file($id)){
+ $file=$id;
+ }else{
+ if(!is_dir($SERVERROOT.'/plugins/'.$id) or !is_file($SERVERROOT.'/plugins/'.$id.'/plugin.xml')){
+ return false;
+ }else{
+ $file=$SERVERROOT.'/plugins/'.$id.'/plugin.xml';
+ }
+ }
+ $data=array();
+ $plugin=new DOMDocument();
+ $plugin->load($file);
+ $data['version']=$plugin->documentElement->getAttribute('version');
+ $info=$plugin->getElementsByTagName('info');
+ if($info->length>0){
+ $info=$info->item(0);
+ $data['info']=array();
+ foreach($info->childNodes as $child){
+ if($child->nodeType==XML_ELEMENT_NODE){
+ $data['info'][$child->tagName]=$child->textContent;
+ }
+ }
+ }
+ $runtime=$plugin->getElementsByTagName('runtime');
+ if($runtime->length>0){
+ $runtime=$runtime->item(0);
+ $data['runtime']=array();
+ foreach($runtime->childNodes as $child){
+ if($child->nodeType==XML_ELEMENT_NODE and $child->tagName=='include'){
+ $data['runtime'][]=$child->textContent;
+ }
+ }
+ }
+ $install=$plugin->getElementsByTagName('install');
+ if($install->length>0){
+ $install=$install->item(0);
+ $data['install']=array();
+ foreach($install->childNodes as $child){
+ if($child->nodeType==XML_ELEMENT_NODE){
+ $data['install']['include']=array();
+ $data['install']['dialog']=array();
+ $data['install']['database']=array();
+ switch($child->tagName){
+ case 'include':
+ $data['install']['include'][]=$child->textContent;
+ break;
+ case 'dialog':
+ $data['install']['dialog'][]=$child->textContent;
+ break;
+ case 'database':
+ $data['install']['database'][]=$child->textContent;
+ $data['install']['database_installed'][$child->textContent]=($child->hasAttribute('installed') and $child->getAttribute('installed')=='true')?true:false;
+ break;
+ }
+ }
+ }
+ }
+ $uninstall=$plugin->getElementsByTagName('uninstall');
+ if($uninstall->length>0){
+ $uninstall=$uninstall->item(0);
+ $data['uninstall']=array();
+ foreach($uninstall->childNodes as $child){
+ if($child->nodeType==XML_ELEMENT_NODE){
+ $data['uninstall']['include']=array();
+ $data['uninstall']['dialog']=array();
+ switch($child->tagName){
+ case 'include':
+ $data['uninstall']['include'][]=$child->textContent;
+ break;
+ case 'dialog':
+ $data['uninstall']['dialog'][]=$child->textContent;
+ break;
+ }
+ }
+ }
+ }
+ return $data;
+ }
+
+
+ /**
+ * Save data to the plugin.xml of a plugin, either identified by the plugin or the path of the plugin.xml file
+ * @param string id
+ * @param array data the plugin data in the same structure as returned by getPluginData
+ * @return bool
+ */
+ public static function savePluginData($id,$data){
+ global $SERVERROOT;
+ if(is_file($id)){
+ $file=$id;
+ }
+ if(!is_dir($SERVERROOT.'/plugins/'.$id) or !is_file($SERVERROOT.'/plugins/'.$id.'/plugin.xml')){
+ return false;
+ }else{
+ $file=$SERVERROOT.'/plugins/'.$id.'/plugin.xml';
+ }
+ $plugin=new DOMDocument();
+ $pluginNode=$plugin->createElement('plugin');
+ $pluginNode->setAttribute('version',$data['version']);
+ $plugin->appendChild($pluginNode);
+ $info=$plugin->createElement('info');
+ foreach($data['info'] as $name=>$value){
+ $node=$plugin->createElement($name);
+ $node->appendChild($plugin->createTextNode($value));
+ $info->appendChild($node);
+ }
+ $pluginNode->appendChild($info);
+ if(isset($data['runtime'])){
+ $runtime=$plugin->createElement('runtime');
+ foreach($data['runtime'] as $include){
+ $node=$plugin->createElement('include');
+ $node->appendChild($plugin->createTextNode($include));
+ $runtime->appendChild($node);
+ }
+ $pluginNode->appendChild($runtime);
+ }
+ if(isset($data['install'])){
+ $install=$plugin->createElement('install');
+ foreach($data['install']['include'] as $include){
+ $node=$plugin->createElement('include');
+ $node->appendChild($plugin->createTextNode($include));
+ $install->appendChild($node);
+ }
+ foreach($data['install']['dialog'] as $dialog){
+ $node=$plugin->createElement('dialog');
+ $node->appendChild($plugin->createTextNode($dialog));
+ $install->appendChild($node);
+ }
+ foreach($data['install']['database'] as $database){
+ $node=$plugin->createElement('database');
+ $node->appendChild($plugin->createTextNode($database));
+ if($data['install']['database_installed'][$database]){
+ $node->setAttribute('installed','true');
+ }
+ $install->appendChild($node);
+ }
+ $pluginNode->appendChild($install);
+ }
+ if(isset($data['uninstall'])){
+ $uninstall=$plugin->createElement('uninstall');
+ foreach($data['uninstall']['include'] as $include){
+ $node=$plugin->createElement('include');
+ $node->appendChild($plugin->createTextNode($include));
+ $uninstall->appendChild($node);
+ }
+ foreach($data['uninstall']['dialog'] as $dialog){
+ $node=$plugin->createElement('dialog');
+ $node->appendChild($plugin->createTextNode($dialog));
+ $uninstall->appendChild($node);
+ }
+ $pluginNode->appendChild($uninstall);
+ }
+ $plugin->save($file);
+ }
+
+ /**
+ * install the databases of a plugin
+ * @param string id
+ * @return bool
+ */
+ public static function installDB($id){
+ global $SERVERROOT;
+ $data=OC_PLUGIN::getPluginData($id);
+ foreach($data['install']['database'] as $db){
+ if (!$data['install']['database_installed'][$db]){
+ $file=$SERVERROOT.'/plugins/'.$id.'/'.$db;
+ OC_DB::createDbFromStructure($file);
+ $data['install']['database_installed'][$db]=true;
+ }
+ }
+ self::savePluginData($id,$data);
+ return true;
+ }
+
+ public static function installPlugin($path){
+ global $SERVERROOT;
+ if(is_file($path)){
+ $zip = new ZipArchive;
+ if($zip->open($path)===TRUE){
+ $folder=sys_get_temp_dir().'/OC_PLUGIN_INSTALL/';
+ mkdir($folder);
+ $zip->extractTo($folder);
+ if(is_file($folder.'/plugin.xml')){
+ $pluginData=self::getPluginData($folder.'/plugin.xml');
+ if(array_search($pluginData['info']['id'],self::listPlugins())===false){
+ if(isset($pluginData['install'])){
+ foreach($pluginData['install']['database'] as $db){
+ OC_DB::createDbFromStructure($folder.'/'.$db);
+ $pluginData['install']['database_installed'][$db]=true;
+ }
+ foreach($pluginData['install']['include'] as $include){
+ include($folder.'/'.$include);
+ }
+ }
+ recursive_copy($folder,$SERVERROOT.'/plugins/'.$pluginData['info']['id']);
+ self::savePluginData($SERVERROOT.'/plugins/'.$pluginData['info']['id'].'/plugin.xml',$pluginData);
+ }
+ }
+ delTree($folder);
+ }
+ }
+ }
+}
+?>
diff --git a/lib/remotestorage.php b/lib/remotestorage.php
new file mode 100644
index 00000000000..ed90cf1fdaf
--- /dev/null
+++ b/lib/remotestorage.php
@@ -0,0 +1,353 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+class OC_FILESTORAGE_REMOTE extends OC_FILESTORAGE{
+ private $url;
+ private $username;
+ private $password;
+ private $remote=false;
+ private $statCache;
+ private $statCacheDir=false;
+ private $changed=array();
+
+ private function cacheDir($dir){
+ if($this->statCacheDir!=$dir or $this->statCacheDir===false){
+ $this->statCache=$this->remote->getFiles($dir);
+ $keys=array_keys($this->statCache);
+ $this->statCacheDir=$dir;
+ }
+ }
+
+ public function __construct($arguments){
+ $this->url=$arguments['url'];
+ $this->username=$arguments['username'];
+ $this->password=$arguments['password'];
+ }
+ private function connect(){
+ if($this->remote===false){
+ $this->remote=OC_CONNECT::connect($this->url,$this->username,$this->password);
+ }
+ }
+ public function mkdir($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $return=$this->remote->newFile($parent,$name,'dir');
+ if($return){
+ $this->notifyObservers($path,OC_FILEACTION_CREATE);
+ }
+ return $return;
+ }
+ public function rmdir($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $return=$this->remote->delete($parent,$name);
+ if($return){
+ $this->notifyObservers($path,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+ public function opendir($path){
+ $this->connect();
+ $this->cacheDir($path);
+ $dirs=array_keys($this->statCache);
+ $id=uniqid();
+ global $FAKEDIRS;
+ $FAKEDIRS[$id]=$dirs;
+ if($return=opendir("fakedir://$id")){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ }
+ return $return;
+ }
+ public function is_dir($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($path);
+ if($path=='' or $path=='/'){
+ return true;
+ }
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return ($this->statCache[$name]['type'=='dir']);
+ }
+ public function is_file($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return ($this->statCache[$name]['type'!='dir']);
+ }
+ public function stat($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return $false;
+ }
+ return $this->statCache[$name];
+ }
+ public function filetype($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['type'];
+ }
+ public function filesize($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return $false;
+ }
+ return $this->statCache[$name]['size'];
+ }
+ public function is_readable($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['readable'];
+ }
+ public function is_writeable($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['writeable'];
+ }
+ public function file_exists($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ return isset($this->statCache[$name]);
+ }
+ public function readfile($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $file=$this->remote->getFile($parent,$name);
+ readfile($file);
+ unlink($file);
+ }
+ public function filectime($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['ctime'];
+ }
+ public function filemtime($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['mtime'];
+ }
+ public function fileatime($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['atime'];
+ }
+ public function file_get_contents($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $file=$this->remote->getFile($parent,$name);
+ file_get_contents($file);
+ unlink($file);
+ }
+ public function file_put_contents($path,$data){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $file=$this->remote->getFile($parent,$name);
+ $file=tempnam(sys_get_temp_dir(),'oc_');
+ file_put_contents($file,$data);
+ if($return=$this->remote->sendTmpFile($file,$parent,$name)){
+ $this->notifyObservers($path,OC_FILEACTION_WRITE);
+ }
+ }
+ public function unlink($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ if($return=$this->remote->delete($paren,$name)){
+ $this->notifyObservers($path,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+ public function rename($path1,$path2){
+ $this->connect();
+ $parent1=dirname($path1);
+ $name1=substr($path1,strlen($parent1)+1);
+ $parent2=dirname($path2);
+ $name2=substr($path2,strlen($parent2)+1);
+ if($return=$this->remote->move($parent1,$name1,$parent2,$name2)){
+ $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
+ }
+ return $return;
+ }
+ public function copy($path1,$path2){
+ $this->connect();
+ $parent1=dirname($path1);
+ $name1=substr($path1,strlen($parent1)+1);
+ $parent2=dirname($path2);
+ $name2=substr($path2,strlen($parent2)+1);
+ if($return=$this->copy->rename($parent1,$name1,$parent2,$name2)){
+ $this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
+ }
+ return $return;
+ }
+ public function fopen($path,$mode){
+ $this->connect();
+ $changed=false;
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ $file=$this->remote->getFile($parent,$name);
+ if($return=fopen($file,$mode)){
+ switch($mode){
+ case 'r':
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ break;
+ case 'r+':
+ case 'w+':
+ case 'x+':
+ case 'a+':
+ $this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE);
+ $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
+ break;
+ case 'w':
+ case 'x':
+ case 'a':
+ $this->notifyObservers($path,OC_FILEACTION_WRITE);
+ $this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
+ break;
+ }
+ }
+ return $return;
+ }
+
+ public function getMimeType($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ if(substr($name,0,1)=='/'){
+ $name=substr($name,1);
+ }
+ $this->cacheDir($parent);
+ if(!isset($this->statCache[$name])){
+ return false;
+ }
+ return $this->statCache[$name]['mime'];
+ }
+
+ public function toTmpFile($path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ if(substr($name,0,1)=='/'){
+ $name=substr($name,1);
+ }
+ $filename=$this->remote->getFile($parent,$name);
+ if($filename){
+ $this->notifyObservers($path,OC_FILEACTION_READ);
+ return $filename;
+ }else{
+ return false;
+ }
+ }
+
+ public function fromTmpFile($tmpFile,$path){
+ $this->connect();
+ $parent=dirname($path);
+ $name=substr($path,strlen($parent)+1);
+ if($this->remote->sendTmpFile($tmpFile,$parent,$name)){
+ $this->notifyObservers($path,OC_FILEACTION_CREATE);
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ public function delTree($dir) {
+ $this->connect();
+ $parent=dirname($dir);
+ $name=substr($dir,strlen($parent)+1);
+ $return=$this->remote->delete($parent,$name);
+ if($return=rmdir($dir)){
+ $this->notifyObservers($dir,OC_FILEACTION_DELETE);
+ }
+ return $return;
+ }
+
+ public function find($path){
+ return $this->getTree($path);
+ }
+
+ public function getTree($dir) {
+ $this->connect();
+ if($return=$this->remote->getTree($dir)){
+ $this->notifyObservers($dir,OC_FILEACTION_READ);
+ }
+ return $return;
+ }
+
+ public function __destruct(){
+ foreach($this->changed as $changed){
+ $this->remote->sendTmpFile($changed['tmp'],$changed['dir'],$changed['file']);
+ }
+ }
+}
+
+?>
diff --git a/lib/template.php b/lib/template.php
new file mode 100644
index 00000000000..0541d55b124
--- /dev/null
+++ b/lib/template.php
@@ -0,0 +1,197 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+oc_require_once( "Smarty/Smarty.class.php" );
+
+/**
+ *
+ */
+function oc_template_helper_link_to( $params, $smarty ){
+ $app = "";
+ if( isset( $params["app"] ))
+ {
+ $app = $params["app"];
+ }
+ $file = $params["file"];
+ return OC_UTIL::linkTo( $app, $file );
+}
+
+/**
+ *
+ */
+function oc_template_helper_image_path( $params, $smarty ){
+ $app = "";
+ if( isset( $params["app"] ))
+ {
+ $app = $params["app"];
+ }
+ $file = $params["file"];
+ return OC_UTIL::imagePath( $app, $file );
+}
+
+class OC_TEMPLATE{
+ private $renderas; // Create a full page?
+ private $name; // name of the template
+ private $application; // template Application
+ private $smarty; // The smarty object
+
+ public function __construct( $application, $name, $renderas = "" ){
+ // Global vars we need
+ global $SERVERROOT;
+
+ $template_dir = "$SERVERROOT/templates/";
+ // Get the right template folder
+ if( $application != "core" ){
+ $template_dir = "$SERVERROOT/$application/templates/";
+ }
+
+ // Set the OC-defaults for Smarty
+ $smarty = new Smarty();
+ $smarty->left_delimiter = "[%";
+ $smarty->right_delimiter = "%]";
+ $smarty->template_dir = $template_dir;
+ $smarty->compile_dir = "$template_dir/_c";
+ $smarty->registerPlugin( "function", "linkto", "oc_template_helper_link_to");
+ $smarty->registerPlugin( "function", "imagepath", "oc_template_helper_image_path");
+
+ // Templates have the ending .tmpl
+ $name = "$name.tmpl";
+ // Set the private data
+ $this->renderas = $renderas;
+ $this->application = $application;
+ $this->name = $name;
+ $this->smarty = $smarty;
+ }
+
+ public function assign( $a, $b = null ){
+ $this->smarty->assign( $a, $b );
+ }
+
+ public function append( $a, $b = null ){
+ $this->smarty->append( $a, $b );
+ }
+
+ public function printPage()
+ {
+ $data = $this->fetchPage();
+ if( $data === false )
+ {
+ return false;
+ }
+ else
+ {
+ print $data;
+ return true;
+ }
+ }
+
+ public function fetchPage()
+ {
+ // global Data we need
+ global $WEBROOT;
+ $data = $this->smarty->fetch( $this->name );
+
+ if( $this->renderas )
+ {
+ // Decide which page we show
+ if( $this->renderas == "user" )
+ {
+ $page = new OC_TEMPLATE( "core", "layout.user" );
+ // Add menu data
+ }
+ elseif( $this->renderas == "admin" )
+ {
+ $page = new OC_TEMPLATE( "core", "layout.admin" );
+ // Add menu data
+ }
+ else
+ {
+ $page = new OC_TEMPLATE( "core", "layout.guest" );
+ // Add data if required
+ }
+
+ // Add the css and js files
+ foreach(OC_UTIL::$scripts as $script){
+ $page->append( "jsfiles", "$WEBROOT/$script.js" );
+ }
+ foreach(OC_UTIL::$styles as $style){
+ $page->append( "cssfiles", "$WEBROOT/$style.css" );
+ }
+
+ // Add navigation entry and personal menu
+ $page->assign( "navigation", OC_UTIL::$navigation );
+ $page->assign( "personalmenu", OC_UTIL::$personalmenu );
+
+ // Add css files and js files
+ $page->assign( "content", $data );
+ return $page->fetchPage();
+ }
+ else
+ {
+ return $data;
+ }
+ }
+ public function __destruct(){
+ }
+
+ /**
+ * @brief Shortcut to print a simple page for users
+ * @param $application The application we render the template for
+ * @param $name Name of the template
+ * @param $parameters Parameters for the template
+ * @returns true/false
+ */
+ public static function printUserPage( $application, $name, $parameters = array() ){
+ $content = new OC_TEMPLATE( $application, $name, "user" );
+ $content->assign( $parameters );
+ return $content->printPage();
+ }
+
+ /**
+ * @brief Shortcut to print a simple page for admins
+ * @param $application The application we render the template for
+ * @param $name Name of the template
+ * @param $parameters Parameters for the template
+ * @returns true/false
+ */
+ public static function printAdminPage( $application, $name, $parameters = array() ){
+ $content = new OC_TEMPLATE( $application, $name, "admin" );
+ $content->assign( $parameters );
+ return $content->printPage();
+ }
+
+ /**
+ * @brief Shortcut to print a simple page for guests
+ * @param $application The application we render the template for
+ * @param $name Name of the template
+ * @param $parameters Parameters for the template
+ * @returns true/false
+ */
+ public static function printGuestPage( $application, $name, $parameters = array() ){
+ $content = new OC_TEMPLATE( $application, $name, "guest" );
+ $content->assign( $parameters );
+ return $content->printPage();
+ }
+}
+
+?>
diff --git a/lib/user.php b/lib/user.php
new file mode 100644
index 00000000000..431d0bfc359
--- /dev/null
+++ b/lib/user.php
@@ -0,0 +1,249 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2010 Frank Karlitschek karlitschek@kde.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+
+
+
+if ( !$CONFIG_INSTALLED ) {
+ $_SESSION['user_id'] = false;
+ $_SESSION['username'] = '';
+ $_SESSION['username_clean'] = '';
+}
+
+//cache the userid's an groupid's
+if ( !isset($_SESSION['user_id_cache']) ) {
+ $_SESSION['user_id_cache'] = array();
+}
+if ( !isset($_SESSION['group_id_cache']) ) {
+ $_SESSION['group_id_cache'] = array();
+}
+
+
+
+
+/**
+ * Class for User Management
+ *
+ */
+class OC_USER {
+
+ // The backend used for user management
+ private static $_backend;
+
+ /**
+ * Set the User Authentication Module
+ *
+ * @param string $backend The backend to use for user managment
+ */
+ public static function setBackend($backend='database') {
+ if ( (null === $backend) OR (!is_string($backend)) ) {
+ $backend = 'database';
+ }
+
+ switch ( $backend ) {
+ case 'database':
+ case 'mysql':
+ case 'sqlite':
+ oc_require_once('User/database.php');
+ self::$_backend = new OC_USER_DATABASE();
+ break;
+ default:
+ $className = 'OC_USER_' . strToUpper($backend);
+ self::$_backend = new $className();
+ break;
+ }
+ }
+
+ /**
+ * Check if the login button is pressed and log the user in
+ *
+ */
+ public static function loginListener() {
+ return self::$_backend->loginListener();
+ }
+
+ /**
+ * Try to create a new user
+ *
+ * @param string $username The username of the user to create
+ * @param string $password The password of the new user
+ */
+ public static function createUser($username, $password) {
+ return self::$_backend->createUser($username, $password);
+ }
+
+ /**
+ * Try to login a user
+ *
+ * @param string $username The username of the user to log in
+ * @param string $password The password of the user
+ */
+ public static function login($username, $password) {
+ return self::$_backend->login($username, $password);
+ }
+
+ /**
+ * Check if the logout button is pressed and logout the user
+ *
+ */
+ public static function logoutListener() {
+ return self::$_backend->logoutListener();
+ }
+
+ /**
+ * Kick the user
+ *
+ */
+ public static function logout() {
+ return self::$_backend->logout();
+ }
+
+ /**
+ * Check if the user is logged in
+ *
+ */
+ public static function isLoggedIn() {
+ return self::$_backend->isLoggedIn();
+ }
+
+ /**
+ * Try to create a new group
+ *
+ * @param string $groupName The name of the group to create
+ */
+ public static function createGroup($groupName) {
+ return self::$_backend->createGroup($groupName);
+ }
+
+ /**
+ * Get the ID of a user
+ *
+ * @param string $username Name of the user to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ public static function getUserId($username, $noCache=false) {
+ return self::$_backend->getUserId($username, $noCache);
+ }
+
+ /**
+ * Get the ID of a group
+ *
+ * @param string $groupName Name of the group to find the ID
+ * @param boolean $noCache If false the cache is used to find the ID
+ */
+ public static function getGroupId($groupName, $noCache=false) {
+ return self::$_backend->getGroupId($groupName, $noCache);
+ }
+
+ /**
+ * Get the name of a group
+ *
+ * @param string $groupId ID of the group
+ * @param boolean $noCache If false the cache is used to find the name of the group
+ */
+ public static function getGroupName($groupId, $noCache=false) {
+ return self::$_backend->getGroupName($groupId, $noCache);
+ }
+
+ /**
+ * Check if a user belongs to a group
+ *
+ * @param string $username Name of the user to check
+ * @param string $groupName Name of the group
+ */
+ public static function inGroup($username, $groupName) {
+ return self::$_backend->inGroup($username, $groupName);
+ }
+
+ /**
+ * Add a user to a group
+ *
+ * @param string $username Name of the user to add to group
+ * @param string $groupName Name of the group in which add the user
+ */
+ public static function addToGroup($username, $groupName) {
+ return self::$_backend->addToGroup($username, $groupName);
+ }
+
+ /**
+ * Remove a user from a group
+ *
+ * @param string $username Name of the user to remove from group
+ * @param string $groupName Name of the group from which remove the user
+ */
+ public static function removeFromGroup($username,$groupName){
+ return self::$_backend->removeFromGroup($username, $groupName);
+ }
+
+ /**
+ * Generate a random password
+ */
+ public static function generatePassword() {
+ return substr(md5(uniqId().time()),0,10);
+ }
+
+ /**
+ * Get all groups the user belongs to
+ *
+ * @param string $username Name of the user
+ */
+ public static function getUserGroups($username) {
+ return self::$_backend->getUserGroups($username);
+ }
+
+ /**
+ * Set the password of a user
+ *
+ * @param string $username User who password will be changed
+ * @param string $password The new password for the user
+ */
+ public static function setPassword($username, $password) {
+ return self::$_backend->setPassword($username, $password);
+ }
+
+ /**
+ * Check if the password of the user is correct
+ *
+ * @param string $username Name of the user
+ * @param string $password Password of the user
+ */
+ public static function checkPassword($username, $password) {
+ return self::$_backend->checkPassword($username, $password);
+ }
+
+ /**
+ * get a list of all users
+ *
+ */
+ public static function getUsers() {
+ return self::$_backend->getUsers();
+ }
+
+ /**
+ * get a list of all groups
+ *
+ */
+ public static function getGroups() {
+ return self::$_backend->getGroups();
+ }
+}