def remove_tag(repo, username=None): """ Remove the specified tag from the project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort(403, 'You are not allowed to remove tags of this project') form = pagure.forms.AddIssueTagForm() if form.validate_on_submit(): tags = form.tag.data tags = [tag.strip() for tag in tags.split(',')] msgs = pagure.lib.remove_tags( SESSION, repo, tags, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER']) try: SESSION.commit() for msg in msgs: flask.flash(msg) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not remove tag: %s' % ','.join(tags), 'error')
def new_repo_hook_token(repo, username=None): """ Re-generate a hook token for the present project. """ if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for('view_settings', username=username, repo=repo) return flask.redirect(flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.abort(400, 'Invalid request') try: repo.hook_token = pagure.lib.login.id_generator(40) SESSION.commit() flask.flash('New hook token generated') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not generate a new token for this project', 'error')
def edit_tag(repo, tag, username=None): """ Edit the specified tag of a project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to edt tags of this project') form = pagure.forms.AddIssueTagForm() if form.validate_on_submit(): new_tag = form.tag.data msgs = pagure.lib.edit_issue_tags( SESSION, repo, tag, new_tag, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER'] ) try: SESSION.commit() for msg in msgs: flask.flash(msg) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not edit tag: %s' % tag, 'error') return flask.redirect(flask.url_for( '.view_settings', repo=repo.name, username=username))
def set_default_email(): """ Set the default email address of the user. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserEmailForm() if form.validate_on_submit(): email = form.email.data useremails = [mail.email for mail in user.emails] if email not in useremails: flask.flash( 'You do not have the email: %s, nothing to set' % email, 'error') return flask.redirect(flask.url_for('.user_settings')) user.default_email = email try: SESSION.commit() flask.flash('Default email set to: %s' % email) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Default email could not be set', 'error') return flask.redirect(flask.url_for('.user_settings'))
def add_user_email(): """ Add a new email for the logged in user. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserEmailForm( emails=[mail.email for mail in user.emails]) if form.validate_on_submit(): email = form.email.data try: pagure.lib.add_user_pending_email(SESSION, user, email) SESSION.commit() flask.flash('Email pending validation') return flask.redirect(flask.url_for('.user_settings')) except pagure.exceptions.PagureException as err: flask.flash(str(err), 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Email could not be added', 'error') return flask.render_template( 'user_emails.html', user=user, form=form, )
def revoke_api_token(repo, token_id, username=None): """ Revokie a token to a specified project. """ if admin_session_timedout(): flask.flash("Action canceled, try it again", "error") url = flask.url_for("view_settings", username=username, repo=repo) return flask.redirect(flask.url_for("auth_login", next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, "Project not found") if not is_repo_admin(repo): flask.abort(403, "You are not allowed to change the settings for this project") token = pagure.lib.get_api_token(SESSION, token_id) if not token or token.project.fullname != repo.fullname or token.user.username != flask.g.fas_user.username: flask.abort(404, "Token not found") form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): try: token.expiration = datetime.datetime.utcnow() SESSION.commit() flask.flash("Token revoked") except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash("Token could not be revoked, please contact an admin", "error") return flask.redirect(flask.url_for(".view_settings", repo=repo.name, username=username))
def reconfirm_email(): """ Re-send the email address of the user. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserEmailForm() if form.validate_on_submit(): email = form.email.data try: pagure.lib.resend_pending_email(SESSION, user, email) SESSION.commit() flask.flash('Confirmation email re-sent') except pagure.exceptions.PagureException as err: flask.flash(str(err), 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Confirmation email could not be re-sent', 'error') return flask.redirect(flask.url_for('.user_settings'))
def new_project(): """ Form to create a new project. """ form = pagure.forms.ProjectForm() if form.validate_on_submit(): name = form.name.data description = form.description.data try: message = pagure.lib.new_project( SESSION, name=name, description=description, user=flask.g.fas_user.username, blacklist=APP.config['BLACKLISTED_PROJECTS'], gitfolder=APP.config['GIT_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], ) SESSION.commit() generate_gitolite_acls() flask.flash(message) return flask.redirect(flask.url_for('view_repo', repo=name)) except pagure.exceptions.PagureException, err: flask.flash(str(err), 'error') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def new_project(): """ Form to create a new project. """ form = pagure.forms.ProjectForm() if form.validate_on_submit(): name = form.name.data description = form.description.data url = form.url.data avatar_email = form.avatar_email.data try: message = pagure.lib.new_project( SESSION, name=name, description=description, url=url, avatar_email=avatar_email, user=flask.g.fas_user.username, blacklist=APP.config['BLACKLISTED_PROJECTS'], gitfolder=APP.config['GIT_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], ) SESSION.commit() generate_gitolite_acls() flask.flash(message) return flask.redirect(flask.url_for('view_repo', repo=name)) except pagure.exceptions.PagureException, err: flask.flash(str(err), 'error') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def delete_repo(repo, username=None): """ Delete the present project. """ if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for('view_settings', username=username, repo=repo) return flask.redirect(flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') try: for issue in repo.issues: for comment in issue.comments: SESSION.delete(comment) SESSION.commit() SESSION.delete(issue) SESSION.delete(repo) SESSION.commit() except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the project', 'error')
def user_settings(): """ Update the user settings. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserSettingsForm() if form.validate_on_submit(): ssh_key = form.ssh_key.data try: message = pagure.lib.update_user_ssh( SESSION, user=user, ssh_key=ssh_key, ) if message != 'Nothing to update': generate_gitolite_key(user.user, ssh_key) generate_authorized_key_file() SESSION.commit() flask.flash(message) return flask.redirect( flask.url_for('view_user', username=user.user)) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def set_default_email(): """ Set the default email address of the user. """ if admin_session_timedout(): return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, "User not found") form = pagure.forms.UserEmailForm() if form.validate_on_submit(): email = form.email.data useremails = [mail.email for mail in user.emails] if email not in useremails: flask.flash("You do not have the email: %s, nothing to set" % email, "error") return flask.redirect(flask.url_for(".user_settings")) user.default_email = email try: SESSION.commit() flask.flash("Default email set to: %s" % email) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash("Default email could not be set", "error") return flask.redirect(flask.url_for(".user_settings"))
def save_reports(repo, username=None, namespace=None): """ Marked for watching or Unwatching """ if not flask.g.repo_admin: flask.abort( 403, 'You are not allowed to create reports for this project') return_point = flask.url_for( 'view_issues', repo=repo, username=username, namespace=namespace) if pagure.is_safe_url(flask.request.referrer): return_point = flask.request.referrer form = pagure.forms.AddReportForm() if not form.validate_on_submit(): flask.abort(400) name = form.report_name.data try: msg = pagure.lib.save_report( SESSION, flask.g.repo, name=name, url=flask.request.referrer, username=flask.g.fas_user.username) SESSION.commit() flask.flash(msg) except pagure.exceptions.PagureException as msg: flask.flash(msg, 'error') return flask.redirect(return_point)
def add_user_email(): """ Add a new email for the logged in user. """ if admin_session_timedout(): return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, "User not found") form = pagure.forms.UserEmailForm() if form.validate_on_submit(): email = form.email.data useremails = [mail.email for mail in user.emails] if email in useremails: flask.flash("The email: %s is already associated to you" % email, "error") return flask.redirect(flask.url_for(".user_settings")) try: pagure.lib.add_user_pending_email(SESSION, user, email) SESSION.commit() flask.flash("Email pending validation") return flask.redirect(flask.url_for(".user_settings")) except pagure.exceptions.PagureException, err: flask.flash(str(err), "error") except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash("Email could not be added", "error")
def user_settings(): """ Update the user settings. """ if admin_session_timedout(): return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, "User not found") form = pagure.forms.UserSettingsForm() if form.validate_on_submit(): ssh_key = form.ssh_key.data try: message = "Nothing to update" if user.public_ssh_key != ssh_key: pagure.lib.update_user_ssh( SESSION, user=user, ssh_key=ssh_key, keydir=APP.config.get("GITOLITE_KEYDIR", None) ) SESSION.commit() message = "Public ssh key updated" flask.flash(message) return flask.redirect(flask.url_for("view_user", username=user.user)) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), "error")
def new_repo_hook_token(repo, username=None): """ Re-generate a hook token for the present project. """ if not pagure.APP.config.get("WEBHOOK", False): flask.abort(404) if admin_session_timedout(): flask.flash("Action canceled, try it again", "error") url = flask.url_for("view_settings", username=username, repo=repo) return flask.redirect(flask.url_for("auth_login", next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, "Project not found") if not is_repo_admin(repo): flask.abort(403, "You are not allowed to change the settings for this project") form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.abort(400, "Invalid request") try: repo.hook_token = pagure.lib.login.id_generator(40) SESSION.commit() flask.flash("New hook token generated") except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash("Could not generate a new token for this project", "error") return flask.redirect(flask.url_for("view_settings", repo=repo.name, username=username))
def remove_tag(repo, username=None): """ Remove the specified tag from the project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to remove tags of this project') form = pagure.forms.AddIssueTagForm() if form.validate_on_submit(): tags = form.tag.data tags = [tag.strip() for tag in tags.split(',')] msgs = pagure.lib.remove_tags( SESSION, repo, tags, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER'] ) try: SESSION.commit() for msg in msgs: flask.flash(msg) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash( 'Could not remove tag: %s' % ','.join(tags), 'error')
def _check_session_cookie(): """ Set the user into flask.g if the user is logged in. """ cookie_name = APP.config.get('SESSION_COOKIE_NAME', 'pagure') cookie_name = '%s_local_cookie' % cookie_name session_id = None user = None login_time = None if cookie_name and cookie_name in flask.request.cookies: sessionid = flask.request.cookies.get(cookie_name) session = pagure.lib.login.get_session_by_visitkey(SESSION, sessionid) if session and session.user: now = datetime.datetime.now() if now > session.expiry: flask.flash('Session timed-out', 'error') elif APP.config.get('CHECK_SESSION_IP', True) \ and session.user_ip != flask.request.remote_addr: flask.flash('Session expired', 'error') else: new_expiry = now + datetime.timedelta(days=30) session_id = session.visit_key user = session.user login_time = session.created session.expiry = new_expiry SESSION.add(session) try: SESSION.commit() except SQLAlchemyError, err: # pragma: no cover flask.flash( 'Could not prolong the session in the db, ' 'please report this error to an admin', 'error') APP.logger.exception(err)
def user_settings(): """ Update the user settings. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserSettingsForm() if form.validate_on_submit(): ssh_key = form.ssh_key.data try: message = 'Nothing to update' if user.public_ssh_key != ssh_key: pagure.lib.update_user_ssh( SESSION, user=user, ssh_key=ssh_key, keydir=APP.config.get('GITOLITE_KEYDIR', None), ) SESSION.commit() message = 'Public ssh key updated' flask.flash(message) return flask.redirect( flask.url_for('view_user', username=user.user)) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def reconfirm_email(): """ Re-send the email address of the user. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user( SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserEmailForm() if form.validate_on_submit(): email = form.email.data try: pagure.lib.resend_pending_email(SESSION, user, email) SESSION.commit() flask.flash('Confirmation email re-sent') except pagure.exceptions.PagureException as err: flask.flash(str(err), 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Confirmation email could not be re-sent', 'error') return flask.redirect(flask.url_for('.user_settings'))
def new_project(): """ Form to create a new project. """ user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) if not pagure.APP.config.get('ENABLE_NEW_PROJECTS', True): flask.abort( 404, 'Creation of new project is not allowed on this \ pagure instance') namespaces = APP.config['ALLOWED_PREFIX'][:] if user: namespaces.extend([grp for grp in user.groups]) form = pagure.forms.ProjectForm(namespaces=namespaces) if form.validate_on_submit(): name = form.name.data description = form.description.data url = form.url.data avatar_email = form.avatar_email.data create_readme = form.create_readme.data namespace = form.namespace.data if namespace: namespace = namespace.strip() try: pagure.lib.new_project( SESSION, name=name, description=description, namespace=namespace, url=url, avatar_email=avatar_email, user=flask.g.fas_user.username, blacklist=APP.config['BLACKLISTED_PROJECTS'], allowed_prefix=APP.config['ALLOWED_PREFIX'], gitfolder=APP.config['GIT_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], add_readme=create_readme, userobj=user, prevent_40_chars=APP.config.get('OLD_VIEW_COMMIT_ENABLED', False), ) SESSION.commit() pagure.lib.git.generate_gitolite_acls() return flask.redirect( flask.url_for('view_repo', repo=name, namespace=namespace)) except pagure.exceptions.PagureException as err: flask.flash(str(err), 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error') return flask.render_template( 'new_project.html', form=form, )
def user_settings(): """ Update the user settings. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user( SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserSettingsForm() if form.validate_on_submit(): ssh_key = form.ssh_key.data try: message = pagure.lib.update_user_ssh( SESSION, user=user, ssh_key=ssh_key, ) if message != 'Nothing to update': generate_gitolite_key(user.user, ssh_key) generate_authorized_key_file() SESSION.commit() flask.flash(message) return flask.redirect( flask.url_for('view_user', username=user.user)) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def add_user_email(): """ Add a new email for the logged in user. """ if admin_session_timedout(): return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) user = pagure.lib.search_user( SESSION, username=flask.g.fas_user.username) if not user: flask.abort(404, 'User not found') form = pagure.forms.UserEmailForm( emails=[mail.email for mail in user.emails]) if form.validate_on_submit(): email = form.email.data try: pagure.lib.add_user_pending_email(SESSION, user, email) SESSION.commit() flask.flash('Email pending validation') return flask.redirect(flask.url_for('.user_settings')) except pagure.exceptions.PagureException as err: flask.flash(str(err), 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Email could not be added', 'error') return flask.render_template( 'user_emails.html', user=user, form=form, )
def save_reports(repo, username=None, namespace=None): """ Marked for watching or Unwatching """ return_point = flask.url_for( 'view_issues', repo=repo, username=username, namespace=namespace) if pagure.is_safe_url(flask.request.referrer): return_point = flask.request.referrer form = pagure.forms.AddReportForm() if not form.validate_on_submit(): flask.abort(400) name = form.report_name.data try: msg = pagure.lib.save_report( SESSION, flask.g.repo, name=name, url=flask.request.referrer, username=flask.g.fas_user.username) SESSION.commit() flask.flash(msg) except pagure.exceptions.PagureException as msg: flask.flash(msg, 'error') return flask.redirect(return_point)
def edit_comment_issue(repo, issueid, commentid, username=None): """Edit comment of an issue """ is_js = flask.request.args.get('js', False) project = pagure.lib.get_project(SESSION, repo, user=username) if not project: flask.abort(404, 'Project not found') if not project.settings.get('issue_tracker', True): flask.abort(404, 'No issue tracker found for this project') issue = pagure.lib.search_issues(SESSION, project, issueid=issueid) if issue is None or issue.project != project: flask.abort(404, 'Issue not found') comment = pagure.lib.get_issue_comment(SESSION, issue.uid, commentid) if comment is None or comment.parent.project != project: flask.abort(404, 'Comment not found') if (flask.g.fas_user.username != comment.user.username or comment.parent.status != 'Open') \ and not is_repo_admin(project): flask.abort(403, 'You are not allowed to edit this comment') form = pagure.forms.EditCommentForm() if form.validate_on_submit(): updated_comment = form.update_comment.data try: message = pagure.lib.edit_comment( SESSION, parent=issue, comment=comment, user=flask.g.fas_user.username, updated_comment=updated_comment, folder=APP.config['TICKETS_FOLDER'], ) SESSION.commit() if not is_js: flask.flash(message) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) if is_js: return 'error' flask.flash('Could not edit the comment: %s' % commentid, 'error') if is_js: return 'ok' return flask.redirect( flask.url_for('view_issue', username=username, repo=project.name, issueid=issueid))
def _check_session_cookie(): """ Set the user into flask.g if the user is logged in. """ cookie_name = APP.config.get('SESSION_COOKIE_NAME', 'pagure') cookie_name = '%s_local_cookie' % cookie_name session_id = None user = None login_time = None if cookie_name and cookie_name in flask.request.cookies: sessionid = flask.request.cookies.get(cookie_name) session = pagure.lib.login.get_session_by_visitkey( SESSION, sessionid) if session and session.user: now = datetime.datetime.now() if now > session.expiry: flask.flash('Session timed-out', 'error') elif APP.config.get('CHECK_SESSION_IP', True) \ and session.user_ip != flask.request.remote_addr: flask.flash('Session expired', 'error') else: new_expiry = now + datetime.timedelta(days=30) session_id = session.visit_key user = session.user login_time = session.created session.expiry = new_expiry SESSION.add(session) try: SESSION.commit() except SQLAlchemyError, err: # pragma: no cover flask.flash( 'Could not prolong the session in the db, ' 'please report this error to an admin', 'error') APP.logger.exception(err)
def do_expire_admin_token(args): """ Expire a specific admin token. :arg args: the argparse object returned by ``parse_arguments()``. """ _log.debug('token: %s', args.token) acls = APP.config['ADMIN_API_ACLS'] token = pagure.lib.search_token(SESSION, acls, token=args.token) if not token: raise pagure.exceptions.PagureException('No such admin token found') print('%s -- %s -- %s' % ( token.id, token.user.user, token.expiration)) print('ACLs:') for acl in token.acls: print(' - %s' % acl.name) print('Do you really want to expire this API token?') if _ask_confirmation(): token.expiration = datetime.datetime.utcnow() SESSION.add(token) SESSION.commit() print('Token expired')
def reset_password(token): """ Method to allow a user to reset his/her password. """ form = forms.ResetPasswordForm() user_obj = pagure.lib.search_user(SESSION, token=token) if not user_obj: flask.flash("No user associated with this token.", "error") return flask.redirect(flask.url_for("auth_login")) elif not user_obj.token: flask.flash("Invalid user, this user never asked for a password change", "error") return flask.redirect(flask.url_for("auth_login")) if form.validate_on_submit(): password = "******" % (form.password.data, APP.config.get("PASSWORD_SEED", None)) user_obj.password = hashlib.sha512(password).hexdigest() user_obj.token = None SESSION.add(user_obj) try: SESSION.commit() flask.flash("Password changed") except SQLAlchemyError as err: SESSION.rollback() flask.flash("Could not set the new password.", "error") APP.logger.debug("Password lost change - Error setting password.") APP.logger.exception(err) return flask.redirect(flask.url_for("auth_login")) return flask.render_template("login/password_reset.html", form=form, token=token)
def fork_project(repo, username=None): """ Fork the project specified into the user's namespace """ repo = pagure.lib.get_project(SESSION, repo, user=username) form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.abort(400) if repo is None: flask.abort(404) try: message = pagure.lib.fork_project( session=SESSION, repo=repo, gitfolder=APP.config['GIT_FOLDER'], forkfolder=APP.config['FORK_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], user=flask.g.fas_user.username) SESSION.commit() pagure.lib.git.generate_gitolite_acls() flask.flash(message) return flask.redirect( flask.url_for( 'view_repo', username=flask.g.fas_user.username, repo=repo.name) ) except pagure.exceptions.PagureException, err: flask.flash(str(err), 'error')
def edit_tag(repo, tag, username=None): """ Edit the specified tag of a project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort(403, 'You are not allowed to edt tags of this project') form = pagure.forms.AddIssueTagForm() if form.validate_on_submit(): new_tag = form.tag.data msgs = pagure.lib.edit_issue_tags( SESSION, repo, tag, new_tag, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER']) try: SESSION.commit() for msg in msgs: flask.flash(msg) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not edit tag: %s' % tag, 'error') return flask.redirect( flask.url_for('.view_settings', repo=repo.name, username=username))
def new_repo_hook_token(repo, username=None): """ Re-generate a hook token for the present project. """ if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for( 'view_settings', username=username, repo=repo) return flask.redirect( flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.abort(400, 'Invalid request') try: repo.hook_token = pagure.lib.login.id_generator(40) SESSION.commit() flask.flash('New hook token generated') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not generate a new token for this project', 'error')
def edit_comment_issue(repo, issueid, commentid, username=None): """Edit comment of an issue """ is_js = flask.request.args.get('js', False) project = pagure.lib.get_project(SESSION, repo, user=username) if not project: flask.abort(404, 'Project not found') if not project.settings.get('issue_tracker', True): flask.abort(404, 'No issue tracker found for this project') issue = pagure.lib.search_issues(SESSION, project, issueid=issueid) if issue is None or issue.project != project: flask.abort(404, 'Issue not found') comment = pagure.lib.get_issue_comment( SESSION, issue.uid, commentid) if comment is None or comment.parent.project != project: flask.abort(404, 'Comment not found') if (flask.g.fas_user.username != comment.user.username or comment.parent.status != 'Open') \ and not is_repo_admin(project): flask.abort(403, 'You are not allowed to edit this comment') form = pagure.forms.EditCommentForm() if form.validate_on_submit(): updated_comment = form.update_comment.data try: message = pagure.lib.edit_comment( SESSION, parent=issue, comment=comment, user=flask.g.fas_user.username, updated_comment=updated_comment, folder=APP.config['TICKETS_FOLDER'], ) SESSION.commit() if not is_js: flask.flash(message) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) if is_js: return 'error' flask.flash( 'Could not edit the comment: %s' % commentid, 'error') if is_js: return 'ok' return flask.redirect(flask.url_for( 'view_issue', username=username, repo=project.name, issueid=issueid))
def revoke_api_user_token(token_id): """ Revoke a user token (ie: not project specific). """ if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for('.user_settings') return flask.redirect(flask.url_for('auth_login', next=url)) token = pagure.lib.get_api_token(SESSION, token_id) if not token \ or token.user.username != flask.g.fas_user.username: flask.abort(404, 'Token not found') form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): try: if token.expiration >= datetime.datetime.utcnow(): token.expiration = datetime.datetime.utcnow() SESSION.add(token) SESSION.commit() flask.flash('Token revoked') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() _log.exception(err) flask.flash('Token could not be revoked, please contact an admin', 'error') return flask.redirect(flask.url_for('.user_settings'))
def pull_request_drop_comment(repo, requestid, username=None): """ Delete a comment of a pull-request. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-requests found for this project') request = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if flask.request.form.get('edit_comment'): commentid = flask.request.form.get('edit_comment') form = pagure.forms.EditCommentForm() if form.validate_on_submit(): return pull_request_edit_comment(repo.name, requestid, commentid, username=username) form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): if flask.request.form.get('drop_comment'): commentid = flask.request.form.get('drop_comment') comment = pagure.lib.get_request_comment(SESSION, request.uid, commentid) if comment is None or comment.pull_request.project != repo: flask.abort(404, 'Comment not found') if (flask.g.fas_user.username != comment.user.username or comment.parent.status is False) \ and not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to remove this comment from ' 'this issue') SESSION.delete(comment) try: SESSION.commit() flask.flash('Comment removed') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not remove the comment: %s' % commentid, 'error') return flask.redirect( flask.url_for('request_pull', username=username, repo=repo.name, requestid=requestid))
def add_token(repo, username=None): """ Add a token to a specified project. """ if admin_session_timedout(): if flask.request.method == "POST": flask.flash("Action canceled, try it again", "error") return flask.redirect(flask.url_for("auth_login", next=flask.request.url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, "Project not found") if not is_repo_admin(repo): flask.abort(403, "You are not allowed to change the settings for this project") acls = pagure.lib.get_acls(SESSION) form = pagure.forms.NewTokenForm(acls=acls) if form.validate_on_submit(): try: msg = pagure.lib.add_token_to_user(SESSION, repo, acls=form.acls.data, username=flask.g.fas_user.username) SESSION.commit() flask.flash(msg) return flask.redirect(flask.url_for(".view_settings", repo=repo.name, username=username)) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash("User could not be added", "error") return flask.render_template("add_token.html", form=form, acls=acls, username=username, repo=repo)
def fork_project(repo, username=None): """ Fork the project specified into the user's namespace """ repo = pagure.lib.get_project(SESSION, repo, user=username) form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.abort(400) if repo is None: flask.abort(404) try: message = pagure.lib.fork_project( session=SESSION, repo=repo, gitfolder=APP.config['GIT_FOLDER'], forkfolder=APP.config['FORK_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], user=flask.g.fas_user.username) SESSION.commit() pagure.lib.git.generate_gitolite_acls() flask.flash(message) return flask.redirect( flask.url_for('view_repo', username=flask.g.fas_user.username, repo=repo.name)) except pagure.exceptions.PagureException, err: flask.flash(str(err), 'error')
def update_project(repo, username=None): """ Update the description of a project. """ if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for( 'view_settings', username=username, repo=repo.name) return flask.redirect( flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') form = pagure.forms.ProjectFormSimplified() if form.validate_on_submit(): try: repo.description = form.description.data repo.avatar_email = form.avatar_email.data.strip() repo.url = form.url.data.strip() SESSION.add(repo) SESSION.commit() flask.flash('Project updated') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def delete_repo(repo, username=None): """ Delete the present project. """ if not pagure.APP.config.get('ENABLE_DEL_PROJECTS', True): flask.abort(404) if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for( 'view_settings', username=username, repo=repo) return flask.redirect( flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') try: for issue in repo.issues: for comment in issue.comments: SESSION.delete(comment) SESSION.commit() SESSION.delete(issue) SESSION.delete(repo) SESSION.commit() except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the project', 'error')
def pull_request_add_comment( repo, requestid, commit=None, filename=None, row=None, username=None): """ Add a comment to a commit in a pull-request. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-requests found for this project') request = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') is_js = flask.request.args.get('js', False) repo = request.project_from form = pagure.forms.AddPullRequestCommentForm() form.commit.data = commit form.filename.data = filename form.requestid.data = requestid form.row.data = row if form.validate_on_submit(): comment = form.comment.data try: message = pagure.lib.add_pull_request_comment( SESSION, request=request, commit=commit, filename=filename, row=row, comment=comment, user=flask.g.fas_user.username, requestfolder=APP.config['REQUESTS_FOLDER'], redis=REDIS, ) SESSION.commit() flask.flash(message) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash(str(err), 'error') if is_js: return 'error' if is_js: return 'ok' return flask.redirect(flask.url_for( 'request_pull', username=username, repo=repo.name, requestid=requestid))
def api_pull_request_close(repo, requestid, username=None): """ Close a pull-request -------------------- Instruct Pagure to close a pull request. :: POST /api/0/<repo>/pull-request/<request id>/close :: POST /api/0/fork/<username>/<repo>/pull-request/<request id>/close Sample response ^^^^^^^^^^^^^^^ :: { "message": "Pull-request closed!" } """ output = {} repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOPROJECT) if not repo.settings.get("pull_requests", True): raise pagure.exceptions.APIError(404, error_code=APIERROR.EPULLREQUESTSDISABLED) if repo != flask.g.token.project: raise pagure.exceptions.APIError(401, error_code=APIERROR.EINVALIDTOK) request = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, requestid=requestid) if not request: raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOREQ) if not is_repo_admin(repo): raise pagure.exceptions.APIError(403, error_code=APIERROR.ENOPRCLOSE) try: pagure.lib.close_pull_request( SESSION, request, flask.g.fas_user.username, requestfolder=APP.config["REQUESTS_FOLDER"], merged=False ) SESSION.commit() output["message"] = "Pull-request closed!" except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) jsonout = flask.jsonify(output) return jsonout
def new_user(): """ Create a new user. """ form = forms.NewUserForm() if form.validate_on_submit(): username = form.user.data if pagure.lib.search_user(SESSION, username=username): flask.flash('Username already taken.', 'error') return flask.redirect(flask.request.url) email = form.email_address.data if pagure.lib.search_user(SESSION, email=email): flask.flash('Email address already taken.', 'error') return flask.redirect(flask.request.url) password = '******' % ( form.password.data, APP.config.get('PASSWORD_SEED', None)) form.password.data = hashlib.sha512(password).hexdigest() token = pagure.lib.login.id_generator(40) user = model.User() user.token = token form.populate_obj(obj=user) user.default_email = form.email_address.data SESSION.add(user) SESSION.flush() emails = [email.email for email in user.emails] if form.email_address.data not in emails: useremail = model.UserEmail( user_id=user.id, email=form.email_address.data) SESSION.add(useremail) SESSION.flush() try: SESSION.flush() send_confirmation_email(user) flask.flash( 'User created, please check your email to activate the ' 'account') except SQLAlchemyError as err: SESSION.rollback() flask.flash('Could not create user.') APP.logger.debug('Could not create user.') APP.logger.exception(err) SESSION.commit() return flask.redirect(flask.url_for('auth_login')) return flask.render_template( 'login/user_new.html', form=form, )
def view_settings(repo, username=None): """ Presents the settings of the project. """ if admin_session_timedout(): if flask.request.method == 'POST': flask.flash('Action canceled, try it again', 'error') return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') repo_admin = is_repo_admin(repo) if not repo_admin: flask.abort( 403, 'You are not allowed to change the settings for this project') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) plugins = pagure.ui.plugins.get_plugin_names( APP.config.get('DISABLED_PLUGINS')) tags = pagure.lib.get_tags_of_project(SESSION, repo) form = pagure.forms.ConfirmationForm() tag_form = pagure.forms.AddIssueTagForm() branches = repo_obj.listall_branches() branches_form = pagure.forms.DefaultBranchForm(branches=branches) if form.validate_on_submit(): settings = {} for key in flask.request.form: if key == 'csrf_token': continue settings[key] = flask.request.form[key] try: message = pagure.lib.update_project_settings( SESSION, repo=repo, settings=settings, user=flask.g.fas_user.username, ) SESSION.commit() flask.flash(message) return flask.redirect(flask.url_for( 'view_repo', username=username, repo=repo.name)) except pagure.exceptions.PagureException as msg: SESSION.rollback() flask.flash(msg, 'error') except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def new_user(): """ Create a new user. """ form = forms.NewUserForm() if form.validate_on_submit(): username = form.user.data if pagure.lib.search_user(SESSION, username=username): flask.flash('Username already taken.', 'error') return flask.redirect(flask.request.url) email = form.email_address.data if pagure.lib.search_user(SESSION, email=email): flask.flash('Email address already taken.', 'error') return flask.redirect(flask.request.url) password = '******' % (form.password.data, APP.config.get('PASSWORD_SEED', None)) form.password.data = hashlib.sha512(password).hexdigest() token = pagure.lib.login.id_generator(40) user = model.User() user.token = token form.populate_obj(obj=user) user.default_email = form.email_address.data SESSION.add(user) SESSION.flush() emails = [email.email for email in user.emails] if form.email_address.data not in emails: useremail = model.UserEmail(user_id=user.id, email=form.email_address.data) SESSION.add(useremail) SESSION.flush() try: SESSION.flush() send_confirmation_email(user) flask.flash( 'User created, please check your email to activate the ' 'account') except SQLAlchemyError as err: SESSION.rollback() flask.flash('Could not create user.') APP.logger.debug('Could not create user.') APP.logger.exception(err) SESSION.commit() return flask.redirect(flask.url_for('auth_login')) return flask.render_template( 'login/user_new.html', form=form, )
def request_pull_edit(repo, requestid, username=None): """ Edit the title of a pull-request. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-requests found for this project') request = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if request.status != 'Open': flask.abort(400, 'Pull-request is already closed') if not is_repo_admin(repo) \ and flask.g.fas_user.username != request.user.username: flask.abort(403, 'You are not allowed to edit this pull-request') form = pagure.forms.RequestPullForm() if form.validate_on_submit(): request.title = form.title.data.strip() request.initial_comment = form.initial_comment.data.strip() SESSION.add(request) try: SESSION.commit() flask.flash('Request pull edited!') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not edit this pull-request in the database', 'error') return flask.redirect( flask.url_for('request_pull', username=username, repo=repo.name, requestid=requestid)) elif flask.request.method == 'GET': form.title.data = request.title form.initial_comment.data = request.initial_comment return flask.render_template( 'pull_request_title.html', select='requests', request=request, repo=repo, username=username, form=form, )
def pull_request_drop_comment(repo, requestid, username=None): """ Delete a comment of a pull-request. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-requests found for this project') request = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if flask.request.form.get('edit_comment'): commentid = flask.request.form.get('edit_comment') form = pagure.forms.EditCommentForm() if form.validate_on_submit(): return pull_request_edit_comment( repo.name, requestid, commentid, username=username) form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): if flask.request.form.get('drop_comment'): commentid = flask.request.form.get('drop_comment') comment = pagure.lib.get_request_comment( SESSION, request.uid, commentid) if comment is None or comment.pull_request.project != repo: flask.abort(404, 'Comment not found') if (flask.g.fas_user.username != comment.user.username or comment.parent.status is False) \ and not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to remove this comment from ' 'this issue') SESSION.delete(comment) try: SESSION.commit() flask.flash('Comment removed') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash( 'Could not remove the comment: %s' % commentid, 'error') return flask.redirect(flask.url_for( 'request_pull', username=username, repo=repo.name, requestid=requestid))
def install(cls, project, dbobj): ''' Method called to install the hook for a project. :arg project: a ``pagure.model.Project`` object to which the hook should be installed ''' if not dbobj.pagure_ci_token: dbobj.pagure_ci_token = pagure.lib.login.id_generator(32) SESSION.commit()
def remove(cls, project): ''' Method called to remove the hook of a project. :arg project: a ``pagure.model.Project`` object to which the hook should be installed ''' for hook in project.ci_hook: hook.pagure_ci_token = None SESSION.commit()
def delete_repo(repo, username=None): """ Delete the present project. """ if not pagure.APP.config.get('ENABLE_DEL_PROJECTS', True): flask.abort(404) if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for( 'view_settings', username=username, repo=repo) return flask.redirect( flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') try: for issue in repo.issues: for comment in issue.comments: SESSION.delete(comment) SESSION.commit() SESSION.delete(issue) SESSION.delete(repo) SESSION.commit() except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the project', 'error') repopath = os.path.join(APP.config['GIT_FOLDER'], repo.path) if repo.is_fork: repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path) docpath = os.path.join(APP.config['DOCS_FOLDER'], repo.path) ticketpath = os.path.join(APP.config['TICKETS_FOLDER'], repo.path) requestpath = os.path.join(APP.config['REQUESTS_FOLDER'], repo.path) try: shutil.rmtree(repopath) shutil.rmtree(docpath) shutil.rmtree(ticketpath) shutil.rmtree(requestpath) except (OSError, IOError) as err: APP.logger.exception(err) flask.flash( 'Could not delete all the repos from the system', 'error') return flask.redirect( flask.url_for('view_user', username=flask.g.fas_user.username))
def pull_request_edit_comment(repo, requestid, commentid, username=None): """Edit comment of a pull request """ is_js = flask.request.args.get("js", False) project = pagure.lib.get_project(SESSION, repo, user=username) if not project: flask.abort(404, "Project not found") if not project.settings.get("pull_requests", True): flask.abort(404, "No pull-requests found for this project") request = pagure.lib.search_pull_requests(SESSION, project_id=project.id, requestid=requestid) if not request: flask.abort(404, "Pull-request not found") comment = pagure.lib.get_request_comment(SESSION, request.uid, commentid) if comment is None or comment.parent.project != project: flask.abort(404, "Comment not found") if (flask.g.fas_user.username != comment.user.username or comment.parent.status != "Open") and not is_repo_admin( project ): flask.abort(403, "You are not allowed to edit the comment") form = pagure.forms.EditCommentForm() if form.validate_on_submit(): updated_comment = form.update_comment.data try: message = pagure.lib.edit_comment( SESSION, parent=request, comment=comment, user=flask.g.fas_user.username, updated_comment=updated_comment, folder=APP.config["REQUESTS_FOLDER"], ) SESSION.commit() if not is_js: flask.flash(message) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() LOG.error(err) if is_js: return "error" flask.flash("Could not edit the comment: %s" % commentid, "error") if is_js: return "ok" return flask.redirect(flask.url_for("request_pull", username=username, repo=project.name, requestid=requestid))
def request_pull_edit(repo, requestid, username=None): """ Edit the title of a pull-request. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-requests found for this project') request = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if request.status != 'Open': flask.abort(400, 'Pull-request is already closed') if not is_repo_admin(repo) \ and flask.g.fas_user.username != request.user.username: flask.abort(403, 'You are not allowed to edit this pull-request') form = pagure.forms.RequestPullForm() if form.validate_on_submit(): request.title = form.title.data.strip() request.initial_comment = form.initial_comment.data.strip() SESSION.add(request) try: SESSION.commit() flask.flash('Request pull edited!') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash( 'Could not edit this pull-request in the database', 'error') return flask.redirect(flask.url_for( 'request_pull', username=username, repo=repo.name, requestid=requestid)) elif flask.request.method == 'GET': form.title.data = request.title form.initial_comment.data = request.initial_comment return flask.render_template( 'pull_request_title.html', select='requests', request=request, repo=repo, username=username, form=form, )
def edit_tag(repo, tag, username=None): """ Edit the specified tag associated with the issues of a project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to edit tags associated with the issues of \ this project') if not repo.settings.get('issue_tracker', True): flask.abort(404, 'No issue tracker found for this project') tags = pagure.lib.get_tags_of_project(SESSION, repo) if not tags or tag not in [t.tag for t in tags]: flask.abort(404, 'Tag %s not found in this project' % tag) form = pagure.forms.AddIssueTagForm() if form.validate_on_submit(): new_tag = form.tag.data msgs = pagure.lib.edit_issue_tags( SESSION, repo, tag, new_tag, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER']) try: SESSION.commit() for msg in msgs: flask.flash(msg) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not edit tag: %s' % tag, 'error') return flask.redirect( flask.url_for('.view_settings', repo=repo.name, username=username)) return flask.render_template( 'edit_tag.html', form=form, username=username, repo=repo, edit_tag=tag, )
def add_group_project(repo, username=None): """ Add the specified group from the project. """ if not pagure.APP.config.get('ENABLE_USER_MNGT', True): flask.abort(404) if admin_session_timedout(): if flask.request.method == 'POST': flask.flash('Action canceled, try it again', 'error') return flask.redirect( flask.url_for('auth_login', next=flask.request.url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to add groups to this project') form = pagure.forms.AddGroupForm() if form.validate_on_submit(): try: msg = pagure.lib.add_group_to_project( SESSION, repo, new_group=form.group.data, user=flask.g.fas_user.username, ) SESSION.commit() pagure.lib.git.generate_gitolite_acls() flask.flash(msg) return flask.redirect( flask.url_for( '.view_settings', repo=repo.name, username=username) ) except pagure.exceptions.PagureException as msg: SESSION.rollback() flask.flash(msg, 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Group could not be added', 'error') return flask.render_template( 'add_group_project.html', form=form, username=username, repo=repo, )
def change_password(): """ Method to change the password for local auth users. """ form = forms.ChangePasswordForm() user_obj = pagure.lib.search_user( SESSION, username=flask.g.fas_user.username) if not user_obj: flask.abort(404, 'User not found') if form.validate_on_submit(): try: password_checks = check_password( form.old_password.data, user_obj.password, seed=APP.config.get('PASSWORD_SEED', None)) except pagure.exceptions.PagureException as err: APP.logger.exception(err) flask.flash( 'Could not update your password, either user or password ' 'could not be checked', 'error') return flask.redirect(flask.url_for('auth_login')) if password_checks: user_obj.password = generate_hashed_value(form.password.data) SESSION.add(user_obj) else: flask.flash( 'Could not update your password, either user or password ' 'could not be checked', 'error') return flask.redirect(flask.url_for('auth_login')) try: SESSION.commit() flask.flash( 'Password changed') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() flask.flash('Could not set the new password.', 'error') APP.logger.debug( 'Password change - Error setting new password.') APP.logger.exception(err) return flask.redirect(flask.url_for('auth_login')) return flask.render_template( 'login/password_recover.html', form=form, )
def delete_repo(repo, username=None): """ Delete the present project. """ if not pagure.APP.config.get('ENABLE_DEL_PROJECTS', True): flask.abort(404) if admin_session_timedout(): flask.flash('Action canceled, try it again', 'error') url = flask.url_for('view_settings', username=username, repo=repo) return flask.redirect(flask.url_for('auth_login', next=url)) repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') if not is_repo_admin(repo): flask.abort( 403, 'You are not allowed to change the settings for this project') try: for issue in repo.issues: for comment in issue.comments: SESSION.delete(comment) SESSION.commit() SESSION.delete(issue) SESSION.delete(repo) SESSION.commit() except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the project', 'error') repopath = os.path.join(APP.config['GIT_FOLDER'], repo.path) if repo.is_fork: repopath = os.path.join(APP.config['FORK_FOLDER'], repo.path) docpath = os.path.join(APP.config['DOCS_FOLDER'], repo.path) ticketpath = os.path.join(APP.config['TICKETS_FOLDER'], repo.path) requestpath = os.path.join(APP.config['REQUESTS_FOLDER'], repo.path) try: shutil.rmtree(repopath) shutil.rmtree(docpath) shutil.rmtree(ticketpath) shutil.rmtree(requestpath) except (OSError, IOError) as err: APP.logger.exception(err) flask.flash('Could not delete all the repos from the system', 'error') return flask.redirect( flask.url_for('view_user', username=flask.g.fas_user.username))
def edit_issue(repo, issueid, username=None): """ Edit the specified issue """ repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: flask.abort(404, 'Project not found') if not repo.settings.get('issue_tracker', True): flask.abort(404, 'No issue tracker found for this project') issue = pagure.lib.search_issues(SESSION, repo, issueid=issueid) if issue is None or issue.project != repo: flask.abort(404, 'Issue not found') if not (is_repo_admin(repo) or flask.g.fas_user.username == issue.user.username): flask.abort(403, 'You are not allowed to edit issues for this project') status = pagure.lib.get_issue_statuses(SESSION) form = pagure.forms.IssueForm(status=status) if form.validate_on_submit(): title = form.title.data content = form.issue_content.data status = form.status.data private = form.private.data try: message = pagure.lib.edit_issue( SESSION, issue=issue, title=title, content=content, status=status, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER'], private=private, redis=REDIS, ) SESSION.commit() flask.flash(message) url = flask.url_for('view_issue', username=username, repo=repo.name, issueid=issueid) return flask.redirect(url) except SQLAlchemyError, err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error')
def do_login(): """ Lo the user in user. """ form = forms.LoginForm() next_url = flask.request.args.get('next_url') if not next_url or next_url == 'None': next_url = flask.url_for('index') if form.validate_on_submit(): username = form.username.data password = '******' % (form.password.data, APP.config.get('PASSWORD_SEED', None)) password = hashlib.sha512(password).hexdigest() user_obj = pagure.lib.search_user(SESSION, username=username) if not user_obj or user_obj.password != password: flask.flash('Username or password invalid.', 'error') return flask.redirect(flask.url_for('auth_login')) elif user_obj.token: flask.flash( 'Invalid user, did you confirm the creation with the url ' 'provided by email?', 'error') return flask.redirect(flask.url_for('auth_login')) else: visit_key = pagure.lib.login.id_generator(40) now = datetime.datetime.utcnow() expiry = now + datetime.timedelta(days=30) session = model.PagureUserVisit( user_id=user_obj.id, user_ip=flask.request.remote_addr, visit_key=visit_key, expiry=expiry, ) SESSION.add(session) try: SESSION.commit() flask.g.fas_user = user_obj flask.g.fas_session_id = visit_key flask.g.fas_user.login_time = now flask.flash('Welcome %s' % user_obj.username) except SQLAlchemyError as err: # pragma: no cover flask.flash( 'Could not set the session in the db, ' 'please report this error to an admin', 'error') APP.logger.exception(err) return flask.redirect(next_url) else: flask.flash('Insufficient information provided', 'error') return flask.redirect(flask.url_for('auth_login'))
def set_assignee_requests(repo, requestid, username=None): ''' Assign a pull-request. ''' repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: flask.abort(404, 'Project not found') if not repo.settings.get('pull_requests', True): flask.abort(404, 'No pull-request allowed on this project') request = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if request.status != 'Open': flask.abort(403, 'Pull-request closed') if not is_repo_admin(repo): flask.abort(403, 'You are not allowed to assign this pull-request') form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): try: # Assign or update assignee of the ticket message = pagure.lib.add_pull_request_assignee( SESSION, request=request, assignee=flask.request.form.get('user', '').strip() or None, user=flask.g.fas_user.username, requestfolder=APP.config['REQUESTS_FOLDER'], ) if message: SESSION.commit() flask.flash(message) except pagure.exceptions.PagureException as err: SESSION.rollback() flask.flash(err.message, 'error') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash(str(err), 'error') return flask.redirect( flask.url_for('request_pull', username=username, repo=repo.name, requestid=requestid))