internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: gratipay/gratipay.com

Issue:
A suspicious user trying to log in results in a 500
https://app.getsentry.com/gratipay/gratipay-com/group/32039756/

<bountysource-plugin>

---

Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/4727299-a-suspicious-user-trying-to-log-in-results-in-a-500?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).
</bountysource-plugin>

A suspicious user trying to log in results in a 500
https://app.getsentry.com/gratipay/gratipay-com/group/32039756/

<bountysource-plugin>

---

Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/4727299-a-suspicious-user-trying-to-log-in-results-in-a-500?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).
</bountysource-plugin>



Discussion:

Resolving patch:
diff --git a/gratipay/security/user.py b/gratipay/security/user.py
--- a/gratipay/security/user.py
+++ b/gratipay/security/user.py
@@ -92,9 +92,7 @@ def ADMIN(self):
 
     @property
     def ANON(self):
-        return self.participant is None or self.participant.is_suspicious is True
-        # Append "is True" here because otherwise Python will return the result
-        # of evaluating the right side of the or expression, which can be None.
+        return self.participant is None
 
     def get_highest_role(self, owner):
         """Return a string representing the highest role this user has.


Test patch:
diff --git a/tests/py/test_user.py b/tests/py/test_user.py
--- a/tests/py/test_user.py
+++ b/tests/py/test_user.py
@@ -51,10 +51,10 @@ def test_whitelisted_user_is_not_ANON(self):
         alice = User.from_username('alice')
         assert alice.ANON is False
 
-    def test_blacklisted_user_is_ANON(self):
+    def test_blacklisted_user_is_not_ANON(self):
         self.make_participant('alice', is_suspicious=True)
         alice = User.from_username('alice')
-        assert alice.ANON is True
+        assert alice.ANON is False
 
 
     # session token
@@ -136,11 +136,6 @@ def test_user_from_bad_id_is_anonymous(self):
         user = User.from_username('deadbeef')
         assert user.ANON
 
-    def test_suspicious_user_from_username_is_anonymous(self):
-        self.make_participant('alice', is_suspicious=True)
-        user = User.from_username('alice')
-        assert user.ANON
-
     def test_signed_out_user_is_anonymous(self):
         self.make_participant('alice')
         alice = User.from_username('alice')
Repository: gratipay/gratipay.com

Issue:
audit csrf_token for httponly
We've received a security disclosure about [not setting `httponly` for `csrf_token`](https://github.com/gratipay/gratipay.com/blob/1749/gratipay/security/csrf.py#L153). We should review that decision and leave a comment in the code where that is necessitated.



Discussion:
The JS code needs [access to the CSRF token](https://github.com/gratipay/gratipay.com/blob/1749/js/gratipay/forms.js#L76) to be able to do POST requests.


Resolving patch:
diff --git a/gratipay/security/csrf.py b/gratipay/security/csrf.py
--- a/gratipay/security/csrf.py
+++ b/gratipay/security/csrf.py
@@ -150,6 +150,8 @@ def add_csrf_token_to_response(response, request=None):
         return  # early parsing must've failed
     csrf_token = request.context.get('csrf_token')
     if csrf_token:
+        # Don't set httponly so that we can POST using XHR.
+        # https://github.com/gratipay/gratipay.com/issues/3030
         response.set_cookie('csrf_token', csrf_token, expires=CSRF_TIMEOUT, httponly=False)
 
         # Content varies with the CSRF cookie, so set the Vary header.


Test patch:
Repository: gratipay/gratipay.com

Issue:
show total ever given
Suggested [via Twitter](https://twitter.com/tripflex/status/532597015210131456):

> is there no way for me to see the total I have donated?  I know I can see it weekly, but what about overall total?



Discussion:
+1. This would be a very useful feature.

+1 that was me :)

@tripflex :-)

+1


Resolving patch:
diff --git a/gratipay/utils/history.py b/gratipay/utils/history.py
--- a/gratipay/utils/history.py
+++ b/gratipay/utils/history.py
@@ -16,6 +16,13 @@ def iter_payday_events(db, participant):
     if not (exchanges or transfers):
         return
 
+    if transfers:
+        yield dict(
+            kind='totals',
+            given=sum(t['amount'] for t in transfers if t['tipper'] == username),
+            received=sum(t['amount'] for t in transfers if t['tippee'] == username),
+        )
+
     payday_dates = db.all("""
         SELECT ts_start::date
           FROM paydays


