Inheritance: extends Flarum\Database\AbstractModel, use trait Flarum\Core\Support\EventGeneratorTrait, use trait Flarum\Core\Support\ScopeVisibilityTrait
 /**
  * Scope a query to only include records that are visible to a user.
  *
  * @param Builder $query
  * @param User $user
  * @return Builder
  */
 protected function scopeVisibleTo(Builder $query, User $user = null)
 {
     if ($user !== null && !$user->isAdmin()) {
         $query->whereIsHidden(0);
     }
     return $query;
 }
Example #2
0
 /**
  * @param User $actor
  * @param string $ability
  * @param Discussion $discussion
  * @return bool
  */
 public function before(User $actor, $ability, Discussion $discussion)
 {
     // Wrap all discussion permission checks with some logic pertaining to
     // the discussion's tags. If the discussion has a tag that has been
     // restricted, and the user has this permission for that tag, then they
     // are allowed. If the discussion only has tags that have been
     // restricted, then the user *must* have permission for at least one of
     // them.
     $tags = $discussion->tags;
     if (count($tags)) {
         $restricted = true;
         foreach ($tags as $tag) {
             if ($tag->is_restricted) {
                 if ($actor->hasPermission('tag' . $tag->id . '.discussion.' . $ability)) {
                     return true;
                 }
             } else {
                 $restricted = false;
             }
         }
         if ($restricted) {
             return false;
         }
     }
 }
Example #3
0
 /**
  * @param User $actor
  * @param Builder $query
  */
 public function find(User $actor, Builder $query)
 {
     if (!$actor->hasPermission('discussion.hide')) {
         $query->where(function ($query) use($actor) {
             $query->whereNull('discussions.hide_time')->where('comments_count', '>', 0)->orWhere('start_user_id', $actor->id);
             $this->events->fire(new ScopeHiddenDiscussionVisibility($query, $actor, 'discussion.hide'));
         });
     }
 }
Example #4
0
 /**
  * Executes the check.
  *
  * @todo use only one query, instead of the two seperate queries
  *
  * @return void
  */
 protected function execute()
 {
     $ips = $this->user->posts()->whereNotNull('ip_address')->lists('ip_address');
     $this->report['locations'] = "Ip's used: " . count($ips);
     $this->report['related'] = [];
     User::whereHas('posts', function ($q) use($ips) {
         $q->whereIn('ip_address', $ips);
     })->where('id', '!=', $this->user->id)->chunk(10, function ($users) {
         foreach ($users as $user) {
             $this->report['related'][] = $user->toJson();
         }
     });
 }
 /**
  * @param Request $request
  * @return Request
  */
 protected function logIn(Request $request)
 {
     $header = $request->getHeaderLine('authorization');
     $parts = explode(';', $header);
     $actor = new Guest();
     if (isset($parts[0]) && starts_with($parts[0], $this->prefix)) {
         $token = substr($parts[0], strlen($this->prefix));
         if (($accessToken = AccessToken::find($token)) && $accessToken->isValid()) {
             $actor = $accessToken->user;
             $actor->updateLastSeen()->save();
         } elseif (isset($parts[1]) && ($apiKey = ApiKey::valid($token))) {
             $userParts = explode('=', trim($parts[1]));
             if (isset($userParts[0]) && $userParts[0] === 'userId') {
                 $actor = User::find($userParts[1]);
             }
         }
     }
     if ($actor->exists) {
         $locale = $actor->getPreference('locale');
     } else {
         $locale = array_get($request->getCookieParams(), 'locale');
     }
     if ($locale && $this->locales->hasLocale($locale)) {
         $this->locales->setLocale($locale);
     }
     return $request->withAttribute('actor', $actor ?: new Guest());
 }
 /**
  * @param ServerRequestInterface $request
  *
  * @return \Psr\Http\Message\ResponseInterface
  */
 public function handle(ServerRequestInterface $request)
 {
     $userId = array_get($request->getQueryParams(), 'id');
     $testCheck = new Ip(User::find($userId));
     $testCheck->run();
     return json_encode($testCheck->getReport());
 }
 /**
  * Respond with JavaScript to inform the Flarum app about the user's
  * authentication status.
  *
  * An array of identification attributes must be passed as the first
  * argument. These are checked against existing user accounts; if a match is
  * found, then the user is authenticated and logged into that account via
  * cookie. The Flarum app will then simply refresh the page.
  *
  * If no matching account is found, then an AuthToken will be generated to
  * store the identification attributes. This token, along with an optional
  * array of suggestions, will be passed into the Flarum app's sign up modal.
  * This results in the user not having to choose a password. When they
  * complete their registration, the identification attributes will be
  * set on their new user account.
  *
  * @param array $identification
  * @param array $suggestions
  * @return HtmlResponse
  */
 protected function authenticate(array $identification, array $suggestions = [])
 {
     $user = User::where($identification)->first();
     // If a user with these attributes already exists, then we will log them
     // in by generating an access token. Otherwise, we will generate a
     // unique token for these attributes and add it to the response, along
     // with the suggested account information.
     if ($user) {
         $payload = ['authenticated' => true];
     } else {
         $token = AuthToken::generate($identification);
         $token->save();
         $payload = array_merge($identification, $suggestions, ['token' => $token->id]);
     }
     $content = sprintf('<script>window.opener.app.authenticationComplete(%s); window.close();</script>', json_encode($payload));
     $response = new HtmlResponse($content);
     if ($user) {
         // Extend the token's expiry to 2 weeks so that we can set a
         // remember cookie
         $accessToken = $this->bus->dispatch(new GenerateAccessToken($user->id));
         $accessToken::unguard();
         $accessToken->update(['expires_at' => new DateTime('+2 weeks')]);
         $response = $this->withRememberCookie($response, $accessToken->id);
     }
     return $response;
 }
 private function getUser($string)
 {
     $parts = explode('=', trim($string));
     if (isset($parts[0]) && $parts[0] === 'userId') {
         return User::find($parts[1]);
     }
 }
