Esempio n. 1
0
def registerValidation(mapped, exclude=None):
    '''
    Register to mapped class all the validations that can be performed based on the SQL alchemy mapping.
    
    @param mapped: class
        The mapped model class.
    @param exclude: list[string]|tuple(string)
        A list of column names to be excluded from automatic validation.
    @return: Property
        The property id of the model.
    '''
    assert isclass(mapped), 'Invalid class %s' % mapped
    mapper, typeModel = mappingFor(mapped), typeFor(mapped)
    assert isinstance(mapper, Mapper), 'Invalid mapped class %s' % mapped
    assert isinstance(typeModel, TypeModel), 'Invalid model class %s' % mapped
    assert not exclude or isinstance(exclude, (list, tuple)), 'Invalid exclude %s' % exclude
    model = typeModel.container
    assert isinstance(model, Model)

    properties = set(model.properties)
    for cp in mapper.iterate_properties:
        if not isinstance(cp, ColumnProperty): continue

        assert isinstance(cp, ColumnProperty)
        if cp.key:
            prop = cp.key
            try: properties.remove(prop)
            except KeyError: continue

            if not (exclude and prop in exclude):
                propRef = getattr(mapped, prop)
                column = getattr(mapper.c, cp.key, None)
                assert isinstance(column, Column), 'Invalid column %s' % column
                if __debug__:
                    propType = typeFor(propRef)
                    assert isinstance(propType, TypeModelProperty), 'Invalid property %s with type %s' % (prop, propType)

                if column.primary_key and column.autoincrement:
                    if prop != model.propertyId:
                        raise MappingError('The primary key is expected to be %s, but got SQL primary key for %s' % 
                                           (model.propertyId, prop))
                    validateAutoId(propRef)
                elif not column.nullable:
                    validateRequired(propRef)

                if isinstance(column.type, String) and column.type.length:
                    validateMaxLength(propRef, column.type.length)
                if column.unique:
                    validateProperty(propRef, partial(onPropertyUnique, mapped))
                if column.foreign_keys:
                    for fk in column.foreign_keys:
                        assert isinstance(fk, ForeignKey)
                        try: fkcol = fk.column
                        except AttributeError:
                            raise MappingError('Invalid foreign column for %s, maybe you are not using the meta class'
                                               % prop)
                        validateProperty(propRef, partial(onPropertyForeignKey, mapped, fkcol), index=INDEX_PROP_FK)

    for prop in properties:
        if not (exclude and prop in exclude): validateManaged(getattr(mapped, prop))
Esempio n. 2
0
    def testValidation(self):
        Entity._ally_listeners = {}

        validateAutoId(Entity.Id)
        validateRequired(Entity.Required)
        validateMaxLength(Entity.WithLength, 5)
        validateManaged(Entity.Managed)

        dummyService = DummyServiceEntity()
        proxySrvNonValid = proxyWrapFor(dummyService)
        proxySrv = proxyWrapFor(dummyService)
        bindValidations(proxySrv)
        assert isinstance(proxySrv, IServiceEntity)

        e = Entity()
        self.assertRaisesRegex(InputError, "(Entity.Required='Expected a value')", proxySrv.insert, e)
        self.assertEqual(proxySrvNonValid.insert(e), 'inserted')
        self.assertRaisesRegex(InputError, "(Entity.Id='Expected a value')", proxySrv.update, e)
        self.assertEqual(proxySrvNonValid.update(e), 'updated')

        e.Id = 'custom id'
        self.assertRaisesRegex(InputError, "(Entity.Id='No value expected')", proxySrv.insert, e)
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'Provided a value'
        self.assertTrue(proxySrv.insert(e) == 'inserted')
        e.Id = 'id'
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'required'
        e.WithLength = 'This is a longer text then 5'
        self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.insert, e)
        e.WithLength = 'hello'
        self.assertTrue(proxySrv.insert(e) == 'inserted')
        e.WithLength = 'This is a longer text then 5'
        e.Id = 'id'
        self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.update, e)
        e.WithLength = 'hello'
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'required'
        e.Managed = 'should not have value'
        self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.insert, e)
        e.Id = 'id'
        self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.update, e)

        self.assertRaises(AttributeError, getattr, proxySrv, '_hidden')