Test patch:
diff --git a/tests/py/test_history.py b/tests/py/test_history.py
--- a/tests/py/test_history.py
+++ b/tests/py/test_history.py
@@ -46,17 +46,21 @@ def test_iter_payday_events(self):
 
         Payday().start()
         events = list(iter_payday_events(self.db, bob))
-        assert len(events) == 8
-        assert events[0]['kind'] == 'day-open'
-        assert events[0]['payday_number'] == 2
-        assert events[1]['balance'] == 12
+        assert len(events) == 9
+        assert events[0]['kind'] == 'totals'
+        assert events[0]['given'] == 0
+        assert events[0]['received'] == 12
+        assert events[1]['kind'] == 'day-open'
+        assert events[1]['payday_number'] == 2
+        assert events[2]['balance'] == 12
         assert events[-1]['kind'] == 'day-close'
         assert events[-1]['balance'] == '0.00'
 
         alice = Participant.from_id(alice.id)
         assert alice.balance == 4990
         events = list(iter_payday_events(self.db, alice))
-        assert len(events) == 10
+        assert events[0]['given'] == 10
+        assert len(events) == 11
 
         carl = Participant.from_id(carl.id)
         assert carl.balance == 0
Repository: gratipay/gratipay.com

Issue:
Funding goal clears when logging in
When logging in I've noticed my funding goal clears.

Repro steps:
1. Log in
2. Set funding goal
3. Log out
4. Log in
5. Check funding goal

Video: https://9k1.us/xV@!/Screencast_2015-01-04_14:08:33.mp4

Funding goal clears when logging in
When logging in I've noticed my funding goal clears.

Repro steps:
1. Log in
2. Set funding goal
3. Log out
4. Log in
5. Check funding goal

Video: https://9k1.us/xV@!/Screencast_2015-01-04_14:08:33.mp4



Discussion:

Resolving patch:
diff --git a/gratipay/models/account_elsewhere.py b/gratipay/models/account_elsewhere.py
--- a/gratipay/models/account_elsewhere.py
+++ b/gratipay/models/account_elsewhere.py
@@ -149,7 +149,6 @@ def opt_in(self, desired_username):
         """Given a desired username, return a User object.
         """
         from gratipay.security.user import User
-        self.participant.update_goal(None)
         user = User.from_username(self.participant.username)
         assert not user.ANON, self.participant  # sanity check
         if self.participant.is_claimed:
diff --git a/gratipay/models/participant.py b/gratipay/models/participant.py
--- a/gratipay/models/participant.py
+++ b/gratipay/models/participant.py
@@ -327,6 +327,7 @@ def set_as_claimed(self):
 
             """, (self.username,))
             self.set_attributes(claimed_time=claimed_time)
+        self.update_goal(None)
 
 
     # Closing


Test patch:
diff --git a/tests/py/test_elsewhere.py b/tests/py/test_elsewhere.py
--- a/tests/py/test_elsewhere.py
+++ b/tests/py/test_elsewhere.py
@@ -50,6 +50,11 @@ def test_opt_in_resets_is_closed_to_false(self):
         assert not user.participant.is_closed
         assert not Participant.from_username('alice').is_closed
 
+    def test_logging_in_doesnt_reset_goal(self):
+        self.make_participant('alice', claimed_time='now', elsewhere='twitter', goal=100)
+        alice = AccountElsewhere.from_user_name('twitter', 'alice').opt_in('alice')[0].participant
+        assert alice.goal == 100
+
     def test_hitting_confirm_plain_results_in_404(self):
         assert self.client.GxT('/on/confirm.html').code == 404
Repository: gratipay/gratipay.com

Issue:
Charges higher than total gifts
For the past three weeks our charges have been about a thousand dollars higher than total gifts.

![screen shot 2015-01-07 at 11 37 20 am](https://cloud.githubusercontent.com/assets/688886/5649147/b16bd278-9661-11e4-8f29-09976884bf8a.png)

Charges higher than total gifts
For the past three weeks our charges have been about a thousand dollars higher than total gifts.

![screen shot 2015-01-07 at 11 37 20 am](https://cloud.githubusercontent.com/assets/688886/5649147/b16bd278-9661-11e4-8f29-09976884bf8a.png)



Discussion:
The timing of #2914 suggests that it may be part of this.

I don't see anything wrong, guess it's just a lot of new people who are being upcharged $10 the first time round. 

The trend is very clear though, which makes me doubt whether I've missed something. Since 2012-11-29, these are the only paydays in which `charge_volume` has exceeded `transfer_volume`.

I'd like @Changaco to review this before we close. 

We're not actually charging more, `charge_volume` has simply been thrown off by #3011.

The timing of #2914 suggests that it may be part of this.

I don't see anything wrong, guess it's just a lot of new people who are being upcharged $10 the first time round. 

The trend is very clear though, which makes me doubt whether I've missed something. Since 2012-11-29, these are the only paydays in which `charge_volume` has exceeded `transfer_volume`.

I'd like @Changaco to review this before we close. 

We're not actually charging more, `charge_volume` has simply been thrown off by #3011.


Resolving patch:
diff --git a/gratipay/billing/payday.py b/gratipay/billing/payday.py
--- a/gratipay/billing/payday.py
+++ b/gratipay/billing/payday.py
@@ -656,6 +656,7 @@ def update_stats(self):
                      SELECT *
                        FROM our_exchanges
                       WHERE amount > 0
+                        AND status <> 'failed'
                  )
             UPDATE paydays
                SET nactive = (


Test patch:
Repository: gratipay/gratipay.com

Issue:
`make test` leaves asset artifacts on filesystem
```
[gratipay] $ git status
# On branch update-test-deps
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       www/assets/gratipay.css
#       www/assets/gratipay.js
nothing added to commit but untracked files present (use "git add" to track)
[gratipay] $
```

`make test` leaves asset artifacts on filesystem
```
[gratipay] $ git status
# On branch update-test-deps
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       www/assets/gratipay.css
#       www/assets/gratipay.js
nothing added to commit but untracked files present (use "git add" to track)
[gratipay] $
```



Discussion:
Leaving this here for reference: https://github.com/gratipay/gratipay.com/pull/2907#issuecomment-62148266

I just got bit by this. I was trying to debug a regression in #3067, but my changes to `js/gratipay/charts.js` were masked by the presence of `www/assets/gratipay.js` left over from my last test run.

Leaving this here for reference: https://github.com/gratipay/gratipay.com/pull/2907#issuecomment-62148266

I just got bit by this. I was trying to debug a regression in #3067, but my changes to `js/gratipay/charts.js` were masked by the presence of `www/assets/gratipay.js` left over from my last test run.


Resolving patch:
diff --git a/gratipay/wireup.py b/gratipay/wireup.py
--- a/gratipay/wireup.py
+++ b/gratipay/wireup.py
@@ -257,8 +257,8 @@ def compile_assets(website):
         os.rename(tmpfpath, filepath)
 
 
-def clean_assets(website):
-    for spt in find_files(website.www_root+'/assets/', '*.spt'):
+def clean_assets(www_root):
+    for spt in find_files(www_root+'/assets/', '*.spt'):
         try:
             os.unlink(spt[:-4])
         except:
@@ -319,7 +319,7 @@ def asset(path):
         compile_assets(website)
     else:
         website.asset = lambda path: env.gratipay_asset_url+path
-        clean_assets(website)
+        clean_assets(website.www_root)
 
     website.google_analytics_id = env.google_analytics_id
     website.optimizely_id = env.optimizely_id


Test patch:
diff --git a/gratipay/testing/__init__.py b/gratipay/testing/__init__.py
--- a/gratipay/testing/__init__.py
+++ b/gratipay/testing/__init__.py
@@ -2,6 +2,7 @@
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import atexit
 import itertools
 import unittest
 from os.path import dirname, join, realpath
@@ -193,3 +194,6 @@ def make_exchange(self, kind, amount, fee, participant, status='succeeded', erro
 
 
 class Foobar(Exception): pass
+
+
+atexit.register(lambda: wireup.clean_assets(WWW_ROOT))
Repository: gratipay/gratipay.com

Issue:
`make test` leaves asset artifacts on filesystem
```
[gratipay] $ git status
# On branch update-test-deps
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       www/assets/gratipay.css
#       www/assets/gratipay.js
nothing added to commit but untracked files present (use "git add" to track)
[gratipay] $
```

`make test` leaves asset artifacts on filesystem
```
[gratipay] $ git status
# On branch update-test-deps
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       www/assets/gratipay.css
#       www/assets/gratipay.js
nothing added to commit but untracked files present (use "git add" to track)
[gratipay] $
```



Discussion:
Leaving this here for reference: https://github.com/gratipay/gratipay.com/pull/2907#issuecomment-62148266

I just got bit by this. I was trying to debug a regression in #3067, but my changes to `js/gratipay/charts.js` were masked by the presence of `www/assets/gratipay.js` left over from my last test run.

#3100 fixes the issue for `make pytest` but not for `make jstest`.

Leaving this here for reference: https://github.com/gratipay/gratipay.com/pull/2907#issuecomment-62148266

I just got bit by this. I was trying to debug a regression in #3067, but my changes to `js/gratipay/charts.js` were masked by the presence of `www/assets/gratipay.js` left over from my last test run.

#3100 fixes the issue for `make pytest` but not for `make jstest`.


Resolving patch:
diff --git a/gratipay/wireup.py b/gratipay/wireup.py
--- a/gratipay/wireup.py
+++ b/gratipay/wireup.py
@@ -2,6 +2,7 @@
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import atexit
 import fnmatch
 import os
 from tempfile import mkstemp
@@ -255,6 +256,7 @@ def compile_assets(website):
         os.write(tmpfd, content)
         os.close(tmpfd)
         os.rename(tmpfpath, filepath)
+    atexit.register(lambda: clean_assets(website.www_root))
 
 
 def clean_assets(www_root):


Test patch:
diff --git a/gratipay/testing/__init__.py b/gratipay/testing/__init__.py
--- a/gratipay/testing/__init__.py
+++ b/gratipay/testing/__init__.py
@@ -2,7 +2,6 @@
 """
 from __future__ import absolute_import, division, print_function, unicode_literals
 
