Пример #1
0
    def _update_actor_balance(self, price):
        rss = RSS.objects.all()[0]

        actor = None
        # Check who is the charging actor (user or organization)
        if self._purchase.organization_owned:
            actor = self._purchase.owner_organization
        else:
            client = self._purchase.customer
            actor = Organization.objects.get(actor_id=client.userprofile.actor_id)

        charge = {
            'currency': self._price_model['general_currency'],
            'amount': price
        }

        # Check balance
        try:
            rss_factory = RSSManagerFactory(rss)
            exp_manager = rss_factory.get_expenditure_manager(rss.access_token)
            exp_manager.update_balance(charge, actor)
        except HTTPError as e:
            # Check if it is needed to refresh the access token
            if e.code == 401:
                rss._refresh_token()
                exp_manager.set_credentials(rss.access_token)
                exp_manager.update_balance(charge, actor)
            # Check if the error is due to an insufficient balance
            else:
                raise e
Пример #2
0
    def delete(self, request, rss):

        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Get rss entry
        try:
            rss_model = RSS.objects.get(name=rss)
        except:
            return build_response(request, 404, 'Not found')

        # Delete provider limits
        rss_factory = RSSManagerFactory(rss_model)

        exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)
        call_result = _make_rss_request(exp_manager, exp_manager.delete_provider_limit, request.user)

        if call_result[0]:
            return build_response(request, call_result[1], call_result[2])

        # Delete rs models
        model_manager = rss_factory.get_model_manager(request.user.userprofile.access_token)
        call_result = _make_rss_request(model_manager, model_manager.delete_provider_models, request.user)

        if call_result[0]:
            return build_response(request, call_result[1], call_result[2])

        # Delete rss model
        rss_model.delete()
        return build_response(request, 204, 'No content')
Пример #3
0
    def _update_actor_balance(self, price):
        rss = RSS.objects.all()[0]

        actor = None
        # Check who is the charging actor (user or organization)
        if self._purchase.organization_owned:
            actor = self._purchase.owner_organization
        else:
            client = self._purchase.customer
            actor = Organization.objects.get(
                actor_id=client.userprofile.actor_id)

        charge = {
            'currency': self._price_model['general_currency'],
            'amount': price
        }

        # Check balance
        try:
            rss_factory = RSSManagerFactory(rss)
            exp_manager = rss_factory.get_expenditure_manager(rss.access_token)
            exp_manager.update_balance(charge, actor)
        except HTTPError as e:
            # Check if it is needed to refresh the access token
            if e.code == 401:
                rss._refresh_token()
                exp_manager.set_credentials(rss.access_token)
                exp_manager.update_balance(charge, actor)
            # Check if the error is due to an insufficient balance
            else:
                raise e
Пример #4
0
    def _check_expenditure_limits(self, price):
        """
        Check if the user can purchase the offering depending on its
        expenditure limits and ir accumulated balance thought the RSS
        """
        # Check is an RSS instance is registered
        if not RSS.objects.all():
            return
        else:
            rss = RSS.objects.all()[0]

        actor = None
        # Check who is the charging actor (user or organization)
        actor = self._purchase.owner_organization

        # Check if the actor has defined expenditure limits
        if not actor.expenditure_limits:
            return

        charge = {
            'currency': self._price_model['general_currency'],
            'amount': price
        }

        # Check balance
        request_failure = None
        try:
            rss_factory = RSSManagerFactory(rss)
            exp_manager = rss_factory.get_expenditure_manager(rss.access_token)
            exp_manager.check_balance(charge, actor)
        except HTTPError as e:
            # Check if it is needed to refresh the access token
            if e.code == 401:
                rss._refresh_token()
                exp_manager.set_credentials(rss.access_token)
                try:
                    exp_manager.check_balance(charge, actor)
                # The user may be unauthorized, an error occurs, or the
                # actor balance is not enough
                except:
                    request_failure = e

            # Check if the error is due to an insufficient balance
            else:
                request_failure = e
        except:
            request_failure = e

        # Raise  the correct failure
        if request_failure:
            if type(request_failure) == HTTPError and request_failure.code == 404\
             and json.loads(request_failure.read())['exceptionId'] == 'SVC3705':
                raise Exception(
                    'There is not enough balance. Check your expenditure limits'
                )
            else:
                raise request_failure

        self._expenditure_used = True
Пример #5
0
    def _check_expenditure_limits(self, price):
        """
        Check if the user can purchase the offering depending on its
        expenditure limits and ir accumulated balance thought the RSS
        """
        # Check is an RSS instance is registered
        if not RSS.objects.all():
            return
        else:
            rss = RSS.objects.all()[0]

        actor = None
        # Check who is the charging actor (user or organization)
        actor = self._purchase.owner_organization

        # Check if the actor has defined expenditure limits
        if not actor.expenditure_limits:
            return

        charge = {
            'currency': self._price_model['general_currency'],
            'amount': price
        }

        # Check balance
        request_failure = None
        try:
            rss_factory = RSSManagerFactory(rss)
            exp_manager = rss_factory.get_expenditure_manager(rss.access_token)
            exp_manager.check_balance(charge, actor)
        except HTTPError as e:
            # Check if it is needed to refresh the access token
            if e.code == 401:
                rss._refresh_token()
                exp_manager.set_credentials(rss.access_token)
                try:
                    exp_manager.check_balance(charge, actor)
                # The user may be unauthorized, an error occurs, or the
                # actor balance is not enough
                except:
                    request_failure = e

            # Check if the error is due to an insufficient balance
            else:
                request_failure = e
        except:
            request_failure = e

        # Raise  the correct failure
        if request_failure:
            if type(request_failure) == HTTPError and request_failure.code == 404\
             and json.loads(request_failure.read())['exceptionId'] == 'SVC3705':
                    raise Exception('There is not enough balance. Check your expenditure limits')
            else:
                raise request_failure

        self._expenditure_used = True
Пример #6
0
    def update(self, request, org):

        # Get the organization
        try:
            organization = Organization.objects.get(name=org)
        except:
            return build_response(request, 404, 'Organization not found')

        if not request.user.is_active:
            return build_response(request, 403, 'Forbidden')

        if not request.user.is_staff and request.user.pk not in organization.managers:
            return build_response(request, 403, 'Forbidden')

        try:
            # Load request data
            data = json.loads(request.raw_post_data)

            if 'notification_url' in data:
                if data['notification_url'] and not is_valid_url(data['notification_url']):
                    raise Exception('Enter a valid URL')

                organization.notification_url = data['notification_url']

            # Load the tax address
            new_taxaddr = {}
            if 'tax_address' in data and data['tax_address'] != {}:
                new_taxaddr = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            organization.tax_address = new_taxaddr

            # Load the payment info
            new_payment = {}
            if 'payment_info' in data and data['payment_info'] != {}:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in organization.payment_info and \
                            is_hidden_credit_card(number, organization.payment_info['number']):
                        number = organization.payment_info['number']
                    else:
                        raise Exception('Invalid credit card number')

                new_payment = {
                    'type': data['payment_info']['type'],
                    'number': number,
                    'expire_year': data['payment_info']['expire_year'],
                    'expire_month': data['payment_info']['expire_month'],
                    'cvv2': data['payment_info']['cvv2']
                }

            if 'limits' in data:
                limits = _check_limits(data['limits'])
                currency = limits['currency']
                # Get default RSS
                rss = RSS.objects.all()[0]
                rss_factory = RSSManagerFactory(rss)
                exp_manager = rss_factory.get_expenditure_manager(rss.access_token)

                try:
                    exp_manager.set_actor_limit(limits, organization)
                except HTTPError as e:
                    if e.code == 401:
                        rss.refresh_token()
                        exp_manager.set_credentials(rss.access_token)
                        exp_manager.set_actor_limit(limits, organization)
                    else:
                        raise e

                # Save limits
                limits['currency'] = currency
                organization.expenditure_limits = limits

            organization.payment_info = new_payment
            organization.save()
        except Exception as e:
            msg = 'Invalid JSON content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 200, 'OK')
Пример #7
0
 def run(self):
     from wstore.rss_adaptor.rss_manager_factory import RSSManagerFactory
     rss_factory = RSSManagerFactory(self.rss)
     r = rss_factory.get_rss_adaptor()
     r.send_cdr(self.cdr)
Пример #8
0
def build_rs_model(offering):

    # Get RSS object
    if not len(RSS.objects.all()):
        return

    rss = RSS.objects.all()[0]

    if rss.api_version == 1:
        return

    rss_factory = RSSManagerFactory(rss)
    model_manager = rss_factory.get_model_manager(rss.access_token)

    # Build basic RS model
    # Get applied class
    revenue_class = None
    for plan in (offering.offering_description['pricing']['price_plans']):
        if 'price_components' in plan:

            for comp in plan['price_components']:
                if 'price_function' in comp:
                    revenue_class = 'use'
                    break

                try:
                    unit = Unit.objects.get(name=comp['unit'])
                except:
                    raise Exception('Unsupported unit in price plan model')

                if unit.defined_model == 'pay per use':
                    revenue_class = 'use'
                    break
                elif unit.defined_model == 'subscription':
                    revenue_class = 'subscription'
                elif unit.defined_model == 'single payment' and revenue_class is None:
                    revenue_class = 'single-payment'

        if revenue_class == 'use':
            break

    if revenue_class is not None:
        # Create new provider in the RSS
        prov_manager = rss_factory.get_provider_manager(rss.access_token)
        provider_info = {
            'provider_id': offering.owner_organization.actor_id,
            'provider_name': offering.owner_organization.name
        }
        try:
            prov_manager.register_provider(provider_info)
        except HTTPError as e:
            if e.code == 401:
                rss.refresh_token()
                prov_manager.set_credentials(rss.access_token)
                try:
                    prov_manager.register_provider(provider_info)
                except:
                    pass

        model_info = {}
        for model in rss.revenue_models:
            if model.revenue_class == revenue_class:
                model_info['aggregatorValue'] = model.percentage
                break

        model_info['ownerValue'] = 100 - model_info['aggregatorValue']
        model_info['productClass'] = offering.owner_organization.name + '/' + offering.name + '/' + offering.version

        try:
            model_manager.create_revenue_model(model_info, offering.owner_organization.actor_id)
        except HTTPError as e:
            if e.code == 401:
                rss.refresh_token()
                model_manager.set_credentials(rss.access_token)
                model_manager.create_revenue_model(model_info, offering.owner_organization.actor_id)
            else:
                raise Exception('Revenue Sharing model for offering ' + offering.owner_organization.name + ' ' + offering.name + ' ' + offering.version)
Пример #9
0
    def update(self, request, username):

        if not request.user.is_staff and not request.user.username == username:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)
        # Update the user
        try:
            user = User.objects.get(username=username)
            # Get the user profile
            user_profile = UserProfile.objects.get(user=user)

            # If WStore is not integrated with the accounts enabler
            # update user info and roles
            if not settings.OILAUTH:
                if request.user.is_staff and 'roles' in data:  # The user cannot change its roles
                    if 'admin' in data['roles'] and request.user.is_staff:
                        user.is_staff = True

                    if 'provider' in data['roles']:
                        # Append the provider role to the user
                        orgs = []
                        for o in user_profile.organizations:
                            if Organization.objects.get(pk=o['organization']).name == user.username \
                                    and 'provider' not in o['roles']:
                                o['roles'].append('provider')

                            orgs.append(o)

                        user_profile.organizations = orgs

                    elif 'provider' not in data[
                            'roles'] and 'provider' in user_profile.get_user_roles(
                            ):
                        # Remove the provider role from the user info
                        orgs = []
                        for o in user_profile.organizations:

                            if Organization.objects.get(
                                    pk=o['organization']
                            ).name == user.username:
                                o['roles'].remove('provider')
                                orgs.append(o)
                            else:
                                orgs.append(o)

                        user_profile.organizations = orgs

                if 'notification_url' in data and 'provider' in user_profile.get_user_roles(
                ):
                    user_org = Organization.objects.get(name=user.username)
                    user_org.notification_url = data['notification_url']
                    user_org.save()

                if 'password' in data:
                    user.set_password(data['password'])

                if 'first_name' in data and 'last_name' in data:
                    user.first_name = data['first_name']
                    user.last_name = data['last_name']
                    user_profile.complete_name = data[
                        'first_name'] + ' ' + data['last_name']
                elif 'complete_name' in data:
                    user_profile.complete_name = data['complete_name']
            else:
                user_org = Organization.objects.get(
                    actor_id=user.userprofile.actor_id)
                if 'notification_url' in data and 'provider' in user_profile.get_user_roles(
                ):
                    user_org.notification_url = data['notification_url']
                    user_org.save()

                # Check if expenditure limits are included in the request
                if 'limits' in data and data['limits']:
                    limits = _check_limits(data['limits'])
                    currency = limits['currency']
                    # Get default RSS instance
                    try:
                        rss_instance = RSS.objects.all()[0]
                    except:
                        raise Exception(
                            'No RSS instance registered: An RSS instance is needed for setting up expenditure limits'
                        )
                    # Create limits in the RSS
                    try:
                        rss_factory = RSSManagerFactory(rss_instance)
                        exp_manager = rss_factory.get_expenditure_manager(
                            rss_instance.access_token)
                        exp_manager.set_actor_limit(limits, user.userprofile)
                    except HTTPError as e:
                        if e.code == 401:
                            rss_instance.refresh_token()
                            exp_manager.set_credentials(
                                rss_instance.access_token)
                            exp_manager.set_actor_limit(
                                limits, user.userprofile)
                        else:
                            raise e

                    # Save limits
                    limits['currency'] = currency
                    user_org.expenditure_limits = limits
                    user_org.save()

            if 'tax_address' in data:
                user_profile.tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }
            else:
                # the update is absolute so if no tax address provided it is deleted
                user_profile.tax_address = {}

            if 'payment_info' in data:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in user_profile.payment_info and \
                    is_hidden_credit_card(number, user_profile.payment_info['number']):
                        number = user_profile.payment_info['number']
                    else:
                        raise Exception('')

                user_profile.payment_info = {
                    'type': data['payment_info']['type'],
                    'number': number,
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }
            else:
                # the update is absolute so if no payment info provided it is deleted
                user_profile.payment_info = {}

            user.save()
            user_profile.save()

        except Exception as e:
            msg = 'Invalid content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 200, 'OK')
