def get_participant(state, restrict=True, redirect_stub=True, allow_member=False): """Given a Request, raise Response or return Participant. If restrict is True then we'll restrict access to owners and admins. """ request = state['request'] user = state['user'] slug = request.line.uri.path['username'] _ = state['_'] if restrict and user.ANON: raise AuthRequired if slug.startswith('~'): thing = 'id' value = slug[1:] participant = user if user and str(user.id) == value else None else: thing = 'lower(username)' value = slug.lower() participant = user if user and user.username.lower() == value else None if participant is None: from liberapay.models.participant import Participant # avoid circular import participant = Participant._from_thing(thing, value) if value else None if participant is None or participant.kind == 'community': raise Response(404) if request.method in ('GET', 'HEAD'): if slug != participant.username: canon = '/' + participant.username + request.line.uri[len(slug) + 1:] raise Response(302, headers={'Location': canon}) status = participant.status if status == 'closed': if user.is_admin: return participant raise Response(410) elif status == 'stub': if redirect_stub: to = participant.resolve_stub() assert to raise Response(302, headers={'Location': to}) if restrict: if participant != user: if allow_member and participant.kind == 'group' and user.member_of( participant): pass elif not user.is_admin: raise Response( 403, _("You are not authorized to access this page.")) return participant
def sign_in_with_form_data(body, state): p = None _, website = state['_'], state['website'] if body.get('log-in.id'): id = body.pop('log-in.id') password = body.pop('log-in.password', None) k = 'email' if '@' in id else 'username' if password: p = Participant.authenticate( k, 'password', id, password, ) if not p: state['log-in.error'] = _("Bad username or password.") if p and p.status == 'closed': p.update_status('active') elif k == 'username': state['log-in.error'] = _("\"{0}\" is not a valid email address.", id) return else: email = id p = Participant._from_thing('email', email) if p: p.start_session() qs = {'log-in.id': p.id, 'log-in.token': p.session_token} p.send_email( 'login_link', email=email, link=p.url('settings/', qs), link_validity=SESSION_TIMEOUT, ) state['log-in.email-sent-to'] = email else: state['log-in.error'] = _( "We didn't find any account whose primary email address is {0}.", email ) p = None elif 'sign-in.email' in body: response = state['response'] kind = body.pop('sign-in.kind') if kind not in ('individual', 'organization'): raise response.error(400, 'bad kind') email = body.pop('sign-in.email') if not email: raise response.error(400, 'email is required') with website.db.get_cursor() as c: p = Participant.make_active( kind, body.pop('sign-in.username', None), body.pop('sign-in.password', None), cursor=c, ) p.set_email_lang(state['request'].headers.get(b'Accept-Language'), cursor=c) p.add_email(email, cursor=c) p.authenticated = True return p
def get_participant(state, restrict=True, redirect_stub=True, allow_member=False): """Given a Request, raise Response or return Participant. If restrict is True then we'll restrict access to owners and admins. """ request = state['request'] user = state['user'] slug = request.line.uri.path['username'] _ = state['_'] if restrict: if user.ANON: if request.method == 'GET': url = '/sign-in?back_to='+urlquote(request.line.uri) raise Response(302, headers={'Location': url}) raise Response(403, _("You need to log in to access this page.")) if slug.startswith('~'): thing = 'id' value = slug[1:] participant = user if user and str(user.id) == value else None else: thing = 'lower(username)' value = slug.lower() participant = user if user and user.username.lower() == value else None if participant is None: from liberapay.models.participant import Participant # avoid circular import participant = Participant._from_thing(thing, value) if value else None if participant is None: raise Response(404) if request.method in ('GET', 'HEAD'): if slug != participant.username: canon = '/' + participant.username + request.line.uri[len(slug)+1:] raise Response(302, headers={'Location': canon}) status = participant.status if status == 'closed': if user.is_admin: return participant raise Response(410) elif status == 'stub': if redirect_stub: to = participant.resolve_stub() assert to raise Response(302, headers={'Location': to}) if restrict: if participant != user: if allow_member and participant.kind == 'group' and user.member_of(participant): pass elif not user.is_admin: raise Response(403, _("You are not authorized to access this page.")) return participant
def sign_in_with_form_data(body, state): p = None _, website = state['_'], state['website'] if body.get('log-in.id'): id = body.pop('log-in.id') k = 'email' if '@' in id else 'username' p = Participant.authenticate( k, 'password', id, body.pop('log-in.password') ) if not p: state['sign-in.error'] = _("Bad username or password.") if p and p.status == 'closed': p.update_status('active') elif body.get('sign-in.username'): if body.pop('sign-in.terms') != 'agree': raise Response(400, 'you have to agree to the terms') kind = body.pop('sign-in.kind') if kind not in ('individual', 'organization'): raise Response(400, 'bad kind') with website.db.get_cursor() as c: p = Participant.make_active( body.pop('sign-in.username'), kind, body.pop('sign-in.password'), cursor=c ) p.add_email(body.pop('sign-in.email'), cursor=c) p.authenticated = True elif body.get('email-login.email'): email = body.pop('email-login.email') p = Participant._from_thing('email', email) if p: p.start_session() qs = {'log-in.id': p.id, 'log-in.token': p.session_token} p.send_email( 'password_reset', email=email, link=p.url('settings/', qs), link_validity=SESSION_TIMEOUT, ) state['email-login.sent-to'] = email else: state['sign-in.error'] = _( "We didn't find any account whose primary email address is {0}.", email ) p = None return p
def sign_in_with_form_data(body, state): p = None _, website = state['_'], state['website'] if body.get('log-in.id'): id = body.pop('log-in.id') k = 'email' if '@' in id else 'username' p = Participant.authenticate(k, 'password', id, body.pop('log-in.password')) if not p: state['sign-in.error'] = _("Bad username or password.") if p and p.status == 'closed': p.update_status('active') elif body.get('sign-in.username'): if body.pop('sign-in.terms') != 'agree': raise Response(400, 'you have to agree to the terms') kind = body.pop('sign-in.kind') if kind not in ('individual', 'organization'): raise Response(400, 'bad kind') with website.db.get_cursor() as c: p = Participant.make_active(body.pop('sign-in.username'), kind, body.pop('sign-in.password'), cursor=c) p.add_email(body.pop('sign-in.email'), cursor=c) p.authenticated = True elif body.get('email-login.email'): email = body.pop('email-login.email') p = Participant._from_thing('email', email) if p: p.start_session() qs = {'log-in.id': p.id, 'log-in.token': p.session_token} p.send_email( 'password_reset', email=email, link=p.url('settings/', qs), link_validity=SESSION_TIMEOUT, ) state['email-login.sent-to'] = email else: state['sign-in.error'] = _( "We didn't find any account whose primary email address is {0}.", email) p = None return p
def sign_in_with_form_data(body, state): p = None _, website = state['_'], state['website'] if body.get('log-in.id'): id = body.pop('log-in.id') password = body.pop('log-in.password', None) k = 'email' if '@' in id else 'username' if password: p = Participant.authenticate( k, 'password', id, password, ) if not p: state['log-in.error'] = _("Bad username or password.") elif k == 'username': state['log-in.error'] = _("\"{0}\" is not a valid email address.", id) return else: email = id p = Participant._from_thing('lower(email)', email.lower()) if p and p.kind == 'group': state['log-in.error'] = _( "{0} is linked to a team account. It's not possible to log in as a team.", email ) elif p: if not p.get_email(email).verified: website.db.hit_rate_limit('log-in.email.not-verified', TooManyLoginEmails) website.db.hit_rate_limit('log-in.email', p.id, TooManyLoginEmails) p.start_session() qs = {'log-in.id': p.id, 'log-in.token': p.session_token} p.send_email( 'login_link', email, link=p.url('settings/', qs), link_validity=SESSION_TIMEOUT, ) state['log-in.email-sent-to'] = email raise LoginRequired else: state['log-in.error'] = _( "We didn't find any account whose primary email address is {0}.", email ) p = None elif 'sign-in.email' in body: response = state['response'] kind = body.pop('sign-in.kind', 'individual') if kind not in ('individual', 'organization'): raise response.error(400, 'bad kind') email = body.pop('sign-in.email') if not email: raise response.error(400, 'email is required') currency = body.pop('sign-in.currency', state.get('currency')) if currency and currency not in CURRENCIES: raise response.error(400, "`currency` value '%s' is invalid of non-supported" % currency) src_addr = state['request'].source website.db.hit_rate_limit('sign-up.ip-addr', str(src_addr), TooManySignUps) website.db.hit_rate_limit('sign-up.ip-net', get_ip_net(src_addr), TooManySignUps) website.db.hit_rate_limit('sign-up.ip-version', src_addr.version, TooManySignUps) with website.db.get_cursor() as c: p = Participant.make_active( kind, body.pop('sign-in.username', None), body.pop('sign-in.password', None), currency=currency, cursor=c, ) p.set_email_lang(state['request'].headers.get(b'Accept-Language'), cursor=c) p.add_email(email, cursor=c) p.authenticated = True return p
def get_participant(state, restrict=True, redirect_stub=True, allow_member=False, block_suspended_user=False, redirect_canon=True): """Given a Request, raise Response or return Participant. If restrict is True then we'll restrict access to owners and admins. """ request = state['request'] response = state['response'] user = state['user'] slug = request.line.uri.path['username'] _ = state['_'] if restrict and user.ANON: raise LoginRequired if slug.startswith('~'): thing = 'id' value = slug[1:] if not value.isdigit(): raise response.error(404) participant = user if user and str(user.id) == value else None else: thing = 'lower(username)' value = slug.lower() participant = user if user and user.username.lower() == value else None if participant is None: from liberapay.models.participant import Participant # avoid circular import participant = Participant._from_thing(thing, value) if value else None if participant is None: if thing == 'lower(username)': look_up_redirections(request, response) raise response.error(404) elif participant.kind == 'community': c_name = Participant.db.one( """ SELECT name FROM communities WHERE participant = %s """, (participant.id, )) raise response.redirect('/for/%s' % c_name) if redirect_canon and request.method in ('GET', 'HEAD'): if slug != participant.username: canon = '/' + participant.username + request.line.uri[len(slug) + 1:] raise response.redirect(canon) status = participant.status if status == 'closed': if user.is_admin: return participant state['closed_account'] = participant response.html_template = 'templates/account-closed.html' raise response.error(410) elif status == 'stub': if redirect_stub: to = participant.resolve_stub() if not to: # Account has been taken over raise response.error(404) raise response.redirect(to) if restrict: if participant != user: if allow_member and participant.kind == 'group' and user.member_of( participant): pass elif not user.is_admin: raise response.error( 403, _("You are not authorized to access this page.")) if block_suspended_user and participant.is_suspended and participant == user: raise AccountSuspended() return participant
def get_participant(state, restrict=True, redirect_stub=True, allow_member=False, block_suspended_user=False, redirect_canon=True): """Given a Request, raise Response or return Participant. If restrict is True then we'll restrict access to owners and admins. """ request = state['request'] response = state['response'] user = state['user'] slug = request.line.uri.path['username'] _ = state['_'] if restrict and user.ANON: raise LoginRequired if slug.startswith('~'): thing = 'id' value = slug[1:] if not value.isdigit(): raise response.error(404) participant = user if user and str(user.id) == value else None else: thing = 'lower(username)' value = slug.lower() participant = user if user and user.username.lower() == value else None if participant is None: from liberapay.models.participant import Participant # avoid circular import participant = Participant._from_thing(thing, value) if value else None if participant is None: if thing == 'lower(username)': look_up_redirections(request, response) raise response.error(404) elif participant.kind == 'community': c_name = Participant.db.one(""" SELECT name FROM communities WHERE participant = %s """, (participant.id,)) raise response.redirect('/for/%s' % c_name) if redirect_canon and request.method in ('GET', 'HEAD'): if slug != participant.username: canon = '/' + participant.username + request.line.uri[len(slug)+1:] raise response.redirect(canon) status = participant.status if status == 'closed': if user.is_admin: return participant state['closed_account'] = participant response.html_template = 'templates/account-closed.html' raise response.error(410) elif status == 'stub': if redirect_stub: to = participant.resolve_stub() if not to: # Account has been taken over raise response.error(404) raise response.redirect(to) if restrict: if participant != user: if allow_member and participant.kind == 'group' and user.member_of(participant): pass elif not user.is_admin: raise response.error(403, _("You are not authorized to access this page.")) if block_suspended_user and participant.is_suspended and participant == user: raise AccountSuspended() return participant