<notnull>true</notnull>
<length>2048</length>
</field>
+ <field>
+ <name>token_client</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>256</length>
+ </field>
+ <field>
+ <name>token_lastuse</name>
+ <type>timestamp</type>
+ <notnull>true</notnull>
+ </field>
</declaration>
</table>
<id>grauphel</id>
<name>Grauphel: Tomboy note server</name>
<description>Tomboy REST API server to sync notes between devices</description>
- <version>0.2.0</version>
+ <version>0.3.0</version>
<licence>AGPL3 or later</licence>
<author>Christian Weiske</author>
<requiremin>7</requiremin>
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\JSONResponse;
+use \OCA\Grauphel\Lib\Client;
use \OCA\Grauphel\Lib\NoteStorage;
use \OCA\Grauphel\Lib\OAuth;
use \OCA\Grauphel\Lib\OAuthException;
'api-version' => '1.0',
);
- $client = $this->getClient();
+ $cl = new Client();
+ $client = $cl->getClient();
if ($client !== false) {
- $data['oauth_authorize_url'] .= '?client='
- . urlencode($this->getNiceClientName($client));
+ $data['oauth_authorize_url'] .= '?client=' . urlencode($client);
}
if ($authenticated) {
return new JSONResponse($note);
}
- protected function getClient()
- {
- if (isset($_SERVER['HTTP_X_TOMBOY_CLIENT'])) {
- $client = $_SERVER['HTTP_X_TOMBOY_CLIENT'];
- $doublepos = strpos($client, ', org.tomdroid');
- if ($doublepos !== false) {
- //https://bugs.launchpad.net/tomdroid/+bug/1375436
- //X-Tomboy-Client header is sent twice
- $client = substr($client, 0, $doublepos);
- }
- return $client;
- }
-
- return false;
- }
-
- protected function getNiceClientName($client)
- {
- if (substr($client, 0, 12) == 'org.tomdroid') {
- //org.tomdroid v0.7.5, build 14, Android v4.4.2, innotek GmbH/VirtualBox
- return 'Tomdroid';
- }
- return $client;
- }
-
/**
* Checks if the given user is authorized (by oauth token or normal login)
*
use \OCP\AppFramework\Controller;
use \OCP\AppFramework\Http\TemplateResponse;
+use \OCA\Grauphel\Lib\Client;
use \OCA\Grauphel\Lib\TokenStorage;
/**
array(
'tokens' => $tokens->loadForUser(
$this->user->getUid(), 'access'
- )
+ ),
+ 'client' => new Client(),
)
);
$this->addNavigation($res, null);
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;
$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);
return new FormResponse(
return $token;
}
- $client = 'unknown';
+ $clientTitle = 'unknown';
+ $clientAgent = '';
if (isset($_GET['client'])) {
- $client = $_GET['client'];
+ $clientAgent = $_GET['client'];
+ $cl = new Client();
+ $clientTitle = $cl->getNiceName($clientAgent);
}
$res = new TemplateResponse('grauphel', 'oauthAuthorize');
$res->setParams(
array(
'oauth_token' => $token->tokenKey,
- 'client' => $client,
+ 'client' => $clientTitle,
'formaction' => $this->deps->urlGen->linkToRoute(
'grauphel.oauth.confirm'
- ),
+ ) . '?client=' . urlencode($clientAgent),
)
);
return $res;
return $res;
}
+ $clientAgent = '';
+ if (isset($_GET['client'])) {
+ $clientAgent = $_GET['client'];
+ }
+
//the user is logged in and authorized
$provider = OAuth::getProvider();
$newToken->secret = $token->secret;
$newToken->verifier = 'v' . bin2hex($provider->generateToken(8));
$newToken->user = $this->user->getUID();
+ $newToken->client = $clientAgent;
$this->deps->tokens->store($newToken);
--- /dev/null
+<?php
+/**
+ * Part of grauphel
+ *
+ * PHP version 5
+ *
+ * @category Tools
+ * @package Grauphel
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @link http://cweiske.de/grauphel.htm
+ */
+namespace OCA\Grauphel\Lib;
+
+/**
+ * Client identification helper
+ *
+ * @category Tools
+ * @package Grauphel
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @version Release: @package_version@
+ * @link http://cweiske.de/grauphel.htm
+ */
+class Client
+{
+ public function getClient()
+ {
+ if (isset($_SERVER['HTTP_X_TOMBOY_CLIENT'])) {
+ $client = $_SERVER['HTTP_X_TOMBOY_CLIENT'];
+ $doublepos = strpos($client, ', org.tomdroid');
+ if ($doublepos !== false) {
+ //https://bugs.launchpad.net/tomdroid/+bug/1375436
+ //X-Tomboy-Client header is sent twice
+ $client = substr($client, 0, $doublepos);
+ }
+ return $client;
+ }
+
+ return false;
+ }
+
+ public function getNiceName($client)
+ {
+ if (substr($client, 0, 12) == 'org.tomdroid') {
+ //org.tomdroid v0.7.5, build 14, Android v4.4.2, innotek GmbH/VirtualBox
+ return 'Tomdroid';
+ }
+ return $client;
+ }
+
+}
+?>
\ No newline at end of file
}
throw $e;
}
+
+ if (time() - $token->lastuse > 60) {
+ //time to update lastuse after at least a minute
+ $this->tokens->updateLastUse($token->tokenKey);
+ }
+
$provider->token_secret = $token->secret;
return OAUTH_OK;
}
/**
* Get a new oauth provider instance.
* Used to work around the fastcgi bug in oauthprovider.
- *
+ *
* @return \OAuthProvider
*/
public static function getProvider()
*/
public $callback;
+ /**
+ * Client name/identifier (user agent)
+ *
+ * @var string
+ */
+ public $client;
+
+ /**
+ * Unix timestamp when the token was used last
+ *
+ * @var integer
+ */
+ public $lastuse;
+
public function __construct($type = null)
{
$this->type = $type;
{
\OC_DB::executeAudited(
'INSERT INTO `*PREFIX*grauphel_oauth_tokens`'
- . '(`token_user`, `token_type`, `token_key`, `token_secret`, `token_verifier`, `token_callback`)'
- . ' VALUES(?, ?, ?, ?, ?, ?)',
+ . '(`token_user`, `token_type`, `token_key`, `token_secret`, `token_verifier`, `token_callback`, `token_client`, `token_lastuse`)'
+ . ' VALUES(?, ?, ?, ?, ?, ?, ?, ?)',
array(
$token->user,
$token->type,
$token->tokenKey,
(string) $token->secret,
(string) $token->verifier,
- (string) $token->callback
+ (string) $token->callback,
+ (string) $token->client,
+ (string) date('c'),
)
);
}
return $tokens;
}
+ /**
+ * Update the "last use" field of a token
+ *
+ * @param string $tokenKey Random token string to load
+ *
+ * @return void
+ */
+ public function updateLastUse($tokenKey)
+ {
+ \OC_DB::executeAudited(
+ 'UPDATE `*PREFIX*grauphel_oauth_tokens`'
+ . ' SET `token_lastuse` = ? WHERE `token_key` = ?',
+ array(
+ (string) date('c'),
+ $tokenKey,
+ )
+ );
+ }
+
protected function fromDb($tokenRow)
{
$token = new Token();
$token->user = $tokenRow['token_user'];
$token->verifier = $tokenRow['token_verifier'];
$token->callback = $tokenRow['token_callback'];
+ $token->client = $tokenRow['token_client'];
+ $token->lastuse = \strtotime($tokenRow['token_lastuse']);
return $token;
}
}
<?php foreach ($_['tokens'] as $token) { ?>
<tr>
<td><?php p($token->tokenKey); ?></td>
- <td></td>
- <td></td>
+ <td title="<?php p($token->client); ?>"><?php p($_['client']->getNiceName($token->client)); ?></td>
+ <td><?php p(\OCP\Util::formatDate($token->lastuse)); ?></td>
<td>Disable Delete</td>
</tr>
<?php } ?>