diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 109f86b2e8752b78c9fd53270d383b61d45f4ecf..0104d0d017f98bcc92590ae131400b1ccecba7ec 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -6,4 +6,4 @@ OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/lib/sharedstorage.
 OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup');
 OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
 OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
-OCP\Util::addScript('files_sharing', 'share');
+OCP\Util::addScript('files_sharing', 'share');
\ No newline at end of file
diff --git a/lib/api.php b/lib/api.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb67e0c2a892f33305e7e74b1146dc4dd50b1f8d
--- /dev/null
+++ b/lib/api.php
@@ -0,0 +1,200 @@
+<?php
+/**
+* ownCloud
+*
+* @author Tom Needham
+* @author Michael Gapczynski
+* @author Bart Visscher
+* @copyright 2012 Tom Needham tom@owncloud.com
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+* @copyright 2012 Bart Visscher bartv@thisnet.nl
+*
+* 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_API {
+
+	/**
+	 * API authentication levels
+	 */
+	const GUEST_AUTH = 0;
+	const USER_AUTH = 1;
+	const SUBADMIN_AUTH = 2;
+	const ADMIN_AUTH = 3;
+
+	private static $server;
+
+	/**
+	 * initialises the OAuth store and server
+	 */
+	private static function init() {
+		self::$server = new OC_OAuth_Server(new OC_OAuth_Store());
+	}
+	
+	/**
+	 * api actions
+	 */
+	protected static $actions = array();
+	
+	/**
+	 * registers an api call
+	 * @param string $method the http method
+	 * @param string $url the url to match
+	 * @param callable $action the function to run
+	 * @param string $app the id of the app registering the call
+	 * @param int $authLevel the level of authentication required for the call
+	 * @param array $defaults
+	 * @param array $requirements
+	 */
+	public static function register($method, $url, $action, $app, 
+				$authLevel = OC_API::USER_AUTH,
+				$defaults = array(),
+				$requirements = array()) {
+		$name = strtolower($method).$url;
+		$name = str_replace(array('/', '{', '}'), '_', $name);
+		if(!isset(self::$actions[$name])) {
+			OC::getRouter()->useCollection('ocs');
+			OC::getRouter()->create($name, $url)
+				->method($method)
+				->action('OC_API', 'call');
+			self::$actions[$name] = array();
+		}
+		self::$actions[$name] = array('app' => $app, 'action' => $action, 'authlevel' => $authLevel);
+	}
+	
+	/**
+	 * handles an api call
+	 * @param array $parameters
+	 */
+	public static function call($parameters) {
+		// Prepare the request variables
+		if($_SERVER['REQUEST_METHOD'] == 'PUT') {
+			parse_str(file_get_contents("php://input"), $parameters['_put']);
+		} else if($_SERVER['REQUEST_METHOD'] == 'DELETE'){
+			parse_str(file_get_contents("php://input"), $parameters['_delete']);
+		}
+		$name = $parameters['_route'];
+		// Check authentication and availability
+		if(self::isAuthorised(self::$actions[$name])) {
+			if(is_callable(self::$actions[$name]['action'])) {
+				$response = call_user_func(self::$actions[$name]['action'], $parameters);
+			} else {
+				$response = new OC_OCS_Result(null, 998, 'Api method not found');
+			} 
+		} else {
+			$response = new OC_OCS_Result(null, 997, 'Unauthorised');
+		}
+		// Send the response
+		$formats = array('json', 'xml');
+		$format = !empty($_GET['format']) && in_array($_GET['format'], $formats) ? $_GET['format'] : 'xml';
+		self::respond($response, $format);
+		// logout the user to be stateless
+		OC_User::logout();
+	}
+	
+	/**
+	 * authenticate the api call
+	 * @param array $action the action details as supplied to OC_API::register()
+	 * @return bool
+	 */
+	private static function isAuthorised($action) {
+		$level = $action['authlevel'];
+		switch($level) {
+			case OC_API::GUEST_AUTH:
+				// Anyone can access
+				return true;
+				break;
+			case OC_API::USER_AUTH:
+				// User required
+				return self::loginUser();
+				break;
+			case OC_API::SUBADMIN_AUTH:
+				// Check for subadmin
+				$user = self::loginUser();
+				if(!$user) {
+					return false;
+				} else {
+					$subAdmin = OC_SubAdmin::isSubAdmin($user);
+					$admin = OC_Group::inGroup($user, 'admin');
+					if($subAdmin || $admin) {
+						return true;
+					} else {
+						return false;
+					}
+				}
+				break;
+			case OC_API::ADMIN_AUTH:
+				// Check for admin
+				$user = self::loginUser();
+				if(!$user) {
+					return false;
+				} else {
+					return OC_Group::inGroup($user, 'admin');
+				}
+				break;
+			default:
+				// oops looks like invalid level supplied
+				return false;
+				break;
+		}
+	} 
+	
+	/**
+	 * http basic auth
+	 * @return string|false (username, or false on failure)
+	 */
+	private static function loginUser(){ 
+		$authUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
+		$authPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
+		return OC_User::login($authUser, $authPw) ? $authUser : false;
+	}
+	
+	/**
+	 * respond to a call
+	 * @param int|array $result the result from the api method
+	 * @param string $format the format xml|json
+	 */
+	private static function respond($result, $format='xml') {
+		$response = array('ocs' => $result->getResult());
+		if ($format == 'json') {
+			OC_JSON::encodedPrint($response);
+		} else if ($format == 'xml') {
+			header('Content-type: text/xml; charset=UTF-8');
+			$writer = new XMLWriter();
+			$writer->openMemory();
+			$writer->setIndent( true );
+			$writer->startDocument();
+			self::toXML($response, $writer);
+			$writer->endDocument();
+			echo $writer->outputMemory(true);
+		}
+	}
+
+	private static function toXML($array, $writer) {
+		foreach($array as $k => $v) {
+			if (is_numeric($k)) {
+				$k = 'element';
+			}
+			if (is_array($v)) {
+				$writer->startElement($k);
+				self::toXML($v, $writer);
+				$writer->endElement();
+			} else {
+				$writer->writeElement($k, $v);
+			}
+		}
+	}
+	
+}
diff --git a/lib/app.php b/lib/app.php
old mode 100755
new mode 100644
index be6d5ab3dd34f0907831944de59bef22fa23cd15..30f76300365f54cca5dd785e5925ea6b6fe30f0b
--- a/lib/app.php
+++ b/lib/app.php
@@ -137,6 +137,20 @@ class OC_App{
 
 		OC_Appconfig::setValue($app, 'types', $appTypes);
 	}
+	
+	/**
+	 * check if app is shipped
+	 * @param string $appid the id of the app to check
+	 * @return bool
+	 */
+	public static function isShipped($appid){
+		$info = self::getAppInfo($appid);
+		if(isset($info['shipped']) && $info['shipped']=='true'){
+			return true;
+		} else {
+			return false;
+		}
+	}
 
 	/**
 	 * get all enabled apps
diff --git a/lib/ocs.php b/lib/ocs.php
index 1a0abf0e367173576eee93afaa0bb935752608e1..879aaa7668739be87f3d2e50df6f5358be914872 100644
--- a/lib/ocs.php
+++ b/lib/ocs.php
@@ -73,14 +73,7 @@ class OC_OCS {
 		}
 	}
 
-	/**
-	main function to handle the REST request
-	**/
-	public static function handle() {
-		// overwrite the 404 error page returncode
-		header("HTTP/1.0 200 OK");
-
-
+	public static function notFound() {
 		if($_SERVER['REQUEST_METHOD'] == 'GET') {
 			$method='get';
 		}elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
@@ -94,169 +87,10 @@ class OC_OCS {
 		}
 
 		$format = self::readData($method, '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));
 
-		$router = new OC_Router();
-		$router->useCollection('root');
-		// CONFIG
-		$router->create('config', '/config.{format}')
-			->defaults(array('format' => $format))
-			->action('OC_OCS', 'apiConfig')
-			->requirements(array('format'=>'xml|json'));
-
-		// PERSON
-		$router->create('person_check', '/person/check.{format}')
-			->post()
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$login = OC_OCS::readData('post', 'login', 'text');
-					$passwd = OC_OCS::readData('post', 'password', 'text');
-					OC_OCS::personCheck($format, $login, $passwd);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// ACTIVITY
-		// activityget - GET ACTIVITY   page,pagesize als urlparameter
-		$router->create('activity_get', '/activity.{format}')
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$page = OC_OCS::readData('get', 'page', 'int', 0);
-					$pagesize = OC_OCS::readData('get', 'pagesize', 'int', 10);
-					if($pagesize<1 or $pagesize>100) $pagesize=10;
-					OC_OCS::activityGet($format, $page, $pagesize);
-				})
-			->requirements(array('format'=>'xml|json'));
-		// activityput - POST ACTIVITY
-		$router->create('activity_put', '/activity.{format}')
-			->post()
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$message = OC_OCS::readData('post', 'message', 'text');
-					OC_OCS::activityPut($format, $message);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// PRIVATEDATA
-		// get - GET DATA
-		$router->create('privatedata_get',
-				  '/privatedata/getattribute/{app}/{key}.{format}')
-			->defaults(array('app' => '', 'key' => '', 'format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$app = addslashes(strip_tags($parameters['app']));
-					$key = addslashes(strip_tags($parameters['key']));
-					OC_OCS::privateDataGet($format, $app, $key);
-				})
-			->requirements(array('format'=>'xml|json'));
-		// set - POST DATA
-		$router->create('privatedata_set',
-				  '/privatedata/setattribute/{app}/{key}.{format}')
-			->post()
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$app = addslashes(strip_tags($parameters['app']));
-					$key = addslashes(strip_tags($parameters['key']));
-					$value=OC_OCS::readData('post', 'value', 'text');
-					OC_OCS::privateDataSet($format, $app, $key, $value);
-				})
-			->requirements(array('format'=>'xml|json'));
-		// delete - POST DATA
-		$router->create('privatedata_delete',
-				  '/privatedata/deleteattribute/{app}/{key}.{format}')
-			->post()
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$app = addslashes(strip_tags($parameters['app']));
-					$key = addslashes(strip_tags($parameters['key']));
-					OC_OCS::privateDataDelete($format, $app, $key);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// CLOUD
-		// systemWebApps
-		$router->create('system_webapps',
-				  '/cloud/system/webapps.{format}')
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					OC_OCS::systemwebapps($format);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// quotaget
-		$router->create('quota_get',
-				  '/cloud/user/{user}.{format}')
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$user = $parameters['user'];
-					OC_OCS::quotaGet($format, $user);
-				})
-			->requirements(array('format'=>'xml|json'));
-		// quotaset
-		$router->create('quota_set',
-				  '/cloud/user/{user}.{format}')
-			->post()
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$user = $parameters['user'];
-					$quota = self::readData('post', 'quota', 'int');
-					OC_OCS::quotaSet($format, $user, $quota);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// keygetpublic
-		$router->create('keygetpublic',
-				  '/cloud/user/{user}/publickey.{format}')
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$user = $parameters['user'];
-					OC_OCS::publicKeyGet($format, $user);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-		// keygetprivate
-		$router->create('keygetpublic',
-				  '/cloud/user/{user}/privatekey.{format}')
-			->defaults(array('format' => $format))
-			->action(function ($parameters) {
-					$format = $parameters['format'];
-					$user = $parameters['user'];
-					OC_OCS::privateKeyGet($format, $user);
-				})
-			->requirements(array('format'=>'xml|json'));
-
-
-// add more calls here
-// please document all the call in the draft spec
-// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD
-
-// TODO:
-// users
-// groups
-// bookmarks
-// sharing
-// versioning
-// news (rss)
-		try {
-			$router->match($_SERVER['PATH_INFO']);
-		} catch (ResourceNotFoundException $e) {
-			$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));
-		} catch (MethodNotAllowedException $e) {
-			OC_Response::setStatus(405);
-		}
-		exit();
 	}
 
 	/**
@@ -273,44 +107,6 @@ class OC_OCS {
 		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.
@@ -431,130 +227,6 @@ class OC_OCS {
 		}
 	}
 
-	/**
-	* return the config data of this server
-	* @param string $format
-	* @return string xml/json
-	*/
-	public static function apiConfig($parameters) {
-		$format = $parameters['format'];
-		$user=OC_OCS::checkpassword(false);
-		$url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'], 0, -11).'';
-
-		$xml['version']='1.7';
-		$xml['website']='ownCloud';
-		$xml['host']=OCP\Util::getServerHost();
-		$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) {
-		$user=OC_OCS::checkpassword();
-
-			//TODO
-
-		$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'];
-		}
-
-
-		$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
@@ -586,156 +258,4 @@ class OC_OCS {
 		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) {
-		return OC_Preferences::setValue($user, $app, $key, $value);
-	}
-
-	/**
-	* 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) {
-		return OC_Preferences::deleteKey($user, $app, $key);
-	}
-
-
-        // CLOUD API #############################################
-
-        /**
-        * get a list of installed web apps
-        * @param string $format
-        * @return string xml/json
-        */
-        private static function systemWebApps($format) {
-                $login=OC_OCS::checkpassword();
-		$apps=OC_App::getEnabledApps();
-		$values=array();
-		foreach($apps as $app) {
-			$info=OC_App::getAppInfo($app);
-			if(isset($info['standalone'])) {
-				$newvalue=array('name'=>$info['name'], 'url'=>OC_Helper::linkToAbsolute($app, ''), 'icon'=>'');
-				$values[]=$newvalue;
-			}
-
-		}
-		$txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0);
-		echo($txt);
-
-        }
-
-
-        /**
-        * get the quota of a user
-        * @param string $format
-        * @param string $user
-        * @return string xml/json
-        */
-        private static function quotaGet($format, $user) {
-                $login=OC_OCS::checkpassword();
-		if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
-
-			if(OC_User::userExists($user)) {
-				// calculate the disc space
-				$user_dir = '/'.$user.'/files';
-				OC_Filesystem::init($user_dir);
-				$rootInfo=OC_FileCache::get('');
-				$sharedInfo=OC_FileCache::get('/Shared');
-				$used=$rootInfo['size']-$sharedInfo['size'];
-				$free=OC_Filesystem::free_space();
-				$total=$free+$used;
-				if($total==0) $total=1;  // prevent division by zero
-				$relative=round(($used/$total)*10000)/100;
-
-				$xml=array();
-				$xml['quota']=$total;
-				$xml['free']=$free;
-				$xml['used']=$used;
-				$xml['relative']=$relative;
-
-				$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
-				echo($txt);
-			}else{
-				echo self::generateXml('', 'fail', 300, 'User does not exist');
-			}
-		}else{
-			echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
-		}
-        }
-
-        /**
-        * set the quota of a user
-        * @param string $format
-        * @param string $user
-        * @param string $quota
-        * @return string xml/json
-        */
-        private static function quotaSet($format, $user, $quota) {
-                $login=OC_OCS::checkpassword();
-                if(OC_Group::inGroup($login, 'admin')) {
-
-			// todo
-			// not yet implemented
-			// add logic here
-			error_log('OCS call: user:'.$user.' quota:'.$quota);
-
-                        $xml=array();
-                        $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
-                        echo($txt);
-                }else{
-                        echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
-                }
-        }
-
-        /**
-        * get the public key of a user
-        * @param string $format
-        * @param string $user
-        * @return string xml/json
-        */
-        private static function publicKeyGet($format, $user) {
-                $login=OC_OCS::checkpassword();
-
-		if(OC_User::userExists($user)) {
-			// calculate the disc space
-			$txt='this is the public key of '.$user;
-			echo($txt);
-		}else{
-			echo self::generateXml('', 'fail', 300, 'User does not exist');
-		}
-	}
-
-        /**
-        * get the private key of a user
-        * @param string $format
-        * @param string $user
-        * @return string xml/json
-        */
-        private static function privateKeyGet($format, $user) {
-                $login=OC_OCS::checkpassword();
-                if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
-
-                        if(OC_User::userExists($user)) {
-                                // calculate the disc space
-                                $txt='this is the private key of '.$user;
-                                echo($txt);
-                        }else{
-                                echo self::generateXml('', 'fail', 300, 'User does not exist');
-                        }
-                }else{
-                        echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
-                }
-        }
-
-
 }
