Example #1
0
 def test_user_can_be_loaded_from_session_token(self):
     self.make_participant('alice')
     user = User.from_username('alice')
     user.sign_in(SimpleCookie())
     token = user.participant.session_token
     actual = User.from_session_token(token).participant.username
     assert actual == 'alice'
Example #2
0
def get_auth_from_request(request):
    """Authenticate from a cookie or an API key in basic auth.
    """
    user = None
    if request.line.uri.startswith('/assets/'):
        pass
    elif 'Authorization' in request.headers:
        header = request.headers['authorization']
        if header.startswith('Basic '):
            creds = header[len('Basic '):].decode('base64')
            token, ignored = creds.split(':')
            user = User.from_api_key(token)

            # We don't require CSRF if they basically authenticated.
            csrf_token = csrf._get_new_csrf_key()
            request.headers.cookie['csrf_token'] = csrf_token
            request.headers['X-CSRF-TOKEN'] = csrf_token
            if 'Referer' not in request.headers:
                request.headers['Referer'] = \
                                        'https://%s/' % csrf._get_host(request)
    elif SESSION in request.headers.cookie:
        token = request.headers.cookie[SESSION].value
        user = User.from_session_token(token)

    request.context['user'] = user or User()
Example #3
0
 def test_user_from_expired_session_is_anonymous(self):
     self.make_participant('alice')
     user = User.from_username('alice')
     user.sign_in(SimpleCookie())
     token = user.participant.session_token
     user.participant.set_session_expires(utcnow())
     user = User.from_session_token(token)
     assert user.ANON
def _get_user_via_api_key(api_key):
    """Given an api_key, return a User. This auth method is deprecated.
    """
    user = User()
    user.participant = Participant._from_thing('api_key', api_key)
    if user.participant:
        p = user.participant
        today = date.today()
        if p.old_auth_usage != today:
            Participant.db.run("""
                UPDATE participants
                   SET old_auth_usage = %s
                 WHERE id = %s
            """, (today, p.id))
    return user
Example #5
0
 def test_session_cookie_is_secure_if_it_should_be(self):
     canonical_scheme = gratipay.canonical_scheme
     gratipay.canonical_scheme = 'https'
     try:
         cookies = SimpleCookie()
         self.make_participant('alice')
         user = User.from_username('alice')
         user.sign_in(cookies)
         assert '; secure' in cookies[SESSION].output()
     finally:
         gratipay.canonical_scheme = canonical_scheme
Example #6
0
 def test_session_is_regularly_refreshed(self):
     self.make_participant('alice')
     user = User.from_username('alice')
     user.sign_in(SimpleCookie())
     cookies = SimpleCookie()
     user.keep_signed_in(cookies)
     assert SESSION not in cookies
     cookies = SimpleCookie()
     expires = user.participant.session_expires
     user.participant.set_session_expires(expires - SESSION_REFRESH)
     user.keep_signed_in(cookies)
     assert SESSION in cookies
Example #7
0
def authenticate_user_if_possible(request, user):
    """This signs the user in.
    """
    if request.line.uri.startswith('/assets/'):
        pass
    elif 'Authorization' in request.headers:
        header = request.headers['authorization']
        if header.startswith('Basic '):
            user = _get_user_via_basic_auth(header)
            if not user.ANON:
                _turn_off_csrf(request)
    elif SESSION in request.headers.cookie:
        token = request.headers.cookie[SESSION].value
        user = User.from_session_token(token)
    return {'user': user}
 def opt_in(self, desired_username):
     """Given a desired username, return a User object.
     """
     from gratipay.security.user import User
     user = User.from_username(self.participant.username)
     assert not user.ANON, self.participant  # sanity check
     if self.participant.is_claimed:
         newly_claimed = False
     else:
         newly_claimed = True
         user.participant.set_as_claimed()
         try:
             user.participant.change_username(desired_username)
         except ProblemChangingUsername:
             pass
     if user.participant.is_closed:
         user.participant.update_is_closed(False)
     return user, newly_claimed
def set_request_context_user(request):
    """Set request.context['user']. This signs the user in.
    """

    request.context['user'] = user = ANON  # Make sure we always have a user object, even if
                                           # there's an exception in the rest of this function.

    if request.line.uri.startswith('/assets/'):
        pass
    elif 'Authorization' in request.headers:
        header = request.headers['authorization']
        if header.startswith('Basic '):
            user = _get_user_via_basic_auth(header)
            if not user.ANON:
                _turn_off_csrf(request)
    elif SESSION in request.headers.cookie:
        token = request.headers.cookie[SESSION].value
        user = User.from_session_token(token)

    request.context['user'] = user