Пример #10
0
    def update(self, request, rss):
        """
        Makes a partial update, only name, limits and default selection
        """
        # Check if the user is staff
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Check rss
        try:
            rss_model = RSS.objects.get(name=rss)
        except:
            return build_response(request, 404, 'Not found')

        # Get data
        try:
            data = json.loads(request.raw_post_data)
        except:
            return build_response(request, 400, 'Invalid JSON data')

        # Check the name
        if 'name' in data and data['name'].lower() != rss.lower():
            # Check that the name does not exist
            exist = True
            try:
                RSS.objects.get(name=data['name'])
            except:
                exist = False

            if exist:
                return build_response(request, 400, 'The selected name is in use')

            rss_model.name = data['name']
            rss_model.save()

        limits = {}
        # Check if limits has been provided
        if 'limits' in data:
            limits = _check_limits(data['limits'])

        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        # Update expenditure limits
        rss_factory = RSSManagerFactory(rss_model)
        if limits:
            old_limits = rss_model.expenditure_limits
            rss_model.expenditure_limits = limits
            rss_model.save()
            # Make the update request
            exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)
            call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

            if call_result[0]:
                # Reset expenditure limits
                rss_model.expenditure_limits = old_limits
                return build_response(request, call_result[1], call_result[2])

        # Update revenue sharing models
        if len(sharing_models):
            rss_model.revenue_models = []

            if rss_model.api_version == 1:
                model_manager = rss_factory.get_model_manager(request.user.userprofile.access_token)

            # Update the models
            for model in sharing_models:
                revenue_model = RevenueModel(
                    revenue_class=model['class'],
                    percentage=Decimal(model['percentage'])
                )

                if rss_model.api_version == 1:
                    def call_model_creation():
                        model_manager.update_revenue_model(model)

                    call_result = _make_rss_request(model_manager, call_model_creation, request.user)

                    if call_result[0]:
                        return build_response(request, call_result[1], call_result[2])

                rss_model.revenue_models.append(revenue_model)

        # Update credentials
        rss_model.access_token = request.user.userprofile.access_token
        rss_model.refresh_token = request.user.userprofile.refresh_token

        # Save the model
        rss_model.save()

        return build_response(request, 200, 'OK')
