Permalink
Browse files

Refactor KeystoreAuthFrontend to use core service ApiKeysService.

  • Loading branch information...
1 parent afe8e12 commit 9ef272c9f05dc4a0ccf196d2109c899d9476c86a @cdujeu cdujeu committed Aug 25, 2016
@@ -0,0 +1,173 @@
+<?php
+/*
+ * Copyright 2007-2016 Abstrium <contact (at) pydio.com>
+ * This file is part of Pydio.
+ *
+ * Pydio is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Pydio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Pydio. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The latest code can be found at <https://pydio.com/>.
+ */
+namespace Pydio\Core\Services;
+
+use Pydio\Conf\Sql\SqlConfDriver;
+use Pydio\Core\Exception\PydioException;
+use Pydio\Core\Utils\Http\UserAgent;
+use Pydio\Core\Utils\Vars\StringHelper;
+
+defined('AJXP_EXEC') or die('Access not allowed');
+
+/**
+ * Class ApiKeysService
+ * @package Pydio\Core\Services
+ */
+class ApiKeysService
+{
+ /**
+ * @return SqlConfDriver
+ * @throws PydioException
+ */
+ private static function getStore(){
+ $store = ConfService::getConfStorageImpl();
+ if (!($store instanceof SqlConfDriver)){
+ throw new PydioException("Wrong configuration driver, please use Sql");
+ }
+ return $store;
+ }
+
+ /**
+ * @param $userId
+ * @param string $deviceId
+ * @param string $deviceUA
+ * @param string $deviceIP
+ * @return array
+ * @throws PydioException
+ * @throws \Exception
+ */
+ public static function generatePairForAuthfront($userId, $deviceId = "", $deviceUA = "", $deviceIP = ""){
+
+ $store = self::getStore();
+ $token = StringHelper::generateRandomString();
+ $private = StringHelper::generateRandomString();
+ $data = array("USER_ID" => $userId, "PRIVATE" => $private);
+ if (!empty($deviceId)) {
+ // Revoke previous tokens for this device
+ $cursor = null;
+ $keys = $store->simpleStoreList("keystore", $cursor, "", "serial", '%"DEVICE_ID";s:' . strlen($deviceId) . ':"' . $deviceId . '"%');
+ foreach ($keys as $keyId => $keyData) {
+ if ($keyData["USER_ID"] != $userId) continue;
+ $store->simpleStoreClear("keystore", $keyId);
+ }
+ $data["DEVICE_ID"] = $deviceId;
+ }
+ $data["DEVICE_UA"] = $deviceUA;
+ $data["DEVICE_IP"] = $deviceIP;
+ $store->simpleStoreSet("keystore", $token, $data, "serial");
+ return ["t" => $token, "p" => $private];
+
+ }
+
+ /**
+ * @param $userId
+ * @param $deviceId
+ * @param string $restrictToIP
+ * @return array
+ * @throws PydioException
+ * @throws \Exception
+ */
+ public static function generatePairForAdminTasks($userId, $deviceId, $restrictToIP = ""){
+
+ $store = self::getStore();
+ $token = StringHelper::generateRandomString();
+ $private = StringHelper::generateRandomString();
+ $data = [
+ "USER_ID" => $userId,
+ "PRIVATE" => $private,
+ "DEVICE_ID" => $deviceId
+ ];
+ if(!empty($restrictToIP)){
+ $data["RESTRICT_TO_IP"] = $restrictToIP;
+ }
+ $store->simpleStoreSet("keystore", $token, $data, "serial");
+ return ["t" => $token, "p" => $private];
+
+ }
+
+ /**
+ * @param $token
+ * @param string $checkPrivate
+ * @return bool
+ * @throws PydioException
+ */
+ public static function loadDataForPair($token, $checkPrivate = ""){
+ $data = null;
+ self::getStore()->simpleStoreGet("keystore", $token, "serial", $data);
+ if (empty($data)) {
+ return false;
+ }
+ if(!empty($checkPrivate)){
+ $p = $data["PRIVATE"];
+ unset($data["PRIVATE"]);
+ return $checkPrivate === $p ? $data : false;
+ }
+ return $data;
+ }
+
+ /**
+ * @param $userId
+ * @param $token
+ * @return int
+ * @throws PydioException
+ */
+ public static function revokeTokens($userId, $token = ""){
+ $keys = self::getStore()->simpleStoreList("keystore", $cursor, $token, "serial", '%"USER_ID";s:' . strlen($userId) . ':"' . $userId . '"%');
+ $c = 0;
+ foreach ($keys as $keyId => $keyData) {
+ $c ++;
+ self::getStore()->simpleStoreClear("keystore", $keyId);
+ }
+ return $c;
+ }
+
+ /**
+ * @param $userId
+ * @return array
+ * @throws PydioException
+ */
+ public static function listPairsForUser($userId){
+ $cursor = null;
+ $keys = self::getStore()->simpleStoreList("keystore", $cursor, "", "serial", '%"USER_ID";s:' . strlen($userId) . ':"' . $userId . '"%');
+ foreach ($keys as $keyId => &$keyData) {
+ unset($keyData["PRIVATE"]);
+ unset($keyData["USER_ID"]);
+ $deviceDesc = "Web Browser";
+ $deviceOS = "Unkown";
+ if (isSet($keyData["DEVICE_UA"])) {
+ $agent = $keyData["DEVICE_UA"];
+ if (strpos($agent, "python-requests") !== false) {
+ $deviceDesc = "PydioSync";
+ if (strpos($agent, "Darwin") !== false) $deviceOS = "Mac OS X";
+ else if (strpos($agent, "Windows/7") !== false) $deviceOS = "Windows 7";
+ else if (strpos($agent, "Windows/8") !== false) $deviceOS = "Windows 8";
+ else if (strpos($agent, "Linux") !== false) $deviceOS = "Linux";
+ } else {
+ $deviceOS = UserAgent::osFromUserAgent($agent);
+ }
+ }
+ $keyData["DEVICE_DESC"] = $deviceDesc;
+ $keyData["DEVICE_OS"] = $deviceOS;
+ }
+ return $keys;
+ }
+
+}
@@ -45,7 +45,7 @@
<clientForm id="scheduler_cronExpression"><![CDATA[
<div id="scheduler_cronExpression" box_width="420">
<div class="dialogLegend" ajxp_message_id="action.scheduler.21">AJXP_MESSAGE[action.scheduler.21]</div>
- <textarea class="dialogFocus" style="width:400px;height:80px; margin-top: 5px;" id="cron_expression"></textarea>
+ <textarea class="dialogFocus" style="width:350px;height:80px; margin-top: 5px;" id="cron_expression"></textarea>
</div>
]]></clientForm>
<serverCallback methodName="switchAction" developerComment="Generate a correct expression to be inserted in Crontab, in order to trigger the {runAll} action on a regular basis."/>
@@ -21,8 +21,12 @@
namespace Pydio\Auth\Frontend;
use Exception;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Pydio\Core\Exception\PydioException;
use Pydio\Core\Model\Context;
use Pydio\Core\Model\ContextInterface;
+use Pydio\Core\Services\ApiKeysService;
use Pydio\Core\Services\AuthService;
use Pydio\Auth\Frontend\Core\AbstractAuthFrontend;
use Pydio\Core\Services\ConfService;
@@ -32,6 +36,7 @@
use Pydio\Core\Utils\Vars\StringHelper;
use Pydio\Core\Utils\Http\UserAgent;
use Pydio\Core\Controller\HTMLWriter;
+use Zend\Diactoros\Response\JsonResponse;
defined('AJXP_EXEC') or die('Access not allowed');
@@ -74,16 +79,12 @@ function tryToLogUser(\Psr\Http\Message\ServerRequestInterface &$request, \Psr\H
//$this->logDebug(__FUNCTION__, "Empty token", $_POST);
return false;
}
- $this->storage = ConfService::getConfStorageImpl();
- if (!($this->storage instanceof \Pydio\Conf\Sql\SqlConfDriver)) return false;
- $data = null;
- $this->storage->simpleStoreGet("keystore", $token, "serial", $data);
- if (empty($data)) {
- //$this->logDebug(__FUNCTION__, "Cannot find token in keystore");
+ $data = ApiKeysService::loadDataForPair($token);
+ if($data === false){
+ $this->logDebug(__FUNCTION__, "Cannot find token in keystore");
return false;
}
- //$this->logDebug(__FUNCTION__, "Found token in keystore");
$userId = $data["USER_ID"];
$private = $data["PRIVATE"];
$explode = explode("?", $_SERVER["REQUEST_URI"]);
@@ -118,31 +119,24 @@ function tryToLogUser(\Psr\Http\Message\ServerRequestInterface &$request, \Psr\H
*/
public function revokeUserTokens(ContextInterface $ctx, $userId)
{
-
- $this->storage = ConfService::getConfStorageImpl();
- if (!($this->storage instanceof \Pydio\Conf\Sql\SqlConfDriver)) return false;
- $cursor = null;
- $keys = $this->storage->simpleStoreList("keystore", $cursor, "", "serial", '%"USER_ID";s:' . strlen($userId) . ':"' . $userId . '"%');
- foreach ($keys as $keyId => $keyData) {
- $this->storage->simpleStoreClear("keystore", $keyId);
- }
- if (count($keys)) {
- $this->logInfo(__FUNCTION__, "Revoking " . count($keys) . " keys for user '" . $userId . "' on password change action.");
- }
- return null;
+ try{
+ $count = ApiKeysService::revokeTokens($userId);
+ $this->logInfo(__FUNCTION__, "Revoking " . $count . " keys for user '" . $userId . "' on user modification action.");
+ }catch (PydioException $e){}
}
/**
- * @param String $action
- * @param array $httpVars
- * @param array $fileVars
- * @param ContextInterface $ctx
+ * @param ServerRequestInterface $requestInterface
+ * @param ResponseInterface $responseInterface
* @return String
- * @throws Exception
*/
- function authTokenActions($action, $httpVars, $fileVars, ContextInterface $ctx)
+ function authTokenActions(ServerRequestInterface $requestInterface, ResponseInterface &$responseInterface)
{
-
+ /** @var ContextInterface $ctx */
+ $ctx = $requestInterface->getAttribute("ctx");
+ $action = $requestInterface->getAttribute("action");
+ $httpVars = $requestInterface->getParsedBody();
+
if (!$ctx->hasUser()) {
return null;
}
@@ -164,29 +158,9 @@ function authTokenActions($action, $httpVars, $fileVars, ContextInterface $ctx)
echo "";
break;
}
-
- $token = StringHelper::generateRandomString();
- $private = StringHelper::generateRandomString();
- $data = array("USER_ID" => $user, "PRIVATE" => $private);
- if (!empty($httpVars["device"])) {
- // Revoke previous tokens for this device
- $device = $httpVars["device"];
- $cursor = null;
- $keys = $this->storage->simpleStoreList("keystore", $cursor, "", "serial", '%"DEVICE_ID";s:' . strlen($device) . ':"' . $device . '"%');
- foreach ($keys as $keyId => $keyData) {
- if ($keyData["USER_ID"] != $user) continue;
- $this->storage->simpleStoreClear("keystore", $keyId);
- }
- $data["DEVICE_ID"] = $device;
- }
- $data["DEVICE_UA"] = $_SERVER['HTTP_USER_AGENT'];
- $data["DEVICE_IP"] = $_SERVER['REMOTE_ADDR'];
- $this->storage->simpleStoreSet("keystore", $token, $data, "serial");
- HTMLWriter::charsetHeader("application/json");
- echo(json_encode(array(
- "t" => $token,
- "p" => $private)
- ));
+ $device = (isSet($httpVars["device"]) ? InputFilter::sanitize($httpVars["device"], InputFilter::SANITIZE_ALPHANUM) : "");
+ $tokenPair = ApiKeysService::generatePairForAuthfront($user, $device, $_SERVER["HTTP_USER_AGENT"], $_SERVER["REMOTE_ADDR"]);
+ $responseInterface = new JsonResponse($tokenPair);
break;
@@ -196,45 +170,19 @@ function authTokenActions($action, $httpVars, $fileVars, ContextInterface $ctx)
$mess = LocaleService::getMessages();
$passedKeyId = "";
if (isSet($httpVars["key_id"])) $passedKeyId = $httpVars["key_id"];
- $cursor = null;
- $keys = $this->storage->simpleStoreList("keystore", $cursor, $passedKeyId, "serial", '%"USER_ID";s:' . strlen($user) . ':"' . $user . '"%');
- foreach ($keys as $keyId => $keyData) {
- $this->storage->simpleStoreClear("keystore", $keyId);
- }
- $message = array(
+ $r = ApiKeysService::revokeTokens($user, $passedKeyId);
+ $responseInterface = new JsonResponse([
"result" => "SUCCESS",
"message" => $mess["keystore.8"]
- );
- HTMLWriter::charsetHeader("application/json");
- echo json_encode($message);
+ ]);
break;
case "keystore_list_tokens":
+
if (!isSet($user)) break;
- $cursor = null;
- $keys = $this->storage->simpleStoreList("keystore", $cursor, "", "serial", '%"USER_ID";s:' . strlen($user) . ':"' . $user . '"%');
- foreach ($keys as $keyId => &$keyData) {
- unset($keyData["PRIVATE"]);
- unset($keyData["USER_ID"]);
- $deviceDesc = "Web Browser";
- $deviceOS = "Unkown";
- if (isSet($keyData["DEVICE_UA"])) {
- $agent = $keyData["DEVICE_UA"];
- if (strpos($agent, "python-requests") !== false) {
- $deviceDesc = "PydioSync";
- if (strpos($agent, "Darwin") !== false) $deviceOS = "Mac OS X";
- else if (strpos($agent, "Windows/7") !== false) $deviceOS = "Windows 7";
- else if (strpos($agent, "Windows/8") !== false) $deviceOS = "Windows 8";
- else if (strpos($agent, "Linux") !== false) $deviceOS = "Linux";
- } else {
- $deviceOS = UserAgent::osFromUserAgent($agent);
- }
- }
- $keyData["DEVICE_DESC"] = $deviceDesc;
- $keyData["DEVICE_OS"] = $deviceOS;
- }
- header("Content-type: application/json;");
- echo json_encode($keys);
+
+ $keys = ApiKeysService::listPairsForUser($user);
+ $responseInterface = new JsonResponse($keys);
break;

0 comments on commit 9ef272c

Please sign in to comment.