Example #10
0
    def build_wsgi_environ(self, *a, **kw):
        """Extend base class to support authenticating as a certain user.
        """

        # csrf - for both anon and authenticated
        csrf_token = kw.get('csrf_token', b'sotokeny')
        if csrf_token:
            self.cookie[b'csrf_token'] = csrf_token
            kw[b'HTTP_X-CSRF-TOKEN'] = csrf_token

        # user authentication
        auth_as = kw.pop('auth_as', None)
        if auth_as is None:
            if SESSION in self.cookie:
                del self.cookie[SESSION]
        else:
            user = User.from_username(auth_as)
            user.sign_in(self.cookie)

        return Client.build_wsgi_environ(self, *a, **kw)
Example #11
0
def _get_user_via_basic_auth(auth_header):
    """Given a basic auth header, return a User object.
    """
    try:
        creds = binascii.a2b_base64(auth_header[len('Basic '):]).split(':', 1)
    except binascii.Error:
        raise Response(400, 'Malformed "Authorization" header')
    if len(creds) != 2:
        raise Response(401)
    userid, api_key = creds
    if len(userid) == 36 and '-' in userid:
        user = _get_user_via_api_key(userid)  # For backward-compatibility
    else:
        try:
            userid = int(userid)
        except ValueError:
            raise Response(401)
        user = User.from_id(userid)
        if user.ANON or not constant_time_compare(user.participant.api_key, api_key):
            raise Response(401)
    return user
Example #12
0
    def build_wsgi_environ(self, *a, **kw):
        """Extend base class to support authenticating as a certain user.
        """

        self.cookie.clear()

        # csrf - for both anon and authenticated
        csrf_token = kw.get('csrf_token', b'ThisIsATokenThatIsThirtyTwoBytes')
        if csrf_token:
            self.cookie[b'csrf_token'] = csrf_token
            kw[b'HTTP_X-CSRF-TOKEN'] = csrf_token

        # user authentication
        auth_as = kw.pop('auth_as', None)
        if auth_as:
            user = User.from_username(auth_as)
            user.sign_in(self.cookie)

        for k, v in kw.pop('cookies', {}).items():
            self.cookie[k] = v

        return Client.build_wsgi_environ(self, *a, **kw)
Example #13
0
 def test_user_from_None_session_token_is_anonymous(self):
     self.make_participant('alice')
     self.make_participant('bob')
     user = User.from_session_token(None)
     assert user.ANON
Example #14
0
 def test_user_from_bad_session_token_is_anonymous(self):
     user = User.from_session_token('deadbeef')
     assert user.ANON
Example #15
0
 def test_whitelisted_user_is_not_ANON(self):
     self.make_participant('alice', is_suspicious=False)
     alice = User.from_username('alice')
     assert alice.ANON is False
Example #16
0
 def test_admin_user_is_admin(self):
     self.make_participant('alice', is_admin=True)
     alice = User.from_username('alice')
     assert alice.ADMIN
Example #17
0
 def test_username_is_case_insensitive(self):
     self.make_participant('AlIcE')
     actual = User.from_username('aLiCe').participant.username_lower
     assert actual == 'alice'
Example #18
0
 def test_signed_out_user_is_anonymous(self):
     self.make_participant('alice')
     alice = User.from_username('alice')
     assert not alice.ANON
     alice.sign_out(SimpleCookie())
     assert alice.ANON
Example #19
0
 def test_user_from_bad_session_token_is_anonymous(self):
     user = User.from_session_token('deadbeef')
     assert user.ANON
Example #20
0
 def test_show_as_team_to_anon(self):
     self.make_participant('alice')
     self.team.add_member(self.make_participant('bob', claimed_time='now'))
     assert self.team.show_as_team(User())
Example #21
0
 def test_show_as_team_to_non_team_member(self):
     self.make_participant('alice')
     self.team.add_member(self.make_participant('bob', claimed_time='now'))
     user = User.from_username('alice')
     assert self.team.show_as_team(user)
Example #22
0
 def test_show_as_team_to_admin(self):
     self.make_participant('alice', is_admin=True)
     user = User.from_username('alice')
     assert self.team.show_as_team(user)
Example #23
0
 def test_user_can_be_loaded_from_api_key(self):
     alice = self.make_participant('alice')
     api_key = alice.recreate_api_key()
     actual = User.from_api_key(api_key).participant.username
     assert actual == 'alice'
Example #24
0
 def test_suspicious_user_from_username_is_anonymous(self):
     self.make_participant('alice', is_suspicious=True)
     user = User.from_username('alice')
     assert user.ANON
Example #25
0
 def test_show_as_team_to_non_team_member(self):
     self.make_participant('alice')
     self.team.add_member(self.make_participant('bob', claimed_time='now'))
     user = User.from_username('alice')
     assert self.team.show_as_team(user)
