Esempio n. 1
0
    def create_comment(
            self,
            thread_uid: str,
            body: str,
            author: auth.model.AbstractUser,
            status: str = 'published',
            parent_uid: str = None) -> comments.model.AbstractComment:
        """Create a new comment
        """
        body = body.strip()

        comment = odm.dispense('comment')  # type: _model.ODMComment
        comment.f_set('thread_uid', thread_uid)
        comment.f_set('body', body)
        comment.f_set('author', author.uid)
        comment.f_set('status', status)
        comment.save()

        if parent_uid:
            parent = odm.get_by_ref('comment:' + parent_uid)
            if parent.depth == comments.get_comment_max_depth():
                raise RuntimeError('Comment depth is too big')

            try:
                auth.switch_user_to_system()
                parent.append_child(comment).save()
            finally:
                auth.restore_user()

        return _model.Comment(comment)
Esempio n. 2
0
    def sign_up(self, data: dict) -> auth.model.AbstractUser:
        """Sign up a new user
        """
        # Create user
        try:
            auth.switch_user_to_system()
            user = auth.create_user(data.get('login'), data.get('password'))

            # Fill additional fields
            for k, v in data.items():
                if k not in ('email', 'first_name', 'last_name',
                             'nickname') or not v:
                    continue
                user.set_field(k, v)

            # Set nickname
            if 'nickname' not in data:
                user.nickname = user.first_last_name

            user.save()

        finally:
            auth.restore_user()

        return user
Esempio n. 3
0
    def _on_pre_delete(self, **kwargs):
        """Hook
        """
        super()._on_pre_delete(**kwargs)

        # Delete linkes, bookmarks, etc
        try:
            auth.switch_user_to_system()
            flag.delete_all(self)
        finally:
            auth.restore_user()
Esempio n. 4
0
def on_content_view(entity: ContentWithURL):
    if entity.has_field('comments_count') and entity.has_field(
            'route_alias') and entity.route_alias:
        # Update entity's comments count
        try:
            auth.switch_user_to_system()
            cnt = comments.get_all_comments_count(entity.route_alias.alias)
            entity.f_set('comments_count', cnt).save(fast=True)
            return cnt
        finally:
            auth.restore_user()
Esempio n. 5
0
    def exec(self) -> int:
        entity = _api.dispense(self.arg('model'), self.arg('uid'))
        if entity and entity.has_field('views_count'):
            try:
                auth.switch_user_to_system()
                entity.f_inc('views_count').save(fast=True)
            finally:
                auth.restore_user()

            return entity.f_get('views_count')

        return 0
Esempio n. 6
0
def on_flag_toggle(flg: flag.Flag):
    if not isinstance(flg.entity, Content):
        return

    f_name = '{}_count'.format(lang.english_plural(flg.variant))
    if flg.entity.has_field(f_name):
        try:
            auth.switch_user_to_system()
            flg.entity.f_set(f_name, flag.count(flg.entity,
                                                flg.variant)).save(fast=True)
        finally:
            auth.restore_user()
Esempio n. 7
0
    def exec(self) -> dict:
        # Is current user authorized
        current_user = auth.get_current_user()
        if current_user.is_anonymous:
            raise self.forbidden()

        # Load user to unblock
        try:
            user = auth.get_user(uid=self.arg('uid'))
            auth.switch_user_to_system()
            current_user.remove_blocked_user(user).save()
        except auth.error.UserNotFound:
            raise self.not_found()
        finally:
            auth.restore_user()

        return {'status': True}
Esempio n. 8
0
    def _on_after_save(self, first_save: bool = False, **kwargs):
        """Hook
        """
        from . import _api

        # Recalculate tags weights
        if first_save and self.has_field('tags'):
            for t in self.tags:
                weight = 0
                for model in _api.get_models().keys():
                    try:
                        weight += _api.find(model, language=self.language).inc('tags', [t]).count()
                    except odm.error.FieldNotDefined:
                        pass

                try:
                    auth.switch_user_to_system()
                    t.f_set('weight', weight).save(fast=True)
                finally:
                    auth.restore_user()

        # Update localization entities references
        # For each language except current one
        for lng in lang.langs(False):
            # Get localization ref for lng
            localization = self.f_get('localization_' + lng)

            # If localization is set
            if isinstance(localization, Content):
                # If localized entity hasn't reference to this entity, set it
                if localization.f_get('localization_' + self.language) != self:
                    localization.f_set('localization_' + self.language, self).save()

            # If localization is not set
            elif localization is None:
                # Clear references from localized entities
                f = _api.find(self.model, language=lng).eq('localization_' + self.language, self)
                for referenced in f.get():
                    referenced.f_set('localization_' + self.language, None).save()

        # Notify content status change
        if self.has_field('status') and self.has_field('prev_status') and self.status != self.prev_status:
            self.content_on_status_change()

        events.fire('*****@*****.**', entity=self)
        events.fire('content@entity.{}.save'.format(self.model), entity=self)
Esempio n. 9
0
    def f_get(self, field_name: str, **kwargs):
        """Get field's value
        """
        if not self.is_new and field_name == 'author':
            try:
                return super().f_get(field_name, **kwargs)

            # Owner was deleted or for some reason cannot be accessed
            except auth.error.UserNotFound:
                try:
                    # Set first admin as owner
                    auth.switch_user_to_system()
                    self.f_set(field_name, auth.get_admin_user()).save()
                finally:
                    auth.restore_user()

                return super().f_get(field_name, **kwargs)

        return super().f_get(field_name, **kwargs)
