diff --git a/lib/private/Authentication/Token/DefaultToken.php b/lib/private/Authentication/Token/DefaultToken.php index ca4c723fba3a..4a64eacb247a 100644 --- a/lib/private/Authentication/Token/DefaultToken.php +++ b/lib/private/Authentication/Token/DefaultToken.php @@ -22,14 +22,12 @@ namespace OC\Authentication\Token; -use JsonSerializable; use OCP\AppFramework\Db\Entity; /** * @method void setId(int $id) * @method void setUid(string $uid); * @method void setPassword(string $password) - * @method string getPassword() * @method void setName(string $name) * @method string getName() * @method void setToken(string $token) @@ -39,7 +37,7 @@ * @method void setLastActivity(int $lastActivity) * @method int getLastActivity() */ -class DefaultToken extends Entity implements IToken, JsonSerializable { +class DefaultToken extends Entity implements IToken { /** * @var string user UID diff --git a/lib/private/Authentication/Token/DefaultTokenMapper.php b/lib/private/Authentication/Token/DefaultTokenMapper.php index 9f1735712705..970c2242dbe8 100644 --- a/lib/private/Authentication/Token/DefaultTokenMapper.php +++ b/lib/private/Authentication/Token/DefaultTokenMapper.php @@ -111,4 +111,17 @@ public function getTokenByUser(IUser $user) { return $entities; } + /** + * @param IUser $user + * @param int $id + */ + public function deleteById(IUser $user, $id) { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->delete('authtoken') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID()))); + $qb->execute(); + } + } diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index 3527f4155a9f..0f7c54dab572 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -150,6 +150,16 @@ public function invalidateToken($token) { $this->mapper->invalidate($this->hashToken($token)); } + /** + * Invalidate (delete) the given token + * + * @param IUser $user + * @param int $id + */ + public function invalidateTokenById(IUser $user, $id) { + $this->mapper->deleteById($user, $id); + } + /** * Invalidate (delete) old session tokens */ diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index b8648dda5b75..e4e4581e738a 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -47,7 +47,7 @@ public function generateToken($token, $uid, $password, $name, $type = IToken::TE * @return IToken */ public function getToken($tokenId) ; - + /** * @param string $token * @throws InvalidTokenException @@ -62,6 +62,14 @@ public function validateToken($token); */ public function invalidateToken($token); + /** + * Invalidate (delete) the given token + * + * @param IUser $user + * @param int $id + */ + public function invalidateTokenById(IUser $user, $id); + /** * Update token activity timestamp * diff --git a/lib/private/Authentication/Token/IToken.php b/lib/private/Authentication/Token/IToken.php index 2a01ea75ea95..b741cd4ac22c 100644 --- a/lib/private/Authentication/Token/IToken.php +++ b/lib/private/Authentication/Token/IToken.php @@ -22,7 +22,9 @@ namespace OC\Authentication\Token; -interface IToken { +use JsonSerializable; + +interface IToken extends JsonSerializable { const TEMPORARY_TOKEN = 0; const PERMANENT_TOKEN = 1; @@ -30,7 +32,7 @@ interface IToken { /** * Get the token ID * - * @return string + * @return int */ public function getId(); diff --git a/settings/Controller/AuthSettingsController.php b/settings/Controller/AuthSettingsController.php index 71868b7688d2..75311920d2a1 100644 --- a/settings/Controller/AuthSettingsController.php +++ b/settings/Controller/AuthSettingsController.php @@ -60,7 +60,8 @@ class AuthSettingsController extends Controller { * @param ISecureRandom $random * @param string $uid */ - public function __construct($appName, IRequest $request, IProvider $tokenProvider, IUserManager $userManager, ISession $session, ISecureRandom $random, $uid) { + public function __construct($appName, IRequest $request, IProvider $tokenProvider, IUserManager $userManager, + ISession $session, ISecureRandom $random, $uid) { parent::__construct($appName, $request); $this->tokenProvider = $tokenProvider; $this->userManager = $userManager; @@ -131,4 +132,20 @@ private function generateRandomDeviceToken() { return implode('-', $groups); } + /** + * @NoAdminRequired + * @NoSubadminRequired + * + * @return JSONResponse + */ + public function destroy($id) { + $user = $this->userManager->get($this->uid); + if (is_null($user)) { + return []; + } + + $this->tokenProvider->invalidateTokenById($user, $id); + return []; + } + } diff --git a/settings/css/settings.css b/settings/css/settings.css index 418c5f955172..7dd6977e4411 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -114,12 +114,17 @@ table.nostyle td { padding: 0.2em 0; } #sessions table td, #devices table th, #devices table td { - padding: 10px; + padding: 10px; } #sessions .token-list td, #devices .token-list td { - border-top: 1px solid #DDD; + border-top: 1px solid #DDD; +} +#sessions .token-list td a.icon-delete, +#devices .token-list td a.icon-delete { + display: block; + opacity: 0.6; } #device-new-token { diff --git a/settings/js/authtoken_view.js b/settings/js/authtoken_view.js index 8ca38d80d84f..31955ffa7e52 100644 --- a/settings/js/authtoken_view.js +++ b/settings/js/authtoken_view.js @@ -26,9 +26,10 @@ OC.Settings = OC.Settings || {}; var TEMPLATE_TOKEN = - '