Exemplo n.º 1
0
    def _timeout_handler(self):

        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(self._purchase.pk)},
            update={'$set': {
                '_lock': True
            }})

        # If _lock not exists or is set to false means that this function has
        # acquired the resource
        if '_lock' not in pre_value or not pre_value['_lock']:

            # Only rollback if the state is pending
            if pre_value['state'] == 'pending':
                # Refresh the purchase
                purchase = Purchase.objects.get(pk=self._purchase.pk)
                rollback(purchase)

            db.wstore_purchase.find_and_modify(
                query={'_id': ObjectId(self._purchase.pk)},
                update={'$set': {
                    '_lock': False
                }})
    def _timeout_handler(self):

        db = get_database_connection()

        # Uses an atomic operation to get and set the _lock value in the purchase
        # document
        pre_value = db.wstore_order.find_one_and_update(
            {'_id': ObjectId(self._order.pk)},
            {'$set': {'_lock': True}}
        )

        # If _lock not exists or is set to false means that this function has
        # acquired the resource
        if '_lock' not in pre_value or not pre_value['_lock']:

            # Only rollback if the state is pending
            if pre_value['state'] == 'pending':
                order = Order.objects.get(pk=self._order.pk)
                timeout_processors = {
                    'initial': self._initial_charge_timeout,
                    'recurring': self._renew_charge_timeout,
                    'usage': self._renew_charge_timeout
                }
                timeout_processors[self._concept](order)

            db.wstore_order.find_one_and_update(
                {'_id': ObjectId(self._order.pk)},
                {'$set': {'_lock': False}}
            )
Exemplo n.º 3
0
    def _generate_cdr_part(self, part, event, description):
        # Create connection for raw database access
        db = get_database_connection()

        # Take and increment the correlation number using
        # the mongoDB atomic access in order to avoid race
        # problems
        corr_number = db.wstore_organization.find_and_modify(
            query={'_id': ObjectId(self._offering.owner_organization.pk)},
            update={'$inc': {
                'correlation_number': 1
            }})['correlation_number']

        cdr_part = {
            'correlation':
            unicode(corr_number),
            'cost_value':
            unicode(part['value']),
            'tax_value':
            unicode(Decimal(part['value']) - Decimal(part['duty_free'])),
            'event':
            event,
            'description':
            description
        }

        cdr_part.update(self._cdr_info)
        return cdr_part
Exemplo n.º 4
0
    def _timeout_handler(self):

        db = get_database_connection()

        # Uses an atomic operation to get and set the _lock value in the purchase
        # document
        pre_value = db.wstore_order.find_one_and_update(
            {'_id': ObjectId(self._order.pk)}, {'$set': {
                '_lock': True
            }})

        # If _lock not exists or is set to false means that this function has
        # acquired the resource
        if '_lock' not in pre_value or not pre_value['_lock']:

            # Only rollback if the state is pending
            if pre_value['state'] == 'pending':
                order = Order.objects.get(pk=self._order.pk)
                timeout_processors = {
                    'initial': self._initial_charge_timeout,
                    'recurring': self._renew_charge_timeout,
                    'usage': self._renew_charge_timeout
                }
                timeout_processors[self._concept](order)

            db.wstore_order.find_one_and_update(
                {'_id': ObjectId(self._order.pk)}, {'$set': {
                    '_lock': False
                }})
Exemplo n.º 5
0
    def _timeout_handler(self):

        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(self._purchase.pk)},
            update={'$set': {'_lock': True}}
        )

        # If _lock not exists or is set to false means that this function has
        # acquired the resource
        if '_lock' not in pre_value or not pre_value['_lock']:

            # Only rollback if the state is pending
            if pre_value['state'] == 'pending':
                # Refresh the purchase
                purchase = Purchase.objects.get(pk=self._purchase.pk)
                rollback(purchase)

            db.wstore_purchase.find_and_modify(
                query={'_id': ObjectId(self._purchase.pk)},
                update={'$set': {'_lock': False}}
            )
Exemplo n.º 6
0
    def send_cdr(self, cdr_info):

        # Build CDRs
        data = []
        for cdr in cdr_info:
            time = cdr['time_stamp'].split(' ')
            time = time[0] + 'T' + time[1] + 'Z'

            data.append({
                'cdrSource': self._rss.aggregator_id,
                'productClass': cdr['product_class'],
                'correlationNumber': cdr['correlation'],
                'timestamp': time,
                'application': cdr['offering'],
                'transactionType': 'C',
                'event': cdr['event'],
                'referenceCode': cdr['purchase'],
                'description': cdr['description'],
                'chargedAmount': cdr['cost_value'],
                'chargedTaxAmount': cdr['tax_value'],
                'currency': cdr['cost_currency'],
                'customerId': cdr['customer'],
                'appProvider': cdr['provider']
            })

        # Make request
        url = urljoin(self._rss.host, 'fiware-rss/rss/cdrs')
        headers = {
            'content-type': 'application/json',
            'Authorization': 'Bearer ' + self._rss.access_token
        }

        request = MethodRequest('POST', url, json.dumps(data), headers)

        opener = urllib2.build_opener()
        try:
            try:
                opener.open(request)
            except HTTPError as e:
                if e.code == 401:
                    self._rss.refresh_token()
                    headers[
                        'Authorization'] = 'Bearer ' + self._rss.access_token
                    request = MethodRequest('POST', url, json.dumps(data),
                                            headers)
                    opener.open(request)
                else:
                    raise e
        except:

            db = get_database_connection()
            # Restore correlation numbers
            for cdr in cdr_info:
                org = Organization.objects.get(actor_id=cdr['provider'])
                db.wstore_organization.find_and_modify(
                    query={'_id': ObjectId(org.pk)},
                    update={'$inc': {
                        'correlation_number': -1
                    }})['correlation_number']