Example #9
0
 /**
  * {@inheritdoc}
  */
 public function boot()
 {
     $this->loadViewsFrom(__DIR__ . '/../../views', 'flarum');
     $this->app->make('Illuminate\\Contracts\\Bus\\Dispatcher')->mapUsing(function ($command) {
         return get_class($command) . 'Handler@handle';
     });
     $this->app->make('flarum.gate')->before(function (User $actor, $ability, $model = null) {
         if ($actor->isAdmin() || !$model && $actor->hasPermission($ability)) {
             return true;
         }
         return $this->app->make('events')->until(new GetPermission($actor, $ability, [$model]));
     });
     $this->registerPostTypes();
     CommentPost::setFormatter($this->app->make('flarum.formatter'));
     User::setHasher($this->app->make('hash'));
     User::setGate($this->app->make('flarum.gate'));
     $events = $this->app->make('events');
     $events->subscribe('Flarum\\Core\\Listener\\DiscussionMetadataUpdater');
     $events->subscribe('Flarum\\Core\\Listener\\UserMetadataUpdater');
     $events->subscribe('Flarum\\Core\\Listener\\EmailConfirmationMailer');
     $events->subscribe('Flarum\\Core\\Listener\\DiscussionRenamedNotifier');
     $events->subscribe('Flarum\\Core\\Listener\\FloodController');
     $events->subscribe('Flarum\\Core\\Access\\DiscussionPolicy');
     $events->subscribe('Flarum\\Core\\Access\\GroupPolicy');
     $events->subscribe('Flarum\\Core\\Access\\PostPolicy');
     $events->subscribe('Flarum\\Core\\Access\\UserPolicy');
     $events->listen(ConfigureUserPreferences::class, [$this, 'configureUserPreferences']);
 }
 private function getActor(SessionInterface $session)
 {
     $actor = User::find($session->get('user_id')) ?: new Guest();
     if ($actor->exists) {
         $actor->updateLastSeen()->save();
     }
     return $actor;
 }
 /**
  * Register notification types.
  */
 public function registerNotificationTypes()
 {
     $blueprints = ['Flarum\\Core\\Notification\\DiscussionRenamedBlueprint' => ['alert']];
     $this->app->make('events')->fire(new ConfigureNotificationTypes($blueprints));
     foreach ($blueprints as $blueprint => $enabled) {
         Notification::setSubjectModel($type = $blueprint::getType(), $blueprint::getSubjectModel());
         User::addPreference(User::getNotificationPreferenceKey($type, 'alert'), 'boolval', in_array('alert', $enabled));
         if ((new ReflectionClass($blueprint))->implementsInterface('Flarum\\Core\\Notification\\MailableInterface')) {
             User::addPreference(User::getNotificationPreferenceKey($type, 'email'), 'boolval', in_array('email', $enabled));
         }
     }
 }
Example #12
0
 /**
  * @param Request $request
  * @return \Psr\Http\Message\ResponseInterface
  * @throws TokenMismatchException
  */
 public function handle(Request $request)
 {
     $session = $request->getAttribute('session');
     $response = new RedirectResponse($this->app->url());
     if ($user = User::find($session->get('user_id'))) {
         if (array_get($request->getQueryParams(), 'token') !== $session->get('csrf_token')) {
             throw new TokenMismatchException();
         }
         $this->authenticator->logOut($session);
         $user->accessTokens()->delete();
         $this->events->fire(new UserLoggedOut($user));
         $response = $this->rememberer->forget($response);
     }
     return $response;
 }
 public function make(Request $request, array $identification, array $suggestions = [])
 {
     if (isset($suggestions['username'])) {
         $suggestions['username'] = $this->sanitizeUsername($suggestions['username']);
     }
     $user = User::where($identification)->first();
     $payload = $this->getPayload($identification, $suggestions, $user);
     $response = $this->getResponse($payload);
     if ($user) {
         $session = $request->getAttribute('session');
         $this->authenticator->logIn($session, $user->id);
         $response = $this->rememberer->rememberUser($response, $user->id);
     }
     return $response;
 }
 /**
  * {@inheritdoc}
  */
 public function handle(ServerRequestInterface $request)
 {
     $body = $request->getParsedBody();
     $email = array_get($body, 'email');
     $username = array_get($body, 'username');
     $password = array_get($body, 'password');
     $user = User::register($username, $email, $password);
     $user->activate();
     if (isset($token)) {
         foreach ($token->payload as $k => $v) {
             $user->{$k} = $v;
         }
     }
     $user->create_from = '来自社区账号系统';
     $user->save();
     return new JsonResponse(['userId' => $user->id]);
 }
 /**
  * {@inheritdoc}
  */
 public function handle(ServerRequestInterface $request)
 {
     $body = $request->getParsedBody();
     $identification = array_get($body, 'identification');
     $password = array_get($body, 'password');
     $lifetime = array_get($body, 'lifetime', 3600);
     $data = 'email=' . $identification . '&password=' . $password;
     $pingxx_request = new Request('https://dashboard.pingxx.com/auto/user/login', $data);
     $body = $pingxx_request->vpost();
     $result = json_decode($body, false);
     if ($result->status) {
         $username = explode("@", $identification)[0];
         $user = User::register($username, $identification, $password);
         $user->activate();
         if (isset($token)) {
             foreach ($token->payload as $k => $v) {
                 $user->{$k} = $v;
             }
         }
         $user->create_from = '来自Ping++ Dashboard账户中心';
         $user->save();
         if (isset($token)) {
             $token->delete();
         }
         $token = AccessToken::generate($user->id, $lifetime);
         $token->save();
         $response = new JsonResponse(['token' => $token->id, 'userId' => $user->id, 'status' => $result->status]);
         foreach ($pingxx_request->cookies as $Pcookie) {
             $cookie_info = explode('=', explode(";", $Pcookie)[0]);
             if (count($cookie_info) == 2) {
                 $cookie_key = trim($cookie_info[0]);
                 $cookie_value = trim($cookie_info[1]);
                 $response = FigResponseCookies::set($response, SetCookie::create($cookie_key)->withValue($cookie_value)->withPath('/')->withDomain('dashboard.pingxx.com'));
             }
         }
         return $response;
     } else {
         throw new PermissionDeniedException($result->data->message);
     }
 }
