/** * @param UploadAvatar $command * @return \Flarum\Core\User * @throws \Flarum\Core\Exception\PermissionDeniedException */ public function handle(UploadAvatar $command) { $actor = $command->actor; $user = $this->users->findOrFail($command->userId); if ($actor->id !== $user->id) { $this->assertCan($actor, 'edit', $user); } $tmpFile = tempnam($this->app->storagePath() . '/tmp', 'avatar'); $command->file->moveTo($tmpFile); try { $file = new UploadedFile($tmpFile, $command->file->getClientFilename(), $command->file->getClientMediaType(), $command->file->getSize(), $command->file->getError(), true); $this->validator->assertValid(['avatar' => $file]); $manager = new ImageManager(); // Explicitly tell Intervention to encode the image as JSON (instead of having to guess from the extension) $encodedImage = $manager->make($tmpFile)->fit(100, 100)->encode('jpg', 100); file_put_contents($tmpFile, $encodedImage); $this->events->fire(new AvatarWillBeSaved($user, $actor, $tmpFile)); $mount = new MountManager(['source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))), 'target' => $this->uploadDir]); if ($user->avatar_path && $mount->has($file = "target://{$user->avatar_path}")) { $mount->delete($file); } $uploadName = Str::lower(Str::quickRandom()) . '.jpg'; $user->changeAvatarPath($uploadName); $mount->move('source://' . pathinfo($tmpFile, PATHINFO_BASENAME), "target://{$uploadName}"); $user->save(); $this->dispatchEventsFor($user, $actor); return $user; } catch (Exception $e) { @unlink($tmpFile); throw $e; } }
/** * @param UploadAvatar $command * @return \Flarum\Core\User * @throws \Flarum\Core\Exception\PermissionDeniedException */ public function handle(UploadAvatar $command) { $actor = $command->actor; $user = $this->users->findOrFail($command->userId); if ($actor->id !== $user->id) { $this->assertCan($actor, 'edit', $user); } $tmpFile = tempnam($this->app->storagePath() . '/tmp', 'avatar'); $command->file->moveTo($tmpFile); $file = new UploadedFile($tmpFile, $command->file->getClientFilename(), $command->file->getClientMediaType(), $command->file->getSize(), $command->file->getError(), true); $this->validator->assertValid(['avatar' => $file]); $manager = new ImageManager(); $manager->make($tmpFile)->fit(100, 100)->save(); $this->events->fire(new AvatarWillBeSaved($user, $actor, $tmpFile)); $mount = new MountManager(['source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))), 'target' => $this->uploadDir]); if ($user->avatar_path && $mount->has($file = "target://{$user->avatar_path}")) { $mount->delete($file); } $uploadName = Str::lower(Str::quickRandom()) . '.jpg'; $user->changeAvatarPath($uploadName); $mount->move("source://" . pathinfo($tmpFile, PATHINFO_BASENAME), "target://{$uploadName}"); $user->save(); $this->dispatchEventsFor($user, $actor); return $user; }
/** * @param $tag * @param UserRepository $users * @return bool */ public static function addId($tag, UserRepository $users) { if ($id = $users->getIdForUsername(rawurlencode($tag->getAttribute('username')))) { $tag->setAttribute('id', $id); return true; } }
/** * @param Request $request * @return JsonResponse|EmptyResponse */ public function handle(Request $request) { $actor = $request->getAttribute('actor'); $Referer = $request->getHeader('Referer'); $params = array_only($request->getParsedBody(), ['identification', 'password']); $response = $this->apiClient->send(TokenController::class, $actor, [], $params); if ($response->getStatusCode() === 200) { $data = json_decode($response->getBody()); $session = $request->getAttribute('session'); $this->authenticator->logIn($session, $data->userId); $token = AccessToken::find($data->token); event(new UserLoggedIn($this->users->findOrFail($data->userId), $token)); $response = FigResponseCookies::set($response, SetCookie::create("lastLoginName")->withValue($request->getParsedBody()['identification'])->withPath('/')); $response = $this->rememberer->remember($response, $token); } elseif ($response->getStatusCode() === 401) { $responseNew = $this->apiClient->send(PingxxTokenController::class, $actor, [], $params); if ($responseNew->getStatusCode() === 200) { $data = json_decode($responseNew->getBody()); $session = $request->getAttribute('session'); $this->authenticator->logIn($session, $data->userId); $token = AccessToken::find($data->token); event(new UserLoggedIn($this->users->findOrFail($data->userId), $token)); $responseNew = FigResponseCookies::set($responseNew, SetCookie::create("lastLoginName")->withValue($request->getParsedBody()['identification'])->withPath('/')->withDomain('dashboard.pingxx.com')); $responseNew = $this->rememberer->remember($responseNew, $token); return $responseNew; } else { return $response; } } return $response; }
/** * @param EditUser $command * @return User * @throws \Flarum\Core\Exception\PermissionDeniedException */ public function handle(EditUser $command) { $actor = $command->actor; $data = $command->data; $user = $this->users->findOrFail($command->userId, $actor); $canEdit = $actor->can('edit', $user); $isSelf = $actor->id === $user->id; $attributes = array_get($data, 'attributes', []); $relationships = array_get($data, 'relationships', []); if (isset($attributes['username'])) { $this->assertPermission($canEdit); $user->rename($attributes['username']); } if (isset($attributes['email'])) { if ($isSelf) { $user->requestEmailChange($attributes['email']); } else { $this->assertPermission($canEdit); $user->changeEmail($attributes['email']); } } if (isset($attributes['password'])) { $this->assertPermission($canEdit); $user->changePassword($attributes['password']); } if (isset($attributes['bio'])) { if (!$isSelf) { $this->assertPermission($canEdit); } $user->changeBio($attributes['bio']); } if (!empty($attributes['readTime'])) { $this->assertPermission($isSelf); $user->markAllAsRead(); } if (!empty($attributes['preferences'])) { $this->assertPermission($isSelf); foreach ($attributes['preferences'] as $k => $v) { $user->setPreference($k, $v); } } if (isset($relationships['groups']['data']) && is_array($relationships['groups']['data'])) { $this->assertPermission($canEdit); $newGroupIds = []; foreach ($relationships['groups']['data'] as $group) { if ($id = array_get($group, 'id')) { $newGroupIds[] = $id; } } $user->raise(new UserGroupsWereChanged($user, $user->groups()->get()->all())); $user->afterSave(function (User $user) use($newGroupIds) { $user->groups()->sync($newGroupIds); }); } $this->events->fire(new UserWillBeSaved($user, $actor, $data)); $this->validator->assertValid(array_merge($user->getDirty(), array_only($attributes, ['password', 'email']))); $user->save(); $this->dispatchEventsFor($user, $actor); return $user; }
/** * {@inheritdoc} */ protected function conditions(AbstractSearch $search, array $matches, $negate) { if (!$search instanceof UserSearch) { throw new LogicException('This gambit can only be applied on a UserSearch'); } $email = trim($matches[1], '"'); $user = $this->users->findByEmail($email); $search->getQuery()->where('id', $negate ? '!=' : '=', $user->id); }
/** * {@inheritdoc} */ protected function conditions(AbstractSearch $search, array $matches, $negate) { if (!$search instanceof DiscussionSearch) { throw new LogicException('This gambit can only be applied on a DiscussionSearch'); } $username = trim($matches[1], '"'); $id = $this->users->getIdForUsername($username); $search->getQuery()->where('start_user_id', $negate ? '!=' : '=', $id); }
/** * @param DeleteUser $command * @return \Flarum\Core\User * @throws PermissionDeniedException */ public function handle(DeleteUser $command) { $actor = $command->actor; $user = $this->users->findOrFail($command->userId, $actor); $this->assertCan($actor, 'delete', $user); $this->events->fire(new UserWillBeDeleted($user, $actor, $command->data)); $user->delete(); $this->dispatchEventsFor($user, $actor); return $user; }
/** * {@inheritdoc} */ protected function data(ServerRequestInterface $request, Document $document) { $id = array_get($request->getQueryParams(), 'id'); if (!is_numeric($id)) { $id = $this->users->getIdForUsername($id); } $actor = $request->getAttribute('actor'); if ($actor->id == $id) { $this->serializer = 'Flarum\\Api\\Serializer\\CurrentUserSerializer'; } return $this->users->findOrFail($id, $actor); }
/** * {@inheritdoc} */ protected function conditions(AbstractSearch $search, array $matches, $negate) { if (!$search instanceof DiscussionSearch) { throw new LogicException('This gambit can only be applied on a DiscussionSearch'); } $usernames = trim($matches[1], '"'); $usernames = explode(',', $usernames); $ids = []; foreach ($usernames as $username) { $ids[] = $this->users->getIdForUsername($username); } $search->getQuery()->whereIn('start_user_id', $ids, 'and', $negate); }
/** * {@inheritdoc} */ public function handle(ServerRequestInterface $request) { $body = $request->getParsedBody(); $identification = array_get($body, 'identification'); $password = array_get($body, 'password'); $user = $this->users->findByIdentification($identification); if (!$user || !$user->checkPassword($password)) { throw new PermissionDeniedException(); } $token = AccessToken::generate($user->id); $token->save(); return new JsonResponse(['token' => $token->id, 'userId' => $user->id]); }
/** * @param Request $request * @return JsonResponse|EmptyResponse */ public function handle(Request $request) { $actor = $request->getAttribute('actor'); $params = array_only($request->getParsedBody(), ['identification', 'password']); $response = $this->apiClient->send(TokenController::class, $actor, [], $params); if ($response->getStatusCode() === 200) { $data = json_decode($response->getBody()); $session = $request->getAttribute('session'); $this->authenticator->logIn($session, $data->userId); $token = AccessToken::find($data->token); event(new UserLoggedIn($this->users->findOrFail($data->userId), $token)); $response = $this->rememberer->remember($response, $token); } return $response; }
/** * @param RequestPasswordReset $command * @return \Flarum\Core\User * @throws ModelNotFoundException */ public function handle(RequestPasswordReset $command) { $user = $this->users->findByEmail($command->email); if (!$user) { throw new ModelNotFoundException(); } $token = PasswordToken::generate($user->id); $token->save(); $data = ['username' => $user->username, 'url' => $this->url->toRoute('resetPassword', ['token' => $token->id]), 'forumTitle' => $this->settings->get('forum_title')]; $this->mailer->send(['text' => 'flarum::emails.resetPassword'], $data, function (Message $message) use($user) { $message->to($user->email); $message->subject('Reset Your Password'); }); return $user; }
/** * {@inheritdoc} */ public function handle(ServerRequestInterface $request) { $body = $request->getParsedBody(); $identification = array_get($body, 'identification'); $password = array_get($body, 'password'); $user = $this->users->findByIdentification($identification); if (!$user || !$user->checkPassword($password)) { throw new PermissionDeniedException(); } if (!$user->is_activated) { $this->events->fire(new UserEmailChangeWasRequested($user, $user->email)); return new JsonResponse(['emailConfirmationRequired' => $user->email], 401); } $token = $this->bus->dispatch(new GenerateAccessToken($user->id)); return new JsonResponse(['token' => $token->id, 'userId' => $user->id]); }
/** * @param RequestPasswordReset $command * @return \Flarum\Core\User * @throws ModelNotFoundException */ public function handle(RequestPasswordReset $command) { $user = $this->users->findByEmail($command->email); if (!$user) { throw new ModelNotFoundException(); } $token = PasswordToken::generate($user->id); $token->save(); $data = ['{username}' => $user->username, '{url}' => $this->url->toRoute('resetPassword', ['token' => $token->id]), '{forum}' => $this->settings->get('forum_title')]; $body = $this->translator->trans('core.email.reset_password.body', $data); $this->mailer->raw($body, function (Message $message) use($user, $data) { $message->to($user->email); $message->subject('[' . $data['{forum}'] . '] ' . $this->translator->trans('core.email.reset_password.subject')); }); return $user; }
/** * @param mixed $command * @param Closure $next */ public function handle($command, $next) { // Check if a command we want to hook. if ($command instanceof RequestPasswordReset) { // Find the user account requesting reset. $user = $this->users->findByEmail($command->email); // Only handle is user exists and is a singleso user. // Let the core handle unrecognized users and local only accounts. if ($user && isset($user->singleso_id)) { // Throw exception for the user to prevent reset. throw new ValidationException(['SingleSO: Direct password resetting disabled.']); } } // Continue on. return $next($command); }
/** * @param DeleteAvatar $command * @return \Flarum\Core\User * @throws PermissionDeniedException */ public function handle(DeleteAvatar $command) { $actor = $command->actor; $user = $this->users->findOrFail($command->userId); if ($actor->id !== $user->id) { $this->assertCan($actor, 'edit', $user); } $avatarPath = $user->avatar_path; $user->changeAvatarPath(null); $this->events->fire(new AvatarWillBeDeleted($user, $actor)); $user->save(); if ($this->uploadDir->has($avatarPath)) { $this->uploadDir->delete($avatarPath); } $this->dispatchEventsFor($user, $actor); return $user; }
/** * @param Request $request * @param array $routeParams * @return JsonResponse|EmptyResponse */ public function handle(Request $request, array $routeParams = []) { $controller = 'Flarum\\Api\\Controller\\TokenController'; $actor = $request->getAttribute('actor'); $params = array_only($request->getParsedBody(), ['identification', 'password']); $response = $this->apiClient->send($controller, $actor, [], $params); if ($response->getStatusCode() === 200) { $data = json_decode($response->getBody()); // Extend the token's expiry to 2 weeks so that we can set a // remember cookie AccessToken::where('id', $data->token)->update(['expires_at' => new DateTime('+2 weeks')]); event(new UserLoggedIn($this->users->findOrFail($data->userId), $data->token)); return $this->withRememberCookie($response, $data->token); } else { return $response; } }
/** * @param Request $request * @param array $routeParams * @return JsonResponse|EmptyResponse */ public function handle(Request $request, array $routeParams = []) { $controller = 'Flarum\\Api\\Controller\\TokenController'; $actor = $request->getAttribute('actor'); $params = array_only($request->getParsedBody(), ['identification', 'password']); $data = json_decode($this->apiClient->send($controller, $actor, [], $params)->getBody()); // TODO: The client needs to pass through exceptions(?) or the whole // response so we can look at the response code. For now if there isn't // any useful data we just assume it's a 401. if (isset($data->userId)) { // Extend the token's expiry to 2 weeks so that we can set a // remember cookie AccessToken::where('id', $data->token)->update(['expires_at' => new DateTime('+2 weeks')]); event(new UserLoggedIn($this->users->findOrFail($data->userId), $data->token)); return $this->withRememberCookie(new JsonResponse($data), $data->token); } else { return new EmptyResponse(401); } }
/** * @param SearchCriteria $criteria * @param int|null $limit * @param int $offset * @param array $load An array of relationships to load on the results. * @return SearchResults */ public function search(SearchCriteria $criteria, $limit = null, $offset = 0, array $load = []) { $actor = $criteria->actor; $query = $this->users->query()->whereVisibleTo($actor); // Construct an object which represents this search for users. // Apply gambits to it, sort, and paging criteria. Also give extensions // an opportunity to modify it. $search = new UserSearch($query->getQuery(), $actor); $this->gambits->apply($search, $criteria->query); $this->applySort($search, $criteria->sort); $this->applyOffset($search, $offset); $this->applyLimit($search, $limit + 1); event(new ConfigureUserSearch($search, $criteria)); // Execute the search query and retrieve the results. We get one more // results than the user asked for, so that we can say if there are more // results. If there are, we will get rid of that extra result. $users = $query->get(); if ($areMoreResults = $limit > 0 && $users->count() > $limit) { $users->pop(); } $users->load($load); return new SearchResults($users, $areMoreResults); }
/** * {@inheritdoc} */ public function apply(AbstractSearch $search, $bit) { $users = $this->users->getIdsForUsername($bit, $search->getActor()); $search->getQuery()->whereIn('id', $users); $search->setDefaultSort(['id' => $users]); }