From 2041810adbc6e663e4520337805c0003c77762e2 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 31 Jan 2017 21:13:33 +0100 Subject: WIP --- src/Wallabag/CoreBundle/Entity/Entry.php | 6 + .../Resources/translations/messages.fr.yml | 22 ++- .../GroupBundle/Controller/ManageController.php | 90 ++++++++++- src/Wallabag/GroupBundle/Entity/Group.php | 172 +++++++++++++++++++-- src/Wallabag/GroupBundle/Entity/Invitation.php | 73 +++++++++ src/Wallabag/GroupBundle/Entity/UserGroup.php | 126 +++++++++++++++ src/Wallabag/GroupBundle/Form/GroupType.php | 28 ++++ src/Wallabag/GroupBundle/Form/NewGroupType.php | 28 ++++ src/Wallabag/GroupBundle/Form/UserGroupType.php | 46 ++++++ .../GroupBundle/Repository/GroupRepository.php | 33 ++++ .../GroupBundle/Resources/config/services.yml | 3 + .../Resources/views/Manage/edit.html.twig | 28 +++- .../Resources/views/Manage/index.html.twig | 3 + .../Resources/views/Manage/new.html.twig | 24 +++ src/Wallabag/GroupBundle/Service/Sha256Salted.php | 18 +++ src/Wallabag/UserBundle/Entity/User.php | 73 +++++++-- 16 files changed, 737 insertions(+), 36 deletions(-) create mode 100644 src/Wallabag/GroupBundle/Entity/Invitation.php create mode 100644 src/Wallabag/GroupBundle/Entity/UserGroup.php create mode 100644 src/Wallabag/GroupBundle/Form/UserGroupType.php create mode 100644 src/Wallabag/GroupBundle/Repository/GroupRepository.php create mode 100644 src/Wallabag/GroupBundle/Resources/config/services.yml create mode 100644 src/Wallabag/GroupBundle/Service/Sha256Salted.php diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index a0503c39..84555b36 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php @@ -233,6 +233,12 @@ class Entry */ private $tags; + /** + * @var ArrayCollection + * @ORM\ManyToMany(targetEntity="Wallabag\GroupBundle\Entity\Group", inversedBy="presentations", cascade={"persist"}) + */ + private $groupShares; + /* * @param User $user */ diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index beb8f324..d909cf15 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml @@ -515,8 +515,8 @@ developer: group: page_title: Gestion des groupes - new_group: Créer un nouveau group - edit_group: Éditer un nouveau groupe + new_group: Créer un nouveau groupe + edit_group: Éditer le groupe « %group% » description: Ici vous pouvez gérer vos groupes (création, mise à jour et suppression) list: actions: Actions @@ -531,6 +531,24 @@ group: delete: Supprimer delete_confirm: Êtes-vous sur ? back_to_list: Revenir à la liste + role_label: Rôles par défaut + access_label: Accès + password_label: Mot de passe (si nécessaire) + roles: + readonly: Lecture seule + write: Écriture + manage_entries: Gestion des articles + manage_users: Gestion des utilisateurs + admin: Administrateur + access: + open: Ouvert + request: Sur demande + password: Par mot de passe + invitation: Sur invitation + hidden: Sur invitation et privée + tab_menu: + public: Groupes publics + own: Mes groupes user: page_title: "Gestion des utilisateurs" diff --git a/src/Wallabag/GroupBundle/Controller/ManageController.php b/src/Wallabag/GroupBundle/Controller/ManageController.php index 7015a465..94196040 100644 --- a/src/Wallabag/GroupBundle/Controller/ManageController.php +++ b/src/Wallabag/GroupBundle/Controller/ManageController.php @@ -2,11 +2,20 @@ namespace Wallabag\GroupBundle\Controller; +use Pagerfanta\Adapter\DoctrineORMAdapter; +use Pagerfanta\Exception\OutOfRangeCurrentPageException; +use Pagerfanta\Pagerfanta; +use Strut\StrutBundle\Service\Sha256Salted; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use Symfony\Component\HttpFoundation\Response; use Wallabag\GroupBundle\Entity\Group; +use Wallabag\GroupBundle\Entity\UserGroup; +use Wallabag\GroupBundle\Form\GroupType; +use Wallabag\GroupBundle\Form\NewGroupType; +use Wallabag\UserBundle\Entity\User; /** * Group controller. @@ -14,19 +23,32 @@ use Wallabag\GroupBundle\Entity\Group; class ManageController extends Controller { /** - * Lists all Group entities. + * Lists all public Group entities. * - * @Route("/", name="group_index") + * @Route("/{page}", name="group_index", defaults={"page" = "1"}) * @Method("GET") */ - public function indexAction() + public function indexAction($page = 1) { $em = $this->getDoctrine()->getManager(); - $groups = $em->getRepository('WallabagGroupBundle:Group')->findAll(); + $groups = $em->getRepository('WallabagGroupBundle:Group')->findPublicGroups(); + + $pagerAdapter = new DoctrineORMAdapter($groups->getQuery(), true, false); + $pagerFanta = new Pagerfanta($pagerAdapter); + $pagerFanta->setMaxPerPage(1); + + try { + $pagerFanta->setCurrentPage($page); + } catch (OutOfRangeCurrentPageException $e) { + if ($page > 1) { + return $this->redirect($this->generateUrl('group_index', ['page' => $pagerFanta->getNbPages()]), 302); + } + } return $this->render('WallabagGroupBundle:Manage:index.html.twig', array( - 'groups' => $groups, + 'groups' => $pagerFanta, + 'currentPage' => $page, )); } @@ -38,14 +60,26 @@ class ManageController extends Controller */ public function newAction(Request $request) { - $group = new Group(''); + $group = new Group(); - $form = $this->createForm('Wallabag\GroupBundle\Form\NewGroupType', $group); + $form = $this->createForm(NewGroupType::class, $group); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); + + if ($group->getAcceptSystem() == Group::ACCESS_PASSWORD) { + /** @var Sha256Salted $encoder */ + $encoder = $this->get('sha256salted_encoder'); + $password = $encoder->encodePassword($group->getPassword(), $this->getParameter('secret')); + $group->setPassword($password); + } + $em->persist($group); + + $groupUser = new UserGroup($this->getUser(), $group, Group::ROLE_ADMIN); + $groupUser->setAccepted(true); + $em->persist($groupUser); $em->flush(); $this->get('session')->getFlashBag()->add( @@ -70,12 +104,23 @@ class ManageController extends Controller */ public function editAction(Request $request, Group $group) { + if ($this->getUser()->getGroupRoleForUser($group) < Group::ROLE_ADMIN) { + $this->createAccessDeniedException(); + } + $deleteForm = $this->createDeleteForm($group); - $editForm = $this->createForm('Wallabag\GroupBundle\Form\GroupType', $group); + $editForm = $this->createForm(GroupType::class, $group); $editForm->handleRequest($request); if ($editForm->isSubmitted() && $editForm->isValid()) { $em = $this->getDoctrine()->getManager(); + + if ($group->getAcceptSystem() === Group::ACCESS_PASSWORD) { + $encoder = $this->get('sha256salted_encoder'); + $password = $encoder->encodePassword($group->getPlainPassword(), $this->getParameter('secret')); + $group->setPassword($password); + } + $em->persist($group); $em->flush(); @@ -134,4 +179,33 @@ class ManageController extends Controller ->getForm() ; } + + /** + * @Route("/group-user-exclude/{group}/{user}", name="group-user-exclude") + * @param Group $group + * @param User $user + * @return Response + */ + public function excludeMemberAction(Group $group, User $user) + { + $logger = $this->get('logger'); + $logger->info('User ' . $this->getUser()->getUsername() . ' wants to exclude user ' . $user->getUsername() . ' from group ' . $group->getName()); + + if (!$this->getUser()->inGroup($group) || $this->getUser()->getGroupRoleForUser($group) < Group::ROLE_MANAGE_USERS) { + $logger->info('User ' . $this->getUser()->getUsername() . ' has not enough rights on group ' . $group->getName() . ' to exclude user ' . $user->getUsername()); + throw $this->createAccessDeniedException(); + } + + if ($user->inGroup($group) && $user->getGroupRoleForUser($group) < Group::ROLE_ADMIN) { + $em = $this->getDoctrine()->getManager(); + + $logger->info('Removing user ' . $this->getUser()->getUsername() . ' from group ' . $group->getName()); + $em->remove($this->getUser()->getUserGroupFromGroup($group)); + + $em->flush(); + + return $this->redirectToRoute('group-manage', ['group' => $group->getId()]); + } + throw $this->createAccessDeniedException(); + } } diff --git a/src/Wallabag/GroupBundle/Entity/Group.php b/src/Wallabag/GroupBundle/Entity/Group.php index 1381d1ea..31c82837 100644 --- a/src/Wallabag/GroupBundle/Entity/Group.php +++ b/src/Wallabag/GroupBundle/Entity/Group.php @@ -8,11 +8,50 @@ use Doctrine\ORM\Mapping as ORM; use Wallabag\UserBundle\Entity\User; /** - * @ORM\Entity + * @ORM\Entity(repositoryClass="Wallabag\GroupBundle\Repository\GroupRepository") * @ORM\Table(name="`group`") */ class Group extends BaseGroup { + + /** + * User Roles + */ + + /** User can only preview presentations */ + const ROLE_READ_ONLY = 1; + + /** User can create new presentations */ + const ROLE_WRITE = 2; + + /** User can manage all group presentations */ + const ROLE_MANAGE_ENTRIES = 3; + + /** User can manage users in the group */ + const ROLE_MANAGE_USERS = 5; + + /** User can rename and delete the group */ + const ROLE_ADMIN = 10; + + /** + * Group join access + */ + + /** Any user can join the group */ + const ACCESS_OPEN = 1; + + /** An user needs to request to join the group */ + const ACCESS_REQUEST = 2; + + /** An user need the password to access the group */ + const ACCESS_PASSWORD = 3; + + /** An user needs to be invited to join the group */ + const ACCESS_INVITATION_ONLY = 4; + + /** An user needs to be invited to join the group, and the group is not publicly listed */ + const ACCESS_HIDDEN = 10; + /** * @ORM\Id * @ORM\Column(type="integer") @@ -21,38 +60,141 @@ class Group extends BaseGroup protected $id; /** - * @ORM\ManyToMany(targetEntity="Wallabag\UserBundle\Entity\User", mappedBy="groups", cascade={"persist"}) + * @ORM\Column(type="integer", options={"default" : 1}) + */ + protected $acceptSystem; + + /** + * @ORM\Column(type="integer", options={"default" : 2}) + */ + protected $defaultRole; + + /** + * @ORM\Column(type="string", nullable=true) + */ + protected $password; + protected $plainPassword; + + /** + * @ORM\ManyToMany(targetEntity="Wallabag\CoreBundle\Entity\Entry", mappedBy="groupShares", cascade={"persist"}) + */ + protected $entries; + + /** + * @ORM\OneToMany(targetEntity="UserGroup", mappedBy="group", cascade={"persist"}) */ protected $users; - public function getUsers() + public function __construct($name = '', array $roles = []) { - return $this->users ?: $this->users = new ArrayCollection(); + parent::__construct($name, $roles); + $this->defaultRole = self::ROLE_READ_ONLY; + $this->acceptSystem = self::ACCESS_REQUEST; } - public function addUser(User $user) + /** + * @return ArrayCollection + */ + public function getUsers() { - if (!$this->getUsers()->contains($user)) { - $this->getUsers()->add($user); + $userObj = new ArrayCollection(); + foreach ($this->users as $userGroup) { + /** @var UserGroup $userGroup */ + $userObj->add($userGroup->getUser()); } + return $userObj; + } - return $this; + /** + * @return int + */ + public function getDefaultRole() + { + return $this->defaultRole; } /** - * {@inheritdoc} + * @return int */ - public function removeUser(User $user) + public function getAcceptSystem() { - if ($this->getUsers()->contains($user)) { - $this->getUsers()->removeElement($user); - } + return $this->acceptSystem; + } + + /** + * @param int $acceptSystem + */ + public function setAcceptSystem($acceptSystem) + { + $this->acceptSystem = $acceptSystem; + } - return $this; + /** + * @return string + */ + public function getPassword() + { + return $this->password ?: ''; + } + + /** + * @param string $password + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * @return string + */ + public function getPlainPassword() + { + return $this->plainPassword ?: ''; + } + + /** + * @param string $plainPassword + */ + public function setPlainPassword($plainPassword) + { + $this->plainPassword = $plainPassword; + } + + /** + * @param int $defaultRole + */ + public function setDefaultRole($defaultRole) + { + $this->defaultRole = $defaultRole; } public function __toString() { - return $this->getName(); + return $this->name; + } + + public function getRequests() + { + $requests = new ArrayCollection(); + foreach ($this->users as $user) /** @var UserGroup $user */ + { + if (!$user->isAccepted()) { + $requests->add($user->getUser()); + } + } + return $requests; + } + + public function getInvited() + { + $invited = new ArrayCollection(); + foreach ($this->users as $userGroup) /** @var UserGroup $userGroup */ + { + if ($userGroup->getInvitation()) { + $invited->add($userGroup); + } + } + return $invited; } } diff --git a/src/Wallabag/GroupBundle/Entity/Invitation.php b/src/Wallabag/GroupBundle/Entity/Invitation.php new file mode 100644 index 00000000..6946bede --- /dev/null +++ b/src/Wallabag/GroupBundle/Entity/Invitation.php @@ -0,0 +1,73 @@ +code = substr(md5(uniqid(rand(), true)), 0, 6); + $this->date = new \DateTime(); + $this->userGroup = $userGroup; + } + + public function getCode() + { + return $this->code; + } + + /** + * @return \DateTime + */ + public function getDate(): \DateTime + { + return $this->date; + } + + /** + * @param \DateTime $date + */ + public function setDate(\DateTime $date) + { + $this->date = $date; + } + + /** + * @return mixed + */ + public function getUserGroup(): UserGroup + { + return $this->userGroup; + } + + /** + * @param mixed $userGroup + */ + public function setUserGroup(UserGroup $userGroup) + { + $this->userGroup = $userGroup; + } +} diff --git a/src/Wallabag/GroupBundle/Entity/UserGroup.php b/src/Wallabag/GroupBundle/Entity/UserGroup.php new file mode 100644 index 00000000..22d1400a --- /dev/null +++ b/src/Wallabag/GroupBundle/Entity/UserGroup.php @@ -0,0 +1,126 @@ +user = $user; + $this->group = $group; + $this->role = $role; + $this->accepted = $request; + } + + /** + * @return Group + */ + public function getGroup() + { + return $this->group; + } + + /** + * @return int + */ + public function getRole() + { + return $this->role; + } + + /** + * @return User + */ + public function getUser() + { + return $this->user; + } + + /** + * @param int $role + * @return UserGroup + */ + public function setRole($role) + { + $this->role = $role; + return $this; + } + + /** + * @param bool $accepted + */ + public function setAccepted($accepted) + { + $this->accepted = $accepted; + } + + /** + * @return bool + */ + public function isAccepted() + { + return $this->accepted; + } + + public function setInvitation($invitation) + { + $this->invitation = $invitation; + } + + public function getInvitation() + { + return $this->invitation; + } +} diff --git a/src/Wallabag/GroupBundle/Form/GroupType.php b/src/Wallabag/GroupBundle/Form/GroupType.php index c2ad764b..c708bdb8 100644 --- a/src/Wallabag/GroupBundle/Form/GroupType.php +++ b/src/Wallabag/GroupBundle/Form/GroupType.php @@ -3,10 +3,13 @@ namespace Wallabag\GroupBundle\Form; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Wallabag\GroupBundle\Entity\Group; class GroupType extends AbstractType { @@ -21,6 +24,31 @@ class GroupType extends AbstractType 'required' => false, 'label' => 'group.form.name_label', ]) + ->add('defaultRole', ChoiceType::class, [ + 'label' => 'group.form.role_label', + 'choices' => [ + 'group.roles.readonly' => Group::ROLE_READ_ONLY, + 'group.roles.write' => Group::ROLE_WRITE, + 'group.roles.manage_entries' => Group::ROLE_MANAGE_ENTRIES, + 'group.roles.manage_users' => Group::ROLE_MANAGE_USERS, + 'group.roles.admin' => Group::ROLE_ADMIN, + ], + ]) + ->add('acceptSystem', ChoiceType::class, [ + 'label' => 'group.form.access_label', + 'choices' => [ + 'group.access.open' => Group::ACCESS_OPEN, + 'group.access.request' => Group::ACCESS_REQUEST, + 'group.access.password' => Group::ACCESS_PASSWORD, + 'group.access.invitation' => Group::ACCESS_INVITATION_ONLY, + 'group.access.hidden' => Group::ACCESS_HIDDEN, + ], + ]) + ->add('plainPassword', PasswordType::class, [ + 'label' => 'group.form.password_label', + 'required' => false, + 'attr' => ['autocomplete' => 'off'], + ]) ->add('save', SubmitType::class, [ 'label' => 'group.form.save', ]) diff --git a/src/Wallabag/GroupBundle/Form/NewGroupType.php b/src/Wallabag/GroupBundle/Form/NewGroupType.php index 29b20fe0..55eebc46 100644 --- a/src/Wallabag/GroupBundle/Form/NewGroupType.php +++ b/src/Wallabag/GroupBundle/Form/NewGroupType.php @@ -3,10 +3,13 @@ namespace Wallabag\GroupBundle\Form; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\GroupBundle\Entity\Group; class NewGroupType extends AbstractType { @@ -17,6 +20,31 @@ class NewGroupType extends AbstractType 'required' => true, 'label' => 'group.form.name_label', ]) + ->add('defaultRole', ChoiceType::class, [ + 'label' => 'group.form.role_label', + 'choices' => [ + 'group.roles.readonly' => Group::ROLE_READ_ONLY, + 'group.roles.write' => Group::ROLE_WRITE, + 'group.roles.manage_entries' => Group::ROLE_MANAGE_ENTRIES, + 'group.roles.manage_users' => Group::ROLE_MANAGE_USERS, + 'group.roles.admin' => Group::ROLE_ADMIN, + ], + ]) + ->add('acceptSystem', ChoiceType::class, [ + 'label' => 'group.form.access_label', + 'choices' => [ + 'group.access.open' => Group::ACCESS_OPEN, + 'group.access.request' => Group::ACCESS_REQUEST, + 'group.access.password' => Group::ACCESS_PASSWORD, + 'group.access.invitation' => Group::ACCESS_INVITATION_ONLY, + 'group.access.hidden' => Group::ACCESS_HIDDEN, + ], + ]) + ->add('plainPassword', PasswordType::class, [ + 'label' => 'group.form.password_label', + 'required' => false, + 'attr' => ['autocomplete' => 'off'], + ]) ->add('save', SubmitType::class, [ 'label' => 'group.form.save', ]) diff --git a/src/Wallabag/GroupBundle/Form/UserGroupType.php b/src/Wallabag/GroupBundle/Form/UserGroupType.php new file mode 100644 index 00000000..e8f814e4 --- /dev/null +++ b/src/Wallabag/GroupBundle/Form/UserGroupType.php @@ -0,0 +1,46 @@ +add('role', ChoiceType::class, [ + 'label' => 'group.edit_user.role', + 'choices' => [ + 'group.roles.readonly' => Group::ROLE_READ_ONLY, + 'group.roles.write' => Group::ROLE_WRITE, + 'group.roles.manage_prez' => Group::ROLE_MANAGE_PREZ, + 'group.roles.manage_users' => Group::ROLE_MANAGE_USERS, + 'group.roles.admin' => Group::ROLE_ADMIN, + ], + ]) + ->add('save', SubmitType::class, [ + 'label' => 'user.form.save', + ]) + ; + } + + /** + * @param OptionsResolver $resolver + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Strut\StrutBundle\Entity\UserGroup', + )); + } +} diff --git a/src/Wallabag/GroupBundle/Repository/GroupRepository.php b/src/Wallabag/GroupBundle/Repository/GroupRepository.php new file mode 100644 index 00000000..47340d07 --- /dev/null +++ b/src/Wallabag/GroupBundle/Repository/GroupRepository.php @@ -0,0 +1,33 @@ +createQueryBuilder('g'); + } + + public function findPublicGroups() + { + return $this->getBuilder() + ->where('g.acceptSystem < 10'); + } + + public function findGroupsByUser(User $user) + { + return $this->getBuilder() + ->join('Wallabag\GroupBundle\Entity\UserGroup', 'u', 'WITH', 'u.group = g.id') + ->where('u.user = :user')->setParameter(':user', $user->getId()); + } +} diff --git a/src/Wallabag/GroupBundle/Resources/config/services.yml b/src/Wallabag/GroupBundle/Resources/config/services.yml new file mode 100644 index 00000000..76e8427a --- /dev/null +++ b/src/Wallabag/GroupBundle/Resources/config/services.yml @@ -0,0 +1,3 @@ +services: + sha256salted_encoder: + class: Strut\StrutBundle\Service\Sha256Salted \ No newline at end of file diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig index 7de68c35..c12e8625 100644 --- a/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig +++ b/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig @@ -1,6 +1,6 @@ {% extends "WallabagCoreBundle::layout.html.twig" %} -{% block title %}{{ 'group.page_title'|trans }}{% endblock %} +{% block title %}{{ 'group.page_title' | trans }}{% endblock %} {% block content %} @@ -9,7 +9,7 @@
-

{{ 'group.edit_group'|trans }}

+

{{ 'group.edit_group'|trans({'%group%': group.name }) }}

{{ form_start(edit_form) }} @@ -23,6 +23,30 @@
+
+
+ {{ form_label(edit_form.defaultRole) }} + {{ form_errors(edit_form.defaultRole) }} + {{ form_widget(edit_form.defaultRole) }} +
+
+ +
+
+ {{ form_label(edit_form.acceptSystem) }} + {{ form_errors(edit_form.acceptSystem) }} + {{ form_widget(edit_form.acceptSystem) }} +
+
+ +
+
+ {{ form_label(edit_form.plainPassword) }} + {{ form_errors(edit_form.plainPassword) }} + {{ form_widget(edit_form.plainPassword) }} +
+
+
{{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig index 58af3a75..01466e52 100644 --- a/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig +++ b/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig @@ -37,6 +37,9 @@

{{ 'group.list.create_new_one'|trans }}

+ {% if groups.getNbPages > 1 %} + {{ pagerfanta(groups, 'twitter_bootstrap_translated', {'proximity': 1}) }} + {% endif %}
diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig index 3f1c2ad5..cb009b5d 100644 --- a/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig +++ b/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig @@ -23,6 +23,30 @@ +
+
+ {{ form_label(form.defaultRole) }} + {{ form_errors(form.defaultRole) }} + {{ form_widget(form.defaultRole) }} +
+
+ +
+
+ {{ form_label(form.acceptSystem) }} + {{ form_errors(form.acceptSystem) }} + {{ form_widget(form.acceptSystem) }} +
+
+ +
+
+ {{ form_label(form.plainPassword) }} + {{ form_errors(form.plainPassword) }} + {{ form_widget(form.plainPassword) }} +
+
+ {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/GroupBundle/Service/Sha256Salted.php b/src/Wallabag/GroupBundle/Service/Sha256Salted.php new file mode 100644 index 00000000..c72486ad --- /dev/null +++ b/src/Wallabag/GroupBundle/Service/Sha256Salted.php @@ -0,0 +1,18 @@ +encodePassword($raw, $salt); + } +} diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index ff658ca5..2b73e344 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -15,6 +15,8 @@ use Symfony\Component\Security\Core\User\UserInterface; use Wallabag\ApiBundle\Entity\Client; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\GroupBundle\Entity\Group; +use Wallabag\GroupBundle\Entity\UserGroup; /** * User. @@ -98,13 +100,11 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf private $authCode; /** - * @ORM\ManyToMany(targetEntity="Wallabag\GroupBundle\Entity\Group", inversedBy="users", cascade={"persist"}) - * @ORM\JoinTable(name="user_group", - * joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, - * inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")} - * ) + * @var ArrayCollection + * + * @ORM\OneToMany(targetEntity="Wallabag\GroupBundle\Entity\UserGroup", mappedBy="user", cascade={"persist", "remove"}) */ - protected $groups; + protected $userGroups; /** * @var bool Enabled yes/no @@ -136,6 +136,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf { parent::__construct(); $this->entries = new ArrayCollection(); + $this->userGroups = new ArrayCollection(); $this->roles = ['ROLE_USER']; } @@ -323,11 +324,65 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf } /** - * @param string $name + * @param Group $group + * @return UserGroup + */ + public function getUserGroupFromGroup(Group $group) + { + foreach ($this->userGroups as $userGroup) { + if ($userGroup->getGroup() == $group) { + return $userGroup; + } + } + return null; + } + + + /** + * @param Group $group + * @param $role + */ + public function setGroupRole(Group $group, $role) + { + if ($userGroup = $this->getUserGroupFromGroup($group)) { + $userGroup->setRole($role); + } + } + + /** + * @param Group $group + * @return int + */ + public function getGroupRoleForUser(Group $group) + { + if ($userGroup = $this->getUserGroupFromGroup($group)) { + return $userGroup->getRole(); + } + return 0; + } + + /** + * @param Group $group * @return bool */ - public function hasGroup($name = '') + public function inGroup(Group $group) { - return in_array($name, $this->getGroupNames()); + if ($group::ACCESS_REQUEST === $group->getAcceptSystem()) { + $userGroup = $this->getUserGroupFromGroup($group); + return $userGroup->isAccepted(); + } + return null !== $this->getUserGroupFromGroup($group); + } + + /** + * @return ArrayCollection + */ + public function getGroups() + { + $groups = new ArrayCollection(); + foreach ($this->userGroups as $userGroup) { + $groups->add($userGroup->getGroup()); + } + return $groups; } } -- cgit v1.2.3