def regenerate_git(repo, username=None): """ Regenerate the specified git repo with the content in 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 regenerate the git repos") regenerate = flask.request.form.get("regenerate") if not regenerate or regenerate.lower() not in ["tickets", "requests"]: flask.abort(400, "You can only regenerate tickest or requests repos") form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): if regenerate.lower() == "requests": for request in repo.requests: pagure.lib.git.update_git(request, repo=repo, repofolder=APP.config["REQUESTS_FOLDER"]) flask.flash("Requests git repo updated") elif regenerate.lower() == "tickets": for ticket in repo.issues: # Do not store private issues in the git if ticket.private: continue pagure.lib.git.update_git(ticket, repo=repo, repofolder=APP.config["TICKETS_FOLDER"]) flask.flash("Tickets git repo updated") return flask.redirect(flask.url_for(".view_settings", repo=repo.name, username=username))
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 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 delete_branch(repo, branchname, username=None): """ Delete the branch of a project. """ repo_obj = pagure.lib.get_project(SESSION, repo, user=username) if not repo_obj: flask.abort(404, 'Project not found') if not is_repo_admin(repo_obj): flask.abort( 403, 'You are not allowed to delete branch for this project') if branchname == 'master': flask.abort(403, 'You are not allowed to delete the master branch') reponame = pagure.get_repo_path(repo_obj) repo_git = pygit2.Repository(reponame) if branchname not in repo_git.listall_branches(): flask.abort(404, 'Branch no found') try: branch = repo_git.lookup_branch(branchname) branch.delete() flask.flash('Branch `%s` deleted' % branchname) except pygit2.GitError, err: APP.logger.exception(err) flask.flash('Could not delete `%s`' % branchname, 'error')
def new_release(repo, username=None): """ Upload a new release. """ if not APP.config.get("UPLOAD_FOLDER_PATH") and not APP.config.get("UPLOAD_FOLDER"): flask.abort(404) 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.UploadFileForm() if form.validate_on_submit(): for filestream in flask.request.files.getlist("filestream"): filename = werkzeug.secure_filename(filestream.filename) try: folder = os.path.join(APP.config["UPLOAD_FOLDER_PATH"], werkzeug.secure_filename(repo.fullname)) if not os.path.exists(folder): os.mkdir(folder) filestream.save(os.path.join(folder, filename)) flask.flash('File "%s" uploaded' % filename) except Exception as err: # pragma: no cover APP.logger.exception(err) flask.flash("Upload failed", "error") return flask.redirect(flask.url_for("view_tags", repo=repo.name, username=username)) return flask.render_template("new_release.html", select="tags", username=username, repo=repo, 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, err: # pragma: no cover SESSION.rollback() APP.logger.exception(err) flask.flash('Could not delete the project', 'error')
def change_ref_head(repo, username=None): """ Change HEAD reference """ 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') repopath = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(repopath) branches = repo_obj.listall_branches() form = pagure.forms.DefaultBranchForm(branches=branches) if form.validate_on_submit(): branchname = form.branches.data try: reference = repo_obj.lookup_reference('refs/heads/%s'%branchname).resolve() repo_obj.set_head(reference.name) flask.flash('Default branch updated to %s'%branchname) except Exception as err: # pragma: no cover APP.logger.exception(err) return flask.redirect(flask.url_for( 'view_settings', username=username, repo=repo.name))
def delete_branch(repo, branchname, username=None): """ Delete the branch of a project. """ repo_obj = pagure.lib.get_project(SESSION, repo, user=username) if not repo_obj: flask.abort(404, "Project not found") if not is_repo_admin(repo_obj): flask.abort(403, "You are not allowed to delete branch for this project") if branchname == "master": flask.abort(403, "You are not allowed to delete the master branch") reponame = pagure.get_repo_path(repo_obj) repo_git = pygit2.Repository(reponame) if branchname not in repo_git.listall_branches(): flask.abort(404, "Branch no found") try: branch = repo_git.lookup_branch(branchname) branch.delete() flask.flash("Branch `%s` deleted" % branchname) except pygit2.GitError as err: APP.logger.exception(err) flask.flash("Could not delete `%s`" % branchname, "error") return flask.redirect(flask.url_for("view_repo", repo=repo, username=username))
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 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 delete_branch(repo, branchname, username=None): """ Delete the branch of a project. """ repo_obj = pagure.lib.get_project(SESSION, repo, user=username) if not repo_obj: flask.abort(404, 'Project not found') if not is_repo_admin(repo_obj): flask.abort(403, 'You are not allowed to delete branch for this project') if branchname == 'master': flask.abort(403, 'You are not allowed to delete the master branch') reponame = pagure.get_repo_path(repo_obj) repo_git = pygit2.Repository(reponame) if branchname not in repo_git.listall_branches(): flask.abort(404, 'Branch no found') try: branch = repo_git.lookup_branch(branchname) branch.delete() flask.flash('Branch `%s` deleted' % branchname) except pygit2.GitError, err: APP.logger.exception(err) flask.flash('Could not delete `%s`' % branchname, '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 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_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 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 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 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 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 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 change_ref_head(repo, username=None): """ Change HEAD reference """ 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') repopath = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(repopath) branches = repo_obj.listall_branches() form = pagure.forms.DefaultBranchForm(branches=branches) if form.validate_on_submit(): branchname = form.branches.data try: reference = repo_obj.lookup_reference('refs/heads/%s' % branchname).resolve() repo_obj.set_head(reference.name) flask.flash('Default branch updated to %s' % branchname) except Exception as err: # pragma: no cover APP.logger.exception(err) return flask.redirect( flask.url_for('view_settings', username=username, repo=repo.name))
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 request_pulls(repo, username=None): """ Request pulling the changes from the fork into the project. """ status = flask.request.args.get('status', 'Open') assignee = flask.request.args.get('assignee', None) author = flask.request.args.get('author', None) 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') if str(status).lower() in ['false', '0']: status = False if str(status).lower() in ['true', '1', 'open']: requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=True, assignee=assignee, author=author) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=False, assignee=assignee, author=author, count=True) else: requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, assignee=assignee, author=author, status=status) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=True, assignee=assignee, author=author, count=True) return flask.render_template( 'requests.html', select='requests', repo=repo, username=username, requests=requests, oth_requests=oth_requests, status=status, assignee=assignee, author=author, repo_admin=is_repo_admin(repo), )
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 view_issue(repo, issueid, username=None): """ List all issues associated to a repo """ 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 issue.private and not is_repo_admin(repo) \ and (not authenticated() or not issue.user.user == flask.g.fas_user.username): flask.abort( 403, 'This issue is private and you are not allowed to view it') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) status = pagure.lib.get_issue_statuses(SESSION) form = pagure.forms.UpdateIssueForm( status=status, priorities=repo.priorities) form.status.data = issue.status form.priority.data = str(issue.priority) tag_list = pagure.lib.get_tags_of_project(SESSION, repo) return flask.render_template( 'issue.html', select='issues', repo=repo, username=username, repo_obj=repo_obj, tag_list=tag_list, issue=issue, issueid=issueid, form=form, repo_admin=is_repo_admin(repo), )
def view_issue(repo, issueid, username=None): """ List all issues associated to a repo """ 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 issue.private and not is_repo_admin(repo) \ and (not authenticated() or not issue.user.user == flask.g.fas_user.username): flask.abort( 403, 'This issue is private and you are not allowed to view it') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) status = pagure.lib.get_issue_statuses(SESSION) form = pagure.forms.UpdateIssueForm(status=status, priorities=repo.priorities) form.status.data = issue.status form.priority.data = str(issue.priority) tag_list = pagure.lib.get_tags_of_project(SESSION, repo) return flask.render_template( 'issue.html', select='issues', repo=repo, username=username, repo_obj=repo_obj, tag_list=tag_list, issue=issue, issueid=issueid, form=form, repo_admin=is_repo_admin(repo), )
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 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 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 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 request_pulls(repo, username=None): """ Request pulling the changes from the fork into the project. """ status = flask.request.args.get('status', 'Open') assignee = flask.request.args.get('assignee', None) author = flask.request.args.get('author', None) 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') if str(status).lower() in ['false', '0']: status = False if str(status).lower() in ['true', '1', 'open']: requests = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, status=True, assignee=assignee, author=author) oth_requests = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, status=False, assignee=assignee, author=author, count=True) else: requests = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, assignee=assignee, author=author, status=status) oth_requests = pagure.lib.search_pull_requests(SESSION, project_id=repo.id, status=True, assignee=assignee, author=author, count=True) return flask.render_template( 'requests.html', select='requests', repo=repo, username=username, requests=requests, oth_requests=oth_requests, status=status, assignee=assignee, author=author, repo_admin=is_repo_admin(repo), )
def view_forks(repo, username=None): """ Presents all the forks of the project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, "Project not found") return flask.render_template( "forks.html", select="forks", username=username, repo=repo, repo_admin=is_repo_admin(repo) )
def request_pulls(repo, username=None): """ Request pulling the changes from the fork into the project. """ status = flask.request.args.get("status", "Open") assignee = flask.request.args.get("assignee", None) author = flask.request.args.get("author", None) 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") if str(status).lower() in ["false", "0"]: status = False if str(status).lower() in ["true", "1", "open"]: requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=True, assignee=assignee, author=author ) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=False, assignee=assignee, author=author, count=True ) else: requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, assignee=assignee, author=author, status=status ) oth_requests = pagure.lib.search_pull_requests( SESSION, project_id=repo.id, status=True, assignee=assignee, author=author, count=True ) reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) if not repo_obj.is_empty and not repo_obj.head_is_unborn: head = repo_obj.head.shorthand else: head = "master" return flask.render_template( "requests.html", select="requests", repo=repo, username=username, requests=requests, oth_requests=oth_requests, status=status, assignee=assignee, author=author, repo_admin=is_repo_admin(repo), form=pagure.forms.ConfirmationForm(), head=head, )
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 view_tree(repo, identifier=None, username=None): """ Render the tree of the repo """ repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: flask.abort(404, 'Project not found') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) branchname = None content = None output_type = None commit = None if not repo_obj.is_empty: if identifier in repo_obj.listall_branches(): branchname = identifier branch = repo_obj.lookup_branch(identifier) commit = branch.get_object() else: try: commit = repo_obj.get(identifier) branchname = identifier except (ValueError, TypeError): # If it's not a commit id then it's part of the filename if 'master' in repo_obj.listall_branches(): commit = repo_obj[repo_obj.head.target] branchname = 'master' # If we're arriving here from the release page, we may have a Tag # where we expected a commit, in this case, get the actual commit if isinstance(commit, pygit2.Tag): commit = commit.get_object() if commit: content = sorted(commit.tree, key=lambda x: x.filemode) output_type = 'tree' return flask.render_template( 'file.html', select='tree', repo_obj=repo_obj, origin='view_tree', repo=repo, username=username, branchname=branchname, branches=sorted(repo_obj.listall_branches()), filename='', content=content, output_type=output_type, repo_admin=is_repo_admin(repo), )
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 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_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 view_tree(repo, identifier=None, username=None): """ Render the tree of the repo """ repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: flask.abort(404, 'Project not found') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) branchname = None content = None output_type = None commit = None if not repo_obj.is_empty: if identifier in repo_obj.listall_branches(): branchname = identifier branch = repo_obj.lookup_branch(identifier) commit = branch.get_object() else: try: commit = repo_obj.get(identifier) branchname = identifier except (ValueError, TypeError): # If it's not a commit id then it's part of the filename if 'master' in repo_obj.listall_branches(): commit = repo_obj[repo_obj.head.target] branchname = 'master' # If we're arriving here from the release page, we may have a Tag # where we expected a commit, in this case, get the actual commit if isinstance(commit, pygit2.Tag): commit = commit.get_object() if commit: content = sorted(commit.tree, key=lambda x: x.filemode) output_type = 'tree' return flask.render_template( 'file.html', select='tree', repo_obj=repo_obj, repo=repo, username=username, branchname=branchname, filename='', content=content, output_type=output_type, repo_admin=is_repo_admin(repo), )
def merge_request_pull(repo, requestid, username=None): """ Request pulling the changes from the fork into the project. """ form = pagure.forms.ConfirmationForm() if not form.validate_on_submit(): flask.flash("Invalid input submitted", "error") return flask.redirect(flask.url_for("request_pull", repo=repo, requestid=requestid, username=username)) 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 not is_repo_admin(repo): flask.abort(403, "You are not allowed to merge pull-request for this project") if repo.settings.get("Only_assignee_can_merge_pull-request", False): if not request.assignee: flask.flash("This request must be assigned to be merged", "error") return flask.redirect(flask.url_for("request_pull", username=username, repo=repo.name, requestid=requestid)) if request.assignee.username != flask.g.fas_user.username: flask.flash("Only the assignee can merge this review", "error") return flask.redirect(flask.url_for("request_pull", username=username, repo=repo.name, requestid=requestid)) threshold = repo.settings.get("Minimum_score_to_merge_pull-request", -1) if threshold > 0 and int(request.score) < int(threshold): flask.flash("This request does not have the minimum review score necessary " "to be merged", "error") return flask.redirect(flask.url_for("request_pull", username=username, repo=repo.name, requestid=requestid)) try: message = pagure.lib.git.merge_pull_request( SESSION, request, flask.g.fas_user.username, APP.config["REQUESTS_FOLDER"] ) flask.flash(message) except pygit2.GitError as err: flask.flash(str(err.message), "error") return flask.redirect(flask.url_for("request_pull", repo=repo.name, requestid=requestid, username=username)) except pagure.exceptions.PagureException as err: flask.flash(str(err), "error") return flask.redirect(flask.url_for("request_pull", repo=repo.name, requestid=requestid, username=username)) 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 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))
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 view_forks(repo, username=None): """ Presents all the forks of the project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') return flask.render_template( 'forks.html', select='forks', username=username, repo=repo, repo_admin=is_repo_admin(repo), )
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 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))
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 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 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 view_tags(repo, username=None): """ Presents all the tags of the project. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if not repo: flask.abort(404, 'Project not found') tags = pagure.lib.git.get_git_tags_objects(repo) return flask.render_template( 'tags.html', select='tags', username=username, repo=repo, tags=tags, repo_admin=is_repo_admin(repo), )
def new_release(repo, username=None): """ Upload a new release. """ if not APP.config.get('UPLOAD_FOLDER_PATH') \ and not APP.config.get('UPLOAD_FOLDER'): flask.abort(404) 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.UploadFileForm() if form.validate_on_submit(): for filestream in flask.request.files.getlist('filestream'): filename = werkzeug.secure_filename(filestream.filename) try: folder = os.path.join( APP.config['UPLOAD_FOLDER_PATH'], werkzeug.secure_filename(repo.fullname)) if not os.path.exists(folder): os.mkdir(folder) filestream.save(os.path.join(folder, filename)) flask.flash('File "%s" uploaded' % filename) except Exception as err: # pragma: no cover APP.logger.exception(err) flask.flash('Upload failed', 'error') return flask.redirect( flask.url_for('view_tags', repo=repo.name, username=username)) return flask.render_template( 'new_release.html', select='tags', username=username, repo=repo, form=form, )
def regenerate_git(repo, username=None): """ Regenerate the specified git repo with the content in 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 regenerate the git repos') regenerate = flask.request.form.get('regenerate') if not regenerate or regenerate.lower() not in ['tickets', 'requests']: flask.abort(400, 'You can only regenerate tickest or requests repos') form = pagure.forms.ConfirmationForm() if form.validate_on_submit(): if regenerate.lower() == 'requests': for request in repo.requests: pagure.lib.git.update_git( request, repo=repo, repofolder=APP.config['REQUESTS_FOLDER']) flask.flash('Requests git repo updated') elif regenerate.lower() == 'tickets': for ticket in repo.issues: # Do not store private issues in the git if ticket.private: continue pagure.lib.git.update_git( ticket, repo=repo, repofolder=APP.config['TICKETS_FOLDER']) flask.flash('Tickets git repo updated') return flask.redirect( flask.url_for('.view_settings', repo=repo.name, username=username) )
def remove_tag(repo, username=None): """ Remove the specified tag, associated with the issues, 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 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') 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 as err: # pragma: no cover SESSION.rollback() LOG.error(err) flask.flash('Could not remove tag: %s' % ','.join(tags), 'error') return flask.redirect( flask.url_for('.view_settings', repo=repo.name, username=username))
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) 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() pagure.lib.update_tags( SESSION, repo, tags=[t.strip() for t in form.tags.data.split(',')], username=flask.g.fas_user.username, ticketfolder=None, ) SESSION.add(repo) SESSION.commit() flask.flash('Project updated') except SQLAlchemyError as err: # pragma: no cover SESSION.rollback() flask.flash(str(err), 'error') return flask.redirect( flask.url_for('view_settings', username=username, repo=repo.name))
def view_repo(repo, username=None): """ Front page of a specific repo. """ repo = pagure.lib.get_project(SESSION, repo, user=username) if repo is None: flask.abort(404, 'Project not found') reponame = pagure.get_repo_path(repo) repo_obj = pygit2.Repository(reponame) cnt = 0 last_commits = [] tree = [] if not repo_obj.is_empty: try: for commit in repo_obj.walk(repo_obj.head.target, pygit2.GIT_SORT_TIME): last_commits.append(commit) cnt += 1 if cnt == 3: break tree = sorted(last_commits[0].tree, key=lambda x: x.filemode) except pygit2.GitError: pass readme = None safe = False for i in tree: name, ext = os.path.splitext(i.name) if name == 'README': content = repo_obj[i.oid].data readme, safe = pagure.doc_utils.convert_readme( content, ext, view_file_url=flask.url_for('view_raw_file', username=username, repo=repo.name, identifier='master', filename='')) diff_commits = [] if repo.is_fork: parentname = os.path.join(APP.config['GIT_FOLDER'], repo.parent.path) if repo.parent.is_fork: parentname = os.path.join(APP.config['FORK_FOLDER'], repo.parent.path) else: parentname = os.path.join(APP.config['GIT_FOLDER'], repo.path) orig_repo = pygit2.Repository(parentname) if not repo_obj.is_empty and not orig_repo.is_empty: orig_branch = orig_repo.lookup_branch('master') branch = repo_obj.lookup_branch('master') if orig_branch and branch: master_commits = [ commit.oid.hex for commit in orig_repo.walk( orig_branch.get_object().hex, pygit2.GIT_SORT_TIME) ] repo_commit = repo_obj[branch.get_object().hex] for commit in repo_obj.walk(repo_commit.oid.hex, pygit2.GIT_SORT_TIME): if commit.oid.hex in master_commits: break diff_commits.append(commit.oid.hex) return flask.render_template( 'repo_info.html', select='overview', repo=repo, repo_obj=repo_obj, username=username, readme=readme, safe=safe, branches=sorted(repo_obj.listall_branches()), branchname='master', last_commits=last_commits, tree=tree, diff_commits=diff_commits, repo_admin=is_repo_admin(repo), form=pagure.forms.ConfirmationForm(), )