Пример #11
0
    def create(self, request):

        # Only the admin can register new RSS instances
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        if 'name' not in data or 'host' not in data or 'api_version' not in data:
            msg = 'RSS creation error: Missing a required field'

            if 'name' not in data:
                msg += ', name'

            if 'host' not in data:
                msg += ', host'

            if 'api_version' not in data:
                msg += ', api_version'

            return build_response(request, 400, msg)

        # Check name regex
        if not is_valid_id(data['name']):
            return build_response(request, 400, 'RSS creation error: Invalid name format')

        # Check url regex
        if not is_valid_url(data['host']):
            return build_response(request, 400, 'RSS creation error: Invalid URL format')

        # Check api_version format
        try:
            api_version = int(data['api_version'])
        except:
            return build_response(request, 400, 'RSS creation error: Invalid api_version format, must be an integer (1 or 2)')

        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'RSS creation error: Invalid api_version, must be 1 or 2')

        # Check if the information provided is not already registered
        if len(RSS.objects.all()) > 0:
            return build_response(request, 409, 'RSS creation error: There is a RSS instance already registered')

        limits = {}
        cont = Context.objects.all()[0]

        # Check request limits
        if 'limits' in data:
            try:
                limits = _check_limits(data['limits'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        if not len(limits):
            # Set default limits
            limits = {
                'currency': cont.allowed_currencies['default'],
                'perTransaction': 10000,
                'weekly': 100000,
                'daily': 10000,
                'monthly': 100000
            }

        # Check revenue sharing models
        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))
        else:
            # Set default revenue models
            sharing_models = [{
                'class': 'single-payment',
                'percentage': 10.0
            }, {
                'class': 'subscription',
                'percentage': 20.0
            }, {
                'class': 'use',
                'percentage': 30.0
            }]

        # Build revenue models
        db_revenue_models = []
        for model in sharing_models:
            db_revenue_models.append(RevenueModel(
                revenue_class=model['class'],
                percentage=Decimal(model['percentage'])
            ))

        if not data['host'].endswith('/'):
            data['host'] += '/'

        # Create the new entry
        rss = RSS.objects.create(
            name=data['name'],
            host=data['host'],
            api_version=api_version,
            expenditure_limits=limits,
            revenue_models=db_revenue_models,
            aggregator_id=request.user.email
        )

        rss_factory = RSSManagerFactory(rss)

        # Create a new provider if needed
        if api_version == 2:
            prov_manager = rss_factory.get_provider_manager(request.user.userprofile.access_token)
            provider_info = {
                'provider_id': settings.STORE_NAME.lower() + '-provider',
                'provider_name': settings.STORE_NAME + '-Provider'
            }
            call_result = _make_rss_request(prov_manager, prov_manager.register_provider, request.user, provider_info)

            if call_result[0]:
                rss.delete()
                # Return error response
                return build_response(request, call_result[1], call_result[2])

        exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)

        # Create default expenditure limits
        call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

        if call_result[0]:
            rss.delete()
            # Return error response
            return build_response(request, call_result[1], call_result[2])

        # Create default revenue sharing models
        if api_version == 1:
            model_manager = rss_factory.get_model_manager(rss, request.user)

            model_created = False
            for model in sharing_models:
                def call_model_creation():
                    model_manager.create_revenue_model(model)

                call_result = _make_rss_request(model_manager, call_model_creation, request.user)

                if call_result[0] and not model_created:
                    rss.delete()
                    return build_response(request, call_result[1], call_result[2])
                elif not call_result[0]:
                    model_created = True

        # The request has been success so the used credentials are valid
        # Store the credentials for future access
        rss.access_token = request.user.userprofile.access_token
        rss.refresh_token = request.user.userprofile.refresh_token
        rss.save()

        return build_response(request, 201, 'Created')
Пример #12
0
    def update(self, request, org):

        # Get the organization
        try:
            organization = Organization.objects.get(name=org)
        except:
            return build_response(request, 404, 'Organization not found')

        if not request.user.is_active:
            return build_response(request, 403, 'Forbidden')

        if not request.user.is_staff and request.user.pk not in organization.managers:
            return build_response(request, 403, 'Forbidden')

        try:
            # Load request data
            data = json.loads(request.raw_post_data)

            if 'notification_url' in data:
                if data['notification_url'] and not is_valid_url(
                        data['notification_url']):
                    raise Exception('Enter a valid URL')

                organization.notification_url = data['notification_url']

            # Load the tax address
            new_taxaddr = {}
            if 'tax_address' in data and data['tax_address'] != {}:
                new_taxaddr = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            organization.tax_address = new_taxaddr

            # Load the payment info
            new_payment = {}
            if 'payment_info' in data and data['payment_info'] != {}:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in organization.payment_info and \
                            is_hidden_credit_card(number, organization.payment_info['number']):
                        number = organization.payment_info['number']
                    else:
                        raise Exception('Invalid credit card number')

                new_payment = {
                    'type': data['payment_info']['type'],
                    'number': number,
                    'expire_year': data['payment_info']['expire_year'],
                    'expire_month': data['payment_info']['expire_month'],
                    'cvv2': data['payment_info']['cvv2']
                }

            if 'limits' in data:
                limits = _check_limits(data['limits'])
                currency = limits['currency']
                # Get default RSS
                rss = RSS.objects.all()[0]
                rss_factory = RSSManagerFactory(rss)
                exp_manager = rss_factory.get_expenditure_manager(
                    rss.access_token)

                try:
                    exp_manager.set_actor_limit(limits, organization)
                except HTTPError as e:
                    if e.code == 401:
                        rss.refresh_token()
                        exp_manager.set_credentials(rss.access_token)
                        exp_manager.set_actor_limit(limits, organization)
                    else:
                        raise e

                # Save limits
                limits['currency'] = currency
                organization.expenditure_limits = limits

            organization.payment_info = new_payment
            organization.save()
        except Exception as e:
            msg = 'Invalid JSON content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 200, 'OK')
