class ScopeDataSchema(BaseSchema): devices = EmqList(required=True, list_type=str) scope = EmqString(required=True, len_max=1000) scopeType = EmqInteger() @validates('devices') def validate_devices(self, value): devices_count = Device.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Device.deviceID.in_(set(value))) \ .count() if devices_count != len(value): raise DataNotFound(field='devices') @post_dump def query_devices(self, data): devices_uid = data.get('devices') devices_result = Device.query \ .filter(Device.deviceID.in_(set(devices_uid))) \ .with_entities(Device.id, Device.deviceID, Device.deviceName) \ .many() devices = [] for device in devices_result: device_record = { key: getattr(device, key) for key in device.keys() } devices.append(device_record) data['devices'] = devices return data
class ApplicationSchema(BaseSchema): """ application management """ appID = EmqString(dump_only=True) appName = EmqString(required=True) appToken = EmqString(dump_only=True) expiredAt = EmqDateTime(allow_none=True) # expired time description = EmqString(allow_none=True, len_max=300) appStatus = EmqInteger(required=True, validate=OneOf([0, 1])) userIntID = EmqInteger(allow_none=True) roleIntID = EmqInteger(required=True) # app role id groups = EmqList(allow_none=True, list_type=str, load_only=True) # product uid @validates('appName') def validate_app_name(self, value): if self._validate_obj('appName', value): return app = Application.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Application.appName == value).first() if app: raise DataExisted(field='appName') @post_load def handle_app_groups(self, in_data): groups_uid = in_data.get('groups') if not groups_uid: return in_data groups = Group.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Group.groupID.in_(set(groups_uid))).all() if len(groups_uid) != len(groups): raise DataNotFound(field='groups') in_data['groups'] = groups return in_data
class UpdateUserSchema(BaseSchema): roleIntID = EmqInteger(required=True) enable = EmqInteger(required=True) expiresAt = EmqDateTime(allow_none=True) phone = EmqString(allow_none=True, len_max=15) userAuthType = EmqInteger(allow_none=True) groups = EmqList(allow_none=True, list_type=str, load_only=True) @post_load def handle_user_auth_type(self, data): if 'user_id' not in g: data['userAuthType'] = 1 groups_uid = self.get_request_data(key='groups') auth_type = data.get('userAuthType') if auth_type not in (1, 2): raise FormInvalid(field='userAuthType') if auth_type == 2 and groups_uid: groups = Group.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Group.groupID.in_(set(groups_uid))).all() if len(groups_uid) != len(groups): raise DataNotFound(field='groups') data['groups'] = groups else: data.pop('groups', None) return data
class EmailActionSchema(BaseSchema): title = EmqString(required=True) content = EmqString(required=True) emails = EmqList(required=True) @validates('emails') def validate_email(self, value): for email in value: validate.Email()(email)
class DataPointSchema(BaseSchema): dataPointName = EmqString(required=True) dataPointID = EmqString(required=True) dataTransType = EmqInteger( required=True) # message 1: Up, 2: Down, 3 UpAndDown pointDataType = EmqInteger( required=True) # 1:num, 2:str, 3:Boolean, 4:datetime, 5:location extendTypeAttr = EmqDict( allow_none=True) # extension attribute for point data type isLocationType = EmqInteger(allow_none=True) # 1:yes, 2:no locationType = EmqInteger( allow_none=True) # 1: longitude, 2: latitude, 3: altitude description = EmqString(allow_none=True, len_max=300) enum = EmqList(allow_none=True) # enum of string or integer productID = EmqString(required=True) # product uid cloudProtocol = EmqInteger(load_only=True) # product cloudProtocol @validates('dataPointName') def name_is_exist(self, value): if self._validate_obj('dataPointName', value): return product_uid = self.get_request_data('productID') point_name = db.session.query(DataPoint.dataPointName) \ .filter(DataPoint.productID == product_uid, DataPoint.dataPointName == value).first() if point_name: raise DataExisted(field='dataPointName') @validates('dataPointID') def validate_point_uid(self, value): if not value or self._validate_obj('dataPointID', value): return if not re.match(r"^[0-9A-Za-z_\-]*$", value): raise FormInvalid(field='dataPointID') product_uid = self.get_request_data('productID') data_point_uid = db.session.query(DataPoint.dataPointID) \ .filter(DataPoint.productID == product_uid, DataPoint.dataPointID == value).first() if data_point_uid: raise DataExisted(field='dataPointID') @pre_load def handle_load_data(self, data): product_uid: str = data.get('productID') if not isinstance(product_uid, str): raise FormInvalid(field='productID') product = Product.query. \ filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Product.productID == product_uid).first() if not product: raise DataNotFound(field='productID') data['productID'] = product.productID data['cloudProtocol'] = product.cloudProtocol data = handle_extend_type_attr(data) return data
class BaseDeviceSchema: deviceName = EmqString(required=True) deviceType = EmqInteger(required=True, validate=OneOf([1, 2])) # 1:endDevice. 2:gateway productID = EmqString(required=True, len_max=6) authType = EmqInteger(required=True, validate=OneOf([1, 2])) # 1:token 2:cert carrier = EmqInteger() upLinkNetwork = EmqInteger(allow_none=True, validate=OneOf(range(1, 8))) deviceID = EmqString(allow_none=True, len_min=8, len_max=36) deviceUsername = EmqString(allow_none=True, len_min=8, len_max=36) token = EmqString(allow_none=True, len_min=8, len_max=36) location = EmqString(allow_none=True) latitude = EmqFloat(allow_none=True) longitude = EmqFloat(allow_none=True) blocked = EmqInteger(allow_none=True) manufacturer = EmqString(allow_none=True) serialNumber = EmqString(allow_none=True) softVersion = EmqString(allow_none=True) hardwareVersion = EmqString(allow_none=True) deviceConsoleIP = EmqString(allow_none=True) deviceConsoleUsername = EmqString(allow_none=True) deviceConsolePort = EmqInteger(allow_none=True) mac = EmqString(allow_none=True) metaData = EmqJson(allow_none=True) description = EmqString(allow_none=True, len_max=300) deviceStatus = EmqInteger(dump_only=True) lastConnection = EmqDateTime(dump_only=True) groups = EmqList(allow_none=True, list_type=str, load_only=True) certs = EmqList(allow_none=True, list_type=int, load_only=True) productType = EmqInteger( load_only=True) # 1:endDevice product 2:gateway product scopes = fields.Nested(DeviceScopeSchema, only='scope', many=True, dump_only=True) def __init__(self, *args, **kwargs): pass
class UserSchema(BaseSchema): username = EmqString(required=True) email = EmqEmail(required=True) password = EmqString(required=True, len_min=6, len_max=100, load_only=True) enable = EmqInteger(allow_none=True) nickname = EmqString(allow_none=True) phone = EmqString(allow_none=True, len_max=15) department = EmqString(allow_none=True) lastRequestTime = EmqDateTime(allow_none=True) loginTime = EmqDateTime(allow_none=True) expiresAt = EmqDateTime(allow_none=True) roleIntID = EmqInteger(allow_none=True) userAuthType = EmqInteger(allow_none=True, validate=OneOf([1, 2])) groups = EmqList(allow_none=True, list_type=str, load_only=True) tenantID = EmqString(dump_only=True) @validates('username') def validate_username(self, value): if value in current_app.config.get('RESERVED'): raise FormInvalid(field='username') @validates('email') def email_is_exist(self, value): try: split_email = value.split('@')[0] if split_email in current_app.config.get('RESERVED'): raise FormInvalid(field='email') except Exception: raise FormInvalid(field='email') email = User.query.filter(User.email == value).first() if email: raise DataExisted(field='email') @post_load def handle_user_auth_type(self, data): if 'user_id' not in g: data['userAuthType'] = 1 groups_uid = self.get_request_data(key='groups') auth_type = data.get('userAuthType') if auth_type not in (1, 2): raise FormInvalid(field='userAuthType') if auth_type == 2 and groups_uid: groups = Group.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Group.groupID.in_(set(groups_uid))).all() if len(groups_uid) != len(groups): raise DataNotFound(field='groups') data['groups'] = groups else: data.pop('groups', None) return data
class StreamPointsSchema(BaseSchema): dataPoints = EmqList(required=True, list_type=int) @post_load def convert_data_points(self, data): data_point_ids = data.get('dataPoints') if data_point_ids: data_points = DataPoint.query \ .filter_tenant(tenant_uid=g.tenant_uid) \ .filter(DataPoint.id.in_(set(data_point_ids))).all() if len(data_points) != len(data_point_ids): raise DataNotFound(field='dataPoints') else: data_points = [] data['dataPoints'] = data_points return data
class UpdateDataStreamSchema(DataStreamSchema): productID = EmqString(dump_only=True) topic = EmqString(dump_only=True, len_max=500) dataPoints = EmqList(allow_none=True, load_only=True, list_type=int) @post_load def handle_data_points(self, data): product_uid = self.get_origin_obj('productID') data_point_ids = data.get('dataPoints') if not data_point_ids: return data data_points = DataPoint.query \ .filter(DataPoint.productID == product_uid, DataPoint.id.in_(set(data_point_ids))).all() if len(data_points) != len(data_point_ids): raise DataNotFound(field='dataPoints') data['data_points'] = data_points return data
class CertDeviceSchema(BaseSchema): devices = EmqList(required=True, list_type=int) @post_load def handle_cert_devices(self, data): devices_id = data['devices'] devices = Device.query \ .filter(Device.id.in_(set(devices_id)), Device.authType == 2) \ .many(allow_none=False, expect_result=len(devices_id)) cert_id = self.get_origin_obj('id') exist_cert_devices = db.session \ .query(func.count(CertDevice.c.deviceIntID)) \ .filter(CertDevice.c.certIntID == cert_id, CertDevice.c.deviceIntID.in_(set(devices_id))) \ .scalar() if exist_cert_devices: raise DataExisted(field='devices') data['devices'] = devices return data
class GroupDeviceSchema(BaseSchema): devices = EmqList(required=True, list_type=int) @post_load def handle_loads(self, data): group_id = request.view_args.get('group_id') devices_id = data['devices'] group_devices_id = db.session.query(GroupDevice.c.deviceIntID) \ .join(Group, Group.groupID == GroupDevice.c.groupID) \ .filter(Group.id == group_id).all() add_devices_id = set(devices_id).difference(set(group_devices_id)) if len(group_devices_id) + len(add_devices_id) > 1001: raise ResourceLimited(field='devices') devices = Device.query.filter_tenant(tenant_uid=g.tenant_uid) \ .filter(Device.id.in_(add_devices_id)).all() if len(devices) != len(add_devices_id): raise DataNotFound(field='devices') data['devices'] = devices return data
class RoleSchema(BaseSchema): roleName = EmqString(required=True) description = EmqString(allow_none=True, len_max=300) permissions = EmqList(required=True, list_type=int) isShare = EmqInteger(dump_only=True) tenantID = EmqString(dump_only=True) @validates('permissions') def is_empty_list(self, value): if not value: raise FormInvalid('permissions') @validates('roleName') def role_name_is_exist(self, value): if self._validate_obj('roleName', value): return role = Role.query \ .join(Tenant, Role.tenantID == Tenant.tenantID) \ .filter(Role.roleName == value) \ .filter(Tenant.tenantID == g.tenant_uid).all() if role: raise DataExisted(field='roleName')
class DeviceScopeSchema: scope = EmqList(required=True)