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 _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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 _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 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 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 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_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. """ 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 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 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 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 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 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 request_pull_patch(repo, requestid, username=None): """ Returns the commits from the specified pull-request as patches. """ 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') repo_from = request.project_from repopath = pagure.get_repo_path(repo_from) repo_obj = pygit2.Repository(repopath) parentpath = _get_parent_repo_path(repo_from) orig_repo = pygit2.Repository(parentpath) branch = repo_obj.lookup_branch(request.branch_from) commitid = None if branch: commitid = branch.get_object().hex diff_commits = [] if request.status != 'Open': commitid = request.commit_stop for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_TIME): diff_commits.append(commit) if commit.oid.hex == request.commit_start: break else: try: diff_commits, diff = pagure.lib.git.diff_pull_request( SESSION, request, repo_obj, orig_repo, requestfolder=APP.config['REQUESTS_FOLDER'], with_diff=False) except pagure.exceptions.PagureException as err: flask.flash(err.message, 'error') return flask.redirect(flask.url_for( 'view_repo', username=username, repo=repo.name)) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash( 'Could not update this pull-request in the database', 'error') diff_commits.reverse() patch = pagure.lib.git.commit_to_patch(repo_obj, diff_commits) return flask.Response(patch, content_type="text/plain;charset=UTF-8")
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 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 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 upload_issue(repo, issueid, username=None, namespace=None): ''' Upload a file to a ticket. ''' repo = flask.g.repo 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') try: user_obj = pagure.lib.get_user( SESSION, flask.g.fas_user.username) except pagure.exceptions.PagureException: flask.abort( 404, 'No such user found in the database: %s' % ( flask.g.fas_user.username)) form = pagure.forms.UploadFileForm() if form.validate_on_submit(): filestream = flask.request.files['filestream'] try: new_filename = pagure.lib.git.add_file_to_git( repo=repo, issue=issue, ticketfolder=APP.config['TICKETS_FOLDER'], user=user_obj, filename=filestream.filename, filestream=filestream.stream, ) except filelock.Timeout as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash( 'We could not save all the info, please try again', 'error') return flask.jsonify({ 'output': 'ok', 'filename': new_filename.split('-', 1)[1], 'filelocation': flask.url_for( 'view_issue_raw_file', repo=repo.name, username=username, namespace=repo.namespace, filename=new_filename, ) }) else: return flask.jsonify({'output': 'notok'})
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 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 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 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 fork_edit_file(repo, branchname, filename, username=None): """ Fork the project specified and open the specific file to edit """ 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) if pagure.lib.get_project( SESSION, repo.name, user=flask.g.fas_user.username): flask.flash('You had already forked this project') return flask.redirect(flask.url_for( 'edit_file', username=flask.g.fas_user.username, repo=repo.name, branchname=branchname, filename=filename )) try: message = pagure.lib.fork_project( session=SESSION, repo=repo, gitfolder=APP.config['GIT_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( 'edit_file', username=flask.g.fas_user.username, repo=repo.name, branchname=branchname, filename=filename )) 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.redirect(flask.url_for('view_repo', repo=repo.name))
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 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') 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 create_readme = form.create_readme.data try: 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'], 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)) 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 fork_edit_file(repo, branchname, filename, username=None): """ Fork the project specified and open the specific file to edit """ 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) if pagure.lib.get_project(SESSION, repo.name, user=flask.g.fas_user.username): flask.flash('You had already forked this project') return flask.redirect( flask.url_for('edit_file', username=flask.g.fas_user.username, repo=repo.name, branchname=branchname, filename=filename)) try: message = pagure.lib.fork_project( session=SESSION, repo=repo, gitfolder=APP.config['GIT_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('edit_file', username=flask.g.fas_user.username, repo=repo.name, branchname=branchname, filename=filename)) 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.redirect(flask.url_for('view_repo', repo=repo.name))
def remove_user(repo, userid, username=None): """ Remove the specified user from the 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 users for this project') form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): userids = [str(user.id) for user in repo.users] if str(userid) not in userids: flask.flash( 'User does not have commit or cannot loose it right', 'error') return flask.redirect( flask.url_for( '.view_settings', repo=repo.name, username=username) ) for user in repo.users: if str(user.id) == str(userid): repo.users.remove(user) break try: SESSION.commit() pagure.lib.git.generate_gitolite_acls() flask.flash('User removed') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('User could not be removed', 'error') return flask.redirect( flask.url_for('.view_settings', repo=repo.name, username=username) )
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 main(debug=False): ''' The function that actually sends the email in case the expiration date is near''' current_time = datetime.utcnow() day_diff_for_mail = [5, 3, 1] email_dates = [email_day.date() for email_day in \ [current_time + timedelta(days=i) for i in day_diff_for_mail]] tokens = SESSION.query(model.Token).all() for token in tokens: if token.expiration.date() in email_dates: user = token.user user_email = user.default_email project = token.project days_left = token.expiration.day - datetime.utcnow().day subject = 'Pagure API key expiration date is near!' text = '''Hi %s, \nYour Pagure API key for the project %s will expire in %s day(s). Please get a new key for non-interrupted service. \n Thanks, \nYour Pagure Admin. ''' % (user.fullname, project.name, days_left) msg = pagure.lib.notify.send_email(text, subject, user_email) if debug: print('Sent mail to %s' % user.fullname) if debug: print('Done')
def cancel_request_pull(repo, requestid, username=None): """ Cancel request pulling request. """ form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): repo_obj = pagure.lib.get_project(SESSION, repo, user=username) if not repo_obj: flask.abort(404, 'Project not found') if not repo_obj.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_obj.id, requestid=requestid) if not request: flask.abort(404, 'Pull-request not found') if not is_repo_admin(repo_obj) \ and not flask.g.fas_user.username == request.user.username: flask.abort( 403, 'You are not allowed to cancel pull-request for this project') pagure.lib.close_pull_request( SESSION, request, flask.g.fas_user.username, requestfolder=APP.config['REQUESTS_FOLDER'], merged=False) try: SESSION.commit() flask.flash('Request pull canceled!') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not update this pull-request in the database', 'error') else: flask.flash('Invalid input submitted', 'error') return flask.redirect(flask.url_for('view_repo', repo=repo))
def remove_user_email(): """ Remove the specified email from 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') if len(user.emails) == 1: flask.flash( 'You must always have at least one email', 'error') return flask.redirect( flask.url_for('.user_settings') ) 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 remove' % email, 'error') return flask.redirect( flask.url_for('.user_settings') ) for mail in user.emails: if mail.email == email: user.emails.remove(mail) break try: SESSION.commit() flask.flash('Email removed') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Email could not be removed', 'error') return flask.redirect(flask.url_for('.user_settings'))
def delete_issue(repo, issueid, username=None): """ Delete 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): flask.abort(403, 'You are not allowed to remove tickets of this project') form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): try: pagure.lib.drop_issue( SESSION, issue, user=flask.g.fas_user.username, ticketfolder=APP.config['TICKETS_FOLDER'], ) SESSION.commit() flask.flash('Issue deleted') return flask.redirect( flask.url_for('view_issues', username=username, repo=repo.name)) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the issue', 'error') return flask.redirect( flask.url_for('view_issue', username=username, repo=repo.name, issueid=issueid))
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 add_api_user_token(): """ Create an user token (not project specific). """ 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)) # Ensure the user is in the DB at least user = _get_user(username=flask.g.fas_user.username) acls = pagure.lib.get_acls(SESSION, restrict=APP.config.get('CROSS_PROJECT_ACLS')) form = pagure.forms.NewTokenForm(acls=acls) if form.validate_on_submit(): try: msg = pagure.lib.add_token_to_user( SESSION, project=None, description=form.description.data.strip() or None, acls=form.acls.data, username=user.username, ) SESSION.commit() flask.flash(msg) return flask.redirect(flask.url_for('.user_settings')) except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() _log.exception(err) flask.flash('API key could not be added', 'error') # When form is displayed after an empty submission, show an error. if form.errors.get('acls'): flask.flash('You must select at least one permission.', 'error') return flask.render_template( 'add_token.html', select='settings', form=form, acls=acls, )
def do_update_watch_status(args): """ Update the watch status of an user on a project. :arg args: the argparse object returned by ``parse_arguments()``. """ _log.debug('user: %s', args.user) _log.debug('status: %s', args.status) _log.debug('project: %s', args.project) # Validate user pagure.lib.get_user(SESSION, args.user) # Ask the status if none were given if args.status is None: print('The watch status can be one of the following: ') for lvl in WATCH: print('%s: %s' % (lvl, WATCH[lvl])) args.status = _get_input('Status:') # Validate the status if args.status not in WATCH: raise pagure.exceptions.PagureException( 'Invalid status provided: %s not in %s' % ( args.status, ', '.join(sorted(WATCH.keys())))) # Get the project project = _get_project(args.project) if project is None: raise pagure.exceptions.PagureException( 'No project found with: %s' % args.project) print('Updating watch status of %s to %s (%s) on %s' % ( args.user, args.status, WATCH[args.status], args.project)) pagure.lib.update_watch_status( session=SESSION, project=project, user=args.user, watch=args.status) SESSION.commit()