* @link http://cweiske.de/grauphel.htm
*/
namespace OCA\Grauphel\Controller;
+
use \OCP\AppFramework\Controller;
+use \OCP\AppFramework\Http;
+use \OCP\AppFramework\Http\RedirectResponse;
+use \OCP\AppFramework\Http\TemplateResponse;
+
+use \OCA\Grauphel\Lib\Client;
+use \OCA\Grauphel\Lib\Token;
+use \OCA\Grauphel\Lib\OAuth;
+use \OCA\Grauphel\Lib\Dependencies;
+use \OCA\Grauphel\Lib\Response\ErrorResponse;
+use \OCA\Grauphel\Lib\Response\FormResponse;
+use \OCA\Grauphel\Lib\OAuthException;
+use \OCA\Grauphel\Lib\UrlHelper;
/**
* OAuth handling
* @version Release: @package_version@
* @link http://cweiske.de/grauphel.htm
*/
-class OAuthController extends Controller
+class OauthController extends Controller
{
+ protected $user;
+
+ /**
+ * constructor of the controller
+ *
+ * @param string $appName Name of the app
+ * @param IRequest $request Instance of the request
+ */
+ public function __construct($appName, \OCP\IRequest $request, $user)
+ {
+ parent::__construct($appName, $request);
+ $this->user = $user;
+ $this->deps = Dependencies::get();
+
+ //default http header: we assume something is broken
+ header('HTTP/1.0 500 Internal Server Error');
+ }
+
/**
* Handle out an access token after verifying the verification token
* OAuth step 3 of 3
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
*/
- public function accessTokenAction()
+ public function accessToken()
{
$oauth = new OAuth();
$oauth->setDeps($this->deps);
+ $urlGen = $this->deps->urlGen;
try {
- $provider = new \OAuthProvider();
+ $provider = OAuth::getProvider();
$oauth->registerHandler($provider)
->registerVerificationTokenHandler($provider);
- $provider->checkOAuthRequest($this->deps->urlGen->oauthAccessToken());
+ $provider->checkOAuthRequest(
+ $urlGen->getAbsoluteURL(
+ $urlGen->linkToRoute('grauphel.oauth.accessToken')
+ )
+ );
$token = $this->deps->tokens->loadAndDelete('verify', $provider->token);
- $newToken = new OAuth_Token('access');
+ $newToken = new Token('access');
$newToken->tokenKey = 'a' . bin2hex($provider->generateToken(8));
$newToken->secret = 's' . bin2hex($provider->generateToken(8));
$newToken->user = $token->user;
+ $newToken->client = $token->client;
$this->deps->tokens->store($newToken);
- $this->deps->renderer->sendFormData(
+ return new FormResponse(
array(
'oauth_token' => $newToken->tokenKey,
'oauth_token_secret' => $newToken->secret,
)
);
- exit(0);
+ } catch (OAuthException $e) {
+ return new ErrorResponse($e->getMessage());
} catch (\OAuthException $e) {
$oauth->error($e);
}
/**
* Log the user in and let him authorize that the app may access notes
* OAuth step 2 of 3
+ *
+ * Page is not public and thus requires owncloud login
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
*/
- public function authorizeAction()
+ public function authorize()
{
- $oauth = new OAuth();
- $oauth->setDeps($this->deps);
-
- if (!isset($_REQUEST['oauth_token'])) {
- $this->deps->renderer->errorOut('oauth_token missing');
+ $token = $this->verifyRequestToken();
+ if (!$token instanceof Token) {
+ return $token;
}
- if (!$oauth->validateToken($_REQUEST['oauth_token'])) {
- $this->deps->renderer->errorOut('Invalid token string');
- }
-
- $reqToken = $_REQUEST['oauth_token'];
- try {
- $token = $this->deps->tokens->load('temp', $reqToken);
- } catch (OAuth_Exception $e) {
- $this->deps->renderer->errorOut($e->getMessage());
+ $clientTitle = 'unknown';
+ $clientAgent = '';
+ if (isset($_GET['client'])) {
+ $clientAgent = $_GET['client'];
+ $cl = new Client();
+ $clientTitle = $cl->getNiceName($clientAgent);
}
- $authState = $this->deps->frontend->doAuthorize(
- $this->deps->urlGen->current()
+ $res = new TemplateResponse('grauphel', 'oauthAuthorize');
+ $res->setParams(
+ array(
+ 'oauth_token' => $token->tokenKey,
+ 'clientTitle' => $clientTitle,
+ 'clientAgent' => $clientAgent,
+ 'formaction' => $this->deps->urlGen->linkToRoute(
+ 'grauphel.oauth.confirm'
+ ),
+ )
);
- if ($authState === null) {
- //this should not happen; doAuthorize() must block
- exit(1);
- }
+ return $res;
+ }
+
+ /**
+ * User confirms or declines the authorization request
+ * OAuth step 2.5 of 3
+ *
+ * @NoAdminRequired
+ */
+ public function confirm()
+ {
+ $token = $this->verifyRequestToken();
+ $oauth = new OAuth();
+ $oauth->setDeps($this->deps);
try {
- $token = $this->deps->tokens->loadAndDelete('temp', $reqToken);
- } catch (OAuth_Exception $e) {
- $this->deps->renderer->errorOut($e->getMessage());
+ $token = $this->deps->tokens->loadAndDelete('temp', $token->tokenKey);
+ } catch (OAuthException $e) {
+ return new ErrorResponse($e->getMessage());
}
+ $authState = isset($_POST['auth']) && $_POST['auth'] == 'ok';
if ($authState === false) {
//user declined
//http://wiki.oauth.net/w/page/12238543/ProblemReporting
- $callback = $this->deps->urlGen->addParams(
- $token->callback,
- array(
- 'oauth_token' => $token->tokenKey,
- 'oauth_problem' => 'permission_denied',
+ $res = new RedirectResponse(
+ UrlHelper::addParams(
+ $token->callback,
+ array(
+ 'oauth_token' => $token->tokenKey,
+ 'oauth_problem' => 'permission_denied',
+ )
)
);
- header('Location: ' . $callback, true, 302);
- exit(0);
+ $res->setStatus(Http::STATUS_SEE_OTHER);
+ return $res;
+ }
+
+ $clientAgent = '';
+ if (isset($_POST['client'])) {
+ $clientAgent = $_POST['client'];
}
//the user is logged in and authorized
- $provider = new \OAuthProvider();
+ $provider = OAuth::getProvider();
- $newToken = new OAuth_Token('verify');
+ $newToken = new Token('verify');
$newToken->tokenKey = $token->tokenKey;
$newToken->secret = $token->secret;
$newToken->verifier = 'v' . bin2hex($provider->generateToken(8));
- $newToken->user = $this->deps->frontend->getUser();
+ $newToken->user = $this->user->getUID();
+ $newToken->client = $clientAgent;
$this->deps->tokens->store($newToken);
//redirect
//FIXME: if no callback is given, show the token to the user
- $callback = $this->deps->urlGen->addParams(
- $token->callback,
- array(
- 'oauth_token' => $newToken->tokenKey,
- 'oauth_verifier' => $newToken->verifier
+ $res = new RedirectResponse(
+ UrlHelper::addParams(
+ $token->callback,
+ array(
+ 'oauth_token' => $newToken->tokenKey,
+ 'oauth_verifier' => $newToken->verifier
+ )
)
);
+ $res->setStatus(Http::STATUS_SEE_OTHER);
+ return $res;
+ }
+
+ protected function verifyRequestToken()
+ {
+ if (!isset($_REQUEST['oauth_token'])) {
+ return new ErrorResponse('oauth_token missing');
+ }
+
+ $oauth = new OAuth();
+ $oauth->setDeps($this->deps);
+ if (!$oauth->validateToken($_REQUEST['oauth_token'])) {
+ return new ErrorResponse('Invalid token string');
+ }
+
+ $reqToken = $_REQUEST['oauth_token'];
- header('Location: ' . $callback, true, 302);
- exit();
+ try {
+ $token = $this->deps->tokens->load('temp', $reqToken);
+ } catch (OAuthException $e) {
+ return new ErrorResponse($e->getMessage());
+ }
+
+ return $token;
}
/**
* Create and return a request token.
* OAuth step 1 of 3
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
*/
- public function requestTokenAction()
+ public function requestToken()
{
$oauth = new OAuth();
$oauth->setDeps($this->deps);
+ $urlGen = $this->deps->urlGen;
try {
- $provider = new \OAuthProvider();
+ $provider = OAuth::getProvider();
$oauth->registerHandler($provider);
$provider->isRequestTokenEndpoint(true);
- $provider->checkOAuthRequest($this->deps->urlGen->oauthRequestToken());
+ $provider->checkOAuthRequest(
+ $urlGen->getAbsoluteURL(
+ $urlGen->linkToRoute('grauphel.oauth.requestToken')
+ )
+ );
//store token + callback URI for later
- $token = new OAuth_Token('temp');
+ $token = new Token('temp');
$token->tokenKey = 'r' . bin2hex($provider->generateToken(8));
$token->secret = 's' . bin2hex($provider->generateToken(8));
$token->callback = $provider->callback;
$this->deps->tokens->store($token);
- $this->deps->renderer->sendFormData(
+ return new FormResponse(
array(
'oauth_token' => $token->tokenKey,
'oauth_token_secret' => $token->secret,
- 'oauth_callback_confirmed' => 'TRUE'
+ 'oauth_callback_confirmed' => 'true'
)
);
+ } catch (OAuthException $e) {
+ return new ErrorResponse($e->getMessage());
} catch (\OAuthException $e) {
$oauth->error($e);
}