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 'client' => $clientTitle,
136 'formaction' => $this->deps->urlGen->linkToRoute(
137 'grauphel.oauth.confirm'
138 ) . '?client=' . urlencode($clientAgent),
145 * User confirms or declines the authorization request
146 * OAuth step 2.5 of 3
150 public function confirm()
152 $token = $this->verifyRequestToken();
153 $oauth = new OAuth();
154 $oauth->setDeps($this->deps);
157 $token = $this->deps->tokens->loadAndDelete('temp', $token->tokenKey);
158 } catch (OAuthException $e) {
159 return new ErrorResponse($e->getMessage());
162 $authState = isset($_POST['auth']) && $_POST['auth'] == 'ok';
163 if ($authState === false) {
166 //http://wiki.oauth.net/w/page/12238543/ProblemReporting
167 $res = new RedirectResponse(
168 UrlHelper::addParams(
171 'oauth_token' => $token->tokenKey,
172 'oauth_problem' => 'permission_denied',
176 $res->setStatus(Http::STATUS_SEE_OTHER);
181 if (isset($_GET['client'])) {
182 $clientAgent = $_GET['client'];
185 //the user is logged in and authorized
186 $provider = OAuth::getProvider();
188 $newToken = new Token('verify');
189 $newToken->tokenKey = $token->tokenKey;
190 $newToken->secret = $token->secret;
191 $newToken->verifier = 'v' . bin2hex($provider->generateToken(8));
192 $newToken->user = $this->user->getUID();
193 $newToken->client = $clientAgent;
195 $this->deps->tokens->store($newToken);
198 //FIXME: if no callback is given, show the token to the user
199 $res = new RedirectResponse(
200 UrlHelper::addParams(
203 'oauth_token' => $newToken->tokenKey,
204 'oauth_verifier' => $newToken->verifier
208 $res->setStatus(Http::STATUS_SEE_OTHER);
212 protected function verifyRequestToken()
214 if (!isset($_REQUEST['oauth_token'])) {
215 return new ErrorResponse('oauth_token missing');
218 $oauth = new OAuth();
219 $oauth->setDeps($this->deps);
220 if (!$oauth->validateToken($_REQUEST['oauth_token'])) {
221 return new ErrorResponse('Invalid token string');
224 $reqToken = $_REQUEST['oauth_token'];
227 $token = $this->deps->tokens->load('temp', $reqToken);
228 } catch (OAuthException $e) {
229 return new ErrorResponse($e->getMessage());
236 * Create and return a request token.
243 public function requestToken()
245 $oauth = new OAuth();
246 $oauth->setDeps($this->deps);
247 $urlGen = $this->deps->urlGen;
250 $provider = OAuth::getProvider();
251 $oauth->registerHandler($provider);
252 $provider->isRequestTokenEndpoint(true);
253 $provider->checkOAuthRequest(
254 $urlGen->getAbsoluteURL(
255 $urlGen->linkToRoute('grauphel.oauth.requestToken')
259 //store token + callback URI for later
260 $token = new Token('temp');
261 $token->tokenKey = 'r' . bin2hex($provider->generateToken(8));
262 $token->secret = 's' . bin2hex($provider->generateToken(8));
263 $token->callback = $provider->callback;
265 $this->deps->tokens->store($token);
267 return new FormResponse(
269 'oauth_token' => $token->tokenKey,
270 'oauth_token_secret' => $token->secret,
271 'oauth_callback_confirmed' => 'true'
274 } catch (OAuthException $e) {
275 return new ErrorResponse($e->getMessage());
276 } catch (\OAuthException $e) {