Ejemplo n.º 1
0
def preferences(request):
    schema = UserPreferencesSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    user = request.user

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        user.update_preferences(appstruct)
        Session.add(user)

        request.session.flash(
            _('The changes were saved successfully'),
            'success',
        )
        return HTTPFound(location=request.route_path('user_preferences'))

    return {
        'form':
        form.render({
            'allow_google_analytics':
            user.allow_google_analytics,
            'send_passwords_periodically':
            user.send_passwords_periodically,
        })
    }
Ejemplo n.º 2
0
def preferences(request):
    schema = UserPreferencesSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    user = request.user

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        user.update_preferences(appstruct)
        Session.add(user)

        request.session.flash(
            _('The changes were saved successfully'),
            'success',
        )
        return HTTPFound(location=request.route_path('user_preferences'))

    return {
        'form': form.render({
            'allow_google_analytics': user.allow_google_analytics,
            'send_passwords_periodically': user.send_passwords_periodically,
        })
    }
Ejemplo n.º 3
0
def verify_email(request):
    try:
        code = request.params['code']
    except KeyError:
        return HTTPBadRequest('Missing code parameter')

    try:
        email = request.params['email']
    except KeyError:
        return HTTPBadRequest('Missing email parameter')

    evc = EmailVerificationCode(code)
    user = evc.verify(email)
    if user is not None:
        request.session.flash(
            _('Congratulations, your email has been successfully verified'),
            'success',
        )
        user.verify_email()
        Session.add(user)
        return {
            'verified': True,
        }
    else:
        request.session.flash(
            _('Sorry, your verification code is not correct or has expired'),
            'error',
        )
        return {
            'verified': False,
        }
Ejemplo n.º 4
0
def verify_email(request):
    try:
        code = request.params['code']
    except KeyError:
        return HTTPBadRequest('Missing code parameter')

    try:
        email = request.params['email']
    except KeyError:
        return HTTPBadRequest('Missing email parameter')

    evc = EmailVerificationCode(code)
    if evc.verify(request.db, email):
        request.session.flash(
            _('Congratulations, your email has been successfully verified'),
            'success',
        )
        evc.remove(request.db, email, True)
        return {
            'verified': True,
        }
    else:
        request.session.flash(
            _('Sorry, your verification code is not correct or has expired'),
            'error',
        )
        return {
            'verified': False,
        }
Ejemplo n.º 5
0
class AccountDestroySchema(colander.MappingSchema):

    reason = colander.SchemaNode(
        colander.String(),
        missing='',
        widget=TextAreaWidget(rows=6),
        title=_('Do you mind telling us your reasons?'),
        description=_('We want to get better!'),
    )
Ejemplo n.º 6
0
def destroy(request):
    schema = AccountDestroySchema()
    button1 = Button('submit', _('Yes, I am sure. Destroy my account'))
    button1.css_class = 'btn-danger'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default'

    form = Form(schema, buttons=(button1, button2))

    user = request.user

    can_destroy = len(user.applications) == 0

    context = {
        'passwords': len(user.passwords),
        'can_destroy': can_destroy,
    }

    if 'submit' in request.POST:

        if not can_destroy:
            request.session.flash(
                _('You must remove your applications before destroying your account'
                  ),
                'error',
            )
            return HTTPFound(
                location=request.route_path('oauth2_developer_applications'))

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            context['form'] = e.render()
            return context

        reason = appstruct['reason']
        notify_admins_of_account_removal(request, user, reason)

        Session.delete(user)

        request.session.flash(
            _('Your account has been removed. Have a nice day!'),
            'success',
        )
        return logout(request)

    elif 'cancel' in request.POST:
        request.session.flash(
            _('Thanks for reconsidering removing your account!'),
            'info',
        )
        return HTTPFound(location=request.route_path('user_information'))

    context['form'] = form.render()
    return context
Ejemplo n.º 7
0
def contributions_paypal_success(request):
    error_msg = _('There was a problem in the confirmation process. Please start the checkout again')
    if request.method == 'POST':
        if 'submit' in request.POST:
            token = request.POST.get('token', None)
            payerid = request.POST.get('payerid', None)
            amount = request.POST.get('amount', None)

            success = False

            if token and payerid and amount:
                try:
                    amount = int(amount)
                except ValueError:
                    return HTTPBadRequest('Amount must be an integer')

                paypal = PayPalExpressCheckout(request)
                success = paypal.do_express_checkout_payment(token, payerid,
                                                             amount)

            if success:
                donation = create_donation(request, request.POST)
                send_thankyou_email(request, donation)
                send_notification_to_admins(request, donation)
                request.session.flash(
                    _('Thank you very much for your great contribution'),
                    'success',
                )
            else:
                request.session.flash(error_msg, 'error')

            return HTTPFound(location=request.route_path('contributions_index'))

        elif 'cancel' in request.POST:
            return HTTPFound(location=request.route_path('contributions_paypal_cancel_callback'))

        else:
            return HTTPBadRequest('Wrong action')

    else:
        token = request.GET.get('token', None)
        payerid = request.GET.get('PayerID', None)

        if token and payerid:
            paypal = PayPalExpressCheckout(request)
            details = paypal.get_express_checkout_details(token, payerid)
            details.update({
                'token': token,
                'payerid': payerid,
            })
            amount = details['amount']
            details['include_sticker'] = include_sticker(amount)
            return details
        else:
            request.session.flash(error_msg, 'error')
            return HTTPFound(location=request.route_path('contributions_index'))
Ejemplo n.º 8
0
def contact(request):
    button1 = Button('submit', _('Send message'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default'

    form = Form(ContactSchema(), buttons=(button1, button2))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        context = {'link': request.route_url('contact')}
        context.update(appstruct)
        subject = ("%s sent a message from Yith's contact form"
                   % appstruct['name'])

        result = send_email_to_admins(
            request,
            'yithlibraryserver:templates/email_contact',
            context,
            subject,
            extra_headers={'Reply-To': appstruct['email']},
        )

        if result is None:
            log.error(
                '%s <%s> tried to send a message from the contact form but no '
                'admin emails were configured. Message: %s' % (
                    appstruct['name'],
                    appstruct['email'],
                    appstruct['message'],
                )
            )

        request.session.flash(
            _('Thank you very much for sharing your opinion'),
            'info',
        )

        return HTTPFound(location=request.route_path('home'))

    elif 'cancel' in request.POST:
        return HTTPFound(location=request.route_path('home'))

    initial = {}
    if request.user is not None:
        initial['name'] = request.user.get('first_name', '')
        if request.user.get('email_verified', False):
            initial['email'] = request.user.get('email', '')

    return {'form': form.render(initial)}
Ejemplo n.º 9
0
def contact(request):
    button1 = Button('submit', _('Send message'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default'

    form = Form(ContactSchema(), buttons=(button1, button2))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        context = {'link': request.route_url('contact')}
        context.update(appstruct)
        subject = ("%s sent a message from Yith's contact form" %
                   appstruct['name'])

        result = send_email_to_admins(
            request,
            'yithlibraryserver:templates/email_contact',
            context,
            subject,
            extra_headers={'Reply-To': appstruct['email']},
        )

        if result is None:
            log.error(
                '%s <%s> tried to send a message from the contact form but no '
                'admin emails were configured. Message: %s' % (
                    appstruct['name'],
                    appstruct['email'],
                    appstruct['message'],
                ))

        request.session.flash(
            _('Thank you very much for sharing your opinion'),
            'info',
        )

        return HTTPFound(location=request.route_path('home'))

    elif 'cancel' in request.POST:
        return HTTPFound(location=request.route_path('home'))

    initial = {}
    if request.user is not None:
        initial['name'] = request.user.first_name
        if request.user.email_verified:
            initial['email'] = request.user.email

    return {'form': form.render(initial)}
Ejemplo n.º 10
0
def destroy(request):
    schema = AccountDestroySchema()
    button1 = Button('submit', _('Yes, I am sure. Destroy my account'))
    button1.css_class = 'btn-danger'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default'

    form = Form(schema, buttons=(button1, button2))

    user = request.user

    can_destroy = len(user.applications) == 0

    context = {
        'passwords': len(user.passwords),
        'can_destroy': can_destroy,
    }

    if 'submit' in request.POST:

        if not can_destroy:
            request.session.flash(
                _('You must remove your applications before destroying your account'),
                'error',
            )
            return HTTPFound(location=request.route_path('oauth2_developer_applications'))

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            context['form'] = e.render()
            return context

        reason = appstruct['reason']
        notify_admins_of_account_removal(request, user, reason)

        Session.delete(user)

        request.session.flash(
            _('Your account has been removed. Have a nice day!'),
            'success',
        )
        return logout(request)

    elif 'cancel' in request.POST:
        request.session.flash(
            _('Thanks for reconsidering removing your account!'),
            'info',
        )
        return HTTPFound(location=request.route_path('user_information'))

    context['form'] = form.render()
    return context
Ejemplo n.º 11
0
class FullApplicationSchema(ApplicationSchema):

    client_id = colander.SchemaNode(
        colander.String(),
        title=_('Client Id'),
        widget=ReadOnlyTextInputWidget(),
    )
    client_secret = colander.SchemaNode(
        colander.String(),
        title=_('Client secret'),
        widget=ReadOnlyTextInputWidget(),
    )
Ejemplo n.º 12
0
def user_information(request):
    schema = UserSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        changes = {
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'screen_name': appstruct['screen_name'],
            'email': appstruct['email']['email'],
            }

        if request.user['email'] != appstruct['email']['email']:
            changes['email_verified'] = False

        result = request.db.users.update({'_id': request.user['_id']},
                                         {'$set': changes},
                                         safe=True)

        if result['n'] == 1:
            request.session.flash(
                _('The changes were saved successfully'),
                'success',
                )
            return HTTPFound(location=request.route_path('user_information'))
        else:
            request.session.flash(
                _('There were an error while saving your changes'),
                'error',
                )
            return {'form': appstruct}

    return {
        'form': form.render({
                'first_name': request.user['first_name'],
                'last_name': request.user['last_name'],
                'screen_name': request.user['screen_name'],
                'email': {
                    'email': request.user['email'],
                    'email_verified': request.user['email_verified'],
                    },
                }),
        }
Ejemplo n.º 13
0
def contributions_paypal_success(request):
    error_msg = _("There was a problem in the confirmation process. Please start the checkout again")
    if request.method == "POST":
        if "submit" in request.POST:
            token = request.POST.get("token", None)
            payerid = request.POST.get("payerid", None)
            amount = request.POST.get("amount", None)

            success = False

            if token and payerid and amount:
                try:
                    amount = int(amount)
                except ValueError:
                    return HTTPBadRequest("Amount must be an integer")

                paypal = PayPalExpressCheckout(request)
                success = paypal.do_express_checkout_payment(token, payerid, amount)

            if success:
                donation = create_donation(request, request.POST)
                send_thankyou_email(request, donation)
                send_notification_to_admins(request, donation)
                request.session.flash(_("Thank you very much for your great contribution"), "success")
            else:
                request.session.flash(error_msg, "error")

            return HTTPFound(location=request.route_path("contributions_index"))

        elif "cancel" in request.POST:
            return HTTPFound(location=request.route_path("contributions_paypal_cancel_callback"))

        else:
            return HTTPBadRequest("Wrong action")

    else:
        token = request.GET.get("token", None)
        payerid = request.GET.get("PayerID", None)

        if token and payerid:
            paypal = PayPalExpressCheckout(request)
            details = paypal.get_express_checkout_details(token, payerid)
            details.update({"token": token, "payerid": payerid})
            amount = details["amount"]
            details["include_sticker"] = include_sticker(amount)
            return details
        else:
            request.session.flash(error_msg, "error")
            return HTTPFound(location=request.route_path("contributions_index"))
Ejemplo n.º 14
0
class ContactSchema(colander.MappingSchema):

    name = colander.SchemaNode(
        colander.String(),
        title=_('Name'),
    )
    email = colander.SchemaNode(
        colander.String(),
        title=_('Email'),
    )
    message = colander.SchemaNode(
        colander.String(),
        widget=TextAreaWidget(rows=10),
        title=_('Message'),
    )
Ejemplo n.º 15
0
def identity_providers(request):
    current_provider = request.session.get('current_provider', None)
    accounts = get_accounts(request.db, request.user, current_provider)
    context = {
        'accounts': accounts
    }
    verified = [ac for ac in accounts if ac['is_verified']]
    context['can_merge'] = len(verified) > 1

    if 'submit' in request.POST:
        if not context['can_merge']:
            return HTTPBadRequest('You do not have enough accounts to merge')

        def is_verified(ac):
            for a in accounts:
                if a['id'] == ac:
                    return a['is_verified']
            return False

        accounts_to_merge = [account.replace('account-', '')
                             for account in request.POST.keys()
                             if account != 'submit']
        accounts_to_merge = [account
                             for account in accounts_to_merge
                             if is_verified(account)]

        if len(accounts_to_merge) > 1:
            merged = merge_accounts(request.db, request.user,
                                    accounts_to_merge)
            localizer = get_localizer(request)
            msg = localizer.pluralize(
                _('Congratulations, ${n_merged} of your accounts has been merged into the current one'),
                _('Congratulations, ${n_merged} of your accounts have been merged into the current one'),
                merged,
                domain=translation_domain,
                mapping={'n_merged': merged},
            )
            request.session.flash(msg, 'success')
        else:
            request.session.flash(
                _('Not enough accounts for merging'),
                'error',
            )

        return HTTPFound(
            location=request.route_path('user_identity_providers'))

    return context
Ejemplo n.º 16
0
def destroy(request):
    schema = AccountDestroySchema()
    button1 = Button('submit', _('Yes, I am sure. Destroy my account'))
    button1.css_class = 'btn-danger'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = ''

    form = Form(schema, buttons=(button1, button2))

    passwords_manager = PasswordsManager(request.db)
    context = {
        'passwords': passwords_manager.retrieve(request.user).count(),
        }

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            context['form'] = e.render()
            return context

        reason = appstruct['reason']
        admin_emails = request.registry.settings['admin_emails']
        if admin_emails:
            notify_admins_of_account_removal(request, request.user,
                                             reason, admin_emails)

        passwords_manager.delete(request.user)
        # TODO: remove user's applications
        delete_user(request.db, request.user)

        request.session.flash(
            _('Your account has been removed. Have a nice day!'),
            'success',
            )
        return logout(request)

    elif 'cancel' in request.POST:
        request.session.flash(
            _('Thanks for reconsidering removing your account!'),
            'info',
            )
        return HTTPFound(location=request.route_path('user_information'))

    context['form'] = form.render()
    return context
Ejemplo n.º 17
0
def backups_import(request):
    response = HTTPFound(location=request.route_path('backups_index'))

    if 'passwords-file' in request.POST:
        passwords_field = request.POST['passwords-file']
        if passwords_field != '':
            try:
                compressed_data = passwords_field.file.read()
                json_data = uncompress(compressed_data)
            except (IOError, ValueError):
                request.session.flash(
                    _('There was a problem reading your passwords file'),
                    'error')
                return response

            Session.query(Password).filter(
                Password.user == request.user).delete(
                    synchronize_session=False)

            for password_data in json_data:
                if 'secret' in password_data:
                    password = Password(user=request.user, **password_data)
                    Session.add(password)

            n_passwords = len(json_data)
            localizer = get_localizer(request)
            msg = localizer.pluralize(
                _('Congratulations, ${n_passwords} password has been imported'
                  ),
                _('Congratulations, ${n_passwords} passwords have been imported'
                  ),
                n_passwords,
                domain=translation_domain,
                mapping={'n_passwords': n_passwords},
            )
            request.session.flash(msg, 'success')
        else:
            request.session.flash(
                _('The passwords file is required to upload the passwords'),
                'error')
            return response
    else:
        request.session.flash(
            _('The passwords file is required to upload the passwords'),
            'error')
        return response

    return response
Ejemplo n.º 18
0
def identity_providers(request):
    current_provider = request.session.get('current_provider', None)
    accounts = request.user.get_accounts(current_provider)
    context = {'accounts': accounts}
    verified = [ac for ac in accounts if ac['is_verified']]
    context['can_merge'] = len(verified) > 1

    if 'submit' in request.POST:
        if not context['can_merge']:
            return HTTPBadRequest('You do not have enough accounts to merge')

        def is_verified(ac):
            for a in accounts:
                if a['id'] == ac:
                    return a['is_verified']
            return False

        accounts_to_merge = [
            account.replace('account-', '') for account in request.POST.keys()
            if account != 'submit'
        ]
        accounts_to_merge = [
            account for account in accounts_to_merge if is_verified(account)
        ]

        if len(accounts_to_merge) > 1:
            merged = merge_accounts(request.user, accounts_to_merge)
            localizer = get_localizer(request)
            msg = localizer.pluralize(
                _('Congratulations, ${n_merged} of your accounts has been merged into the current one'
                  ),
                _('Congratulations, ${n_merged} of your accounts have been merged into the current one'
                  ),
                merged,
                domain=translation_domain,
                mapping={'n_merged': merged},
            )
            request.session.flash(msg, 'success')
        else:
            request.session.flash(
                _('Not enough accounts for merging'),
                'error',
            )

        return HTTPFound(
            location=request.route_path('user_identity_providers'))

    return context
Ejemplo n.º 19
0
def revoke_application(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)

    if 'submit' in request.POST:

        authorized_apps = Session.query(AuthorizedApplication).filter(
            AuthorizedApplication.application == app,
            AuthorizedApplication.user == request.user).all()
        for authorized_app in authorized_apps:
            Session.delete(authorized_app)

        request.session.flash(
            _('The access to application ${app} has been revoked',
              mapping={'app': app.name}),
            'success',
        )
        return HTTPFound(
            location=request.route_path('oauth2_authorized_applications'))

    return {'app': app}
Ejemplo n.º 20
0
def developer_application_delete(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)
    if app.user != request.user:
        return HTTPUnauthorized()

    if 'submit' in request.POST:
        Session.delete(app)
        request.session.flash(
            _('The application ${app} was deleted successfully',
              mapping={'app': app.name}),
            'success',
        )
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    return {'app': app}
Ejemplo n.º 21
0
class UserPreferencesSchema(colander.MappingSchema):

    allow_google_analytics = colander.SchemaNode(
        colander.Boolean(),
        title=_('Allow statistics cookie'),
        missing=False,
    )

    send_passwords_periodically = colander.SchemaNode(
        colander.Boolean(),
        title=_('Send my passwords to my email monthly'),
        missing=False,
        description=
        _('You will receive your passwords backup on the first day of the month'
          ),
    )
Ejemplo n.º 22
0
class NewUserSchema(BaseUserSchema):

    email = colander.SchemaNode(
        colander.String(),
        title=_('Email'),
        missing='',
    )
Ejemplo n.º 23
0
def developer_application_delete(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)
    if app.user != request.user:
        return HTTPUnauthorized()

    if 'submit' in request.POST:
        Session.delete(app)
        request.session.flash(
            _('The application ${app} was deleted successfully',
              mapping={'app': app.name}),
            'success',
        )
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    return {'app': app}
Ejemplo n.º 24
0
def revoke_application(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)

    if 'submit' in request.POST:

        authorized_apps = Session.query(AuthorizedApplication).filter(
            AuthorizedApplication.application == app,
            AuthorizedApplication.user == request.user
        ).all()
        for authorized_app in authorized_apps:
            Session.delete(authorized_app)

        request.session.flash(
            _('The access to application ${app} has been revoked',
              mapping={'app': app.name}),
            'success',
        )
        return HTTPFound(
            location=request.route_path('oauth2_authorized_applications'))

    return {'app': app}
Ejemplo n.º 25
0
def revoke_application(request):
    assert_authenticated_user_is_registered(request)

    try:
        app_id = bson.ObjectId(request.matchdict['app'])
    except bson.errors.InvalidId:
        return HTTPBadRequest(body='Invalid application id')

    app = request.db.applications.find_one(app_id)
    if app is None:
        return HTTPNotFound()

    authorizator = Authorizator(request.db, app)

    if not authorizator.is_app_authorized(request.user):
        return HTTPUnauthorized()

    if 'submit' in request.POST:
        authorizator.remove_user_authorization(request.user)

        request.session.flash(
            _('The access to application ${app} has been revoked',
              mapping={'app': app['name']}),
            'success',
            )
        return HTTPFound(
            location=request.route_path('oauth2_authorized_applications'))

    return {'app': app}
Ejemplo n.º 26
0
def developer_application_delete(request):
    try:
        app_id = bson.ObjectId(request.matchdict['app'])
    except bson.errors.InvalidId:
        return HTTPBadRequest(body='Invalid application id')

    app = request.db.applications.find_one(app_id)
    if app is None:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)
    if app['owner'] != request.user['_id']:
        return HTTPUnauthorized()

    if 'submit' in request.POST:
        request.db.applications.remove(app_id, safe=True)
        request.session.flash(
            _('The application ${app} was deleted successfully',
              mapping={'app': app['name']}),
            'success',
            )
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    return {'app': app}
Ejemplo n.º 27
0
class BaseUserSchema(colander.MappingSchema):

    first_name = colander.SchemaNode(
        colander.String(),
        title=_('First name'),
        missing='',
    )
    last_name = colander.SchemaNode(
        colander.String(),
        title=_('Last name'),
        missing='',
    )
    screen_name = colander.SchemaNode(
        colander.String(),
        title=_('Screen name'),
        missing='',
    )
Ejemplo n.º 28
0
def backups_import(request):
    response = HTTPFound(location=request.route_path('backups_index'))

    if 'passwords-file' in request.POST:
        passwords_field = request.POST['passwords-file']
        if passwords_field != '':
            try:
                compressed_data = passwords_field.file.read()
                json_data = uncompress(compressed_data)
            except (IOError, ValueError):
                request.session.flash(
                    _('There was a problem reading your passwords file'),
                    'error')
                return response

            Session.query(Password).filter(
                Password.user == request.user
            ).delete(synchronize_session=False)

            for password_data in json_data:
                if 'secret' in password_data:
                    password = Password(user=request.user, **password_data)
                    Session.add(password)

            n_passwords = len(json_data)
            localizer = get_localizer(request)
            msg = localizer.pluralize(
                _('Congratulations, ${n_passwords} password has been imported'),
                _('Congratulations, ${n_passwords} passwords have been imported'),
                n_passwords,
                domain=translation_domain,
                mapping={'n_passwords': n_passwords},
            )
            request.session.flash(msg, 'success')
        else:
            request.session.flash(
                _('The passwords file is required to upload the passwords'),
                'error')
            return response
    else:
        request.session.flash(
            _('The passwords file is required to upload the passwords'),
            'error')
        return response

    return response
Ejemplo n.º 29
0
def user_information(request):
    schema = UserSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    user = request.user

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        changes = {
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'screen_name': appstruct['screen_name'],
            'email': appstruct['email']['email'],
        }
        user.update_user_info(changes)

        Session.add(user)

        request.session.flash(
            _('The changes were saved successfully'),
            'success',
        )
        return HTTPFound(location=request.route_path('user_information'))

    return {
        'form':
        form.render({
            'first_name': user.first_name,
            'last_name': user.last_name,
            'screen_name': user.screen_name,
            'email': {
                'email': user.email,
                'email_verified': user.email_verified,
            },
        }),
    }
Ejemplo n.º 30
0
def user_information(request):
    schema = UserSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    user = request.user

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        changes = {
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'screen_name': appstruct['screen_name'],
            'email': appstruct['email']['email'],
        }
        user.update_user_info(changes)

        Session.add(user)

        request.session.flash(
            _('The changes were saved successfully'),
            'success',
        )
        return HTTPFound(location=request.route_path('user_information'))

    return {
        'form': form.render({
            'first_name': user.first_name,
            'last_name': user.last_name,
            'screen_name': user.screen_name,
            'email': {
                'email': user.email,
                'email_verified': user.email_verified,
            },
        }),
    }
Ejemplo n.º 31
0
def developer_application_new(request):
    assert_authenticated_user_is_registered(request)
    schema = ApplicationSchema()
    button1 = Button('submit', _('Save application'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = ''
    form = Form(schema, buttons=(button1, button2))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        # the data is fine, save into the db
        application = {
            'owner': request.user['_id'],
            'name': appstruct['name'],
            'main_url': appstruct['main_url'],
            'callback_url': appstruct['callback_url'],
            'authorized_origins': appstruct['authorized_origins'],
            'production_ready': appstruct['production_ready'],
            'image_url': appstruct['image_url'],
            'description': appstruct['description'],
            }
        create_client_id_and_secret(application)

        request.session.flash(
            _('The application ${app} was created successfully',
              mapping={'app': appstruct['name']}),
            'success')

        request.db.applications.insert(application, safe=True)
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))
    elif 'cancel' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    # this is a GET
    return {'form': form.render()}
Ejemplo n.º 32
0
class UserSchema(BaseUserSchema):

    email = EmailSchema(
        title=_('Email'),
        widget=EmailWidget(),
        missing={
            'email': '',
            'email_verified': False
        },
    )
Ejemplo n.º 33
0
def developer_application_new(request):
    assert_authenticated_user_is_registered(request)
    schema = ApplicationSchema()
    button1 = Button('submit', _('Save application'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default'
    form = Form(schema, buttons=(button1, button2))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        # the data is fine, save into the db
        application = Application(
            name=appstruct['name'],
            main_url=appstruct['main_url'],
            callback_url=appstruct['callback_url'],
            authorized_origins=appstruct['authorized_origins'],
            production_ready=appstruct['production_ready'],
            image_url=appstruct['image_url'],
            description=appstruct['description'],
        )
        request.user.applications.append(application)

        request.session.flash(
            _('The application ${app} was created successfully',
              mapping={'app': appstruct['name']}), 'success')

        Session.add(request.user)

        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))
    elif 'cancel' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    # this is a GET
    return {'form': form.render()}
Ejemplo n.º 34
0
def backups_import(request):
    response = HTTPFound(location=request.route_path('backups_index'))

    if 'passwords-file' in request.POST:
        passwords_field = request.POST['passwords-file']
        if passwords_field != '':
            try:
                json_data = uncompress(passwords_field.file.read())
                passwords_manager = PasswordsManager(request.db)
                passwords_manager.delete(request.user)
                passwords_manager.create(request.user, json_data)
            except (IOError, ValueError):
                request.session.flash(
                    _('There was a problem reading your passwords file'),
                    'error')
                return response

            n_passwords = len(json_data)
            localizer = get_localizer(request)
            msg = localizer.pluralize(
                _('Congratulations, ${n_passwords} password has been imported'),
                _('Congratulations, ${n_passwords} passwords have been imported'),
                n_passwords,
                domain=translation_domain,
                mapping={'n_passwords': n_passwords},
            )
            request.session.flash(msg, 'success')
        else:
            request.session.flash(
                _('The passwords file is required to upload the passwords'),
                'error')
            return response
    else:
        request.session.flash(
            _('The passwords file is required to upload the passwords'),
            'error')
        return response

    return response
Ejemplo n.º 35
0
def preferences(request):
    schema = UserPreferencesSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    today = request.date_service.today()
    # use 28 to get a consistent day_to_send no matter what the
    # current month is. The disadvantage is that there are
    # several days in a regular month that are not used.
    day_to_send = get_day_to_send(request.user, 28)

    if day_to_send > today.day:
        day_to_send_msg = _(
            'You will receive your passwords backup on the day ${day} of this month',
            mapping={'day': day_to_send})
    elif day_to_send < today.day:
        day_to_send_msg = _(
            'You will receive your passwords backup on the day ${day} of next month',
            mapping={'day': day_to_send})
    else:
        day_to_send_msg = _(
            'You will receive your passwords backup today!',
            mapping={'day': day_to_send})

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render(), 'day_to_send': day_to_send_msg}

        changes = dict([(pref, appstruct[pref]) for pref in (
                    analytics.USER_ATTR,
                    'send_passwords_periodically',
                    )])

        result = request.db.users.update({'_id': request.user['_id']},
                                         {'$set': changes},
                                         safe=True)

        if result['n'] == 1:
            request.session.flash(
                _('The changes were saved successfully'),
                'success',
                )
            return HTTPFound(location=request.route_path('user_preferences'))
        else:
            request.session.flash(
                _('There were an error while saving your changes'),
                'error',
                )
            return {'form': appstruct, 'day_to_send': day_to_send_msg}

    return {'form': form.render(request.user), 'day_to_send': day_to_send_msg}
Ejemplo n.º 36
0
def preferences(request):
    schema = UserPreferencesSchema()
    button1 = Button('submit', _('Save changes'))
    button1.css_class = 'btn-primary'

    form = Form(schema, buttons=(button1, ))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        changes = dict([(pref, appstruct[pref]) for pref in (
            analytics.USER_ATTR,
            'send_passwords_periodically',
        )])

        result = request.db.users.update({'_id': request.user['_id']},
                                         {'$set': changes})

        if result['n'] == 1:
            request.session.flash(
                _('The changes were saved successfully'),
                'success',
            )
            return HTTPFound(location=request.route_path('user_preferences'))
        else:
            request.session.flash(
                _('There were an error while saving your changes'),
                'error',
            )
            return {'form': appstruct}

    return {'form': form.render(request.user)}
Ejemplo n.º 37
0
class ApplicationSchema(colander.MappingSchema):

    name = colander.SchemaNode(
        colander.String(),
        title=_('Name'),
    )
    main_url = colander.SchemaNode(
        colander.String(),
        title=_('Main URL'),
    )
    callback_url = colander.SchemaNode(
        colander.String(),
        title=_('Callback URL'),
    )
    authorized_origins = AuthorizedOriginsNode(
        colander.String(),
        title=_('Authorized Origins'),
        description=_('One per line. For example https://example.com'),
        widget=TextAreaWidget(rows=5),
        missing=[],
    )
    production_ready = colander.SchemaNode(
        colander.Boolean(),
        title=_('Production ready'),
        missing=False,
    )
    image_url = colander.SchemaNode(
        colander.String(),
        title=_('Image URL'),
        missing='',
    )
    description = colander.SchemaNode(
        colander.String(),
        title=_('Description'),
        missing='',
    )
Ejemplo n.º 38
0
from pyramid.httpexceptions import HTTPNotImplemented, HTTPUnauthorized
from pyramid.view import view_config

from yithlibraryserver.i18n import TranslationString as _
from yithlibraryserver.oauth2.application import create_client_id_and_secret
from yithlibraryserver.oauth2.authentication import authenticate_client
from yithlibraryserver.oauth2.authorization import Authorizator
from yithlibraryserver.oauth2.schemas import ApplicationSchema
from yithlibraryserver.oauth2.schemas import FullApplicationSchema
from yithlibraryserver.user.security import assert_authenticated_user_is_registered


DEFAULT_SCOPE = 'passwords'

SCOPE_NAMES = {
    'passwords': _('Access your passwords'),
    }


@view_config(route_name='oauth2_developer_applications',
             renderer='templates/developer_applications.pt',
             permission='view-applications')
def developer_applications(request):
    assert_authenticated_user_is_registered(request)
    owned_apps_filter = {'owner': request.user['_id']}
    return {
        'applications': request.db.applications.find(owned_apps_filter)
        }


@view_config(route_name='oauth2_developer_application_new',
Ejemplo n.º 39
0
def developer_application_edit(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)

    if app.user != request.user:
        return HTTPUnauthorized()

    schema = FullApplicationSchema()
    button1 = Button('submit', _('Save application'))
    button1.css_class = 'btn-primary'
    button2 = Button('delete', _('Delete application'))
    button2.css_class = 'btn-danger'
    button3 = Button('cancel', _('Cancel'))
    button3.css_class = 'btn-default'
    form = Form(schema, buttons=(button1, button2, button3))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render(), 'app': app}

        # the data is fine, save into the db
        app.name = appstruct['name']
        app.main_url = appstruct['main_url']
        app.callback_url = appstruct['callback_url']
        app.authorized_origins = appstruct['authorized_origins']
        app.production_ready = appstruct['production_ready']
        app.image_url = appstruct['image_url']
        app.description = appstruct['description']

        Session.add(app)

        request.session.flash(_('The changes were saved successfully'),
                              'success')

        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))
    elif 'delete' in request.POST:
        return HTTPFound(location=request.route_path(
            'oauth2_developer_application_delete', app=app.id))
    elif 'cancel' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    # this is a GET
    return {
        'form':
        form.render({
            'name': app.name,
            'main_url': app.main_url,
            'callback_url': app.callback_url,
            'authorized_origins': app.authorized_origins,
            'production_ready': app.production_ready,
            'image_url': app.image_url,
            'description': app.description,
            'client_id': app.id,
            'client_secret': app.secret,
        }),
        'app':
        app,
    }
Ejemplo n.º 40
0
def authorization_endpoint(request):
    response_type = request.params.get('response_type')
    if response_type is None:
        return HTTPBadRequest('Missing required response_type')

    if response_type != 'code':
        return HTTPNotImplemented('Only code is supported')

    client_id = request.params.get('client_id')
    if client_id is None:
        return HTTPBadRequest('Missing required client_type')

    app = request.db.applications.find_one({'client_id': client_id})
    if app is None:
        return HTTPNotFound()

    redirect_uri = request.params.get('redirect_uri')
    if redirect_uri is None:
        redirect_uri = app['callback_url']
    else:
        if redirect_uri != app['callback_url']:
            return HTTPBadRequest(
                'Redirect URI does not match registered callback URL')

    scope = request.params.get('scope', DEFAULT_SCOPE)

    state = request.params.get('state')

    user = assert_authenticated_user_is_registered(request)

    authorizator = Authorizator(request.db, app)

    if 'submit' in request.POST:
        if not authorizator.is_app_authorized(request.user):
            authorizator.store_user_authorization(request.user)

        code = authorizator.auth_codes.create(
            request.user['_id'], app['client_id'], scope)
        url = authorizator.auth_codes.get_redirect_url(
            code, redirect_uri, state)
        return HTTPFound(location=url)

    elif 'cancel' in request.POST:
        return HTTPFound(app['main_url'])

    else:
        if authorizator.is_app_authorized(user):
            code = authorizator.auth_codes.create(
                user['_id'], app['client_id'], scope)
            url = authorizator.auth_codes.get_redirect_url(
                code, redirect_uri, state)
            return HTTPFound(location=url)

        else:
            authorship_information = ''
            owner_id = app.get('owner', None)
            if owner_id is not None:
                owner = request.db.users.find_one({'_id': owner_id})
                if owner:
                    email = owner.get('email', None)
                    if email:
                        authorship_information = _('By ${owner}',
                                                   mapping={'owner': email})

            scopes = [SCOPE_NAMES.get(scope, scope)
                      for scope in scope.split(' ')]
            return {
                'response_type': response_type,
                'client_id': client_id,
                'redirect_uri': redirect_uri,
                'scope': scope,
                'state': state,
                'app': app,
                'scopes': scopes,
                'authorship_information': authorship_information,
                }
Ejemplo n.º 41
0
def contributions_paypal_cancel(request):
    request.session.flash(
        _('Thanks for considering donating to Yith Library. We will be ready if you change your mind'),
        'info',
    )
    return HTTPFound(location=request.route_path('contributions_index'))
Ejemplo n.º 42
0
 def message(self):
     return _('Log in with ${idp}', mapping={'idp': self.name})
Ejemplo n.º 43
0
def register_new_user(request):
    try:
        user_info = request.session['user_info']
    except KeyError:
        return HTTPBadRequest('Missing user info in the session')

    try:
        next_url = request.session['next_url']
    except KeyError:
        next_url = request.route_url('oauth2_clients')

    schema = NewUserSchema()
    button1 = Button('submit', _('Register into Yith Library'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default logout'

    form = Form(schema, buttons=(button1, button2))

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {
                'form': e.render(),
                'provider': user_info.get('provider', ''),
                'email': user_info.get('email', ''),
                'next_url': next_url,
            }

        email = appstruct['email']
        if email != '' and email == user_info['email']:
            email_verified = True
        else:
            email_verified = False

        user_attrs = {
            'screen_name': appstruct['screen_name'],
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'email': email,
            'email_verified': email_verified,
        }

        if request.google_analytics.is_in_session():
            allow_analytics = request.google_analytics.show_in_session()
            user_attrs[analytics.USER_ATTR] = allow_analytics
            request.google_analytics.clean_session()

        user = User(**user_attrs)
        provider = user_info['provider']
        external_id = user_info['external_id']
        user.add_identity(provider, external_id)
        Session.add(user)

        if not email_verified and email != '':
            evc = EmailVerificationCode()
            user.email_verification_code = evc.code
            link = request.route_url('user_verify_email')
            evc.send(request, user, link)

        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        Session.flush()

        request.session['current_provider'] = provider
        return HTTPFound(location=next_url,
                         headers=remember(request, str(user.id)))
    elif 'cancel' in request.POST:
        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        return HTTPFound(location=next_url)

    return {
        'form':
        form.render({
            'first_name': user_info.get('first_name', ''),
            'last_name': user_info.get('last_name', ''),
            'screen_name': user_info.get('screen_name', ''),
            'email': user_info.get('email', ''),
        }),
        'provider':
        user_info.get('provider', ''),
        'email':
        user_info.get('email', ''),
        'next_url':
        next_url,
    }
Ejemplo n.º 44
0
class RequestValidator(oauthlib.oauth2.RequestValidator):

    scopes = {
        'read-passwords': _('Access your passwords'),
        'write-passwords': _('Modify your passwords'),
        'read-userinfo': _('Access your user information'),
    }

    def __init__(self, default_scopes=None):
        if default_scopes is None:
            self.default_scopes = ['read-passwords']
        else:
            self.default_scopes = default_scopes

    def get_client(self, client_id):
        try:
            uuid.UUID(client_id)
        except ValueError:
            client = None
        else:
            try:
                client = Session.query(Application).filter(
                    Application.id == client_id).one()
            except NoResultFound:
                client = None

        return client

    def get_pretty_scopes(self, scopes):
        return [self.scopes.get(scope) for scope in scopes]

    # Pre- and post-authorization

    def validate_client_id(self, client_id, request, *args, **kwargs):
        """Simple validity check, does client exist? Not banned?"""
        request.client = self.get_client(client_id)
        result = request.client is not None
        logger.debug('Validating client id: %s Result: %s', client_id, result)
        return result

    def validate_redirect_uri(self, client_id, redirect_uri, request, *args,
                              **kwargs):
        """Is the client allowed to use the supplied redirect_uri?
        i.e. has the client previously registered this EXACT redirect uri.
        """
        client = request.client or self.get_client(client_id)
        return client.callback_url == redirect_uri

    def get_default_redirect_uri(self, client_id, request, *args, **kwargs):
        """The redirect used if none has been supplied.

        Prefer your clients to pre register a redirect uri rather than
        supplying one on each authorization request.
        """
        client = request.client or self.get_client(client_id)
        return client.callback_url

    def validate_scopes(self, client_id, scopes, client, request, *args,
                        **kwargs):
        """Is the client allowed to access the requested scopes?"""
        valid_scopes = self.scopes.keys()
        return set(valid_scopes).issuperset(set(scopes))

    def get_default_scopes(self, client_id, request, *args, **kwargs):
        """Scopes a client will authorize for if none are supplied in the
        authorization request.
        """
        return self.default_scopes

    def validate_response_type(self, client_id, response_type, client, request,
                               *args, **kwargs):
        """Clients should only be allowed to use one type of response type, the
        one associated with their one allowed grant type.

        In this case it must be "code" or "token".
        """
        # TODO: store the allowed types in the client
        return response_type in ('code', 'token')

    # Post-authorization

    def save_authorization_code(self, client_id, code, request, *args,
                                **kwargs):
        """Remember to associate it with request.scopes, request.redirect_uri
        request.client, request.state and request.user

        (the last is passed in post_authorization credentials,
        i.e. { 'user': request.user}.
        """
        now = datetime.datetime.utcnow()
        expiration = now + datetime.timedelta(minutes=10)

        authorization_code = AuthorizationCode(
            code=code['code'],
            creation=now,
            expiration=expiration,
            scope=request.scopes,
            redirect_uri=request.redirect_uri,
            application=request.client,
            user=request.user,
        )
        Session.add(authorization_code)

    # Token request

    def authenticate_client(self, request, *args, **kwargs):
        """Whichever authentication method suits you, HTTP Basic might work."""
        auth = request.headers.get('Authorization', None)
        if auth:
            auth_type, s = auth.split(' ')
            if auth_type != 'Basic':
                return False
            client_id, client_secret = decode_base64(s).split(':')
            client_id = to_unicode(client_id, 'utf-8')
            client_secret = to_unicode(client_secret, 'utf-8')

        else:
            client_id = getattr(request, 'client_id', None)
            client_secret = getattr(request, 'client_secret', None)
            if client_id is None or client_secret is None:
                return False

        client = self.get_client(client_id)
        if not client:
            return False

        request.client = client
        request.client_id = client_id

        # oauthlib expect the client to has a client_id attribute
        request.client.client_id = client_id

        if client.secret != client_secret:
            return False

        # if client.client_type != 'confidential':
        #     return False

        return True

    def authenticate_client_id(self, client_id, request, *args, **kwargs):
        """Don't allow public (non-authenticated) clients."""
        raise NotImplementedError()

    def validate_code(self, client_id, code, client, request, *args, **kwargs):
        """Validate the code belongs to the client.

        Add associated scopes, state and user to request.scopes, request.state
        and request.user.
        """
        try:
            record = Session.query(AuthorizationCode).filter(
                AuthorizationCode.code == code,
                AuthorizationCode.application == request.client,
            ).one()
        except NoResultFound:
            record = None

        if record is None:
            return False

        if datetime.datetime.utcnow() > record.expiration:
            return False

        request.user = record.user
        request.scopes = record.scope
        return True

    def confirm_redirect_uri(self, client_id, code, redirect_uri, client,
                             *args, **kwargs):
        """You did save the redirect uri with the authorization code right?"""
        if redirect_uri is None:
            return True

        try:
            authorization_code = Session.query(AuthorizationCode).filter(
                AuthorizationCode.code == code,
                AuthorizationCode.application == client,
            ).one()
        except NoResultFound:
            authorization_code = None

        if authorization_code is None:
            return False

        return authorization_code.redirect_uri == redirect_uri

    def validate_grant_type(self, client_id, grant_type, client, request,
                            *args, **kwargs):
        """Clients should only be allowed to use one type of grant.

        In this case, it must be "authorization_code" or "refresh_token".
        """
        return grant_type == 'authorization_code'

    def save_bearer_token(self, token, request, *args, **kwargs):
        """Remember to associate it with request.scopes, request.user and
        request.client.

        The two former will be set when you validate# the authorization code.
        Don't forget to save both the access_token and the refresh_token and
        set expiration for the access_token to now + expires_in seconds.
        """
        now = datetime.datetime.utcnow()
        expiration = now + datetime.timedelta(seconds=token['expires_in'])
        access_code = AccessCode(
            code=token['access_token'],
            code_type=token['token_type'],
            expiration=expiration,
            refresh_code=token.get('refresh_token', ''),
            user=request.user,
            scope=request.scopes,
            application=request.client,
        )
        Session.add(access_code)

    def invalidate_authorization_code(self, client_id, code, request, *args,
                                      **kwargs):
        """Authorization codes are use once, invalidate it when a Bearer token
        has been acquired.
        """
        authorization_code = Session.query(AuthorizationCode).filter(
            AuthorizationCode.code == code,
            AuthorizationCode.application == request.client,
        ).one()
        Session.delete(authorization_code)

    # Protected resource request

    def validate_bearer_token(self, token, scopes, request):
        """Remember to check expiration and scope membership"""
        if token is None:
            return False

        try:
            access_code = Session.query(AccessCode).filter(
                AccessCode.code == token, ).one()
        except NoResultFound:
            access_code = None

        if access_code is None:
            return False

        if datetime.datetime.utcnow() > access_code.expiration:
            return False

        if not set(access_code.scope).issuperset(set(scopes)):
            return False

        request.access_token = access_code
        request.user = access_code.user
        request.scopes = scopes
        request.client_id = access_code.application_id
        request.client = access_code.application

        return True

    # Token refresh request

    def get_original_scopes(self, refresh_token, request, *args, **kwargs):
        """Obtain the token associated with the given refresh_token and
        return its scopes, these will be passed on to the refreshed access
        token if the client did not specify a scope during the request.
        """
        raise NotImplementedError()
Ejemplo n.º 45
0
 def message(self):
     return _("Log in with ${idp}", mapping={"idp": self.name.capitalize()})
Ejemplo n.º 46
0
def contact(request):
    button1 = Button('submit', _('Send message'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = ''

    form = Form(ContactSchema(), buttons=(button1, button2))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render()}

        context = {'link': request.route_url('contact')}
        context.update(appstruct)

        text_body = render('yithlibraryserver:templates/email_contact.txt',
                           context, request=request)

        # chamaleon txt templates are rendered as utf-8 bytestrings
        text_body = text_body.decode('utf-8')

        html_body = render('yithlibraryserver:templates/email_contact.pt',
                           context, request=request)

        admin_emails = request.registry.settings['admin_emails']

        if admin_emails:
            message = Message(
                subject=("%s sent a message from Yith's contact form" %
                         appstruct['name']),
                recipients=request.registry.settings['admin_emails'],
                body=text_body,
                html=html_body,
                extra_headers={'Reply-To': appstruct['email']},
                )

            get_mailer(request).send(message)
        else:
            log.error(
                '%s <%s> tried to send a message from the contact form but no '
                'admin emails were configured. Message: %s' % (
                    appstruct['name'],
                    appstruct['email'],
                    appstruct['message'],
                    )
                )

        request.session.flash(
            _('Thank you very much for sharing your opinion'),
            'info',
            )

        return HTTPFound(location=request.route_path('home'))

    elif 'cancel' in request.POST:
        return HTTPFound(location=request.route_path('home'))

    initial = {}
    if request.user is not None:
        initial['name'] = request.user.get('first_name', '')
        if request.user.get('email_verified', False):
            initial['email'] = request.user.get('email', '')

    return {'form': form.render(initial)}
Ejemplo n.º 47
0
def register_new_user(request):
    try:
        user_info = request.session['user_info']
    except KeyError:
        return HTTPBadRequest('Missing user info in the session')

    try:
        next_url = request.session['next_url']
    except KeyError:
        next_url = request.route_url('oauth2_clients')

    schema = NewUserSchema()
    button1 = Button('submit', _('Register into Yith Library'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default logout'

    form = Form(schema, buttons=(button1, button2))

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {
                'form': e.render(),
                'provider': user_info.get('provider', ''),
                'email': user_info.get('email', ''),
                'next_url': next_url,
            }

        email = appstruct['email']
        if email != '' and email == user_info['email']:
            email_verified = True
        else:
            email_verified = False

        user_attrs = {
            'screen_name': appstruct['screen_name'],
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'email': email,
            'email_verified': email_verified,
        }

        if request.google_analytics.is_in_session():
            allow_analytics = request.google_analytics.show_in_session()
            user_attrs[analytics.USER_ATTR] = allow_analytics
            request.google_analytics.clean_session()

        user = User(**user_attrs)
        provider = user_info['provider']
        external_id = user_info['external_id']
        user.add_identity(provider, external_id)
        Session.add(user)

        if not email_verified and email != '':
            evc = EmailVerificationCode()
            user.email_verification_code = evc.code
            link = request.route_url('user_verify_email')
            evc.send(request, user, link)

        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        Session.flush()

        request.session['current_provider'] = provider
        return HTTPFound(location=next_url,
                         headers=remember(request, str(user.id)))
    elif 'cancel' in request.POST:
        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        return HTTPFound(location=next_url)

    return {
        'form': form.render({
            'first_name': user_info.get('first_name', ''),
            'last_name': user_info.get('last_name', ''),
            'screen_name': user_info.get('screen_name', ''),
            'email': user_info.get('email', ''),
        }),
        'provider': user_info.get('provider', ''),
        'email': user_info.get('email', ''),
        'next_url': next_url,
    }
Ejemplo n.º 48
0
def developer_application_edit(request):
    try:
        app_id = bson.ObjectId(request.matchdict['app'])
    except bson.errors.InvalidId:
        return HTTPBadRequest(body='Invalid application id')

    assert_authenticated_user_is_registered(request)

    app = request.db.applications.find_one(app_id)
    if app is None:
        return HTTPNotFound()

    if app['owner'] != request.user['_id']:
        return HTTPUnauthorized()

    schema = FullApplicationSchema()
    button1 = Button('submit', _('Save application'))
    button1.css_class = 'btn-primary'
    button2 = Button('delete', _('Delete application'))
    button2.css_class = 'btn-danger'
    button3 = Button('cancel', _('Cancel'))
    button3.css_class = ''
    form = Form(schema, buttons=(button1, button2, button3))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render(), 'app': app}

        # the data is fine, save into the db
        application = {
            'owner': request.user['_id'],
            'name': appstruct['name'],
            'main_url': appstruct['main_url'],
            'callback_url': appstruct['callback_url'],
            'authorized_origins': appstruct['authorized_origins'],
            'production_ready': appstruct['production_ready'],
            'image_url': appstruct['image_url'],
            'description': appstruct['description'],
            'client_id': app['client_id'],
            'client_secret': app['client_secret'],
            }

        request.db.applications.update({'_id': app['_id']},
                                       application, safe=True)

        request.session.flash(_('The changes were saved successfully'),
                              'success')

        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))
    elif 'delete' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_application_delete',
                                        app=app['_id']))
    elif 'cancel' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    # this is a GET
    return {'form': form.render(app), 'app': app}
Ejemplo n.º 49
0
def developer_application_edit(request):
    app_id = request.matchdict['app']

    try:
        uuid.UUID(app_id)
    except ValueError:
        return HTTPBadRequest()

    try:
        app = Session.query(Application).filter(Application.id == app_id).one()
    except NoResultFound:
        return HTTPNotFound()

    assert_authenticated_user_is_registered(request)

    if app.user != request.user:
        return HTTPUnauthorized()

    schema = FullApplicationSchema()
    button1 = Button('submit', _('Save application'))
    button1.css_class = 'btn-primary'
    button2 = Button('delete', _('Delete application'))
    button2.css_class = 'btn-danger'
    button3 = Button('cancel', _('Cancel'))
    button3.css_class = 'btn-default'
    form = Form(schema, buttons=(button1, button2, button3))

    if 'submit' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {'form': e.render(), 'app': app}

        # the data is fine, save into the db
        app.name = appstruct['name']
        app.main_url = appstruct['main_url']
        app.callback_url = appstruct['callback_url']
        app.authorized_origins = appstruct['authorized_origins']
        app.production_ready = appstruct['production_ready']
        app.image_url = appstruct['image_url']
        app.description = appstruct['description']

        Session.add(app)

        request.session.flash(_('The changes were saved successfully'),
                              'success')

        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))
    elif 'delete' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_application_delete',
                                        app=app.id))
    elif 'cancel' in request.POST:
        return HTTPFound(
            location=request.route_path('oauth2_developer_applications'))

    # this is a GET
    return {
        'form': form.render({
            'name': app.name,
            'main_url': app.main_url,
            'callback_url': app.callback_url,
            'authorized_origins': app.authorized_origins,
            'production_ready': app.production_ready,
            'image_url': app.image_url,
            'description': app.description,
            'client_id': app.id,
            'client_secret': app.secret,
        }),
        'app': app,
    }
Ejemplo n.º 50
0
def contributions_paypal_success(request):
    error_msg = _('There was a problem in the confirmation process. Please start the checkout again')
    if request.method == 'POST':
        if 'submit' in request.POST:
            token = request.POST.get('token', None)
            payerid = request.POST.get('payerid', None)
            amount = request.POST.get('amount', None)

            success = False

            if token and payerid and amount:
                try:
                    amount = int(amount)
                except ValueError:
                    return HTTPBadRequest('Amount must be an integer')

                paypal = PayPalExpressCheckout(request)
                success = paypal.do_express_checkout_payment(token, payerid,
                                                             amount)

            if success:
                donation = Donation(
                    amount=amount,
                    first_name=request.POST['firstname'],
                    last_name=request.POST['lastname'],
                    city=request.POST['city'],
                    country=request.POST['country'],
                    state=request.POST['state'],
                    street=request.POST['street'],
                    zipcode=request.POST['zip'],
                    email=request.POST['email'],
                )
                if donation.should_include_sticker():
                    if 'no-sticker' in request.POST:
                        donation.send_sticker = False
                    else:
                        donation.send_sticker = True
                else:
                    donation.send_sticker = False

                donation.user = request.user

                Session.add(donation)
                Session.flush()

                send_thankyou_email(request, donation)
                send_notification_to_admins(request, donation)
                request.session.flash(
                    _('Thank you very much for your great contribution'),
                    'success',
                )
            else:
                request.session.flash(error_msg, 'error')

            return HTTPFound(location=request.route_path('contributions_index'))

        elif 'cancel' in request.POST:
            return HTTPFound(location=request.route_path('contributions_paypal_cancel_callback'))

        else:
            return HTTPBadRequest('Wrong action')

    else:
        token = request.GET.get('token', None)
        payerid = request.GET.get('PayerID', None)

        if token and payerid:
            paypal = PayPalExpressCheckout(request)
            details = paypal.get_express_checkout_details(token, payerid)
            details.update({
                'token': token,
                'payerid': payerid,
            })
            amount = details['amount']
            details['include_sticker'] = include_sticker(amount)
            return details
        else:
            request.session.flash(error_msg, 'error')
            return HTTPFound(location=request.route_path('contributions_index'))
Ejemplo n.º 51
0
def register_new_user(request):
    try:
        user_info = request.session['user_info']
    except KeyError:
        return HTTPBadRequest('Missing user info in the session')

    try:
        next_url = request.session['next_url']
    except KeyError:
        next_url = request.route_url('oauth2_clients')

    schema = NewUserSchema()
    button1 = Button('submit', _('Register into Yith Library'))
    button1.css_class = 'btn-primary'
    button2 = Button('cancel', _('Cancel'))
    button2.css_class = 'btn-default logout'

    form = Form(schema, buttons=(button1, button2))

    if 'submit' in request.POST:

        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except ValidationFailure as e:
            return {
                'form': e.render(),
                'provider': user_info.get('provider', ''),
                'email': user_info.get('email', ''),
                'next_url': next_url,
            }

        provider = user_info['provider']
        provider_key = provider + '_id'

        email = appstruct['email']
        if email != '' and email == user_info['email']:
            email_verified = True
        else:
            email_verified = False

        now = datetime.datetime.now(tz=utc)

        user_attrs = {
            provider_key: user_info[provider_key],
            'screen_name': appstruct['screen_name'],
            'first_name': appstruct['first_name'],
            'last_name': appstruct['last_name'],
            'email': email,
            'email_verified': email_verified,
            'date_joined': now,
            'last_login': now,
            'send_passwords_periodically': False,
        }

        if request.google_analytics.is_in_session():
            allow_analytics = request.google_analytics.show_in_session()
            user_attrs[analytics.USER_ATTR] = allow_analytics
            request.google_analytics.clean_session()

        _id = request.db.users.insert(user_attrs)

        if not email_verified and email != '':
            evc = EmailVerificationCode()
            user = request.db.users.find_one({'_id': _id})
            if evc.store(request.db, user):
                link = request.route_url('user_verify_email')
                evc.send(request, user, link)

        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        request.session['current_provider'] = provider
        return HTTPFound(location=next_url,
                         headers=remember(request, str(_id)))
    elif 'cancel' in request.POST:
        del request.session['user_info']
        if 'next_url' in request.session:
            del request.session['next_url']

        return HTTPFound(location=next_url)

    return {
        'form': form.render({
            'first_name': user_info.get('first_name', ''),
            'last_name': user_info.get('last_name', ''),
            'screen_name': user_info.get('screen_name', ''),
            'email': user_info.get('email', ''),
        }),
        'provider': user_info.get('provider', ''),
        'email': user_info.get('email', ''),
        'next_url': next_url,
    }
Ejemplo n.º 52
0
 def message(self):
     return _('Log in with ${idp}', mapping={'idp': self.name})