1: <?php
2:
3: namespace ProgrammingAreHard\Arbiter\Domain;
4:
5: use ProgrammingAreHard\Arbiter\Model\IdentityFactoryInterface;
6: use ProgrammingAreHard\Arbiter\Model\IndexedAceResolverInterface;
7: use ProgrammingAreHard\Arbiter\Model\PermissionsInterface;
8: use ProgrammingAreHard\Arbiter\Model\ObjectArbiterInterface;
9: use ProgrammingAreHard\Arbiter\Model\PermissionsTransformerInterface;
10: use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
11: use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
12: use Symfony\Component\Security\Acl\Model\AclInterface;
13: use Symfony\Component\Security\Acl\Model\MutableAclProviderInterface;
14: use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
15: use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
16: use Symfony\Component\Security\Core\User\UserInterface;
17:
18: class ObjectArbiter implements ObjectArbiterInterface
19: {
20: 21: 22:
23: protected $objectIdentity;
24:
25: 26: 27:
28: protected $aclProvider;
29:
30: 31: 32:
33: protected $permissionsTransformer;
34:
35: 36: 37:
38: protected $identityFactory;
39:
40: 41: 42: 43: 44: 45: 46:
47: public function __construct(
48: MutableAclProviderInterface $aclProvider,
49: PermissionsTransformerInterface $permissionsTransformer = null,
50: IdentityFactoryInterface $identityFactory = null
51: ) {
52: $this->aclProvider = $aclProvider;
53: $this->permissionsTransformer = $permissionsTransformer ? : new PermissionsTransformer;
54: $this->identityFactory = $identityFactory ? : new IdentityFactory;
55: }
56:
57: 58: 59:
60: public function setObject($object)
61: {
62: $this->objectIdentity = $this->identityFactory->getObjectIdentity($object);
63:
64: return $this;
65: }
66:
67: 68: 69:
70: public function newPermissions(array $permissions = array())
71: {
72: return $this->permissionsTransformer->newPermissions($permissions);
73: }
74:
75: 76: 77:
78: public function getPermissions(UserInterface $user)
79: {
80: $this->ensureObjectIdentityPresent();
81:
82: $userIdentity = $this->identityFactory->getUserIdentity($user);
83:
84: $mask = 0;
85:
86: try {
87: $acl = $this->aclProvider->findAcl($this->objectIdentity);
88: $indexedAce = $this->resolveIndexedAce($acl, $userIdentity);
89: $mask = $indexedAce->getAce()->getMask();
90: } catch (AclNotFoundException $e) {
91: } catch (NoAceFoundException $e) {
92: }
93:
94: return $this->permissionsTransformer->maskToPermissions($mask);
95: }
96:
97:
98: 99: 100:
101: public function updatePermissions(UserInterface $user, PermissionsInterface $permissions)
102: {
103: $this->ensureObjectIdentityPresent();
104:
105: $userIdentity = $this->identityFactory->getUserIdentity($user);
106:
107: $mask = $this->permissionsTransformer->permissionsToMask($permissions);
108:
109: try {
110: $acl = $this->aclProvider->findAcl($this->objectIdentity);
111: } catch (AclNotFoundException $e) {
112: $acl = $this->aclProvider->createAcl($this->objectIdentity);
113: }
114:
115: try {
116: $indexedAce = $this->resolveIndexedAce($acl, $userIdentity);
117:
118: $index = $indexedAce->getIndex();
119:
120: if ($mask > 0) {
121: $acl->updateObjectAce($index, $mask);
122: } else {
123: $acl->deleteObjectAce($index);
124: }
125: } catch (NoAceFoundException $e) {
126: $acl->insertObjectAce($userIdentity, $mask);
127: }
128:
129: $this->aclProvider->updateAcl($acl);
130: }
131:
132: 133: 134:
135: public function isGranted(UserInterface $user, PermissionsInterface $permissions)
136: {
137: if (0 === count($permissions)) {
138: return true;
139: }
140:
141: $this->ensureObjectIdentityPresent();
142:
143: $userIdentity = $this->identityFactory->getUserIdentity($user);
144:
145: try {
146: $acl = $this->aclProvider->findAcl($this->objectIdentity);
147: $masks = $this->permissionsTransformer->permissionsToMasks($permissions);
148: return $acl->isGranted($masks, array($userIdentity));
149: } catch (AclNotFoundException $e) {
150: } catch (NoAceFoundException $e) {
151: }
152:
153: return false;
154: }
155:
156: 157: 158: 159: 160: 161: 162: 163:
164: private function resolveIndexedAce(AclInterface $acl, SecurityIdentityInterface $sid)
165: {
166: foreach ($acl->getObjectAces() as $index => $ace) {
167: if ($ace->getSecurityIdentity()->equals($sid)) {
168: return new IndexedAce($index, $ace);
169: }
170: }
171:
172: throw new NoAceFoundException;
173: }
174:
175: 176: 177: 178: 179:
180: private function ensureObjectIdentityPresent()
181: {
182: if (!$this->objectIdentity) {
183: throw new \InvalidArgumentException(sprintf(
184: '%s needs resource to grant and check permissions.',
185: get_class($this)
186: ));
187: }
188: }
189: }