예제 #1
0
    def plugin_data(self, request: Request):
        del request  # unused
        menu_data = PluginUtils.get_plugins_menus(self.config_type)
        plugin_names = []
        plugin_states = {}
        plugin_components = {}
        plugins = PluginUtils.get_plugins(self.config_type)
        for plugin_name in plugins:
            plugin_names.append(plugin_name)
            plugin = plugins[plugin_name]
            if self.config_type in plugin.states:
                states_data, found = plugin.states[
                    self.config_type].get_javascript()
                if found:
                    plugin_states[plugin_name] = states_data
            if self.config_type in plugin.components:
                components = plugin.components[self.config_type]
                plugin_components[plugin_name] = {}
                for component_name in components:
                    component_data, found = components[
                        component_name].get_javascript()
                    if found:
                        plugin_components[plugin_name][
                            component_name] = component_data

        return Response(
            data={
                'menu_data': menu_data,
                'plugin_names': plugin_names,
                'plugin_states': plugin_states,
                'plugin_components': plugin_components,
            })
예제 #2
0
    def save_component_data(self, instance):
        plugins = PluginUtils.get_plugins_for_component(
            config_type=self.Meta.plugin_config_type,
            component_name=self.Meta.component_name)

        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(
                self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning(
                    'Component does not define serializer class or reverse relation name, skipping'
                )
                continue

            component_data_serializer = self.fields[
                component.reverse_relation_name]
            if hasattr(instance, component.reverse_relation_name):
                if component_data_serializer.is_valid(raise_exception=True):
                    update_serializer = component.serializer_class(
                        instance=getattr(instance,
                                         component.reverse_relation_name))
                    validated_data = component_data_serializer.validated_data
                    del validated_data[component.parent_obj_name]
                    update_serializer.update(
                        instance=getattr(instance,
                                         component.reverse_relation_name),
                        validated_data=validated_data,
                    )
            else:
                setattr(component_data_serializer, component.parent_obj_name,
                        instance)
                if component_data_serializer.is_valid(raise_exception=True):
                    component_data_serializer.save()
예제 #3
0
    def cleanup_component_data(self, keep_for_plugins: List[Plugin] = None):
        if keep_for_plugins is None:
            keep_for_plugins = []

        if self.instance is None:
            LOG.error('Cleanup component data called with no instance, aborting')
            return

        plugins = PluginUtils.get_plugins_for_component(
            config_type=self.Meta.plugin_config_type,
            component_name=self.Meta.component_name
        )

        data_deleted = False
        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning('Component does not define serializer class or reverse relation name, skipping')
                continue

            if plugin.plugin_model in keep_for_plugins:
                continue

            component_data_instance = getattr(self.instance, component.reverse_relation_name, None)
            if component_data_instance is not None:
                component_data_instance.delete()
                setattr(self.instance, component.reverse_relation_name, None)
                data_deleted = True

        if data_deleted:
            self.instance.save()
예제 #4
0
 def create_options(self, request):
     groups = ServerGroup.objects.values('id', 'name')
     server_plugins = PluginUtils.get_server_plugins()
     return Response({
         'statusList': ServerStatus.CHOICES,
         'plugins': server_plugins,
         'groups': groups
     })
예제 #5
0
    def get_plugin_data(product):
        if product.module.plugin_label:
            component = PluginUtils.get_staff_component(
                plugin_label=product.module.plugin_label,
                component_name='ProductSettings')

            if component:
                return component.get(product=product)

        return None
예제 #6
0
    def get_plugin_details(obj):
        if obj.plugin:
            plugin = PluginUtils.get_plugin(config_type='staff',
                                            plugin_label=obj.plugin.app_label)
            has_settings_component = PluginUtils.has_component(
                config_type='staff',
                plugin_label=obj.plugin.app_label,
                component_name='ServerSettings')

            return {
                'label': obj.plugin.app_label,
                'id': obj.plugin.id,
                'display_name': obj.plugin.display_name,
                'has_settings_component': has_settings_component,
                'has_server_settings': True,
                'server_settings': plugin.server_settings
            }
        else:
            return None
예제 #7
0
 def plugins_menu(self, request):
     del request  # unused
     if has_license:
         return Response(data=PluginUtils.get_plugins_menus(PluginConfigTypes.staff))
     else:
         return Response(
             data={
                 'menus': [],
                 'menu_items': [],
             }
         )
예제 #8
0
    def plugins_with_component(self, request):
        component_name = request.query_params.get('component_name', None)
        labels = PluginUtils.get_plugins_labels_for_component(
            config_type=PluginConfigTypes.staff,
            component_name=component_name,
        )

        plugins = self.queryset.filter(app_label__in=labels).all()

        return Response(
            data={
                'plugins': StaffPluginSerializer(many=True).to_representation(plugins),
            }
        )
예제 #9
0
    def register_module(self, import_path, name):
        LOG.debug('Register called for '
                  '{}'
                  ' -> {}'.format(name, import_path))

        product_module = ProductModule.objects.filter(path=import_path).first()
        plugin_definition = PluginUtils.get_plugin_definition_for_module_path(
            module_path=import_path)
        if product_module is None:
            LOG.debug(
                'Product module not found in database by path, checking by name'
            )
            product_module = ProductModule.objects.filter(name=name).first()

            if product_module is None:
                LOG.debug('Product module not found in database, creating')
                product_module = ProductModule.objects.create(
                    name=name,
                    path=import_path,
                    plugin=None if plugin_definition is None else
                    plugin_definition.plugin_model)
            else:
                LOG.debug(
                    'Product module found in database by name, updating path')
                product_module.path = import_path
                product_module.plugin = plugin_definition.plugin_model
                product_module.save()

        else:
            if product_module.id in self.modules_by_id:
                LOG.debug('Module already registered, skipping')
                return

            if product_module.name != name:
                LOG.warning('Product names do not match, updating name')
                product_module.name = name
                product_module.save()

            if plugin_definition and product_module.plugin != plugin_definition.plugin_model:
                LOG.warning('Product plugins do not match, updating plugin')
                product_module.plugin = plugin_definition.plugin_model
                product_module.save()

        module_id = product_module.id
        self.modules_by_id[module_id] = RegisteredModule(
            module_id, import_path)
        LOG.debug('Module registered')
예제 #10
0
 def to_representation(self, instance):
     repres = super(ServerSerializer, self).to_representation(instance)
     if instance.plugin:
         component = PluginUtils.get_staff_component(
             plugin_label=instance.plugin.app_label,
             component_name=COMPONENT_NAME)
         settings_serializer = getattr(component,
                                       'server_settings_serializer', None)
         if settings_serializer:
             context = {
                 'request': self.context.get('request'),
                 'server': instance
             }
             repres['settings'] = settings_serializer(
                 instance=instance.settings,
                 context=context).to_representation(instance.settings)
     return repres
예제 #11
0
    def get_states(self, request: Request):
        del request  # unused
        plugin_instance = PluginUtils.get_plugin(
            config_type=self.config_type,
            plugin_label=self.plugin_label,
        )
        if plugin_instance and self.config_type in plugin_instance.states:
            states_data, found = plugin_instance.states[self.config_type].get_javascript()

            if found:
                return Response(data={
                    'states': states_data
                })
            else:
                LOG.error('States javascript found for plugin {}:{}'.format(self.config_type, self.plugin_label))
                return HttpResponse(status=204)
        else:
            LOG.error('States not found for plugin {}:{}'.format(self.config_type, self.plugin_label))
            return HttpResponse(status=204)
예제 #12
0
    def get_component(self, request: Request):
        component_name = request.query_params.get('component', None)
        component_instance = PluginUtils.get_component(
            config_type=self.config_type,
            plugin_label=self.plugin_label,
            component_name=component_name,
        )
        if component_instance:
            component_data, found = component_instance.get_javascript()

            if found:
                return Response(data={
                    'data': component_data
                })
            else:
                LOG.error('Component javascript not found for plugin {}:{}'.format(self.config_type, self.plugin_label))
                return HttpResponse(status=204)
        else:
            LOG.error('Component not registered for plugin {}:{}'.format(self.config_type, self.plugin_label))
            return HttpResponse(status=204)
예제 #13
0
    def get_service(self, request: Request):
        service_name = request.query_params.get('service', None)
        service_instance = PluginUtils.get_service(
            config_type=self.config_type,
            plugin_label=self.plugin_label,
            service_name=service_name,
        )
        if service_instance:
            service_data, found = service_instance.get_javascript()

            if found:
                return Response(data={
                    'data': service_data
                })
            else:
                LOG.error('Service javascript not found for plugin {}:{}'.format(self.config_type, self.plugin_label))
                return HttpResponse(status=204)
        else:
            LOG.error('Service not registered for plugin {}:{}'.format(self.config_type, self.plugin_label))
            return HttpResponse(status=204)
예제 #14
0
    def get_components(self, request: Request):
        component_names = request.query_params.get('components', None)  # type: str

        if not component_names:
            return HttpResponse(status=204)

        component_names_list = component_names.split(',')
        component_names_list = list(set(component_names_list))
        components_data = {}

        for component_name in component_names_list:
            component_instance = PluginUtils.get_component(
                config_type=self.config_type,
                plugin_label=self.plugin_label,
                component_name=component_name,
            )
            if component_instance:
                component_data, found = component_instance.get_javascript()

                if found:
                    components_data[component_instance.component_name] = component_data
                else:
                    LOG.error('Component {} javascript not found for plugin {}:{}'.format(
                        component_name,
                        self.config_type,
                        self.plugin_label,
                    ))
            else:
                LOG.error('Component {} not registered for plugin {}:{}'.format(
                    component_name,
                    self.config_type,
                    self.plugin_label,
                ))

        if len(components_data) > 0:
            return Response(data={
                'components': components_data
            })
        else:
            return HttpResponse(status=204)
예제 #15
0
    def create_options(self, request):
        del request  # unused
        options = dict()
        options['groups'] = [{
            'id': group.id,
            'name': group.name,
            'description': group.description
        } for group in ProductGroup.objects.filter(visible=True).all()]
        if not options['groups']:
            raise ObjectNotFound('No product groups exist')
        modules_queryset = ProductModule.objects.filter(
            plugin__enabled=True).exclude(
                plugin__staff_feature_name__in=staff_active_features.
                get_disabled_features())
        options['modules'] = {
            module.id: {
                'id':
                module.id,
                'name':
                module.name,
                'plugin':
                module.plugin_label
                if module.plugin_label and PluginUtils.has_staff_component(
                    plugin_label=module.plugin_label,
                    component_name='ProductSettings') else None,
                'description':
                module.description
            }
            for module in modules_queryset
        }
        if not options['modules']:
            raise ObjectNotFound('No product modules exist')

        options['product_types'] = ProductType.choices
        options['statuses'] = PublicStatuses.choices
        options['price_models'] = PricingModel.choices
        options['auto_setups'] = ProductAutoSetup.choices

        return Response(options)
예제 #16
0
    def save_component_data(self, instance):
        plugins = PluginUtils.get_plugins_for_component(
            config_type=self.Meta.plugin_config_type,
            component_name=self.Meta.component_name
        )

        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning('Component does not define serializer class or reverse relation name, skipping')
                continue

            if component.reverse_relation_name in self.component_fields:
                component_data_serializer = self.component_fields[component.reverse_relation_name]
                if component_data_serializer.instance:
                    # performing an update
                    if component_data_serializer.is_valid(raise_exception=True):
                        component_data_serializer.save()
                else:
                    # performing an create
                    component_data_serializer = self.component_fields[component.reverse_relation_name]
                    component_data_serializer.initial_data[component.parent_obj_name] = instance.id
                    if component_data_serializer.is_valid(raise_exception=True):
                        component_data_serializer.save()
예제 #17
0
 def to_internal_value(self, data):
     intern = super(ServerSerializer, self).to_internal_value(data)
     plugin = intern.get('plugin')
     if plugin:
         component = PluginUtils.get_staff_component(
             plugin_label=plugin.app_label, component_name=COMPONENT_NAME)
         settings_serializer = getattr(component,
                                       'server_settings_serializer', None)
         if settings_serializer:
             if self.instance:
                 server = self.instance
             else:
                 server = None
             context = {
                 'request': self.context.get('request'),
                 'server': server
             }
             try:
                 intern['settings'] = settings_serializer(
                     context=context).to_internal_value(
                         intern.get('settings'))
             except ValidationError as v:
                 raise ValidationError(detail={'settings': [v.detail]})
     return intern
예제 #18
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if not hasattr(
                self, 'Meta'
        ) or self.Meta.plugin_config_type is None or self.Meta.component_name is None:
            # component_name and plugin_config_type should be defined in serializer Meta class
            raise Exception(
                'Serializer meta does contain component information')

        plugins = PluginUtils.get_plugins_for_component(
            config_type=self.Meta.plugin_config_type,
            component_name=self.Meta.component_name)

        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(
                self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning(
                    'Component does not define serializer class or reverse relation name, skipping'
                )
                continue

            if 'data' in kwargs:
                data = kwargs['data']
                component_data = data[component.reverse_relation_name]
                # TODO: see if this is safe
                component_data[component.parent_obj_name] = data['id']
                self.fields[
                    component.
                    reverse_relation_name] = component.serializer_class(
                        data=component_data)
            else:
                self.fields[
                    component.
                    reverse_relation_name] = component.serializer_class()
예제 #19
0
 def get_available_plugins(obj):
     return PluginUtils.get_server_plugins()
예제 #20
0
    def update(self, instance, validated_data):
        configurable_options = validated_data.pop('configurable_options', None)
        with transaction.atomic():
            # removing name and description from validated data since they should not be updated
            del validated_data['name'], validated_data['description']
            product = validated_data['product']
            component = PluginUtils.get_enduser_component(
                plugin_label=product.module.plugin_label,
                component_name='OrderProduct',
            )

            if component:
                plugin_data = validated_data['plugin_data']
                serializer = component.create_serializer(
                    plugin_data=plugin_data, context=self.context)
                if serializer and serializer.is_valid(raise_exception=True):
                    # update data just in case it was changed during validation process
                    validated_data['plugin_data'] = dict(
                        serializer.validated_data)
                    # TODO: this is a temporary solution, we should abstract this so it would not depend on domains
                    if product.module.plugin_label == 'domains':
                        validated_data['name'] = plugin_data['name']

            order_item = super().update(
                instance=instance,
                validated_data=validated_data)  # type: OrderItem
            order_item.configurable_options.all().delete()
            for config_option in configurable_options:
                # Filter out all configurable options no longer valid
                if not config_option['option'].has_cycle(
                        cycle=order_item.cycle.cycle,
                        cycle_multiplier=order_item.cycle.cycle_multiplier,
                        choice_value=config_option.get('option_value'),
                        currency=order_item.currency.code,
                ):
                    continue
                if config_option['option'].widget == 'yesno':
                    if config_option['option_value'] != 'yes':
                        # Ignore unchecked checkboxes
                        continue
                choice_value = None
                has_price = True
                if config_option['option'].widget == 'text_in':
                    has_price = False
                quantity = config_option.get('quantity')
                if config_option['option'].has_choices:
                    choice_value = config_option['option_value']
                unit_price, price, setupfee = config_option[
                    'option'].get_price_by_cycle_quantity_and_choice(
                        cycle_name=order_item.cycle.cycle,
                        cycle_multiplier=order_item.cycle.cycle_multiplier,
                        currency=order_item.currency,
                        quantity=config_option['quantity'],
                        choice_value=choice_value,
                        option_value=config_option['option_value'],
                    )
                order_item.configurable_options.create(
                    option=config_option['option'],
                    option_value=config_option['option_value'],
                    quantity=quantity,
                    has_price=has_price,
                    taxable=validated_data['taxable'],
                    unit_price=unit_price,
                    price=price,
                    setup_fee=setupfee)
            # Update order item taxes
            order_item.taxes.all().delete()
            self.create_taxes(order_item=order_item)

            return order_item
예제 #21
0
 def get_has_plugin(obj):
     return PluginUtils.has_enduser_component(
         plugin_label=obj.product.module.plugin_label,
         component_name='OrderProduct')
예제 #22
0
    def validate(self, attrs):
        cart = attrs['cart']
        product = attrs.get('product')
        cycle = attrs.get('cycle')
        attrs['name'] = product.name
        attrs[
            'description'] = product.description or product.name or 'Product'  # NOTE(tomo): description is required
        if not cycle and product.price_model != PricingModel.free:
            raise serializers.ValidationError(
                {'cycle': _('A billing cycle is required')})
        if cycle:
            try:
                product.cycles.available_for_order(currency=cart.currency).get(
                    pk=cycle.pk)
            except (ProductCycle.DoesNotExist,
                    ProductCycle.MultipleObjectsReturned):
                LOG.debug(
                    'Tried to add a product to cart with an invalid currency.'
                    ' Cart currency {}; Cycle currency: {}'.format(
                        cart.currency, cycle.currency))
                raise serializers.ValidationError(
                    detail=_('Product not available'))
            attrs['cycle_display'] = cycle.display_name

        # update pricing information here
        self.update_pricing_from_product(attrs=attrs)

        # validate configurable options are valid and public and all required are present
        configurable_options = attrs.get('configurable_options')
        if cycle:
            req_filter = dict(cycle=cycle.cycle,
                              cycle_multiplier=cycle.cycle_multiplier,
                              currency=cycle.currency,
                              required=True)
            required_options = product.configurable_options.public(
            ).with_cycles(**req_filter)
            for req_opt in required_options:
                found = False
                for sent_opt in configurable_options:
                    if req_opt.pk == sent_opt['option'].pk:
                        found = True
                if not found:
                    raise serializers.ValidationError(
                        detail=_('Value is required for {}').format(
                            req_opt.description))

        for conf_opt in configurable_options:
            db_opt = conf_opt.get('option')
            if not db_opt:
                raise serializers.ValidationError(
                    detail=_('Invalid option selected'))
            if db_opt.status != ConfigurableOptionStatus.public:
                raise serializers.ValidationError(
                    detail=_('Invalid option selected'))
            if not product.configurable_options.filter(id=db_opt.id).exists():
                raise serializers.ValidationError(
                    detail=_('Invalid option selected'))

        # validate plugin data
        plugin_label = product.module.plugin_label
        component = PluginUtils.get_enduser_component(
            plugin_label=plugin_label,
            component_name='OrderProduct',
        )

        if component:
            plugin_data = attrs['plugin_data']
            serializer = component.create_serializer(plugin_data=plugin_data,
                                                     context=self.context)
            if serializer:
                try:
                    serializer.is_valid(raise_exception=True)
                except ValidationError as e:
                    raise ValidationError(detail={'plugin_data': e.detail})

        return super().validate(attrs)
예제 #23
0
    url(
        r'',
        include(('fleiostaff.servers.urls', 'fleiostaff.servers'),
                namespace='server')),
    url(
        r'',
        include(('fleio.osbackup.urls', 'fleio.osbackup'),
                namespace='osbackup')),
    url(r'^get-sso-session$', views.get_sso_session, name='get-sso-session'),
    url(r'^set-license$', views.set_license, name='set-license'),
    url(r'^refresh-license$', views.refresh_license, name='refresh-license'),
    url(r'^login$', views.login, name='login'),
    url(r'^logout$', views.logout, name='logout'),
    url(r'^current-user$', views.current_user, name='current-user'),
    url(r'^services-statuses$',
        views.get_services_statuses,
        name='services-statuses'),
    url(r'^app-status', views.get_app_status, name='app-status'),
    url(r'^get-license-info$', views.get_license_info,
        name='get-license-info'),
    url(r'^reset-password/$', password_reset, name='reset-password'),
    url(r'^reset-password/confirm/$',
        password_reset_confirm,
        name='reset-password-confirm'),
    url('',
        include(('fleio.reports.urls', 'fleio.reports'), namespace='reports'))
]

PluginUtils.append_plugin_urls(urlpatterns=urlpatterns,
                               config_type=PluginConfigTypes.staff)
예제 #24
0
    def __init__(self, *args, **kwargs):
        plugins = PluginUtils.get_plugins_for_component(
            config_type=self.Meta.plugin_config_type,
            component_name=self.Meta.component_name
        )

        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning('Component does not define serializer class or reverse relation name, skipping')
                continue

            if self.Meta.fields != '__all__' and component.reverse_relation_name not in self.Meta.fields:
                self.Meta.fields += (component.reverse_relation_name, )
        super().__init__(*args, **kwargs)

        if not hasattr(self, 'Meta') or self.Meta.plugin_config_type is None or self.Meta.component_name is None:
            # component_name and plugin_config_type should be defined in serializer Meta class
            raise Exception('Serializer meta does contain component information')

        data = kwargs.get('data', None)
        partial = kwargs.get('partial', False)
        update = self.instance is not None and data is not None
        self.component_fields = {}
        for plugin in plugins:  # PluginDefinition
            component = plugin.components[self.Meta.plugin_config_type].get(self.Meta.component_name)
            if component.reverse_relation_name is None or component.serializer_class is None:
                LOG.warning('Component does not define serializer class or reverse relation name, skipping')
                continue

            if update:
                # performing an update
                if component.reverse_relation_name not in data:
                    # serializer has no data for component, ignoring
                    continue

                self.component_fields[component.reverse_relation_name] = component.serializer_class(
                    data=data[component.reverse_relation_name],
                    instance=getattr(self.instance, component.reverse_relation_name, None),
                    partial=partial
                )

                continue

            if data:
                # performing a create
                if component.reverse_relation_name not in data:
                    # serializer has no data for component, ignoring
                    continue

                component_data_serializer = component.serializer_class(
                    data=data[component.reverse_relation_name],
                )

                self.component_fields[component.reverse_relation_name] = component_data_serializer

                continue

            if self.instance:
                # performing a retrieve
                if hasattr(self.instance, component.reverse_relation_name):
                    self.fields[component.reverse_relation_name] = component.serializer_class(
                        instance=getattr(self.instance, component.reverse_relation_name, None)
                    )
예제 #25
0
 def get_has_settings_component(obj: Server):
     return PluginUtils.has_staff_component(
         plugin_label=obj.plugin.app_label, component_name=COMPONENT_NAME)
예제 #26
0
                namespace='notifications')),
    path(
        'sfauth/',
        include(('fleio.core.second_factor_auth.urls',
                 'fleio.core.second_factor_auth'),
                namespace='sfatypesmanager')),
    path('login', views.login, name='login'),
    path('logout', views.logout, name='logout'),
    path('sso', views.sso, name='sso'),
    path('current-user', views.current_user, name='current-user'),
    path('reset-password/', views.password_reset, name='reset-password'),
    path('reset-password/confirm/',
         views.password_reset_confirm,
         name='reset-password-confirm'),
    path('confirm-email/',
         views.confirm_email_after_signup,
         name='email-sign-up-confirmation'),
    path('resend-confirmation-email/',
         views.resend_email_confirmation_email_message,
         name='resend-email-confirmation'),
    path('get-external-billing-url/',
         views.get_external_billing_url,
         name='get-external-billing-url'),
    path('terms-of-service', tos_preview, name='terms_of_service_preview'),
]

PluginUtils.append_plugin_urls(
    urlpatterns=urlpatterns,
    config_type=PluginConfigTypes.enduser,
)