diff --git a/src/Security/AdminModule/DefaultPresenter.php b/src/Security/AdminModule/DefaultPresenter.php index 32a35d70..d952e721 100755 --- a/src/Security/AdminModule/DefaultPresenter.php +++ b/src/Security/AdminModule/DefaultPresenter.php @@ -93,22 +93,20 @@ protected function startup() */ protected function createComponentTable() { - $repository = $this->entityManager->getRepository($this->type); - $admin = $this->adminGridFactory->create($repository); + $admin = $this->adminGridFactory->create($this->userRepository); $table = $admin->getTable(); $table->setTranslator($this->translator); - $table->setPrimaryKey('user.id'); - $table->addColumnText('user.email', 'E-mail') + $table->addColumnText('email', 'E-mail') ->setSortable() ->getCellPrototype()->width = '100%'; - $table->getColumn('user.email') + $table->getColumn('email') ->setFilterText()->setSuggestion(); - $form = $admin->addForm('user', 'User', function (ExtendedUser $extendedUser = null) { - return $this->getUserType()->getFormService()->getFormFactory($extendedUser ? $extendedUser->getUser()->getId() : null); + $form = $admin->addForm('user', 'User', function (User $user = null) { + return $this->getUserType()->getFormService()->getFormFactory($user ? $user->getId() : null); }, Form::TYPE_LARGE); - $form->onSuccess[] = function (\Nette\Application\UI\Form $form) { + $form->onSuccess[] = function () { $this->flashMessage('User has been saved.', 'success'); $this->redrawControl('flashes'); }; diff --git a/src/Security/DI/SecurityExtension.php b/src/Security/DI/SecurityExtension.php index 64e19c8c..fd25f938 100755 --- a/src/Security/DI/SecurityExtension.php +++ b/src/Security/DI/SecurityExtension.php @@ -15,6 +15,7 @@ use Kdyby\Events\DI\EventsExtension; use Nette\DI\ContainerBuilder; use Nette\DI\Statement; +use Venne\Security\DefaultType\Mapping\PasswordContainer; use Venne\Security\Events\LoginEvent; use Venne\Security\Events\NewPasswordEvent; use Venne\Security\Events\PasswordRecoveryEvent; @@ -28,6 +29,7 @@ class SecurityExtension extends \Nette\DI\CompilerExtension implements \Kdyby\Doctrine\DI\IEntityProvider, \Venne\Notifications\DI\IEventProvider, \Venne\System\DI\IPresenterProvider, + \Venne\System\DI\IFormMapperProvider, \Venne\Security\DI\UserTypeProvider { @@ -72,6 +74,9 @@ public function loadConfiguration() ->setFactory('Venne\System\Commands\InstallCommand') ->addTag(ConsoleExtension::COMMAND_TAG); + $container->addDefinition($this->prefix('passwordContainerMapper')) + ->setClass(PasswordContainer::class); + $this->setupSecurity($container); $this->registerUsers(); } @@ -176,4 +181,14 @@ public function getUserTypes() ); } + /** + * @return string[] + */ + public function getFormMappers() + { + return array( + PasswordContainer::class, + ); + } + } diff --git a/src/Security/DefaultType/AdminFormFactory.php b/src/Security/DefaultType/AdminFormFactory.php index d62bc690..f4919cc1 100755 --- a/src/Security/DefaultType/AdminFormFactory.php +++ b/src/Security/DefaultType/AdminFormFactory.php @@ -45,22 +45,12 @@ public function create() $user->addText('name', 'Name'); $user->addTextArea('notation', 'Notation', 40, 4) ->getControlPrototype()->attrs['class'] = 'input-block-level'; - $user->addMultiSelect('roleEntities', 'Roles') + $user->addMultiSelect('entityRoles', 'Roles') ->setOption(IComponentMapper::ITEMS_TITLE, 'name'); $user->addText('key', 'Lock key') ->setOption('description', 'If is set user cannot log in.'); - $user->setCurrentGroup($form->addGroup('Password')); - $passwordNew = $user->addCheckbox('password_new', 'Change password'); - $passwordNew->addCondition($form::EQUAL, true)->toggle('setPasswd'); - $user->setCurrentGroup($form->addGroup()->setOption('container', 'fieldset id=setPasswd')); - $user->addPassword('password', 'Password') - ->addConditionOn($passwordNew, Form::FILLED) - ->addRule(Form::FILLED, 'Enter password') - ->addRule(Form::MIN_LENGTH, 'Password is short', 5); - $user->addPassword('password_confirm', 'Confirm password') - ->addConditionOn($passwordNew, Form::FILLED) - ->addRule(Form::EQUAL, 'Invalid re password', $user['password']); + $user['password'] = new PasswordContainer(); return $form; } diff --git a/src/Security/DefaultType/FrontFormFactory.php b/src/Security/DefaultType/FrontFormFactory.php index 4757780a..ed78f2c8 100755 --- a/src/Security/DefaultType/FrontFormFactory.php +++ b/src/Security/DefaultType/FrontFormFactory.php @@ -42,20 +42,7 @@ public function create() $user->addTextArea('notation', 'Notation', 40, 4) ->getControlPrototype()->attrs['class'] = 'input-block-level'; - //$route = $user->addOne('route'); - //$route->setCurrentGroup($group); - //$route->addFileEntityInput('photo', 'Avatar'); - - $user->setCurrentGroup($form->addGroup('Password')); - $user->addCheckbox('password_new', 'Change password')->addCondition($form::EQUAL, true)->toggle('setPasswd'); - $user->setCurrentGroup($form->addGroup()->setOption('id', 'setPasswd')); - $user->addPassword('password', 'Password') - ->addConditionOn($user['password_new'], $form::FILLED) - ->addRule($form::FILLED, 'Enter password') - ->addRule($form::MIN_LENGTH, 'Password is short', 5); - $user->addPassword('password_confirm', 'Confirm password') - ->addConditionOn($user['password_new'], $form::FILLED) - ->addRule($form::EQUAL, 'Invalid re password', $user['password']); + $user['password'] = new PasswordContainer(); return $form; } diff --git a/src/Security/DefaultType/FrontFormService.php b/src/Security/DefaultType/FrontFormService.php index bff173c5..8876d3ac 100644 --- a/src/Security/DefaultType/FrontFormService.php +++ b/src/Security/DefaultType/FrontFormService.php @@ -44,8 +44,9 @@ protected function save(Form $form, $entity) try { $this->getEntityFormMapper()->save($entity, $form); - $this->getEntityManager()->persist($entity); + $this->getEntityManager()->persist($entity->getUser()); $this->getEntityManager()->flush($entity->getUser()); + $this->getEntityManager()->persist($entity); $this->getEntityManager()->flush($entity); $this->getEntityManager()->commit(); diff --git a/src/Security/DefaultType/Mapping/PasswordContainer.php b/src/Security/DefaultType/Mapping/PasswordContainer.php new file mode 100644 index 00000000..5bba9acc --- /dev/null +++ b/src/Security/DefaultType/Mapping/PasswordContainer.php @@ -0,0 +1,75 @@ + + */ +class PasswordContainer extends \Nette\Object implements \Kdyby\DoctrineForms\IComponentMapper +{ + + /** @var \Kdyby\DoctrineForms\EntityFormMapper */ + private $mapper; + + public function setEntityFormMapper(EntityFormMapper $mapper) + { + $this->mapper = $mapper; + } + + /** + * @param ClassMetadata $meta + * @param Component $component + * @param object $entity + * @return boolean + */ + public function load(ClassMetadata $meta, Component $component, $entity) + { + if (!$component instanceof \Venne\Security\DefaultType\PasswordContainer) { + return false; + } + + if (!$entity instanceof User) { + return false; + } + + return true; + } + + /** + * @param ClassMetadata $meta + * @param Component $component + * @param object $entity + * @return boolean + */ + public function save(ClassMetadata $meta, Component $component, $entity) + { + if (!$component instanceof \Venne\Security\DefaultType\PasswordContainer) { + return false; + } + + if (!$entity instanceof User) { + return false; + } + + if ($component->isPasswordSet()) { + $entity->setPassword($component->getValue()); + } + + return true; + } + +} diff --git a/src/Security/DefaultType/PasswordContainer.php b/src/Security/DefaultType/PasswordContainer.php new file mode 100644 index 00000000..2cf9a258 --- /dev/null +++ b/src/Security/DefaultType/PasswordContainer.php @@ -0,0 +1,70 @@ + + */ +class PasswordContainer extends \Nette\Forms\Container +{ + + /** @var boolean */ + private $forceChangePassword; + + public function __construct($forceChangePassword = false) + { + $this->monitor(Form::class); + $this->forceChangePassword = $forceChangePassword; + } + + protected function attached($obj) + { + parent::attached($obj); + + $form = $this->getForm(); + + $this->setCurrentGroup($form->addGroup()); + + if (!$this->forceChangePassword) { + $passwordNew = $this->addCheckbox('password_new', 'Change password'); + $passwordNew->addCondition($form::EQUAL, true)->toggle('setPasswd'); + } + + $this->setCurrentGroup($form->addGroup()->setOption('container', 'fieldset id=setPasswd')); + $this->addPassword('password_set', 'Password') + ->addConditionOn($passwordNew, Form::FILLED) + ->addRule(Form::FILLED, 'Enter password') + ->addRule(Form::MIN_LENGTH, 'Password is short', 5); + $this->addPassword('password_confirm', 'Confirm password') + ->addConditionOn($passwordNew, Form::FILLED) + ->addRule(Form::EQUAL, 'Invalid re password', $this['password_set']); + } + + /** + * @return boolean + */ + public function isPasswordSet() + { + return $this->forceChangePassword || (boolean) $this['password_new']->getValue(); + } + + /** + * @return string + */ + public function getValue() + { + return $this['password_set']->getValue(); + } + +} diff --git a/src/Security/DefaultType/RegistrationFormFactory.php b/src/Security/DefaultType/RegistrationFormFactory.php index 2b659619..f4716cd6 100755 --- a/src/Security/DefaultType/RegistrationFormFactory.php +++ b/src/Security/DefaultType/RegistrationFormFactory.php @@ -12,15 +12,12 @@ namespace Venne\Security\DefaultType; use Nette\Forms\Form; -use Nette\Utils\Random; use Venne\Forms\IFormFactory; -use Venne\Security\ILoginProvider; -use Venne\Security\IRegistrationForm; /** * @author Josef Kříž */ -class RegistrationFormFactory extends \Nette\Object implements IRegistrationForm, IFormFactory +class RegistrationFormFactory extends \Nette\Object implements IFormFactory { /** @var \Venne\Forms\IFormFactory */ @@ -43,25 +40,9 @@ public function create() $user->addText('email', 'E-mail') ->addRule(Form::EMAIL, 'Enter email'); - $user->addPassword('password', 'Password') - ->addRule(Form::FILLED, 'Enter password') - ->addRule(Form::MIN_LENGTH, 'Password is short', 5); - $user->addPassword('password_confirm', 'Confirm password') - ->addRule(Form::EQUAL, 'Invalid re password', $user['password']); + $user['password'] = new PasswordContainer(); return $form; } - /** - * @param Form $form - * @param ILoginProvider $loginProvider - */ - public function connectWithLoginProvider(Form $form, ILoginProvider $loginProvider) - { - $loginProviderEntity = $loginProvider->getLoginProviderEntity(); - - $form['user']['email']->setValue($loginProviderEntity->email); - $form['user']['password_confirm']->value = $form['user']['password']->value = Random::generate(); - } - } diff --git a/src/Security/DefaultType/RegistrationFormService.php b/src/Security/DefaultType/RegistrationFormService.php index 966e7bd7..3fbc5af8 100644 --- a/src/Security/DefaultType/RegistrationFormService.php +++ b/src/Security/DefaultType/RegistrationFormService.php @@ -46,8 +46,9 @@ protected function save(Form $form, $entity) try { $this->getEntityFormMapper()->save($entity, $form); - $this->getEntityManager()->persist($entity); + $this->getEntityManager()->persist($entity->getUser()); $this->getEntityManager()->flush($entity->getUser()); + $this->getEntityManager()->persist($entity); $this->getEntityManager()->flush($entity); $this->getEntityManager()->commit(); diff --git a/src/Security/IRegistrationForm.php b/src/Security/IRegistrationForm.php deleted file mode 100755 index 3b812370..00000000 --- a/src/Security/IRegistrationForm.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ -interface IRegistrationForm -{ - - /** - * @param \Nette\Forms\Form $form - * @param \Venne\Security\ILoginProvider $loginProvider - */ - public function connectWithLoginProvider(Form $form, ILoginProvider $loginProvider); - -} diff --git a/src/Security/User.php b/src/Security/User.php index 98974f51..dc42ad49 100644 --- a/src/Security/User.php +++ b/src/Security/User.php @@ -84,7 +84,7 @@ class User extends \Kdyby\Doctrine\Entities\BaseEntity implements \Nette\Securit * inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE")} * ) */ - protected $roleEntities; + private $roleEntities; /** * @var \Venne\Security\Login[]|\Doctrine\Common\Collections\ArrayCollection @@ -286,6 +286,24 @@ public function __toString() return $this->name !== null ? $this->name : (string) $this->email; } + /** + * @return ArrayCollection|Role[] + */ + public function getEntityRoles() + { + return $this->roleEntities->toArray(); + } + + public function addEntityRole(Role $role) + { + $this->roleEntities[] = $role; + } + + public function removeRole(Role $role) + { + $this->roleEntities->removeElement($role); + } + /******************************** Getters and setters **************************************/ /** diff --git a/src/System/Forms/DoctrineForms/Controls/TextControl.php b/src/System/Forms/DoctrineForms/Controls/TextControl.php index 1a240282..45cb23c1 100755 --- a/src/System/Forms/DoctrineForms/Controls/TextControl.php +++ b/src/System/Forms/DoctrineForms/Controls/TextControl.php @@ -1,11 +1,12 @@