Various updates.

This commit is contained in:
Julien Fontanet 2013-03-22 18:33:49 +01:00
parent 27178cfd09
commit 25d00f2fcb
5 changed files with 222 additions and 68 deletions

8
composer.lock generated
View File

@ -188,12 +188,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/vatesfr/rekodi.git", "url": "https://github.com/vatesfr/rekodi.git",
"reference": "b95faecb9b5b0f9e541a0cf8aac680cad834a4be" "reference": "a0122f7958e9375626d265497b1bfef62c552915"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/vatesfr/rekodi/zipball/b95faecb9b5b0f9e541a0cf8aac680cad834a4be", "url": "https://api.github.com/repos/vatesfr/rekodi/zipball/a0122f7958e9375626d265497b1bfef62c552915",
"reference": "b95faecb9b5b0f9e541a0cf8aac680cad834a4be", "reference": "a0122f7958e9375626d265497b1bfef62c552915",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -222,7 +222,7 @@
"keywords": [ "keywords": [
"event" "event"
], ],
"time": "2013-03-22 12:24:15" "time": "2013-03-22 15:41:39"
} }
], ],
"packages-dev": [ "packages-dev": [

View File

@ -271,7 +271,7 @@ final class Application extends Base
// Creates the user. // Creates the user.
$user = $users->create(array( $user = $users->create(array(
'name' => $name, 'name' => $name,
'password' => password_hash($password, PASSWORD_DEFAULT), 'password' => $password,
'permission' => $permission, 'permission' => $permission,
)); ));
@ -343,12 +343,11 @@ final class Application extends Base
// Checks the new password is valid. // Checks the new password is valid.
if (($new === $old) if (($new === $old)
|| !User::check('password', $new)) || !$user->checkAndSet('password', $new))
{ {
return array(2, 'invalid password'); return array(2, 'invalid password');
} }
$user->password = password_hash($new, PASSWORD_DEFAULT);
$users->save($user); $users->save($user);
// Returns success. // Returns success.
@ -371,6 +370,10 @@ final class Application extends Base
null, null,
array('id', 'name', 'permission') array('id', 'name', 'permission')
); );
foreach ($users as &$user)
{
$user['permission'] = User::permissionToString($user['permission']);
}
$c->respond($id, $users); $c->respond($id, $users);
} }
@ -385,7 +388,7 @@ final class Application extends Base
{ {
return -32602; // Invalid params. return -32602; // Invalid params.
} }
list($id, $properties) = $params; list($uid, $properties) = $params;
if (!$c->isAuthenticated() if (!$c->isAuthenticated()
|| !$this->_checkPermission($c->uid, User::ADMIN)) || !$this->_checkPermission($c->uid, User::ADMIN))
@ -394,15 +397,36 @@ final class Application extends Base
} }
$users = $this->_di->get('users'); $users = $this->_di->get('users');
$user = $users->get($id);
// Checks user exists and is not the current user.
if (($uid === $c->uid)
|| !($user = $users->get($uid, false)))
{
return array(1, 'invalid user');
}
foreach ($properties as $field => $value) foreach ($properties as $field => $value)
{ {
switch ($field) switch ($field)
{ {
case 'name': case 'name':
if (!$user->checkAndSet('name', $value))
{
return array(3, 'invalid user name');
}
break;
case 'password': case 'password':
if (!$user->checkAndSet('password', $value))
{
return array(4, 'invalid password');
}
break;
case 'permission': case 'permission':
if (!$user->checkAndSet('permission', $value))
{
return array(5, 'invalid permission '.$value);
}
break;
default: default:
return array(2, 'invalid property'); return array(2, 'invalid property');
} }
@ -550,16 +574,15 @@ final class Application extends Base
if (!$vm) if (!$vm)
{ {
$manager->create($properties); $manager->create($properties);
echo "new VM: $id\n"; echo "new VM: $id\n";
} }
else else
{ {
$vm->set($properties, true); $vm->set($properties, true);
$keys = array_keys($vm->getDirty());
sort($keys);
$dirty = implode(', ', $keys);
$manager->save($vm); $manager->save($vm);
echo "updated VM: $id ($dirty)\n";
echo "updated VM: $id\n";
} }
} }
} }

View File

