Example #1
0
    def test_identity_manager_notification_org(self):

        from django.conf import settings
        settings.OILAUTH = True
        
        # Mock purchase info
        purchase = MagicMock()
        purchase.offering.notification_url = ''
        purchase.offering.applications = [{
            'id': 1,
            'name': 'test_app1'
        }]
        purchase.organization_owned = True
        purchase.offering.owner_organization.name = 'test_user'
        purchase.owner_organization.actor_id = 2
        purchase.offering.version = '1.0'
        purchase.offering.name = 'test_offering'
        purchase.ref = '11111'

        self.user.userprofile.access_token = 'aaa'
        self.user.userprofile.save()
        purchase.customer = self.user

        notify_provider.notify_provider(purchase)
        opener = self._urllib._opener

        content = json.loads(opener._body)

        self.assertEquals(len(content['applications']), 1)
        self.assertEquals(content['applications'][0]['id'], 1)
        self.assertEquals(content['applications'][0]['name'], 'test_app1')
        self.assertEquals(content['customer'], 2)
Example #2
0
    def test_provider_notification(self):

        settings.OILAUTH = False
        notify_provider.requests = MagicMock(name="requests")
        purchase = Purchase.objects.get(pk='61005aba8e05ac2115f022f0')

        expected_data = {
            'offering': {
                'name': 'test_offering',
                'organization': 'test_organization',
                'version': '1.0'
            },
            'customer':
            'test_organization1',
            'reference':
            '61005aba8e05ac2115f022f0',
            'resources': [{
                "url":
                "http://antares.ls.fi.upm.es:8000/media/resources/test_user__test_resource__1.0",
                "version": "1.0",
                "name": "test_resource",
                "content_type": ""
            }]
        }

        headers = {'Content-type': 'application/json'}
        notify_provider.notify_provider(purchase)
        notify_provider.requests.post.assert_called_with(
            purchase.offering.notification_url,
            data=json.dumps(expected_data),
            headers=headers,
            cert=(settings.NOTIF_CERT_FILE, settings.NOTIF_CERT_KEY_FILE))
Example #3
0
    def test_provider_notification(self):

        settings.OILAUTH = False
        notify_provider.requests = MagicMock(name="requests")
        purchase = Purchase.objects.get(pk='61005aba8e05ac2115f022f0')

        expected_data = {
            'offering':  {
                'name': 'test_offering',
                'organization': 'test_organization',
                'version': '1.0'
            },
            'customer': 'test_organization1',
            'reference': '61005aba8e05ac2115f022f0',
            'resources': [{
                "url": "http://antares.ls.fi.upm.es:8000/media/resources/test_user__test_resource__1.0",
                "version": "1.0",
                "name": "test_resource",
                "content_type": ""
            }]
        }

        headers = {
            'Content-type': 'application/json'
        }
        notify_provider.notify_provider(purchase)
        notify_provider.requests.post.assert_called_with(
            purchase.offering.notification_url,
            data=json.dumps(expected_data),
            headers=headers,
            cert=(settings.NOTIF_CERT_FILE, settings.NOTIF_CERT_KEY_FILE)
        )
Example #4
0
    def test_provider_notification(self):

        purchase = Purchase.objects.get(pk='61005aba8e05ac2115f022f0')
        notify_provider.notify_provider(purchase)

        opener = self._urllib._opener

        content = json.loads(opener._body)

        self.assertEqual(content['offering']['name'], 'test_offering')
        self.assertEqual(content['offering']['organization'], 'test_organization')
        self.assertEqual(content['offering']['version'], '1.0')

        self.assertEqual(content['customer'], 'test_organization1')
        self.assertEqual(content['reference'], '61005aba8e05ac2115f022f0')
Example #5
0
    def test_identity_manager_notification_token_refresh(self):

        from django.conf import settings
        settings.OILAUTH = True
        
        # Mock purchase info
        purchase = MagicMock()
        purchase.offering.notification_url = ''
        purchase.offering.applications = [{
            'id': 1,
            'name': 'test_app1'
        }]
        purchase.organization_owned = True
        purchase.offering.owner_organization.name = 'test_user'
        purchase.owner_organization.actor_id = 2
        purchase.offering.version = '1.0'
        purchase.offering.name = 'test_offering'
        purchase.ref = '11111'

        self.user.userprofile.access_token = 'bca'
        self.user.userprofile.save()

        # Mock social auth methods
        UserSocialAuth.refresh_token = MagicMock()
        user_social_auth = UserSocialAuth.objects.create(user=self.user, provider='fiware')

        user_social_auth.extra_data = {
            'access_token': 'bbb',
            'refresh_token': 'ccc'
        }

        user_social_auth.save()
        self.user.social_auth = [user_social_auth]

        purchase.customer = self.user

        # Call the tested method
        notify_provider.notify_provider(purchase)
        opener = self._urllib._opener

        content = json.loads(opener._body)

        UserSocialAuth.refresh_token.assert_any_call()
        self.assertEquals(len(content['applications']), 1)
        self.assertEquals(content['applications'][0]['id'], 1)
        self.assertEquals(content['applications'][0]['name'], 'test_app1')
        self.assertEquals(content['customer'], 2)
Example #6
0
    def read(self, request, reference):
        purchase = None
        try:
            token = request.GET.get('token')
            payer_id = request.GET.get('PayerID', '')

            db = get_database_connection()

            # Uses an atomic operation to get and set the _lock value in the purchase
            # document
            pre_value = db.wstore_purchase.find_and_modify(
                query={'_id': ObjectId(reference)},
                update={'$set': {'_lock': True}}
            )

            # If the value of _lock before setting it to true was true, means
            # that the time out function has acquired it previously so the
            # view ends
            if '_lock' in pre_value and pre_value['_lock']:
                raise Exception('')

            purchase = Purchase.objects.get(ref=reference)

            # Check that the request user is authorized to end the payment
            if request.user.userprofile.current_organization != purchase.owner_organization:
                raise Exception()

            # If the purchase state value is different from pending means that
            # the timeout function has completely ended before acquire the resource
            # so _lock is set to false and the view ends
            if purchase.state != 'pending':
                db.wstore_purchase.find_and_modify(
                    query={'_id': ObjectId(reference)},
                    update={'$set': {'_lock': False}}
                )
                raise Exception('')

            pending_info = purchase.contract.pending_payment

            # Get the payment client
            # Load payment client
            cln_str = settings.PAYMENT_CLIENT
            client_class = cln_str.split('.')[-1]
            client_package = cln_str.partition('.' + client_class)[0]

            payment_client = getattr(__import__(client_package, globals(), locals(), [client_class], -1), client_class)

            # build the payment client
            client = payment_client(purchase)
            client.end_redirection_payment(token, payer_id)

            charging_engine = ChargingEngine(purchase)
            accounting = None
            if 'accounting' in pending_info:
                accounting = pending_info['accounting']

            charging_engine.end_charging(pending_info['price'], pending_info['concept'], pending_info['related_model'], accounting)
        except:
            # Rollback the purchase if existing
            if purchase is not None:
                rollback(purchase)

            context = {
                'title': 'Payment Canceled',
                'message': 'Your payment has been canceled. An error occurs or the timeout has finished, if you want to acquire the offering purchase it again in WStore.'
            }
            return render(request, 'err_msg.html', context)

        # Check if is the first payment
        if len(purchase.contract.charges) == 1:

            if purchase.organization_owned:
                org = purchase.owner_organization
                org.offerings_purchased.append(purchase.offering.pk)
                org.save()
            else:
                # Add the offering to the user profile
                user_profile = UserProfile.objects.get(user=purchase.customer)
                user_profile.offerings_purchased.append(purchase.offering.pk)
                user_profile.save()

            notify_provider(purchase)

        # _lock is set to false
        db.wstore_purchase.find_and_modify(
            query={'_id': reference},
            update={'$set': {'_lock': False}}
        )

        # Return the confirmation web page
        context = {
            'title': 'Payment Confirmed',
            'message': 'Your payment has been received. To download the resources and the invoice go to the offering details page.'
        }
        return render(request, 'err_msg.html', context)
def create_purchase(user, offering, org_owned=False, payment_info=None):

    if offering.state != 'published':
        raise PermissionDenied("This offering can't be purchased")

    if offering.open:
        raise PermissionDenied('Open offerings cannot be purchased')

    if accepted_needed(offering) and not payment_info['accepted']:
        raise PermissionDenied('You must accept the terms and conditions of the offering to acquire it')
 
    profile = UserProfile.objects.get(user=user)

    # Check if the offering is already purchased
    if (org_owned and offering.pk in profile.current_organization.offerings_purchased) \
    or (not org_owned and offering.pk in profile.offerings_purchased):
            raise PermissionDenied('The offering has been already purchased')

    organization = profile.current_organization

    plan = None
    # Check the selected plan
    if payment_info and 'plan' in payment_info:
        plan = payment_info['plan']

    # Get the effective tax address
    if not 'tax_address' in payment_info:
        if org_owned:
            tax = organization.tax_address
        else:
            tax = profile.tax_address

        # Check that the customer has a tax address
        if not 'street' in tax:
            raise ValueError('The customer does not have a tax address')
    else:
        tax = payment_info['tax_address']

        # Check tax_address fields
        if (not 'street' in tax) or (not 'postal' in tax) or (not 'city' in tax) or (not 'country' in tax):
            raise ValueError('The tax address is not valid')

    # Check the payment method before purchase creation in order to avoid
    # an inconsistent state in the database
    credit_card_info = None
    if payment_info['payment_method'] == 'credit_card':
        if 'credit_card' in payment_info:
            # Check credit card info
            if (not ('number' in payment_info['credit_card'])) or (not ('type' in payment_info['credit_card']))\
            or (not ('expire_year' in payment_info['credit_card'])) or (not ('expire_month' in payment_info['credit_card']))\
            or (not ('cvv2' in payment_info['credit_card'])):
                raise ValueError('Invalid credit card info')

            credit_card_info = payment_info['credit_card']
        else:
            if org_owned:
                credit_card_info = organization.payment_info
            else:
                credit_card_info = profile.payment_info

            # Check the credit card info
            if not 'number' in credit_card_info:
                raise Exception('The customer does not have payment info')

    elif payment_info['payment_method'] != 'paypal':
        raise ValueError('Invalid payment method')

    # Create the purchase
    purchase = Purchase.objects.create(
        customer=user,
        date=datetime.now(),
        offering=offering,
        organization_owned=org_owned,
        state='pending',
        tax_address=tax,
        owner_organization = organization
    )

    # Load ref
    purchase.ref = purchase.pk
    purchase.save()

    if credit_card_info != None:
        charging_engine = ChargingEngine(purchase, payment_method='credit_card', credit_card=credit_card_info, plan=plan)
    else:
        charging_engine = ChargingEngine(purchase, payment_method='paypal', plan=plan)

    redirect_url = charging_engine.resolve_charging(new_purchase=True)

    if redirect_url == None:
        result = purchase

        # If no redirect URL is provided the purchase has ended so the user profile
        # info is updated
        if org_owned:
            organization.offerings_purchased.append(offering.pk)
            organization.save()
        else:
            profile.offerings_purchased.append(offering.pk)
            profile.save()

        notify_provider(purchase)

    else:
        result = redirect_url

    # Update offering indexes
    index_path = settings.DATADIR
    index_path = os.path.join(index_path, 'search')
    index_path = os.path.join(index_path, 'indexes')

    se = SearchEngine(index_path)
    se.update_index(offering)

    return result
Example #8
0
    def read(self, request, reference):
        purchase = None
        try:
            token = request.GET.get('token')
            payer_id = request.GET.get('PayerID', '')

            db = get_database_connection()

            # Uses an atomic operation to get and set the _lock value in the purchase
            # document
            pre_value = db.wstore_purchase.find_and_modify(
                query={'_id': ObjectId(reference)},
                update={'$set': {
                    '_lock': True
                }})

            # If the value of _lock before setting it to true was true, means
            # that the time out function has acquired it previously so the
            # view ends
            if '_lock' in pre_value and pre_value['_lock']:
                raise Exception('')

            purchase = Purchase.objects.get(ref=reference)

            # Check that the request user is authorized to end the payment
            if request.user.userprofile.current_organization != purchase.owner_organization:
                raise Exception()

            # If the purchase state value is different from pending means that
            # the timeout function has completely ended before acquire the resource
            # so _lock is set to false and the view ends
            if purchase.state != 'pending':
                db.wstore_purchase.find_and_modify(
                    query={'_id': ObjectId(reference)},
                    update={'$set': {
                        '_lock': False
                    }})
                raise Exception('')

            pending_info = purchase.contract.pending_payment

            # Get the payment client
            # Load payment client
            cln_str = settings.PAYMENT_CLIENT
            client_class = cln_str.split('.')[-1]
            client_package = cln_str.partition('.' + client_class)[0]

            payment_client = getattr(
                __import__(client_package, globals(), locals(), [client_class],
                           -1), client_class)

            # build the payment client
            client = payment_client(purchase)
            client.end_redirection_payment(token, payer_id)

            charging_engine = ChargingEngine(purchase)
            accounting = None
            if 'accounting' in pending_info:
                accounting = pending_info['accounting']

            charging_engine.end_charging(pending_info['price'],
                                         pending_info['concept'],
                                         pending_info['related_model'],
                                         accounting)
        except:
            # Rollback the purchase if existing
            if purchase is not None:
                rollback(purchase)

            context = {
                'title':
                'Payment Canceled',
                'message':
                'Your payment has been canceled. An error occurs or the timeout has finished, if you want to acquire the offering purchase it again in WStore.'
            }
            return render(request, 'err_msg.html', context)

        # Check if is the first payment
        if len(purchase.contract.charges) == 1:

            if purchase.organization_owned:
                org = purchase.owner_organization
                org.offerings_purchased.append(purchase.offering.pk)
                org.save()
            else:
                # Add the offering to the user profile
                user_profile = UserProfile.objects.get(user=purchase.customer)
                user_profile.offerings_purchased.append(purchase.offering.pk)
                user_profile.save()

            notify_provider(purchase)

        # _lock is set to false
        db.wstore_purchase.find_and_modify(query={'_id': reference},
                                           update={'$set': {
                                               '_lock': False
                                           }})

        # Return the confirmation web page
        context = {
            'title':
            'Payment Confirmed',
            'message':
            'Your payment has been received. To download the resources and the invoice go to the offering details page.'
        }
        return render(request, 'err_msg.html', context)