Esempio n. 3
0
    def testValidation(self):
        Entity._ally_listeners = {}

        validateAutoId(Entity.Id)
        validateRequired(Entity.Required)
        validateMaxLength(Entity.WithLength, 5)
        validateManaged(Entity.Managed)

        dummyService = DummyServiceEntity()
        proxySrvNonValid = proxyWrapFor(dummyService)
        proxySrv = proxyWrapFor(dummyService)
        bindValidations(proxySrv)
        assert isinstance(proxySrv, IServiceEntity)

        e = Entity()
        self.assertRaisesRegex(InputError, "(Entity.Required='Expected a value')", proxySrv.insert, e)
        self.assertEqual(proxySrvNonValid.insert(e), 'inserted')
        self.assertRaisesRegex(InputError, "(Entity.Id='Expected a value')", proxySrv.update, e)
        self.assertEqual(proxySrvNonValid.update(e), 'updated')

        e.Id = 'custom id'
        self.assertRaisesRegex(InputError, "(Entity.Id='No value expected')", proxySrv.insert, e)
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'Provided a value'
        self.assertTrue(proxySrv.insert(e) == 'inserted')
        e.Id = 'id'
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'required'
        e.WithLength = 'This is a longer text then 5'
        self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.insert, e)
        e.WithLength = 'hello'
        self.assertTrue(proxySrv.insert(e) == 'inserted')
        e.WithLength = 'This is a longer text then 5'
        e.Id = 'id'
        self.assertRaisesRegex(InputError, "(Entity.WithLength='Maximum length allowed is 5)", proxySrv.update, e)
        e.WithLength = 'hello'
        self.assertTrue(proxySrv.update(e) == 'updated')

        e = Entity()
        e.Required = 'required'
        e.Managed = 'should not have value'
        self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.insert, e)
        e.Id = 'id'
        self.assertRaisesRegex(InputError, "(Entity.Managed='No value expected')", proxySrv.update, e)

        self.assertRaises(AttributeError, getattr, proxySrv, '_hidden')
Esempio n. 4
0
        return self.author.Name

    # Non REST model attributes --------------------------------------
    typeId = Column('fk_type_id', ForeignKey(PostTypeMapped.id, ondelete='RESTRICT'), nullable=False)
    type = relationship(PostTypeMapped, uselist=False, lazy='joined')
    author = relationship(CollaboratorMapped, uselist=False, lazy='joined')
    creator = relationship(UserMapped, uselist=False, lazy='joined')

    # Expression for hybrid ------------------------------------
    @classmethod
    @IsModified.expression
    def _IsModified(cls):
        return case([(cls.UpdatedOn != None, True)], else_=False)
    @classmethod
    @IsPublished.expression
    def _IsPublished(cls):
        return case([(cls.PublishedOn != None, True)], else_=False)
    @classmethod
    @AuthorName.expression
    def _AuthorName(cls):
        return case([(cls.Author == None, UserMapped.Name)], else_=CollaboratorMapped.Name)

validateRequired(PostMapped.Type)
validateManaged(PostMapped.Type, key=EVENT_PROP_UPDATE)
validateManaged(PostMapped.Author, key=EVENT_PROP_UPDATE)

