Merge branch 'feature-user'
This commit is contained in:
commit
b5e96aa94c
|
@ -22,8 +22,18 @@ php-censor:
|
||||||
comments:
|
comments:
|
||||||
commit: false
|
commit: false
|
||||||
pull_request: false
|
pull_request: false
|
||||||
authentication_settings:
|
|
||||||
state: false
|
|
||||||
user_id: 1
|
|
||||||
build:
|
build:
|
||||||
remove_builds: true
|
remove_builds: true
|
||||||
|
security:
|
||||||
|
disable_auth: false
|
||||||
|
default_user_id: 1
|
||||||
|
auth_providers:
|
||||||
|
internal:
|
||||||
|
type: internal
|
||||||
|
ldap:
|
||||||
|
type: ldap
|
||||||
|
data:
|
||||||
|
host: 'ldap.php-censor.local'
|
||||||
|
port: 389
|
||||||
|
base_dn: 'dc=php-censor,dc=local'
|
||||||
|
mail_attribute: mail
|
||||||
|
|
|
@ -9,10 +9,12 @@ username/password pair and have forgotten the password, and if the server is on
|
||||||
the `forgot password` email, then editing the config file manually would be handy. To do so, just edit the `php-censor`
|
the `forgot password` email, then editing the config file manually would be handy. To do so, just edit the `php-censor`
|
||||||
section in the config file (which is in [yaml format](https://en.wikipedia.org/wiki/YAML)), and add
|
section in the config file (which is in [yaml format](https://en.wikipedia.org/wiki/YAML)), and add
|
||||||
|
|
||||||
php-censor:
|
```yml
|
||||||
authentication_settings:
|
php-censor:
|
||||||
state: 1
|
security:
|
||||||
user_id: 1
|
disable_auth: true
|
||||||
|
default_user_id: 1
|
||||||
|
```
|
||||||
|
|
||||||
where you can get the user_id by logging into the mysql database and selecting your user ID from the `users` table in
|
where you can get the `default_user_id by` logging into the mysql database and selecting your user ID from the `users` table in
|
||||||
the PHP Censor database.
|
the PHP Censor database.
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
<testsuite name="PHP Censor ProcessControl Test Suite">
|
<testsuite name="PHP Censor ProcessControl Test Suite">
|
||||||
<directory suffix="Test.php">./tests/PHPCensor/ProcessControl</directory>
|
<directory suffix="Test.php">./tests/PHPCensor/ProcessControl</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
<testsuite name="PHP Censor Security Test Suite">
|
||||||
|
<directory suffix="Test.php">./tests/PHPCensor/Security</directory>
|
||||||
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||||
|
|
|
@ -158,13 +158,13 @@ class Application extends b8\Application
|
||||||
*/
|
*/
|
||||||
protected function shouldSkipAuth()
|
protected function shouldSkipAuth()
|
||||||
{
|
{
|
||||||
$config = b8\Config::getInstance();
|
$config = b8\Config::getInstance();
|
||||||
$state = (bool)$config->get('php-censor.authentication_settings.state', false);
|
$disableAuth = (bool)$config->get('php-censor.security.disable_auth', false);
|
||||||
$userId = $config->get('php-censor.authentication_settings.user_id', 0);
|
$defaultUserId = (integer)$config->get('php-censor.security.default_user_id', 1);
|
||||||
|
|
||||||
if (false !== $state && 0 != (int)$userId) {
|
if ($disableAuth && $defaultUserId) {
|
||||||
$user = b8\Store\Factory::getStore('User')
|
$user = b8\Store\Factory::getStore('User')
|
||||||
->getByPrimaryKey($userId);
|
->getByPrimaryKey($defaultUserId);
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$_SESSION['php-censor-user'] = $user;
|
$_SESSION['php-censor-user'] = $user;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/**
|
/**
|
||||||
* PHPCI - Continuous Integration for PHP
|
* PHPCI - Continuous Integration for PHP
|
||||||
*
|
*
|
||||||
* @copyright Copyright 2014, Block 8 Limited.
|
* @copyright Copyright 2015, Block 8 Limited.
|
||||||
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
* @link https://www.phptesting.org/
|
* @link https://www.phptesting.org/
|
||||||
*/
|
*/
|
||||||
|
@ -14,9 +14,12 @@ use b8;
|
||||||
use PHPCensor\Helper\Email;
|
use PHPCensor\Helper\Email;
|
||||||
use PHPCensor\Helper\Lang;
|
use PHPCensor\Helper\Lang;
|
||||||
use PHPCensor\Controller;
|
use PHPCensor\Controller;
|
||||||
|
use PHPCensor\Security\Authentication\Service;
|
||||||
|
use PHPCensor\Store\UserStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session Controller - Handles user login / logout.
|
* Session Controller - Handles user login / logout.
|
||||||
|
*
|
||||||
* @author Dan Cryer <dan@block8.co.uk>
|
* @author Dan Cryer <dan@block8.co.uk>
|
||||||
* @package PHPCI
|
* @package PHPCI
|
||||||
* @subpackage Web
|
* @subpackage Web
|
||||||
|
@ -24,22 +27,29 @@ use PHPCensor\Controller;
|
||||||
class SessionController extends Controller
|
class SessionController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \PHPCensor\Store\UserStore
|
* @var UserStore
|
||||||
*/
|
*/
|
||||||
protected $userStore;
|
protected $userStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Service
|
||||||
|
*/
|
||||||
|
protected $authentication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise the controller, set up stores and services.
|
* Initialise the controller, set up stores and services.
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
$this->response->disableLayout();
|
$this->response->disableLayout();
|
||||||
$this->userStore = b8\Store\Factory::getStore('User');
|
|
||||||
|
$this->userStore = b8\Store\Factory::getStore('User');
|
||||||
|
$this->authentication = Service::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles user login (form and processing)
|
* Handles user login (form and processing)
|
||||||
*/
|
*/
|
||||||
public function login()
|
public function login()
|
||||||
{
|
{
|
||||||
$isLoginFailure = false;
|
$isLoginFailure = false;
|
||||||
|
@ -51,23 +61,42 @@ class SessionController extends Controller
|
||||||
} else {
|
} else {
|
||||||
unset($_SESSION['login_token']);
|
unset($_SESSION['login_token']);
|
||||||
|
|
||||||
$user = $this->userStore->getByEmailOrName($this->getParam('email'));
|
$email = $this->getParam('email');
|
||||||
|
$password = $this->getParam('password', '');
|
||||||
|
$isLoginFailure = true;
|
||||||
|
|
||||||
if ($user && password_verify($this->getParam('password', ''), $user->getHash())) {
|
$user = $this->userStore->getByEmailOrName($email);
|
||||||
session_regenerate_id(true);
|
|
||||||
$_SESSION['php-censor-user-id'] = $user->getId();
|
$providers = $this->authentication->getLoginPasswordProviders();
|
||||||
|
|
||||||
|
if (null !== $user) {
|
||||||
|
// Delegate password verification to the user provider, if found
|
||||||
|
$key = $user->getProviderKey();
|
||||||
|
$isLoginFailure = !isset($providers[$key]) || !$providers[$key]->verifyPassword($user, $password);
|
||||||
|
} else {
|
||||||
|
// Ask each providers to provision the user
|
||||||
|
foreach ($providers as $provider) {
|
||||||
|
$user = $provider->provisionUser($email);
|
||||||
|
if ($user !== null && $provider->verifyPassword($user, $password)) {
|
||||||
|
$this->userStore->save($user);
|
||||||
|
$isLoginFailure = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$isLoginFailure) {
|
||||||
|
$_SESSION['php-censor-user-id'] = $user->getId();
|
||||||
$response = new b8\Http\Response\RedirectResponse();
|
$response = new b8\Http\Response\RedirectResponse();
|
||||||
$response->setHeader('Location', $this->getLoginRedirect());
|
$response->setHeader('Location', $this->getLoginRedirect());
|
||||||
return $response;
|
return $response;
|
||||||
} else {
|
|
||||||
$isLoginFailure = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = new b8\Form();
|
$form = new b8\Form();
|
||||||
$form->setMethod('POST');
|
$form->setMethod('POST');
|
||||||
$form->setAction(APP_URL.'session/login');
|
$form->setAction(APP_URL . 'session/login');
|
||||||
|
|
||||||
$email = new b8\Form\Element\Text('email');
|
$email = new b8\Form\Element\Text('email');
|
||||||
$email->setLabel(Lang::get('login'));
|
$email->setLabel(Lang::get('login'));
|
||||||
|
|
|
@ -47,6 +47,7 @@ class SettingsController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display settings forms.
|
* Display settings forms.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
|
@ -72,18 +73,18 @@ class SettingsController extends Controller
|
||||||
$emailSettings = $this->settings['php-censor']['email_settings'];
|
$emailSettings = $this->settings['php-censor']['email_settings'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$authSettings = [];
|
$securitySettings = [];
|
||||||
if (isset($this->settings['php-censor']['authentication_settings'])) {
|
if (isset($this->settings['php-censor']['security'])) {
|
||||||
$authSettings = $this->settings['php-censor']['authentication_settings'];
|
$securitySettings = $this->settings['php-censor']['security'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->view->configFile = APP_DIR . 'config.yml';
|
$this->view->configFile = APP_DIR . 'config.yml';
|
||||||
$this->view->basicSettings = $this->getBasicForm($basicSettings);
|
$this->view->basicSettings = $this->getBasicForm($basicSettings);
|
||||||
$this->view->buildSettings = $this->getBuildForm($buildSettings);
|
$this->view->buildSettings = $this->getBuildForm($buildSettings);
|
||||||
$this->view->github = $this->getGithubForm();
|
$this->view->github = $this->getGithubForm();
|
||||||
$this->view->emailSettings = $this->getEmailForm($emailSettings);
|
$this->view->emailSettings = $this->getEmailForm($emailSettings);
|
||||||
$this->view->authenticationSettings = $this->getAuthenticationForm($authSettings);
|
$this->view->securitySettings = $this->getAuthenticationForm($securitySettings);
|
||||||
$this->view->isWriteable = $this->canWriteConfig();
|
$this->view->isWriteable = $this->canWriteConfig();
|
||||||
|
|
||||||
if (!empty($this->settings['php-censor']['github']['token'])) {
|
if (!empty($this->settings['php-censor']['github']['token'])) {
|
||||||
$this->view->githubUser = $this->getGithubUser($this->settings['php-censor']['github']['token']);
|
$this->view->githubUser = $this->getGithubUser($this->settings['php-censor']['github']['token']);
|
||||||
|
@ -187,8 +188,8 @@ class SettingsController extends Controller
|
||||||
{
|
{
|
||||||
$this->requireAdmin();
|
$this->requireAdmin();
|
||||||
|
|
||||||
$this->settings['php-censor']['authentication_settings']['state'] = $this->getParam('disable_authentication', 0);
|
$this->settings['php-censor']['security']['disable_auth'] = (boolean)$this->getParam('disable_authentication', false);
|
||||||
$this->settings['php-censor']['authentication_settings']['user_id'] = $_SESSION['php-censor-user-id'];
|
$this->settings['php-censor']['security']['default_user_id'] = (integer)$_SESSION['php-censor-user-id'];
|
||||||
|
|
||||||
$error = $this->storeSettings();
|
$error = $this->storeSettings();
|
||||||
|
|
||||||
|
@ -479,8 +480,8 @@ class SettingsController extends Controller
|
||||||
$field->setContainerClass('form-group');
|
$field->setContainerClass('form-group');
|
||||||
$field->setValue(0);
|
$field->setValue(0);
|
||||||
|
|
||||||
if (isset($values['state'])) {
|
if (isset($values['disable_auth'])) {
|
||||||
$field->setValue((int)$values['state']);
|
$field->setValue((integer)$values['disable_auth']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$form->addField($field);
|
$form->addField($field);
|
||||||
|
|
|
@ -119,10 +119,12 @@ class Email
|
||||||
*
|
*
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public function send(Builder $builder)
|
public function send(Builder $builder = null)
|
||||||
{
|
{
|
||||||
$smtpServer = $this->config->get('php-censor.email_settings.smtp_address');
|
$smtpServer = $this->config->get('php-censor.email_settings.smtp_address');
|
||||||
$builder->logDebug(sprintf("SMTP: '%s'", !empty($smtpServer) ? 'true' : 'false'));
|
if (null !== $builder) {
|
||||||
|
$builder->logDebug(sprintf("SMTP: '%s'", !empty($smtpServer) ? 'true' : 'false'));
|
||||||
|
}
|
||||||
|
|
||||||
$factory = new MailerFactory($this->config->get('php-censor'));
|
$factory = new MailerFactory($this->config->get('php-censor'));
|
||||||
$mailer = $factory->getSwiftMailerFromConfig();
|
$mailer = $factory->getSwiftMailerFromConfig();
|
||||||
|
|
|
@ -21,17 +21,19 @@ class LoginIsDisabled
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Checks if
|
* Checks if
|
||||||
|
*
|
||||||
* @param $method
|
* @param $method
|
||||||
* @param array $params
|
* @param array $params
|
||||||
|
*
|
||||||
* @return mixed|null
|
* @return mixed|null
|
||||||
*/
|
*/
|
||||||
public function __call($method, $params = [])
|
public function __call($method, $params = [])
|
||||||
{
|
{
|
||||||
unset($method, $params);
|
unset($method, $params);
|
||||||
|
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
$state = (bool) $config->get('php-censor.authentication_settings.state', false);
|
$disableAuth = (boolean)$config->get('php-censor.security.disable_auth', false);
|
||||||
|
|
||||||
return (false !== $state);
|
return $disableAuth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Phinx\Db\Adapter\MysqlAdapter;
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
class AddUserProviders extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Migrate Up.
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Add the provider columns
|
||||||
|
$this
|
||||||
|
->table('user')
|
||||||
|
// The provider name
|
||||||
|
->addColumn('provider_key', 'string', [
|
||||||
|
'default' => 'internal',
|
||||||
|
'limit' => MysqlAdapter::TEXT_SMALL
|
||||||
|
])
|
||||||
|
// A data used by the provider
|
||||||
|
->addColumn('provider_data', 'string', [
|
||||||
|
'null' => true,
|
||||||
|
'limit' => MysqlAdapter::TEXT_SMALL
|
||||||
|
])
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate Down.
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Remove the provider columns
|
||||||
|
$this
|
||||||
|
->table('user')
|
||||||
|
->removeColumn('provider_key')
|
||||||
|
->removeColumn('provider_data')
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,11 +22,11 @@ class UniqueEmailAndNameUserFields extends AbstractMigration
|
||||||
$user_table = $this->table('user');
|
$user_table = $this->table('user');
|
||||||
|
|
||||||
if ($user_table->hasIndex('email', ['unique' => true])) {
|
if ($user_table->hasIndex('email', ['unique' => true])) {
|
||||||
$user_table->removeIndex('email', ['unique' => true])->save();
|
$user_table->removeIndex(['email'], ['unique' => true])->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user_table->hasIndex('name', ['unique' => true])) {
|
if ($user_table->hasIndex('name', ['unique' => true])) {
|
||||||
$user_table->removeIndex('name', ['unique' => true])->save();
|
$user_table->removeIndex(['name'], ['unique' => true])->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,13 +33,15 @@ class UserBase extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $data = [
|
protected $data = [
|
||||||
'id' => null,
|
'id' => null,
|
||||||
'email' => null,
|
'email' => null,
|
||||||
'hash' => null,
|
'hash' => null,
|
||||||
'is_admin' => null,
|
'is_admin' => null,
|
||||||
'name' => null,
|
'name' => null,
|
||||||
'language' => null,
|
'language' => null,
|
||||||
'per_page' => null,
|
'per_page' => null,
|
||||||
|
'provider_key' => null,
|
||||||
|
'provider_data' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,13 +49,15 @@ class UserBase extends Model
|
||||||
*/
|
*/
|
||||||
protected $getters = [
|
protected $getters = [
|
||||||
// Direct property getters:
|
// Direct property getters:
|
||||||
'id' => 'getId',
|
'id' => 'getId',
|
||||||
'email' => 'getEmail',
|
'email' => 'getEmail',
|
||||||
'hash' => 'getHash',
|
'hash' => 'getHash',
|
||||||
'is_admin' => 'getIsAdmin',
|
'is_admin' => 'getIsAdmin',
|
||||||
'name' => 'getName',
|
'name' => 'getName',
|
||||||
'language' => 'getLanguage',
|
'language' => 'getLanguage',
|
||||||
'per_page' => 'getPerPage',
|
'per_page' => 'getPerPage',
|
||||||
|
'provider_key' => 'getProviderKey',
|
||||||
|
'provider_data' => 'getProviderData',
|
||||||
// Foreign key getters:
|
// Foreign key getters:
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -62,13 +66,15 @@ class UserBase extends Model
|
||||||
*/
|
*/
|
||||||
protected $setters = [
|
protected $setters = [
|
||||||
// Direct property setters:
|
// Direct property setters:
|
||||||
'id' => 'setId',
|
'id' => 'setId',
|
||||||
'email' => 'setEmail',
|
'email' => 'setEmail',
|
||||||
'hash' => 'setHash',
|
'hash' => 'setHash',
|
||||||
'is_admin' => 'setIsAdmin',
|
'is_admin' => 'setIsAdmin',
|
||||||
'name' => 'setName',
|
'name' => 'setName',
|
||||||
'language' => 'setLanguage',
|
'language' => 'setLanguage',
|
||||||
'per_page' => 'setPerPage',
|
'per_page' => 'setPerPage',
|
||||||
|
'provider_key' => 'setProviderKey',
|
||||||
|
'provider_data' => 'setProviderData',
|
||||||
// Foreign key setters:
|
// Foreign key setters:
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -112,6 +118,17 @@ class UserBase extends Model
|
||||||
'length' => 11,
|
'length' => 11,
|
||||||
'default' => null,
|
'default' => null,
|
||||||
],
|
],
|
||||||
|
'provider_key' => [
|
||||||
|
'type' => 'varchar',
|
||||||
|
'length' => 255,
|
||||||
|
'default' => 'internal',
|
||||||
|
],
|
||||||
|
'provider_data' => [
|
||||||
|
'type' => 'varchar',
|
||||||
|
'length' => 255,
|
||||||
|
'nullable' => true,
|
||||||
|
'default' => null,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,6 +182,18 @@ class UserBase extends Model
|
||||||
return $rtn;
|
return $rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of Name / name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
$rtn = $this->data['name'];
|
||||||
|
|
||||||
|
return $rtn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of IsAdmin / is_admin.
|
* Get the value of IsAdmin / is_admin.
|
||||||
*
|
*
|
||||||
|
@ -178,13 +207,25 @@ class UserBase extends Model
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of Name / name.
|
* Get the value of ProviderKey / provider_key.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getName()
|
public function getProviderKey()
|
||||||
{
|
{
|
||||||
$rtn = $this->data['name'];
|
$rtn = $this->data['provider_key'];
|
||||||
|
|
||||||
|
return $rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of ProviderData / provider_data.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getProviderData()
|
||||||
|
{
|
||||||
|
$rtn = $this->data['provider_data'];
|
||||||
|
|
||||||
return $rtn;
|
return $rtn;
|
||||||
}
|
}
|
||||||
|
@ -273,6 +314,26 @@ class UserBase extends Model
|
||||||
$this->setModified('hash');
|
$this->setModified('hash');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of Name / name.
|
||||||
|
*
|
||||||
|
* Must not be null.
|
||||||
|
* @param $value string
|
||||||
|
*/
|
||||||
|
public function setName($value)
|
||||||
|
{
|
||||||
|
$this->validateNotNull('Name', $value);
|
||||||
|
$this->validateString('Name', $value);
|
||||||
|
|
||||||
|
if ($this->data['name'] === $value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data['name'] = $value;
|
||||||
|
|
||||||
|
$this->setModified('name');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of IsAdmin / is_admin.
|
* Set the value of IsAdmin / is_admin.
|
||||||
*
|
*
|
||||||
|
@ -294,23 +355,41 @@ class UserBase extends Model
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of Name / name.
|
* Set the value of ProviderKey / provider_key.
|
||||||
*
|
*
|
||||||
* Must not be null.
|
* Must not be null.
|
||||||
* @param $value string
|
* @param $value string
|
||||||
*/
|
*/
|
||||||
public function setName($value)
|
public function setProviderKey($value)
|
||||||
{
|
{
|
||||||
$this->validateNotNull('Name', $value);
|
$this->validateNotNull('ProviderKey', $value);
|
||||||
$this->validateString('Name', $value);
|
$this->validateString('ProviderKey', $value);
|
||||||
|
|
||||||
if ($this->data['name'] === $value) {
|
if ($this->data['provider_key'] === $value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->data['name'] = $value;
|
$this->data['provider_key'] = $value;
|
||||||
|
|
||||||
$this->setModified('name');
|
$this->setModified('provider_key');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of ProviderData / provider_data.
|
||||||
|
*
|
||||||
|
* @param $value string
|
||||||
|
*/
|
||||||
|
public function setProviderData($value)
|
||||||
|
{
|
||||||
|
$this->validateString('ProviderData', $value);
|
||||||
|
|
||||||
|
if ($this->data['provider_data'] === $value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data['provider_data'] = $value;
|
||||||
|
|
||||||
|
$this->setModified('provider_data');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace PHPCensor\Plugin\Option;
|
||||||
class PhpUnitOptions
|
class PhpUnitOptions
|
||||||
{
|
{
|
||||||
protected $options;
|
protected $options;
|
||||||
protected $arguments = array();
|
protected $arguments = [];
|
||||||
|
|
||||||
public function __construct($options)
|
public function __construct($options)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ class PhpUnitOptions
|
||||||
$prefix = $argumentName[0] == '-' ? '' : '--';
|
$prefix = $argumentName[0] == '-' ? '' : '--';
|
||||||
|
|
||||||
if (!is_array($argumentValues)) {
|
if (!is_array($argumentValues)) {
|
||||||
$argumentValues = array($argumentValues);
|
$argumentValues = [$argumentValues];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($argumentValues as $argValue) {
|
foreach ($argumentValues as $argValue) {
|
||||||
|
@ -139,7 +139,7 @@ class PhpUnitOptions
|
||||||
if (isset($this->arguments[$argumentName])) {
|
if (isset($this->arguments[$argumentName])) {
|
||||||
if (!is_array($this->arguments[$argumentName])) {
|
if (!is_array($this->arguments[$argumentName])) {
|
||||||
// Convert existing argument values into an array
|
// Convert existing argument values into an array
|
||||||
$this->arguments[$argumentName] = array($this->arguments[$argumentName]);
|
$this->arguments[$argumentName] = [$this->arguments[$argumentName]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends the new argument to the list
|
// Appends the new argument to the list
|
||||||
|
@ -160,14 +160,14 @@ class PhpUnitOptions
|
||||||
$directories = $this->getOption('directory');
|
$directories = $this->getOption('directory');
|
||||||
|
|
||||||
if (is_string($directories)) {
|
if (is_string($directories)) {
|
||||||
$directories = array($directories);
|
$directories = [$directories];
|
||||||
} else {
|
} else {
|
||||||
if (is_null($directories)) {
|
if (is_null($directories)) {
|
||||||
$directories = array();
|
$directories = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_array($directories) ? $directories : array($directories);
|
return is_array($directories) ? $directories : [$directories];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,10 +240,10 @@ class PhpUnitOptions
|
||||||
if (isset($this->arguments[$argumentName])) {
|
if (isset($this->arguments[$argumentName])) {
|
||||||
return is_array(
|
return is_array(
|
||||||
$this->arguments[$argumentName]
|
$this->arguments[$argumentName]
|
||||||
) ? $this->arguments[$argumentName] : array($this->arguments[$argumentName]);
|
) ? $this->arguments[$argumentName] : [$this->arguments[$argumentName]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -255,12 +255,12 @@ class PhpUnitOptions
|
||||||
*/
|
*/
|
||||||
public static function findConfigFile($buildPath)
|
public static function findConfigFile($buildPath)
|
||||||
{
|
{
|
||||||
$files = array(
|
$files = [
|
||||||
'phpunit.xml',
|
'phpunit.xml',
|
||||||
'phpunit.xml.dist',
|
'phpunit.xml.dist',
|
||||||
'tests/phpunit.xml',
|
'tests/phpunit.xml',
|
||||||
'tests/phpunit.xml.dist',
|
'tests/phpunit.xml.dist',
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (file_exists($buildPath . $file)) {
|
if (file_exists($buildPath . $file)) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ use PHPCensor\ZeroConfigPluginInterface;
|
||||||
class PhpUnit extends Plugin implements ZeroConfigPluginInterface
|
class PhpUnit extends Plugin implements ZeroConfigPluginInterface
|
||||||
{
|
{
|
||||||
/** @var string[] Raw options from the PHPCI config file */
|
/** @var string[] Raw options from the PHPCI config file */
|
||||||
protected $options = array();
|
protected $options = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
|
|
|
@ -29,10 +29,10 @@ class PhpUnitResult
|
||||||
const SEVERITY_SKIPPED = 'skipped';
|
const SEVERITY_SKIPPED = 'skipped';
|
||||||
|
|
||||||
protected $options;
|
protected $options;
|
||||||
protected $arguments = array();
|
protected $arguments = [];
|
||||||
protected $results;
|
protected $results;
|
||||||
protected $failures = 0;
|
protected $failures = 0;
|
||||||
protected $errors = array();
|
protected $errors = [];
|
||||||
|
|
||||||
public function __construct($outputFile, $buildPath = '')
|
public function __construct($outputFile, $buildPath = '')
|
||||||
{
|
{
|
||||||
|
@ -60,8 +60,8 @@ class PhpUnitResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the parsing variables
|
// Reset the parsing variables
|
||||||
$this->results = array();
|
$this->results = [];
|
||||||
$this->errors = array();
|
$this->errors = [];
|
||||||
$this->failures = 0;
|
$this->failures = 0;
|
||||||
|
|
||||||
if (is_array($events)) {
|
if (is_array($events)) {
|
||||||
|
@ -88,13 +88,13 @@ class PhpUnitResult
|
||||||
{
|
{
|
||||||
list($pass, $severity) = $this->getStatus($event);
|
list($pass, $severity) = $this->getStatus($event);
|
||||||
|
|
||||||
$data = array(
|
$data = [
|
||||||
'pass' => $pass,
|
'pass' => $pass,
|
||||||
'severity' => $severity,
|
'severity' => $severity,
|
||||||
'message' => $this->buildMessage($event),
|
'message' => $this->buildMessage($event),
|
||||||
'trace' => $pass ? array() : $this->buildTrace($event),
|
'trace' => $pass ? [] : $this->buildTrace($event),
|
||||||
'output' => $event['output'],
|
'output' => $event['output'],
|
||||||
);
|
];
|
||||||
|
|
||||||
if (!$pass) {
|
if (!$pass) {
|
||||||
$this->failures++;
|
$this->failures++;
|
||||||
|
@ -142,7 +142,7 @@ class PhpUnitResult
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($pass, $severity);
|
return [$pass, $severity];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,7 +172,7 @@ class PhpUnitResult
|
||||||
*/
|
*/
|
||||||
protected function buildTrace($event)
|
protected function buildTrace($event)
|
||||||
{
|
{
|
||||||
$formattedTrace = array();
|
$formattedTrace = [];
|
||||||
|
|
||||||
if (!empty($event['trace'])) {
|
if (!empty($event['trace'])) {
|
||||||
foreach ($event['trace'] as $step){
|
foreach ($event['trace'] as $step){
|
||||||
|
@ -195,12 +195,12 @@ class PhpUnitResult
|
||||||
$firstTrace = end($event['trace']);
|
$firstTrace = end($event['trace']);
|
||||||
reset($event['trace']);
|
reset($event['trace']);
|
||||||
|
|
||||||
$this->errors[] = array(
|
$this->errors[] = [
|
||||||
'message' => $data['message'],
|
'message' => $data['message'],
|
||||||
'severity' => $data['severity'],
|
'severity' => $data['severity'],
|
||||||
'file' => str_replace($this->buildPath, '', $firstTrace['file']),
|
'file' => str_replace($this->buildPath, '', $firstTrace['file']),
|
||||||
'line' => $firstTrace['line'],
|
'line' => $firstTrace['line'],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2015, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication;
|
||||||
|
|
||||||
|
use PHPCensor\Model\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User provider which authenticiation using a password.
|
||||||
|
*
|
||||||
|
* @author Adirelle <adirelle@gmail.com>
|
||||||
|
*/
|
||||||
|
interface LoginPasswordProviderInterface extends UserProviderInterface
|
||||||
|
{
|
||||||
|
/** Verify if the supplied password matches the user's one.
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @param string $password
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function verifyPassword(User $user, $password);
|
||||||
|
}
|
109
src/PHPCensor/Security/Authentication/Service.php
Normal file
109
src/PHPCensor/Security/Authentication/Service.php
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2015, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication;
|
||||||
|
|
||||||
|
use b8\Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication facade.
|
||||||
|
*
|
||||||
|
* @author Adirelle <adirelle@gmail.com>
|
||||||
|
*/
|
||||||
|
class Service
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var Service
|
||||||
|
*/
|
||||||
|
static private $instance;
|
||||||
|
|
||||||
|
/** Return the service singletion.
|
||||||
|
*
|
||||||
|
* @return Service
|
||||||
|
*/
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
if (self::$instance === null) {
|
||||||
|
$config = Config::getInstance()->get(
|
||||||
|
'php-censor.security.auth_providers',
|
||||||
|
[
|
||||||
|
'internal' => [
|
||||||
|
'type' => 'internal'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$providers = [];
|
||||||
|
foreach ($config as $key => $providerConfig) {
|
||||||
|
$providers[$key] = self::buildProvider($key, $providerConfig);
|
||||||
|
}
|
||||||
|
self::$instance = new self($providers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a provider from a given configuration.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string|array $config
|
||||||
|
*
|
||||||
|
* @return UserProviderInterface
|
||||||
|
*/
|
||||||
|
public static function buildProvider($key, $config)
|
||||||
|
{
|
||||||
|
$class = ucfirst($config['type']);
|
||||||
|
if (class_exists('\\PHPCensor\\Security\\Authentication\\UserProvider\\' . $class)) {
|
||||||
|
$class = '\\PHPCensor\\Security\\Authentication\\UserProvider\\' . $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new $class($key, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The table of providers.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $providers;
|
||||||
|
|
||||||
|
/** Initialize the service.
|
||||||
|
*
|
||||||
|
* @param array $providers
|
||||||
|
*/
|
||||||
|
public function __construct(array $providers)
|
||||||
|
{
|
||||||
|
$this->providers = $providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return all providers.
|
||||||
|
*
|
||||||
|
* @return UserProviderInterface[]
|
||||||
|
*/
|
||||||
|
public function getProviders()
|
||||||
|
{
|
||||||
|
return $this->providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the user providers that allows password authentication.
|
||||||
|
*
|
||||||
|
* @return LoginPasswordProviderInterface[]
|
||||||
|
*/
|
||||||
|
public function getLoginPasswordProviders()
|
||||||
|
{
|
||||||
|
$providers = [];
|
||||||
|
foreach ($this->providers as $key => $provider) {
|
||||||
|
if ($provider instanceof LoginPasswordProviderInterface) {
|
||||||
|
$providers[$key] = $provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $providers;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication\UserProvider;
|
||||||
|
|
||||||
|
use PHPCensor\Security\Authentication\UserProviderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract user provider.
|
||||||
|
*
|
||||||
|
* @author Adirelle <adirelle@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class AbstractProvider implements UserProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AbstractProvider constructor
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param array $config
|
||||||
|
*/
|
||||||
|
public function __construct($key, array $config)
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication\UserProvider;
|
||||||
|
|
||||||
|
use PHPCensor\Model\User;
|
||||||
|
use PHPCensor\Security\Authentication\LoginPasswordProviderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal user provider
|
||||||
|
*
|
||||||
|
* @author Adirelle <adirelle@gmail.com>
|
||||||
|
*/
|
||||||
|
class Internal extends AbstractProvider implements LoginPasswordProviderInterface
|
||||||
|
{
|
||||||
|
public function verifyPassword(User $user, $password)
|
||||||
|
{
|
||||||
|
return password_verify($password, $user->getHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkRequirements()
|
||||||
|
{
|
||||||
|
// Always fine
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provisionUser($identifier)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
78
src/PHPCensor/Security/Authentication/UserProvider/Ldap.php
Normal file
78
src/PHPCensor/Security/Authentication/UserProvider/Ldap.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication\UserProvider;
|
||||||
|
|
||||||
|
use b8\Store\Factory;
|
||||||
|
use PHPCensor\Model\User;
|
||||||
|
use PHPCensor\Security\Authentication\LoginPasswordProviderInterface;
|
||||||
|
use PHPCensor\Service\UserService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ldap user provider.
|
||||||
|
*
|
||||||
|
* @author Dmitrii Zolotov (@itherz)
|
||||||
|
*/
|
||||||
|
class Ldap extends AbstractProvider implements LoginPasswordProviderInterface
|
||||||
|
{
|
||||||
|
public function verifyPassword(User $user, $password)
|
||||||
|
{
|
||||||
|
if (isset($this->config['data'])) {
|
||||||
|
$ldapData = $this->config['data'];
|
||||||
|
$ldapPort = !empty($ldapData['port']) ? $ldapData['port'] : null;
|
||||||
|
$ldapHost = !empty($ldapData['host']) ? $ldapData['host'] : 'localhost';
|
||||||
|
$ldapBaseDn = !empty($ldapData['base_dn']) ? $ldapData['base_dn'] : 'dc=nodomain';
|
||||||
|
$ldapMail = !empty($ldapData['mail_attribute']) ? $ldapData['mail_attribute'] : 'mail';
|
||||||
|
|
||||||
|
if ($ldapPort) {
|
||||||
|
$ldap = @ldap_connect($ldapHost, $ldapPort);
|
||||||
|
} else {
|
||||||
|
$ldap = @ldap_connect($ldapHost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $ldap) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||||
|
|
||||||
|
$ls = @ldap_search($ldap, $ldapBaseDn, $ldapMail . '=' . $user->getEmail());
|
||||||
|
if (false === $ls) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$le = @ldap_get_entries($ldap, $ls);
|
||||||
|
if (!$le['count']) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dn = $le[0]['dn'];
|
||||||
|
|
||||||
|
return @ldap_bind($ldap, $dn, $password);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkRequirements()
|
||||||
|
{
|
||||||
|
// Always fine
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provisionUser($identifier)
|
||||||
|
{
|
||||||
|
$userService = new UserService(Factory::getStore('User'));
|
||||||
|
|
||||||
|
$parts = explode("@", $identifier);
|
||||||
|
$username = $parts[0];
|
||||||
|
|
||||||
|
return $userService->createUserWithProvider($username, $identifier, $this->key, null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2015, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCensor\Security\Authentication;
|
||||||
|
|
||||||
|
use PHPCensor\Model\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User provider interface.
|
||||||
|
*
|
||||||
|
* @author Adirelle <adirelle@gmail.com>
|
||||||
|
*/
|
||||||
|
interface UserProviderInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Check if all software requirements are met (libraries, extensions, ...)
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function checkRequirements();
|
||||||
|
|
||||||
|
/** Provision an new user for the given identifier.
|
||||||
|
*
|
||||||
|
* @param string $identifier The user identifier.
|
||||||
|
*
|
||||||
|
* @return User|null The new user or null if the provider does not know the user.
|
||||||
|
*/
|
||||||
|
public function provisionUser($identifier);
|
||||||
|
}
|
|
@ -57,6 +57,31 @@ class UserService
|
||||||
return $this->store->save($user);
|
return $this->store->save($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user within PHPCI (with provider).
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @param $emailAddress
|
||||||
|
* @param $providerKey
|
||||||
|
* @param $providerData
|
||||||
|
* @param bool $isAdmin
|
||||||
|
*
|
||||||
|
* @return \PHPCI\Model\User
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function createUserWithProvider($name, $emailAddress, $providerKey, $providerData, $isAdmin = false)
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setName($name);
|
||||||
|
$user->setEmail($emailAddress);
|
||||||
|
$user->setHash("");
|
||||||
|
$user->setProviderKey($providerKey);
|
||||||
|
$user->setProviderData($providerData);
|
||||||
|
$user->setIsAdmin(($isAdmin ? 1 : 0));
|
||||||
|
|
||||||
|
return $this->store->save($user);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a user.
|
* Update a user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
Be careful: This setting disables authentication and uses your current admin account for all actions within PHP Censor with admin rights.
|
Be careful: This setting disables authentication and uses your current admin account for all actions within PHP Censor with admin rights.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<?php print $authenticationSettings; ?>
|
<?php print $securitySettings; ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,7 +75,7 @@ class CommandExecutorTest extends \PHPUnit_Framework_TestCase
|
||||||
/bin/sh -c 'data="$(printf %%${length}s | tr " " "-")"; >&2 echo "\$data"; >&1 echo "\$data"'
|
/bin/sh -c 'data="$(printf %%${length}s | tr " " "-")"; >&2 echo "\$data"; >&1 echo "\$data"'
|
||||||
EOD;
|
EOD;
|
||||||
$data = str_repeat("-", $length);
|
$data = str_repeat("-", $length);
|
||||||
$returnValue = $this->testedExecutor->executeCommand(array($script));
|
$returnValue = $this->testedExecutor->executeCommand([$script]);
|
||||||
$this->assertTrue($returnValue);
|
$this->assertTrue($returnValue);
|
||||||
$this->assertEquals($data, trim($this->testedExecutor->getLastOutput()));
|
$this->assertEquals($data, trim($this->testedExecutor->getLastOutput()));
|
||||||
$this->assertEquals($data, trim($this->testedExecutor->getLastError()));
|
$this->assertEquals($data, trim($this->testedExecutor->getLastError()));
|
||||||
|
|
|
@ -21,80 +21,80 @@ class PhpUnitOptionsTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function validOptionsProvider()
|
public function validOptionsProvider()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'config' => 'tests/phpunit.xml',
|
'config' => 'tests/phpunit.xml',
|
||||||
'args' => '--stop-on-error --log-junit /path/to/log/',
|
'args' => '--stop-on-error --log-junit /path/to/log/',
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'stop-on-error' => '',
|
'stop-on-error' => '',
|
||||||
'log-junit' => '/path/to/log/',
|
'log-junit' => '/path/to/log/',
|
||||||
'configuration' => 'tests/phpunit.xml',
|
'configuration' => 'tests/phpunit.xml',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'coverage' => '/path/to/coverage2/',
|
'coverage' => '/path/to/coverage2/',
|
||||||
'args' => array(
|
'args' => [
|
||||||
'coverage-html' => '/path/to/coverage1/',
|
'coverage-html' => '/path/to/coverage1/',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'coverage-html' => array(
|
'coverage-html' => [
|
||||||
'/path/to/coverage1/',
|
'/path/to/coverage1/',
|
||||||
'/path/to/coverage2/',
|
'/path/to/coverage2/',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'directory' => array(
|
'directory' => [
|
||||||
'/path/to/test1/',
|
'/path/to/test1/',
|
||||||
'/path/to/test2/',
|
'/path/to/test2/',
|
||||||
),
|
],
|
||||||
'args' => array(
|
'args' => [
|
||||||
'coverage-html' => '/path/to/coverage1/',
|
'coverage-html' => '/path/to/coverage1/',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'coverage-html' => '/path/to/coverage1/',
|
'coverage-html' => '/path/to/coverage1/',
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'config' => array('tests/phpunit.xml'),
|
'config' => ['tests/phpunit.xml'],
|
||||||
'args' => "--testsuite=unit --bootstrap=vendor/autoload.php",
|
'args' => "--testsuite=unit --bootstrap=vendor/autoload.php",
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'testsuite' => 'unit',
|
'testsuite' => 'unit',
|
||||||
'bootstrap' => 'vendor/autoload.php',
|
'bootstrap' => 'vendor/autoload.php',
|
||||||
'configuration' => array('tests/phpunit.xml'),
|
'configuration' => ['tests/phpunit.xml'],
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'config' => array('tests/phpunit.xml'),
|
'config' => ['tests/phpunit.xml'],
|
||||||
'args' => "--testsuite='unit' --bootstrap 'vendor/autoload.php'",
|
'args' => "--testsuite='unit' --bootstrap 'vendor/autoload.php'",
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'testsuite' => 'unit',
|
'testsuite' => 'unit',
|
||||||
'bootstrap' => 'vendor/autoload.php',
|
'bootstrap' => 'vendor/autoload.php',
|
||||||
'configuration' => array('tests/phpunit.xml'),
|
'configuration' => ['tests/phpunit.xml'],
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
array(
|
[
|
||||||
'config' => array('tests/phpunit.xml'),
|
'config' => ['tests/phpunit.xml'],
|
||||||
'args' => '--testsuite="unit" --bootstrap "vendor/autoload.php"',
|
'args' => '--testsuite="unit" --bootstrap "vendor/autoload.php"',
|
||||||
),
|
],
|
||||||
array(
|
[
|
||||||
'testsuite' => 'unit',
|
'testsuite' => 'unit',
|
||||||
'bootstrap' => 'vendor/autoload.php',
|
'bootstrap' => 'vendor/autoload.php',
|
||||||
'configuration' => array('tests/phpunit.xml'),
|
'configuration' => ['tests/phpunit.xml'],
|
||||||
),
|
],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,10 +112,10 @@ class PhpUnitOptionsTest extends \PHPUnit_Framework_TestCase
|
||||||
public function testGetters()
|
public function testGetters()
|
||||||
{
|
{
|
||||||
$options = new PhpUnitOptions(
|
$options = new PhpUnitOptions(
|
||||||
array(
|
[
|
||||||
'run_from' => '/path/to/run/from',
|
'run_from' => '/path/to/run/from',
|
||||||
'path' => 'subTest',
|
'path' => 'subTest',
|
||||||
)
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals('/path/to/run/from', $options->getRunFrom());
|
$this->assertEquals('/path/to/run/from', $options->getRunFrom());
|
||||||
|
|
|
@ -19,11 +19,11 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testSingleConfigFile()
|
public function testSingleConfigFile()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'config' => ROOT_DIR . 'phpunit.xml'
|
'config' => ROOT_DIR . 'phpunit.xml'
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('runConfigFile'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['runConfigFile'])->getMock();
|
||||||
$mockPlugin->expects($this->once())->method('runConfigFile')->with(ROOT_DIR . 'phpunit.xml');
|
$mockPlugin->expects($this->once())->method('runConfigFile')->with(ROOT_DIR . 'phpunit.xml');
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
@ -31,16 +31,16 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testMultiConfigFile()
|
public function testMultiConfigFile()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'config' => array(
|
'config' => [
|
||||||
ROOT_DIR . 'phpunit1.xml',
|
ROOT_DIR . 'phpunit1.xml',
|
||||||
ROOT_DIR . 'phpunit2.xml',
|
ROOT_DIR . 'phpunit2.xml',
|
||||||
)
|
]
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('runConfigFile'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['runConfigFile'])->getMock();
|
||||||
$mockPlugin->expects($this->exactly(2))->method('runConfigFile')->withConsecutive(
|
$mockPlugin->expects($this->exactly(2))->method('runConfigFile')->withConsecutive(
|
||||||
array(ROOT_DIR . 'phpunit1.xml'), array(ROOT_DIR . 'phpunit2.xml')
|
[ROOT_DIR . 'phpunit1.xml'], [ROOT_DIR . 'phpunit2.xml']
|
||||||
);
|
);
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
@ -53,30 +53,30 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
*
|
*
|
||||||
* @return \PHPUnit_Framework_MockObject_MockBuilder
|
* @return \PHPUnit_Framework_MockObject_MockBuilder
|
||||||
*/
|
*/
|
||||||
protected function getPluginBuilder($options = array())
|
protected function getPluginBuilder($options = [])
|
||||||
{
|
{
|
||||||
$loggerMock = $this->getMockBuilder('\Monolog\Logger')
|
$loggerMock = $this->getMockBuilder('\Monolog\Logger')
|
||||||
->setConstructorArgs(array('Test'))
|
->setConstructorArgs(['Test'])
|
||||||
->setMethods(array('addRecord'))
|
->setMethods(['addRecord'])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$mockBuild = $this->getMockBuilder('\PHPCensor\Model\Build')->getMock();
|
$mockBuild = $this->getMockBuilder('\PHPCensor\Model\Build')->getMock();
|
||||||
$mockBuilder = $this->getMockBuilder('\PHPCensor\Builder')
|
$mockBuilder = $this->getMockBuilder('\PHPCensor\Builder')
|
||||||
->setConstructorArgs(array($mockBuild, $loggerMock))
|
->setConstructorArgs([$mockBuild, $loggerMock])
|
||||||
->setMethods(array('executeCommand'))->getMock();
|
->setMethods(['executeCommand'])->getMock();
|
||||||
|
|
||||||
return $this->getMockBuilder('PHPCensor\Plugin\PhpUnit')->setConstructorArgs(
|
return $this->getMockBuilder('PHPCensor\Plugin\PhpUnit')->setConstructorArgs(
|
||||||
array($mockBuilder, $mockBuild, $options)
|
[$mockBuilder, $mockBuild, $options]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSingleDir()
|
public function testSingleDir()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'directory' => '/test/directory/one'
|
'directory' => '/test/directory/one'
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('runDir'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['runDir'])->getMock();
|
||||||
$mockPlugin->expects($this->once())->method('runDir')->with('/test/directory/one');
|
$mockPlugin->expects($this->once())->method('runDir')->with('/test/directory/one');
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
@ -84,16 +84,16 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testMultiDir()
|
public function testMultiDir()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'directory' => array(
|
'directory' => [
|
||||||
'/test/directory/one',
|
'/test/directory/one',
|
||||||
'/test/directory/two',
|
'/test/directory/two',
|
||||||
)
|
]
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('runDir'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['runDir'])->getMock();
|
||||||
$mockPlugin->expects($this->exactly(2))->method('runDir')->withConsecutive(
|
$mockPlugin->expects($this->exactly(2))->method('runDir')->withConsecutive(
|
||||||
array('/test/directory/one'), array('/test/directory/two')
|
['/test/directory/one'], ['/test/directory/two']
|
||||||
);
|
);
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
@ -101,11 +101,11 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testProcessResultsFromConfig()
|
public function testProcessResultsFromConfig()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'config' => ROOT_DIR . 'phpunit.xml'
|
'config' => ROOT_DIR . 'phpunit.xml'
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('processResults'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['processResults'])->getMock();
|
||||||
$mockPlugin->expects($this->once())->method('processResults')->with($this->isType('string'));
|
$mockPlugin->expects($this->once())->method('processResults')->with($this->isType('string'));
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
@ -113,11 +113,11 @@ class PhpUnitTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testProcessResultsFromDir()
|
public function testProcessResultsFromDir()
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = [
|
||||||
'directory' => ROOT_DIR . 'Tests'
|
'directory' => ROOT_DIR . 'Tests'
|
||||||
);
|
];
|
||||||
|
|
||||||
$mockPlugin = $this->getPluginBuilder($options)->setMethods(array('processResults'))->getMock();
|
$mockPlugin = $this->getPluginBuilder($options)->setMethods(['processResults'])->getMock();
|
||||||
$mockPlugin->expects($this->once())->method('processResults')->with($this->isType('string'));
|
$mockPlugin->expects($this->once())->method('processResults')->with($this->isType('string'));
|
||||||
|
|
||||||
$mockPlugin->execute();
|
$mockPlugin->execute();
|
||||||
|
|
86
tests/PHPCensor/Security/Authentication/ServiceTest.php
Normal file
86
tests/PHPCensor/Security/Authentication/ServiceTest.php
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tests\PHPCensor\Security\Authentication;
|
||||||
|
|
||||||
|
use PHPCensor\Security\Authentication\Service;
|
||||||
|
|
||||||
|
class ServiceTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @covers Service::getInstance
|
||||||
|
*/
|
||||||
|
public function testGetInstance()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('\PHPCensor\Security\Authentication\Service', Service::getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Service::buildProvider
|
||||||
|
*/
|
||||||
|
public function testBuildBuiltinProvider()
|
||||||
|
{
|
||||||
|
$provider = Service::buildProvider('test', ['type' => 'internal']);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('\PHPCensor\Security\Authentication\UserProvider\Internal', $provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Service::buildProvider
|
||||||
|
*/
|
||||||
|
public function testBuildAnyProvider()
|
||||||
|
{
|
||||||
|
$config = ['type' => '\Tests\PHPCensor\Security\Authentication\DummyProvider'];
|
||||||
|
$provider = Service::buildProvider("test", $config);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('\Tests\PHPCensor\Security\Authentication\DummyProvider', $provider);
|
||||||
|
$this->assertEquals('test', $provider->key);
|
||||||
|
$this->assertEquals($config, $provider->config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Service::getProviders
|
||||||
|
*/
|
||||||
|
public function testGetProviders()
|
||||||
|
{
|
||||||
|
$a = $this->prophesize('\PHPCensor\Security\Authentication\UserProviderInterface')->reveal();
|
||||||
|
$b = $this->prophesize('\PHPCensor\Security\Authentication\UserProviderInterface')->reveal();
|
||||||
|
$providers = ['a' => $a, 'b' => $b];
|
||||||
|
|
||||||
|
$service = new Service($providers);
|
||||||
|
|
||||||
|
$this->assertEquals($providers, $service->getProviders());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Service::getLoginPasswordProviders
|
||||||
|
*/
|
||||||
|
public function testGetLoginPasswordProviders()
|
||||||
|
{
|
||||||
|
$a = $this->prophesize('\PHPCensor\Security\Authentication\UserProviderInterface')->reveal();
|
||||||
|
$b = $this->prophesize('\PHPCensor\Security\Authentication\LoginPasswordProviderInterface')->reveal();
|
||||||
|
$providers = ['a' => $a, 'b' => $b];
|
||||||
|
|
||||||
|
$service = new Service($providers);
|
||||||
|
|
||||||
|
$this->assertEquals(['b' => $b], $service->getLoginPasswordProviders());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DummyProvider
|
||||||
|
{
|
||||||
|
public $key;
|
||||||
|
public $config;
|
||||||
|
public function __construct($key, array $config)
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tests\PHPCensor\Security\Authentication\UserProvider;
|
||||||
|
|
||||||
|
use PHPCensor\Model\User;
|
||||||
|
use PHPCensor\Security\Authentication\UserProvider\Internal;
|
||||||
|
|
||||||
|
class InternalTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Internal
|
||||||
|
*/
|
||||||
|
protected $provider;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->provider = new Internal('internal', [
|
||||||
|
'type' => 'internal',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Internal::verifyPassword
|
||||||
|
*/
|
||||||
|
public function testVerifyPassword()
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$password = 'bla';
|
||||||
|
$user->setHash(password_hash($password, PASSWORD_DEFAULT));
|
||||||
|
|
||||||
|
$this->assertTrue($this->provider->verifyPassword($user, $password));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Internal::verifyPassword
|
||||||
|
*/
|
||||||
|
public function testVerifyInvaldPassword()
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$password = 'foo';
|
||||||
|
$user->setHash(password_hash($password, PASSWORD_DEFAULT));
|
||||||
|
|
||||||
|
$this->assertFalse($this->provider->verifyPassword($user, 'bar'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Internal::checkRequirements
|
||||||
|
*/
|
||||||
|
public function testCheckRequirements()
|
||||||
|
{
|
||||||
|
$this->provider->checkRequirements();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Internal::provisionUser
|
||||||
|
*/
|
||||||
|
public function testProvisionUser()
|
||||||
|
{
|
||||||
|
$this->assertNull($this->provider->provisionUser('john@doe.com'));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue