예제 #1
0
    def get_user(self, username):
        """Allows an admin to fetch specific user data
        """
        user = User.find_by_identity(username)

        if user is None:
            response = {'error': USER_NOT_FOUND}
            return response, 404

        invoices = Invoice.billing_history(user=user)
        if user.subscription:
            # get the upcoming invoice from Stripe
            upcoming = Invoice.upcoming(customer_id=user.payment_id)
        else:
            upcoming = None

        dumped_user = user_detail_schema.dump(user)
        dumped_invoices = invoices_schema.dump(invoices)
        response = {
            'data': {
                'user': dumped_user,
                'invoices': dumped_invoices,
                'upcoming_invoice': upcoming
            }
        }
        return response
예제 #2
0
def users(db):
    """
    Create user fixtures. They reset per test.

    :param db: Pytest fixture
    :return: SQLAlchemy database session
    """
    # db.session.query(User).delete()

    users = [
        {
            'role': 'admin',
            'email': '*****@*****.**',
            'username': '******',
            'password': '******'
        },
        {
            'email': '*****@*****.**',
            'username': '******',
            'password': '******'
        }
    ]

    for user in users:
        exists = User.find_by_identity(user['username'])
        if exists:
            exists.delete()
        db.session.add(User(**user))

    db.session.commit()

    return db
예제 #3
0
    def edit_user(self, username):
        """
        Admins can edit user accounts, for example if the username is
        offensive/goes against guidelines or update their permissions
        """
        # find the User
        user = User.find_by_identity(username)

        if user is None:
            response = {'error': USER_NOT_FOUND}
            return response, 404

        # load the json data
        json_data = request.get_json()

        # check for errors
        if not json_data:
            response = {'error': 'Invalid input.'}
            return response, 400

        try:
            data = admin_edit_user_schema.load(json_data)
        except ValidationError as err:
            response = {'error': err.messages}
            return response, 422

        # check if user is the last admin
        if User.is_last_admin(user, data['role']):
            response = {'error': 'User is the last admin in the system.'}
            return response, 400

        # is username being changed
        if user.username != data['username']:
            existing_username = User.find_by_identity(data['username'])
            if existing_username is None:
                user.username = data['username']
            else:
                response = {'error': 'Username is already taken.'}
                return response, 400

        user.role = data['role']
        user.save()

        headers = {
            'Location': url_for('AdminView:get_user', username=user.username)
        }
        return '', 204, headers
예제 #4
0
    def test_deliver_verification_email(self, token):
        """Successfully deliver a verification email"""
        with mail.record_messages() as outbox:
            user = User.find_by_identity('*****@*****.**')
            deliver_verification_email(user.id, token)

            assert len(outbox) == 1
            assert token in outbox[0].body
예제 #5
0
def token(db):
    """
    Serialize a JWS token.

    :param db: Pytest fixture
    :return: JWS token
    """
    user = User.find_by_identity('*****@*****.**')
    return user.serialize_token()
예제 #6
0
def ensure_unique_identity(data):
    """
    Ensures that an email and/or username is not already taken

    :return: data from the request
    """
    user = User.find_by_identity(data)

    if user:
        raise ValidationError('{0} already exists.'.format(data))

    return data
예제 #7
0
    def test_edit_user(self, subscriptions):
        """Successfully update a user account and set location headers"""
        self.authenticate()
        data = {'role': 'admin', 'username': '******'}
        response = self.client.put(url_for('AdminView:edit_user',
                                           username='******'),
                                   json=data)
        location = response.headers['Location']
        assert response.status_code == 204
        assert location == url_for('AdminView:get_user', username='******')

        user = User.find_by_identity('firstSub1')
        assert user.role == 'admin'
예제 #8
0
    def test_cancel_subscription(self, subscriptions, mock_stripe):
        """Successfully cancel a user's subscription"""
        self.authenticate()
        response = self.client.delete(
            url_for('AdminView:cancel_subscription', username='******'))
        data = response.get_json()['data']

        assert response.status_code == 200
        assert data['deleted'] is True
        assert data['message'] == 'User\'s subscription has been cancelled.'

        user = User.find_by_identity('firstSub1')
        assert user.subscription is None
        assert user.cancelled_subscription_on <= \
            datetime.datetime.now(pytz.utc)
예제 #9
0
def subscriptions(db):
    """
    Create subscription fixutres.

    :param db: Pytest fixture
    :return: SQLAlchemy database session
    """
    subscriber = User.find_by_identity('*****@*****.**')
    if subscriber:
        subscriber.delete()
    db.session.query(Subscription).delete()

    params = {
        'role': 'member',
        'email': '*****@*****.**',
        'username': '******',
        'name': 'Subby',
        'payment_id': 'cus_000',
        'password': '******',
        'active': True
    }

    subscriber = User(**params)
    # User needs to be commited to be able to assign a subscription to it
    db.session.add(subscriber)
    db.session.commit()

    # Create a subscription
    params = {
        'user_id': subscriber.id,
        'plan': 'gold'
    }
    subscription = Subscription(**params)
    db.session.add(subscription)

    # Create the users CC
    params = {
        'user_id': subscriber.id,
        'brand': 'Visa',
        'last4': '4242',
        'exp_date': datetime.date(2019, 6, 1)
    }
    credit_card = CreditCard(**params)
    db.session.add(credit_card)

    db.session.commit()

    return db
예제 #10
0
    def post(self):
        json_data = request.get_json()

        if not json_data:
            response = jsonify({'error': 'Invalid input.'})
            return response, 400

        try:
            data = auth_schema.load(json_data)
        except ValidationError as err:
            response = jsonify({'error': err.messages})

            return response, 422

        user = User.find_by_identity(data['identity'])

        if user and user.authenticated(password=data['password']):
            if user.is_active():
                # identity is used to lookup a user on protected endpoints
                access_token = create_access_token(identity=user.username)

                user.update_activity_tracking(request.remote_addr)

                response = jsonify({'data': {'access_token': access_token}})

                # Set the JWTs and the CSRF double submit protection cookies
                # Clients such as web browsers support cookies and
                # "set_access_cookies" will set two cookies in the browser,
                # 1)access_token 2)CSRF token
                set_access_cookies(response, access_token)

                return response, 200
            else:
                error = ('This account is not active. If you recently signed'
                         ' up for an account, check your email for a'
                         ' verification link.')
                return jsonify({'error': error}), 400

        response = jsonify({'error': 'Invalid credentials.'})
        return response, 401
예제 #11
0
    def cancel_subscription(self, username):
        """Admins can canel a user's subscription"""

        user = User.find_by_identity(username)

        if user is None:
            response = {'error': USER_NOT_FOUND}
            return response, 404

        if not user.subscription:
            error = '{0} doesn\'t have an active subscription.'.format(
                username)
            response = {'error': error}
            return response, 400

        subscription = Subscription()
        subscription.cancel(user=user)
        response = {
            'data': {
                'deleted': True,
                'message': 'User\'s subscription has been cancelled.'
            }
        }
        return response, 200
예제 #12
0
 def test_is_active(self):
     user = User.find_by_identity('*****@*****.**')
     assert user.is_active() is True