@ -25,7 +25,7 @@
namespace Bean; namespace Bean;
/** /**
* * @todo Migrate check() and checkAndSet() to \Rekodi\Bean.
*/ */
final class User extends \Rekodi\Bean final class User extends \Rekodi\Bean
{ {
@ -112,10 +112,13 @@ final class User extends \Rekodi\Bean
&& preg_match('/^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/', $value) && preg_match('/^[a-z0-9]+(?:[-_.][a-z0-9]+)*$/', $value)
); );
case 'password': case 'password':
return ( if (!is_string($value)
is_string($value) || !preg_match('/^.{8,}$/', $value))
&& preg_match('/^.{8,}$/', $value) {
); return false;
}
$value = password_hash($value, PASSWORD_DEFAULT);
return true;
case 'permission': case 'permission':
$value = self::permissionFromString($value); $value = self::permissionFromString($value);
return (false !== $value); return (false !== $value);
@ -124,6 +127,20 @@ final class User extends \Rekodi\Bean
return false; return false;
} }
/**
*
*/
function checkAndSet($field, $value)
{
if (!self::check($field, $value))
{
return false;
}
$this->__set($field, $value);
return true;
}
protected static $_fields; protected static $_fields;
} }
User::init(); User::init();

View File

@ -84,56 +84,7 @@ final class DI extends Base
); );
} }
$file = $config['database.file']; return JSONDatabase::factory($config['database.file']);
if (file_exists($file))
{
$data = @file_get_contents($file);
if ((false === $data)
|| (null === ($data = json_decode($data, true))))
{
trigger_error(
'could not read the database',
E_USER_ERROR
);
}
return \Rekodi\Manager\Memory::createFromState($data);
}
$manager = new \Rekodi\Manager\Memory;
// Create tables.
$manager->createTable('tokens', function ($table) {
$table
->string('id')->unique()
->integer('expiration')
->string('user_id')
;
});
$manager->createTable('users', function ($table) {
$table
->integer('id')->autoIncremented()
->string('name')->unique()
->string('password')
->integer('permission')
;
});
// Insert initial data.
$manager->create('users', array(
array(
'name' => 'admin',
'password' => '$2y$10$VzBQqiwnhG5zc2.MQmmW4ORcPW6FE7SLhPr1VBV2ubn5zJoesnmli',
'permission' => \Bean\User::ADMIN,
),
));
trigger_error(
'no existing database, creating default user (admin:admin)',
E_USER_WARNING
);
return $manager;
} }
private function _init_errorLogger() private function _init_errorLogger()

163
lib/JSONDatabase.php Normal file
View File

@ -0,0 +1,163 @@
<?php
/**
* This file is a part of Xen Orchestra Server.
*
* Xen Orchestra Server is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Xen Orchestra Server 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xen Orchestra Server. If not, see
* <http://www.gnu.org/licenses/>.
*
* @author Julien Fontanet <julien.fontanet@vates.fr>
* @license http://www.gnu.org/licenses/gpl-3.0-standalone.html GPLv3
*
* @package Xen Orchestra Server
*/
final class JSONDatabase extends \Rekodi\Manager\Memory
{
/**
*
*/
static function factory($file)
{
if (file_exists($file))
{
$data = @file_get_contents($file);
if ((false === $data)
|| (null === ($data = json_decode($data, true))))
{
trigger_error(
'could not read the database',
E_USER_ERROR
);
}
$manager = static::createFromState($data);
}
else
{
$manager = new static;
// Create tables.
$manager->createTable('tokens', function ($table) {
$table
->string('id')->unique()
->integer('expiration')
->string('user_id')
;
});
$manager->createTable('users', function ($table) {
$table
->integer('id')->autoIncremented()
->string('name')->unique()
->string('password')
->integer('permission')
;
});
// Insert initial data.
$manager->create('users', array(
array(
'name' => 'admin',
'password' => '$2y$10$VzBQqiwnhG5zc2.MQmmW4ORcPW6FE7SLhPr1VBV2ubn5zJoesnmli',
'permission' => \Bean\User::ADMIN,
),
));
trigger_error(
'no existing database, creating default user (admin:admin)',
E_USER_WARNING
);
}
$manager->_file = $file;
return $manager;
}
/**
*
*/
function createTable($name, $callback)
{
$result = parent::createTable($name, $callback);
$this->_save();
return $result;
}
/**
*
*/
function deleteTable($name)
{
$result = parent::deleteTable($name);
$this->_save();
return $result;
}
/**
*
*/
function create($table, array $entries)
{
$result = parent::create($table, $entries);
$this->_save();
return $result;
}
/**
*
*/
function delete($table, array $filter)
{
$result = parent::delete($table, $filter);
$this->_save();
return $result;
}
/**
*
*/
function update($table, array $filter, array $properties)
{
$result = parent::update($table, $filter, $properties);
$this->_save();
return $result;
}
/**
*
*/
private $_file;
/**
*
*/
private function _save()
{
if (!$this->_file)
{
return;
}
$bytes = @file_put_contents(
$this->_file,
json_encode($this->getState())
);
if (!$bytes)
{
trigger_error(
'could not write the database',
E_USER_ERROR
);
}
}
}