diff --git a/lib/ocs/activity.php b/lib/ocs/activity.php
new file mode 100644
index 0000000000000000000000000000000000000000..c30e21018d33921afdda06d540f79bbf4e1159b4
--- /dev/null
+++ b/lib/ocs/activity.php
@@ -0,0 +1,28 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @copyright 2012 Frank Karlitschek frank@owncloud.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_OCS_Activity {
+
+	public static function activityGet($parameters){
+		// TODO
+	}
+}
diff --git a/lib/ocs/cloud.php b/lib/ocs/cloud.php
new file mode 100644
index 0000000000000000000000000000000000000000..21095ec91e9991a3a647ed79c6279001eaf96add
--- /dev/null
+++ b/lib/ocs/cloud.php
@@ -0,0 +1,98 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @author Tom Needham
+* @copyright 2012 Frank Karlitschek frank@owncloud.org
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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_OCS_Cloud {
+
+	public static function getSystemWebApps($parameters) {
+		OC_Util::checkLoggedIn();
+		$apps = OC_App::getEnabledApps();
+		$values = array();
+		foreach($apps as $app) {
+			$info = OC_App::getAppInfo($app);
+			if(isset($info['standalone'])) {
+				$newValue = array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
+				$values[] = $newValue;
+			}
+		}
+		return new OC_OCS_Result($values);
+	}
+	
+	public static function getUserQuota($parameters) {
+		$user = OC_User::getUser();
+		if(OC_Group::inGroup($user, 'admin') or ($user==$parameters['user'])) {
+
+			if(OC_User::userExists($parameters['user'])) {
+				// calculate the disc space
+				$userDir = '/'.$parameters['user'].'/files';
+				OC_Filesystem::init($useDir);
+				$rootInfo = OC_FileCache::get('');
+				$sharedInfo = OC_FileCache::get('/Shared');
+				$used = $rootInfo['size'] - $sharedInfo['size'];
+				$free = OC_Filesystem::free_space();
+				$total = $free + $used;
+				if($total===0) $total = 1;  // prevent division by zero
+				$relative = round(($used/$total)*10000)/100;
+
+				$xml = array();
+				$xml['quota'] = $total;
+				$xml['free'] = $free;
+				$xml['used'] = $used;
+				$xml['relative'] = $relative;
+
+				return new OC_OCS_Result($xml);
+			} else {
+				return new OC_OCS_Result(null, 300);
+			}
+		} else {
+			return new OC_OCS_Result(null, 300);
+		}
+	}
+	
+	public static function getUserPublickey($parameters) {
+
+		if(OC_User::userExists($parameters['user'])) {
+			// calculate the disc space
+			// TODO
+			return new OC_OCS_Result(array());
+		} else {
+			return new OC_OCS_Result(null, 300);
+		}
+	}
+	
+	public static function getUserPrivatekey($parameters) {
+		$user = OC_User::getUser();
+		if(OC_Group::inGroup($user, 'admin') or ($user==$parameters['user'])) {
+
+			if(OC_User::userExists($user)) {
+				// calculate the disc space
+				$txt = 'this is the private key of '.$parameters['user'];
+				echo($txt);
+			} else {
+				return new OC_OCS_Result(null, 300, 'User does not exist');
+			}
+		} else {
+			return new OC_OCS_Result('null', 300, 'You don´t have permission to access this ressource.');
+		}
+	}
+}
diff --git a/lib/ocs/config.php b/lib/ocs/config.php
new file mode 100644
index 0000000000000000000000000000000000000000..03c54aa23142fee3c88b0f0a5631e18bf970fdc6
--- /dev/null
+++ b/lib/ocs/config.php
@@ -0,0 +1,36 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @author Tom Needham
+* @copyright 2012 Frank Karlitschek frank@owncloud.org
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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_OCS_Config {
+	
+	public static function apiConfig($parameters) {
+		$xml['version'] = '1.7';
+		$xml['website'] = 'ownCloud';
+		$xml['host'] = OCP\Util::getServerHost();
+		$xml['contact'] = '';
+		$xml['ssl'] = 'false';
+		return new OC_OCS_Result($xml);
+	}
+	
+}
diff --git a/lib/ocs/person.php b/lib/ocs/person.php
new file mode 100644
index 0000000000000000000000000000000000000000..169cc8211db2fe78a4fb901392d7531bd6946e14
--- /dev/null
+++ b/lib/ocs/person.php
@@ -0,0 +1,42 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @author Tom Needham
+* @copyright 2012 Frank Karlitschek frank@owncloud.org
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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_OCS_Person {
+
+	public static function check($parameters) {
+		$login = isset($_POST['login']) ? $_POST['login'] : false;
+		$password = isset($_POST['password']) ? $_POST['password'] : false;
+		if($login && $password) {
+			if(OC_User::checkPassword($login, $password)) {
+				$xml['person']['personid'] = $login;
+				return new OC_OCS_Result($xml);
+			} else {
+				return new OC_OCS_Result(null, 102);
+			}
+		} else {
+			return new OC_OCS_Result(null, 101);
+		}
+	}
+	
+}
diff --git a/lib/ocs/privatedata.php b/lib/ocs/privatedata.php
new file mode 100644
index 0000000000000000000000000000000000000000..e01ed5e8b0757013832ceb7d1286dbf3201001af
--- /dev/null
+++ b/lib/ocs/privatedata.php
@@ -0,0 +1,66 @@
+<?php
+/**
+* ownCloud
+*
+* @author Frank Karlitschek
+* @author Tom Needham
+* @copyright 2012 Frank Karlitschek frank@owncloud.org
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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_OCS_Privatedata {
+
+	public static function get($parameters) {
+		OC_Util::checkLoggedIn();
+		$user = OC_User::getUser();
+		$app = addslashes(strip_tags($parameters['app']));
+		$key = addslashes(strip_tags($parameters['key']));
+		$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'];
+		}
+		return new OC_OCS_Result($xml);
+		//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
+	}
+	
+	public static function set($parameters) {
+		OC_Util::checkLoggedIn();
+		$user = OC_User::getUser();
+		$app = addslashes(strip_tags($parameters['app']));
+		$key = addslashes(strip_tags($parameters['key']));
+		$value = OC_OCS::readData('post', 'value', 'text');
+		if(OC_Preferences::setValue($user, $app, $key, $value)){
+			return new OC_OCS_Result(null, 100);
+		}
+	}
+	
+	public static function delete($parameters) {
+		OC_Util::checkLoggedIn();
+		$user = OC_User::getUser();
+		$app = addslashes(strip_tags($parameters['app']));
+		$key = addslashes(strip_tags($parameters['key']));
+		if($key==="" or $app==="") {
+			return new OC_OCS_Result(null, 101); //key and app are NOT optional here
+		}
+		if(OC_Preferences::deleteKey($user, $app, $key)) {
+			return new OC_OCS_Result(null, 100);
+		}
+	}
+}
diff --git a/lib/ocs/result.php b/lib/ocs/result.php
new file mode 100644
index 0000000000000000000000000000000000000000..b08d911f785f63922d3ca41f27e123e0c2397f1c
--- /dev/null
+++ b/lib/ocs/result.php
@@ -0,0 +1,75 @@
+<?php
+/**
+* ownCloud
+*
+* @author Tom Needham
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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_OCS_Result{
+	
+	private $data, $message, $statusCode, $items, $perPage;
+	
+	/**
+	 * create the OCS_Result object
+	 * @param $data mixed the data to return
+	 */
+	public function __construct($data=null, $code=100, $message=null) {
+		$this->data = $data;
+		$this->statusCode = $code;
+		$this->message = $message;
+	}
+	
+	/**
+	 * optionally set the total number of items available
+	 * @param $items int
+	 */
+	public function setTotalItems(int $items) {
+		$this->items = $items;
+	}
+	
+	/**
+	 * optionally set the the number of items per page
+	 * @param $items int
+	 */
+	public function setItemsPerPage(int $items) {
+		$this->perPage = $items;
+	}
+	
+	/**
+	 * returns the data associated with the api result
+	 * @return array
+	 */
+	public function getResult() {
+		$return = array();
+		$return['meta'] = array();
+		$return['meta']['status'] = ($this->statusCode === 100) ? 'ok' : 'failure';
+		$return['meta']['statuscode'] = $this->statusCode;
+		$return['meta']['message'] = $this->message;
+		if(isset($this->items)) {
+			$return['meta']['totalitems'] = $this->items;
+		}
+		if(isset($this->perPage)) {
+			$return['meta']['itemsperpage'] = $this->perPage;
+		}
+		$return['data'] = $this->data;
+		// Return the result data.
+		return $return;
+	}
+	
+	
+}
\ No newline at end of file
diff --git a/lib/public/api.php b/lib/public/api.php
new file mode 100644
index 0000000000000000000000000000000000000000..a85daa1935cbc7456fc19f81d706db4f90dcc095
--- /dev/null
+++ b/lib/public/api.php
@@ -0,0 +1,44 @@
+<?php
+/**
+* ownCloud
+*
+* @author Tom Needham
+* @copyright 2012 Tom Needham tom@owncloud.com
+*
+* 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/>.
+*
+*/
+
+namespace OCP;
+
+/**
+ * This class provides functions to manage apps in ownCloud
+ */
+class API {
+        
+	/**
+	 * registers an api call
+	 * @param string $method the http method
+	 * @param string $url the url to match
+	 * @param callable $action the function to run
+	 * @param string $app the id of the app registering the call
+	 * @param int $authLevel the level of authentication required for the call (See OC_API constants)
+	 * @param array $defaults
+	 * @param array $requirements
+	 */
+	public static function register($method, $url, $action, $app, $authLevel = OC_API::USER_AUTH, $defaults = array(), $requirements = array()){
+		\OC_API::register($method, $url, $action, $app, $authLevel, $defaults, $requirements);
+	}
+     
+}
diff --git a/lib/router.php b/lib/router.php
index 8cb8fd4f33b3e68664ba8f228f2ff5228c7388de..27e14c38abf0aef0773017232af51236bb6ee984 100644
--- a/lib/router.php
+++ b/lib/router.php
@@ -58,6 +58,23 @@ class OC_Router {
 	 * loads the api routes
 	 */
 	public function loadRoutes() {
+
+		// TODO cache
+		$this->root = $this->getCollection('root');
+		foreach(OC_APP::getEnabledApps() as $app){
+			$file = OC_App::getAppPath($app).'/appinfo/routes.php';
+			if(file_exists($file)){
+				$this->useCollection($app);
+				require_once($file);
+				$collection = $this->getCollection($app);
+				$this->root->addCollection($collection, '/apps/'.$app);
+			}
+		}
+		// include ocs routes
+		require_once(OC::$SERVERROOT.'/ocs/routes.php');
+		$collection = $this->getCollection('ocs');
+		$this->root->addCollection($collection, '/ocs');
+
 		foreach($this->getRoutingFiles() as $app => $file) {
 			$this->useCollection($app);
 			require_once $file;
@@ -67,6 +84,7 @@ class OC_Router {
 		$this->useCollection('root');
 		require_once 'settings/routes.php';
 		require_once 'core/routes.php';
+
 	}
 
 	protected function getCollection($name) {
diff --git a/ocs/routes.php b/ocs/routes.php
new file mode 100644
index 0000000000000000000000000000000000000000..d77b96fc1452372e889f75cb046a27eaa5dda337
--- /dev/null
+++ b/ocs/routes.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright (c) 2012, Tom Needham <tom@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+
+// Config
+OC_API::register('get', '/config', array('OC_OCS_Config', 'apiConfig'), 'ocs', OC_API::GUEST_AUTH);
+// Person
+OC_API::register('post', '/person/check', array('OC_OCS_Person', 'check'), 'ocs', OC_API::GUEST_AUTH);
+// Activity
+OC_API::register('get', '/activity', array('OC_OCS_Activity', 'activityGet'), 'ocs', OC_API::USER_AUTH); 
+// Privatedata
+OC_API::register('get', '/privatedata/getattribute', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH, array('app' => '', 'key' => ''));
+OC_API::register('get', '/privatedata/getattribute/{app}', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH, array('key' => ''));
+OC_API::register('get', '/privatedata/getattribute/{app}/{key}', array('OC_OCS_Privatedata', 'get'), 'ocs', OC_API::USER_AUTH);
+OC_API::register('post', '/privatedata/setattribute/{app}/{key}', array('OC_OCS_Privatedata', 'set'), 'ocs', OC_API::USER_AUTH);
+OC_API::register('post', '/privatedata/deleteattribute/{app}/{key}', array('OC_OCS_Privatedata', 'delete'), 'ocs', OC_API::USER_AUTH);
+?>
diff --git a/ocs/v1.php b/ocs/v1.php
index 1652b0bedbe223138f1a59ca57ca037626e5c196..af83a56ff147715f7ebd1378ade420ccee4b60f2 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -21,6 +21,15 @@
 *
 */
 
-require_once '../lib/base.php';
-@ob_clean();
-OC_OCS::handle();
+require_once('../lib/base.php');
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+try {
+	OC::getRouter()->match('/ocs'.$_SERVER['PATH_INFO']);
+} catch (ResourceNotFoundException $e) {
+	OC_OCS::notFound();
+} catch (MethodNotAllowedException $e) {
+	OC_Response::setStatus(405);
+}
+
diff --git a/settings/css/oauth.css b/settings/css/oauth.css
new file mode 100644
index 0000000000000000000000000000000000000000..ccdb98cfa396a83bb37d8ceb5c69c5629e5de5e7
--- /dev/null
+++ b/settings/css/oauth.css
@@ -0,0 +1,4 @@
+.guest-container{ width:35%; margin: 2em auto 0 auto; }
+#oauth-request a.button{ float: right; }
+#oauth-request ul li{ list-style: disc; }
+#oauth-request ul { margin-left: 2em; margin-top: 1em; }
diff --git a/settings/oauth.php b/settings/oauth.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dba9b33a53b4faeb4c85022cb5363193b7d01eb
--- /dev/null
+++ b/settings/oauth.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright (c) 2012, Tom Needham <tom@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+
+require_once('../lib/base.php');
+// Logic
+$operation = isset($_GET['operation']) ? $_GET['operation'] : '';
+$server = OC_OAuth_server::init();
+
+switch($operation){
+	
+	case 'register':
+
+		// Here external apps can register with an ownCloud
+		if(empty($_GET['name']) || empty($_GET['url'])){
+			// Invalid request
+			echo 401;
+		} else {
+			$callbacksuccess = empty($_GET['callback_success']) ? null : $_GET['callback_success'];
+			$callbackfail = empty($_GET['callback_fail']) ? null : $_GET['callback_fail'];
+			$consumer = OC_OAuth_Server::register_consumer($_GET['name'], $_GET['url'], $callbacksuccess, $callbackfail);
+			
+			echo 'Registered consumer successfully! </br></br>Key: ' . $consumer->key . '</br>Secret: ' . $consumer->secret;
+		}
+	break;
+	
+	case 'request_token':
+		
+		try {
+			$request = OAuthRequest::from_request();
+			$token = $server->get_request_token($request);
+			echo $token;
+		} catch (OAuthException $exception) {
+			OC_Log::write('OC_OAuth_Server', $exception->getMessage(), OC_LOG::ERROR);
+			echo $exception->getMessage();
+		}
+	
+	break;
+	case 'authorise';
+	
+		OC_API::checkLoggedIn();
+		// Example
+		$consumer = array(
+			'name' => 'Firefox Bookmark Sync',
+			'scopes' => array('ookmarks'),
+		);
+		
+		// Check that the scopes are real and installed
+		$apps = OC_App::getEnabledApps();
+		$notfound = array();
+		foreach($consumer['scopes'] as $requiredapp){
+			// App scopes are in this format: app_$appname
+			$requiredapp = end(explode('_', $requiredapp));
+			if(!in_array($requiredapp, $apps)){
+				$notfound[] = $requiredapp;
+			}
+		}
+		if(!empty($notfound)){
+			// We need more apps :( Show error
+			if(count($notfound)==1){
+				$message = 'requires that you have an extra app installed on your ownCloud. Please contact your ownCloud administrator and ask them to install the app below.';
+			} else {
+				$message = 'requires that you have some extra apps installed on your ownCloud. Please contract your ownCloud administrator and ask them to install the apps below.';
+			}
+			$t = new OC_Template('settings', 'oauth-required-apps', 'guest');
+			OC_Util::addStyle('settings', 'oauth');
+			$t->assign('requiredapps', $notfound);
+			$t->assign('consumer', $consumer);
+			$t->assign('message', $message);
+			$t->printPage();
+		} else {
+			$t = new OC_Template('settings', 'oauth', 'guest');
+			OC_Util::addStyle('settings', 'oauth');
+			$t->assign('consumer', $consumer);
+			$t->printPage();
+		}
+	break;
+	
+	case 'access_token';
+		try {
+			$request = OAuthRequest::from_request();
+			$token = $server->fetch_access_token($request);
+			echo $token;
+		} catch (OAuthException $exception) {
+			OC_Log::write('OC_OAuth_Server', $exception->getMessage(), OC_LOG::ERROR);
+			echo $exception->getMessage();
+		}
+		
+	break;
+	default:
+		// Something went wrong, we need an operation!
+		OC_Response::setStatus(400);
+	break;
+	
+}
diff --git a/settings/templates/oauth-required-apps.php b/settings/templates/oauth-required-apps.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4fce54c59c1f96d2ee28fe2581c9b34930635a0
--- /dev/null
+++ b/settings/templates/oauth-required-apps.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright (c) 2012, Tom Needham <tom@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+?>
+<div id="oauth-request" class="guest-container">
+	<p><strong><?php echo $_['consumer']['name'].'</strong> '.$_['message']; ?></p>
+	<ul>
+		<?php
+		// Foreach requested scope
+		foreach($_['requiredapps'] as $requiredapp){
+			echo '<li>'.$requiredapp.'</li>';
+		}
+		?>
+	</ul>
+	<a href="<?php echo OC::$WEBROOT; ?>" id="back-home" class="button">Back to ownCloud</a>
+</div>
diff --git a/settings/templates/oauth.php b/settings/templates/oauth.php
new file mode 100644
index 0000000000000000000000000000000000000000..053a8aee6d3f1fa946b580cb05d7471b31420968
--- /dev/null
+++ b/settings/templates/oauth.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright (c) 2012, Tom Needham <tom@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ */
+?>
+<div id="oauth-request" class="guest-container">
+	<p><strong><?php echo $_['consumer']['name']; ?></strong> is requesting your permission to read, write, modify and delete data from the following apps:</p>
+	<ul>
+		<?php
+		// Foreach requested scope
+		foreach($_['consumer']['scopes'] as $app){
+			echo '<li>'.$app.'</li>';
+		}
+		?>
+	</ul>
+	<a href="#" class="button">Allow</a>
+	<a href="#" class="button">Disallow</a>
+</div>