class Traffic(ResourceModel, models.Model): title = models.CharField(max_length=64) introduction = models.TextField(null=True, default='', blank=True) Type = Enum( BACKGROUND=1, INTELLIGENT=2, ) type = models.PositiveIntegerField(default=Type.BACKGROUND) public = models.BooleanField(default=True) is_copy = models.BooleanField(default=False) hash = models.CharField(max_length=100, null=True, default=tool_hash) category = models.ForeignKey(TrafficCategory, on_delete=models.SET_NULL, null=True) create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='traffic_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='traffic_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) Status = Enum( DELETE=0, NORMAL=1 ) status = models.PositiveIntegerField(default=Status.NORMAL) parent = models.PositiveIntegerField(null=True) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.title
class CrEvent(Owner): name = models.CharField(max_length=225) logo = models.ImageField(upload_to='event_logo', default='event_logo/default_event_logo/img1.png') description = models.TextField(default='') hash = models.CharField(max_length=100, null=True, default=tool_hash) cr_scenes = models.ManyToManyField(CrScene, through='CrEventScene') # 实例进程 Process = Enum( INPROGRESS=0, COMING=1, OVER=2, ) start_time = models.DateTimeField() end_time = models.DateTimeField() # 实例状态 Status = Enum( DELETE=0, NORMAL=1, PAUSE=2, INPROGRESS=3, OVER=4, ) status = models.PositiveIntegerField(default=Status.NORMAL) # 实例正常 objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.name
class CrSceneEventTask(models.Model): cr_event = models.ForeignKey(CrEvent, on_delete=models.PROTECT) # 任务hash, 事件hash, hash后缀.mission, .tarffic hash = models.CharField(max_length=500) score = models.FloatField(default=0) # 类型, 考试, CTF, ManualCheck, SystemCheck, AgentCheck, 事件 Type = Enum(EXAM=0, CTF=1, MANUAL=2, SYSTEM=3, AGENT=4, TRAFFIC=5) type = models.PositiveIntegerField() # 任务/事件 状态 Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL)
class CrScene(ResourceModel, models.Model): name = models.CharField(max_length=225) scene_config = models.OneToOneField(SceneConfig, on_delete=models.PROTECT) scene = models.ForeignKey(Scene, on_delete=models.SET_NULL, null=True, default=None) roles = models.TextField(default='[]') missions = models.ManyToManyField(Mission) traffic_events = models.ManyToManyField(TrafficEvent) cr_scene_config = models.TextField(default='{}') create_time = models.DateTimeField(default=timezone.now) # 实例状态 Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def __unicode__(self): return '%s' % self.name
class EvaluationReportWebsocket(UserWebsocket): Event = Enum( LATEST_EVALUATION=1, ALL_EVALUATIONS=2, ) def receive(self, content, **kwargs): message = self.message if not message.user.is_authenticated: message.reply_channel.send({"close": True}) return if content: event_id = content self.all_evaluation_reports(message.user, event_id) @classmethod def _get_all_evaluation_reports(cls, cr_event): start_time = datetime.now() - timedelta(hours=1) evaluations = evaluation_models.EvaluationReport.objects.filter( report__cr_event_id=cr_event, report__create_time__gte=start_time) data = evaluation_serializer.EvaluationReportSerializer(evaluations, many=True).data return data @classmethod def all_evaluation_reports(cls, user, cr_event): data = cls._get_all_evaluation_reports(cr_event) cls.user_send(user, data, code=cls.Event.ALL_EVALUATIONS) @classmethod def latest_evaluation_report(cls, user, data): cls.user_send(user, data, code=cls.Event.LATEST_EVALUATION)
class StandardDeviceWebsocket(UserWebsocket): Event = Enum( SCENE_STATUS_UPDATE=1, IMAGE_STATUS_UPDATE=2, ) @classmethod def _get_device_data(cls, user, device): user = get_user(user) device = get_obj(device, StandardDevice) data = mserializers.StandardDeviceSerializer(device, context={ 'user': user }).data return data @classmethod def scene_status_update(cls, user, device): data = cls._get_device_data(user, device) cls.user_send(user, data, code=cls.Event.SCENE_STATUS_UPDATE) @classmethod def image_status_update(cls, user, device): data = cls._get_device_data(user, device) cls.user_send(user, data, code=cls.Event.IMAGE_STATUS_UPDATE)
class SceneConfig(ResourceModel, Owner): Type = Enum(BASE=1, ) type = models.PositiveIntegerField(default=Type.BASE) file = models.FileField(upload_to='scene', null=True, default=None) json_config = models.TextField(default='{}') # info from json name = models.CharField(max_length=100, default=None, null=True)
class User(ResourceModel, AbstractUser): logo = models.ImageField(upload_to='user_logo', default='') nickname = models.CharField(max_length=100, default='') name = models.CharField(max_length=100, default='') profile = models.TextField(default='') organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, null=True) last_login_ip = models.CharField(max_length=100, null=True, default=None) Group = Enum( ADMIN=1, STAFF=2, ) Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) extra = models.TextField(default='') objects = MUserManager({'status': Status.DELETE}) original_objects = models.Manager() @property def rep_name(self): return self.name or self.username @property def group(self): if self.is_superuser: return None group = self.groups.first() if not group: return None return group.pk @property def is_admin(self): if self.is_superuser: return True return self.group == User.Group.ADMIN
class SceneWebsocket(UserWebsocket): Event = Enum( SCENE_STATUS_UPDATE=1, SCENE_NET_STATUS_UPDATE=2, SCENE_GATEWAY_STATUS_UPDATE=3, SCENE_TERMINAL_STATUS_UPDATE=4, ) @classmethod def _get_scene_data(cls, user, scene, fields=None): user = get_user(user) scene = get_obj(scene, Scene) handler = SceneHandler(user, scene=scene) data = handler.scene_util.get_data(fields=fields) return data @classmethod def _get_scene_net_data(cls, user, scene_net, fields=None): user = get_user(user) scene_net = get_obj(scene_net, SceneNet) handler = SceneHandler(user) net_util = handler.get_net_util(scene_net) data = net_util.get_data(fields=fields) return data @classmethod def _get_scene_terminal_data(cls, user, scene_terminal, fields=None): user = get_user(user) scene_terminal = get_obj(scene_terminal, SceneTerminal) handler = SceneHandler(user) terminal_util = handler.get_terminal_util(scene_terminal) data = terminal_util.get_data(fields=fields) return data @classmethod def scene_status_update(cls, user, scene, fields=None): data = cls._get_scene_data(user, scene, fields=fields) cls.user_send(user, data, code=cls.Event.SCENE_STATUS_UPDATE) @classmethod def scene_net_status_update(cls, user, scene_net, fields=None): data = cls._get_scene_net_data(user, scene_net, fields=fields) cls.user_send(user, data, code=cls.Event.SCENE_NET_STATUS_UPDATE) @classmethod def scene_terminal_status_update(cls, user, scene_terminal, fields=None, data_handler=None): data = cls._get_scene_terminal_data(user, scene_terminal, fields=fields) if data_handler: data_handler(data) cls.user_send(user, data, code=cls.Event.SCENE_TERMINAL_STATUS_UPDATE)
class IntelligentTraffic(models.Model): traffic = models.OneToOneField(Traffic, primary_key=True, related_name='intelligent_traffic') Suffix = Enum( PY=0, SH=1 ) code = models.TextField(default=None) file_name = models.CharField(max_length=100, blank=True) suffix = models.PositiveIntegerField(default=Suffix.PY) tgm = models.ForeignKey(StandardDevice, related_name='traffic_tgm', on_delete=models.SET_NULL, null=True, default=None)
class MissionPeriod(models.Model): cr_scene = models.ForeignKey(CrScene, on_delete=models.CASCADE) period_name = models.CharField(max_length=100) period_index = models.PositiveIntegerField() Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
def __new__(cls, **errors): custom_errors = {} for attr_name, error_desc in errors.items(): error_code = cls.generate_error_code(attr_name) if isinstance(error_desc, six.string_types): detail = ErrorDetail(error_desc, error_code) else: error_desc.code = error_code detail = error_desc custom_errors[attr_name] = detail cls.error.update(**custom_errors) return Enum(**custom_errors)
class TrafficCategory(models.Model): Status = Enum( DELETE=0, NORMAL=1, ) cn_name = models.CharField(max_length=64) en_name = models.CharField(max_length=64) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class Installer(Owner): name = models.CharField(max_length=100) type = models.ForeignKey(InstallerType, on_delete=models.PROTECT) resources = models.ManyToManyField(InstallerResource) Status = Enum( DELETE=0, NORMAL=1, ) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class User(AbstractUser): logo = models.ImageField(upload_to='user_logo', default='') nickname = models.CharField(max_length=100, default='') Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) extra = models.TextField(default='') objects = MUserManager({'status': Status.DELETE}) original_objects = models.Manager()
class BackgroundTraffic(models.Model): traffic = models.OneToOneField(Traffic, primary_key=True, related_name='background_traffic') pcap_file = models.FileField(upload_to='traffic/pcap') file_name = models.CharField(max_length=100, default=None) trm = models.ForeignKey(StandardDevice, related_name='traffic_trm', on_delete=models.SET_NULL, null=True, default=None) Loop = Enum( LOOP=0, ONCE=1 ) loop = models.PositiveIntegerField(default=Loop.ONCE) mbps = models.PositiveIntegerField(null=True) multiplier = models.FloatField()
class Disk(Owner): name = models.CharField(max_length=100, unique=True) size = models.PositiveIntegerField() used_size = models.FloatField(default=0) Format = Enum( NTFS='NTFS', EXT4='EXT4', FAT32='FAT32', ) format = models.CharField(max_length=100, default=Format.NTFS) disk_id = models.CharField(max_length=50, default=None, null=True) mnt_dir = models.CharField(max_length=1024, default=None, null=True) Status = Enum( DELETE=0, AVAILABLE=1, USING=2, DETACHING=3, ERROR=4, ) status = models.IntegerField(default=Status.AVAILABLE) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() def sync(self): if self.status != Disk.Status.DELETE and self.disk_id: status_map = { 'available': Disk.Status.AVAILABLE, 'in-use': Disk.Status.USING, 'detaching': Disk.Status.DETACHING, 'error': Disk.Status.ERROR, } disk = cloud.volume.get(self.disk_id) self.name = disk.name self.size = disk.size self.modify_time = timezone.now() self.status = status_map.get(disk.status, Disk.Status.AVAILABLE) self.save()
class CrEventSceneWebsocket(UserWebsocket): Event = Enum(SCENE_START=1, ) @classmethod def _get_cr_event_data(cls, user, cr_event): cr_event = get_obj(cr_event, CrEvent) data = mserializers.CrEventSerializers(cr_event, fields=('id', )).data return data @classmethod def cr_event_start(cls, user, cr_event): data = cls._get_cr_event_data(user, cr_event) cls.user_send(user, data, code=cls.Event.SCENE_START)
class TrafficEvent(ResourceModel, models.Model): title = models.CharField(max_length=64) introduction = models.TextField(null=True, default='', blank=True) Type = Enum( BACKGROUND=1, INTELLIGENT=2, ) type = models.PositiveIntegerField(default=Type.BACKGROUND) StartUpMode = Enum( AUTO=1, DELAY=2 ) start_up_mode = models.PositiveIntegerField(default=StartUpMode.AUTO) delay_time = models.PositiveIntegerField(null=True) public = models.BooleanField(default=True) traffic = models.ForeignKey(Traffic, related_name='traffic_event') target = models.CharField(max_length=128, default=None, blank=True) runner = models.CharField(max_length=100, default=None) target_net = models.CharField(max_length=100, default=None) parameter = models.CharField(max_length=200, default='', blank=True) pid = models.CharField(max_length=128, default='') create_time = models.DateTimeField(auto_now_add=True) create_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='event_traffic_create_user', null=True, default=None) last_edit_user = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True, related_name='event_traffic_last_edit_user') last_edit_time = models.DateTimeField(auto_now=True) Status = Enum( DELETE=0, NORMAL=1, RUNNING=2, ERROR=3, ) status = models.PositiveIntegerField(default=Status.NORMAL) error = models.TextField(max_length=2048, default=None, null=True) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class OperationLog(models.Model): create_time = models.DateTimeField(default=timezone.now) create_user = models.ForeignKey(User, on_delete=models.PROTECT) module = models.PositiveIntegerField(default=0) # 操作类型 OType = Enum( CREATE=0, UPDATE=1, DELETE=2, ) operation_type = models.PositiveIntegerField(default=OType.CREATE) # 操作对象id operation_obj = models.PositiveIntegerField(default=0) # 操作对象str,一般为title,name属性 operation_str = models.CharField(default=None, null=True, max_length=512) # 详细内容 content = models.CharField(null=True, max_length=10240) SyslogLevel = Enum( INFO=0, WARN=1, SEVERE=2, ) level = models.PositiveIntegerField(default=SyslogLevel.INFO) LogStatus = Enum( SUCCESS=0, FAIL=1, PARTIAL_SUCCESS=2, OPERATING=3, ) log_status = models.PositiveIntegerField(default=Status.NORMAL)
class Network(Owner): name = models.CharField(max_length=100, unique=True) company = models.CharField(max_length=100, default=None, null=True) cidr = models.CharField(max_length=1024, default=None, null=True) gateway = models.CharField(max_length=1024, default=None, null=True) dns = models.CharField(max_length=1024, default=None, null=True) dhcp = models.BooleanField(default=True) net_id = models.CharField(max_length=50, default=None, null=True) subnet_id = models.CharField(max_length=50, default=None, null=True) Status = Enum( DELETE=0, NORMAL=1, ) status = models.IntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager()
class GuacamoleSystemPermission(models.Model): user = models.ForeignKey(GuacamoleUser, on_delete=models.CASCADE) Permission = Enum( CREATE_CONNECTION='CREATE_CONNECTION', CREATE_CONNECTION_GROUP='CREATE_CONNECTION_GROUP', CREATE_SHARING_PROFILE='CREATE_SHARING_PROFILE', CREATE_USER='******', ADMINISTER='ADMINISTER', ) permission = models.CharField(max_length=32) objects = GuacamoleManager() class Meta: unique_together = (('user', 'permission'), ) db_table = 'guacamole_system_permission' managed = False
class GuacamoleSharingProfilePermission(models.Model): user = models.ForeignKey(GuacamoleUser, on_delete=models.CASCADE) sharing_profile = models.ForeignKey(GuacamoleSharingProfile, on_delete=models.CASCADE) Permission = Enum( READ='READ', UPDATE='UPDATE', DELETE='DELETE', ADMINISTER='ADMINISTER', ) permission = models.CharField(max_length=32) objects = GuacamoleManager() class Meta: unique_together = (('user', 'sharing_profile', 'permission'), ) db_table = 'guacamole_sharing_profile_permission' managed = False
class CrEventUserStandardDevice(Owner): cr_event_scene = models.ForeignKey(CrEventScene, on_delete=models.PROTECT) standard_device = models.CharField(max_length=100, null=True) # 某次启动的scene_id scene_id = models.PositiveIntegerField() Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() class Meta: unique_together = ('scene_id', 'standard_device')
class GuacamoleConnectionGroupPermission(models.Model): user = models.ForeignKey(GuacamoleUser, on_delete=models.CASCADE) connection_group = models.ForeignKey(GuacamoleConnectionGroup, on_delete=models.CASCADE) Permission = Enum( READ='READ', UPDATE='UPDATE', DELETE='DELETE', ADMINISTER='ADMINISTER', ) permission = models.CharField(max_length=32) objects = GuacamoleManager() class Meta: unique_together = (('user', 'connection_group', 'permission'), ) db_table = 'guacamole_connection_group_permission' managed = False
class GuacamoleConnectionGroup(models.Model): connection_group_id = models.IntegerField(primary_key=True) connection_group_name = models.CharField(max_length=128) parent = models.ForeignKey('self', null=True, related_name='+') Type = Enum( ORGANIZATIONAL='ORGANIZATIONAL', BALANCING='BALANCING', ) type = models.CharField(max_length=32, default=Type.ORGANIZATIONAL) max_connections = models.IntegerField(null=True) max_connections_per_user = models.IntegerField(null=True) enable_session_affinity = models.BooleanField(default=False) objects = GuacamoleManager() class Meta: unique_together = (('connection_group_name', 'parent'), ) db_table = 'guacamole_connection_group' managed = False
class BaseNotice(models.Model): notice = models.CharField(max_length=1024) is_topped = models.BooleanField(default=False) create_time = models.DateTimeField(default=timezone.now) last_edit_time = models.DateTimeField(default=timezone.now) # 通知状态 Status = Enum( DELETE=0, NORMAL=1, ) status = models.PositiveIntegerField(default=Status.NORMAL) objects = MManager({'status': Status.DELETE}) original_objects = models.Manager() class Meta: abstract = True
class Scene(models.Model): user = models.ForeignKey(User, on_delete=models.SET_NULL, default=None, null=True) Type = SceneConfig.Type type = models.PositiveIntegerField(default=Type.BASE) file = models.FileField(upload_to='scene', null=True, default=None) json_config = models.TextField(default='{}') # 被外部引用的关系 hang_info = models.TextField(default='{}') # 资源名称前缀 name_prefix = models.CharField(max_length=100, default='') Status = Enum( DELETED=0, CREATING=1, RUNNING=2, PAUSE=3, ERROR=4, ) status = models.IntegerField(default=Status.CREATING) status_updated = models.ForeignKey(Executor, on_delete=models.SET_NULL, default=None, null=True, related_name='+') # 记录环境创建流程日志 log = models.TextField(default='[]') # 记录环境出错信息 error = models.CharField(max_length=2048, default=None, null=True) # 环境创建时间 create_time = models.DateTimeField(default=timezone.now) # 环境创建完成时间 created_time = models.DateTimeField(default=None, null=True) # 环境创建消耗时间 consume_time = models.PositiveIntegerField(default=0) # 环境暂停时间 pause_time = models.DateTimeField(default=None, null=True) @property def name(self): return json.loads(self.json_config).get('scene', {}).get('name')
class Owner(models.Model): user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='+') PublicMode = Enum( PRIVATE=0, INNER=1, OUTER=2, ) public_mode = models.PositiveIntegerField(default=PublicMode.PRIVATE) public_operate = models.BooleanField(default=False) create_time = models.DateTimeField(default=timezone.now) modify_user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='+') modify_time = models.DateTimeField(default=timezone.now) class Meta: abstract = True
class GuacamoleUserPermission(models.Model): user = models.ForeignKey(GuacamoleUser, on_delete=models.CASCADE, related_name="+") affected_user = models.ForeignKey(GuacamoleUser, on_delete=models.CASCADE, related_name="+") Permission = Enum( READ='READ', UPDATE='UPDATE', DELETE='DELETE', ADMINISTER='ADMINISTER', ) permission = models.CharField(max_length=32) objects = GuacamoleManager() class Meta: unique_together = (('user', 'affected_user', 'permission'), ) db_table = 'guacamole_user_permission' managed = False