-import atexit
 import itertools
 import unittest
 from os.path import dirname, join, realpath
@@ -194,6 +193,3 @@ def make_exchange(self, kind, amount, fee, participant, status='succeeded', erro
 
 
 class Foobar(Exception): pass
-
-
-atexit.register(lambda: wireup.clean_assets(WWW_ROOT))
Repository: gratipay/gratipay.com

Issue:
provide a way to browse/search teams
I want to be able to easily find teams to contribute to.

<bountysource-plugin>

---

Want to back this issue? **[Place a bounty on it!](https://www.bountysource.com/issues/950213-gittip-com-teams?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F85909&utm_medium=issues&utm_source=github).
</bountysource-plugin>



Discussion:
Good idea. :-)

+1 from @michelp in [IRC](https://botbot.me/freenode/gittip/msg/13535556/).


Resolving patch:
diff --git a/gratipay/utils/i18n.py b/gratipay/utils/i18n.py
--- a/gratipay/utils/i18n.py
+++ b/gratipay/utils/i18n.py
@@ -182,8 +182,8 @@ def match_lang(languages):
     return LOCALE_EN
 
 
-def format_currency_with_options(number, currency, locale='en', trailing_zeroes=True):
-    s = format_currency(number, currency, locale=locale)
+def format_currency_with_options(number, currency, format=None, locale='en', trailing_zeroes=True):
+    s = format_currency(number, currency, format, locale=locale)
     if not trailing_zeroes:
         s = s.replace(get_decimal_symbol(locale)+'00', '')
     return s


Test patch:
Repository: gratipay/gratipay.com

Issue:
allow admins to browse unclaimed (stub/archived/closed) accounts
I am looking at a btc payout for user whose balance comes from another taken-over account, and I'd love to be able to browse the old account to understand what's going on better.

This would help with some of the accounts on #2341 as well.

allow admins to browse unclaimed (stub/archived/closed) accounts
I am looking at a btc payout for user whose balance comes from another taken-over account, and I'd love to be able to browse the old account to understand what's going on better.

This would help with some of the accounts on #2341 as well.



Discussion:

Resolving patch:
diff --git a/gratipay/models/participant.py b/gratipay/models/participant.py
--- a/gratipay/models/participant.py
+++ b/gratipay/models/participant.py
@@ -176,6 +176,18 @@ def is_whitelisted(self):
     def is_claimed(self):
         return self.claimed_time is not None
 
+    @property
+    def closed_time(self):
+        return self.db.one("""
+            SELECT ts AT TIME ZONE 'UTC'
+              FROM events
+             WHERE payload->>'id'=%s
+               AND payload->>'action'='set'
+               AND payload->'values'->>'is_closed'='true'
+          ORDER BY ts DESC
+             LIMIT 1
+        """, (str(self.id),))
+
 
     # Number
     # ======
diff --git a/gratipay/utils/__init__.py b/gratipay/utils/__init__.py
--- a/gratipay/utils/__init__.py
+++ b/gratipay/utils/__init__.py
@@ -66,18 +66,21 @@ def get_participant(state, restrict=True, resolve_unclaimed=True):
     canonicalize(request.line.uri.path.raw, '/', participant.username, slug, qs)
 
     if participant.is_closed:
+        if user.ADMIN:
+            return participant
         raise Response(410)
 
     if participant.claimed_time is None and resolve_unclaimed:
-
-        # This is a stub participant record for someone on another platform who
-        # hasn't actually registered with Gratipay yet. Let's bounce the viewer
-        # over to the appropriate platform page.
-
         to = participant.resolve_unclaimed()
-        if to is None:
+        if to:
+            # This is a stub account (someone on another platform who hasn't
+            # actually registered with Gratipay yet)
+            request.redirect(to)
+        else:
+            # This is an archived account (result of take_over)
+            if user.ADMIN:
+                return participant
             raise Response(404)
-        request.redirect(to)
 
     if restrict:
         if participant != user.participant:


Test patch:
Repository: gratipay/gratipay.com

Issue:
move SQL functions out of schema.sql
Following on from #2360, and in view of the hack at https://github.com/gratipay/gratipay.com/pull/3154#issuecomment-73041912, what if we moved SQL functions to a separate file from schema.sql? If we had one file per function we could automate the process of updating those functions during deployment, and we'd get sensible diffs on PRs because we wouldn't have to use branch.sql as a go-between (branch.sql would remain for table changes).



Discussion:
Decouple stored procedures from data structure seems like a logical way to do.


Resolving patch:
diff --git a/gratipay/billing/payday.py b/gratipay/billing/payday.py
--- a/gratipay/billing/payday.py
+++ b/gratipay/billing/payday.py
@@ -26,7 +26,7 @@
 from psycopg2 import IntegrityError
 
 
-with open('fake_payday.sql') as f:
+with open('sql/fake_payday.sql') as f:
     FAKE_PAYDAY = f.read()
 
 


Test patch:
diff --git a/gratipay/testing/__init__.py b/gratipay/testing/__init__.py
--- a/gratipay/testing/__init__.py
+++ b/gratipay/testing/__init__.py
@@ -19,7 +19,6 @@
 
 
 TOP = realpath(join(dirname(dirname(__file__)), '..'))
-SCHEMA = open(join(TOP, "schema.sql")).read()
 WWW_ROOT = str(realpath(join(TOP, 'www')))
 PROJECT_ROOT = str(TOP)
Repository: gratipay/gratipay.com

Issue:
Blurred (GitHub?) avatars on profile pages
Some profile pictures (avatars) appear blurry for me. Judging from a few samples, mostly pictures imported from Github seem to be affected. Take mine as an example:
https://gratipay.com/korakinos/
https://github.com/korakinos

Among the samples I took, almost all avatars from Twitter weren't blurred, except, strangely, for one. As I don't know if the person appreciates linking, I'll just post the username: InquilineKea

A similar issue in the past was [issue 887](https://github.com/gratipay/gratipay.com/issues/887). Only back then, Twitter images were blurred.

_(Off topic: Gratipay is awesome. Thank you all so much for your efforts!)_



Discussion:
We used to show avatars in 128px maximum, then we switched to 160px, but we forgot to modify the avatar URLs.


Resolving patch:
diff --git a/gratipay/models/account_elsewhere.py b/gratipay/models/account_elsewhere.py
--- a/gratipay/models/account_elsewhere.py
+++ b/gratipay/models/account_elsewhere.py
@@ -81,7 +81,7 @@ def upsert(cls, i):
             fragment = ''
             if netloc.endswith('githubusercontent.com') or \
                netloc.endswith('gravatar.com'):
-                query = 's=128'
+                query = 's=160'
             i.avatar_url = urlunsplit((scheme, netloc, path, query, fragment))
 
         # Serialize extra_info


Test patch:
Repository: gratipay/gratipay.com

Issue:
Fix credit card expiration notification
https://app.getsentry.com/gratipay/gratipay-com/group/60379450/

Regression from #3282.



Discussion:

Resolving patch:
diff --git a/gratipay/models/participant.py b/gratipay/models/participant.py
--- a/gratipay/models/participant.py
+++ b/gratipay/models/participant.py
@@ -726,7 +726,7 @@ def credit_card_expiring(self):
         if not route:
             return
         card = balanced.Card.fetch(route.address)
-        year, month = card['expiration_year'], card['expiration_month']
+        year, month = card.expiration_year, card.expiration_month
         if not (year and month):
             return False
         return is_card_expiring(int(year), int(month))


Test patch: