Exemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        """Initialize and maintain Engine"""
        # Since SQLAlchemyProvider can cater to multiple databases, it is important
        #   that we know which database we are dealing with, to run database-specific
        #   statements like `PRAGMA` for SQLite.
        if 'DATABASE' not in args[2]:
            logger.error(
                f'Missing `DATABASE` information in conn_info: {args[2]}')
            raise ConfigurationError(
                'Missing `DATABASE` attribute in Connection info')

        super().__init__(*args, **kwargs)

        kwargs = self._get_database_specific_engine_args()

        self._engine = create_engine(make_url(self.conn_info['DATABASE_URI']),
                                     **kwargs)

        if self.conn_info['DATABASE'] == Database.POSTGRESQL.value:
            # Nest database tables under a schema, so that we have complete control
            #   on creating/dropping db structures. We cannot control structures in the
            #   the default `public` schema.
            #
            # Use `SCHEMA` value if specified as part of the conn info. Otherwise, construct
            #   and use default schema name as `DB`_schema.
            schema = self.conn_info[
                'SCHEMA'] if 'SCHEMA' in self.conn_info else 'public'

            self._metadata = MetaData(bind=self._engine, schema=schema)
        else:
            self._metadata = MetaData(bind=self._engine)

        # A temporary cache of already constructed model classes
        self._model_classes = {}
Exemplo n.º 2
0
    def process_request(self, request_object):
        email = request_object.email
        account = Account.query.filter(email=email).first

        if account:
            token = str(uuid.uuid4())
            token_ts = datetime.datetime.utcnow() + datetime.timedelta(
                hours=24)
            account.update({
                "verification_token": token,
                "token_timestamp": token_ts
            })

            # Send the password request email
            email_builder = perform_import(active_config.RESET_EMAIL_CALLBACK)
            if not email_builder:
                raise ConfigurationError(
                    '`RESET_EMAIL_CALLBACK` config must be set to a '
                    'valid function.')
            email_msg = email_builder(account.email, token)
            email_msg.send()

            return ResponseSuccess(Status.SUCCESS, {"message": "Success"})
        else:
            return ResponseFailure.build_unprocessable_error(
                {'email': 'Account does not exist.'})
Exemplo n.º 3
0
    def _initialize_brokers(self):
        """Read config file and initialize brokers"""
        configured_brokers = self.config['BROKERS']
        broker_objects = {}

        logger.debug("Initializing brokers...")
        if configured_brokers and isinstance(configured_brokers, dict):
            if 'default' not in configured_brokers:
                raise ConfigurationError("You must define a 'default' broker")

            for broker_name, conn_info in configured_brokers.items():
                broker_full_path = conn_info['PROVIDER']
                broker_module, broker_class = broker_full_path.rsplit(
                    '.', maxsplit=1)

                broker_cls = getattr(importlib.import_module(broker_module),
                                     broker_class)
                broker_objects[broker_name] = broker_cls(
                    broker_name, self, conn_info)

        self._brokers = broker_objects

        # Initialize subscribers for Brokers
        for _, subscriber_record in self.subscribers.items():
            subscriber = subscriber_record.cls
            broker_name = subscriber.meta_.broker

            if broker_name not in self._brokers:
                raise ConfigurationError(
                    f"Broker {broker_name} has not been configured.")

            self._brokers[broker_name].register(subscriber.meta_.domain_event,
                                                subscriber)

        # Initialize command handlers for Brokers
        for _, command_handler_record in self.command_handlers.items():
            command_handler = command_handler_record.cls
            broker_name = command_handler.meta_.broker

            if broker_name not in self._brokers:
                raise ConfigurationError(
                    f"Broker {broker_name} has not been configured.")

            self._brokers[broker_name].register(
                command_handler.meta_.command_cls, command_handler)
Exemplo n.º 4
0
    def generate_identity(cls):
        """Generate Unique Identifier, based on configured strategy"""
        if current_domain.config['IDENTITY_STRATEGY'] == IdentityStrategy.UUID:
            if current_domain.config['IDENTITY_TYPE'] == IdentityType.INTEGER:
                return uuid4().int
            elif current_domain.config['IDENTITY_TYPE'] == IdentityType.STRING:
                return str(uuid4())
            elif current_domain.config['IDENTITY_TYPE'] == IdentityType.UUID:
                return uuid4()
            else:
                raise ConfigurationError(
                    f'Unknown Identity Type {current_domain.config["IDENTITY_TYPE"]}'
                )

        return None  # Database will generate the identity