Exemplo n.º 7
0
    def send_cdr(self, cdr_info):

        # Build CDRs
        data = []
        for cdr in cdr_info:
            time = cdr['time_stamp'].split(' ')
            time = time[0] + 'T' + time[1] + 'Z'

            data.append({
                'cdrSource': self._rss.aggregator_id,
                'productClass': cdr['product_class'],
                'correlationNumber': cdr['correlation'],
                'timestamp': time,
                'application': cdr['offering'],
                'transactionType': 'C',
                'event': cdr['event'],
                'referenceCode': cdr['purchase'],
                'description': cdr['description'],
                'chargedAmount': cdr['cost_value'],
                'chargedTaxAmount': cdr['tax_value'],
                'currency': cdr['cost_currency'],
                'customerId': cdr['customer'],
                'appProvider': cdr['provider']
            })

        # Make request
        url = urljoin(self._rss.host, 'fiware-rss/rss/cdrs')
        headers = {
            'content-type': 'application/json',
            'Authorization': 'Bearer ' + self._rss.access_token
        }

        request = MethodRequest('POST', url, json.dumps(data), headers)

        opener = urllib2.build_opener()
        try:
            try:
                opener.open(request)
            except HTTPError as e:
                if e.code == 401:
                    self._rss.refresh_token()
                    headers['Authorization'] = 'Bearer ' + self._rss.access_token
                    request = MethodRequest('POST', url, json.dumps(data), headers)
                    opener.open(request)
                else:
                    raise e
        except:

            db = get_database_connection()
            # Restore correlation numbers
            for cdr in cdr_info:
                org = Organization.objects.get(actor_id=cdr['provider'])
                db.wstore_organization.find_and_modify(
                    query={'_id': ObjectId(org.pk)},
                    update={'$inc': {'correlation_number': -1}}
                )['correlation_number']
