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}} )
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
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 }})
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 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']
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']
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()
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 _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
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')
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 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 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()
# -*- 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")
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)
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()
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')