def report_private_issue(form, public_url): """Report the issue privately. This also allows us to pass in public_url metadata, to be embedded in the issue body. Returns None (so we don't accidentally leak data). """ path = 'repos/{0}'.format(PRIVATE_REPO_URI) milestone = PRIVATE_REPO_MILESTONE form = add_metadata(form, {'public_url': public_url}) formdata = build_formdata(form) # add the milestone number to set formdata['milestone'] = milestone proxy_request('post', path, data=json.dumps(formdata)) return None
def tag_new_public_issue(issue_info): """Set the core actions on new opened issues. When a new issue is opened, we set a couple of things. - Browser label - Priority label - Issue milestone - Any "extra" labels, set from GET params Then Send a GitHub PATCH to set labels and milestone for the issue. PATCH /repos/:owner/:repo/issues/:number { "milestone": 2, "labels": ['Label1', 'Label2'] } """ issue_body = issue_info['body'] issue_number = issue_info['number'] # Grabs the labels already set so they will not be erased # Gets the labels from the body labels = get_issue_labels(issue_body) labels.extend(issue_info['original_labels']) milestone = app.config['STATUSES']['needstriage']['id'] # Preparing the proxy request headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}'.format(PUBLIC_REPO, issue_number) payload_request = {'labels': labels, 'milestone': milestone} proxy_response = proxy_request('patch', path, headers=headers, data=json.dumps(payload_request)) return proxy_response
def new_opened_issue(payload): """Set the core actions on new opened issues. When a new issue is opened, we set a couple of things. - Browser label - Priority label - Issue milestone - Any "extra" labels, set from GET params Then Send a GitHub PATCH to set labels and milestone for the issue. PATCH /repos/:owner/:repo/issues/:number { "milestone": 2, "labels": ['Label1', 'Label2'] } """ issue_body = payload.get('issue')['body'] issue_number = payload.get('issue')['number'] labels = get_issue_labels(issue_body) milestone = app.config['STATUSES']['needstriage']['id'] # Preparing the proxy request headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], issue_number) payload_request = {'labels': labels, 'milestone': milestone} proxy_response = proxy_request('patch', path, headers=headers, data=json.dumps(payload_request)) return proxy_response
def private_issue_moderation(issue_info): """Write the private issue in public. Send a GitHub PATCH to set labels and milestone for the issue. PATCH /repos/:owner/:repo/issues/:number { "title": "a string for the title", "body": "the full body", "labels": ['Label1', 'Label2'], } Milestone should be already set on needstriage we get the destination through the public_url """ payload_request = prepare_accepted_issue(issue_info) public_number = get_public_issue_number(issue_info['public_url']) # Preparing the proxy request headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], public_number) proxy_response = proxy_request(method='patch', path=path, headers=headers, data=json.dumps(payload_request)) return proxy_response
def edit_issue(number): '''XHR endpoint to push back edits to GitHub for a single issue. Note: this is always proxied to allow any logged in user to be able to edit issues. ''' path = 'repos/{0}/{1}'.format(ISSUES_PATH, number) edit = proxy_request('patch', path, data=request.data) return (edit.content, edit.status_code, {'content-type': JSON_MIME})
def report_issue(form, proxy=False): '''Report an issue, as a logged in user or anonymously.''' # /repos/:owner/:repo/issues path = 'repos/{0}'.format(REPO_URI) if proxy: return proxy_request('post', path, data=json.dumps(build_formdata(form))) else: return github.post(path, build_formdata(form))
def report_public_issue(): """Report the issue publicly. Returns a requests.Response object. """ path = 'repos/{0}'.format(REPO_URI) public_data = moderation_template() # We add action-needsmoderation label, so reviewers can filter out public_data['labels'] = ['action-needsmoderation'] return proxy_request('post', path, data=json.dumps(public_data))
def private_issue_rejected(issue_info): """Send a rejected moderation PATCH on the public issue.""" payload_request = prepare_rejected_issue() public_number = get_public_issue_number(issue_info['public_url']) # Preparing the proxy request headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], public_number) proxy_response = proxy_request(method='patch', path=path, headers=headers, data=json.dumps(payload_request)) return proxy_response
def make_request(method, path, payload_request): """Helper method to wrap webcompat.helpers.proxy_request. Throws requests.exceptions.HTTPError for a non-2XX or 3XX response. """ headers = {'Authorization': f'token {app.config["OAUTH_TOKEN"]}'} r = proxy_request(method, path, headers=headers, data=json.dumps(payload_request)) r.raise_for_status() return r
def set_labels(payload, issue_number): """Does a GitHub POST request to set a label for the issue. POST /repos/:owner/:repo/issues/:number/labels ['Label1', 'Label2'] """ headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}/labels'.format(app.config['ISSUES_REPO_URI'], issue_number) return proxy_request('post', path, headers=headers, data=json.dumps(payload))
def set_labels(payload, issue_number): """Does a GitHub POST request to set a label for the issue. POST /repos/:owner/:repo/issues/:number/labels ['Label1', 'Label2'] """ headers = { 'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN']) } path = 'repos/{0}/{1}/labels'.format( app.config['ISSUES_REPO_URI'], issue_number) return proxy_request('post', path, headers=headers, data=json.dumps(payload))
def report_issue(form, proxy=False): '''Report an issue, as a logged in user or anonymously.''' # /repos/:owner/:repo/issues path = 'repos/{0}'.format(REPO_URI) if proxy: # Return a Response object. response = proxy_request('post', path, data=json.dumps(build_formdata(form))) json_response = response.json() else: # Return JSON data as a dict json_response = github.post(path, build_formdata(form)) return json_response
def modify_labels(number): """XHR endpoint to modify issue labels. Sending in an empty array removes them all as well. This method is always proxied because non-repo collabs can't normally edit labels for an issue. """ if g.user: path = 'repos/{0}/{1}/labels'.format(ISSUES_PATH, number) labels = proxy_request('put', path, data=request.data) return (labels.content, labels.status_code, get_response_headers(labels)) else: abort(403)
def update_issue(payload, issue_number): """Send a GitHub PATCH to set labels and milestone for the issue. PATCH /repos/:owner/:repo/issues/:number { "milestone": 2, "labels": ['Label1', 'Label2'] } """ headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], issue_number) return proxy_request('patch', path, headers=headers, data=json.dumps(payload))
def update_issue(payload, issue_number): """Send a GitHub PATCH to set labels and milestone for the issue. PATCH /repos/:owner/:repo/issues/:number { "milestone": 2, "labels": ['Label1', 'Label2'] } """ headers = { 'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN']) } path = 'repos/{0}/{1}'.format(app.config['ISSUES_REPO_URI'], issue_number) return proxy_request('patch', path, headers=headers, data=json.dumps(payload))
def edit_issue(number): '''XHR endpoint to push back edits to GitHub for a single issue. Note: this is always proxied to allow any logged in user to be able to edit issues. ''' path = 'repos/{0}/{1}'.format(ISSUES_PATH, number) # we can only change the state of the issue: closed or open states_list = ['closed', 'open'] patch_data = json.loads(request.data) # check to see if we're trying to change state from/to closed or open # and make sure that's the only thing we're trying to change if patch_data.get('state') in states_list and len(patch_data) == 1: edit = proxy_request('patch', path, data=request.data) return (edit.content, edit.status_code, {'content-type': JSON_MIME}) else: abort(403)
def report_issue(form, proxy=False): """Report an issue, as a logged in user or anonymously.""" # /repos/:owner/:repo/issues path = 'repos/{0}'.format(REPO_URI) submit_type = form.get('submit_type') if proxy and submit_type == 'github-proxy-report': # Return a Response object. response = proxy_request('post', path, data=json.dumps(build_formdata(form))) json_response = response.json() elif (not proxy) and submit_type == 'github-auth-report': # Return JSON data as a dict json_response = github.post(path, build_formdata(form)) else: abort(400) return json_response
def comment_public_uri(issue_info): """Publish a comment on the private issue with the public uri.""" # issue number on private repo number = issue_info['number'] # public issue data public_url = issue_info['public_url'] public_number = get_public_issue_number(public_url) # prepare the payload comment_body = '[Original issue {nb}]({url})'.format(nb=public_number, url=public_url) payload = {'body': comment_body} # Preparing the proxy request headers = {'Authorization': 'token {0}'.format(app.config['OAUTH_TOKEN'])} path = 'repos/{0}/{1}/comments'.format(PRIVATE_REPO, number) proxy_response = proxy_request(method='post', path=path, headers=headers, data=json.dumps(payload)) return proxy_response
def edit_issue(number): """XHR endpoint to push back edits to GitHub for a single issue. - It only allows change of state and change of milestones. - It is always proxied to allow any logged in user to be able to edit issues. Format: {'milestone': 2, 'state': 'open'} """ path = 'repos/{0}/{1}'.format(ISSUES_PATH, number) patch_data = json.loads(request.data) # Create a list of associated milestones id with their mandatory state. STATUSES = app.config['STATUSES'] valid_statuses = [(STATUSES[status]['id'], STATUSES[status]['state']) for status in STATUSES] data_check = (patch_data['milestone'], patch_data['state']) # The PATCH data can only be of length: 2 if data_check in valid_statuses and len(patch_data) == 2: edit = proxy_request('patch', path, data=request.data) return (edit.content, edit.status_code, {'content-type': JSON_MIME}) # Default will be 403 for this route abort(403)