[Tracker-discuss] [issue634] Only link PR to the bpo that is in the PR title, not the body

2017-10-28 Thread Maciej Szulik

Maciej Szulik <solt...@gmail.com> added the comment:

One other option is to give different priorities. For example, if title has 
bpo- we don't look further in the body and assume this is it. But I bet 
people will complain about that approach as well. I doubt there's a golden 
middle way we can satisfy all users.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue634>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue615] Set stage to 'patch review' when a PR is added

2017-08-04 Thread Maciej Szulik

Maciej Szulik added the comment:

> So after http://psf.upfronthosting.co.za/roundup/meta/msg3305 and 
> http://psf.upfronthosting.co.za/roundup/meta/msg3306 I explicitly said "I'll 
> commit it when I get a code review, thanks!" in my earlier comment, and you 
> still did the same thing.

Berker I know, I'm terribly sorry. When I was going through those patches I was 
in a hurry going through tons of emails after my PTO :( I've noticed your 
message about committing this the moment I've pushed changes to the server :(

> I think I should spend my free time elsewhere.

Please, your help here is invaluable :)

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue615>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue635] Information on meta-tracker server migration

2017-08-02 Thread Maciej Szulik

Maciej Szulik added the comment:

I'm back right now and just starting the initial work.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue635>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue463] HTTPS only version for login for this tracker

2017-06-07 Thread Maciej Szulik

Maciej Szulik added the comment:

We're currently working with Mark to migrate bpo to a different server. I'll 
make sure this is fixed along the way.

--
nosy: +maciej.szulik

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue463>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue625] Limit the number of bpo issues linked to a PR

2017-04-05 Thread Maciej Szulik

Maciej Szulik added the comment:

I've personally used multiple issues under single PR (not for python, but in 
general), but that was never than 2 or 3. So completely disabling, or rather 
limiting to 1 is not a good solution. Lowering the limit by half, from 10 to 5, 
seems ok to me.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue625>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue625] Limit the number of bpo issues linked to a PR

2017-04-04 Thread Maciej Szulik

Maciej Szulik added the comment:

Initial patch from Ezio with my addons applied in 
https://hg.python.org/tracker/roundup/rev/51efd8e5b8a8

--
status: in-progress -> testing

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue625>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue625] Limit the number of bpo issues linked to a PR

2017-04-04 Thread Maciej Szulik

Maciej Szulik added the comment:

Updated version with issue comment handled, as well.

--
nosy: +maciej.szulik
status: unread -> in-progress

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue625>
___diff --git a/roundup/github.py b/roundup/github.py
--- a/roundup/github.py
+++ b/roundup/github.py
@@ -20,6 +20,8 @@
 ISSUE_RE = re.compile(r'%sbpo-(?P\d+)' % VERBS, re.I|re.U)
 BRANCH_RE = re.compile(r'(2\.\d|3\.\d|master)', re.I)
 
+ISSUE_LIMIT = 10
+
 COMMENT_TEMPLATE = u"""\
 New changeset {changeset_id} by {author} in branch '{branch}':
 {commit_msg}
@@ -170,6 +172,10 @@
 issue_ids = list(self.db.issue.create(
 title=title.encode('utf-8')))
 prid, title, status = self.get_pr_details()
+# limit to max 10 issues
+if len(issue_ids) > ISSUE_LIMIT:
+logging.info("Limiting links for %s: %s", prid, issue_ids)
+issue_ids = issue_ids[:ISSUE_LIMIT]
 self.handle_action(action, prid, title, status, issue_ids)
 
 def handle_create(self, prid, title, status, issue_ids):
@@ -220,6 +226,16 @@
 else:
 self.handle_create(prid, title, status, [issue_id])
 
+def unique_ordered(self, issue_ids):
+"""
+Helper method returning unique and ordered (how they appear) issue_ids.
+"""
+ids = []
+for id in issue_ids:
+if id not in ids:
+ids.append(id)
+return ids
+
 def handle_action(self, action, prid, title, status, issue_ids):
 raise NotImplementedError
 
@@ -258,7 +274,7 @@
 body = pull_request.get('body', '') or ''  # body can be None
 title_ids = [x[1] for x in ISSUE_RE.findall(title)]
 body_ids = [x[1] for x in ISSUE_RE.findall(body)]
-return list(set(title_ids + body_ids))
+return self.unique_ordered(title_ids + body_ids)
 
 def get_pr_details(self):
 """
@@ -315,7 +331,7 @@
 body = comment.get('body', '')
 title_ids = [x[1] for x in ISSUE_RE.findall(title)]
 body_ids = [x[1] for x in ISSUE_RE.findall(body)]
-return list(set(title_ids + body_ids))
+return self.unique_ordered(title_ids + body_ids)
 
 def get_pr_details(self):
 """
diff --git a/test/data/issuecommentevent1.txt b/test/data/issuecommentevent1.txt
new file mode 100644
--- /dev/null
+++ b/test/data/issuecommentevent1.txt
@@ -0,0 +1,11 @@
+POST /python-dev/pull_request HTTP/1.1
+Host: 2f3784dc.ngrok.io
+Accept: */*
+User-Agent: GitHub-Hookshot/9667e0c
+X-GitHub-Event: issue_comment
+X-GitHub-Delivery: c6d12700-270e-11e6-86c5-8e9c9c898175
+content-type: application/json
+X-Hub-Signature: sha1=aee43a9a43bb58292f782a27cad0396f890226e3
+Content-Length: 8525
+
+{"action":"created","issue":{"url":"https://api.github.com/repos/python/cpython/issues/1","repository_url":"https://api.github.com/repos/python/cpython","labels_url":"https://api.github.com/repos/python/cpython/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/python/cpython/issues/1/comments","events_url":"https://api.github.com/repos/python/cpython/issues/1/events","html_url":"https://github.com/python/cpython/pull/1","id":156471938,"number":1,"title":"bpo-1","user":{"login":"AnishShah","id":3175743,"avatar_url":"https://avatars.githubusercontent.com/u/3175743?v=3","gravatar_id":"","url":"https://api.github.com/users/AnishShah","html_url":"https://github.com/AnishShah","followers_url":"https://api.github.com/users/AnishShah/followers","following_url":"https://api.github.com/users/AnishShah/following{/other_user}","gists_url":"https://api.github.com/users/AnishShah/gists{/gist_id}","starred_url":"https://api.github.com/users/AnishShah/starred{/owner}{/rep
 
o}","subscriptions_url":"https://api.github.com/users/AnishShah/subscriptions","organizations_url":"https://api.github.com/users/AnishShah/orgs","repos_url":"https://api.github.com/users/AnishShah/repos","events_url":"https://api.github.com/users/AnishShah/events{/privacy}","received_events_url":"https://api.github.com/users/AnishShah/received_events","type":"User","site_admin":false},"labels":[],"state":"closed",&q

[Tracker-discuss] [issue619] Use author's name if committer is set to GitHub on commit notifications

2017-03-24 Thread Maciej Szulik

Maciej Szulik added the comment:

Sorry Berker, didn't want to offend you by doing so.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue619>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue619] Use author's name if committer is set to GitHub on commit notifications

2017-03-23 Thread Maciej Szulik

Maciej Szulik added the comment:

Updated patch with my changes applied here: 

https://hg.python.org/tracker/roundup/rev/6d6954a7b401

--
status: chatting -> resolved

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue619>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue613] Commits notifications don't show up on bugs.p.o

2017-03-23 Thread Maciej Szulik

Maciej Szulik added the comment:

I've added more logging: 

https://hg.python.org/tracker/roundup/rev/b5c6f372b227

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue613>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue619] Use author's name if committer is set to GitHub on commit notifications

2017-03-17 Thread Maciej Szulik

Maciej Szulik added the comment:

I've created alternate solution in this patch: 
http://psf.upfronthosting.co.za/roundup/meta/file459/issue613.patch

--
nosy: +maciej.szulik

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue619>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue613] Commits notifications don't show up on bugs.p.o

2017-03-17 Thread Maciej Szulik

Maciej Szulik added the comment:

Brett, can I ask you to send me directly (or attach here) some of those 
rejected requests? Based on the current one I don't see anything suspicious, 
but maybe I'm overlooking something...

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue613>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue613] Commits notifications don't show up on bugs.p.o

2017-03-17 Thread Maciej Szulik

Maciej Szulik added the comment:

Brett, the most worrying thing is missing `X-Hub-Signature` header in the 
request from http://psf.upfronthosting.co.za/roundup/meta/msg3281. I've 
uploaded tweaked patch from Berker but I've mostly switched to logging, we 
don't want to simplify hacking our tracker, too much returning exact 
information what went wrong. Most importantly I've added X-GitHub-Delivery, so 
it's easier to track the actual requests on GH. Additionally I've fixed author 
matching if committer is GitHub, we ignore that information (this happens when 
using GH UI).

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue613>
___diff --git a/roundup/github.py b/roundup/github.py
--- a/roundup/github.py
+++ b/roundup/github.py
@@ -46,8 +46,11 @@
 self.extract()
 except (Unauthorised, MethodNotAllowed,
 UnsupportedMediaType, Reject) as err:
+logging.error('X-GitHub-Delivery: %s', self.get_delivery())
+logging.error(err, exc_info=True)
 raise
 except Exception as err:
+logging.error('X-GitHub-Delivery: %s', self.get_delivery())
 logging.error(err, exc_info=True)
 raise Reject()
 
@@ -70,8 +73,11 @@
 handler.dispatch()
 elif event == 'push':
 data = json.loads(self.form.value)
-handler = Push(self.db, data)
+handler = Push(self.db, data, self.get_delivery())
 handler.dispatch()
+else:
+logging.error('X-GitHub-Delivery: %s', self.get_delivery())
+logging.error('Unknown event %s', event)
 
 def validate_webhook_secret(self):
 """