Example #26
0
 def test_dont_show_individuals_as_team(self):
     alice = self.make_participant('alice', number='singular')
     assert not alice.show_as_team(User())
Example #27
0
 def test_user_from_bad_username_is_anonymous(self):
     user = User.from_username('deadbeef')
     assert user.ANON
Example #28
0
 def test_dont_show_plural_no_members_as_team_to_anon(self):
     group = self.make_participant('Group', number='plural')
     assert not group.show_as_team(User())
Example #29
0
 def test_anonymous_user_is_not_admin(self):
     user = User()
     assert not user.ADMIN
Example #30
0
 def test_dont_show_plural_no_members_as_team_to_auth(self):
     group = self.make_participant('Group', number='plural')
     self.make_participant('alice')
     assert not group.show_as_team(User.from_username('alice'))
Example #31
0
 def test_known_user_is_not_admin(self):
     self.make_participant('alice')
     alice = User.from_username('alice')
     assert not alice.ADMIN
Example #32
0
 def test_show_plural_no_members_as_team_to_self(self):
     group = self.make_participant('Group', number='plural')
     assert group.show_as_team(User.from_username('Group'))
Example #33
0
 def test_unreviewed_user_is_not_ANON(self):
     self.make_participant('alice', is_suspicious=None)
     alice = User.from_username('alice')
     assert alice.ANON is False
Example #34
0
 def test_show_plural_no_members_as_team_to_admin(self):
     group = self.make_participant('Group', number='plural')
     self.make_participant('Admin', is_admin=True)
     assert group.show_as_team(User.from_username('Admin'))
Example #35
0
 def test_blacklisted_user_is_not_ANON(self):
     self.make_participant('alice', is_suspicious=True)
     alice = User.from_username('alice')
     assert alice.ANON is False
Example #36
0
 def test_show_plural_no_members_as_team_to_self(self):
     group = self.make_participant('Group', number='plural')
     assert group.show_as_team(User.from_username('Group'))
Example #37
0
 def test_user_from_bad_api_key_is_anonymous(self):
     user = User.from_api_key('deadbeef')
     assert user.ANON
Example #38
0
 def test_user_from_None_api_key_is_anonymous(self):
     self.make_participant('alice')
     self.make_participant('bob')
     user = User.from_api_key(None)
     assert user.ANON
Example #39
0
 def test_blacklisted_user_is_ANON(self):
     self.make_participant('alice', is_suspicious=True)
     alice = User.from_username('alice')
     assert alice.ANON is True
Example #40
0
 def test_user_from_None_id_is_anonymous(self):
     user = User.from_id(None)
     assert user.ANON
Example #41
0
 def test_show_as_team_to_admin(self):
     self.make_participant('alice', is_admin=True)
     user = User.from_username('alice')
     assert self.team.show_as_team(user)
Example #42
0
 def test_user_can_be_loaded_from_id(self):
     alice = self.make_participant('alice')
     actual = User.from_id(alice.id).participant.username
     assert actual == 'alice'
Example #43
0
 def test_dont_show_plural_no_members_as_team_to_auth(self):
     group = self.make_participant('Group', number='plural')
     self.make_participant('alice')
     assert not group.show_as_team(User.from_username('alice'))
Example #44
0
 def test_user_from_None_session_token_is_anonymous(self):
     self.make_participant('alice')
     self.make_participant('bob')
     user = User.from_session_token(None)
     assert user.ANON
Example #45
0
 def test_show_plural_no_members_as_team_to_admin(self):
     group = self.make_participant('Group', number='plural')
     self.make_participant('Admin', is_admin=True)
     assert group.show_as_team(User.from_username('Admin'))
Example #46
0
 def test_user_from_bad_id_is_anonymous(self):
     user = User.from_id(1786541)
     assert user.ANON
Example #47
0
 def test_anonymous_user_is_anonymous(self):
     user = User()
     assert user.ANON
Example #48
0
"""Defines website authentication helpers.
"""
import binascii
from datetime import date

from aspen import Response
from gratipay.models.participant import Participant
from gratipay.security import csrf
from gratipay.security.crypto import constant_time_compare
from gratipay.security.user import User, SESSION

ANON = User()


def _get_user_via_api_key(api_key):
    """Given an api_key, return a User. This auth method is deprecated.
    """
    user = User(Participant._from_thing('api_key', api_key))
    if user.participant:
        p = user.participant
        today = date.today()
        if p.old_auth_usage != today:
            Participant.db.run(
                """
                UPDATE participants
                   SET old_auth_usage = %s
                 WHERE id = %s
            """, (today, p.id))
    return user