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, })
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()
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()
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 })
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
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
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': [], } )
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), } )
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')
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
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)
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)
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)
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)
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)
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()
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
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()
def get_available_plugins(obj): return PluginUtils.get_server_plugins()
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
def get_has_plugin(obj): return PluginUtils.has_enduser_component( plugin_label=obj.product.module.plugin_label, component_name='OrderProduct')
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)
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)
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) )
def get_has_settings_component(obj: Server): return PluginUtils.has_staff_component( plugin_label=obj.plugin.app_label, component_name=COMPONENT_NAME)
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, )