Exemplo n.º 8
0
    def _process_payouts(self, data):
        db = get_database_connection()
        reference = "__payout__engine__context__lock__"
        # Uses an atomic operation to get and set the _lock value in the purchase
        # document
        pre_value = db.wstore_payout.find_one_and_update(
            {'_id': reference}, {'$set': {
                '_lock': True
            }})

        # If no reference exists, create it
        if pre_value is None:
            db.wstore_payout.insert_one({'_id': reference, '_lock': False})
            pre_value = db.wstore_payout.find_one_and_update(
                {'_id': reference}, {'$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 PayoutError('There is a payout running.')

        payments = []
        context = Context.objects.all()[0]
        current_id = context.payouts_n

        for currency, users in data.items():
            payments.append([])
            for user, values in users.items():
                for value, report in values:
                    sender_id = '{}_{}'.format(report, current_id)
                    payment = {
                        'recipient_type': 'EMAIL',
                        'amount': {
                            'value': "{0:.2f}".format(round(Decimal(value),
                                                            2)),
                            'currency': currency
                        },
                        'receiver': user,
                        'sender_item_id': sender_id
                    }
                    current_id += 1
                    payments[-1].append(payment)

        context.payouts_n = current_id
        context.save()

        # _lock is set to false
        db.wstore_payout.find_one_and_update({'_id': reference},
                                             {'$set': {
                                                 '_lock': False
                                             }})

        return [self.paypal.batch_payout(paybatch) for paybatch in payments]
    def send_cdr(self, cdr_info):
        # Build CDRs
        data = []
        for cdr in cdr_info:

            data.append({
                'cdrSource': settings.WSTOREMAIL,
                'productClass': cdr['product_class'],
                'correlationNumber': cdr['correlation'],
                'timestamp': cdr['time_stamp'],
                'application': cdr['offering'],
                'transactionType': cdr['type'],
                'event': cdr['event'],
                'referenceCode': cdr['order'],
                'description': cdr['description'],
                'chargedAmount': cdr['cost_value'],
                'chargedTaxAmount': cdr['tax_value'],
                'currency': cdr['cost_currency'],
                'customerId': cdr['customer'],
                'appProvider': cdr['provider']
            })

        # Make request
        url = settings.RSS
        if not url.endswith('/'):
            url += '/'

        url += 'rss/cdrs'

        headers = {
            'content-type': 'application/json',
            'X-Nick-Name': settings.STORE_NAME,
            'X-Roles': settings.ADMIN_ROLE,
            'X-Email': settings.WSTOREMAIL
        }

        response = requests.post(url, json=data, headers=headers)

        if response.status_code != 201:
            db = get_database_connection()
            # Restore correlation numbers
            for cdr in cdr_info:
                org = Organization.objects.get(name=cdr['provider'])
                db.wstore_organization.find_and_modify(
                    query={'_id': ObjectId(org.pk)},
                    update={'$inc': {
                        'correlation_number': -1
                    }})['correlation_number']

            context = Context.objects.all()[0]
            context.failed_cdrs.extend(cdr_info)
            context.save()
    def send_cdr(self, cdr_info):
        # Build CDRs
        data = []
        for cdr in cdr_info:

            data.append({
                'cdrSource': settings.WSTOREMAIL,
                'productClass': cdr['product_class'],
                'correlationNumber': cdr['correlation'],
                'timestamp': cdr['time_stamp'],
                'application': cdr['offering'],
                'transactionType': cdr['type'],
                'event': cdr['event'],
                'referenceCode': cdr['order'],
                'description': cdr['description'],
                'chargedAmount': cdr['cost_value'],
                'chargedTaxAmount': cdr['tax_value'],
                'currency': cdr['cost_currency'],
                'customerId': cdr['customer'],
                'appProvider': cdr['provider']
            })

        # Make request
        url = settings.RSS
        if not url.endswith('/'):
            url += '/'

        url += 'rss/cdrs'

        headers = {
            'content-type': 'application/json',
            'X-Nick-Name': settings.STORE_NAME,
            'X-Roles': 'provider',
            'X-Email': settings.WSTOREMAIL
        }

        response = requests.post(url, json=data, headers=headers)

        if response.status_code != 201:
            db = get_database_connection()
            # Restore correlation numbers
            for cdr in cdr_info:
                org = Organization.objects.get(name=cdr['provider'])
                db.wstore_organization.find_and_modify(
                    query={'_id': ObjectId(org.pk)},
                    update={'$inc': {'correlation_number': -1}}
                )['correlation_number']

            context = Context.objects.all()[0]
            context.failed_cdrs.extend(cdr_info)
            context.save()
Exemplo n.º 11
0
    def _generate_cdr_part(self, part, model, cdr_info):
        # Create connection for raw database access
        db = get_database_connection()

        # Take and increment the correlation number using
        # the mongoDB atomic access in order to avoid race
        # problems
        currency = self._price_model['general_currency']

        if cdr_info['rss'].api_version == 1:
            # Version 1 uses a global correlation number
            corr_number = db.wstore_rss.find_and_modify(
                query={'_id': ObjectId(cdr_info['rss'].pk)},
                update={'$inc': {
                    'correlation_number': 1
                }})['correlation_number']

            currency = get_curency_code(self._price_model['general_currency'])

        else:
            # Version 2 uses a correlation number per provider
            corr_number = db.wstore_organization.find_and_modify(
                query={'_id': ObjectId(self._purchase.owner_organization.pk)},
                update={'$inc': {
                    'correlation_number': 1
                }})['correlation_number']

        return {
            'provider': cdr_info['provider'],
            'service': cdr_info['service_name'],
            'defined_model': model,
            'correlation': str(corr_number),
            'purchase': self._purchase.ref,
            'offering': cdr_info['offering'],
            'product_class': cdr_info['product_class'],
            'description': cdr_info['description'],
            'cost_currency': currency,
            'cost_value': str(part['value']),
            'tax_currency': currency,
            'tax_value': '0.0',
            'source': '1',
            'operator': '1',
            'country': cdr_info['country_code'],
            'time_stamp': cdr_info['time_stamp'],
            'customer': cdr_info['customer'],
            'event': self._purchase.contract.revenue_class
        }
Exemplo n.º 12
0
    def _generate_cdr_part(self, part, model, cdr_info):
        # Create connection for raw database access
        db = get_database_connection()

        # Take and increment the correlation number using
        # the mongoDB atomic access in order to avoid race
        # problems
        currency = self._price_model['general_currency']

        if cdr_info['rss'].api_version == 1:
            # Version 1 uses a global correlation number
            corr_number = db.wstore_rss.find_and_modify(
                query={'_id': ObjectId(cdr_info['rss'].pk)},
                update={'$inc': {'correlation_number': 1}}
            )['correlation_number']

            currency = get_curency_code(self._price_model['general_currency'])

        else:
            # Version 2 uses a correlation number per provider
            corr_number = db.wstore_organization.find_and_modify(
                query={'_id': ObjectId(self._purchase.owner_organization.pk)},
                update={'$inc': {'correlation_number': 1}}
            )['correlation_number']

        return {
            'provider': cdr_info['provider'],
            'service': cdr_info['service_name'],
            'defined_model': model,
            'correlation': str(corr_number),
            'purchase': self._purchase.ref,
            'offering': cdr_info['offering'],
            'product_class': cdr_info['product_class'],
            'description': cdr_info['description'],
            'cost_currency': currency,
            'cost_value': str(part['value']),
            'tax_currency': currency,
            'tax_value': '0.0',
            'source': '1',
            'operator': '1',
            'country': cdr_info['country_code'],
            'time_stamp': cdr_info['time_stamp'],
            'customer': cdr_info['customer'],
            'event': self._purchase.contract.revenue_class
        }
    def _process_payouts(self, data):
        db = get_database_connection()
        reference = "__payout__engine__context__lock__"
        # Uses an atomic operation to get and set the _lock value in the purchase
        # document
        pre_value = db.wstore_payout.find_one_and_update({"_id": reference}, {"$set": {"_lock": True}})

        # If no reference exists, create it
        if pre_value is None:
            db.wstore_payout.insert_one({"_id": reference, "_lock": False})
            pre_value = db.wstore_payout.find_one_and_update({"_id": reference}, {"$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 PayoutError("There is a payout running.")

        payments = []
        context = Context.objects.all()[0]
        current_id = context.payouts_n

        for currency, users in data.items():
            payments.append([])
            for user, values in users.items():
                for value, report in values:
                    sender_id = "{}_{}".format(report, current_id)
                    payment = {
                        "recipient_type": "EMAIL",
                        "amount": {"value": "{0:.2f}".format(round(Decimal(value), 2)), "currency": currency},
                        "receiver": user,
                        "sender_item_id": sender_id,
                    }
                    current_id += 1
                    payments[-1].append(payment)

        context.payouts_n = current_id
        context.save()

        # _lock is set to false
        db.wstore_payout.find_one_and_update({"_id": reference}, {"$set": {"_lock": False}})

        return [self.paypal.batch_payout(paybatch) for paybatch in payments]
    def _generate_cdr_part(self, part, event, description):
        # Create connection for raw database access
        db = get_database_connection()

        # Take and increment the correlation number using
        # the mongoDB atomic access in order to avoid race
        # problems
        corr_number = db.wstore_organization.find_and_modify(
            query={'_id': ObjectId(self._offering.owner_organization.pk)},
            update={'$inc': {'correlation_number': 1}}
        )['correlation_number']

        cdr_part = {
            'correlation': unicode(corr_number),
            'cost_value': unicode(part['value']),
            'tax_value': unicode(Decimal(part['value']) - Decimal(part['duty_free'])),
            'event': event,
            'description': description
        }

        cdr_part.update(self._cdr_info)
        return cdr_part
Exemplo n.º 15
0
    def handle(self, *args, **kargs):
        """
        Launch failed cdrs
        """
        contexts = Context.objects.all()
        if len(contexts) < 1:
            raise CommandError("No context")

        context = contexts[0]
        cdrs = context.failed_cdrs
        context.failed_cdrs = []
        context.save()

        if len(cdrs) == 0:
            print("No failed cdrs to send")
            exit(0)

        db = get_database_connection()
        time_stamp = datetime.utcnow().isoformat() + 'Z'

        for cdr in cdrs:
            # Modify time_stamp
            cdr['time_stamp'] = time_stamp

            # Modify correlation number
            org = Organization.objects.get(name=cdr['provider'])

            new_org = db.wstore_organization.find_and_modify(
                query={'_id': ObjectId(org.pk)},
                update={'$inc': {
                    'correlation_number': 1
                }})

            cdr['correlation'] = new_org['correlation_number']

        r = RSSAdaptor()
        r.send_cdr(cdrs)
    def handle(self, *args, **kargs):
        """
        Launch failed cdrs
        """
        contexts = Context.objects.all()
        if len(contexts) < 1:
            raise CommandError("No context")

        context = contexts[0]
        cdrs = context.failed_cdrs
        context.failed_cdrs = []
        context.save()

        if len(cdrs) == 0:
            print("No failed cdrs to send")
            exit(0)

        db = get_database_connection()
        time_stamp = datetime.utcnow().isoformat() + 'Z'

        for cdr in cdrs:
            # Modify time_stamp
            cdr['time_stamp'] = time_stamp

            # Modify correlation number
            org = Organization.objects.get(name=cdr['provider'])

            new_org = db.wstore_organization.find_and_modify(
                query={'_id': ObjectId(org.pk)},
                update={'$inc': {'correlation_number': 1}}
            )

            cdr['correlation'] = new_org['correlation_number']

        r = RSSAdaptor()
        r.send_cdr(cdrs)
    def create(self, request):

        order = None
        concept = None
        self.ordering_client = OrderingClient()
        try:
            # Extract payment information
            data = json.loads(request.body)

            if 'reference' not in data or 'paymentId' not in data or 'payerId' not in data:
                raise ValueError('Missing required field. It must contain reference, paymentId, and payerId')

            reference = data['reference']
            token = data['paymentId']
            payer_id = data['payerId']

            if not Order.objects.filter(pk=reference):
                raise ValueError('The provided reference does not identify a valid order')

            db = get_database_connection()

            # Uses an atomic operation to get and set the _lock value in the purchase
            # document
            pre_value = db.wstore_order.find_one_and_update(
                {'_id': ObjectId(reference)},
                {'$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 not pre_value or '_lock' in pre_value and pre_value['_lock']:
                raise PaymentError('The timeout set to process the payment has finished')

            order = Order.objects.get(pk=reference)
            raw_order = self.ordering_client.get_order(order.order_id)
            pending_info = order.pending_payment
            concept = pending_info.concept

            # If the order state value is different from pending means that
            # the timeout function has completely ended before acquiring the resource
            # so _lock is set to false and the view ends
            if pre_value['state'] != 'pending':
                db.wstore_order.find_one_and_update(
                    {'_id': ObjectId(reference)},
                    {'$set': {'_lock': False}}
                )
                raise PaymentError('The timeout set to process the payment has finished')

            # Check that the request user is authorized to end the payment
            if request.user.userprofile.current_organization != order.owner_organization or request.user != order.customer:
                raise PaymentError('You are not authorized to execute the payment')

            transactions = pending_info.transactions

            # Get the payment client
            # Load payment client
            cln_str = settings.PAYMENT_CLIENT
            client_package, client_class = cln_str.rsplit('.', 1)

            payment_client = getattr(importlib.import_module(client_package), client_class)

            # build the payment client
            client = payment_client(order)
            order.sales_ids = client.end_redirection_payment(token, payer_id)
            order.save()

            charging_engine = ChargingEngine(order)
            charging_engine.end_charging(transactions, pending_info.free_contracts, concept)

        except Exception as e:

            # Rollback the purchase if existing
            if order is not None and raw_order is not None:
                if concept == 'initial':
                    # Set the order to failed in the ordering API
                    # Set all items as Failed, mark the whole order as failed
                    self.ordering_client.update_items_state(raw_order, 'Failed')
                    order.delete()
                else:
                    order.state = 'paid'
                    order.pending_payment = None
                    order.save()

            expl = ' due to an unexpected error'
            err_code = 500
            if isinstance(e, PaymentError) or isinstance(e, ValueError):
                expl = ': ' + unicode(e)
                err_code = 403

            msg = 'The payment has been canceled' + expl
            return build_response(request, err_code, msg)

        # Change states of TMForum resources (orderItems, products, etc)
        # depending on the concept of the payment

        states_processors = {
            'initial': self._set_initial_states,
            'recurring': self._set_renovation_states,
            'usage': self._set_renovation_states
        }
        # Include the free contracts as transactions in order to activate them
        ext_transactions = deepcopy(transactions)
        ext_transactions.extend([{'item': contract.item_id} for contract in pending_info.free_contracts])

        states_processors[concept](ext_transactions, raw_order, order)

        # _lock is set to false
        db.wstore_order.find_one_and_update(
            {'_id': ObjectId(reference)},
            {'$set': {'_lock': False}}
        )

        return build_response(request, 200, 'Ok')
Exemplo n.º 18
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)
Exemplo n.º 19
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)
Exemplo n.º 20
0
    def handle(self, *args, **options):
        """
        Starts and configures a new WStore instance
        """

        # Check if the user want to create an initial configuration
        opt = get_yes_no_option(
            "Do you want to create an initial configuration")

        if opt == 'n':
            print "You can configure WStore manually editing settings.py file"
            read_from_cmd()
            return

        settings = {
            'email_user': '******',
            'wstore_email': 'wstore_email',
            'wstore_email_passwd': 'wstore_email_passwd',
            'email_smtp_server': 'wstore_smtp_server',
            'provider_req_email': 'provider_requ_email',
            'client_id': 0,
            'client_secret': 'Client_secret',
            'oilauth': False,
            'idm_endpoint': 'idm_endpoint'
        }

        # Get database name
        print "Include a database name: "
        settings['database'] = read_from_cmd()

        # Create the default site
        print "Include a site name: "
        site_name = read_from_cmd()

        site_domain = get_url("Include a site domain: ")

        # Get WStore name
        print "Include a name for your instance: "
        settings['store_name'] = read_from_cmd()

        option = get_yes_no_option(
            "Do you want to include email configuration?")

        if option == 'y':
            print "Include email smtp server endpoint: "
            settings['provider_req_email'] = read_from_cmd()

            print "Include WStore email: "
            settings['wstore_email'] = read_from_cmd()

            print "Include WStore email user: "******"Include WStore email password: "******"Include WStore provider requests email: "
            settings['provider_req_email'] = read_from_cmd()

        correct = False
        while not correct:
            # Select authentication method
            print "Select authentication method: "
            print "1) Identity manager"
            print "2) WStore"

            option = read_from_cmd()
            try:
                number_opt = int(option)
            except:
                print "Invalid option. Please select 1 or 2"
                continue

            if number_opt != 1 and number_opt != 2:
                print "Invalid option. Please select 1 or 2"
                continue

            correct = True

        syn_command = 'python manage.py syncdb'
        # Get auth info
        if number_opt == 1:
            print "Include Identity manager endpoint: (default https://account.lab.fiware.org/)"
            settings['oilauth'] = True

            settings['idm_endpoint'] = read_from_cmd()

            if not len(settings['idm_endpoint']
                       ) or settings['idm_endpoint'].isspace():
                settings['idm_endpoint'] = "https://account.lab.fiware.org/"

            syn_command += ' --noinput'

            # Get idm api version
            correct = False
            while not correct:
                print "Include KeyRock API version [1/2]: "
                api_version = read_from_cmd()
                if api_version.isdigit() and (int(api_version) == 1
                                              or int(api_version) == 2):
                    settings['idm_api_version'] = int(api_version)
                    correct = True
                else:
                    print "Please include 1 or 2"

            if settings['idm_api_version'] == 2:
                if settings['idm_endpoint'].startswith(
                        'https://account.lab.fiware.org'):
                    settings[
                        'keystone_endpoint'] = "http://cloud.lab.fiware.org:4731"
                else:
                    settings['keystone_endpoint'] = get_url(
                        "Include KeyStone endpoint: ")

            option = get_yes_no_option(
                "Do you want to include OAuth2 configuration?")

            if option == 'y':
                print "Include Client id: "
                settings['client_id'] = read_from_cmd()
                print "Include client secret:"
                settings['client_secret'] = read_from_cmd()
            else:
                print """OAuth2 credentials are required for authentication using an Identity Manager, 
                please include this credentials in the file settings.py as soon as you have them"""
        else:
            settings['idm_api_version'] = 2

        # Render templates

        template = loader.get_template('conf/settings_template.py')
        settings_content = template.render(Context(settings))

        # Create intermediate settings file
        f = codecs.open(
            os.path.join(django.conf.settings.BASEDIR, 'settings.py'), "wb",
            'utf-8')
        f.seek(0)
        f.write(settings_content)
        f.truncate()
        f.close()

        # Execute final commands
        exec_external_cmd(syn_command)
        exec_external_cmd('python manage.py collectstatic --noinput')
        exec_external_cmd('python manage.py createsite ' + site_name + ' ' +
                          site_domain)

        # Reload the settings
        reload(django.conf)

        # Get site pk to include it as site_id, raw mongo access since it is not
        # possible to change the database dynamically
        db = get_database_connection()
        settings['site_id'] = unicode(
            db.django_site.find_one({'name': site_name})['_id'])

        # Create final settings file including site_id
        settings_content = template.render(Context(settings))

        # Create final settings file
        f = codecs.open(
            os.path.join(django.conf.settings.BASEDIR, 'settings.py'), "wb",
            'utf-8')
        f.seek(0)
        f.write(settings_content)
        f.truncate()
        f.close()
 def __init__(self):
     self._db = get_database_connection()
Exemplo n.º 22
0
# -*- coding: utf-8 -*-

# Copyright (c) 2013 CoNWeT Lab., Universidad Politécnica de Madrid

# This file is part of WStore.

# WStore is free software: you can redistribute it and/or modify
# it under the terms of the European Union Public Licence (EUPL)
# as published by the European Commission, either version 1.1
# of the License, or (at your option) any later version.

# WStore is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# European Union Public Licence for more details.

# You should have received a copy of the European Union Public Licence
# along with WStore.
# If not, see <https://joinup.ec.europa.eu/software/page/eupl/licence-eupl>.

from wstore.store_commons.database import get_database_connection

db = get_database_connection()

# Create index for tagging if not created
db.wstore_offering.ensure_index("tags")
Exemplo n.º 23
0
def delete_offering(user, offering):
    # If the offering has been purchased it is not deleted
    # it is marked as deleted in order to allow customers that
    # have purchased the offering to install it if needed

    # delete the usdl description from the repository
    if offering.state == 'deleted':
        raise PermissionDenied('The offering is already deleted')

    if offering.state == 'published' and len(offering.description_url):
        repository_adaptor = unreg_repository_adaptor_factory(offering.description_url)

        if settings.OILAUTH:
            repository_adaptor.set_credentials(user.userprofile.access_token)

        repository_adaptor.delete()

    index_path = os.path.join(settings.BASEDIR, 'wstore')
    index_path = os.path.join(index_path, 'search')
    index_path = os.path.join(index_path, 'indexes')

    se = SearchEngine(index_path)

    if offering.state == 'uploaded':
        _remove_offering(offering, se)
    else:
        offering.state = 'deleted'
        offering.save()

        # Delete the offering from marketplaces
        for market in offering.marketplaces:
            market_adaptor = marketadaptor_factory(market.marketplace, user)
            market_adaptor.delete_service(market.offering_name)

        # Update offering indexes
        if not offering.open:
            se.update_index(offering)

        context = Context.objects.all()[0]
        # Check if the offering is in the newest list
        if offering.pk in context.newest:
            # Remove the offering from the newest list
            newest = context.newest

            if len(newest) < 8:
                newest.remove(offering.pk)
            else:
                # Get the 8 newest offerings using the publication date for sorting
                db = get_database_connection()
                offerings = db.wstore_offering
                newest_off = offerings.find({'state': 'published'}).sort('publication_date', -1).limit(8)

                newest = []
                for n in newest_off:
                    newest.append(str(n['_id']))

            context.newest = newest
            context.save()

        # Check if the offering is in the top rated list
        if offering.pk in context.top_rated:
            # Remove the offering from the top rated list
            top_rated = context.top_rated
            if len(top_rated) < 8:
                top_rated.remove(offering.pk)
            else:
                # Get the 4 top rated offerings
                db = get_database_connection()
                offerings = db.wstore_offering
                top_off = offerings.find({'state': 'published', 'rating': {'$gt': 0}}).sort('rating', -1).limit(8)

                top_rated = []
                for t in top_off:
                    top_rated.append(str(t['_id']))

            context.top_rated = top_rated
            context.save()

        if offering.open:
            _remove_offering(offering, se)
Exemplo n.º 24
0
def get_offerings(user, filter_='published', state=None, pagination=None, sort=None):

    allowed_states = ['uploaded', 'published', 'deleted']

    if pagination and (not int(pagination['skip']) > 0 or not int(pagination['limit']) > 0):
        raise ValueError('Invalid pagination limits')

    # Validate states
    if state:
        for st in state:
            if st not in allowed_states:
                raise ValueError('Invalid state: ' + st)

    # Set sorting values
    order = -1
    if sort is None or sort == 'date':
        if filter_ == 'published' or filter_ == 'purchased':
            sorting = 'publication_date'
        else:
            sorting = 'creation_date'
    elif sort == 'popularity':
        sorting = 'rating'
    else:
        sorting = sort
        if sorting == 'name':
            order = 1

    # Get all the offerings owned by the provider using raw mongodb access
    db = get_database_connection()
    offerings = db.wstore_offering

    # Pagination: define the first element and the number of elements
    if filter_ == 'provided':
        current_organization = user.userprofile.current_organization
        query = {
            'owner_organization_id': ObjectId(current_organization.id),
            'state': {'$in': state}
        }

        prov_offerings = offerings.find(query).sort(sorting, order)

    elif filter_ == 'purchased':
        if pagination:
            prov_offerings = _get_purchased_offerings(user, db, pagination, sort=sorting)
            pagination = None
        else:
            prov_offerings = _get_purchased_offerings(user, db, sort=sorting)

    elif filter_ == 'published':
            prov_offerings = offerings.find({'state': 'published'}).sort(sorting, order)
    else:
        raise ValueError('Invalid filter: ' + filter_)

    if pagination:
        prov_offerings = prov_offerings.skip(int(pagination['skip']) - 1).limit(int(pagination['limit']))

    result = []

    for offer in prov_offerings:
        if '_id' in offer:
            pk = str(offer['_id'])
        else:
            pk = offer

        offering = Offering.objects.get(pk=pk)
        # Use get_offering_info to create the JSON with the offering info
        result.append(get_offering_info(offering, user))

    return result
    def handle(self, *args, **options):
        """
        Starts and configures a new WStore instance
        """

        # Check if the user want to create an initial configuration
        opt = get_yes_no_option("Do you want to create an initial configuration")

        if opt == "n":
            print "You can configure WStore manually editing settings.py file"
            read_from_cmd()
            return

        settings = {
            "email_user": "******",
            "wstore_email": "wstore_email",
            "wstore_email_passwd": "wstore_email_passwd",
            "email_smtp_server": "wstore_smtp_server",
            "provider_req_email": "provider_requ_email",
            "client_id": 0,
            "client_secret": "Client_secret",
            "oilauth": False,
            "idm_endpoint": "idm_endpoint",
        }

        # Get database name
        print "Include a database name: "
        settings["database"] = read_from_cmd()

        # Create the default site
        print "Include a site name: "
        site_name = read_from_cmd()

        site_domain = get_url("Include a site domain: ")

        # Get WStore name
        print "Include a name for your instance: "
        settings["store_name"] = read_from_cmd()

        option = get_yes_no_option("Do you want to include email configuration?")

        if option == "y":
            print "Include email smtp server endpoint: "
            settings["provider_req_email"] = read_from_cmd()

            print "Include WStore email: "
            settings["wstore_email"] = read_from_cmd()

            print "Include WStore email user: "******"email_user"] = read_from_cmd()

            print "Include WStore email password: "******"wstore_email_passwd"] = read_from_cmd()

            print "Include WStore provider requests email: "
            settings["provider_req_email"] = read_from_cmd()

        correct = False
        while not correct:
            # Select authentication method
            print "Select authentication method: "
            print "1) Identity manager"
            print "2) WStore"

            option = read_from_cmd()
            try:
                number_opt = int(option)
            except:
                print "Invalid option. Please select 1 or 2"
                continue

            if number_opt != 1 and number_opt != 2:
                print "Invalid option. Please select 1 or 2"
                continue

            correct = True

        syn_command = "python manage.py syncdb"
        # Get auth info
        if number_opt == 1:
            print "Include Identity manager endpoint: (default https://account.lab.fiware.org/)"
            settings["oilauth"] = True

            settings["idm_endpoint"] = read_from_cmd()

            if not len(settings["idm_endpoint"]) or settings["idm_endpoint"].isspace():
                settings["idm_endpoint"] = "https://account.lab.fiware.org/"

            syn_command += " --noinput"

            # Get idm api version
            correct = False
            while not correct:
                print "Include KeyRock API version [1/2]: "
                api_version = read_from_cmd()
                if api_version.isdigit() and (int(api_version) == 1 or int(api_version) == 2):
                    settings["idm_api_version"] = int(api_version)
                    correct = True
                else:
                    print "Please include 1 or 2"

            if settings["idm_api_version"] == 2:
                if settings["idm_endpoint"].startswith("https://account.lab.fiware.org"):
                    settings["keystone_endpoint"] = "http://cloud.lab.fiware.org:4731"
                else:
                    settings["keystone_endpoint"] = get_url("Include KeyStone endpoint: ")

            option = get_yes_no_option("Do you want to include OAuth2 configuration?")

            if option == "y":
                print "Include Client id: "
                settings["client_id"] = read_from_cmd()
                print "Include client secret:"
                settings["client_secret"] = read_from_cmd()
            else:
                print """OAuth2 credentials are required for authentication using an Identity Manager, 
                please include this credentials in the file settings.py as soon as you have them"""
        else:
            settings["idm_api_version"] = 2

        # Render templates

        template = loader.get_template("conf/settings_template.py")
        settings_content = template.render(Context(settings))

        # Create intermediate settings file
        f = codecs.open(os.path.join(django.conf.settings.BASEDIR, "settings.py"), "wb", "utf-8")
        f.seek(0)
        f.write(settings_content)
        f.truncate()
        f.close()

        # Execute final commands
        exec_external_cmd(syn_command)
        exec_external_cmd("python manage.py collectstatic --noinput")
        exec_external_cmd("python manage.py createsite " + site_name + " " + site_domain)

        # Reload the settings
        reload(django.conf)

        # Get site pk to include it as site_id, raw mongo access since it is not
        # possible to change the database dynamically
        db = get_database_connection()
        settings["site_id"] = unicode(db.django_site.find_one({"name": site_name})["_id"])

        # Create final settings file including site_id
        settings_content = template.render(Context(settings))

        # Create final settings file
        f = codecs.open(os.path.join(django.conf.settings.BASEDIR, "settings.py"), "wb", "utf-8")
        f.seek(0)
        f.write(settings_content)
        f.truncate()
        f.close()
Exemplo n.º 26
0
    def create(self, request):

        order = None
        concept = None
        self.ordering_client = OrderingClient()
        try:
            # Extract payment information
            data = json.loads(request.body)

            if 'reference' not in data or 'paymentId' not in data or 'payerId' not in data:
                raise ValueError('Missing required field. It must contain reference, paymentId, and payerId')

            reference = data['reference']
            token = data['paymentId']
            payer_id = data['payerId']

            if not Order.objects.filter(pk=reference):
                raise ValueError('The provided reference does not identify a valid order')

            db = get_database_connection()

            # Uses an atomic operation to get and set the _lock value in the purchase
            # document
            pre_value = db.wstore_order.find_one_and_update(
                {'_id': ObjectId(reference)},
                {'$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 not pre_value or '_lock' in pre_value and pre_value['_lock']:
                raise PaymentError('The timeout set to process the payment has finished')

            order = Order.objects.get(pk=reference)
            raw_order = self.ordering_client.get_order(order.order_id)
            pending_info = order.pending_payment
            concept = pending_info['concept']

            # If the order state value is different from pending means that
            # the timeout function has completely ended before acquiring the resource
            # so _lock is set to false and the view ends
            if pre_value['state'] != 'pending':
                db.wstore_order.find_one_and_update(
                    {'_id': ObjectId(reference)},
                    {'$set': {'_lock': False}}
                )
                raise PaymentError('The timeout set to process the payment has finished')

            # Check that the request user is authorized to end the payment
            if request.user.userprofile.current_organization != order.owner_organization:
                raise PaymentError('You are not authorized to execute the payment')

            transactions = pending_info['transactions']

            # Get the payment client
            # Load payment client
            cln_str = settings.PAYMENT_CLIENT
            client_package, client_class = cln_str.rsplit('.', 1)

            payment_client = getattr(importlib.import_module(client_package), client_class)

            # build the payment client
            client = payment_client(order)
            order.sales_ids = client.end_redirection_payment(token, payer_id)
            order.save()

            charging_engine = ChargingEngine(order)
            charging_engine.end_charging(transactions, concept)

        except Exception as e:

            # Rollback the purchase if existing
            if order is not None and raw_order is not None:
                if concept == 'initial':
                    # Set the order to failed in the ordering API
                    # Set all items as Failed, mark the whole order as failed
                    self.ordering_client.update_items_state(raw_order, 'Failed')
                    order.delete()
                else:
                    order.state = 'paid'
                    order.pending_payment = {}
                    order.save()

            expl = ' due to an unexpected error'
            err_code = 500
            if isinstance(e, PaymentError) or isinstance(e, ValueError):
                expl = ': ' + unicode(e)
                err_code = 403

            msg = 'The payment has been canceled' + expl
            return build_response(request, err_code, msg)

        # Change states of TMForum resources (orderItems, products, etc)
        # depending on the concept of the payment

        states_processors = {
            'initial': self._set_initial_states,
            'renovation': self._set_renovation_states,
            'use': self._set_renovation_states
        }
        states_processors[concept](transactions, raw_order, order)

        # _lock is set to false
        db.wstore_order.find_one_and_update(
            {'_id': ObjectId(reference)},
            {'$set': {'_lock': False}}
        )

        return build_response(request, 200, 'Ok')