Exemplo n.º 5
0
    def build_field(self, field_obj):
        """ Map the Entity field to a Marshmallow field """

        # Lookup the field mapping in the dictionary, default to String field
        e_field_type = type(field_obj)
        if e_field_type in self.field_mapping:
            field_opts = {}
            if e_field_type == field.List:
                field_opts['cls_or_instance'] = ma.fields.String
            return self.field_mapping[e_field_type](**field_opts)
        elif e_field_type == field.Auto:
            raise ConfigurationError(
                'Fields of type `Auto` must be manually set in the serializer.'
            )
        else:
            return ma.fields.String()
Exemplo n.º 6
0
    def _initialize_providers(self):
        """Read config file and initialize providers"""
        configured_providers = self.config['DATABASES']
        provider_objects = {}

        if configured_providers and isinstance(configured_providers, dict):
            if 'default' not in configured_providers:
                raise ConfigurationError(
                    "You must define a 'default' provider")

            for provider_name, conn_info in configured_providers.items():
                provider_full_path = conn_info['PROVIDER']
                provider_module, provider_class = provider_full_path.rsplit(
                    '.', maxsplit=1)

                provider_cls = getattr(
                    importlib.import_module(provider_module), provider_class)
                provider_objects[provider_name] = provider_cls(
                    provider_name, self, conn_info)

        return provider_objects
Exemplo n.º 7
0
def _get_identity_type():
    """Retrieve the configured data type for AutoGenerated Identifiers

    If `current_domain` is not yet available, it simply means that Protean is still being loaded.
    Default to `Identity.STRING`
    """
    try:
        if current_domain.config['IDENTITY_TYPE'] == IdentityType.INTEGER:
            return sa_types.Integer
        elif current_domain.config['IDENTITY_TYPE'] == IdentityType.STRING:
            return sa_types.String
        elif current_domain.config['IDENTITY_TYPE'] == IdentityType.UUID:
            return GUID
        else:
            raise ConfigurationError(
                f'Unknown Identity Type {current_domain.config["IDENTITY_TYPE"]}'
            )
    except RuntimeError as exc:
        logger.error(
            f'RuntimeError while identifying data type for identities: {exc}')
        return sa_types.String
Exemplo n.º 8
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Updates the declared fields with the fields of the Entity class
        if not self.opts.entity_cls or not \
                issubclass(self.opts.entity_cls, Entity):
            raise ConfigurationError(
                '`Meta.entity` option must be set and a subclass of `Entity`.')

        entity_fields = OrderedDict()
        for field_name, field_obj in \
                self.opts.entity_cls.meta_.declared_fields.items():
            if self.opts.fields and field_name not in self.opts.fields:
                continue
            elif self.opts.exclude and field_name in self.opts.exclude:
                continue
            elif isinstance(field_obj, field.Reference):
                continue
            elif field_name not in self.declared_fields:
                entity_fields[field_name] = self.build_field(field_obj)

        self.declared_fields.update(entity_fields)
Exemplo n.º 9
0
    def _initialize_email_providers(self):
        """Read config file and initialize email providers"""
        configured_email_providers = self.domain.config["EMAIL_PROVIDERS"]
        email_provider_objects = {}

        if configured_email_providers and isinstance(
                configured_email_providers, dict):
            if "default" not in configured_email_providers:
                raise ConfigurationError(
                    "You must define a 'default' email provider")

            for provider_name, conn_info in configured_email_providers.items():
                provider_full_path = conn_info["PROVIDER"]
                provider_module, provider_class = provider_full_path.rsplit(
                    ".", maxsplit=1)

                provider_cls = getattr(
                    importlib.import_module(provider_module), provider_class)
                email_provider_objects[provider_name] = provider_cls(
                    provider_name, self, conn_info)

        self._email_providers = email_provider_objects
Exemplo n.º 10
0
 def get_serializer_cls(self):
     """ Get the serializer class from the settings"""
     if not active_config.ACCOUNT_SERIALIZER_CLS:
         raise ConfigurationError(
             '`ACCOUNT_SERIALIZER_CLS` has not been set in the config.')
     return perform_import(active_config.ACCOUNT_SERIALIZER_CLS)
Exemplo n.º 11
0
 def get_entity_cls(self):
     """ Get the schema class from the config """
     if not active_config.ACCOUNT_ENTITY:
         raise ConfigurationError(
             '`ACCOUNT_ENTITY` has not been set in the config.')
     return perform_import(active_config.ACCOUNT_ENTITY)