Exemple #1
0
def login():
    if current_user.is_authenticated:
        return redirect(url_for('wiki.home'))

    form = LoginForm()
    if form.validate_on_submit():
        user = WikiUser.objects(name=form.username.data).first()
        if user is not None and user.verify_password(form.password.data):
            user_id_dict = convert_user_ids_to_dict(session.get('user_id'))
            user_id_dict[g.wiki_group] = user.id
            user.id = convert_dict_to_user_ids(user_id_dict)
            login_user(user, form.remember_me.data)
            WikiLoginRecord(username=form.username.data,
                            browser=request.user_agent.browser,
                            platform=request.user_agent.platform,
                            details=request.user_agent.string,
                            ip=request.remote_addr).save()

            # details on `url_parse` and `netloc`:
            # https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins
            next_page = request.args.get('next')
            if not next_page or url_parse(next_page).netloc != '':
                next_page = url_for('wiki.home')
            return redirect(next_page)
        flash('Invalid username or password.', 'danger')
    else:
        flash_errors(form)
    return render_template('auth/login.html', form=form)
Exemple #2
0
def manage_user(wiki_user_id):
    user = WikiUser.objects(id=wiki_user_id).first()
    if user is None:
        return redirect(url_for('.all_users'))

    form = ManageUserForm(username=user.name,
                          email=user.email,
                          is_admin=user.is_admin)

    if form.validate_on_submit():
        if form.remove.data:
            user.delete()
            flash('User removed.', 'warning')
        else:
            user.name = form.username.data
            user.email = form.email.data
            user.is_admin = form.is_admin.data
            if form.password.data:
                user.set_password(form.password.data)
            user.save()
            flash('User updated.', 'success')
        return redirect(url_for('.all_users'))
    else:
        flash_errors(form)

    return render_template('admin/manage_user.html', form=form)
Exemple #3
0
def rename(wiki_page_id):
    wiki_page = WikiPage.objects.only('title').get_or_404(id=wiki_page_id)
    if wiki_page.title == 'Home':
        return redirect(url_for('.home'))

    form = RenameForm(new_title=wiki_page.title)

    if form.validate_on_submit():
        new_title = form.new_title.data
        if wiki_page.title == new_title:
            flash('The page name is not changed.', 'warning')
        elif WikiPage.objects(title=new_title).count() > 0:
            flash('The new page title has already been taken.', 'danger')
        else:
            old_md = '[[{}]]'.format(wiki_page.title)
            new_md = '[[{}]]'.format(new_title)

            old_html = render_wiki_page(wiki_page.id, wiki_page.title)
            new_html = render_wiki_page(wiki_page.id, new_title)

            # update the markdown of referencing wiki page
            wiki_referencing_pages = (WikiPage.objects(
                refs__contains=wiki_page_id).only('md', 'html',
                                                  'comments').all())

            for ref in wiki_referencing_pages:
                new_md_content = ref.md.replace(old_md, new_md)
                new_html_content = ref.html.replace(old_html, new_html)

                (WikiPage.objects(id=ref.id).update_one(
                    set__md=new_md_content, set__html=new_html_content))

            # update renamed page title in comments
            for wp in WikiPage.objects(
                    comments__md__contains=old_md).only('comments'):
                for comment in wp.comments:
                    comment.md = comment.md.replace(old_md, new_md)
                    comment.html = comment.html.replace(old_html, new_html)
                WikiPage.objects(id=wp.id).update_one(comments=wp.comments)

            # update the diff of related wiki page versions
            for pv in WikiPageVersion.objects.search_text(old_md).all():
                pv.diff = pv.diff.replace(old_md, new_md)
                pv.save()

            (WikiPage.objects(id=wiki_page.id).update_one(
                set__title=new_title))

            return redirect(url_for('.page', wiki_page_id=wiki_page.id))
    else:
        flash_errors(form)

    return render_template('wiki/rename.html', wiki_page=wiki_page, form=form)
Exemple #4
0
def home():
    """Manage wiki groups."""
    all_wiki_groups = WikiGroup.objects.all()
    form = AddWikiGroupForm()

    # Create a new wiki group with its own database and static file directory
    if form.validate_on_submit():
        new_wiki_group_name = form.wiki_group_name.data
        new_db_name = new_wiki_group_name.replace(' ', '')

        # Save the name of the new wiki group in database `_admin`
        # Remove whitespaces in the wiki group name.
        # Then use it to name the database which is about to be initialized.
        new_group = WikiGroup(name=new_wiki_group_name,
                              db_name=new_db_name,
                              active=True)

        # Initialize a new database for the just-created group
        # Make sure the new group name is not occupied.
        if new_group.db_name in db.connection.database_names():
            flash('Wiki group already exists', 'danger')
        else:
            try:
                os.mkdir(
                    os.path.join(current_app.config['UPLOAD_PATH'],
                                 new_group.db_name))
                new_group.save()
                db.register_connection(
                    alias=new_group.db_name,
                    name=new_group.db_name,
                    host=current_app.config['MONGODB_SETTINGS']['host'],
                    port=current_app.config['MONGODB_SETTINGS']['port'])

                new_user = WikiUser(name=form.username.data,
                                    email=form.email.data,
                                    is_admin=True)
                new_user.set_password(form.password.data)
                new_user.switch_db(new_group.db_name).save()
                WikiPage(title='Home').switch_db(new_group.db_name).save()
                flash('New wiki group added', 'success')
                return redirect(url_for('.home'))
            except FileExistsError:
                flash('Upload directory already exists', 'danger')

    else:
        flash_errors(form)

    return render_template('super_admin/home.html',
                           form=form,
                           all_wiki_groups=all_wiki_groups)
