/** * Render user initials or an abbreviated name for a given username. If the account was deleted, use the username as fallback. * * @param string $format Supported are "fullFirstName" and "initials" * @return string */ public function render($format = 'initials') { if (!in_array($format, array('fullFirstName', 'initials', 'fullName'))) { throw new \InvalidArgumentException(sprintf('Format "%s" given to history:userInitials(), only supporting "fullFirstName", "initials" and "fullName".', $format), 1415705861); } $username = $this->renderChildren(); /* @var $requestedUser Person */ $requestedUser = $this->domainUserService->getUser($username); if ($requestedUser === null || $requestedUser->getName() === null) { return $username; } $currentUser = $this->userService->getBackendUser(); if ($currentUser) { if ($currentUser === $requestedUser) { $translationHelper = new TranslationHelper(); $you = $translationHelper->translate('you', null, [], 'Main', 'TYPO3.Neos'); } } switch ($format) { case 'initials': return mb_substr($requestedUser->getName()->getFirstName(), 0, 1) . mb_substr($requestedUser->getName()->getLastName(), 0, 1); case 'fullFirstName': return isset($you) ? $you : $requestedUser->getName()->getFirstName() . ' ' . mb_substr($requestedUser->getName()->getLastName(), 0, 1) . '.'; case 'fullName': return isset($you) ? $you : $requestedUser->getName()->getFullName(); } }
/** * Returns an array of usage reference objects. * * @param AssetInterface $asset * @return array<\TYPO3\Neos\Domain\Model\Dto\AssetUsageInNodeProperties> * @throws \TYPO3\TYPO3CR\Exception\NodeConfigurationException */ public function getUsageReferences(AssetInterface $asset) { $assetIdentifier = $this->persistenceManager->getIdentifierByObject($asset); if (isset($this->firstlevelCache[$assetIdentifier])) { return $this->firstlevelCache[$assetIdentifier]; } $userWorkspace = $this->userService->getPersonalWorkspace(); $relatedNodes = []; foreach ($this->getRelatedNodes($asset) as $relatedNodeData) { $accessible = $this->domainUserService->currentUserCanReadWorkspace($relatedNodeData->getWorkspace()); if ($accessible) { $context = $this->createContextMatchingNodeData($relatedNodeData); } else { $context = $this->createContentContext($userWorkspace->getName()); } $site = $context->getCurrentSite(); $node = $this->nodeFactory->createFromNodeData($relatedNodeData, $context); $flowQuery = new FlowQuery([$node]); /** @var \TYPO3\TYPO3CR\Domain\Model\NodeInterface $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $relatedNodes[] = new AssetUsageInNodeProperties($asset, $site, $documentNode, $node, $accessible); } $this->firstlevelCache[$assetIdentifier] = $relatedNodes; return $this->firstlevelCache[$assetIdentifier]; }
/** * @test */ public function getPersonalWorkspaceNameReturnsTheUsersWorkspaceNameIfAUserIsLoggedIn() { $mockUser = $this->getMockBuilder('TYPO3\\Neos\\Domain\\Model\\User')->disableOriginalConstructor()->getMock(); $this->mockUserDomainService->expects($this->atLeastOnce())->method('getCurrentUser')->will($this->returnValue($mockUser)); $this->mockUserDomainService->expects($this->atLeastOnce())->method('getUserName')->with($mockUser)->will($this->returnValue('TheUserName')); $this->assertSame('user-TheUserName', $this->userService->getPersonalWorkspaceName()); }
/** * @param NodeInterface $node The node that is currently edited (optional) * @param array $arguments Additional arguments (key / value) * @return array */ public function getData(NodeInterface $node, array $arguments) { $options = []; foreach ($this->userService->getUsers() as $user) { $options[$this->persistenceManager->getIdentifierByObject($user)] = ['label' => $user->getLabel()]; } return $options; }
/** * Returns TRUE, if the specified user ($value) does not exist yet. * * If at least one error occurred, the result is FALSE. * * @param mixed $value The value that should be validated * @return void * @throws InvalidSubjectException */ protected function isValid($value) { if (!is_string($value)) { throw new InvalidSubjectException('The given username was not a string.', 1325155784); } if ($this->userService->getUser($value) !== null) { $this->addError('The username is already in use.', 1325156008); } }
/** * Returns the name of the currently logged in user's personal workspace (even if that might not exist at that time). * If no user is logged in this method returns null. * * @return string * @api */ public function getPersonalWorkspaceName() { $currentUser = $this->userDomainService->getCurrentUser(); if (!$currentUser instanceof User) { return null; } $username = $this->userDomainService->getUsername($currentUser); return 'user-' . preg_replace('/[^a-z0-9]/i', '', $username); }
/** * Returns the name of the currently logged in user's personal workspace (even if that might not exist at that time). * If no user is logged in this method returns null. * * @return string * @api */ public function getPersonalWorkspaceName() { $currentUser = $this->userDomainService->getCurrentUser(); if (!$currentUser instanceof User) { return null; } $username = $this->userDomainService->getUsername($currentUser); return $username === null ? null : UserUtility::getPersonalWorkspaceNameForUsername($username); }
/** * @return \TYPO3\Flow\Security\Account */ public function getInstagramAccountHavingParty() { foreach ($this->userService->getCurrentUser()->getAccounts() as $account) { /* @var $account \TYPO3\Flow\Security\Account */ if ($account->getAuthenticationProviderName() === 'InstagramOAuth2Provider') { return $account; } } return NULL; }
/** * Update/adds a user preference * * @param string $key The key of the preference to update/add * @param string $value The value of the preference * @return void */ public function updateAction($key, $value) { // TODO: This should be done in an earlier stage (TypeConverter ?) if (strtolower($value) === 'false') { $value = false; } elseif (strtolower($value) === 'true') { $value = true; } $user = $this->userService->getCurrentUser(); $user->getPreferences()->set($key, $value); $this->userService->updateUser($user); $this->throwStatus(204, 'User preferences have been updated'); }
/** * Delete an electronic address action * * @param User $user * @param ElectronicAddress $electronicAddress * @return void */ public function deleteElectronicAddressAction(User $user, ElectronicAddress $electronicAddress) { $user->removeElectronicAddress($electronicAddress); $this->userService->updateUser($user); $this->addFlashMessage('The electronic address "%s" (%s) has been deleted for "%s".', 'Electronic address removed', Message::SEVERITY_NOTICE, array(htmlspecialchars($electronicAddress->getIdentifier()), htmlspecialchars($electronicAddress->getType()), htmlspecialchars($user->getName())), 1412374678); $this->redirect('edit', null, null, array('user' => $user)); }
/** * Creates an array of user names and their respective labels which are possible owners for a workspace. * * @return array */ protected function prepareOwnerOptions() { $ownerOptions = ['' => '-']; foreach ($this->userService->getUsers() as $user) { /** @var User $user */ $ownerOptions[$this->persistenceManager->getIdentifierByObject($user)] = $user->getLabel(); } return $ownerOptions; }
/** * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded. * * @param TokenInterface $authenticationToken The token to be authenticated * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException * @return void */ public function authenticate(TokenInterface $authenticationToken) { if (!$authenticationToken instanceof AbstractClientToken) { throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1383754993); } $credentials = $authenticationToken->getCredentials(); // There is no way to validate the Token or check the scopes at the moment apart from "trying" (and possibly receiving an access denied) // we could check the validity of the Token and the scopes here in the future when Instagram provides that // Only check if an access Token is present at this time and do a single test call if (isset($credentials['accessToken']) && $credentials['accessToken'] !== NULL) { // check if a secure request is possible (https://www.instagram.com/developer/secure-api-requests/) $userInfo = $this->instagramTokenEndpoint->validateSecureRequestCapability($credentials['accessToken']); if ($userInfo === FALSE) { $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS); $this->securityLogger->log('A secure call to the API with the provided accessToken and clientSecret was not possible', LOG_NOTICE); return FALSE; } } else { } // From here, we surely know the user is considered authenticated against the remote service, // yet to check if there is an immanent account present. $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL); /** @var $account \TYPO3\Flow\Security\Account */ $account = NULL; $providerName = $this->name; $accountRepository = $this->accountRepository; $this->securityContext->withoutAuthorizationChecks(function () use($userInfo, $providerName, $accountRepository, &$account) { $account = $accountRepository->findByAccountIdentifierAndAuthenticationProviderName($userInfo['id'], $providerName); }); if ($account === NULL) { $account = new Account(); $account->setAccountIdentifier($userInfo['id']); $account->setAuthenticationProviderName($providerName); $this->accountRepository->add($account); } $authenticationToken->setAccount($account); // the access token is valid for an "undefined time" according to instagram (so we cannot know when the user needs to log in again) $account->setCredentialsSource($credentials['accessToken']); $this->accountRepository->update($account); // check if a user is already attached to this account if ($this->partyService->getAssignedPartyOfAccount($account) === null || count($this->partyService->getAssignedPartyOfAccount($account)) < 1) { $user = $this->userService->getCurrentUser(); if ($user !== null) { $user->addAccount($account); $this->userService->updateUser($user); $this->persistenceManager->whitelistObject($user); } else { $this->securityLogger->logException(new Exception("The InstagramProvider was unable to determine the backend user, make sure the configuration Typo3BackendProvider requestPattern matches the Instagram Controller and the authentication strategy is set to 'atLeastOne' Token")); } } // persistAll is called automatically at the end of this function, account gets whitelisted to allow // persisting for an object thats tinkered with via a GET request $this->persistenceManager->whitelistObject($account); }
/** * Create a workspace * * @param string $workspaceName * @param Workspace $baseWorkspace * @param string $ownerAccountIdentifier * @return string */ public function createAction($workspaceName, Workspace $baseWorkspace, $ownerAccountIdentifier = null) { $existingWorkspace = $this->workspaceRepository->findByIdentifier($workspaceName); if ($existingWorkspace !== null) { $this->throwStatus(409, 'Workspace already exists', ''); } if ($ownerAccountIdentifier !== null) { $owner = $this->userService->getUser($ownerAccountIdentifier); if ($owner === null) { $this->throwStatus(422, 'Requested owner account does not exist', ''); } } else { $owner = null; } $workspace = new Workspace($workspaceName, $baseWorkspace, $owner); $this->workspaceRepository->add($workspace); $this->throwStatus(201, 'Workspace created', ''); }
/** * Prepares a table row for output with data of the given User * * @param User $user The user * @return array */ protected function getTableRowForUser(User $user) { $roleNames = array(); $accountIdentifiers = array(); foreach ($user->getAccounts() as $account) { /** @var Account $account */ $authenticationProviderName = $account->getAuthenticationProviderName(); if ($authenticationProviderName !== $this->userService->getDefaultAuthenticationProviderName()) { $authenticationProviderLabel = ' (' . (isset($this->authenticationProviderSettings[$authenticationProviderName]['label']) ? $this->authenticationProviderSettings[$authenticationProviderName]['label'] : $authenticationProviderName) . ')'; } else { $authenticationProviderLabel = ''; } $accountIdentifiers[] = $account->getAccountIdentifier() . $authenticationProviderLabel; foreach ($account->getRoles() as $role) { /** @var Role $role */ $roleNames[] = $role->getIdentifier(); } } return array($user->getName()->getFullName(), $user->getPrimaryElectronicAddress(), implode(', ', $accountIdentifiers), implode(', ', $roleNames), $user->isActive() ? 'yes' : 'no'); }
/** * Get Related Nodes for an asset * * @param Asset $asset * @return void */ public function relatedNodesAction(Asset $asset) { $userWorkspace = $this->userService->getPersonalWorkspace(); $relatedNodes = []; foreach ($this->getRelatedNodes($asset) as $relatedNodeData) { $accessible = $this->domainUserService->currentUserCanReadWorkspace($relatedNodeData->getWorkspace()); if ($accessible) { $context = $this->createContextMatchingNodeData($relatedNodeData); } else { $context = $this->createContentContext($userWorkspace->getName()); } $site = $context->getCurrentSite(); $node = $this->nodeFactory->createFromNodeData($relatedNodeData, $context); $flowQuery = new FlowQuery([$node]); /** @var Node $documentNode */ $documentNode = $flowQuery->closest('[instanceof TYPO3.Neos:Document]')->get(0); $documentNodeIdentifier = $documentNode instanceof NodeInterface ? $documentNode->getIdentifier() : null; $relatedNodes[$site->getNodeName()]['site'] = $site; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['node'] = $documentNode; $relatedNodes[$site->getNodeName()]['documentNodes'][$documentNodeIdentifier]['nodes'][] = ['node' => $node, 'nodeData' => $relatedNodeData, 'contextDocumentNode' => $documentNode, 'accessible' => $accessible]; } $this->view->assignMultiple(['asset' => $asset, 'relatedNodes' => $relatedNodes, 'contentDimensions' => $this->contentDimensionPresetSource->getAllPresets(), 'userWorkspace' => $userWorkspace]); }
/** * Create a new workspace * * This command creates a new workspace. * * @param string $workspace Name of the workspace, for example "christmas-campaign" * @param string $baseWorkspace Name of the base workspace. If none is specified, "live" is assumed. * @param string $title Human friendly title of the workspace, for example "Christmas Campaign" * @param string $description A description explaining the purpose of the new workspace * @param string $owner The identifier of a User to own the workspace * @return void */ public function createCommand($workspace, $baseWorkspace = 'live', $title = null, $description = null, $owner = '') { $workspaceName = $workspace; $workspace = $this->workspaceRepository->findOneByName($workspaceName); if ($workspace instanceof Workspace) { $this->outputLine('Workspace "%s" already exists', [$workspaceName]); $this->quit(1); } $baseWorkspaceName = $baseWorkspace; $baseWorkspace = $this->workspaceRepository->findOneByName($baseWorkspaceName); if (!$baseWorkspace instanceof Workspace) { $this->outputLine('The base workspace "%s" does not exist', [$baseWorkspaceName]); $this->quit(2); } if ($owner === '') { $owningUser = null; } else { $owningUser = $this->userService->getUser($owner); if ($owningUser === null) { $this->outputLine('The user "%s" specified as owner does not exist', [$owner]); $this->quit(3); } } if ($title === null) { $title = $workspaceName; } $workspace = new Workspace($workspaceName, $baseWorkspace, $owningUser); $workspace->setTitle($title); $workspace->setDescription($description); $this->workspaceRepository->add($workspace); if ($owningUser instanceof User) { $this->outputLine('Created a new workspace "%s", based on workspace "%s", owned by "%s".', [$workspaceName, $baseWorkspaceName, $owner]); } else { $this->outputLine('Created a new workspace "%s", based on workspace "%s".', [$workspaceName, $baseWorkspaceName]); } }
/** * This method is called when the form of this step has been submitted * * @param array $formValues * @return void */ public function postProcessFormValues(array $formValues) { $this->userService->createUser($formValues['username'], $formValues['password'], $formValues['firstName'], $formValues['lastName'], array('TYPO3.Neos:Administrator')); }