UserService.php (7424B)
1 <?php 2 3 namespace PartKeepr\AuthBundle\Services; 4 5 use Doctrine\ORM\EntityManager; 6 use Doctrine\ORM\NoResultException; 7 use Doctrine\ORM\QueryBuilder; 8 use FOS\UserBundle\Model\UserManagerInterface; 9 use FOS\UserBundle\Util\UserManipulator; 10 use PartKeepr\AuthBundle\Entity\User; 11 use PartKeepr\AuthBundle\Entity\UserProvider; 12 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; 13 14 class UserService 15 { 16 /** 17 * @var TokenStorage 18 */ 19 private $tokenStorage; 20 21 /** 22 * @var EntityManager 23 */ 24 private $entityManager; 25 26 /** 27 * @var UserManipulator 28 */ 29 private $userManipulator; 30 31 /** 32 * @var UserManagerInterface 33 */ 34 private $userManager; 35 36 /** 37 * The maximum number of users allowed. 38 * 39 * @var int|bool 40 */ 41 private $userLimit; 42 43 const BUILTIN_PROVIDER = 'Builtin'; 44 45 public function __construct( 46 TokenStorage $tokenStorage, 47 EntityManager $entityManager, 48 UserManipulator $userManipulator, 49 UserManagerInterface $userManager, 50 $userLimit = false 51 ) { 52 $this->tokenStorage = $tokenStorage; 53 $this->entityManager = $entityManager; 54 $this->userManipulator = $userManipulator; 55 $this->userManager = $userManager; 56 $this->userLimit = $userLimit; 57 } 58 59 /** 60 * Returns the PartKeeprUser based on the user token within the Symfony2 environment. 61 * 62 * @return User The proxy user 63 */ 64 public function getUser() 65 { 66 $tokenProvider = $this->tokenStorage->getToken()->getAttribute('provider'); 67 68 $provider = $this->getProvider($tokenProvider); 69 $username = $this->tokenStorage->getToken()->getUsername(); 70 71 return $this->getProxyUser($username, $provider, true); 72 } 73 74 public function getProvider($providerClass) 75 { 76 $providerType = $this->getProviderTypeByClass($providerClass); 77 78 return $this->getProviderByType($providerType); 79 } 80 81 public function getProviderTypeByClass($providerClass) 82 { 83 switch ($providerClass) { 84 case 'Escape\WSSEAuthenticationBundle\Security\Core\Authentication\Provider\Provider': 85 return self::BUILTIN_PROVIDER; 86 break; 87 case 'Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider': 88 return self::BUILTIN_PROVIDER; 89 break; 90 case 'FR3D\LdapBundle\Security\Authentication\LdapAuthenticationProvider': 91 return 'LDAP'; 92 break; 93 default: 94 throw new \Exception('Unknown provider '.$providerClass); 95 } 96 } 97 98 /** 99 * Syncronizes the data of the given user with the FOSRestBundle. 100 * 101 * 102 * @param $user 103 * 104 * @throws \Exception If the password was not set 105 */ 106 public function syncData(User $user) 107 { 108 if ($user->getProvider()->getType() !== self::BUILTIN_PROVIDER) { 109 return; 110 } 111 112 $FOSUser = $this->userManager->findUserByUsername($user->getUsername()); 113 114 if ($FOSUser === null) { 115 if ($user->getNewPassword() == '') { 116 throw new \Exception('Password must be set'); 117 } 118 119 $FOSUser = $this->userManipulator->create($user->getUsername(), $user->getNewPassword(), '', true, false); 120 $user->setLegacy(false); 121 } 122 if ($user->getNewPassword() != '') { 123 $this->userManipulator->changePassword($user->getUsername(), $user->getNewPassword()); 124 } 125 126 $FOSUser->setEmail($user->getEmail()); 127 $FOSUser->setEnabled($user->isActive()); 128 } 129 130 /** 131 * Deletes an user from the FOSUser system. 132 * 133 * @param User $user 134 */ 135 public function deleteFOSUser(User $user) 136 { 137 if ($user->getProvider()->getType() !== self::BUILTIN_PROVIDER) { 138 return; 139 } 140 141 $FOSUser = $this->userManager->findUserByUsername($user->getUsername()); 142 143 if ($FOSUser !== null) { 144 $this->userManager->deleteUser($FOSUser); 145 } 146 } 147 148 public function getProviderByType($type) 149 { 150 $provider = $this->entityManager->getRepository('PartKeeprAuthBundle:UserProvider')->findOneBy(['type' => $type]); 151 152 if ($provider !== null) { 153 return $provider; 154 } 155 156 $provider = new UserProvider(); 157 $provider->setType($type); 158 159 if ($type !== self::BUILTIN_PROVIDER) { 160 $provider->setEditable(false); 161 } 162 163 $this->entityManager->persist($provider); 164 $this->entityManager->flush(); 165 166 return $provider; 167 } 168 169 public function getBuiltinProvider() 170 { 171 return $this->getProviderByType(self::BUILTIN_PROVIDER); 172 } 173 174 /** 175 * Returns the proxy user for a given username and provider. 176 * 177 * @param $username 178 * @param $provider 179 * @param bool|false $create If set to true 180 * 181 * @throws NoResultException 182 * @throws \Doctrine\ORM\NonUniqueResultException 183 * 184 * @return mixed|User 185 */ 186 public function getProxyUser($username, UserProvider $provider, $create = false) 187 { 188 /** 189 * @var QueryBuilder 190 */ 191 $queryBuilder = $this->entityManager->createQueryBuilder(); 192 193 $queryBuilder->select('u') 194 ->from('PartKeeprAuthBundle:User', 'u') 195 ->where('u.provider = :provider') 196 ->andWhere('u.username = :username') 197 ->setParameter('provider', $provider) 198 ->setParameter('username', $username); 199 200 $query = $queryBuilder->getQuery(); 201 202 try { 203 $user = $query->getSingleResult(); 204 205 return $user; 206 } catch (NoResultException $e) { 207 if ($create === false) { 208 throw $e; 209 } else { 210 return $this->createProxyUser($username, $provider); 211 } 212 } 213 } 214 215 private function createProxyUser($username, $provider) 216 { 217 $user = new User($username, $provider); 218 $user->setLegacy(false); 219 $user->setProtected(false); 220 $user->setActive(true); 221 $this->entityManager->persist($user); 222 $this->entityManager->flush(); 223 224 return $user; 225 } 226 227 /** 228 * Protects a given user against changes. 229 * 230 * @param User $user 231 */ 232 public function protect(User $user) 233 { 234 $user->setProtected(true); 235 $this->entityManager->flush(); 236 } 237 238 /** 239 * Unprotects a given user against changes. 240 * 241 * @param User $user 242 */ 243 public function unprotect(User $user) 244 { 245 $user->setProtected(false); 246 $this->entityManager->flush(); 247 } 248 249 /** 250 * Returns the number of users present in the system. 251 * 252 * @return mixed 253 */ 254 public function getUserCount() 255 { 256 $dql = 'SELECT COUNT(u) FROM PartKeepr\\AuthBundle\\Entity\\FOSUser u WHERE u.enabled = 1'; 257 $query = $this->entityManager->createQuery($dql); 258 259 return $query->getSingleScalarResult(); 260 } 261 262 /** 263 * Checks if the amount of users is exceeded. 264 * 265 * @return bool 266 */ 267 public function checkUserLimit() 268 { 269 if ($this->userLimit !== false) { 270 if ($this->getUserCount() >= $this->userLimit) { 271 return true; 272 } 273 } 274 275 return false; 276 } 277 }