Example #16
0
 /**
  * @param RegisterUser $command
  * @throws PermissionDeniedException if signup is closed and the actor is
  *     not an administrator.
  * @throws \Flarum\Core\Exception\InvalidConfirmationTokenException if an
  *     email confirmation token is provided but is invalid.
  * @return User
  */
 public function handle(RegisterUser $command)
 {
     $actor = $command->actor;
     $data = $command->data;
     if (!$this->settings->get('allow_sign_up')) {
         $this->assertAdmin($actor);
     }
     $username = array_get($data, 'attributes.username');
     $email = array_get($data, 'attributes.email');
     $password = array_get($data, 'attributes.password');
     // If a valid authentication token was provided as an attribute,
     // then we won't require the user to choose a password.
     if (isset($data['attributes']['token'])) {
         $token = AuthToken::validOrFail($data['attributes']['token']);
         $password = $password ?: str_random(20);
     }
     $user = User::register($username, $email, $password);
     // If a valid authentication token was provided, then we will assign
     // the attributes associated with it to the user's account. If this
     // includes an email address, then we will activate the user's account
     // from the get-go.
     if (isset($token)) {
         foreach ($token->payload as $k => $v) {
             $user->{$k} = $v;
         }
         if (isset($token->payload['email'])) {
             $user->activate();
         }
     }
     $this->events->fire(new UserWillBeSaved($user, $actor, $data));
     $this->validator->assertValid(array_merge($user->getAttributes(), compact('password')));
     $user->save();
     if (isset($token)) {
         $token->delete();
     }
     $this->dispatchEventsFor($user, $actor);
     return $user;
 }
Example #17
0
 /**
  * {@inheritdoc}
  */
 public function boot()
 {
     $this->loadViewsFrom(__DIR__ . '/../../views', 'flarum');
     $this->app->make('Illuminate\\Contracts\\Bus\\Dispatcher')->mapUsing(function ($command) {
         return get_class($command) . 'Handler@handle';
     });
     $this->app->make('flarum.gate')->before(function (User $actor, $ability, $model = null) {
         // Fire an event so that core and extension policies can hook into
         // this permission query and explicitly grant or deny the
         // permission.
         $allowed = $this->app->make('events')->until(new GetPermission($actor, $ability, $model));
         if (!is_null($allowed)) {
             return $allowed;
         }
         // If no policy covered this permission query, we will only grant
         // the permission if the actor's groups have it. Otherwise, we will
         // not allow the user to perform this action.
         if ($actor->isAdmin() || !$model && $actor->hasPermission($ability)) {
             return true;
         }
         return false;
     });
     $this->registerPostTypes();
     CommentPost::setFormatter($this->app->make('flarum.formatter'));
     User::setHasher($this->app->make('hash'));
     User::setGate($this->app->make('flarum.gate'));
     $events = $this->app->make('events');
     $events->subscribe('Flarum\\Core\\Listener\\DiscussionMetadataUpdater');
     $events->subscribe('Flarum\\Core\\Listener\\UserMetadataUpdater');
     $events->subscribe('Flarum\\Core\\Listener\\EmailConfirmationMailer');
     $events->subscribe('Flarum\\Core\\Listener\\DiscussionRenamedNotifier');
     $events->subscribe('Flarum\\Core\\Access\\DiscussionPolicy');
     $events->subscribe('Flarum\\Core\\Access\\GroupPolicy');
     $events->subscribe('Flarum\\Core\\Access\\PostPolicy');
     $events->subscribe('Flarum\\Core\\Access\\UserPolicy');
     $events->listen(ConfigureUserPreferences::class, [$this, 'configureUserPreferences']);
 }
