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
14 namespace OCA\Grauphel\Controller;
16 use \OCP\AppFramework\Controller;
17 use \OCP\AppFramework\Http;
18 use \OCP\AppFramework\Http\RedirectResponse;
19 use \OCP\AppFramework\Http\TemplateResponse;
21 use \OCA\Grauphel\Lib\Client;
22 use \OCA\Grauphel\Lib\Token;
23 use \OCA\Grauphel\Lib\OAuth;
24 use \OCA\Grauphel\Lib\Dependencies;
25 use \OCA\Grauphel\Lib\Response\ErrorResponse;
26 use \OCA\Grauphel\Lib\Response\FormResponse;
27 use \OCA\Grauphel\Lib\OAuthException;
28 use \OCA\Grauphel\Lib\UrlHelper;
35 * @author Christian Weiske <cweiske@cweiske.de>
36 * @copyright 2014 Christian Weiske
37 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
38 * @version Release: @package_version@
39 * @link http://cweiske.de/grauphel.htm
41 class OauthController extends Controller
46 * constructor of the controller
48 * @param string $appName Name of the app
49 * @param IRequest $request Instance of the request
51 public function __construct($appName, \OCP\IRequest $request, $user)
53 parent::__construct($appName, $request);
55 $this->deps = Dependencies::get();
57 //default http header: we assume something is broken
58 header('HTTP/1.0 500 Internal Server Error');
62 * Handle out an access token after verifying the verification token
69 public function accessToken()
72 $oauth->setDeps($this->deps);
73 $urlGen = $this->deps->urlGen;
76 $provider = OAuth::getProvider();
77 $oauth->registerHandler($provider)
78 ->registerVerificationTokenHandler($provider);
79 $provider->checkOAuthRequest(
80 $urlGen->getAbsoluteURL(
81 $urlGen->linkToRoute('grauphel.oauth.accessToken')
85 $token = $this->deps->tokens->loadAndDelete('verify', $provider->token);
87 $newToken = new Token('access');
88 $newToken->tokenKey = 'a' . bin2hex($provider->generateToken(8));
89 $newToken->secret = 's' . bin2hex($provider->generateToken(8));
90 $newToken->user = $token->user;
91 $newToken->client = $token->client;
92 $this->deps->tokens->store($newToken);
94 return new FormResponse(
96 'oauth_token' => $newToken->tokenKey,
97 'oauth_token_secret' => $newToken->secret,
100 } catch (OAuthException $e) {
101 return new ErrorResponse($e->getMessage());
102 } catch (\OAuthException $e) {
108 * Log the user in and let him authorize that the app may access notes
111 * Page is not public and thus requires owncloud login
116 public function authorize()
118 $token = $this->verifyRequestToken();
119 if (!$token instanceof Token) {
123 $clientTitle = 'unknown';
125 if (isset($_GET['client'])) {
126 $clientAgent = $_GET['client'];
128 $clientTitle = $cl->getNiceName($clientAgent);
131 $res = new TemplateResponse('grauphel', 'oauthAuthorize');
134 'oauth_token' => $token->tokenKey,
135 'clientTitle' => $clientTitle,
136 'clientAgent' => $clientAgent,
137 'formaction' => $this->deps->urlGen->linkToRoute(
138 'grauphel.oauth.confirm'
146 * User confirms or declines the authorization request
147 * OAuth step 2.5 of 3
151 public function confirm()
153 $token = $this->verifyRequestToken();
154 $oauth = new OAuth();
155 $oauth->setDeps($this->deps);
158 $token = $this->deps->tokens->loadAndDelete('temp', $token->tokenKey);
159 } catch (OAuthException $e) {
160 return new ErrorResponse($e->getMessage());
163 $authState = isset($_POST['auth']) && $_POST['auth'] == 'ok';
164 if ($authState === false) {
167 //http://wiki.oauth.net/w/page/12238543/ProblemReporting
168 $res = new RedirectResponse(
169 UrlHelper::addParams(
172 'oauth_token' => $token->tokenKey,
173 'oauth_problem' => 'permission_denied',
177 $res->setStatus(Http::STATUS_SEE_OTHER);
182 if (isset($_POST['client'])) {
183 $clientAgent = $_POST['client'];
186 //the user is logged in and authorized
187 $provider = OAuth::getProvider();
189 $newToken = new Token('verify');
190 $newToken->tokenKey = $token->tokenKey;
191 $newToken->secret = $token->secret;
192 $newToken->verifier = 'v' . bin2hex($provider->generateToken(8));
193 $newToken->user = $this->user->getUID();
194 $newToken->client = $clientAgent;
196 $this->deps->tokens->store($newToken);
199 //FIXME: if no callback is given, show the token to the user
200 $res = new RedirectResponse(
201 UrlHelper::addParams(
204 'oauth_token' => $newToken->tokenKey,
205 'oauth_verifier' => $newToken->verifier
209 $res->setStatus(Http::STATUS_SEE_OTHER);
213 protected function verifyRequestToken()
215 if (!isset($_REQUEST['oauth_token'])) {
216 return new ErrorResponse('oauth_token missing');
219 $oauth = new OAuth();
220 $oauth->setDeps($this->deps);
221 if (!$oauth->validateToken($_REQUEST['oauth_token'])) {
222 return new ErrorResponse('Invalid token string');
225 $reqToken = $_REQUEST['oauth_token'];
228 $token = $this->deps->tokens->load('temp', $reqToken);
229 } catch (OAuthException $e) {
230 return new ErrorResponse($e->getMessage());
237 * Create and return a request token.
244 public function requestToken()
246 $oauth = new OAuth();
247 $oauth->setDeps($this->deps);
248 $urlGen = $this->deps->urlGen;
251 $provider = OAuth::getProvider();
252 $oauth->registerHandler($provider);
253 $provider->isRequestTokenEndpoint(true);
254 $provider->checkOAuthRequest(
255 $urlGen->getAbsoluteURL(
256 $urlGen->linkToRoute('grauphel.oauth.requestToken')
260 //store token + callback URI for later
261 $token = new Token('temp');
262 $token->tokenKey = 'r' . bin2hex($provider->generateToken(8));
263 $token->secret = 's' . bin2hex($provider->generateToken(8));
264 $token->callback = $provider->callback;
266 $this->deps->tokens->store($token);
268 return new FormResponse(
270 'oauth_token' => $token->tokenKey,
271 'oauth_token_secret' => $token->secret,
272 'oauth_callback_confirmed' => 'true'
275 } catch (OAuthException $e) {
276 return new ErrorResponse($e->getMessage());
277 } catch (\OAuthException $e) {