Migrate catalyst auth bundle to its own composer repository #194
This commit is contained in:
parent
45892ceac9
commit
ef4dd404e3
11 changed files with 930 additions and 1026 deletions
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class CatalystAuthBundle extends Bundle
|
||||
{
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
abstract class Role
|
||||
{
|
||||
const SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column(type="string", length=80)
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
// NOTE: annotation should be in the child class
|
||||
protected $users;
|
||||
|
||||
// array of permissions this role has access to
|
||||
/**
|
||||
* @ORM\Column(type="json_array")
|
||||
*/
|
||||
protected $acl_attributes;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->users = new ArrayCollection();
|
||||
$this->acl_attributes = [];
|
||||
}
|
||||
|
||||
public function setID($id)
|
||||
{
|
||||
// example ROLE_SUPER_ADMIN, ROLE_CASHIER, etc
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getUsers()
|
||||
{
|
||||
return $this->users;
|
||||
}
|
||||
|
||||
public function getUsersCount()
|
||||
{
|
||||
return $this->users->count();
|
||||
}
|
||||
|
||||
public function isSuperAdmin()
|
||||
{
|
||||
if ($this->id == self::SUPER_ADMIN)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function clearACLAttributes()
|
||||
{
|
||||
$this->acl_attributes = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getACLAttributes()
|
||||
{
|
||||
return $this->acl_attributes;
|
||||
}
|
||||
|
||||
public function addACLAccess($attribute)
|
||||
{
|
||||
$this->acl_attributes[$attribute] = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasACLAccess($attribute)
|
||||
{
|
||||
// if it's super admin, they always have access
|
||||
if ($this->isSuperAdmin())
|
||||
return true;
|
||||
|
||||
// check ACL attributes
|
||||
if (isset($this->acl_attributes[$attribute]) && $this->acl_attributes[$attribute])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Serializable;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
// base User class
|
||||
abstract class User implements UserInterface,Serializable
|
||||
{
|
||||
// NOTE: doctrine annotations for roles have to be declared on the child class
|
||||
protected $roles;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->roles = new ArrayCollection();
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
// array of string roles, needed by symfony
|
||||
public function getRoles()
|
||||
{
|
||||
$str_roles = [];
|
||||
foreach ($this->roles as $role)
|
||||
$str_roles[] = $role->getID();
|
||||
|
||||
return $str_roles;
|
||||
}
|
||||
|
||||
public function getRoleObjects()
|
||||
{
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
public function addRole(Role $role)
|
||||
{
|
||||
$this->roles->add($role);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function clearRoles()
|
||||
{
|
||||
$this->roles->clear();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEnabled($enabled = true)
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Exception;
|
||||
|
||||
use Symfony\Component\Security\Core\Exception\AccountStatusException;
|
||||
|
||||
class AccountDisabledException extends AccountStatusException
|
||||
{
|
||||
public function getMessageKey()
|
||||
{
|
||||
return 'Account has been disabled.';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Service;
|
||||
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Yaml\Parser as YamlParser;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
class ACLGenerator
|
||||
{
|
||||
protected $router;
|
||||
protected $cache_dir;
|
||||
protected $config_dir;
|
||||
protected $acl_file;
|
||||
protected $acl_key;
|
||||
|
||||
public function __construct(RouterInterface $router, string $cache_dir, string $config_dir,
|
||||
string $acl_file, string $acl_key)
|
||||
{
|
||||
$this->router = $router;
|
||||
$this->cache_dir = $cache_dir;
|
||||
$this->config_dir = $config_dir;
|
||||
$this->acl_file = $acl_file;
|
||||
$this->acl_key = $acl_key;
|
||||
}
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
$key = $this->acl_key;
|
||||
|
||||
// cache config
|
||||
$cache_file = $this->cache_dir . '/' . $key . '.serial';
|
||||
$cache = new ConfigCache($cache_file, true);
|
||||
|
||||
// check if cache is fresh
|
||||
if (!$cache->isFresh())
|
||||
{
|
||||
$files = [];
|
||||
$resources = [];
|
||||
|
||||
try
|
||||
{
|
||||
// get location of the yaml file with the acls
|
||||
// $path = $this->config_dir . '/<acl yaml filename>';
|
||||
$path = $this->config_dir . '/' . $this->acl_file;
|
||||
|
||||
$files[] = $path;
|
||||
$resources[] = new FileResource($path);
|
||||
|
||||
// process acl config file
|
||||
$data = $this->parseACL($path, $key);
|
||||
}
|
||||
catch (\InvalidArgumentException $e)
|
||||
{
|
||||
error_log($e->getMessage());
|
||||
error_log($key . ' key not found in ' . $this->acl_file . 'file.');
|
||||
return $data;
|
||||
}
|
||||
|
||||
$acl_serial = serialize($data);
|
||||
$cache->write($acl_serial, $resources);
|
||||
}
|
||||
else
|
||||
{
|
||||
$acl_serial = file_get_contents($cache_file);
|
||||
$data = unserialize($acl_serial);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function parseACL($path, $key)
|
||||
{
|
||||
|
||||
$parser = new YamlParser();
|
||||
$config = $parser->parse(file_get_contents($path));
|
||||
|
||||
// check if we have access keys
|
||||
if (!isset($config[$key]))
|
||||
{
|
||||
error_log('No ' . $key . ' found for ' . $path);
|
||||
return;
|
||||
}
|
||||
|
||||
$acl_hierarchy = [];
|
||||
$acl_index = [];
|
||||
|
||||
// go through each one
|
||||
foreach ($config[$key] as $acl_data)
|
||||
{
|
||||
// build hierarchy
|
||||
$acl_hierarchy[$acl_data['id']] = [
|
||||
'label' => $acl_data['label'],
|
||||
'acls' => []
|
||||
];
|
||||
|
||||
foreach ($acl_data['acls'] as $acl)
|
||||
{
|
||||
$id = $acl['id'];
|
||||
$label = $acl['label'];
|
||||
|
||||
// set hierarchy and index
|
||||
$acl_hierarchy[$acl_data['id']]['acls'][$id] = $label;
|
||||
$acl_index[$id] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'hierarchy' => $acl_hierarchy,
|
||||
'index' => $acl_index
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Service;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter as BaseVoter;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class ACLVoter extends BaseVoter
|
||||
{
|
||||
protected $acl_gen;
|
||||
protected $user_class;
|
||||
protected $security;
|
||||
|
||||
public function __construct(Security $security, ACLGenerator $acl_gen, $user_class)
|
||||
{
|
||||
$this->acl_gen = $acl_gen;
|
||||
$this->user_class = $user_class;
|
||||
$this->security = $security;
|
||||
}
|
||||
|
||||
protected function supports($attribute, $subject)
|
||||
{
|
||||
// NOTE: we currently do not check for subject, we'll leave that to other voters
|
||||
|
||||
// check if it's using our user class
|
||||
$user = $this->security->getUser();
|
||||
if (!($user instanceof $this->user_class))
|
||||
return false;
|
||||
|
||||
// check if the attribute is in our acl key index
|
||||
$acl_data = $this->acl_gen->getACL();
|
||||
if (isset($acl_data['index'][$attribute]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
||||
{
|
||||
$user = $token->getUser();
|
||||
|
||||
// check if any of the user's roles have access
|
||||
$roles = $user->getRoleObjects();
|
||||
foreach ($roles as $role)
|
||||
{
|
||||
if ($role->hasACLAccess($attribute))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\AuthBundle\Service;
|
||||
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||
use Catalyst\AuthBundle\Entity\User;
|
||||
use Catalyst\AuthBundle\Exception\AccountDisabledException;
|
||||
|
||||
class UserChecker implements UserCheckerInterface
|
||||
{
|
||||
public function checkPreAuth(UserInterface $user)
|
||||
{
|
||||
// do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
public function checkPostAuth(UserInterface $user)
|
||||
{
|
||||
// handle catalyst suth users
|
||||
if (!($user instanceof User))
|
||||
return;
|
||||
|
||||
// check if enabled
|
||||
if (!$user->isEnabled())
|
||||
{
|
||||
throw new AccountDisabledException("Account has been disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"repositories": [
|
||||
{ "type": "vcs", "url": "https://gitlab.com/jankstudio-catalyst/catalyst-auth.git" }
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"ext-iconv": "*",
|
||||
|
|
@ -15,14 +18,14 @@
|
|||
"symfony/filesystem": "^4.0",
|
||||
"symfony/flex": "^1.0",
|
||||
"symfony/framework-bundle": "^4.0",
|
||||
"symfony/lts": "^4@dev",
|
||||
"symfony/maker-bundle": "^1.0",
|
||||
"symfony/orm-pack": "^1.0",
|
||||
"symfony/profiler-pack": "^1.0",
|
||||
"symfony/security-bundle": "^4.0",
|
||||
"symfony/twig-bundle": "^4.0",
|
||||
"symfony/validator": "^4.0",
|
||||
"symfony/yaml": "^4.0"
|
||||
"symfony/yaml": "^4.0",
|
||||
"catalyst/auth-bundle": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-fixtures-bundle": "^3.0",
|
||||
|
|
@ -38,9 +41,7 @@
|
|||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/",
|
||||
"Catalyst\\APIBundle\\": "catalyst/api-bundle/",
|
||||
"RamcarBattery\\APIBundle\\": "ramcar-batery/api-bundle/",
|
||||
"Catalyst\\AuthBundle\\": "catalyst/auth-bundle/"
|
||||
"Catalyst\\APIBundle\\": "catalyst/api-bundle/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
|
|
|
|||
1516
composer.lock
generated
1516
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -11,8 +11,6 @@ return [
|
|||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
|
||||
Catalyst\APIBundle\CatalystAPIBundle::class => ['all' => true],
|
||||
// DataDog\AuditBundle\DataDogAuditBundle::class => ['all' => true],
|
||||
Catalyst\AuthBundle\CatalystAuthBundle::class => ['all' => true],
|
||||
];
|
||||
|
|
|
|||
33
symfony.lock
33
symfony.lock
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"catalyst/auth-bundle": {
|
||||
"version": "dev-master"
|
||||
},
|
||||
"creof/doctrine2-spatial": {
|
||||
"version": "1.2.0"
|
||||
},
|
||||
|
|
@ -128,9 +131,6 @@
|
|||
"psr/log": {
|
||||
"version": "1.0.2"
|
||||
},
|
||||
"psr/simple-cache": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"ralouphie/getallheaders": {
|
||||
"version": "2.0.5"
|
||||
},
|
||||
|
|
@ -149,6 +149,9 @@
|
|||
"symfony/cache": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
"symfony/cache-contracts": {
|
||||
"version": "v1.1.1"
|
||||
},
|
||||
"symfony/config": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
|
|
@ -161,9 +164,6 @@
|
|||
"ref": "9f94d3ea453cd8a3b95db7f82592d7344fe3a76a"
|
||||
}
|
||||
},
|
||||
"symfony/contracts": {
|
||||
"version": "v1.0.2"
|
||||
},
|
||||
"symfony/debug": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
|
|
@ -179,6 +179,9 @@
|
|||
"symfony/event-dispatcher": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
"symfony/event-dispatcher-contracts": {
|
||||
"version": "v1.1.1"
|
||||
},
|
||||
"symfony/filesystem": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
|
|
@ -212,9 +215,6 @@
|
|||
"symfony/inflector": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
"symfony/lts": {
|
||||
"version": "4-dev"
|
||||
},
|
||||
"symfony/maker-bundle": {
|
||||
"version": "1.0",
|
||||
"recipe": {
|
||||
|
|
@ -224,18 +224,27 @@
|
|||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||
}
|
||||
},
|
||||
"symfony/mime": {
|
||||
"version": "v4.3.0"
|
||||
},
|
||||
"symfony/orm-pack": {
|
||||
"version": "v1.0.5"
|
||||
},
|
||||
"symfony/polyfill-ctype": {
|
||||
"version": "v1.9.0"
|
||||
},
|
||||
"symfony/polyfill-intl-idn": {
|
||||
"version": "v1.11.0"
|
||||
},
|
||||
"symfony/polyfill-mbstring": {
|
||||
"version": "v1.6.0"
|
||||
},
|
||||
"symfony/polyfill-php72": {
|
||||
"version": "v1.6.0"
|
||||
},
|
||||
"symfony/polyfill-php73": {
|
||||
"version": "v1.11.0"
|
||||
},
|
||||
"symfony/profiler-pack": {
|
||||
"version": "v1.0.3"
|
||||
},
|
||||
|
|
@ -272,12 +281,18 @@
|
|||
"symfony/security-http": {
|
||||
"version": "v4.2.2"
|
||||
},
|
||||
"symfony/service-contracts": {
|
||||
"version": "v1.1.2"
|
||||
},
|
||||
"symfony/stopwatch": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
"symfony/thanks": {
|
||||
"version": "v1.1.0"
|
||||
},
|
||||
"symfony/translation-contracts": {
|
||||
"version": "v1.1.2"
|
||||
},
|
||||
"symfony/twig-bridge": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue