Spaces:
No application file
No application file
namespace Mautic\UserBundle\Controller\Api; | |
use Doctrine\Persistence\ManagerRegistry; | |
use Mautic\ApiBundle\Controller\CommonApiController; | |
use Mautic\ApiBundle\Helper\EntityResultHelper; | |
use Mautic\CoreBundle\Factory\MauticFactory; | |
use Mautic\CoreBundle\Factory\ModelFactory; | |
use Mautic\CoreBundle\Helper\AppVersion; | |
use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
use Mautic\CoreBundle\Security\Permissions\CorePermissions; | |
use Mautic\CoreBundle\Translation\Translator; | |
use Mautic\UserBundle\Entity\User; | |
use Mautic\UserBundle\Model\UserModel; | |
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
use Symfony\Component\Form\FormFactoryInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\RequestStack; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; | |
use Symfony\Component\Routing\RouterInterface; | |
/** | |
* @extends CommonApiController<User> | |
*/ | |
class UserApiController extends CommonApiController | |
{ | |
/** | |
* @var UserModel|null | |
*/ | |
protected $model; | |
public function __construct( | |
CorePermissions $security, | |
Translator $translator, | |
EntityResultHelper $entityResultHelper, | |
RouterInterface $router, | |
FormFactoryInterface $formFactory, | |
AppVersion $appVersion, | |
private UserPasswordHasherInterface $hasher, | |
RequestStack $requestStack, | |
ManagerRegistry $doctrine, | |
ModelFactory $modelFactory, | |
EventDispatcherInterface $dispatcher, | |
CoreParametersHelper $coreParametersHelper, | |
MauticFactory $factory | |
) { | |
$userModel = $modelFactory->getModel('user.user'); | |
\assert($userModel instanceof UserModel); | |
$this->model = $userModel; | |
$this->entityClass = User::class; | |
$this->entityNameOne = 'user'; | |
$this->entityNameMulti = 'users'; | |
$this->serializerGroups = ['userDetails', 'roleList', 'publishDetails']; | |
$this->dataInputMasks = ['signature' => 'html']; | |
parent::__construct($security, $translator, $entityResultHelper, $router, $formFactory, $appVersion, $requestStack, $doctrine, $modelFactory, $dispatcher, $coreParametersHelper, $factory); | |
} | |
/** | |
* Obtains the logged in user's data. | |
* | |
* @return Response | |
* | |
* @throws NotFoundHttpException | |
*/ | |
public function getSelfAction() | |
{ | |
$currentUser = $this->get('security.token_storage')->getToken()->getUser(); | |
$view = $this->view($currentUser, Response::HTTP_OK); | |
return $this->handleView($view); | |
} | |
/** | |
* Creates a new user. | |
*/ | |
public function newEntityAction(Request $request) | |
{ | |
$entity = $this->model->getEntity(); | |
if (!$this->security->isGranted('user:users:create')) { | |
return $this->accessDenied(); | |
} | |
$parameters = $request->request->all(); | |
if (isset($parameters['plainPassword']['password'])) { | |
$submittedPassword = $parameters['plainPassword']['password']; | |
$entity->setPassword($this->model->checkNewPassword($entity, $this->hasher, $submittedPassword)); | |
} | |
return $this->processForm($request, $entity, $parameters, 'POST'); | |
} | |
/** | |
* Edits an existing user or creates a new one on PUT if not found. | |
* | |
* @param int $id User ID | |
* | |
* @return Response | |
* | |
* @throws NotFoundHttpException | |
*/ | |
public function editEntityAction(Request $request, $id) | |
{ | |
$entity = $this->model->getEntity($id); | |
$parameters = $request->request->all(); | |
$method = $request->getMethod(); | |
if (!$this->security->isGranted('user:users:edit')) { | |
return $this->accessDenied(); | |
} | |
if (null === $entity) { | |
if ('PATCH' === $method | |
|| ('PUT' === $method && !$this->security->isGranted('user:users:create')) | |
) { | |
// PATCH requires that an entity exists or must have create access for PUT | |
return $this->notFound(); | |
} else { | |
$entity = $this->model->getEntity(); | |
if (isset($parameters['plainPassword']['password'])) { | |
$submittedPassword = $parameters['plainPassword']['password']; | |
$entity->setPassword($this->model->checkNewPassword($entity, $this->hasher, $submittedPassword)); | |
} | |
} | |
} else { | |
// Changing passwords via API is forbidden | |
if (!empty($parameters['plainPassword'])) { | |
unset($parameters['plainPassword']); | |
} | |
if ('PATCH' == $method) { | |
// PATCH will accept a diff so just remove the entities | |
// Changing username via API is forbidden | |
if (!empty($parameters['username'])) { | |
unset($parameters['username']); | |
} | |
} else { | |
// PUT requires the entire entity so overwrite the username with the original | |
$parameters['username'] = $entity->getUsername(); | |
$parameters['role'] = $entity->getRole()->getId(); | |
} | |
} | |
return $this->processForm($request, $entity, $parameters, $method); | |
} | |
protected function preSaveEntity(&$entity, $form, $parameters, $action = 'edit') | |
{ | |
switch ($action) { | |
case 'new': | |
$submittedPassword = null; | |
if (isset($parameters['plainPassword'])) { | |
if (is_array($parameters['plainPassword']) && isset($parameters['plainPassword']['password'])) { | |
$submittedPassword = $parameters['plainPassword']['password']; | |
} else { | |
$submittedPassword = $parameters['plainPassword']; | |
} | |
} | |
$entity->setPassword($this->model->checkNewPassword($entity, $this->hasher, $submittedPassword, true)); | |
break; | |
} | |
} | |
/** | |
* Verifies if a user has permission(s) to a action. | |
* | |
* @param int $id User ID | |
* | |
* @return Response | |
* | |
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException | |
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
*/ | |
public function isGrantedAction(Request $request, $id) | |
{ | |
$entity = $this->model->getEntity($id); | |
if (!$entity instanceof $this->entityClass) { | |
return $this->notFound(); | |
} | |
$permissions = $request->request->all()['permissions'] ?? []; | |
if (empty($permissions)) { | |
return $this->badRequest('mautic.api.call.permissionempty'); | |
} elseif (!is_array($permissions)) { | |
$permissions = [$permissions]; | |
} | |
$return = $this->security->isGranted($permissions, 'RETURN_ARRAY', $entity); | |
$view = $this->view($return, Response::HTTP_OK); | |
return $this->handleView($view); | |
} | |
/** | |
* Obtains a list of roles for user edits. | |
* | |
* @return Response | |
*/ | |
public function getRolesAction(Request $request) | |
{ | |
if (!$this->security->isGranted( | |
['user:users:create', 'user:users:edit'], | |
'MATCH_ONE' | |
) | |
) { | |
return $this->accessDenied(); | |
} | |
$filter = $request->query->get('filter', null); | |
$limit = $request->query->get('limit', null); | |
$roles = $this->model->getLookupResults('role', $filter, $limit); | |
$view = $this->view($roles, Response::HTTP_OK); | |
$context = $view->getContext()->setGroups(['roleList']); | |
$view->setContext($context); | |
return $this->handleView($view); | |
} | |
} | |