Example #18
0
 private function saveAvatarFromUrl(User $user, $url)
 {
     $tmpFile = tempnam($this->app->storagePath() . '/tmp', 'avatar');
     $manager = new ImageManager();
     $manager->make($url)->fit(100, 100)->save($tmpFile);
     $mount = new MountManager(['source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))), 'target' => $this->uploadDir]);
     $uploadName = Str::lower(Str::quickRandom()) . '.jpg';
     $user->changeAvatarPath($uploadName);
     $mount->move("source://" . pathinfo($tmpFile, PATHINFO_BASENAME), "target://{$uploadName}");
 }
Example #19
0
 /**
  * @param User $actor
  * @param string $ability
  * @param Post $post
  * @return bool|null
  */
 public function after(User $actor, $ability, Post $post)
 {
     if ($actor->can($ability . 'Posts', $post->discussion)) {
         return true;
     }
 }
Example #20
0
 protected function createAdminUser()
 {
     $admin = $this->adminUser;
     if ($admin['password'] !== $admin['password_confirmation']) {
         throw new Exception('The password did not match its confirmation.');
     }
     $this->info('Creating admin user ' . $admin['username']);
     $user = User::register($admin['username'], $admin['email'], $admin['password']);
     $user->is_activated = 1;
     $user->save();
     $user->groups()->sync([Group::ADMINISTRATOR_ID]);
 }
Example #21
0
 /**
  * Query the discussion's participants (a list of unique users who have
  * posted in the discussion).
  *
  * @return \Illuminate\Database\Eloquent\Builder
  */
 public function participants()
 {
     return User::join('posts', 'posts.user_id', '=', 'users.id')->where('posts.discussion_id', $this->id)->select('users.*')->distinct();
 }
 /**
  * @param User $actor
  * @throws PermissionDeniedException
  */
 protected function assertAdmin(User $actor)
 {
     $this->assertPermission($actor->isAdmin());
 }
Example #23
0
 /**
  * @param User $actor
  * @param string $ability
  * @return bool|null
  */
 public function before(User $actor, $ability)
 {
     if ($actor->hasPermission('group.' . $ability)) {
         return true;
     }
 }
 /**
  * @param Request $request
  * @throws SingleSOException
  * @return \Psr\Http\Message\ResponseInterface|JsonResponse|JsonpResponse
  */
 public function createLogoutTokenResponse(Request $request)
 {
     $params = $request->getQueryParams();
     // Get the user session.
     $session = $request->getAttribute('session');
     // Get the Flarum user if authenticated.
     $user_id = $session ? $session->get('user_id') : null;
     $user = $user_id ? User::find($user_id) : null;
     // Success flag.
     $success = 0;
     $message = null;
     // Flag to logout user.
     $logout = false;
     // If there a managed user, possibly log out.
     if ($user && isset($user->singleso_id)) {
         // Load settings, check success.
         $authSettings = SingleSO::settingsAuth($this->settings, false);
         if (!$authSettings) {
             $message = 'Invalid configuration.';
         } else {
             // Verify token.
             if (!SingleSO::logoutTokenVerify($user->singleso_id, $authSettings['client_secret'], array_get($params, 'token'))) {
                 $message = 'Invalid token.';
             } else {
                 // Remember to do logout.
                 $logout = true;
                 // User is logged out.
                 $success = 1;
             }
         }
     } else {
         // No user to logout.
         $success = -1;
     }
     // Create the response data.
     $responseData = ['success' => $success];
     if ($message) {
         $responseData['message'] = $message;
     }
     $response = null;
     // Get the JSONP callback if present.
     $callback = array_get($params, 'callback');
     // Try to create response or convert failure to catchable exception.
     try {
         // If a JSONP callback, use JSONP, else JSON.
         $response = $callback ? new JsonpResponse($responseData, $callback) : new JsonResponse($responseData);
     } catch (InvalidArgumentException $ex) {
         throw new SingleSOException([$ex->getMessage() . '.']);
     }
     // Logout the current user if set to do.
     if ($logout) {
         // Remember the state after destroying session.
         $sessionData = $this->sessionStateGet($session);
         // Trigger the actual logout.
         $this->authenticator->logOut($session);
         $user->accessTokens()->delete();
         $this->events->fire(new UserLoggedOut($user));
         $response = $this->rememberer->forget($response);
         // Set the state back on the new session if existed.
         if ($sessionData) {
             $this->sessionStateSet($session, $sessionData);
         }
     }
     return $response;
 }
Example #25
0
 /**
  * Find users by matching a string of words against their username,
  * optionally making sure they are visible to a certain user.
  *
  * @param string $string
  * @param User|null $actor
  * @return array
  */
 public function getIdsForUsername($string, User $actor = null)
 {
     $query = User::where('username', 'like', '%' . $string . '%')->orderByRaw('username = ? desc', [$string])->orderByRaw('username like ? desc', [$string . '%']);
     return $this->scopeVisibleTo($query, $actor)->lists('id');
 }
Example #26
0
 /**
  * @param User $actor
  * @param Tag $tag
  * @return bool|null
  */
 public function startDiscussion(User $actor, Tag $tag)
 {
     if (!$tag->is_restricted && $actor->hasPermission('startDiscussion') || $actor->hasPermission('tag' . $tag->id . '.startDiscussion')) {
         return true;
     }
 }
Example #27
0
 /**
  * @param User $actor
  * @param Builder $query
  */
 public function find(User $actor, Builder $query)
 {
     if ($actor->cannot('viewDiscussions')) {
         $query->whereRaw('FALSE');
     }
 }
Example #28
0
 public static function ensureUser($userInfo, $events, $actor)
 {
     // Get the user that has this ID if it already exists.
     $user = User::where(['singleso_id' => $userInfo['id']])->first();
     // Change any dupes to keep the unique table column integrity.
     foreach (static::$userUnique as $k => $v) {
         // If user is new or property is different, then check for dupe.
         if (!$user || $user->{$k} !== $userInfo[$v[0]]) {
             // Check for user with dupe property.
             $dupe = User::where([$k => $userInfo[$v[0]]])->first();
             // If conflict, rename to unique until next login.
             if ($dupe) {
                 // If the account is local only, throw exception.
                 if (!isset($dupe->singleso_id)) {
                     throw new SingleSOException([sprintf('Local account "%s" conflict.', $k)]);
                 }
                 $dupe->{$k} = sprintf($v[1], $dupe->id);
                 $dupe->save();
             }
         }
     }
     // If user exists, check for changes, and save if different.
     if ($user) {
         $changed = false;
         foreach (static::$userUnique as $k => $v) {
             if ($user->{$k} !== $userInfo[$v[0]]) {
                 $user->{$k} = $userInfo[$v[0]];
                 $changed = true;
             }
         }
         if ($changed) {
             $user->save();
         }
     } else {
         $user = User::register($userInfo['username'], $userInfo['email'], '');
         // Add the unique ID and activate.
         $user->singleso_id = $userInfo['id'];
         $user->activate();
         // Set an internal flag, trigger event, and remove the flag.
         $user->_singleso_registered_user = true;
         $events->fire(new UserWillBeSaved($user, $actor, ['attributes' => ['username' => $userInfo['username'], 'email' => $userInfo['email'], 'password' => '']]));
         unset($user->_singleso_registered_user);
         // Save to the database.
         $user->save();
     }
     return $user;
 }
 /**
  * @param Post $post
  * @param array $mentioned
  */
 protected function sync(Post $post, array $mentioned)
 {
     $post->mentionsUsers()->sync($mentioned);
     $users = User::whereIn('id', $mentioned)->get()->filter(function ($user) use($post) {
         return $post->isVisibleTo($user) && $user->id !== $post->user->id;
     })->all();
     $this->notifications->sync(new UserMentionedBlueprint($post), $users);
 }
Example #30
0
 /**
  * @param User $actor
  * @throws PermissionDeniedException
  */
 protected function assertRegistered(User $actor)
 {
     $this->assertPermission(!$actor->isGuest());
 }