Пример #13
0
 def run(self):
     from wstore.rss_adaptor.rss_manager_factory import RSSManagerFactory
     rss_factory = RSSManagerFactory(self.rss)
     r = rss_factory.get_rss_adaptor()
     r.send_cdr(self.cdr)
Пример #14
0
    def update(self, request, username):

        if not request.user.is_staff and not request.user.username == username:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)
        # Update the user
        try:
            user = User.objects.get(username=username)
            # Get the user profile
            user_profile = UserProfile.objects.get(user=user)

            # If WStore is not integrated with the accounts enabler
            # update user info and roles
            if not settings.OILAUTH:
                if request.user.is_staff and 'roles' in data:  # The user cannot change its roles
                    if 'admin' in data['roles'] and request.user.is_staff:
                        user.is_staff = True

                    if 'provider' in data['roles']:
                        # Append the provider role to the user
                        orgs = []
                        for o in user_profile.organizations:
                            if Organization.objects.get(pk=o['organization']).name == user.username \
                                    and 'provider' not in o['roles']:
                                o['roles'].append('provider')

                            orgs.append(o)

                        user_profile.organizations = orgs

                    elif 'provider' not in data['roles'] and 'provider' in user_profile.get_user_roles():
                        # Remove the provider role from the user info
                        orgs = []
                        for o in user_profile.organizations:

                            if Organization.objects.get(pk=o['organization']).name == user.username:
                                o['roles'].remove('provider')
                                orgs.append(o)
                            else:
                                orgs.append(o)

                        user_profile.organizations = orgs

                if 'notification_url' in data and 'provider' in user_profile.get_user_roles():
                    user_org = Organization.objects.get(name=user.username)
                    user_org.notification_url = data['notification_url']
                    user_org.save()

                if 'password' in data:
                    user.set_password(data['password'])

                if 'first_name' in data and 'last_name' in data:
                    user.first_name = data['first_name']
                    user.last_name = data['last_name']
                    user_profile.complete_name = data['first_name'] + ' ' + data['last_name']
                elif 'complete_name' in data:
                    user_profile.complete_name = data['complete_name']
            else:
                user_org = Organization.objects.get(actor_id=user.userprofile.actor_id)
                if 'notification_url' in data and 'provider' in user_profile.get_user_roles():
                    user_org.notification_url = data['notification_url']
                    user_org.save()

                # Check if expenditure limits are included in the request
                if 'limits' in data and data['limits']:
                    limits = _check_limits(data['limits'])
                    currency = limits['currency']
                    # Get default RSS instance
                    try:
                        rss_instance = RSS.objects.all()[0]
                    except:
                        raise Exception('No RSS instance registered: An RSS instance is needed for setting up expenditure limits')
                    # Create limits in the RSS
                    try:
                        rss_factory = RSSManagerFactory(rss_instance)
                        exp_manager = rss_factory.get_expenditure_manager(rss_instance.access_token)
                        exp_manager.set_actor_limit(limits, user.userprofile)
                    except HTTPError as e:
                        if e.code == 401:
                            rss_instance.refresh_token()
                            exp_manager.set_credentials(rss_instance.access_token)
                            exp_manager.set_actor_limit(limits, user.userprofile)
                        else:
                            raise e

                    # Save limits
                    limits['currency'] = currency
                    user_org.expenditure_limits = limits
                    user_org.save()

            if 'tax_address' in data:
                user_profile.tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }
            else:
                # the update is absolute so if no tax address provided it is deleted
                user_profile.tax_address = {}

            if 'payment_info' in data:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in user_profile.payment_info and \
                    is_hidden_credit_card(number, user_profile.payment_info['number']):
                        number = user_profile.payment_info['number']
                    else:
                        raise Exception('')

                user_profile.payment_info = {
                    'type': data['payment_info']['type'],
                    'number': number,
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }
            else:
                # the update is absolute so if no payment info provided it is deleted
                user_profile.payment_info = {}

            user.save()
            user_profile.save()

        except Exception as e:
            msg = 'Invalid content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 200, 'OK')