def get(self, token): activator = self.account_activator_factory() try: activator.activate_account(token) except TokenError as e: flash(e.reason, 'danger') except ValidationError as e: flash(e.reason, 'danger') return redirect(url_for('forum.index')) else: try: db.session.commit() except Exception: # noqa logger.exception("Database error while activating account") db.session.rollback() flash( _( "Could not activate account due to an unrecoverable error" # noqa ), "danger" ) return redirect(url_for('auth.request_activation_token')) flash( _("Your account has been activated and you can now login."), "success" ) return redirect(url_for("forum.index")) return redirect(url_for('auth.activate_account'))
def post(self): form = self.form() if form.validate_on_submit(): token = form.token.data activator = self.account_activator_factory() try: activator.activate_account(token) except TokenError as e: form.populate_errors([('token', e.reason)]) except ValidationError as e: flash(e.reason, 'danger') return redirect(url_for('forum.index')) else: try: db.session.commit() except Exception: # noqa logger.exception("Database error while activating account") db.session.rollback() flash( _( "Could not activate account due to an unrecoverable error" # noqa ), "danger" ) return redirect(url_for('auth.request_activation_token')) flash( _("Your account has been activated and you can now login."), "success" ) return redirect(url_for("forum.index")) return render_template("auth/account_activation.html", form=form)
def post(self, token): form = self.form() if form.validate_on_submit(): try: service = self.password_reset_service_factory() service.reset_password( token, form.email.data, form.password.data ) except TokenError as e: flash(e.reason, 'danger') return redirect(url_for('auth.forgot_password')) except StopValidation as e: form.populate_errors(e.reasons) form.token.data = token return render_template("auth/reset_password.html", form=form) except Exception: logger.exception("Error when resetting password") flash(_('Error when resetting password')) return redirect(url_for('auth.forgot_password')) finally: try: db.session.commit() except Exception: logger.exception( "Error while finalizing database when resetting password" # noqa ) db.session.rollback() flash(_("Your password has been updated."), "success") return redirect(url_for("auth.login")) form.token.data = token return render_template("auth/reset_password.html", form=form)
def delete_user(user_id=None): # ajax request if request.is_xhr: ids = request.get_json()["ids"] data = [] for user in User.query.filter(User.id.in_(ids)).all(): # do not delete current user if current_user.id == user.id: continue if user.delete(): data.append({ "id": user.id, "type": "delete", "reverse": False, "reverse_name": None, "reverse_url": None }) return jsonify( message="{} Users deleted.".format(len(data)), category="success", data=data, status=200 ) user = User.query.filter_by(id=user_id).first_or_404() if current_user.id == user.id: flash(_("You cannot delete yourself.", "danger")) return redirect(url_for("management.users")) user.delete() flash(_("User successfully deleted."), "success") return redirect(url_for("management.users"))
def register(): """Register a new user.""" if current_user is not None and current_user.is_authenticated: return redirect_or_next(url_for("forum.index")) if not flaskbb_config["REGISTRATION_ENABLED"]: flash(_("The registration has been disabled."), "info") return redirect_or_next(url_for("forum.index")) form = RegisterForm(request.form) form.language.choices = available_languages() form.language.default = flaskbb_config["DEFAULT_LANGUAGE"] form.process(request.form) # needed because a default is overriden if form.validate_on_submit(): user = form.save() if flaskbb_config["ACTIVATE_ACCOUNT"]: send_activation_token(user) flash(_("An account activation email has been sent to %(email)s", email=user.email), "success") else: login_user(user) flash(_("Thanks for registering."), "success") return redirect_or_next(url_for("forum.index")) return render_template("auth/register.html", form=form)
def unban_user(user_id=None): if not can_ban_user(current_user): flash(_("You do not have the permissions to unban this user."), "danger") return redirect(url_for("management.overview")) # ajax request if request.is_xhr: ids = request.get_json()["ids"] data = [] for user in jnt_models.User.query.filter(jnt_models.User.id.in_(ids)).all(): if user.unban(): data.append( { "id": user.id, "type": "unban", "reverse": "ban", "reverse_name": _("Ban"), "reverse_url": url_for("management.ban_user", user_id=user.id), } ) return jsonify(message="{} Users unbanned.".format(len(data)), category="success", data=data, status=200) user = jnt_models.User.query.filter_by(id=user_id).first_or_404() if user.unban(): flash(_("User is now unbanned."), "success") else: flash(_("Could not unban user."), "danger") return redirect(url_for("management.banned_users"))
def delete_group(group_id=None): if request.is_xhr: ids = request.get_json()["ids"] if not (set(ids) & set(["1", "2", "3", "4", "5"])): data = [] for group in jnt_models.Group.query.filter(jnt_models.Group.id.in_(ids)).all(): group.delete() data.append( {"id": group.id, "type": "delete", "reverse": False, "reverse_name": None, "reverse_url": None} ) return jsonify(message="{} Groups deleted.".format(len(data)), category="success", data=data, status=200) return jsonify( message=_("You cannot delete one of the standard groups."), category="danger", data=None, status=404 ) if group_id is not None: if group_id <= 5: # there are 5 standard groups flash(_("You cannot delete the standard groups. " "Try renaming them instead.", "danger")) return redirect(url_for("management.groups")) group = jnt_models.Group.query.filter_by(id=group_id).first_or_404() group.delete() flash(_("Group successfully deleted."), "success") return redirect(url_for("management.groups")) flash(_("No group choosen.."), "danger") return redirect(url_for("management.groups"))
def validate_moderators(self, field): approved_moderators = list() if field.data: # convert the CSV string in a list moderators = field.data.split(",") # remove leading and ending spaces moderators = [mod.strip() for mod in moderators] for moderator in moderators: # Check if the usernames exist user = jnt_models.User.query.filter_by(username=moderator).first() # Check if the user has the permissions to moderate a forum if user: if not (user.get_permissions()["mod"] or user.get_permissions()["admin"] or user.get_permissions()["super_mod"]): raise ValidationError( _("%(user)s is not in a moderators group.", user=user.username) ) else: approved_moderators.append(user) else: raise ValidationError(_("User %(moderator)s not found.", moderator=moderator)) field.data = approved_moderators else: field.data = approved_moderators
def post(self, post_id): post = Post.query.filter(Post.id == post_id).first_or_404() if not Permission(Has("makehidden"), IsAtleastModeratorInForum( forum=post.topic.forum)): flash(_("You do not have permission to hide this post"), "danger") return redirect(post.topic.url) if post.hidden: flash(_("Post is already hidden"), "warning") return redirect(post.topic.url) first_post = post.first_post post.hide(current_user) post.save() if first_post: flash(_("Topic hidden"), "success") else: flash(_("Post hidden"), "success") if post.first_post and not Permission(Has("viewhidden")): return redirect(post.topic.forum.url) return redirect(post.topic.url)
def reset_password(token): """ Handles the reset password process. """ if not current_user.is_anonymous: return redirect(url_for("forum.index")) form = ResetPasswordForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() expired, invalid, data = user.verify_reset_token(form.token.data) if invalid: flash(_("Your Password Token is invalid."), "danger") return redirect(url_for("auth.forgot_password")) if expired: flash(_("Your Password Token is expired."), "danger") return redirect(url_for("auth.forgot_password")) if user and data: user.password = form.password.data user.save() flash(_("Your Password has been updated."), "success") return redirect(url_for("auth.login")) form.token.data = token return render_template("auth/reset_password.html", form=form)
def enable_plugin(plugin): plugin = get_plugin_from_all(plugin) if not plugin.enabled: plugin_dir = os.path.join( os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "plugins", plugin.identifier ) disabled_file = os.path.join(plugin_dir, "DISABLED") try: if os.path.exists(disabled_file): os.remove(disabled_file) flash(_("Plugin is enabled. Please reload your app."), "success") else: flash(_("Plugin is already enabled. Please reload your app."), "warning") except OSError: flash( _( "If you are using a host which doesn't support writting " "on the disk, this won't work - than you need to delete " "the 'DISABLED' file by yourself." ), "danger", ) else: flash(_("Couldn't enable Plugin."), "danger") return redirect(url_for("management.plugins"))
def validate_to_user(self, field): user = User.query.filter_by(username=field.data).first() if not user: raise ValidationError(_("The username you entered does not " "exist.")) if user.id == current_user.id: raise ValidationError(_("You cannot send a PM to yourself."))
def disable_plugin(plugin): try: plugin = get_plugin(plugin) except KeyError: flash(_("Plugin %(plugin)s not found.", plugin=plugin.name), "danger") return redirect(url_for("management.plugins")) plugin_dir = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "plugins", plugin.identifier) disabled_file = os.path.join(plugin_dir, "DISABLED") try: open(disabled_file, "a").close() flash(_("Plugin is disabled. Please reload your app."), "success") except OSError: flash( _( "If you are using a host which doesn't " "support writting on the disk, this won't work - than you " "need to create a 'DISABLED' file by yourself." ), "info", ) return redirect(url_for("management.plugins"))
def reset_password(token): """Handles the reset password process.""" if not current_user.is_anonymous: return redirect(url_for("forum.index")) form = ResetPasswordForm() if form.validate_on_submit(): expired, invalid, user = get_token_status(form.token.data, "reset_password") if invalid: flash(_("Your password token is invalid."), "danger") return redirect(url_for("auth.forgot_password")) if expired: flash(_("Your password token is expired."), "danger") return redirect(url_for("auth.forgot_password")) if user: user.password = form.password.data user.save() flash(_("Your password has been updated."), "success") return redirect(url_for("auth.login")) form.token.data = token return render_template("auth/reset_password.html", form=form)
def activate_account(token=None): """Handles the account activation process.""" if current_user.is_active or not flaskbb_config["ACTIVATE_ACCOUNT"]: flash(_("This account is already activated."), "info") return redirect(url_for('forum.index')) form = None if token is not None: expired, invalid, user = get_token_status(token, "activate_account") else: form = AccountActivationForm() if form.validate_on_submit(): expired, invalid, user = get_token_status(form.token.data, "activate_account") if invalid: flash(_("Your account activation token is invalid."), "danger") return redirect(url_for("auth.request_email_confirmation")) if expired: flash(_("Your account activation token is expired."), "danger") return redirect(url_for("auth.request_activation_token")) if user: user.activated = True user.save() if current_user != user: logout_user() login_user(user) flash(_("Your account has been activated."), "success") return redirect(url_for("forum.index")) return render_template("auth/account_activation.html", form=form)
def login(): """Logs the user in.""" if current_user is not None and current_user.is_authenticated: return redirect_or_next(url_for("forum.index")) current_limit = getattr(g, 'view_rate_limit', None) login_recaptcha = False if current_limit is not None: window_stats = limiter.limiter.get_window_stats(*current_limit) stats_diff = flaskbb_config["AUTH_REQUESTS"] - window_stats[1] login_recaptcha = stats_diff >= flaskbb_config["LOGIN_RECAPTCHA"] form = LoginForm() if login_recaptcha and flaskbb_config["RECAPTCHA_ENABLED"]: form = LoginRecaptchaForm() if form.validate_on_submit(): try: user = User.authenticate(form.login.data, form.password.data) if not login_user(user, remember=form.remember_me.data): flash(_("In order to use your account you have to activate it " "through the link we have sent to your email " "address."), "danger") return redirect_or_next(url_for("forum.index")) except AuthenticationError: flash(_("Wrong username or password."), "danger") return render_template("auth/login.html", form=form, login_recaptcha=login_recaptcha)
def add_group(): form = AddGroupForm() if form.validate_on_submit(): form.save() flash(_("Group successfully added."), "success") return redirect(url_for("management.groups")) return render_template("management/group_form.html", form=form, title=_("Add Group"))
def add_user(): form = AddUserForm() if form.validate_on_submit(): form.save() flash(_("User successfully added."), "success") return redirect(url_for("management.users")) return render_template("management/user_form.html", form=form, title=_("Add User"))
def validate_email(self, field): self.user = User.query.filter_by(email=field.data).first() # check if the username matches the one found in the database if not self.user.username == self.username.data: raise ValidationError(_("User does not exist.")) if self.user.activated is True: raise ValidationError(_("User is already active."))
def new_conversation(): form = ConversationForm() to_user = request.args.get("to_user") message_count = Conversation.query.\ filter(Conversation.user_id == current_user.id).\ count() if message_count >= flaskbb_config["MESSAGE_QUOTA"]: flash(_("You cannot send any messages anymore because you have" "reached your message limit."), "danger") return redirect(url_for("message.inbox")) if request.method == "POST": if "save_message" in request.form and form.validate(): to_user = User.query.filter_by(username=form.to_user.data).first() shared_id = uuid.uuid4() form.save(from_user=current_user.id, to_user=to_user.id, user_id=current_user.id, unread=False, as_draft=True, shared_id=shared_id) flash(_("Message saved."), "success") return redirect(url_for("message.drafts")) if "send_message" in request.form and form.validate(): to_user = User.query.filter_by(username=form.to_user.data).first() # this is the shared id between conversations because the messages # are saved on both ends shared_id = uuid.uuid4() # Save the message in the current users inbox form.save(from_user=current_user.id, to_user=to_user.id, user_id=current_user.id, unread=False, shared_id=shared_id) # Save the message in the recievers inbox form.save(from_user=current_user.id, to_user=to_user.id, user_id=to_user.id, unread=True, shared_id=shared_id) to_user.invalidate_cache(permissions=False) flash(_("Message sent."), "success") return redirect(url_for("message.sent")) else: form.to_user.data = to_user return render_template("message/message_form.html", form=form, title=_("Compose Message"))
def add_category(): form = CategoryForm() if form.validate_on_submit(): form.save() flash(_("Category successfully added."), "success") return redirect(url_for("management.forums")) return render_template("management/category_form.html", form=form, title=_("Add Category"))
def post(self, report_id=None): # AJAX request if request.is_xhr: ids = request.get_json()["ids"] data = [] for report in Report.query.filter(Report.id.in_(ids)).all(): report.zapped_by = current_user.id report.zapped = time_utcnow() report.save() data.append( { "id": report.id, "type": "read", "reverse": False, "reverse_name": None, "reverse_url": None } ) return jsonify( message="{} reports marked as read.".format(len(data)), category="success", data=data, status=200 ) # mark single report as read if report_id: report = Report.query.filter_by(id=report_id).first_or_404() if report.zapped: flash( _("Report %(id)s is already marked as read.", id=report.id), "success" ) return redirect(url_for("management.reports")) report.zapped_by = current_user.id report.zapped = time_utcnow() report.save() flash(_("Report %(id)s marked as read.", id=report.id), "success") return redirect(url_for("management.reports")) # mark all as read reports = Report.query.filter(Report.zapped == None).all() report_list = [] for report in reports: report.zapped_by = current_user.id report.zapped = time_utcnow() report_list.append(report) db.session.add_all(report_list) db.session.commit() flash(_("All reports were marked as read."), "success") return redirect(url_for("management.reports"))
def post(self, user_id=None): if not Permission(CanBanUser, identity=current_user): flash( _("You do not have the permissions to ban this user."), "danger" ) return redirect(url_for("management.overview")) # ajax request if request.is_xhr: ids = request.get_json()["ids"] data = [] users = User.query.filter(User.id.in_(ids)).all() for user in users: # don't let a user ban himself and do not allow a moderator # to ban a admin user if (current_user.id == user.id or Permission(IsAdmin, identity=user) and Permission(Not(IsAdmin), current_user)): continue elif user.ban(): data.append( { "id": user.id, "type": "ban", "reverse": "unban", "reverse_name": _("Unban"), "reverse_url": url_for("management.unban_user", user_id=user.id) } ) return jsonify( message="{} users banned.".format(len(data)), category="success", data=data, status=200 ) user = User.query.filter_by(id=user_id).first_or_404() # Do not allow moderators to ban admins if Permission(IsAdmin, identity=user) and Permission( Not(IsAdmin), identity=current_user): flash(_("A moderator cannot ban an admin user."), "danger") return redirect(url_for("management.overview")) if not current_user.id == user.id and user.ban(): flash(_("User is now banned."), "success") else: flash(_("Could not ban user."), "danger") return redirect(url_for("management.banned_users"))
def post(self): form = AddGroupForm() if form.validate_on_submit(): form.save() flash(_('Group added.'), 'success') return redirect(url_for('management.groups')) return render_template( 'management/group_form.html', form=form, title=_('Add Group') )
def post(self): form = self.form() if form.validate_on_submit(): form.save() flash(_('User added.'), 'success') return redirect(url_for('management.users')) return render_template( 'management/user_form.html', form=form, title=_('Add User') )
def install_plugin(plugin): plugin = get_plugin_from_all(plugin) if plugin.installable and not plugin.uninstallable: plugin.install() Setting.invalidate_cache() flash(_("Plugin has been installed."), "success") else: flash(_("Cannot install Plugin."), "danger") return redirect(url_for("management.plugins"))
def edit_category(category_id): category = jnt_models.Category.query.filter_by(id=category_id).first_or_404() form = CategoryForm(obj=category) if form.validate_on_submit(): form.populate_obj(category) flash(_("Category successfully updated."), "success") category.save() return render_template("management/category_form.html", form=form, title=_("Edit Category"))
def post(self): form = self.form() if form.validate_on_submit(): form.save() flash(_('Category added.'), 'success') return redirect(url_for('management.forums')) return render_template( 'management/category_form.html', form=form, title=_('Add Category') )
def reauth(): """Reauthenticates a user.""" if not login_fresh(): form = ReauthForm(request.form) if form.validate_on_submit(): if current_user.check_password(form.password.data): confirm_login() flash(_("Reauthenticated."), "success") return redirect_or_next(current_user.url) flash(_("Wrong password."), "danger") return render_template("auth/reauth.html", form=form) return redirect(request.args.get("next") or current_user.url)
def post(self, forum_id=None, slug=None): # Mark a single forum as read if forum_id is not None: forum_instance = Forum.query.filter_by(id=forum_id).first_or_404() forumsread = ForumsRead.query.filter_by( user_id=real(current_user).id, forum_id=forum_instance.id ).first() TopicsRead.query.filter_by( user_id=real(current_user).id, forum_id=forum_instance.id ).delete() if not forumsread: forumsread = ForumsRead() forumsread.user = real(current_user) forumsread.forum = forum_instance forumsread.last_read = time_utcnow() forumsread.cleared = time_utcnow() db.session.add(forumsread) db.session.commit() flash( _( "Forum %(forum)s marked as read.", forum=forum_instance.title ), "success" ) return redirect(forum_instance.url) # Mark all forums as read ForumsRead.query.filter_by(user_id=real(current_user).id).delete() TopicsRead.query.filter_by(user_id=real(current_user).id).delete() forums = Forum.query.all() forumsread_list = [] for forum_instance in forums: forumsread = ForumsRead() forumsread.user = real(current_user) forumsread.forum = forum_instance forumsread.last_read = time_utcnow() forumsread.cleared = time_utcnow() forumsread_list.append(forumsread) db.session.add_all(forumsread_list) db.session.commit() flash(_("All forums marked as read."), "success") return redirect(url_for("forum.index"))
def new_topic(forum_id, slug=None): forum_instance = Forum.query.filter_by(id=forum_id).first_or_404() if not Permission(CanPostTopic): flash(_("You do not have the permissions to create a new topic."), "danger") return redirect(forum_instance.url) form = NewTopicForm() if request.method == "POST": if "preview" in request.form and form.validate(): return render_template("forum/new_topic.html", forum=forum_instance, form=form, preview=form.content.data) if "submit" in request.form and form.validate(): topic = form.save(current_user, forum_instance) # redirect to the new topic return redirect(url_for('forum.view_topic', topic_id=topic.id)) return render_template("forum/new_topic.html", forum=forum_instance, form=form)
def get(cls) -> ['ViewGlobalModel']: ''' The resource give list of available view in the system. User should be admin. ''' fbp.set_lng(request.headers.get('Accept-Language')) if UserModel.find_by_id(get_jwt_identity()).is_admin: payload = [ view_global_get_schema.dump(_view) for _view in ViewGlobalModel.find() ] count = len(payload) return { 'message': str( _("There are %(count)s views in our database as follows:", count=count)), 'payload': payload }, 200 else: return no_access()
class DeleteForum(MethodView): decorators = [ allows.requires( IsAdmin, on_fail=FlashAndRedirect( message=_("You are not allowed to modify forums"), level="danger", endpoint="management.overview" ) ) ] def post(self, forum_id): forum = Forum.query.filter_by(id=forum_id).first_or_404() involved_users = User.query.filter( Topic.forum_id == forum.id, Post.user_id == User.id ).all() forum.delete(involved_users) flash(_("Forum deleted."), "success") return redirect(url_for("management.forums"))
class CeleryStatus(MethodView): decorators = [ allows.requires( IsAtleastModerator, on_fail=FlashAndRedirect( message=_("You are not allowed to access the management settings"), # noqa level="danger", endpoint="management.overview" ) ) ] def get(self): celery_inspect = celery.control.inspect() try: celery_running = True if celery_inspect.ping() else False except Exception: # catching Exception is bad, and just catching ConnectionError # from redis is also bad because you can run celery with other # brokers as well. celery_running = False return jsonify(celery_running=celery_running, status=200)
class DeletePost(MethodView): decorators = [ login_required, allows.requires( CanDeletePost, on_fail=FlashAndRedirect( message=_("You are not allowed to delete this post"), level="danger", endpoint=lambda *a, **k: current_topic.url)), ] def post(self, post_id): post = Post.query.filter_by(id=post_id).first_or_404() first_post = post.first_post topic_url = post.topic.url forum_url = post.topic.forum.url post.delete() # If the post was the first post in the topic, redirect to the forums if first_post: return redirect(forum_url) return redirect(topic_url)
class DeleteCategory(MethodView): decorators = [ allows.requires( IsAdmin, on_fail=FlashAndRedirect( message=_("You are not allowed to modify categories"), level="danger", endpoint="management.overview" ) ) ] def post(self, category_id): category = Category.query.filter_by(id=category_id).first_or_404() involved_users = User.query.filter( Forum.category_id == category.id, Topic.forum_id == Forum.id, Post.user_id == User.id ).all() category.delete(involved_users) flash(_("Category with all associated forums deleted."), "success") return redirect(url_for("management.forums"))
def post(self, post_id): post = Post.query.filter_by(id=post_id).first_or_404() form = self.form(obj=post) if form.validate_on_submit(): try: current_app.pluggy.hook.flaskbb_form_edit_post_save(form=form) form.populate_obj(post) post.date_modified = time_utcnow() post.modified_by = real(current_user).username post.save() return redirect(url_for("forum.view_post", post_id=post.id)) except StopEditPost as e: flash(e.reason, "danger") except BaseFlaskBBError as e: flask(e.reason, "warning") except Exception: flash(_("Unrecoverable error while submiting modified post")) return render_template("forum/new_post.html", topic=post.topic, form=form, edit_mode=True)
def post(self, slug=None, plugin=None): form, old_settings, plugin_obj, active_nav = \ self._determine_active_settings(slug, plugin) all_groups = SettingsGroup.query.all() all_plugins = PluginRegistry.query.filter( db.and_(PluginRegistry.values != None, PluginRegistry.enabled == True)).all() if form.validate_on_submit(): new_settings = populate_settings_dict(form, old_settings) if plugin_obj is not None: plugin_obj.update_settings(new_settings) else: Setting.update(settings=new_settings) flash(_("Settings saved."), "success") return render_template("management/settings.html", form=form, all_groups=all_groups, all_plugins=all_plugins, active_nav=active_nav)
def put(cls): ''' Update instance and save to db. ''' if not UserModel.find_by_id(get_jwt_identity()).is_admin: return no_access() # print('\ncontents, resources, view, update_json ->', request.get_json()) _update_json = view_global_get_schema.load(request.get_json()) # print('\ncontents, resources, view, update_json ->', _update_json) _view = ViewGlobalModel.find_by_id(view_id=_update_json['view_id']) if _view is None: return cls.not_found(_update_json.get('view_id')) _view.update(_update_json) return { 'message': str( _( "The view with id '%(view_id)s' has been updated " "successfully. Details are in payload.", view_id=_update_json['view_id'])), 'payload': view_global_get_schema.dump(_view) }, 200
def reply_post(topic_id, post_id): topic = Topic.query.filter_by(id=topic_id).first_or_404() post = Post.query.filter_by(id=post_id).first_or_404() if not Permission(CanPostReply): flash(_("You do not have the permissions to post in this topic."), "danger") return redirect(topic.forum.url) form = ReplyForm() if form.validate_on_submit(): if "preview" in request.form: return render_template("forum/new_post.html", topic=topic, form=form, preview=form.content.data) else: form.save(current_user, topic) return redirect(post.topic.url) else: form.content.data = format_quote(post.username, post.content) return render_template("forum/new_post.html", topic=post.topic, form=form)
def validate(self): if not super(GroupForm, self).validate(): return False result = True permission_fields = ( self.editpost, self.deletepost, self.deletetopic, self.posttopic, self.postreply, self.mod_edituser, self.mod_banuser, self.viewhidden, self.makehidden, self.ignorekarma ) group_fields = [ self.admin, self.super_mod, self.mod, self.banned, self.guest ] # we do not allow to modify any guest permissions if self.guest.data: for field in permission_fields: if field.data: # if done in 'validate_guest' it would display this # warning on the fields field.errors.append( _("Can't assign any permissions to this group.") ) result = False checked = [] for field in group_fields: if field.data and field.data in checked: if len(checked) > 1: field.errors.append( "A group can't have multiple group types." ) result = False else: checked.append(field.data) return result
def edit_post(post_id): post = Post.query.filter_by(id=post_id).first_or_404() if not Permission(CanEditPost): flash(_("You do not have the permissions to edit this post."), "danger") return view_post(post.id) if post.first_post: form = NewTopicForm() else: form = ReplyForm() if form.validate_on_submit(): if "preview" in request.form: return render_template( "forum/new_post.html", topic=post.topic, form=form, preview=form.content.data, edit_mode=True ) else: form.populate_obj(post) post.date_modified = time_utcnow() post.modified_by = current_user.username post.save() if post.first_post: post.topic.title = form.title.data post.topic.save() return view_post(post.id) else: if post.first_post: form.title.data = post.topic.title form.content.data = post.content return render_template("forum/new_post.html", topic=post.topic, form=form, edit_mode=True)
class ConfigsView(Hub): decorators = [ allows.requires(CanAccessServerHubAdditional(), on_fail=FlashAndRedirect( message=_("You are not allowed to access the hub"), level="danger", endpoint="forum.index")) ] def get(self): server_id = request.args["server"] servers = current_app.config["BYOND_SERVERS"] for server in servers: if server.id == server_id: config_folder_entries = [ os.path.join(server.configs_path, f) for f in os.listdir(server.configs_path) ] config_files = [ f for f in config_folder_entries if os.path.isfile(f) ] config_files_names = [ os.path.split(f)[1] for f in config_files ] config_files_names = [ f for f in config_files_names if f not in server.configs_exclude ] config_files_names.sort() return render_template("hub/configs.html", **self.get_args(), configs=config_files_names) return render_template("hub/configs.html", **self.get_args())
class RequestActivationForm(FlaskBBForm): username = StringField( _("Username"), validators=[ DataRequired(message=_("A valid username is required.")), is_valid_username ] ) email = StringField( _("Email address"), validators=[ DataRequired(message=_("A valid email address is required.")), Email(message=_("Invalid email address.")) ] ) submit = SubmitField(_("Send Confirmation Mail"))
class EditGroup(MethodView): decorators = [ allows.requires( IsAdmin, on_fail=FlashAndRedirect( message=_("You are not allowed to modify groups."), level="danger", endpoint="management.overview" ) ) ] form = EditGroupForm def get(self, group_id): group = Group.query.filter_by(id=group_id).first_or_404() form = self.form(group) return render_template( 'management/group_form.html', form=form, title=_('Edit Group') ) def post(self, group_id): group = Group.query.filter_by(id=group_id).first_or_404() form = EditGroupForm(group) if form.validate_on_submit(): form.populate_obj(group) group.save() if group.guest: Guest.invalidate_cache() flash(_('Group updated.'), 'success') return redirect(url_for('management.groups', group_id=group.id)) return render_template( 'management/group_form.html', form=form, title=_('Edit Group') )
class DeleteReport(MethodView): decorators = [ allows.requires(IsAtleastModerator, on_fail=FlashAndRedirect( message=_("You are not allowed to view reports."), level="danger", endpoint="management.overview")) ] def post(self, report_id=None): if request.get_json() is not None: ids = request.get_json().get("ids") if not ids: return jsonify(message="No ids provided.", category="error", status=404) data = [] for report in Report.query.filter(Report.id.in_(ids)).all(): if report.delete(): data.append({ "id": report.id, "type": "delete", "reverse": False, "reverse_name": None, "reverse_url": None }) return jsonify(message="{} reports deleted.".format(len(data)), category="success", data=data, status=200) report = Report.query.filter_by(id=report_id).first_or_404() report.delete() flash(_("Report deleted."), "success") return redirect_or_next(url_for("management.reports"))
class EditTopicForm(TopicForm): submit = SubmitField(_("Save topic")) def __init__(self, *args, **kwargs): self.topic = kwargs.get("obj").topic TopicForm.__init__(self, *args, **kwargs) def populate_obj(self, *objs): """ Populates the attributes of the passed `obj`s with data from the form's fields. This is especially useful to populate the topic and post objects at the same time. """ for obj in objs: super(EditTopicForm, self).populate_obj(obj) def save(self, user, forum): if self.track_topic.data: user.track_topic(self.topic) else: user.untrack_topic(self.topic) if ( self.topic.last_post_id == forum.last_post_id and self.title.data != forum.last_post_title ): forum.last_post_title = self.title.data self.topic.first_post.date_modified = time_utcnow() self.topic.first_post.modified_by = user.username self.topic.first_post.modified_by_user_id = user.id current_app.pluggy.hook.flaskbb_form_topic_save( form=self, topic=self.topic ) return self.topic.save(user=user, forum=forum)
def login(): """Logs the user in.""" if current_user is not None and current_user.is_authenticated: return redirect_or_next(url_for("forum.index")) current_limit = getattr(g, 'view_rate_limit', None) login_recaptcha = False if current_limit is not None: window_stats = limiter.limiter.get_window_stats(*current_limit) stats_diff = flaskbb_config["AUTH_REQUESTS"] - window_stats[1] login_recaptcha = stats_diff >= flaskbb_config["LOGIN_RECAPTCHA"] form = LoginForm(request.form) if form.validate_on_submit(): try: user = User.authenticate(form.login.data, form.password.data) login_user(user, remember=form.remember_me.data) return redirect_or_next(url_for("forum.index")) except AuthenticationError: flash(_("Wrong username or password."), "danger") return render_template("auth/login.html", form=form, login_recaptcha=login_recaptcha)
def post(cls) -> Dict: ''' Create content instance and save to db. ''' _lng = request.headers.get('Accept-Language') _user_id = get_jwt_identity() # print('\ncontents, resources, post, lng ->', _lng) fbp.set_lng(_lng) if not UserModel.find_by_id(_user_id).is_admin: return cls.no_access() _request_json = { **request.get_json(), 'locale_id': _lng, 'user_id': _user_id } _content = content_schema.load(_request_json, session=dbs_global.session) _content_fm_db = ContentModel.find_by_identity_view_locale( identity=_content.identity, view_id=_content.view_id, locale_id=_content.locale_id) if _content_fm_db is not None: return cls.already_exists(identity=_content.identity, view_id=_content.view_id, locale_id=_content.locale_id) error_info = _content.save_to_db() if error_info is not None: return cls.error_message(error_info) return { 'message': str( _("The content has been saved successfully. " "Details are in payload.")), 'payload': content_get_schema.dump(_content) # 'payload': content_schema.dump(_content) }, 201
def topictracker(): page = request.args.get("page", 1, type=int) topics = current_user.tracked_topics.\ outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == current_user.id)).\ add_entity(TopicsRead).\ order_by(Topic.last_updated.desc()).\ paginate(page, flaskbb_config['TOPICS_PER_PAGE'], True) # bulk untracking if request.method == "POST": topic_ids = request.form.getlist("rowid") tmp_topics = Topic.query.filter(Topic.id.in_(topic_ids)).all() for topic in tmp_topics: current_user.untrack_topic(topic) current_user.save() flash(_("%(topic_count)s topics untracked.", topic_count=len(tmp_topics)), "success") return redirect(url_for("forum.topictracker")) return render_template("forum/topictracker.html", topics=topics)
def delete_report(report_id=None): if request.is_xhr: ids = request.get_json()["ids"] data = [] for report in Report.query.filter(Report.id.in_(ids)).all(): if report.delete(): data.append({ "id": report.id, "type": "delete", "reverse": False, "reverse_name": None, "reverse_url": None }) return jsonify(message="{} reports deleted.".format(len(data)), category="success", data=data, status=200) report = Report.query.filter_by(id=report_id).first_or_404() report.delete() flash(_("Report deleted."), "success") return redirect(url_for("management.reports"))
def settings(slug=None): slug = slug if slug else "general" # get the currently active group active_group = SettingsGroup.query.filter_by(key=slug).first_or_404() # get all groups - used to build the navigation all_groups = SettingsGroup.query.all() SettingsForm = Setting.get_form(active_group) old_settings = Setting.get_settings(active_group) new_settings = {} form = SettingsForm() if form.validate_on_submit(): for key, values in iteritems(old_settings): try: # check if the value has changed if values['value'] == form[key].data: continue else: new_settings[key] = form[key].data except KeyError: pass Setting.update(settings=new_settings, app=current_app) flash(_("Settings saved."), "success") else: for key, values in iteritems(old_settings): try: form[key].data = values['value'] except (KeyError, ValueError): pass return render_template("management/settings.html", form=form, all_groups=all_groups, active_group=active_group)
class RequestActivationForm(FlaskForm): username = StringField(_("Username"), validators=[ DataRequired(message=_("A valid username is required.")), is_valid_username]) email = StringField(_("Email address"), validators=[ DataRequired(message=_("A valid email address is required.")), Email(message=_("Invalid email address."))]) submit = SubmitField(_("Send Confirmation Mail")) def validate_email(self, field): self.user = User.query.filter_by(email=field.data).first() # check if the username matches the one found in the database if not self.user.username == self.username.data: raise ValidationError(_("User does not exist.")) if self.user.activated is True: raise ValidationError(_("User is already active."))
class ResetPasswordForm(FlaskForm): token = HiddenField('Token') email = StringField(_('Email address'), validators=[ DataRequired(message=_("A valid email address is required.")), Email()]) password = PasswordField(_('Password'), validators=[ InputRequired(), EqualTo('confirm_password', message=_('Passwords must match.'))]) confirm_password = PasswordField(_('Confirm password')) submit = SubmitField(_("Reset password")) def validate_email(self, field): email = User.query.filter_by(email=field.data).first() if not email: raise ValidationError(_("Wrong email address."))
class ChangePasswordForm(FlaskBBForm): old_password = PasswordField( _("Password"), validators=[DataRequired(message=_("Please enter your password."))], ) new_password = PasswordField( _("New password"), validators=[ InputRequired(), EqualTo("confirm_new_password", message=_("New passwords must match.")), ], ) confirm_new_password = PasswordField(_("Confirm new password")) submit = SubmitField(_("Save")) def as_change(self): return PasswordUpdate(new_password=self.new_password.data, old_password=self.old_password.data)
class SearchPageForm(FlaskForm): search_query = StringField( _("Criteria"), validators=[DataRequired(), Length(min=3, max=50)]) search_types = SelectMultipleField( _("Content"), validators=[DataRequired()], choices=[ ("post", _("Post")), ("topic", _("Topic")), ("forum", _("Forum")), ("user", _("Users")), ], ) submit = SubmitField(_("Search")) def get_results(self): # Because the DB is not yet initialized when this form is loaded, # the query objects cannot be instantiated in the class itself search_actions = { "post": Post.query.whooshee_search, "topic": Topic.query.whooshee_search, "forum": Forum.query.whooshee_search, "user": User.query.whooshee_search, } query = self.search_query.data types = self.search_types.data results = {} for search_type in search_actions.keys(): if search_type in types: results[search_type] = search_actions[search_type](query) return results
class ChangePasswordForm(Form): old_password = PasswordField( _("Password"), validators=[DataRequired(message=_("Please enter your password."))]) new_password = PasswordField( _('New password'), validators=[ InputRequired(), EqualTo('confirm_new_password', message=_('New passwords must match.')) ]) confirm_new_password = PasswordField(_('Confirm new password')) submit = SubmitField(_("Save")) def validate_old_password(self, field): if not current_user.check_password(field.data): raise ValidationError(_("Old password is wrong."))
class CategoryForm(Form): title = StringField(_("Category title"), validators=[ DataRequired(message=_("Please enter a category title."))]) description = TextAreaField( _("Description"), validators=[Optional()], description=_("You can format your description with Markdown.") ) position = IntegerField( _("Position"), default=1, validators=[DataRequired(message=_("Please enter a position for the " "category."))] ) submit = SubmitField(_("Save")) def save(self): data = self.data data.pop('submit', None) category = Category(**data) return category.save()
class CategoryForm(Form): title = StringField(_("Category Title"), validators=[ DataRequired(message=_("A Category Title is required."))]) description = TextAreaField( _("Description"), validators=[Optional()], description=_("You can format your description with BBCode.") ) position = IntegerField( _("Position"), default=1, validators=[DataRequired(message=_("The Category Position is " "required."))] ) submit = SubmitField(_("Save")) def save(self): data = self.data data.pop('submit', None) category = Category(**data) return category.save()
class ResetPasswordForm(FlaskBBForm): token = HiddenField('Token') email = StringField( _('Email address'), validators=[ DataRequired(message=_("A valid email address is required.")), Email() ] ) password = PasswordField( _('Password'), validators=[ InputRequired(), EqualTo('confirm_password', message=_('Passwords must match.')) ] ) confirm_password = PasswordField(_('Confirm password')) submit = SubmitField(_("Reset password"))