diff --git a/customer_ftp.php b/customer_ftp.php index 474ea057..b2131b07 100644 --- a/customer_ftp.php +++ b/customer_ftp.php @@ -171,74 +171,11 @@ if ($page == 'overview') { if (isset($result['username']) && $result['username'] != '') { if (isset($_POST['send']) && $_POST['send'] == 'send') { - // @FIXME use a good path-validating regex here (refs #1231) - $path = validate($_POST['path'], 'path'); - - $shell = "/bin/false"; - if (Settings::Get('system.allow_customer_shell') == '1') { - $shell = isset($_POST['shell']) ? validate($_POST['shell'], 'shell') : '/bin/false'; + try { + Ftps::getLocal($userinfo, $_POST)->update(); + } catch (Exception $e) { + dynamic_error($e->getMessage()); } - - $_setnewpass = false; - if (isset($_POST['ftp_password']) && $_POST['ftp_password'] != '') { - $password = validate($_POST['ftp_password'], 'password'); - $password = validatePassword($password); - $_setnewpass = true; - } - - if ($_setnewpass) { - if ($password == '') { - standard_error(array('stringisempty', 'mypassword')); - } elseif ($result['username'] == $password) { - standard_error('passwordshouldnotbeusername'); - } - $log->logAction(USR_ACTION, LOG_INFO, "updated ftp-account password for '" . $result['username'] . "'"); - $cryptPassword = makeCryptPassword($password); - - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `password` = :password - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("customerid" => $userinfo['customerid'], "id" => $id, "password" => $cryptPassword)); - } - - if ($path != '') { - $path = makeCorrectDir($userinfo['documentroot'] . '/' . $path); - - if ($path != $result['homedir']) { - if (!file_exists($path)) { - // it's the task for "new ftp" but that will - // create all directories and correct their permissions - inserttask(5); - } - - $log->logAction(USR_ACTION, LOG_INFO, "updated ftp-account homdir for '" . $result['username'] . "'"); - - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `homedir` = :homedir - WHERE `customerid` = :customerid - AND `id` = :id" - ); - $params = array( - "homedir" => $path, - "customerid" => $userinfo['customerid'], - "id" => $id - ); - Database::pexecute($stmt, $params); - } - } - - $log->logAction(USR_ACTION, LOG_INFO, "edited ftp-account '" . $result['username'] . "'"); - inserttask(5); - $description = validate($_POST['ftp_description'], 'description'); - $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` - SET `description` = :desc, `shell` = :shell - WHERE `customerid` = :customerid - AND `id` = :id" - ); - Database::pexecute($stmt, array("desc" => $description, "shell" => $shell, "customerid" => $userinfo['customerid'], "id" => $id)); - redirectTo($filename, array('page' => $page, 's' => $s)); } else { if (strpos($result['homedir'], $userinfo['documentroot']) === 0) { diff --git a/lib/classes/api/commands/class.Ftps.php b/lib/classes/api/commands/class.Ftps.php index 226de773..a723080e 100644 --- a/lib/classes/api/commands/class.Ftps.php +++ b/lib/classes/api/commands/class.Ftps.php @@ -80,7 +80,7 @@ class Ftps extends ApiCommand implements ResourceEntity } $params = array(); - // get needed customer info to reduce the mysql-usage-counter by one + // get needed customer info to reduce the ftp-user-counter by one if ($this->isAdmin()) { // get customer id $customer_id = $this->getParam('customer_id'); @@ -88,7 +88,7 @@ class Ftps extends ApiCommand implements ResourceEntity 'id' => $customer_id ))->get(); $customer = json_decode($json_result, true)['data']; - // check whether the customer has enough resources to get the database added + // check whether the customer has enough resources to get the ftp-user added if ($customer['ftps_used'] >= $customer['ftps'] && $customer['ftps'] != '-1') { throw new Exception("Customer has no more resources available", 406); } @@ -133,11 +133,6 @@ class Ftps extends ApiCommand implements ResourceEntity if (! empty($username_check) && $username_check['username'] = $username) { standard_error('usernamealreadyexists', $username, true); - } elseif ($password == '') { - standard_error(array( - 'stringisempty', - 'mypassword' - ), '', true); } elseif ($username == $password) { standard_error('passwordshouldnotbeusername', '', true); } else { @@ -346,7 +341,117 @@ class Ftps extends ApiCommand implements ResourceEntity } public function update() - {} + { + if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'ftp')) { + throw new Exception("You cannot access this resource", 405); + } + + $id = $this->getParam('id', true, 0); + $un_optional = ($id <= 0 ? false : true); + $username = $this->getParam('username', $un_optional, ''); + + $json_result = Ftps::getLocal($this->getUserData(), array( + 'id' => $id, + 'username' => $username + ))->get(); + $result = json_decode($json_result, true)['data']; + $id = $result['id']; + + // parameters + $path = $this->getParam('path', true, ''); + $password = $this->getParam('ftp_password', true, ''); + $description = $this->getParam('ftp_description', true, $result['description']); + $shell = $this->getParam('shell', true, $result['shell']); + + // validation + $password = validate($password, 'password', '', '', array(), true); + $description = validate(trim($description), 'description', '', '', array(), true); + + if (Settings::Get('system.allow_customer_shell') == '1') { + $shell = validate(trim($shell), 'shell', '', '', array(), true); + } else { + $shell = "/bin/false"; + } + + $params = array(); + // get needed customer info to reduce the ftp-user-counter by one + if ($this->isAdmin()) { + // get customer id + $customer_id = $this->getParam('customer_id'); + $json_result = Customers::getLocal($this->getUserData(), array( + 'id' => $customer_id + ))->get(); + $customer = json_decode($json_result, true)['data']; + } else { + $customer_id = $this->getUserDetail('customerid'); + $customer = $this->getUserData(); + } + + // password update? + if ($password != '') { + // validate password + $password = validatePassword($password, true); + + if ($password == $result['username']) { + standard_error('passwordshouldnotbeusername', '', true); + } + $cryptPassword = makeCryptPassword($password); + + $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` + SET `password` = :password + WHERE `customerid` = :customerid + AND `id` = :id + "); + Database::pexecute($stmt, array( + "customerid" => $customer['customerid'], + "id" => $id, + "password" => $cryptPassword + ), true, true); + $this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated ftp-account password for '" . $result['username'] . "'"); + } + + // path update? + if ($path != '') { + $path = makeCorrectDir($customer['documentroot'] . '/' . $path); + + if ($path != $result['homedir']) { + $stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "` + SET `homedir` = :homedir + WHERE `customerid` = :customerid + AND `id` = :id + "); + Database::pexecute($stmt, array( + "homedir" => $path, + "customerid" => $customer['customerid'], + "id" => $id + ), true, true); + $this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] updated ftp-account homdir for '" . $result['username'] . "'"); + } + } + // it's the task for "new ftp" but that will + // create all directories and correct their permissions + inserttask(5); + + $stmt = Database::prepare(" + UPDATE `" . TABLE_FTP_USERS . "` + SET `description` = :desc, `shell` = :shell + WHERE `customerid` = :customerid + AND `id` = :id + "); + Database::pexecute($stmt, array( + "desc" => $description, + "shell" => $shell, + "customerid" => $customer['customerid'], + "id" => $id + ), true, true); + + $json_result = Ftps::getLocal($this->getUserData(), array( + 'username' => $result['username'] + ))->get(); + $result = json_decode($json_result, true)['data']; + $this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'"); + return $this->response(200, "successfull", $result); + } /** * list all ftp-users, if called from an admin, list all ftp-users of all customers you are allowed to view, or specify id or loginname for one specific customer @@ -496,7 +601,7 @@ class Ftps extends ApiCommand implements ResourceEntity "username" => "," . $result['username'], "customerid" => $customer_data['customerid'] ), true, true); - + // refs #293 if ($delete_userfiles == 1) { inserttask('8', $customer_data['loginname'], $result['homedir']); diff --git a/lib/classes/api/commands/class.Mysqls.php b/lib/classes/api/commands/class.Mysqls.php index 5811477f..0d043d6d 100644 --- a/lib/classes/api/commands/class.Mysqls.php +++ b/lib/classes/api/commands/class.Mysqls.php @@ -363,7 +363,6 @@ class Mysqls extends ApiCommand implements ResourceEntity // validation $password = validate($password, 'password', '', '', array(), true); - $password = validatePassword($password, true); $databasedescription = validate(trim($databasedescription), 'description', '', '', array(), true); // validate whether the dbserver exists diff --git a/tests/Ftps/FtpsTest.php b/tests/Ftps/FtpsTest.php index 2b2165ee..d9d185a3 100644 --- a/tests/Ftps/FtpsTest.php +++ b/tests/Ftps/FtpsTest.php @@ -21,6 +21,22 @@ class FtpsTest extends TestCase $this->assertEquals('test1', $result['username']); } + public function testResellerFtpsGetId() + { + global $admin_userdata; + // get reseller + $json_result = Admins::getLocal($admin_userdata, array( + 'loginname' => 'reseller' + ))->get(); + $reseller_userdata = json_decode($json_result, true)['data']; + $reseller_userdata['adminsession'] = 1; + $json_result = Ftps::getLocal($reseller_userdata, array( + 'id' => 1 + ))->get(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals('test1', $result['username']); + } + public function testCustomerFtpsGetId() { global $admin_userdata; @@ -104,4 +120,151 @@ class FtpsTest extends TestCase $this->assertEquals(1, $result['count']); $this->assertEquals('test1', $result['list'][0]['username']); } + + public function testCustomerFtpsAdd() + { + global $admin_userdata; + + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + + $data = [ + 'ftp_password' => 'h4xXx0r', + 'path' => '/', + 'ftp_description' => 'testing', + 'sendinfomail' => 1 + ]; + $json_result = Ftps::getLocal($customer_userdata, $data)->add(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals($customer_userdata['documentroot'], $result['homedir']); + } + + public function testCustomerFtpsAddNoMoreResources() + { + global $admin_userdata; + + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data'];# + + $customer_userdata['ftps_used'] = 100; + + $this->expectExceptionCode(406); + $this->expectExceptionMessage('No more resources available'); + $json_result = Ftps::getLocal($customer_userdata)->add(); + } + + public function testAdminFtpsAddCustomerRequired() + { + global $admin_userdata; + + $data = [ + 'ftp_password' => 'h4xXx0r', + 'path' => '/', + 'ftp_description' => 'testing', + 'sendinfomail' => 1 + ]; + + $this->expectExceptionCode(404); + $this->expectExceptionMessage('Requested parameter "customer_id" could not be found for "Ftps:add"'); + $json_result = Ftps::getLocal($admin_userdata, $data)->add(); + } + + public function testCustomerFtpsEdit() + { + global $admin_userdata; + + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + + $data = [ + 'username' => 'test1ftp1', + 'ftp_password' => 'h4xXx0r2', + 'path' => '/subfolder', + 'ftp_description' => 'testing2' + ]; + $json_result = Ftps::getLocal($customer_userdata, $data)->update(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals($customer_userdata['documentroot'].'subfolder/', $result['homedir']); + $this->assertEquals('testing2', $result['description']); + } + + public function testAdminFtpsEdit() + { + global $admin_userdata; + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + $data = [ + 'username' => 'test1ftp1', + 'customer_id' => 1, + 'ftp_password' => 'h4xXx0r2', + 'path' => '/anotherfolder', + 'ftp_description' => 'testing3' + ]; + $json_result = Ftps::getLocal($admin_userdata, $data)->update(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals($customer_userdata['documentroot'].'anotherfolder/', $result['homedir']); + $this->assertEquals('testing3', $result['description']); + } + + public function testAdminFtpsAdd() + { + global $admin_userdata; + + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + + $data = [ + 'customer_id' => $customer_userdata['customerid'], + 'ftp_password' => 'h4xXx0r', + 'path' => '/', + 'ftp_description' => 'testing', + 'sendinfomail' => 1 + ]; + $json_result = Ftps::getLocal($admin_userdata, $data)->add(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals($customer_userdata['documentroot'], $result['homedir']); + } + + public function testCustomerFtpsDelete() + { + global $admin_userdata; + + // get customer + $json_result = Customers::getLocal($admin_userdata, array( + 'loginname' => 'test1' + ))->get(); + $customer_userdata = json_decode($json_result, true)['data']; + $data = [ + 'username' => 'test1ftp1' + ]; + $json_result = Ftps::getLocal($customer_userdata, $data)->delete(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals('test1ftp1', $result['username']); + } + + public function testAdminFtpsDelete() + { + global $admin_userdata; + $data = [ + 'username' => 'test1ftp2' + ]; + $json_result = Ftps::getLocal($admin_userdata, $data)->delete(); + $result = json_decode($json_result, true)['data']; + $this->assertEquals('test1ftp2', $result['username']); + } }