Esempio n. 10
0
    def _on_f_get(self, field_name: str, value, **kwargs):
        if field_name == 'picture':
            if not self.get_field('picture').get_val() and \
                    not (self.is_new or self.is_deleted or self.is_being_deleted):
                try:
                    # Load user picture from Gravatar
                    img_url = 'https://www.gravatar.com/avatar/' + util.md5_hex_digest(
                        self.f_get('login')) + '?s=512'
                    img = file.create(img_url)
                    auth.switch_user_to_system()
                    self.f_set('picture', img).save()
                    value = img
                finally:
                    auth.restore_user()

        elif field_name == 'is_confirmed':
            value = not self.f_get('confirmation_hash')

        return value
Esempio n. 11
0
    def _on_after_delete(self, **kwargs):
        """Hook
        """
        super()._on_after_delete()

        # Delete comments
        try:
            auth.switch_user_to_system()
            comments.delete_thread(self.route_alias.alias)
        except (NotImplementedError, comments.error.NoDriversRegistered):
            pass
        finally:
            auth.restore_user()

        # Delete linked route alias
        try:
            self.route_alias.delete()
        except odm.error.EntityDeleted:
            # Entity was deleted by another instance
            pass
Esempio n. 12
0
    def _on_submit(self):
        """Hook
        """
        try:
            token = self.attr('token')
            user = auth.get_user(_RESET_TOKENS_POOL.get(token))

            auth.switch_user_to_system()
            user.password = self.val('password')
            user.save()
            auth.restore_user()

            _RESET_TOKENS_POOL.rm(token)

            router.session().add_success_message(
                lang.t('auth_ui_password@reset_password_success'))

            self.redirect = router.rule_url('auth_ui@sign_in',
                                            {'driver': 'password'})

        except auth.error.UserNotFound:
            raise RuntimeError('Invalid token')
Esempio n. 13
0
    def exec(self):
        try:
            # Search for user
            user = next(
                auth.find_users(
                    query.Query(query.Eq('confirmation_hash',
                                         self.arg('code')))))
        except StopIteration:
            # No user found, redirect to sign in URL
            return self.redirect(_api.sign_in_url(redirect=router.base_url()))

        try:
            auth.switch_user_to_system()
            user.confirmation_hash = None
            if user.status == auth.USER_STATUS_WAITING:
                user.status = auth.get_new_user_status()
            user.save()
        finally:
            auth.restore_user()

        router.session().add_success_message(
            lang.t('auth_ui@registration_confirm_success'))

        return self.redirect(_api.sign_in_url(redirect=router.base_url()))
Esempio n. 14
0
    def sign_up(self, data: dict) -> _auth.model.AbstractUser:
        # Searching for token in input data
        token = data.get('token')
        if not token:
            for k, v in data.items():
                if k.endswith('token'):
                    token = v
                    break

        if not token:
            raise ValueError('No uLogin token received')

        # Getting user's data from uLogin
        response = _urlopen(
            'http://ulogin.ru/token.php?token={}&host={}'.format(
                token,
                _router.request().host))
        if response.status != 200:
            raise _auth.error.AuthenticationError(
                "Bad response status code from uLogin: {}.".format(
                    response.status))
        ulogin_data = _json.loads(response.read().decode('utf-8'))
        if 'error' in ulogin_data:
            raise _auth.error.AuthenticationError(
                "Bad response from uLogin: '******'.".format(ulogin_data['error']))
        if 'email' not in ulogin_data or ulogin_data['verified_email'] != '1':
            raise _auth.error.AuthenticationError(
                "Email '{}' is not verified by uLogin.".format(
                    ulogin_data['email']))

        email = ulogin_data['email']

        try:
            user = _auth.get_user(email)
            is_new_user = False

        except _auth.error.UserNotFound:
            # User is not exists and its creation is not allowed
            if not _auth.is_sign_up_enabled():
                raise _auth.error.AuthenticationError(
                    _lang.t('auth_ui_ulogin@signup_is_disabled'))
            else:
                # New users can be created only by system user
                _auth.switch_user_to_system()

                # Create new user
                user = _auth.create_user(email)
                is_new_user = True

        # As soon as user created or loaded, set it as current
        _auth.switch_user(user)

        # Picture
        if is_new_user:
            current_pic = user.picture
            picture_url = ulogin_data.get('photo_big')
            if not picture_url:
                picture_url = ulogin_data.get('photo')

            # Replace existing picture with provided by uLogin
            if picture_url:
                user.picture = _file.create(picture_url)
                current_pic.delete()

        # Name
        if not user.first_name:
            user.first_name = ulogin_data.get('first_name')
        if not user.last_name:
            user.last_name = ulogin_data.get('last_name')

        # Alter nickname
        if is_new_user:
            user.nickname = user.first_last_name

        # Gender
        if user.gender not in ('m', 'f') and 'sex' in ulogin_data:
            user.gender = 'f' if int(ulogin_data['sex']) == 1 else 'm'

        # Birth date
        if 'bdate' in ulogin_data:
            try:
                b_date = _strptime(ulogin_data['bdate'], '%d.%m.%Y')
                user.birth_date = _datetime(*b_date[0:5])
            except ValueError:
                # Yes, sometimes uLogin provides strange data here :(
                pass

        # Link to profile
        if 'profile' in ulogin_data and ulogin_data['profile']:
            user.urls = user.urls + (ulogin_data['profile'], )

        # Options
        options = dict(user.options)
        options['ulogin'] = ulogin_data
        user.options = options

        user.save()

        return user