From 649fafe5c0a5f51c0e8abd200ce2f6699a74a255 Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Thu, 9 Aug 2012 08:38:39 +0200 Subject: [PATCH 1/7] Added new ideas to TODO Signed-off-by: Gergely Polonkai --- TODO | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index a60decb..d5841c3 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,12 @@ -PDF header fix +* PDF header fix +* draft flag for Document and Article: only writer and administrators see it from the Document/Article list, in preview mode +* site-based theme for ckeditor (both ui and the editor) +* full Document/Article list for administrators +* news editor for administrators + +Document + draft + News sticky @@ -29,7 +37,10 @@ PollAnswer poll (back-reference to Poll) text -Article check if public +Article +* check if public + draft + category (new entity) UserForumViewed User From 121f6a110cfab10968f07803a2dbb1f7dfd7e8d8 Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Thu, 9 Aug 2012 09:31:44 +0200 Subject: [PATCH 2/7] Article view is now security aware ArticleController::viewAction is now aware of Article::public Signed-off-by: Gergely Polonkai --- src/KekRozsak/FrontBundle/Controller/ArticleController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/KekRozsak/FrontBundle/Controller/ArticleController.php b/src/KekRozsak/FrontBundle/Controller/ArticleController.php index 078e9c0..03792d0 100644 --- a/src/KekRozsak/FrontBundle/Controller/ArticleController.php +++ b/src/KekRozsak/FrontBundle/Controller/ArticleController.php @@ -20,6 +20,9 @@ class ArticleController extends Controller */ public function viewAction(Article $article) { + if ((!is_object($this->_securityContext->getToken()) || !is_object($this->_securityContext->getToken()->getUser())) && !$article->isPublic()) + throw new AccessDeniedException('A cikk megtekintéséhez be kell jelentkezned!'); + return array( 'article' => $article, ); From f782c28678ed7ee38e7a8f8d642a4484d7a6f2af Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Thu, 9 Aug 2012 17:53:55 +0200 Subject: [PATCH 3/7] Changed the style of non- buttons Signed-off-by: Gergely Polonkai --- app/Resources/views/Box/Events.html.twig | 2 +- app/Resources/views/Box/Login.html.twig | 2 +- app/Resources/views/Box/UserProfile.html.twig | 2 +- app/Resources/views/main_template.html.twig | 4 +++- web/css/kekrozsak_front.css | 10 ++++++++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/Resources/views/Box/Events.html.twig b/app/Resources/views/Box/Events.html.twig index b611451..419b41f 100644 --- a/app/Resources/views/Box/Events.html.twig +++ b/app/Resources/views/Box/Events.html.twig @@ -1,7 +1,7 @@ {# vim: ft=htmljinja #}
- [események gomb] + [események gomb]

{{ firstDay|date('Y-m') }}

diff --git a/app/Resources/views/Box/Login.html.twig b/app/Resources/views/Box/Login.html.twig index 92ddaf7..349fb58 100644 --- a/app/Resources/views/Box/Login.html.twig +++ b/app/Resources/views/Box/Login.html.twig @@ -1,7 +1,7 @@ {# vim: ft=htmljinja #}
- Bejelentkezés + Bejelentkezés
diff --git a/app/Resources/views/Box/UserProfile.html.twig b/app/Resources/views/Box/UserProfile.html.twig index a164d67..75a858c 100644 --- a/app/Resources/views/Box/UserProfile.html.twig +++ b/app/Resources/views/Box/UserProfile.html.twig @@ -1,7 +1,7 @@ {# vim: ft=htmljinja #}
- [avatar] {{ app.user.displayName }} + [avatar] {{ app.user.displayName }}
[avatar] diff --git a/app/Resources/views/main_template.html.twig b/app/Resources/views/main_template.html.twig index 362cea4..5f08c12 100644 --- a/app/Resources/views/main_template.html.twig +++ b/app/Resources/views/main_template.html.twig @@ -35,15 +35,17 @@ {% include ':Box:UserProfile.html.twig' %} {% include ':Box:Events.html.twig' %} {% else %} {% include ':Box:Login.html.twig' %} {% endif %} +{# +#}
diff --git a/web/css/kekrozsak_front.css b/web/css/kekrozsak_front.css index 459b3c2..ccb6660 100644 --- a/web/css/kekrozsak_front.css +++ b/web/css/kekrozsak_front.css @@ -465,5 +465,15 @@ td.uj-post p .kuldes-gomb { background-color: #cccccc; color: black; white-space: nowrap; + cursor: pointer; +} + +#top-line .gomb { + background-color: transparent; + color: #c4d3ff; +} + +.gomb a { + color: inherit !important; } From 099a6d3609cc8ab026676657dfbd941332bb832b Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Thu, 9 Aug 2012 17:54:55 +0200 Subject: [PATCH 4/7] Bug fix: _securityController was not defined in ArticleController Signed-off-by: Gergely Polonkai --- src/KekRozsak/FrontBundle/Controller/ArticleController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/KekRozsak/FrontBundle/Controller/ArticleController.php b/src/KekRozsak/FrontBundle/Controller/ArticleController.php index 03792d0..4735d94 100644 --- a/src/KekRozsak/FrontBundle/Controller/ArticleController.php +++ b/src/KekRozsak/FrontBundle/Controller/ArticleController.php @@ -6,6 +6,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; use KekRozsak\FrontBundle\Entity\Article; @@ -20,7 +21,8 @@ class ArticleController extends Controller */ public function viewAction(Article $article) { - if ((!is_object($this->_securityContext->getToken()) || !is_object($this->_securityContext->getToken()->getUser())) && !$article->isPublic()) + $scontext = $this->get('security.context'); + if ((!is_object($scontext->getToken()) || !is_object($scontext->getToken()->getUser())) && !$article->isPublic()) throw new AccessDeniedException('A cikk megtekintéséhez be kell jelentkezned!'); return array( From 828dccba7abd0d225ff38c8ffdee552a3f766fb2 Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Thu, 9 Aug 2012 18:36:08 +0200 Subject: [PATCH 5/7] Bug fix: AccessDeniedException was not imported in EventController Signed-off-by: Gergely Polonkai --- src/KekRozsak/FrontBundle/Controller/EventController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KekRozsak/FrontBundle/Controller/EventController.php b/src/KekRozsak/FrontBundle/Controller/EventController.php index b9c72ba..9ec141d 100644 --- a/src/KekRozsak/FrontBundle/Controller/EventController.php +++ b/src/KekRozsak/FrontBundle/Controller/EventController.php @@ -6,6 +6,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; use KekRozsak\FrontBundle\Entity\Event; From 3b9788462c20559b884c033f9575a1e9b39c1b2b Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Fri, 10 Aug 2012 01:15:22 +0200 Subject: [PATCH 6/7] Updated and priorized TODO Signed-off-by: Gergely Polonkai --- TODO | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index d5841c3..2b897a7 100644 --- a/TODO +++ b/TODO @@ -1,17 +1,29 @@ -* PDF header fix -* draft flag for Document and Article: only writer and administrators see it from the Document/Article list, in preview mode -* site-based theme for ckeditor (both ui and the editor) -* full Document/Article list for administrators +* book creation + +* event creation + +* "sticky" news flag + * news editor for administrators -Document - draft +* PDF header fix -News - sticky +* draft flag for Document and Article: only writer and administrators see it + from the Document/Article list, in preview mode -User - FavouriteForumTopics +* full Document/Article list for administrators + +* polls + +* chat + +* Users' favourite forum topics + +* article categories + +* blog + +* site-based theme for ckeditor (both ui and the editor) Poll id @@ -37,11 +49,6 @@ PollAnswer poll (back-reference to Poll) text -Article -* check if public - draft - category (new entity) - UserForumViewed User ForumTopic @@ -90,3 +97,9 @@ GroupChatMessage from user to group timestamp + +PublicChatMessage + id + from user + to channel (ChatChannel class with id and name fields) + timestamp From b613d6223af9b70e37db9f5e2a14cffc4b6b2d6d Mon Sep 17 00:00:00 2001 From: Polonkai Gergely Date: Wed, 15 Aug 2012 09:59:37 +0200 Subject: [PATCH 7/7] Added Role hierarchy service. Signed-off-by: Gergely Polonkai --- .../Version20120815091637.php | 32 ++++++++ .../Compiler/OverrideServiceCompilerPass.php | 16 ++++ src/KekRozsak/SecurityBundle/Entity/Role.php | 78 ++++++------------- src/KekRozsak/SecurityBundle/Entity/User.php | 13 +++- .../KekRozsakSecurityBundle.php | 8 ++ .../SecurityBundle/Service/RoleHierarchy.php | 57 ++++++++++++++ 6 files changed, 147 insertions(+), 57 deletions(-) create mode 100644 app/DoctrineMigrations/Version20120815091637.php create mode 100644 src/KekRozsak/SecurityBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php create mode 100644 src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php diff --git a/app/DoctrineMigrations/Version20120815091637.php b/app/DoctrineMigrations/Version20120815091637.php new file mode 100644 index 0000000..a35708a --- /dev/null +++ b/app/DoctrineMigrations/Version20120815091637.php @@ -0,0 +1,32 @@ +abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); + + $this->addSql("CREATE TABLE role_hierarchy (parent_role_id INT NOT NULL, child_role_id INT NOT NULL, INDEX IDX_AB8EFB72A44B56EA (parent_role_id), INDEX IDX_AB8EFB72B4B76AB7 (child_role_id), PRIMARY KEY(parent_role_id, child_role_id)) ENGINE = InnoDB"); + $this->addSql("ALTER TABLE role_hierarchy ADD CONSTRAINT FK_AB8EFB72A44B56EA FOREIGN KEY (parent_role_id) REFERENCES roles (id)"); + $this->addSql("ALTER TABLE role_hierarchy ADD CONSTRAINT FK_AB8EFB72B4B76AB7 FOREIGN KEY (child_role_id) REFERENCES roles (id)"); + $this->addSql("ALTER TABLE roles DROP admin, DROP superAdmin"); + } + + public function down(Schema $schema) + { + // this down() migration is autogenerated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); + + $this->addSql("DROP TABLE role_hierarchy"); + $this->addSql("ALTER TABLE roles ADD admin TINYINT(1) NOT NULL, ADD superAdmin TINYINT(1) NOT NULL"); + } +} diff --git a/src/KekRozsak/SecurityBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php b/src/KekRozsak/SecurityBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php new file mode 100644 index 0000000..59947ae --- /dev/null +++ b/src/KekRozsak/SecurityBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php @@ -0,0 +1,16 @@ +getDefinition('security.role_hierarchy'); + $definition->setClass('KekRozsak\SecurityBundle\Service\RoleHierarchy'); + $definition->setArguments(array(new Reference('doctrine'))); + } +} diff --git a/src/KekRozsak/SecurityBundle/Entity/Role.php b/src/KekRozsak/SecurityBundle/Entity/Role.php index 159e0c8..e92f31d 100644 --- a/src/KekRozsak/SecurityBundle/Entity/Role.php +++ b/src/KekRozsak/SecurityBundle/Entity/Role.php @@ -78,62 +78,6 @@ class Role implements RoleInterface return $this; } - /** - * @var boolean $admin - * @ORM\Column(type="boolean", nullable=false) - */ - protected $admin; - - /** - * Set admin - * - * @param boolean $admin - * @return Role - */ - public function setAdmin($admin) - { - $this->admin = $admin; - return $this; - } - - /** - * Get admin - * - * @return boolean - */ - public function isAdmin() - { - return $this->admin; - } - - /** - * @var boolean $superadmin - * @ORM\Column(type="boolean", nullable=false) - */ - protected $superAdmin; - - /** - * Set superadmin - * - * @param boolean $superadmin - * @return Role - */ - public function setSuperadmin($superadmin) - { - $this->superadmin = $superadmin; - return $this; - } - - /** - * Get superadmin - * - * @return boolean - */ - public function getSuperadmin() - { - return $this->superadmin; - } - /** * @var text description * @ORM\Column(type="string", length=150, nullable=true) @@ -199,5 +143,27 @@ class Role implements RoleInterface { return $this->shortDescription; } + + /** + * List of inherited Roles + * + * @ORM\ManyToMany(targetEntity="Role", fetch="LAZY") + * @ORM\JoinTable(name="role_hierarchy", joinColumns={ + * @ORM\JoinColumn(name="parent_role_id", referencedColumnName="id") + * }, inverseJoinColumns={ + * @ORM\JoinColumn(name="child_role_id", referencedColumnName="id") + * }) + */ + protected $inheritedRoles; + + /** + * Get all inherited roles + * + * @return Doctrine\Common\Collections\ArrayCollection + */ + public function getInheritedRoles() + { + return $this->inheritedRoles; + } } diff --git a/src/KekRozsak/SecurityBundle/Entity/User.php b/src/KekRozsak/SecurityBundle/Entity/User.php index 415ecde..f5f50ec 100644 --- a/src/KekRozsak/SecurityBundle/Entity/User.php +++ b/src/KekRozsak/SecurityBundle/Entity/User.php @@ -323,7 +323,18 @@ class User implements UserInterface, AdvancedUserInterface } /** - * Get all roles + * Get all roles as an ArrayCollection + * + * @return Doctrine\Common\Collections\ArrayCollection + */ + public function getRolesCollection() + { + return $this->roles; + } + + /** + * Get all roles, for UserInterface implementation. To get the + * collection, use getRolesCollection() instead * * @return array */ diff --git a/src/KekRozsak/SecurityBundle/KekRozsakSecurityBundle.php b/src/KekRozsak/SecurityBundle/KekRozsakSecurityBundle.php index 26a4099..e8d27b7 100644 --- a/src/KekRozsak/SecurityBundle/KekRozsakSecurityBundle.php +++ b/src/KekRozsak/SecurityBundle/KekRozsakSecurityBundle.php @@ -3,7 +3,15 @@ namespace KekRozsak\SecurityBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +use KekRozsak\SecurityBundle\DependencyInjection\Compiler\OverrideServiceCompilerPass; class KekRozsakSecurityBundle extends Bundle { + public function build(ContainerBuilder $container) + { + parent::build($container); + $container->addCompilerPass(new OverrideServiceCompilerPass()); + } } diff --git a/src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php b/src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php new file mode 100644 index 0000000..6105777 --- /dev/null +++ b/src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php @@ -0,0 +1,57 @@ +hierarchy = array(); + $this->roleRepo = $doctrine->getRepository('KekRozsakSecurityBundle:Role'); + + $this->buildRoleMap(); + } + + public function getReachableRoles(array $roles) + { + $reachableRoles = array(); + foreach ($roles as $role) { + if (!isset($this->map[$role->getRole()])) { + continue; + } + + foreach ($this->map[$role->getRole()] as $r) { + if (($childRole = $this->roleRepo->findOneByName($r)) !== null) { + $reachableRoles[] = $childRole; + } + } + } + + return $reachableRoles; + } + + private function buildRoleMap() + { + $this->map = array(); + $roles = $this->roleRepo->findAll(); + foreach ($roles as $mainRole) { + $main = $mainRole->getRole(); + $this->map[$main] = array(); + foreach ($mainRole->getInheritedRoles() as $childRole) { + $this->map[$main][] = $childRole->getRole(); + // TODO: This is one-level only. Get as deep as possible. + // BEWARE OF RECURSIVE NESTING! + foreach ($childRole->getInheritedRoles() as $grandchildRole) { + $this->map[$main][] = $grandchildRole->getRole(); + } + } + } + } +}