validateManaged(PostMapped.CreatedOn)
validateManaged(PostMapped.PublishedOn)
validateManaged(PostMapped.UpdatedOn)
validateManaged(PostMapped.DeletedOn)
Esempio n. 5
0
'''

from ..api.user import User
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.types import String, DateTime
from superdesk.person.meta.person import PersonMapped
from ally.support.sqlalchemy.mapper import validate
from ally.container.binder_op import validateManaged, validateRequired

# --------------------------------------------------------------------

@validate(exclude=('Password', 'CreatedOn', 'DeletedOn'))
class UserMapped(PersonMapped, User):
    '''
    Provides the mapping for User entity.
    '''
    __tablename__ = 'user'
    __table_args__ = dict(mysql_engine='InnoDB', mysql_charset='utf8')

    Name = Column('name', String(20), nullable=False)
    CreatedOn = Column('created_on', DateTime, nullable=False)
    DeletedOn = Column('deleted_on', DateTime)
    # Non REST model attribute --------------------------------------
    userId = Column('fk_person_id', ForeignKey(PersonMapped.Id, ondelete='CASCADE'), primary_key=True)
    password = Column('password', String(255), nullable=False)
    # Never map over the inherited id

validateRequired(UserMapped.Password)
validateManaged(UserMapped.CreatedOn)
validateManaged(UserMapped.DeletedOn)
Esempio n. 6
0
from superdesk.person.meta.person import PersonMapped
from sqlalchemy.dialects.mysql.base import INTEGER

# --------------------------------------------------------------------

@validate(exclude=('Password', 'CreatedOn', 'Active', 'Type'))
class UserMapped(PersonMapped, User):
    '''
    Provides the mapping for User entity.
    '''
    __tablename__ = 'user'
    __table_args__ = (UniqueConstraint('name', name='uix_user_name'),
                      dict(mysql_engine='InnoDB', mysql_charset='utf8'))

    Name = Column('name', String(150), nullable=False, unique=True)
    Uuid = Column('uuid', String(32), unique=True, nullable=True)
    Cid = Column('cid', INTEGER(unsigned=True), nullable=True, default=0)
    CreatedOn = Column('created_on', DateTime, nullable=False)
    Active = Column('active', Boolean, nullable=False, default=True)
    Type = association_proxy('type', 'Key')
    # Non REST model attribute --------------------------------------
    userId = Column('fk_person_id', ForeignKey(PersonMapped.Id, ondelete='CASCADE'), primary_key=True)
    password = Column('password', String(255), nullable=False)
    # Never map over the inherited id
    typeId = Column('fk_type_id', ForeignKey(UserTypeMapped.id, ondelete='RESTRICT'), nullable=False)
    type = relationship(UserTypeMapped, uselist=False, lazy='joined')

validateRequired(UserMapped.Password)
validateManaged(UserMapped.CreatedOn)
validateManaged(UserMapped.Active)
Esempio n. 7
0
    # Non REST model attributes --------------------------------------
    typeId = Column('fk_type_id',
                    ForeignKey(PostTypeMapped.id, ondelete='RESTRICT'),
                    nullable=False)
    type = relationship(PostTypeMapped, uselist=False, lazy='joined')
    author = relationship(CollaboratorMapped, uselist=False, lazy='joined')
    creator = relationship(UserMapped, uselist=False, lazy='joined')

    # Expression for hybrid ------------------------------------
    @classmethod
    @IsModified.expression
    def _IsModified(cls):
        return case([(cls.UpdatedOn != None, True)], else_=False)

    @classmethod
    @AuthorName.expression
    def _AuthorName(cls):
        return case([(cls.Author == None, UserMapped.Name)],
                    else_=CollaboratorMapped.Name)


validateRequired(PostMapped.Type)
validateManaged(PostMapped.Type, key=EVENT_PROP_UPDATE)
validateManaged(PostMapped.Author, key=EVENT_PROP_UPDATE)

validateManaged(PostMapped.CreatedOn)
validateManaged(PostMapped.PublishedOn)
validateManaged(PostMapped.UpdatedOn)
validateManaged(PostMapped.DeletedOn)
Esempio n. 8
0
def registerValidation(mapped, exclude=None):
    '''
    Register to mapped class all the validations that can be performed based on the SQL alchemy mapping.
    
    @param mapped: class
        The mapped model class.
    @param exclude: list[string]|tuple(string)
        A list of column names to be excluded from automatic validation.
    @return: Property
        The property id of the model.
    '''
    assert isclass(mapped), 'Invalid class %s' % mapped
    mapper, typeModel = mappingFor(mapped), typeFor(mapped)
    assert isinstance(mapper, Mapper), 'Invalid mapped class %s' % mapped
    assert isinstance(typeModel, TypeModel), 'Invalid model class %s' % mapped
    assert not exclude or isinstance(
        exclude, (list, tuple)), 'Invalid exclude %s' % exclude
    model = typeModel.container
    assert isinstance(model, Model)

    properties = set(model.properties)
    for cp in mapper.iterate_properties:
        if not isinstance(cp, ColumnProperty): continue

        assert isinstance(cp, ColumnProperty)
        if cp.key:
            prop = cp.key
            try:
                properties.remove(prop)
            except KeyError:
                continue

            if not (exclude and prop in exclude):
                propRef = getattr(mapped, prop)
                column = getattr(mapper.c, cp.key, None)
                assert isinstance(column, Column), 'Invalid column %s' % column
                if __debug__:
                    propType = typeFor(propRef)
                    assert isinstance(
                        propType, TypeModelProperty
                    ), 'Invalid property %s with type %s' % (prop, propType)

                if column.primary_key and column.autoincrement:
                    if prop != model.propertyId:
                        raise MappingError(
                            'The primary key is expected to be %s, but got SQL primary key for %s'
                            % (model.propertyId, prop))
                    validateAutoId(propRef)
                elif not column.nullable:
                    validateRequired(propRef)

                if isinstance(column.type, String) and column.type.length:
                    validateMaxLength(propRef, column.type.length)
                if column.unique:
                    validateProperty(propRef, partial(onPropertyUnique,
                                                      mapped))
                if column.foreign_keys:
                    for fk in column.foreign_keys:
                        assert isinstance(fk, ForeignKey)
                        try:
                            fkcol = fk.column
                        except AttributeError:
                            raise MappingError(
                                'Invalid foreign column for %s, maybe you are not using the meta class'
                                % prop)
                        validateProperty(propRef,
                                         partial(onPropertyForeignKey, mapped,
                                                 fkcol),
                                         index=INDEX_PROP_FK)

    for prop in properties:
        if not (exclude and prop in exclude):
            validateManaged(getattr(mapped, prop))