diff --git a/modules/oauth/bin/demo.php b/modules/oauth/bin/demo.php
new file mode 100755
index 0000000000000000000000000000000000000000..e73fe124ea6054b9859fffbd1af8dbd3835dfdc2
--- /dev/null
+++ b/modules/oauth/bin/demo.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+<?php
+
+/* This is the base directory of the simpleSAMLphp installation. */
+$baseDir = dirname(dirname(dirname(dirname(__FILE__))));
+
+/* Add library autoloader. */
+require_once($baseDir . '/lib/_autoload.php');
+
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+$baseurl = (isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 'https://foodle.feide.no/simplesaml');
+$key = (isset($_SERVER['argv'][2]) ? $_SERVER['argv'][1] : 'key');
+$secret = (isset($_SERVER['argv'][3]) ? $_SERVER['argv'][1] : 'secret');
+
+echo 'Welcome to the OAuth CLI client' . "\n";
+$consumer = new sspmod_oauth_Consumer($key, $secret);
+
+// Get the request token
+$requestToken = $consumer->getRequestToken($baseurl . '/module.php/oauth/requestToken.php');
+echo "Got a request token from the OAuth service provider [" . $requestToken->key . "] with the secret [" . $requestToken->secret . "]\n";
+
+// Authorize the request token
+$consumer->getAuthorizeRequest($baseurl . '/module.php/oauth/authorize.php', $requestToken);
+
+// Replace the request token with an access token
+$accessToken = $consumer->getAccessToken( $baseurl . '/module.php/oauth/accessToken.php', $requestToken);
+echo "Got an access token from the OAuth service provider [" . $accessToken->key . "] with the secret [" . $accessToken->secret . "]\n";
+
+$userdata = $consumer->getUserInfo($baseurl . '/module.php/oauth/getUserInfo.php', $accessToken);
+
+
+echo 'You are successfully authenticated to this Command Line CLI. ' . "\n";
+echo 'Got data [' . join(', ', array_keys($userdata)) . ']' . "\n";
+echo 'Your user ID is :  ' . $userdata['eduPersonPrincipalName'][0] . "\n";
+
+
+
+
+
+
+
diff --git a/modules/oauth/default-disable b/modules/oauth/default-disable
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/modules/oauth/lib/Consumer.php b/modules/oauth/lib/Consumer.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a7407442412d0d4358d3b0e54ca0dc5aa1d15f0
--- /dev/null
+++ b/modules/oauth/lib/Consumer.php
@@ -0,0 +1,83 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+/**
+ * OAuth Consumer
+ *
+ * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_oauth_Consumer {
+	
+	private $consumer;
+	private $signer;
+	
+	public function __construct($key, $secret) {
+		$this->consumer = new OAuthConsumer($key, $secret, NULL);
+		$this->signer = new OAuthSignatureMethod_HMAC_SHA1();
+	}
+	
+	public function getRequestToken($url) {
+		$req_req = OAuthRequest::from_consumer_and_token($this->consumer, NULL, "GET", $url, NULL);
+		$req_req->sign_request($this->signer, $this->consumer, NULL);
+
+		echo "Requesting a request token\n";
+		// echo 'go to url: ' . $req_req->to_url() . "\n"; exit;
+		$response_req = file_get_contents($req_req->to_url());
+
+		parse_str($response_req, $responseParsed);
+		
+		if(array_key_exists('error', $responseParsed))
+			throw new Exception('Error getting request token: ') . $responseParsed['error'];
+		
+		$requestToken = $responseParsed['oauth_token'];
+		$requestTokenSecret = $responseParsed['oauth_token_secret'];
+		
+		return new OAuthToken($requestToken, $requestTokenSecret);
+	}
+	
+	public function getAuthorizeRequest($url, $requestToken) {
+		$authorizeURL = $url . '?oauth_token=' . $requestToken->key;
+
+		echo "Please go to this URL to authorize access: " . $authorizeURL . "\n";
+		system("open " . $authorizeURL);
+
+		echo "Waiting 15 seconds for you to authenticate. Usually you should let the user enter return or click a continue button.\n";
+
+		sleep(15);
+	}
+	
+	public function getAccessToken($url, $requestToken) {
+
+		$acc_req = OAuthRequest::from_consumer_and_token($this->consumer, $requestToken, "GET", $url, NULL);
+		$acc_req->sign_request($this->signer, $this->consumer, $requestToken);
+
+		$response_acc = file_get_contents($acc_req->to_url());
+		
+		parse_str($response_acc, $accessResponseParsed);
+		
+		if(array_key_exists('error', $accessResponseParsed))
+			throw new Exception('Error getting request token: ') . $accessResponseParsed['error'];
+		
+		$accessToken = $accessResponseParsed['oauth_token'];
+		$accessTokenSecret = $accessResponseParsed['oauth_token_secret'];
+
+		return new OAuthToken($accessToken, $accessTokenSecret);
+	}
+	
+	public function getUserInfo($url, $accessToken) {
+		
+		$data_req = OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "GET", $url, NULL);
+		$data_req->sign_request($this->signer, $this->consumer, $accessToken);
+
+		$data = file_get_contents($data_req->to_url());
+		// print_r($data);
+
+		$dataDecoded = json_decode($data, TRUE);
+		return $dataDecoded;
+	}
+	
+}
+
diff --git a/modules/oauth/lib/OAuthServer.php b/modules/oauth/lib/OAuthServer.php
new file mode 100644
index 0000000000000000000000000000000000000000..195ab24be618c06fdb429c2a97fb01fa69c42d7a
--- /dev/null
+++ b/modules/oauth/lib/OAuthServer.php
@@ -0,0 +1,17 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+/**
+ * OAuth Provider implementation..
+ *
+ * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_oauth_OAuthServer extends OAuthServer {
+	public function get_signature_methods() {
+		return $this->signature_methods;
+	}
+}
+
diff --git a/modules/oauth/lib/OAuthStore.php b/modules/oauth/lib/OAuthStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..20e8ab3f49dcb5f45ae4c5734cf949fbc4f6e7e4
--- /dev/null
+++ b/modules/oauth/lib/OAuthStore.php
@@ -0,0 +1,94 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+/**
+ * OAuth Provider implementation..
+ *
+ * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_oauth_OAuthStore extends OAuthDataStore {
+
+	private $path;
+
+    function __construct($path = '/tmp/oauth/') {
+		$this->path = $path;
+    }
+
+	private function filename($key) {
+		return $this->path . sha1($key) . '.oauthstore';
+	}
+	
+	private function exists($key) {
+		return file_exists($this->filename($key));
+	}
+	
+	private function get($key) {
+		error_log( 'Getting :' . $key . ' : ' . ($this->exists($key) ? 'FOUND' : 'NOTFOUND'));
+		if (!$this->exists($key)) return NULL;
+		return unserialize(file_get_contents($this->filename($key)));
+	}
+	
+	private function set($key, $value) {
+		error_log('Setting :' . $key . ' : ' . ($this->exists($key) ? 'FOUND' : 'NOTFOUND'));
+		file_put_contents($this->filename($key), serialize($value));
+	}
+
+	private function remove($key) {
+		unlink($this->filename($key));
+	}
+	
+	public function authorize($requestToken, $data) {
+		$this->set('validated.request.' . $requestToken, $data);
+	}
+	
+	public function isAuthorized($requestToken) {
+		return $this->exists('validated.request.' . $requestToken);
+	}
+	
+	public function getAuthorizedData($token) {
+		return $this->get('validated.request.' . $token);
+	}
+	
+	public function moveAuthorizedData($requestToken, $accessToken) {
+		$this->authorize($accessToken, $this->getAuthorizedData($requestToken));
+		$this->remove('validated.request.' . $requestToken);
+	}
+	
+	private function tokenTag($tokenType = 'default', $token) {
+		return 'token.' . $token . '.' . $tokenType;
+	}
+
+    function lookup_consumer($consumer_key) {
+        if ($consumer_key == 'key') return new OAuthConsumer("key", "secret", NULL);
+        return NULL;
+    }
+
+    function lookup_token($consumer, $tokenType = 'default', $token) {
+		return $this->get($this->tokenTag($tokenType, $token));
+    }
+
+    function lookup_nonce($consumer, $token, $nonce, $timestamp) {
+		$nonceTag = 'nonce.' . $consumer->key . '.' . $nonce;
+		if ($this->exists($nonceTag))
+			return TRUE;
+		
+		$this->set($nonceTag, $timestamp);
+		return FALSE;
+    }
+
+    function new_request_token($consumer) {
+		$token = new OAuthToken(SimpleSAML_Utilities::generateID(), SimpleSAML_Utilities::generateID());
+		$this->set($this->tokenTag('request', $token->key), $token);
+        return $token;
+    }
+
+    function new_access_token($token, $consumer) {
+		$token = new OAuthToken(SimpleSAML_Utilities::generateID(), SimpleSAML_Utilities::generateID());
+		$this->set($this->tokenTag('access', $token->key), $token);
+        return $token;
+    }
+
+}
diff --git a/modules/oauth/libextinc/OAuth.php b/modules/oauth/libextinc/OAuth.php
new file mode 100644
index 0000000000000000000000000000000000000000..029166175c5f4b6ad07fac4bb47ea0502c7b95f9
--- /dev/null
+++ b/modules/oauth/libextinc/OAuth.php
@@ -0,0 +1,770 @@
+<?php
+// vim: foldmethod=marker
+
+/* Generic exception class
+ */
+class OAuthException extends Exception {/*{{{*/
+  // pass
+}/*}}}*/
+
+class OAuthConsumer {/*{{{*/
+  public $key;
+  public $secret;
+
+  function __construct($key, $secret, $callback_url=NULL) {/*{{{*/
+    $this->key = $key;
+    $this->secret = $secret;
+    $this->callback_url = $callback_url;
+  }/*}}}*/
+
+  function __toString() {/*{{{*/
+    return "OAuthConsumer[key=$this->key,secret=$this->secret]";
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthToken {/*{{{*/
+  // access tokens and request tokens
+  public $key;
+  public $secret;
+
+  /**
+   * key = the token
+   * secret = the token secret
+   */
+  function __construct($key, $secret) {/*{{{*/
+    $this->key = $key;
+    $this->secret = $secret;
+  }/*}}}*/
+
+  /**
+   * generates the basic string serialization of a token that a server
+   * would respond to request_token and access_token calls with
+   */
+  function to_string() {/*{{{*/
+    return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) . 
+        "&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret);
+  }/*}}}*/
+
+  function __toString() {/*{{{*/
+    return $this->to_string();
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthSignatureMethod {/*{{{*/
+  public function check_signature(&$request, $consumer, $token, $signature) {
+    $built = $this->build_signature($request, $consumer, $token);
+    return $built == $signature;
+  }
+}/*}}}*/
+
+class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {/*{{{*/
+  function get_name() {/*{{{*/
+    return "HMAC-SHA1";
+  }/*}}}*/
+
+  public function build_signature($request, $consumer, $token) {/*{{{*/
+    $base_string = $request->get_signature_base_string();
+    $request->base_string = $base_string;
+
+    $key_parts = array(
+      $consumer->secret,
+      ($token) ? $token->secret : ""
+    );
+
+    $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
+    $key = implode('&', $key_parts);
+
+    return base64_encode( hash_hmac('sha1', $base_string, $key, true));
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {/*{{{*/
+  public function get_name() {/*{{{*/
+    return "PLAINTEXT";
+  }/*}}}*/
+
+  public function build_signature($request, $consumer, $token) {/*{{{*/
+    $sig = array(
+      OAuthUtil::urlencode_rfc3986($consumer->secret)
+    );
+
+    if ($token) {
+      array_push($sig, OAuthUtil::urlencode_rfc3986($token->secret));
+    } else {
+      array_push($sig, '');
+    }
+
+    $raw = implode("&", $sig);
+    // for debug purposes
+    $request->base_string = $raw;
+
+    return OAuthUtil::urlencode_rfc3986($raw);
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {/*{{{*/
+  public function get_name() {/*{{{*/
+    return "RSA-SHA1";
+  }/*}}}*/
+
+  protected function fetch_public_cert(&$request) {/*{{{*/
+    // not implemented yet, ideas are:
+    // (1) do a lookup in a table of trusted certs keyed off of consumer
+    // (2) fetch via http using a url provided by the requester
+    // (3) some sort of specific discovery code based on request
+    //
+    // either way should return a string representation of the certificate
+    throw Exception("fetch_public_cert not implemented");
+  }/*}}}*/
+
+  protected function fetch_private_cert(&$request) {/*{{{*/
+    // not implemented yet, ideas are:
+    // (1) do a lookup in a table of trusted certs keyed off of consumer
+    //
+    // either way should return a string representation of the certificate
+    throw Exception("fetch_private_cert not implemented");
+  }/*}}}*/
+
+  public function build_signature(&$request, $consumer, $token) {/*{{{*/
+    $base_string = $request->get_signature_base_string();
+    $request->base_string = $base_string;
+  
+    // Fetch the private key cert based on the request
+    $cert = $this->fetch_private_cert($request);
+
+    // Pull the private key ID from the certificate
+    $privatekeyid = openssl_get_privatekey($cert);
+
+    // Sign using the key
+    $ok = openssl_sign($base_string, $signature, $privatekeyid);   
+
+    // Release the key resource
+    openssl_free_key($privatekeyid);
+  
+    return base64_encode($signature);
+  } /*}}}*/
+
+  public function check_signature(&$request, $consumer, $token, $signature) {/*{{{*/
+    $decoded_sig = base64_decode($signature);
+
+    $base_string = $request->get_signature_base_string();
+  
+    // Fetch the public key cert based on the request
+    $cert = $this->fetch_public_cert($request);
+
+    // Pull the public key ID from the certificate
+    $publickeyid = openssl_get_publickey($cert);
+
+    // Check the computed signature against the one passed in the query
+    $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);   
+
+    // Release the key resource
+    openssl_free_key($publickeyid);
+  
+    return $ok == 1;
+  } /*}}}*/
+}/*}}}*/
+
+class OAuthRequest {/*{{{*/
+  private $parameters;
+  private $http_method;
+  private $http_url;
+  // for debug purposes
+  public $base_string;
+  public static $version = '1.0';
+
+  function __construct($http_method, $http_url, $parameters=NULL) {/*{{{*/
+    @$parameters or $parameters = array();
+    $this->parameters = $parameters;
+    $this->http_method = $http_method;
+    $this->http_url = $http_url;
+  }/*}}}*/
+
+
+  /**
+   * attempt to build up a request from what was passed to the server
+   */
+  public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {/*{{{*/
+    $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https';
+    @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
+    @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
+    
+    $request_headers = OAuthRequest::get_headers();
+
+    // let the library user override things however they'd like, if they know
+    // which parameters to use then go for it, for example XMLRPC might want to
+    // do this
+    if ($parameters) {
+      $req = new OAuthRequest($http_method, $http_url, $parameters);
+    } else {
+      // collect request parameters from query string (GET) and post-data (POST) if appropriate (note: POST vars have priority)
+      $req_parameters = $_GET;
+      if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) {
+        $req_parameters = array_merge($req_parameters, $_POST);
+      }
+
+      // next check for the auth header, we need to do some extra stuff
+      // if that is the case, namely suck in the parameters from GET or POST
+      // so that we can include them in the signature
+      if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
+        $header_parameters = OAuthRequest::split_header($request_headers['Authorization']);
+        $parameters = array_merge($req_parameters, $header_parameters);
+        $req = new OAuthRequest($http_method, $http_url, $parameters);
+      } else $req = new OAuthRequest($http_method, $http_url, $req_parameters);
+    }
+
+    return $req;
+  }/*}}}*/
+
+  /**
+   * pretty much a helper function to set up the request
+   */
+  public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {/*{{{*/
+    @$parameters or $parameters = array();
+    $defaults = array("oauth_version" => OAuthRequest::$version,
+                      "oauth_nonce" => OAuthRequest::generate_nonce(),
+                      "oauth_timestamp" => OAuthRequest::generate_timestamp(),
+                      "oauth_consumer_key" => $consumer->key);
+    $parameters = array_merge($defaults, $parameters);
+
+    if ($token) {
+      $parameters['oauth_token'] = $token->key;
+    }
+    return new OAuthRequest($http_method, $http_url, $parameters);
+  }/*}}}*/
+
+  public function set_parameter($name, $value) {/*{{{*/
+    $this->parameters[$name] = $value;
+  }/*}}}*/
+
+  public function get_parameter($name) {/*{{{*/
+    return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
+  }/*}}}*/
+
+  public function get_parameters() {/*{{{*/
+    return $this->parameters;
+  }/*}}}*/
+
+  /**
+   * Returns the normalized parameters of the request
+   * 
+   * This will be all (except oauth_signature) parameters,
+   * sorted first by key, and if duplicate keys, then by
+   * value.
+   *
+   * The returned string will be all the key=value pairs
+   * concated by &.
+   * 
+   * @return string
+   */
+  public function get_signable_parameters() {/*{{{*/
+    // Grab all parameters
+    $params = $this->parameters;
+		
+    // Remove oauth_signature if present
+    if (isset($params['oauth_signature'])) {
+      unset($params['oauth_signature']);
+    }
+		
+    // Urlencode both keys and values
+    $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
+    $values = OAuthUtil::urlencode_rfc3986(array_values($params));
+    $params = array_combine($keys, $values);
+
+    // Sort by keys (natsort)
+    uksort($params, 'strcmp');
+
+    // Generate key=value pairs
+    $pairs = array();
+    foreach ($params as $key=>$value ) {
+      if (is_array($value)) {
+        // If the value is an array, it's because there are multiple 
+        // with the same key, sort them, then add all the pairs
+        natsort($value);
+        foreach ($value as $v2) {
+          $pairs[] = $key . '=' . $v2;
+        }
+      } else {
+        $pairs[] = $key . '=' . $value;
+      }
+    }
+		
+    // Return the pairs, concated with &
+    return implode('&', $pairs);
+  }/*}}}*/
+
+  /**
+   * Returns the base string of this request
+   *
+   * The base string defined as the method, the url
+   * and the parameters (normalized), each urlencoded
+   * and the concated with &.
+   */
+  public function get_signature_base_string() {/*{{{*/
+    $parts = array(
+      $this->get_normalized_http_method(),
+      $this->get_normalized_http_url(),
+      $this->get_signable_parameters()
+    );
+
+    $parts = OAuthUtil::urlencode_rfc3986($parts);
+
+    return implode('&', $parts);
+  }/*}}}*/
+
+  /**
+   * just uppercases the http method
+   */
+  public function get_normalized_http_method() {/*{{{*/
+    return strtoupper($this->http_method);
+  }/*}}}*/
+
+  /**
+   * parses the url and rebuilds it to be
+   * scheme://host/path
+   */
+  public function get_normalized_http_url() {/*{{{*/
+    $parts = parse_url($this->http_url);
+
+    $port = @$parts['port'];
+    $scheme = $parts['scheme'];
+    $host = $parts['host'];
+    $path = @$parts['path'];
+
+    $port or $port = ($scheme == 'https') ? '443' : '80';
+
+    if (($scheme == 'https' && $port != '443')
+        || ($scheme == 'http' && $port != '80')) {
+      $host = "$host:$port";
+    }
+    return "$scheme://$host$path";
+  }/*}}}*/
+
+  /**
+   * builds a url usable for a GET request
+   */
+  public function to_url() {/*{{{*/
+    $out = $this->get_normalized_http_url() . "?";
+    $out .= $this->to_postdata();
+    return $out;
+  }/*}}}*/
+
+  /**
+   * builds the data one would send in a POST request
+   *
+   * TODO(morten.fangel):
+   * this function might be easily replaced with http_build_query()
+   * and corrections for rfc3986 compatibility.. but not sure
+   */
+  public function to_postdata() {/*{{{*/
+    $total = array();
+    foreach ($this->parameters as $k => $v) {
+      if (is_array($v)) {
+        foreach ($v as $va) {
+          $total[] = OAuthUtil::urlencode_rfc3986($k) . "[]=" . OAuthUtil::urlencode_rfc3986($va);
+        }
+      } else {
+        $total[] = OAuthUtil::urlencode_rfc3986($k) . "=" . OAuthUtil::urlencode_rfc3986($v);
+      }
+    }
+    $out = implode("&", $total);
+    return $out;
+  }/*}}}*/
+
+  /**
+   * builds the Authorization: header
+   */
+  public function to_header() {/*{{{*/
+    $out ='Authorization: OAuth realm=""';
+    $total = array();
+    foreach ($this->parameters as $k => $v) {
+      if (substr($k, 0, 5) != "oauth") continue;
+      if (is_array($v)) throw new OAuthException('Arrays not supported in headers');
+      $out .= ',' . OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"';
+    }
+    return $out;
+  }/*}}}*/
+
+  public function __toString() {/*{{{*/
+    return $this->to_url();
+  }/*}}}*/
+
+
+  public function sign_request($signature_method, $consumer, $token) {/*{{{*/
+    $this->set_parameter("oauth_signature_method", $signature_method->get_name());
+    $signature = $this->build_signature($signature_method, $consumer, $token);
+    $this->set_parameter("oauth_signature", $signature);
+  }/*}}}*/
+
+  public function build_signature($signature_method, $consumer, $token) {/*{{{*/
+    $signature = $signature_method->build_signature($this, $consumer, $token);
+    return $signature;
+  }/*}}}*/
+
+  /**
+   * util function: current timestamp
+   */
+  private static function generate_timestamp() {/*{{{*/
+    return time();
+  }/*}}}*/
+
+  /**
+   * util function: current nonce
+   */
+  private static function generate_nonce() {/*{{{*/
+    $mt = microtime();
+    $rand = mt_rand();
+
+    return md5($mt . $rand); // md5s look nicer than numbers
+  }/*}}}*/
+
+  /**
+   * util function for turning the Authorization: header into
+   * parameters, has to do some unescaping
+   */
+  private static function split_header($header) {/*{{{*/
+    $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
+    $offset = 0;
+    $params = array();
+    while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
+      $match = $matches[0];
+      $header_name = $matches[2][0];
+      $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
+      $params[$header_name] = OAuthUtil::urldecode_rfc3986( $header_content );
+      $offset = $match[1] + strlen($match[0]);
+    }
+  
+    if (isset($params['realm'])) {
+       unset($params['realm']);
+    }
+
+    return $params;
+  }/*}}}*/
+
+  /**
+   * helper to try to sort out headers for people who aren't running apache
+   */
+  private static function get_headers() {/*{{{*/
+    if (function_exists('apache_request_headers')) {
+      // we need this to get the actual Authorization: header
+      // because apache tends to tell us it doesn't exist
+      return apache_request_headers();
+    }
+    // otherwise we don't have apache and are just going to have to hope
+    // that $_SERVER actually contains what we need
+    $out = array();
+    foreach ($_SERVER as $key => $value) {
+      if (substr($key, 0, 5) == "HTTP_") {
+        // this is chaos, basically it is just there to capitalize the first
+        // letter of every word that is not an initial HTTP and strip HTTP
+        // code from przemek
+        $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
+        $out[$key] = $value;
+      }
+    }
+    return $out;
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthServer {/*{{{*/
+  protected $timestamp_threshold = 300; // in seconds, five minutes
+  protected $version = 1.0;             // hi blaine
+  protected $signature_methods = array();
+
+  protected $data_store;
+
+  function __construct($data_store) {/*{{{*/
+    $this->data_store = $data_store;
+  }/*}}}*/
+
+  public function add_signature_method($signature_method) {/*{{{*/
+    $this->signature_methods[$signature_method->get_name()] = 
+        $signature_method;
+  }/*}}}*/
+  
+  // high level functions
+
+  /**
+   * process a request_token request
+   * returns the request token on success
+   */
+  public function fetch_request_token(&$request) {/*{{{*/
+    $this->get_version($request);
+
+    $consumer = $this->get_consumer($request);
+
+    // no token required for the initial token request
+    $token = NULL;
+
+    $this->check_signature($request, $consumer, $token);
+
+    $new_token = $this->data_store->new_request_token($consumer);
+
+    return $new_token;
+  }/*}}}*/
+
+  /**
+   * process an access_token request
+   * returns the access token on success
+   */
+  public function fetch_access_token(&$request) {/*{{{*/
+    $this->get_version($request);
+
+    $consumer = $this->get_consumer($request);
+
+    // requires authorized request token
+    $token = $this->get_token($request, $consumer, "request");
+
+
+    $this->check_signature($request, $consumer, $token);
+
+    $new_token = $this->data_store->new_access_token($token, $consumer);
+
+    return $new_token;
+  }/*}}}*/
+
+  /**
+   * verify an api call, checks all the parameters
+   */
+  public function verify_request(&$request) {/*{{{*/
+    $this->get_version($request);
+    $consumer = $this->get_consumer($request);
+    $token = $this->get_token($request, $consumer, "access");
+    $this->check_signature($request, $consumer, $token);
+    return array($consumer, $token);
+  }/*}}}*/
+
+  // Internals from here
+  /**
+   * version 1
+   */
+  private function get_version(&$request) {/*{{{*/
+    $version = $request->get_parameter("oauth_version");
+    if (!$version) {
+      $version = 1.0;
+    }
+    if ($version && $version != $this->version) {
+      throw new OAuthException("OAuth version '$version' not supported");
+    }
+    return $version;
+  }/*}}}*/
+
+  /**
+   * figure out the signature with some defaults
+   */
+  private function get_signature_method(&$request) {/*{{{*/
+    $signature_method =  
+        @$request->get_parameter("oauth_signature_method");
+    if (!$signature_method) {
+      $signature_method = "PLAINTEXT";
+    }
+    if (!in_array($signature_method, 
+                  array_keys($this->signature_methods))) {
+      throw new OAuthException(
+        "Signature method '$signature_method' not supported try one of the following: " . implode(", ", array_keys($this->signature_methods))
+      );      
+    }
+    return $this->signature_methods[$signature_method];
+  }/*}}}*/
+
+  /**
+   * try to find the consumer for the provided request's consumer key
+   */
+  private function get_consumer(&$request) {/*{{{*/
+    $consumer_key = @$request->get_parameter("oauth_consumer_key");
+    if (!$consumer_key) {
+      throw new OAuthException("Invalid consumer key");
+    }
+
+    $consumer = $this->data_store->lookup_consumer($consumer_key);
+    if (!$consumer) {
+      throw new OAuthException("Invalid consumer");
+    }
+
+    return $consumer;
+  }/*}}}*/
+
+  /**
+   * try to find the token for the provided request's token key
+   */
+  private function get_token(&$request, $consumer, $token_type="access") {/*{{{*/
+    $token_field = @$request->get_parameter('oauth_token');
+    $token = $this->data_store->lookup_token(
+      $consumer, $token_type, $token_field
+    );
+    if (!$token) {
+      throw new OAuthException("Invalid $token_type token: $token_field");
+    }
+    return $token;
+  }/*}}}*/
+
+  /**
+   * all-in-one function to check the signature on a request
+   * should guess the signature method appropriately
+   */
+  private function check_signature(&$request, $consumer, $token) {/*{{{*/
+    // this should probably be in a different method
+    $timestamp = @$request->get_parameter('oauth_timestamp');
+    $nonce = @$request->get_parameter('oauth_nonce');
+
+    $this->check_timestamp($timestamp);
+    $this->check_nonce($consumer, $token, $nonce, $timestamp);
+
+    $signature_method = $this->get_signature_method($request);
+
+    $signature = $request->get_parameter('oauth_signature');    
+    $valid_sig = $signature_method->check_signature(
+      $request, 
+      $consumer, 
+      $token, 
+      $signature
+    );
+
+    if (!$valid_sig) {
+      throw new OAuthException("Invalid signature");
+    }
+  }/*}}}*/
+
+  /**
+   * check that the timestamp is new enough
+   */
+  private function check_timestamp($timestamp) {/*{{{*/
+    // verify that timestamp is recentish
+    $now = time();
+    if ($now - $timestamp > $this->timestamp_threshold) {
+      throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
+    }
+  }/*}}}*/
+
+  /**
+   * check that the nonce is not repeated
+   */
+  private function check_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
+    // verify that the nonce is uniqueish
+    $found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp);
+    if ($found) {
+      throw new OAuthException("Nonce already used: $nonce");
+    }
+  }/*}}}*/
+
+
+
+}/*}}}*/
+
+class OAuthDataStore {/*{{{*/
+  function lookup_consumer($consumer_key) {/*{{{*/
+    // implement me
+  }/*}}}*/
+
+  function lookup_token($consumer, $token_type, $token) {/*{{{*/
+    // implement me
+  }/*}}}*/
+
+  function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
+    // implement me
+  }/*}}}*/
+
+  function new_request_token($consumer) {/*{{{*/
+    // return a new token attached to this consumer
+  }/*}}}*/
+
+  function new_access_token($token, $consumer) {/*{{{*/
+    // return a new access token attached to this consumer
+    // for the user associated with this token if the request token
+    // is authorized
+    // should also invalidate the request token
+  }/*}}}*/
+
+}/*}}}*/
+
+
+/*  A very naive dbm-based oauth storage
+ */
+class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
+  private $dbh;
+
+  function __construct($path = "oauth.gdbm") {/*{{{*/
+    $this->dbh = dba_popen($path, 'c', 'gdbm');
+  }/*}}}*/
+
+  function __destruct() {/*{{{*/
+    dba_close($this->dbh);
+  }/*}}}*/
+
+  function lookup_consumer($consumer_key) {/*{{{*/
+    $rv = dba_fetch("consumer_$consumer_key", $this->dbh);
+    if ($rv === FALSE) {
+      return NULL;
+    }
+    $obj = unserialize($rv);
+    if (!($obj instanceof OAuthConsumer)) {
+      return NULL;
+    }
+    return $obj;
+  }/*}}}*/
+
+  function lookup_token($consumer, $token_type, $token) {/*{{{*/
+    $rv = dba_fetch("${token_type}_${token}", $this->dbh);
+    if ($rv === FALSE) {
+      return NULL;
+    }
+    $obj = unserialize($rv);
+    if (!($obj instanceof OAuthToken)) {
+      return NULL;
+    }
+    return $obj;
+  }/*}}}*/
+
+  function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
+    if (dba_exists("nonce_$nonce", $this->dbh)) {
+      return TRUE;
+    } else {
+      dba_insert("nonce_$nonce", "1", $this->dbh);
+      return FALSE;
+    }
+  }/*}}}*/
+
+  function new_token($consumer, $type="request") {/*{{{*/
+    $key = md5(time());
+    $secret = time() + time();
+    $token = new OAuthToken($key, md5(md5($secret)));
+    if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
+      throw new OAuthException("doooom!");
+    }
+    return $token;
+  }/*}}}*/
+
+  function new_request_token($consumer) {/*{{{*/
+    return $this->new_token($consumer, "request");
+  }/*}}}*/
+
+  function new_access_token($token, $consumer) {/*{{{*/
+
+    $token = $this->new_token($consumer, 'access');
+    dba_delete("request_" . $token->key, $this->dbh);
+    return $token;
+  }/*}}}*/
+}/*}}}*/
+
+class OAuthUtil {/*{{{*/
+  public static function urlencode_rfc3986($input) {/*{{{*/
+	if (is_array($input)) {
+		return array_map(array('OAuthUtil','urlencode_rfc3986'), $input);
+	} else if (is_scalar($input)) {
+		return str_replace('+', ' ',
+	                       str_replace('%7E', '~', rawurlencode($input)));
+	} else {
+		return '';
+	}
+  }/*}}}*/
+    
+
+  // This decode function isn't taking into consideration the above 
+  // modifications to the encoding process. However, this method doesn't 
+  // seem to be used anywhere so leaving it as is.
+  public static function urldecode_rfc3986($string) {/*{{{*/
+    return rawurldecode($string);
+  }/*}}}*/
+}/*}}}*/
+
+?>
diff --git a/modules/oauth/templates/authorized.php b/modules/oauth/templates/authorized.php
new file mode 100644
index 0000000000000000000000000000000000000000..8820a8ac89a1cc995a3279bae67854e97b2ec938
--- /dev/null
+++ b/modules/oauth/templates/authorized.php
@@ -0,0 +1,15 @@
+<?php
+
+$this->data['header'] = 'OAuth Authorization';
+$this->includeAtTemplateBase('includes/header.php');
+
+?>
+
+    <p style="margin-top: 2em">
+       You are now successfully authenticated, and you may click <em>Continue</em> in the application where you initiated authentication.
+    </p>
+
+
+<?php
+$this->includeAtTemplateBase('includes/footer.php');
+?>
\ No newline at end of file
diff --git a/modules/oauth/www/accessToken.php b/modules/oauth/www/accessToken.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4de1f7f1da910d762d3015aa37de591c5d89b2f
--- /dev/null
+++ b/modules/oauth/www/accessToken.php
@@ -0,0 +1,27 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+$store = new sspmod_oauth_OAuthStore();
+$server = new sspmod_oauth_OAuthServer($store);
+
+$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
+
+$server->add_signature_method($hmac_method);
+$server->add_signature_method($plaintext_method);
+
+$req = OAuthRequest::from_request();
+$requestToken = $req->get_parameter('oauth_token');
+
+
+if (!$store->isAuthorized($requestToken)) {
+	throw new Exception('Your request was not authorized. Request token [' . $requestToken . '] not found.');
+}
+
+$accessToken = $server->fetch_access_token($req);
+
+$data = $store->moveAuthorizedData($requestToken, $accessToken->key);
+
+echo $accessToken;
+
diff --git a/modules/oauth/www/authorize.php b/modules/oauth/www/authorize.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe67606dd94a76530089b5444bcbfbab6e6a75df
--- /dev/null
+++ b/modules/oauth/www/authorize.php
@@ -0,0 +1,52 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+if(!array_key_exists('oauth_token', $_REQUEST)) {
+	throw new Exception('Required URL parameter [oauth_token] is missing.');
+}
+$requestToken = $_REQUEST['oauth_token'];
+
+$store = new sspmod_oauth_OAuthStore();
+$server = new sspmod_oauth_OAuthServer($store);
+
+$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
+
+$server->add_signature_method($hmac_method);
+$server->add_signature_method($plaintext_method);
+
+
+
+
+$config = SimpleSAML_Configuration::getInstance();
+$session = SimpleSAML_Session::getInstance();
+
+$as = 'saml2';
+if (!$session->isValid($as)) {
+	SimpleSAML_Auth_Default::initLogin($as, SimpleSAML_Utilities::selfURL());
+}
+
+$attributes = $session->getAttributes();
+
+#print_r($attributes);
+
+$store->authorize($requestToken, $attributes);
+
+$t = new SimpleSAML_XHTML_Template($config, 'oauth:authorized.php');
+
+$t->data['header'] = '{status:header_saml20_sp}';
+$t->data['remaining'] = $session->remainingTime();
+$t->data['sessionsize'] = $session->getSize();
+$t->data['attributes'] = $attributes;
+$t->data['logouturl'] = SimpleSAML_Utilities::selfURLNoQuery() . '?logout';
+$t->data['icon'] = 'bino.png';
+$t->show();
+
+
+
+
+// 
+// $req = OAuthRequest::from_request();
+// $token = $server->fetch_request_token($req);
+// echo $token;
diff --git a/modules/oauth/www/getUserInfo.php b/modules/oauth/www/getUserInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..4045288d5c8e731893202692b99424f6eece081b
--- /dev/null
+++ b/modules/oauth/www/getUserInfo.php
@@ -0,0 +1,19 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+$store = new sspmod_oauth_OAuthStore();
+$server = new sspmod_oauth_OAuthServer($store);
+
+$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
+
+$server->add_signature_method($hmac_method);
+$server->add_signature_method($plaintext_method);
+
+$req = OAuthRequest::from_request();
+list($consumer, $token) = $server->verify_request($req);
+
+$data = $store->getAuthorizedData($token->key);
+
+echo json_encode($data);
\ No newline at end of file
diff --git a/modules/oauth/www/requestToken.php b/modules/oauth/www/requestToken.php
new file mode 100644
index 0000000000000000000000000000000000000000..f77a56def473821dcc9575c8f405bc07bb97940c
--- /dev/null
+++ b/modules/oauth/www/requestToken.php
@@ -0,0 +1,18 @@
+<?php
+
+require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
+
+$store = new sspmod_oauth_OAuthStore();
+$server = new sspmod_oauth_OAuthServer($store);
+
+
+$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
+
+$server->add_signature_method($hmac_method);
+$server->add_signature_method($plaintext_method);
+
+$req = OAuthRequest::from_request();
+$token = $server->fetch_request_token($req);
+
+echo $token;