make linking of notes with <speci"a'l> chars work
[grauphel.git] / lib / oauth.php
1 <?php
2 /**
3  * Part of grauphel
4  *
5  * PHP version 5
6  *
7  * @category  Tools
8  * @package   Grauphel
9  * @author    Christian Weiske <cweiske@cweiske.de>
10  * @copyright 2014 Christian Weiske
11  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12  * @link      http://cweiske.de/grauphel.htm
13  */
14 namespace OCA\Grauphel\Lib;
15
16 /**
17  * Storage base class that implements note updating
18  *
19  * @category  Tools
20  * @package   Grauphel
21  * @author    Christian Weiske <cweiske@cweiske.de>
22  * @copyright 2014 Christian Weiske
23  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
24  * @version   Release: @package_version@
25  * @link      http://cweiske.de/grauphel.htm
26  */
27 class OAuth
28 {
29     /**
30      * Token data store
31      *
32      * @var Token_Storage
33      */
34     protected $tokens;
35
36     public function setDeps(Dependencies $deps)
37     {
38         $this->tokens = $deps->tokens;
39     }
40
41     /**
42      * Register callbacks for the oauth dance.
43      */
44     public function registerHandler(\OAuthProvider $provider)
45     {
46         $provider->consumerHandler(array($this, 'lookupConsumer'));
47         $provider->timestampNonceHandler(array($this, 'timestampNonceChecker'));
48         return $this;
49     }
50
51     public function registerVerificationTokenHandler(\OAuthProvider $provider)
52     {
53         $provider->tokenHandler(array($this, 'verifyTokenHandler'));
54         return $this;
55     }
56
57     public function registerAccessTokenHandler(\OAuthProvider $provider)
58     {
59         $provider->tokenHandler(array($this, 'accessTokenHandler'));
60         return $this;
61     }
62
63     public function validateToken($tokenKey)
64     {
65         return (bool) preg_match('#^[a-z0-9]+$#', $tokenKey);
66     }
67
68     public function lookupConsumer(\OAuthProvider $provider)
69     {
70         //tomboy assumes secret==key=="anyone"
71         $provider->consumer_secret = $provider->consumer_key;//'anyone';
72         $provider->addRequiredParameter('oauth_callback');
73
74         return OAUTH_OK;
75     }
76
77     public function timestampNonceChecker(\OAuthProvider $provider)
78     {
79         //var_dump($provider->nonce, $provider->timestamp);
80         //OAUTH_BAD_NONCE
81         //OAUTH_BAD_TIMESTAMP
82         return OAUTH_OK;
83     }
84
85     public function verifyTokenHandler(\OAuthProvider $provider)
86     {
87         $token = $this->tokens->load('verify', $provider->token);
88         if ($provider->verifier == '') {
89             return OAUTH_VERIFIER_INVALID;
90         }
91         if ($provider->verifier != $token->verifier) {
92             return OAUTH_VERIFIER_INVALID;
93         }
94
95         $provider->token_secret = $token->secret;
96         return OAUTH_OK;
97     }
98
99     public function accessTokenHandler(\OAuthProvider $provider)
100     {
101         if ($provider->token == '') {
102             //conboy sends empty token when not authed yet
103             return OAUTH_PARAMETER_ABSENT;
104         }
105
106         try {
107             $token = $this->tokens->load('access', $provider->token);
108         } catch (OAuthException $e) {
109             if ($e->getCode() == OAUTH_TOKEN_REJECTED) {
110                 return OAUTH_TOKEN_REJECTED;
111             }
112             throw $e;
113         }
114
115         if (time() - $token->lastuse > 60) {
116             //time to update lastuse after at least a minute
117             $this->tokens->updateLastUse($token->tokenKey);
118         }
119
120         $provider->token_secret = $token->secret;
121         return OAUTH_OK;
122     }
123
124     public function verifyOAuthUser($username, $url)
125     {
126         try {
127             $provider = OAuth::getProvider();
128             $this->registerHandler($provider);
129             $this->registerAccessTokenHandler($provider);
130             //do not use "user" in signature
131             $provider->setParam('user', null);
132
133             $provider->checkOAuthRequest($url);
134
135             $token = $this->tokens->load('access', $provider->token);
136             if ($token->user != $username) {
137                 errorOut('Invalid user');
138             }
139         } catch (\OAuthException $e) {
140             $this->error($e);
141         }
142     }
143
144     public function error(\OAuthException $e)
145     {
146         header('HTTP/1.0 400 Bad Request');
147         //header('Content-type: application/x-www-form-urlencoded');
148         echo \OAuthProvider::reportProblem($e);
149         //var_dump($e);
150         exit(1);
151     }
152
153     /**
154      * Get a new oauth provider instance.
155      * Used to work around the fastcgi bug in oauthprovider.
156      *
157      * @return \OAuthProvider
158      */
159     public static function getProvider()
160     {
161         $params = array();
162         //$_SERVER['REDIRECT_HTTP_AUTHORIZATION'] = $_SERVER['HTTP_AUTHORIZATION'];
163
164         if (isset($_SERVER['HTTP_AUTHORIZATION'])
165             && $_SERVER['HTTP_AUTHORIZATION'] == ''
166         ) {
167             //work around bug https://bugs.php.net/bug.php?id=68168
168             //#68168: HTTP Basic auth and empty auth header reported
169             //        as "signature_method_rejected"
170             $params['oauth_signature_method'] = OAUTH_SIG_METHOD_PLAINTEXT;
171         }
172
173         if (!isset($_SERVER['HTTP_AUTHORIZATION'])
174             && isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])
175         ) {
176             //FastCgi puts the headers in REDIRECT_HTTP_AUTHORIZATION,
177             // but the oauth extension does not read that.
178             // we have to parse the parameters manually
179             $regex = "/(oauth_[a-z_-]*)=(?:\"([^\"]*)\"|([^,]*))/";
180             preg_match_all(
181                 $regex, $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches
182             );
183
184             foreach ($matches[1] as $key => $paramName) {
185                 $params[$paramName] = urldecode($matches[2][$key]);
186             }
187         }
188
189         return new \OAuthProvider($params);
190     }
191 }
192 ?>