@@ -102,6 +108,8 @@
 if content_type != 'application/json':
 raise UnsupportedMediaType()
 if self.get_event() is None:
+logging.error('X-GitHub-Delivery: %s', self.get_delivery())
+logging.error('no X-GitHub-Event header found in the request 
headers')
 raise Reject()
 
 def get_event(self):
@@ -110,6 +118,12 @@
 """
 return self.request.headers.get('X-GitHub-Event', None)
 
+def get_delivery(self):
+"""
+Extracts GitHub delivery id.
+"""
+return self.request.headers.get('X-GitHub-Delivery', None)
+
 
 class Event(object):
 """
@@ -328,6 +342,11 @@
 Class responsible for handling push events.
 """
 
+def __init__(self, db, data, delivery):
+self.db = db
+self.data = data
+self.delivery = delivery
+
 def get_github_username(self):
 """
 Extract GitHub username from a push event.
@@ -342,7 +361,7 @@
 commits = self.data.get('commits', [])
 ref = self.data.get('ref', 'refs/heads/master')
 # messages dictionary maps issue number to a tuple containing
-# the message to be posted as a comment an boolean flag informing
+# the message to be posted as a comment and a boolean flag informing
 # if the issue should be 'closed'
 messages = {}
 # extract commit messages
@@ -357,6 +376,7 @@
 # close the issue
 messages[issue_id] = (curr_msg + u'\n' + msg, curr_close or 
close)
 if not messages:
+logging.error('zero messages created for %s', self.delivery)
 return
 for issue_id, (msg, close) in messages.iteritems():
 # add comments to appropriate issues...
@@ -398,9 +418,14 @@
 if data['issue_id'] in messages:
 continue
 close = bool(data.get('verb'))
-author=commit.get('author', {}).get('name', '')
-committer=commit.get('committer', {}).get('name', '')
+author = commit.get('author', {}).get('name', '')
+committer = commit.get('committer', {}).get('name', '')
+# committer should not be GitHub bot, fallback to original author
+# in these cases, this happens when using GitHub UI
+if committer == "GitHub":
+committer = author
 author_line = committer
+# check if the author and committer are different persons
 if author != committer:
 author_line = u"{} ({})".format(committer, author)
 messages[data['issue_id']] = (COMMENT_TEMPLATE.format(
diff --git a/test/data/pushevent6.txt b/test/data/pushevent6.txt
new file mode 100644
--- /dev/null
+++ b/test/data/pushevent6.txt
@@ -0,0 +1,11 @@
+POST /python-dev/pull_request HTTP/1.1
+Host: 3ab1787e.ngrok.io
+Accept: */*
+User-Agent: GitHub-Hookshot/6b02022
+X-GitHub-Delivery: 2076d100-0054-11e7-9584-1096a01ee5f0
+X

[Tracker-discuss] [issue614] Duplicate commit message on branch merge

2017-02-20 Thread Maciej Szulik

Maciej Szulik added the comment:

Anish thanks! I had to tweak the patch a bit (just tests), since you forgot to 
include pushevent5.txt, but I've created it manually :)

The change was pushed in https://hg.python.org/tracker/roundup/rev/3050f361cf3e

--
status: chatting -> testing

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue614>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue613] Commits notifications don't show up on bugs.p.o

2017-02-15 Thread Maciej Szulik

Maciej Szulik added the comment:

Yeah, as soon as I fix the local testing of those things I'll get back to 
having 4-digit requirement for bpo issues, that should additionally save us 
from unnecessary errors, like the one above.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue613>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue611] Update issue with a commit information

2017-01-30 Thread Maciej Szulik

Maciej Szulik added the comment:

Committed in https://hg.python.org/tracker/roundup/rev/bcf18f92716d.

--
status: in-progress -> testing

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue611>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue611] Update issue with a commit information

2017-01-28 Thread Maciej Szulik

Maciej Szulik added the comment:

Patch updated and most importantly tested with github. Comments inline below:

> I think you'll end up with a user_id in the >1 case and a list (assuming 
> filter returns a list) in the <1 case.  At the end you take the first element 
> of the list, which is 
> correct only for the <1 case (unless filters returns a single id, but in that 
> case I'm not sure what the [0] at the end is for).  I would also suggest to 
> user user_ids and 
> user_id to distinguish the list from the single id.

> Ezio seems to be right about user_id and getting a list or a name depending 
> on which branch is taken based on the line that sets user_id initially. It 
> also might be clearer if > you check for `not len(user_id)` or `len(user_id) 
> == 0` instead of `len(user_id) < 1`.

Yeah, filter returns list always, I've updated the patch accordingly.


> I would rename set_current_user() to something more explicit, or, if the only 
> purpose of this method is to affect the author=self.db.getuid(), perhaps 
> remove the method and use 
> a module/class-level constant.  The same constant could also be used in the 
> snippet I pasted above to avoid duplication.

I've changed it to set_roundup_user, not sure what kind of constant you were 
talking about.


> Does produces the correct output in the history at the bottom of the issue? 
> (i.e. does it show "set  messages: +msgXXX" with only the new message, rather 
> than the whole list 
> of messages?)

Yes, it's 'messages +msgX', as expected.


> I would move the .encode('utf-8') from dispatch() to handle_action() (add it 
> to the line "'branch': branch.encode('utf-8'),").

Done


> The commit_id variable in handle_action() is unused.

Removed


> Any reason why you used Template() instead of a simply using format() (or %)? 
>  You might also be able to get rid of all those encode if you use format().

Laziness, I just copy what I got from hglookup.py ;) Changed to format.


> github/roundup should be capitalized properly in the docstrings.  The 
> docstring for handle_action() could be a bit more explicit :)

Done

> And thanks for handling the case when there's no match. I wouldn't be 
> surprised if people don't sign the CLA but still get a PR merged that e.g. 
> fixes a single line of the 
> documentation.

N/p :)

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue611>
___diff --git a/roundup/github.py b/roundup/github.py
--- a/roundup/github.py
+++ b/roundup/github.py
@@ -1,5 +1,3 @@
-from roundup.exceptions import *
-
 import hashlib
 import hmac
 import json
@@ -7,6 +5,8 @@
 import os
 import logging
 
+from roundup.exceptions import Unauthorised, MethodNotAllowed, \
+UnsupportedMediaType, Reject
 
 if hasattr(hmac, 'compare_digest'):
 compare_digest = hmac.compare_digest
@@ -14,8 +14,15 @@
 def compare_digest(a, b):
 return a == b
 
-url_re = re.compile(r'https://github.com/python/cpython/pull/(?P\d+)')
-issue_id_re = re.compile(r'bpo\s*(\d+)', re.I)
+URL_RE = re.compile(r'https://github.com/python/cpython/pull/(?P\d+)')
+ISSUE_GH_RE = re.compile(r'bpo\s*(\d+)', re.I)
+ISSUE_BPO_RE = re.compile(r'(#|issue|bug)\s*(?P\d+)', re.I)
+
+COMMENT_TEMPLATE = """\
+New changeset {changeset_id} by {author} in branch '{branch}':
+{commit_msg}
+{changeset_url}
+"""
 
 class GitHubHandler:
 """
@@ -59,6 +66,10 @@
 data = json.loads(self.form.value)
 handler = IssueComment(self.db, data)
 handler.dispatch()
+elif event == 'push':
+data = json.loads(self.form.value)
+handler = Push(self.db, data)
+handler.dispatch()
 
 def validate_webhook_secret(self):
 """
@@ -93,7 +104,7 @@
 
 def get_event(self):
 """
-Extracts github event from header field.
+Extracts GitHub event from header field.
 """
 return self.request.headers.get('X-GitHub-Event', None)
 
@@ -107,24 +118,27 @@
 self.db = db
 self.data = data
 
-def set_current_user(self):
+def set_roundup_user(self):
 """
-Helper method used for setting current user for roundup, based
-on the information from github about event author.
+Helper method used for setting the current user for Roundup, based
+on the information from GitHub about event author.
 """
 github_username = self.get_github_username()
-user_id = self.db.user.filter(None, {'github': github_username})
-# TODO set bpobot as userid when none is found
-if le

[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue586, issue589)

2017-01-12 Thread Maciej Szulik

Maciej Szulik added the comment:

Done in https://hg.python.org/tracker/roundup/rev/719a007ca12d and 
https://hg.python.org/tracker/python-dev/rev/74d7030f0eef
Thanks everyone for help!

--
status: in-progress -> testing

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue610] Hyperlink git hashes of 10 or 11 characters

2016-12-22 Thread Maciej Szulik

Maciej Szulik added the comment:

Still LGTM.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue610>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue610] Hyperlink git hashes of 10 or 11 characters

2016-12-22 Thread Maciej Szulik

Maciej Szulik added the comment:

SGTM

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue610>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue610] Hyperlink git hashes of 10 or 11 characters

2016-12-21 Thread Maciej Szulik

Maciej Szulik added the comment:

LGTM, Ezio or David mind merging this?

--
nosy: +ezio.melotti, maciej.szulik, r.david.murray
status: unread -> chatting

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue610>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)

2016-12-06 Thread Maciej Szulik

Maciej Szulik added the comment:

I'm uploading the current version of the patch, it's still not fully reviewed, 
I've left a few TODO's here and there for what should be double checked.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
@@ -22,6 +22,7 @@
 from roundup.mailer import Mailer, MessageSendError, encode_quopri
 from roundup.cgi import accept_language
 from roundup import xmlrpc
+from roundup.pull_request import GitHubHandler
 
 from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \
 get_cookie_date
@@ -378,6 +379,8 @@
 try:
 if self.path == 'xmlrpc':
 self.handle_xmlrpc()
+elif self.path == 'pull_request':
+self.handle_pull_request()
 else:
 self.inner_main()
 finally:
@@ -385,6 +388,34 @@
 self.db.close()
 
 
+def handle_pull_request(self):
+# Set the charset and language, since other parts of
+# Roundup may depend upon that.
+self.determine_charset()
+self.determine_language()
+# Open the database as the correct user.
+self.determine_user()
+self.check_anonymous_access()
+
+try:
+handler = GitHubHandler(self)
+handler.dispatch()
+except Unauthorised, message:
+self.response_code = 403
+self.write(message)
+except UnsupportedMediaType, message:
+self.response_code = 415
+self.write(message)
+except MethodNotAllowed, message:
+self.response_code = 405
+self.write(message)
+except Reject, message:
+self.response_code = 400
+self.write(message)
+else:
+self.write("Done!")
+
+
 def handle_xmlrpc(self):
 if self.env.get('CONTENT_TYPE') != 'text/xml':
 self.write("This is the endpoint of Roundup https://github.com/python/cpython/pull/(?P\d+)')
+issue_re = re.compile(r'fixes\s+(?:bpo(\d+))(?:,\s*bpo(\d+))*', re.I)
+issue_id_re = re.compile(r'bpo(\d+)', re.I)
+
+class GitHubHandler:
+"""
+GitHubHandler is responsible for parsing and serving all events coming
+from GitHub. Details about GitHub webhooks can be found at:
+https://developer.github.com/webhooks/
+"""
+
+def __init__(self, client):
+self.db = client.db
+self.request = client.request
+self.form = client.form
+self.env = client.env
+
+def dispatch(self):
+try:
+self.verify_request()
+self.validate_webhook_secret()
+self.extract()
+except Unauthorised, message:
+logging.error(message, exc_info=True)
+raise
+except MethodNotAllowed, message:
+logging.error(message, exc_info=True)
+raise
+except UnsupportedMediaType, message:
+logging.error(message, exc_info=True)
+raise
+except Exception, message:
+logging.error(message, exc_info=True)
+raise Reject('Invalid Request')
+
+def extract(self):
+"""
+This method is responsible for extracting information from GitHub event
+and decide what to do with it more. Currently it knows how to handle
+pull requests and comments.
+"""
+event = self.get_event()
+if event not in ('pull_request', 'issue_comment'):
+raise Reject('Unkown X-GitHub-Event {}'.format(event))
+data = json.loads(self.form.value)
+if event == 'pull_request':
+handler = PullRequest(self.db, data)
+handler.dispatch()
+# TODO: verify if this is about gh issues or pr comments, not sure?
+elif event == 'issue_comment':
+handler = IssueComment(self.db, data)
+handler.dispatch()
+
+def validate_webhook_secret(self):
+"""
+Validates request signature against SECRET_KEY environment variable.
+This verification is based on HMAC hex digest calculated from the sent
+payload. The value of SECRET_KEY should be exactly the same as the one
+configured in GitHub webhook secret field.
+"""
+key = os.environ['SECRET_KEY']
+data = self.form.value
+signature = 'sha1=' + hmac.new(key, data,
+   hashlib.sha1).hexdigest()
+header_signature = self.request.headers.get('X-Hub-Signature', '')
+if not compare_digest(signature, header_signature):
+rai

[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-27 Thread Maciej Szulik

Maciej Szulik added the comment:

Uploading fixed patch with Ezio's changes.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___diff --git a/detectors/pull_request.py b/detectors/pull_request.py
new file mode 100644
--- /dev/null
+++ b/detectors/pull_request.py
@@ -0,0 +1,69 @@
+# Auditor for GitHub URLs
+# Check if it is a valid GitHub Pull Request URL and extract PR number
+
+import re
+
+
+repo_number_re = re.compile(r'^#?(?P\d+)$')
+url_re = 
re.compile(r'(https?:\\)?github\.com/python/cpython/pull/(?P\d+)')
+
+def validate_pr_uniqueness(db, cl, nodeid, newvalues):
+"""
+Verifies if newly added PR isn't already attached to an issue.
+This process is a 2-level action, first a pull_request object is created, 
which
+goes through validate_pr_number to extract the PR number in case an URL is 
passed,
+only then we validate PR uniqueness within a single issue.
+"""
+newprs = set(newvalues.get('pull_requests',()))
+if not newprs:
+return
+oldprs = set()
+if nodeid:
+# if this is an existing issue, get the list of existing prs
+oldprs = set(db.issue.get(nodeid, 'pull_requests'))
+newprs -= oldprs
+try:
+# get the newly created PR number
+number = db.pull_request.get(newprs.pop(), 'number')
+except KeyError:
+return
+# and compare with those already attached to an issue
+for oldpr in oldprs:
+oldnumber = db.pull_request.get(oldpr, 'number')
+if number == oldnumber:
+raise ValueError("GitHub PR already added to issue")
+
+def validate_pr_number(db, cl, nodeid, newvalues):
+try:
+number = extract_number(newvalues['number'])
+if number:
+newvalues['number'] = number
+except KeyError:
+pass
+
+def extract_number(input):
+"""
+Extracts PR number from the following forms:
+- #number
+- number
+- full url
+and returns its number.
+"""
+# try matching just the number
+repo_number_match = repo_number_re.search(input)
+if repo_number_match:
+return repo_number_match.group('number')
+# fallback to parsing the entire url
+url_match = url_re.search(input)
+if url_match:
+return url_match.group('number')
+# if nothing else raise error
+raise ValueError("Unknown PR format, acceptable formats are: "
+ "full github URL, #pr_number, pr_number")
+
+
+def init(db):
+db.issue.audit('create', validate_pr_uniqueness)
+db.issue.audit('set', validate_pr_uniqueness)
+db.pull_request.audit('create', validate_pr_number)
+db.pull_request.audit('set', validate_pr_number)
diff --git a/extensions/pull_request.py b/extensions/pull_request.py
new file mode 100644
--- /dev/null
+++ b/extensions/pull_request.py
@@ -0,0 +1,11 @@
+
+baseurl = 'https://github.com/python/cpython/'
+
+def get_pr_url(pr):
+"""Transforms pr into a working URL."""
+return 'PR %s' % (baseurl, pr.number, 
pr.title, pr.number)
+
+
+def init(instance):
+instance.registerUtil('get_pr_url', get_pr_url)
+
diff --git a/html/issue.item.html b/html/issue.item.html
--- a/html/issue.item.html
+++ b/html/issue.item.html
@@ -220,6 +220,14 @@
  
 
 
+
+ GitHub PR:
+ 
+  
+  
+ 
+
+
 
 
 
@@ -273,6 +281,34 @@
  
 
 
+
+ Pull Requests
+ 
+  URL
+  Linked
+  Edit
+ 
+ 
+  
+  
+   creator's name,
+   creation date
+  
+  
+edit
+  
+  
+
+ 
+ 
+ 
+
+  
+ 
+
+
 
@@ -284,7 +320,7 @@
  once it's done your name will have a * next to it.)
 
 
- Repositories containing patches
+ Repositories containing patches
  
   

+Pull Request - 
+Pull Request
+
+
+
+
+ You are not allowed to view this page.
+
+
+ Please login with your username and password.
+
+
+
+
+ 
+  URL
+  
+ 
+ 
+  Title
+  
+ 
+
+ 
+  
+   
+   
+   
+  
+  submit button here
+ 
+
+
+
+
+   File has been classified as spam.
+
+
+
+
+
+This PR is linked to :
+   
+
+
+
+This PR has been unlinked from :
+   
+
+
+
+
+
+
+
+
+
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -173,6 +173,12 @@
patchbranch=String(),
)
 
+pull_request = Class(db, "pull_request",
+ number=String(),
+ title=String(),
+ )
+pull_request.setlabelprop('id')
+
 # IssueClass automatically gets these properties in addition to the Class ones:
 #   title = String()
 #   messages = Multilink("msg")
@@ -194,7 +200,8 @@
stage=Link('stage'),
nosy_count=Number(),
message_count

[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-24 Thread Maciej Szulik

Maciej Szulik added the comment:

The alternate version with pr number and repository fields.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___diff --git a/detectors/pull_request.py b/detectors/pull_request.py
new file mode 100644
--- /dev/null
+++ b/detectors/pull_request.py
@@ -0,0 +1,79 @@
+# Auditor for GitHub URLs
+# Check if it is a valid GitHub Pull Request URL and extract PR number
+
+import re
+
+
+just_number_re = re.compile(r'\d+')
+repo_number_re = re.compile(r'(?P\w+)?#(?P\d+)')
+url_re = re.compile(r'github\.com/cpython/(?P\w+)/(?P\d+)')
+
+default_repository = 'python'
+
+def validate_pull_requests(db, cl, nodeid, newvalues):
+newprs = set(newvalues.get('pull_requests',()))
+if not newprs:
+return
+oldprs = set()
+if nodeid:
+oldprs = set(db.issue.get(nodeid, 'pull_requests'))
+newprs -= oldprs
+try:
+prid = newprs.pop()
+except KeyError:
+return
+repository = db.pull_request.get(prid, 'repository')
+number = db.pull_request.get(prid, 'number')
+for oldpr in oldprs:
+oldrepository = db.pull_request.get(oldpr, 'repository')
+oldnumber = db.pull_request.get(oldpr, 'number')
+if repository == oldrepository and number == oldnumber:
+raise ValueError("GitHub PR already added to issue")
+
+def validate_url(db, cl, nodeid, newvalues):
+try:
+repository, number = parse_url(newvalues['url'])
+if repository and number:
+newvalues['repository'] = repository
+newvalues['number'] = number
+del newvalues['url']
+except KeyError:
+pass
+try:
+newvalues['title']
+except KeyError:
+newvalues['title'] = ''
+
+def parse_url(url):
+"""
+Transform following forms:
+- full url
+- repository#number
+- #number
+- number
+and returns tuple repository name and pull request number.
+"""
+# first try just the number
+just_number_match = just_number_re.search(url)
+if just_number_match:
+return default_repository, just_number_match.group()
+# then try repository#number (repository part can be omitted here)
+repo_number_match = repo_number_re.search(url)
+if repo_number_match:
+repository = repo_number_match.group('repository')
+if repository is None:
+repository = default_repository
+return repository, repo_number_match.group('number')
+# finally parse the url
+url_match = url_re.search(url)
+if url_match:
+return url_match.group('repository'), url_match.group('number')
+# if nothing else raise error
+raise ValueError("Unknown PR format, acceptable formats are: full github 
URL, repository#pr_number, #pr_number, pr_number")
+
+
+def init(db):
+db.issue.audit('create', validate_pull_requests)
+db.issue.audit('set', validate_pull_requests)
+db.pull_request.audit('create', validate_url)
+db.pull_request.audit('set', validate_url)
diff --git a/extensions/pull_request.py b/extensions/pull_request.py
new file mode 100644
--- /dev/null
+++ b/extensions/pull_request.py
@@ -0,0 +1,9 @@
+
+def get_pr_url(repository, number):
+"""Transforms pull_request object into working URL."""
+baseurl = 'https://github.com/cpython/'
+return "%s%s/%d" % (baseurl, repository, number)
+
+def init(instance):
+instance.registerUtil('get_pr_url', get_pr_url)
+
diff --git a/html/issue.item.html b/html/issue.item.html
--- a/html/issue.item.html
+++ b/html/issue.item.html
@@ -220,6 +220,14 @@
  
 
 
+
+ GitHub PR:
+ 
+  
+  
+ 
+
+
 
 
 
@@ -273,6 +281,31 @@
  
 
 
+
+ Pull Requests
+ 
+  URL
+  Linked
+  Edit
+ 
+ 
+  
+   
+URL
+   
+  
+  
+   creator's name,
+   creation date
+  
+  
+edit
+  
+ 
+
+
 
@@ -284,7 +317,7 @@
  once it's done your name will have a * next to it.)
 
 
- Repositories containing patches
+ Repositories containing patches
  
   

+Pull Request - 
+Pull Request
+
+
+
+
+ You are not allowed to view this page.
+
+
+ Please login with your username and password.
+
+
+
+
+ 
+  URL
+  
+ 
+ 
+  Title
+  
+ 
+
+ 
+  
+   
+   
+   
+   
+  
+  submit button here
+ 
+
+
+
+
+   File has been classified as spam.
+
+
+
+
+
+This PR is linked to :
+   
+
+
+
+This PR has been unlinked from :
+   
+
+
+
+
+
+
+
+
+
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -173,6 +173,13 @@
patchbranch=String(),
)
 
+pull_request = Class(db, "pull_request",
+ url=String(),
+ repository=String(),
+ n

[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-24 Thread Maciej Szulik

Maciej Szulik added the comment:

I've added slight changes to previous patch, fixing the look of the PRs table 
and the class in hgrepos table header (it had typo, Header vs header).

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___diff --git a/detectors/pull_request.py b/detectors/pull_request.py
new file mode 100644
--- /dev/null
+++ b/detectors/pull_request.py
@@ -0,0 +1,55 @@
+# Auditor for GitHub URLs
+# Check if it is a valid GitHub Pull Request URL and extract PR number
+
+import re
+import urlparse
+
+
+def validate_pull_requests(db, cl, nodeid, newvalues):
+newprs = set(newvalues.get('pull_requests',()))
+oldprs = set()
+if nodeid:
+oldprs = set(db.issue.get(nodeid, 'pull_requests'))
+newprs -= oldprs
+newurl = ''
+for prid in newprs:
+newurl = parse_url(db.pull_request.get(prid, 'url'))
+if newurl != '':
+for prid in oldprs:
+if newurl == db.pull_request.get(prid, 'url'):
+raise ValueError("GitHub PR already added to issue")
+
+def validate_url(db, cl, nodeid, newvalues):
+try:
+newurl = parse_url(newvalues['url'])
+if newurl != '':
+newvalues['url'] = newurl
+except KeyError:
+pass
+try:
+newvalues['title']
+except KeyError:
+newvalues['title'] = ''
+
+def parse_url(url):
+if url == '':
+return
+# TODO: transform following forms:
+# - username/repo#prno
+# - repo/#prno
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme == '':
+url = 'https://' + url
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme not in ('http', 'https'):
+raise ValueError("Invalid URL scheme in GitHub PR")
+if 'github.com' not in parsed_url.netloc or 'pull' not in parsed_url.path:
+raise ValueError("Invalid GitHub PR")
+return parsed_url.geturl().strip('/')
+
+
+def init(db):
+db.issue.audit('create', validate_pull_requests)
+db.issue.audit('set', validate_pull_requests)
+db.pull_request.audit('create', validate_url)
+db.pull_request.audit('set', validate_url)
diff --git a/html/issue.item.html b/html/issue.item.html
--- a/html/issue.item.html
+++ b/html/issue.item.html
@@ -220,6 +220,14 @@
  
 
 
+
+ GitHub PR:
+ 
+  
+  
+ 
+
+
 
 
 
@@ -273,6 +281,31 @@
  
 
 
+
+ Pull Requests
+ 
+  URL
+  Linked
+  Edit
+ 
+ 
+  
+   
+URL
+   
+  
+  
+   creator's name,
+   creation date
+  
+  
+edit
+  
+ 
+
+
 
@@ -284,7 +317,7 @@
  once it's done your name will have a * next to it.)
 
 
- Repositories containing patches
+ Repositories containing patches
  
   

+Pull Request - 
+Pull Request
+
+
+
+
+ You are not allowed to view this page.
+
+
+ Please login with your username and password.
+
+
+
+
+ 
+  URL
+  
+ 
+ 
+  Title
+  
+ 
+
+ 
+  
+   
+   
+   
+   
+  
+  submit button here
+ 
+
+
+
+
+   File has been classified as spam.
+
+
+
+
+
+This PR is linked to :
+   
+
+
+
+This PR has been unlinked from :
+   
+
+
+
+
+
+
+
+
+
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -173,6 +173,11 @@
patchbranch=String(),
)
 
+pull_request = Class(db, "pull_request",
+ url=String(),
+ title=String(),
+ )
+
 # IssueClass automatically gets these properties in addition to the Class ones:
 #   title = String()
 #   messages = Multilink("msg")
@@ -194,7 +199,8 @@
stage=Link('stage'),
nosy_count=Number(),
message_count=Number(),
-   hgrepos=Multilink('hgrepo'))
+   hgrepos=Multilink('hgrepo'),
+   pull_requests=Multilink('pull_request'))
 
 #
 # TRACKER SECURITY SETTINGS
@@ -222,7 +228,7 @@
 
 for cl in ('issue_type', 'severity', 'component',
'version', 'priority', 'stage', 'status', 'resolution',
-   'issue', 'keyword', 'hgrepo'):
+   'issue', 'keyword', 'hgrepo', 'pull_request'):
 db.security.addPermissionToRole('User', 'View', cl)
 db.security.addPermissionToRole('Anonymous', 'View', cl)
 
@@ -233,6 +239,13 @@
   properties=['url', 'patchbranch'])
 db.security.addPermissionToRole('User', p)
 
+def may_edit_pull_request(db, userid, itemid):
+return userid == db.pull_request.get(itemid, "creator")
+db.security.addPermissionToRole('User', 'Create', 'pull_request')
+p = db.security.addPermission(name='Edit', klass='pull_request',
+  check=may_edit_pull_request, properties=['url', 
'title'])
+db.security.addPermissionToR

[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-21 Thread Maciej Szulik

Maciej Szulik added the comment:

Permissions problem should be addressed as well, since I've added option to 
unlink, rather than remove. Similarly to what is available for files.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-21 Thread Maciej Szulik

Maciej Szulik added the comment:

Apparently I can't leave title set to none, I had to explicitly set it to empty 
if none is set.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___diff --git a/detectors/pull_request.py b/detectors/pull_request.py
new file mode 100644
--- /dev/null
+++ b/detectors/pull_request.py
@@ -0,0 +1,55 @@
+# Auditor for GitHub URLs
+# Check if it is a valid GitHub Pull Request URL and extract PR number
+
+import re
+import urlparse
+
+
+def validate_pull_requests(db, cl, nodeid, newvalues):
+newprs = set(newvalues.get('pull_requests',()))
+oldprs = set()
+if nodeid:
+oldprs = set(db.issue.get(nodeid, 'pull_requests'))
+newprs -= oldprs
+newurl = ''
+for prid in newprs:
+newurl = parse_url(db.pull_request.get(prid, 'url'))
+if newurl != '':
+for prid in oldprs:
+if newurl == db.pull_request.get(prid, 'url'):
+raise ValueError("GitHub PR already added to issue")
+
+def validate_url(db, cl, nodeid, newvalues):
+try:
+newurl = parse_url(newvalues['url'])
+if newurl != '':
+newvalues['url'] = newurl
+except KeyError:
+pass
+try:
+newvalues['title']
+except KeyError:
+newvalues['title'] = ''
+
+def parse_url(url):
+if url == '':
+return
+# TODO: transform following forms:
+# - username/repo#prno
+# - repo/#prno
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme == '':
+url = 'https://' + url
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme not in ('http', 'https'):
+raise ValueError("Invalid URL scheme in GitHub PR")
+if 'github.com' not in parsed_url.netloc or 'pull' not in parsed_url.path:
+raise ValueError("Invalid GitHub PR")
+return parsed_url.geturl().strip('/')
+
+
+def init(db):
+db.issue.audit('create', validate_pull_requests)
+db.issue.audit('set', validate_pull_requests)
+db.pull_request.audit('create', validate_url)
+db.pull_request.audit('set', validate_url)
diff --git a/html/issue.item.html b/html/issue.item.html
--- a/html/issue.item.html
+++ b/html/issue.item.html
@@ -220,6 +220,14 @@
  
 
 
+
+ GitHub PR:
+ 
+  
+  
+ 
+
+
 
 
 
@@ -273,6 +281,31 @@
  
 
 
+
+ Pull Requests
+ 
+  URL
+  Linked
+  Edit
+ 
+ 
+  
+   
+URL
+   
+  
+  
+   creator's name,
+   creation date
+  
+  
+edit
+  
+ 
+
+
 
diff --git a/html/pull_request.item.html b/html/pull_request.item.html
new file mode 100644
--- /dev/null
+++ b/html/pull_request.item.html
@@ -0,0 +1,72 @@
+
+Pull Request - 
+Pull Request
+
+
+
+
+ You are not allowed to view this page.
+
+
+ Please login with your username and password.
+
+
+
+
+ 
+  URL
+  
+ 
+ 
+  Title
+  
+ 
+
+ 
+  
+   
+   
+   
+   
+  
+  submit button here
+ 
+
+
+
+
+   File has been classified as spam.
+
+
+
+
+
+This PR is linked to :
+   
+
+
+
+This PR has been unlinked from :
+   
+
+
+
+
+
+
+
+
+
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -173,6 +173,11 @@
patchbranch=String(),
)
 
+pull_request = Class(db, "pull_request",
+ url=String(),
+ title=String(),
+ )
+
 # IssueClass automatically gets these properties in addition to the Class ones:
 #   title = String()
 #   messages = Multilink("msg")
@@ -194,7 +199,8 @@
stage=Link('stage'),
nosy_count=Number(),
message_count=Number(),
-   hgrepos=Multilink('hgrepo'))
+   hgrepos=Multilink('hgrepo'),
+   pull_requests=Multilink('pull_request'))
 
 #
 # TRACKER SECURITY SETTINGS
@@ -222,7 +228,7 @@
 
 for cl in ('issue_type', 'severity', 'component',
'version', 'priority', 'stage', 'status', 'resolution',
-   'issue', 'keyword', 'hgrepo'):
+   'issue', 'keyword', 'hgrepo', 'pull_request'):
 db.security.addPermissionToRole('User', 'View', cl)
 db.security.addPermissionToRole('Anonymous', 'View', cl)
 
@@ -233,6 +239,13 @@
   properties=['url', 'patchbranch'])
 db.security.addPermissionToRole('User', p)
 
+def may_edit_pull_request(db, userid, itemid):
+return userid == db.pull_request.get(itemid, "creator")
+db.security.addPermissionToRole('User', 'Create', 'pull_request')
+p = db.security.addPermission(name='Edit', klass='pull_request',
+  check=may_edit_pull_request, properties=['url', 
'title'])
+db.security.addPermissionToRole('User', p)
+
 class may_view_spam:
 def __init_

[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-11-21 Thread Maciej Szulik

Maciej Szulik added the comment:

Addressed  1, 2, 4, 5. I'll handle 3rd along with title as a followup issue.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___diff --git a/detectors/pull_request.py b/detectors/pull_request.py
new file mode 100644
--- /dev/null
+++ b/detectors/pull_request.py
@@ -0,0 +1,49 @@
+# Auditor for GitHub URLs
+# Check if it is a valid GitHub Pull Request URL and extract PR number
+
+import re
+import urlparse
+
+
+def validate_pull_requests(db, cl, nodeid, newvalues):
+newprs = set(newvalues.get('pull_requests',()))
+oldprs = set()
+if nodeid:
+oldprs = set(db.issue.get(nodeid, 'pull_requests'))
+newprs -= oldprs
+newurl = ''
+for prid in newprs:
+newurl = parse_url(db.pull_request.get(prid, 'url'))
+if newurl != '':
+for prid in oldprs:
+if newurl == db.pull_request.get(prid, 'url'):
+raise ValueError("GitHub PR already added to issue")
+
+def validate_url(db, cl, nodeid, newvalues):
+newurl = parse_url(newvalues.get('url', ''))
+if newurl != '':
+newvalues['url'] = newurl
+# TODO: read PR title here
+
+def parse_url(url):
+if url == '':
+return
+# TODO: transform following forms:
+# - username/repo#prno
+# - repo/#prno
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme == '':
+url = 'https://' + url
+parsed_url = urlparse.urlparse(url)
+if parsed_url.scheme not in ('http', 'https'):
+raise ValueError("Invalid URL scheme in GitHub PR")
+if 'github.com' not in parsed_url.netloc or 'pull' not in parsed_url.path:
+raise ValueError("Invalid GitHub PR")
+return parsed_url.geturl().strip('/')
+
+
+def init(db):
+db.issue.audit('create', validate_pull_requests)
+db.issue.audit('set', validate_pull_requests)
+db.pull_request.audit('create', validate_url)
+db.pull_request.audit('set', validate_url)
diff --git a/html/issue.item.html b/html/issue.item.html
--- a/html/issue.item.html
+++ b/html/issue.item.html
@@ -220,6 +220,14 @@
  
 
 
+
+ GitHub PR:
+ 
+  
+  
+ 
+
+
 
 
 
@@ -273,6 +281,31 @@
  
 
 
+
+ Pull Requests
+ 
+  URL
+  Linked
+  Edit
+ 
+ 
+  
+   
+URL
+   
+  
+  
+   creator's name,
+   creation date
+  
+  
+edit
+  
+ 
+
+
 
diff --git a/html/pull_request.item.html b/html/pull_request.item.html
new file mode 100644
--- /dev/null
+++ b/html/pull_request.item.html
@@ -0,0 +1,72 @@
+
+File display - 
+Pull Request
+
+
+
+
+ You are not allowed to view this page.
+
+
+ Please login with your username and password.
+
+
+
+
+ 
+  URL
+  
+ 
+ 
+  Title
+  
+ 
+
+ 
+  
+   
+   
+   
+   
+  
+  submit button here
+ 
+
+
+
+
+   File has been classified as spam.
+
+
+
+
+
+This PR is linked to :
+   
+
+
+
+This PR has been unlinked from :
+   
+
+
+
+
+
+
+
+
+
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -173,6 +173,11 @@
patchbranch=String(),
)
 
+pull_request = Class(db, "pull_request",
+ url=String(),
+ title=String(),
+ )
+
 # IssueClass automatically gets these properties in addition to the Class ones:
 #   title = String()
 #   messages = Multilink("msg")
@@ -194,7 +199,8 @@
stage=Link('stage'),
nosy_count=Number(),
message_count=Number(),
-   hgrepos=Multilink('hgrepo'))
+   hgrepos=Multilink('hgrepo'),
+   pull_requests=Multilink('pull_request'))
 
 #
 # TRACKER SECURITY SETTINGS
@@ -222,7 +228,7 @@
 
 for cl in ('issue_type', 'severity', 'component',
'version', 'priority', 'stage', 'status', 'resolution',
-   'issue', 'keyword', 'hgrepo'):
+   'issue', 'keyword', 'hgrepo', 'pull_request'):
 db.security.addPermissionToRole('User', 'View', cl)
 db.security.addPermissionToRole('Anonymous', 'View', cl)
 
@@ -233,6 +239,13 @@
   properties=['url', 'patchbranch'])
 db.security.addPermissionToRole('User', p)
 
+def may_edit_pull_request(db, userid, itemid):
+return userid == db.pull_request.get(itemid, "creator")
+db.security.addPermissionToRole('User', 'Create', 'pull_request')
+p = db.security.addPermission(name='Edit', klass='pull_request',
+  check=may_edit_pull_request, properties=['url', 
'title'])
+db.security.addPermissionToRole('User', p)
+
 class may_view_spam:
 def __init__(self, klassname):
 self.klassname = klassname
@@ -292,7 +305,7 @@
   properties=('title', 't

[Tracker-discuss] [issue600] Convert patches to GitHub Pull Request (depends on issue586)

2016-08-29 Thread Maciej Szulik

Maciej Szulik added the comment:

> I have updated the patch.

Thank you, the patch itself LGTM.

> > We do need proper error handling, still.
> The problem is "err" variable has stdout of that process. So, even if we 
> change/push branch, it will be non-empty. Any idea how to solve this problem?

If I'm reading this [1] correctly communicate returns you a tuple where first 
argument
is stdout contents and second stderr, isn't that what you want?

> One more thing, if we create PR using API, it triggers GitHub webhooks. So, 
> I'm removing the part where we are storing the response in DB.

Yup, your webhook should handle that part nicely, already.

> Also, I'm not sure how to add tests for this.

Yeah, let's leave it like this for now. 

[1] 
https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue600>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)

2016-08-22 Thread Maciej Szulik

Maciej Szulik added the comment:

LGTM

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue592>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue586, issue589)

2016-08-16 Thread Maciej Szulik

Maciej Szulik added the comment:

Thanks, works ok.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)

2016-08-14 Thread Maciej Szulik

Maciej Szulik added the comment:

Anish, can you please update the roundup part so that it applies cleanly and 
apply all the suggestions discussed on core-workflow mailing list?

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue592>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue586, issue589)

2016-08-14 Thread Maciej Szulik

Maciej Szulik added the comment:

Anish while reviewing 592 I've got into trouble applying the roundup part on 
top of 589, I guess due to the amount of changes in it. Can you please update 
the patch so it applies cleanly?

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)

2016-08-14 Thread Maciej Szulik

Maciej Szulik added the comment:

LGTM

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)

2016-08-09 Thread Maciej Szulik

Maciej Szulik added the comment:

> Sorry. I didn't get you. You mean, same tests for PR body, right?

Yeah, exactly that. I'd like to see both body and title tests. Sorry I was 
initially noting down my thoughts and apparently forgot to "normalize" that 
part of the sentence ;)


> I was thinking of adding "Exception, e" instead of checking for just
> KeyError in dispatch method. But that will also catch Unauthorized,
> MethodNotAllowed and unsupportedmediatype. Can you suggest a better way to
> do this?

Only going through the code and figure out what are the possible exceptions
and just name them explicitly. No magic option here, sorry :(

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue586, issue589)

2016-08-07 Thread Maciej Szulik

Maciej Szulik added the comment:

LGTM

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)

2016-08-06 Thread Maciej Szulik

Maciej Szulik added the comment:

roundup/pull_request.py:

> key = os.environ['SECRET_KEY']

If this env is missing the code throws KeyError, which is not nice. It would be 
better
to check if it exists and fail nicely, informing about the problem.


> def testPullRequestEventForTitle(self):
> # When the title of a PR has string "fixes bpo123"
> dummy_client = self._make_client("pullrequestevent.txt")

But both pullrequestevent.txt and pullrequestevent1.txt have 'fixes bpo1' in 
body, not in title.


> return self.db.issue.create(title=title)

I haven't seen the issue being created, when testing this locally. I mean, 
the code goes this path, but there's no new issue in the bugtracker, am I 
missing something here? OK I got it, here's again the problem with per
issue URL, iow. I'm failing this condition:

> issue_exists = len(self.db.issue.filter(None, {'id': issue_id})) == 1
> url_exists = len(self.db.pull_request.filter(None, {'url': url})) == 1
> if issue_exists and not url_exists:

The issue exists, but unfortunately I'm again using the same PR URL.
You should check just this issue's urls.

 
> title_match = self.issue_re.search(title)
> body_match = self.issue_re.search(body)

This matching code only matches the last one, so if I specify multiple 
fixes bpoX, bpoY, only Y will be updated. 


> self._validate_webhook_secret()
> self._verify_request()
> self._extract()

_verify_request should come before _validate_webhook_secret, otherwise if 
somebody
sends you malformed data (wrong event, method, content type) you first try to 
interpret
it in secret validation, instead of rejecting the request.


Generally, try more defensive approach when accessing dictionaries, since this 
endpoint will be available to outside world, it may be a potential place to 
attacks, this means you should be prepared to KeyErrors at any place you're 
accessing
dictionary. A except KeyError at one of the higher levels (eg. _extract) will 
be perfectly 
fine and that should immediately throw Reject exception.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue600] Convert patches to GitHub Pull Request

2016-07-25 Thread Maciej Szulik

Maciej Szulik added the comment:

@Berker the work included in this issue is the main part of Anish work during 
his GSoC time. I'm currently in the process of reviewing his submissions.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue600>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue592] Show GitHub comments on b.p.o

2016-07-25 Thread Maciej Szulik

Maciej Szulik added the comment:

@David, @Berker the original idea of this patch is to entirely ignore gh 
notifications and have that information available in bpo. Moreover, instead of 
a bunch of comments you should get one combined information that the review has 
be posted with a link to the PR. The initial timeout we agreed on was 30 mins, 
iow. 30 mins of inactivity would cause this to create such comment on bpo. I'm 
currently reviewing those patches and I'll make sure this is working as 
described. Is that more to your liking?

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue592>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue589)

2016-07-25 Thread Maciej Szulik

Maciej Szulik added the comment:

@anish since issue 589 needs update so does this one.

--
nosy: +anish.shah

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue589)

2016-07-25 Thread Maciej Szulik

Maciej Szulik added the comment:

@berker I've decided to split this into several steps for simplicity of 
tracking Anish progress. For that I'd prefer to keep it separate, if you don't 
mind.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue590>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)

2016-07-25 Thread Maciej Szulik

Maciej Szulik added the comment:

@anish.shah

I still don't see my comments from previous review addressed. Additionally, 
since issue 586 has changed the schema you should update it here as well.


@David:

> Hmm.  Good question.  We could use a specific user to create such issues.

The other option is to look for gh username, since we already store them and 
create the issue on behalf of that, falling back to that specific only when
none is found. But using specific user is a good starting point.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-07-22 Thread Maciej Szulik

Maciej Szulik added the comment:

LGTM

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue581] Add rest endpoint to roundup

2016-07-19 Thread Maciej Szulik

Maciej Szulik added the comment:

@rouilj it's currently stuck, hopefully after summer I'll be able to get back 
to the topic. Sorry :(

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue581>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks

2016-07-18 Thread Maciej Szulik

Maciej Szulik added the comment:

@anish.shah

roundup/github_pullrequest_url.py

> def __init__(self, client):
> 
> self._validate_webhook_secret()
> self._verify_request()
> self._extract()

Don't put the entire action in the constructor of the object. Its 
responsibility is to create an object
and then you call actions on it. Here dispatch is the method you should create 
that should do what you want here.

>  result = compare_digest(signature, header_signature)
>if not result:

Replace with:

if not compare_digest(signature, header_signature):

reads better.

> def _get_event(self):
> event = self.request.headers.get('X-GitHub-Event', None)
> return event

Replace with:

def _get_event(self):
return self.request.headers.get('X-GitHub-Event', None)

> if event == 'pull_request':
> PullRequest(self.db, self.data)
> elif event == 'issue_comment':
> IssueComment(self.db, self.data)

Same here. Create objects and act upon them, don't run actions inside the 
initialization. 

I'll get back to this patch once again tomorrow.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue589>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page

2016-07-18 Thread Maciej Szulik

Maciej Szulik added the comment:

@anish.shah

> I'm reconstructing because URL might contain fragment identifier/query 
> string. What do you think?

Doesn't matter, the parsed_url is just an object representation of that url.

>  I will change this. But, I will need to change this in all the patches that 
> I have submitted. 

Sorry, but yes please. And apply Berker's suggestion of not having github word 
in it, as well.

> I have added a 'state' field in issue590

Cool.


@Berker

> Issue 589 is a different feature and it should be discussed there (by the way 
> it would be really nice if you could give more information about the feature 
> and the patch -- I had to read the whole patch to understand what it does).

> The problem with this implementation is that I will need to go to 
> bugs.python.org/issue and paste a URL everytime I open a pull request on 
> GitHub. Instead of this manual step, Roundup should automatically look for 
> "Issue #" in all pull request titles and list all matched items by using 
> JavaScript on bugs.python.org/issue.

It's exactly like David is saying. With issue 589 b.p.o is notified through 
github webhook of new events, such as PRs in which we parse the title and 
comment in search for bpoNNN and link the PR automatically. The idea of having 
a client side javascript assuming you have a gh opened in one tab and bpo in 
other doesn't seem right. I'm currently reviewing Anish all submissions from 
his GSoC and he'll soon create an extensive article describing all the things 
he has done. Anyway thanks for your time and review!

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue586>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue581] Add rest endpoint to roundup

2016-03-10 Thread Maciej Szulik

Maciej Szulik added the comment:

Pefu my work is based on top of work started during GSoC. For now I've decided 
to cut the current implementation just to have GET working (needed for github 
migration). I'm hoping to work on enabling other actions as well. At the end of 
the day my hope is we can upstream this feature.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue581>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue581] Add rest endpoint to roundup

2016-02-29 Thread Maciej Szulik

Maciej Szulik added the comment:

The auth error seems to be minor with the fact that passing non-existent auth 
data gives me full access to any data. Working on it now...

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue581>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue581] Add rest endpoint to roundup

2016-02-27 Thread Maciej Szulik

Maciej Szulik added the comment:

Still needs fixing:
- auth error

Additionally, if we want full-REST support we need:
- decide if we want to have delete at all
- post using json, not just form-data, since we return GET data with json
- fix validation when post-ing

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue581>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Tracker-discuss] [issue581] Add rest endpoint to roundup

2016-02-27 Thread Maciej Szulik

Maciej Szulik added the comment:

This partially derived from #579. 

Previous problem I've described was that any user was able to see others full 
details, including password. I've finally nailed what was the problem when 
calling hasPermissions item_id was not passed. I've fixed that and added some 
more tests. 

As discussed previously I've removed all PUT/POST/PATCH actions leaving just 
GETs.

My work is under https://bitbucket.org/soltysh/roundup/branch/rest 
Yet I'm attaching current patch here.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue581>
___diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
@@ -22,6 +22,7 @@
 from roundup.mailer import Mailer, MessageSendError, encode_quopri
 from roundup.cgi import accept_language
 from roundup import xmlrpc
+from roundup import rest
 
 from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \
 get_cookie_date
@@ -378,6 +379,8 @@
 try:
 if self.path == 'xmlrpc':
 self.handle_xmlrpc()
+elif self.path == 'rest' or self.path[:5] == 'rest/':
+self.handle_rest()
 else:
 self.inner_main()
 finally:
@@ -419,6 +422,24 @@
 self.setHeader("Content-Length", str(len(output)))
 self.write(output)
 
+def handle_rest(self):
+# Set the charset and language
+self.determine_charset()
+self.determine_language()
+# Open the database as the correct user.
+# TODO: add everything to RestfulDispatcher
+self.determine_user()
+self.check_anonymous_access()
+
+# Call rest library to handle the request
+handler = rest.RestfulInstance(self, self.db)
+output = handler.dispatch(self.env['REQUEST_METHOD'], self.path,
+  self.form)
+
+# self.setHeader("Content-Type", "text/xml")
+self.setHeader("Content-Length", str(len(output)))
+self.write(output)
+
 def add_ok_message(self, msg, escape=True):
 add_message(self._ok_message, msg, escape)
 
diff --git a/roundup/rest.py b/roundup/rest.py
new file mode 100644
--- /dev/null
+++ b/roundup/rest.py
@@ -0,0 +1,551 @@
+"""
+Restful API for Roundup
+
+This module is free software, you may redistribute it
+and/or modify under the same terms as Python.
+"""
+
+import urlparse
+import os
+import json
+import pprint
+import sys
+import time
+import traceback
+import re
+
+from roundup import hyperdb
+from roundup import date
+from roundup import actions
+from roundup.exceptions import *
+from roundup.cgi.exceptions import *
+
+
+def _data_decorator(func):
+"""Wrap the returned data into an object."""
+def format_object(self, *args, **kwargs):
+# get the data / error from function
+try:
+code, data = func(self, *args, **kwargs)
+except NotFound, msg:
+code = 404
+data = msg
+except IndexError, msg:
+code = 404
+data = msg
+except Unauthorised, msg:
+code = 403
+data = msg
+except UsageError, msg:
+code = 400
+data = msg
+except (AttributeError, Reject), msg:
+code = 405
+data = msg
+except ValueError, msg:
+code = 409
+data = msg
+except NotImplementedError:
+code = 402  # nothing to pay, just a mark for debugging purpose
+data = 'Method under development'
+except:
+exc, val, tb = sys.exc_info()
+code = 400
+ts = time.ctime()
+data = '%s: An error occurred. Please check the server log' \
+   ' for more information.' % ts
+# out to the logfile
+print 'EXCEPTION AT', ts
+traceback.print_exc()
+
+# decorate it
+self.client.response_code = code
+if code >= 400:  # any error require error format
+result = {
+'error': {
+'status': code,
+'msg': data
+}
+}
+else:
+result = {
+'data': data
+}
+return result
+return format_object
+
+
+def parse_accept_header(accept):
+"""
+Parse the Accept header *accept*, returning a list with 3-tuples of
+[(str(media_type), dict(params), float(q_value)),] ordered by q values.
+
+If the accept header includes vendor-specific types like::
+application/vnd.yourcompany.yourproduct-v1.1+json
+
+It will actual

[Tracker-discuss] [issue580] CSV Injection Vulnerability

2016-02-23 Thread Maciej Szulik

New submission from Maciej Szulik:

Copied from http://bugs.python.org/issue26399:

The "Download as CSV " feature of bugs.python.org does not properly "escape" 
fields. This allows an adversary to turn a field into active content so when we 
download the csv and opens it, the active content gets executed. Here is more 
information about this issue:
http://www.contextis.com/resources/blog/comma-separated-vulnerabilities/

Steps to Reproduce.
1. Enter the title with the payload : -2+3+cmd|' /C calc'!A0
2. Download the bugs as CSV
3. Open it with excel and Calc will get prompted.

Depending upon the system user privileges, an attacker can perform various 
tasks using the same.
If the user is with high privilege, it is easy to change the system password as 
mentioned below
-2+3+cmd|' /C net user administrator lol@123'!A0

Mitigations:
Ensure all fields are properly "escaped" before returning the CSV file to the 
user.

Regards,
Acid

Impact of this one is high, as download as CSV is present for guest user as 
well. Means anyone can download the bugs using "Download as CSV " function and 
as the file is downloaded from the trusted resource so the possibility is high 
the code will get executed.

--
messages: 3008
nosy: maciej.szulik
priority: urgent
status: unread
title: CSV Injection Vulnerability

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue580>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss


[Tracker-discuss] [issue579] Add github field in user profile

2016-02-21 Thread Maciej Szulik

Maciej Szulik added the comment:

After further investigating into the rest patch that I temporarily applied here 
https://bitbucket.org/soltysh/roundup/branch/rest my current findings are:
- we return too much information on GET, any authenticated user gets ALL of the 
details from any user, including password (hashed but still it's there). 
- I'm not clear how the POST works, it does not accept JSON as input but rather 
tries to parse incoming arguments, which fails.

I'll try cutting this patch into something smaller. In the first place I'd 
suggest removing all modifications actions and start with just read ones. Ezio 
I'll ping you tomorrow on IRC to discuss this more.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue579>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss


[Tracker-discuss] [issue579] Add github field in user profile

2016-02-21 Thread Maciej Szulik

Maciej Szulik added the comment:

I've added the search for github user name according to the discussion on IRC. 
I'm including the patch, but for the record, it's also being available at 
https://bitbucket.org/soltysh/python-dev/branch/github

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue579>
___diff --git a/extensions/pydevutils.py b/extensions/pydevutils.py
--- a/extensions/pydevutils.py
+++ b/extensions/pydevutils.py
@@ -20,6 +20,11 @@
 db = request.client.db
 return 'Coordinator' in db.user.get(user, 'roles')

+def is_developer(request):
+user = request.client.userid
+db = request.client.db
+return 'Developer' in db.user.get(user, 'roles')
+
 def clean_ok_message(ok_message):
 """Remove nosy_count and message_count from the ok_message."""
 pattern = '\s*(?:nosy|message)_count,|,\s*(?:nosy|message)_count(?= 
edited)'
@@ -60,6 +65,7 @@
 def init(instance):
 instance.registerUtil('is_history_ok', is_history_ok)
 instance.registerUtil('is_coordinator', is_coordinator)
+instance.registerUtil('is_developer', is_developer)
 instance.registerUtil('clean_ok_message', clean_ok_message)
 instance.registerUtil('issueid_and_action_from_class',
   issueid_and_action_from_class)
diff --git a/html/style.css b/html/style.css
--- a/html/style.css
+++ b/html/style.css
@@ -177,6 +177,10 @@
   white-space: nowrap;
 }

+table.form th:last-child {
+  border-right: #ddd solid 1px;
+}
+
 table.form th.header {
   font-weight: bold;
   text-align: left;
diff --git a/html/user.index.html b/html/user.index.html
--- a/html/user.index.html
+++ b/html/user.index.html
@@ -19,7 +19,7 @@
 

-   Search for users
+   Search for users

Username

@@ -33,6 +33,14 @@
  name name;
  id name"/>

+   
+   Github
+   
+   
+   
+   



diff --git a/html/user.item.html b/html/user.item.html
--- a/html/user.item.html
+++ b/html/user.item.html
@@ -105,7 +105,12 @@

  
   Home page
-  
+  
+ 
+
+ 
+  GitHub Name
+  
  

  
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -96,7 +96,8 @@
  contrib_form_date=Date(),
  openids=String(), # space separated list
  iscommitter=Boolean(),
- homepage=String()
+ homepage=String(),
+ github=String()
  )
 user.setkey("username")
 db.security.addPermission(name='Register', klass='user',
@@ -349,7 +350,7 @@
 p = db.security.addPermission(name='View', klass='user',
 properties=('id', 'username', 'address', 'realname', 'phone',
 'organisation', 'alternate_addresses', 'timezone',
-'roles', 'contrib_form', 'iscommitter', 'homepage'))
+'roles', 'contrib_form', 'iscommitter', 'homepage', 
'github'))
 db.security.addPermissionToRole('User', p)
 db.security.addPermissionToRole('Developer', p)
 # Coordinator may view all user properties.
@@ -374,8 +375,8 @@
 'address', 'realname',
 'phone', 'organisation',
 'alternate_addresses',
-'queries',
-'timezone')) # Note: 'roles' excluded - users should not be 
able to edit their own roles.
+'queries', 'timezone',
+'homepage', 'github')) # Note: 'roles' excluded - users should 
not be able to edit their own roles.
  # Also excluded: contrib_form, contrib_form_date, 
iscommitter
 for r in 'User', 'Developer':
 db.security.addPermissionToRole(r, p)
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss


[Tracker-discuss] [issue579] Add github field in user profile

2016-02-19 Thread Maciej Szulik

Maciej Szulik added the comment:

I did initial check whether patch from 
https://bitbucket.org/kinggreedy1991/roundup-bpo/branc
hes/compare/kinggreedy1991/roundup-bpo:tip%0Dezio_melotti/roundup-bpo:bugs.python.org#diff
 works correctly. From initial glimpses it's working ok, though I reserve some 
more time to have a deeper analysis, still.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue579>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss


[Tracker-discuss] [issue579] Add github field in user profile

2016-02-15 Thread Maciej Szulik

Maciej Szulik added the comment:

No, I have not :/ Lemme you give it a try and check those details.

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue579>
___
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss


[Tracker-discuss] [issue579] Add github field in user profile

2016-02-12 Thread Maciej Szulik

New submission from Maciej Szulik:

Add github field to user profile.

--
assignedto: ezio.melotti
files: gh.diff
messages: 3001
nosy: ezio.melotti, maciej.szulik
priority: feature
status: in-progress
title: Add github field in user profile

___
PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za>
<http://psf.upfronthosting.co.za/roundup/meta/issue579>
___diff --git a/html/user.item.html b/html/user.item.html
--- a/html/user.item.html
+++ b/html/user.item.html
@@ -105,7 +105,12 @@
 
  
   Home page
-  
+  
+ 
+
+ 
+  GitHub Name
+  
  
 
  
diff --git a/schema.py b/schema.py
--- a/schema.py
+++ b/schema.py
@@ -96,7 +96,8 @@
  contrib_form_date=Date(),
  openids=String(), # space separated list
  iscommitter=Boolean(),
- homepage=String()
+ homepage=String(),
+ github=String()
  )
 user.setkey("username")
 db.security.addPermission(name='Register', klass='user',
___
Tracker-discuss mailing list
Tracker-discuss@python.org
https://mail.python.org/mailman/listinfo/tracker-discuss