Exemple #5
0
def change_password():
    form = ChangePwdForm()
    if form.validate_on_submit():
        if not current_user.verify_password(form.old_password.data):
            flash('Password Verification Failed.', 'danger')
        elif form.new_password.data != form.confirm_password.data:
            flash('Please confirm new password again.', 'danger')
        else:
            current_user.set_password(form.new_password.data)
            (WikiUser.objects(name=current_user.name).update_one(
                set__password_hash=current_user.password_hash))
            flash('Password changed.', 'success')
    else:
        flash_errors(form)

    return render_template('auth/change_password.html', form=form)
Exemple #6
0
def keypage_edit():
    wiki_keypages = (WikiPage.objects(
        keypage__exists=True).only('title').order_by('+keypage'))
    keypage_titles = [wiki_keypage.title for wiki_keypage in wiki_keypages]
    form = KeyPageEditForm(textArea='\n'.join(keypage_titles))

    if form.validate_on_submit():
        (WikiPage.objects(keypage__exists=True).update(unset__keypage=1))

        new_titles = form.textArea.data.splitlines()
        for i, new_title in enumerate(new_titles):
            (WikiPage.objects(title=new_title).update_one(set__keypage=i + 1))

        return redirect(url_for('wiki.home'))
    else:
        flash_errors(form)

    return render_template('admin/keypage_edit.html', form=form)
Exemple #7
0
def all_users():
    form = NewUserForm()

    if form.validate_on_submit():
        user = WikiUser.objects(name=form.username.data).first()
        if not user:
            new_user = WikiUser(name=form.username.data,
                                email=form.email.data,
                                is_admin=form.is_admin.data)
            new_user.set_password(form.password.data)
            new_user.save()
            flash('New user added', 'success')
            return redirect(url_for('.all_users'))
        else:
            flash('User already exists.', 'danger')
    else:
        flash_errors(form)

    all_wiki_users = WikiUser.objects.order_by('+id').all()
    return render_template('admin/all_users.html',
                           form=form,
                           all_wiki_users=all_wiki_users)
Exemple #8
0
def login():
    if current_user.is_authenticated:
        return redirect(url_for('.home'))

    form = LoginForm()
    if form.validate_on_submit():
        user = WikiUser.objects(name=form.username.data).first()
        if user is not None and user.verify_password(form.password.data):
            user_id_dict = {g.wiki_group: user.id}
            user.id = convert_dict_to_user_ids(user_id_dict)
            login_user(user, form.remember_me.data)
            WikiLoginRecord(username=form.username.data,
                            browser=request.user_agent.browser,
                            platform=request.user_agent.platform,
                            details=request.user_agent.string,
                            ip=request.remote_addr).save()

            return redirect(url_for('.home'))
        flash('Invalid username or password.', 'danger')
    else:
        flash_errors(form)
    return render_template('auth/login.html', form=form)
Exemple #9
0
def history(wiki_page_id):
    fields = [
        'title', 'md', 'current_version', 'modified_on', 'modified_by',
        'versions'
    ]
    wiki_page = (WikiPage.objects.only(*fields).get_or_404(id=wiki_page_id))

    if wiki_page.current_version == 1:
        return redirect(url_for('.page', wiki_page_id=wiki_page_id))

    form = HistoryRecoverForm()
    if form.validate_on_submit():
        if form.version.data >= wiki_page.current_version:
            flash('Please enter an old version number.', 'danger')
        else:
            old_to_current = wiki_page.versions[(form.version.data - 1):]
            old_to_current_patches = [pv.diff for pv in old_to_current[::-1]]
            recovered_content = apply_patches(wiki_page.md,
                                              old_to_current_patches,
                                              revert=True)

            diff = make_patch(wiki_page.md, recovered_content)
            if diff:
                toc, html = markdown(wiki_page, recovered_content)
                wiki_page.update_db(diff, recovered_content, html, toc=toc)
            return redirect(url_for('.page', wiki_page_id=wiki_page.id))
    else:
        flash_errors(form)

    old_ver_num = request.args.get('version',
                                   default=wiki_page.current_version - 1,
                                   type=int)
    new_ver_num = old_ver_num + 1
    if new_ver_num > wiki_page.current_version:
        return redirect(
            url_for('.history',
                    wiki_page_id=wiki_page_id,
                    version=wiki_page.current_version - 1))

    wiki_page_versions = wiki_page.versions[old_ver_num - 1:]
    old_to_current_patches = [pv.diff for pv in wiki_page_versions[::-1]]
    new_markdown = apply_patches(wiki_page.md,
                                 old_to_current_patches[:-1],
                                 revert=True)
    old_markdown = apply_patches(new_markdown, [old_to_current_patches[-1]],
                                 revert=True)

    diff = difflib.HtmlDiff()
    diff_table = diff.make_table(old_markdown.splitlines(),
                                 new_markdown.splitlines())
    diff_table = diff_table.replace(' ',
                                    ' ').replace(' nowrap="nowrap"', '')

    kwargs = dict()
    get_pagination_kwargs(kwargs, old_ver_num, wiki_page.current_version - 1)

    return render_template('wiki/history.html',
                           wiki_page=wiki_page,
                           form=form,
                           wiki_page_versions=wiki_page_versions,
                           old_ver_num=old_ver_num,
                           new_ver_num=new_ver_num,
                           diff_table=diff_table,
                           **kwargs)