From 5cfd70847668a12605f56ef3482b7e1107f2470a Mon Sep 17 00:00:00 2001 From: invisig0th Date: Tue, 2 Jul 2024 17:04:22 -0400 Subject: [PATCH 1/7] Add $lib.cron.get().kill() (#3787) --- synapse/cortex.py | 28 ++++++++++++++++++++++++++++ synapse/lib/agenda.py | 6 ++++++ synapse/lib/stormtypes.py | 23 +++++++++++++++++------ synapse/tests/test_lib_agenda.py | 4 +++- synapse/tests/test_lib_stormtypes.py | 5 +++++ 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/synapse/cortex.py b/synapse/cortex.py index a0d1ddc140..3f677f852e 100644 --- a/synapse/cortex.py +++ b/synapse/cortex.py @@ -1400,6 +1400,13 @@ def _initCorePerms(self): 'desc': 'Controls the ability to check if the Axon contains a file.'}, {'perm': ('axon', 'del'), 'gate': 'cortex', 'desc': 'Controls the ability to remove a file from the Axon.'}, + + {'perm': ('cron', 'kill'), 'gate': 'cronjob', + 'desc': 'Controls the ability to terminate a running cron job.'}, + {'perm': ('cron', 'set'), 'gate': 'cronjob', + 'desc': 'Controls the ability to set any editable property on a cron job.'}, + {'perm': ('cron', 'set', ''), 'gate': 'cronjob', + 'desc': 'Controls the ability to set the named editable property on a cron job.'}, )) for pdef in self._cortex_permdefs: s_storm.reqValidPermDef(pdef) @@ -6112,6 +6119,7 @@ async def delCronJob(self, iden): Args: iden (bytes): The iden of the cron job to be deleted ''' + await self._killCronTask(iden) try: await self.agenda.delete(iden) except s_exc.NoSuchIden: @@ -6151,8 +6159,28 @@ async def disableCronJob(self, iden): iden (bytes): The iden of the cron job to be changed ''' await self.agenda.disable(iden) + await self._killCronTask(iden) await self.feedBeholder('cron:disable', {'iden': iden}, gates=[iden]) + async def killCronTask(self, iden): + if self.agenda.appts.get(iden) is None: + return False + return await self._push('cron:task:kill', iden) + + @s_nexus.Pusher.onPush('cron:task:kill') + async def _killCronTask(self, iden): + + appt = self.agenda.appts.get(iden) + if appt is None: + return False + + task = appt.task + if task is None: + return False + + await task.kill() + return True + async def listCronJobs(self): ''' Get information about all the cron jobs accessible to the current user diff --git a/synapse/lib/agenda.py b/synapse/lib/agenda.py index 7b4dfd4e2d..e7a2f0a4c0 100644 --- a/synapse/lib/agenda.py +++ b/synapse/lib/agenda.py @@ -274,6 +274,7 @@ class _Appt: def __init__(self, stor, iden, recur, indx, query, creator, recs, nexttime=None, view=None, created=None, pool=False): self.doc = '' self.name = '' + self.task = None self.stor = stor self.pool = pool self.iden = iden @@ -801,7 +802,12 @@ async def _execute(self, appt): coro = self._runJob(user, appt) task = self.core.runActiveTask(coro) + appt.task = await self.core.boss.promotetask(task, f'Cron {appt.iden}', user, info=info) + async def fini(): + appt.task = None + + appt.task.onfini(fini) async def _markfailed(self, appt, reason): now = self._getNowTick() diff --git a/synapse/lib/stormtypes.py b/synapse/lib/stormtypes.py index f9e1876c77..c675693718 100644 --- a/synapse/lib/stormtypes.py +++ b/synapse/lib/stormtypes.py @@ -8449,9 +8449,9 @@ async def set(self, name, valu): valu = await tostr(valu) if name == 'user': - self.runt.user.confirm(('trigger', 'set', 'user')) + self.runt.confirm(('trigger', 'set', 'user')) else: - self.runt.user.confirm(('trigger', 'set', name), gateiden=viewiden) + self.runt.confirm(('trigger', 'set', name), gateiden=viewiden) await self.runt.snap.view.setTriggerInfo(trigiden, name, valu) @@ -9276,14 +9276,19 @@ class CronJob(Prim): {'name': 'valu', 'type': 'any', 'desc': 'The value to set on the definition.', }, ), 'returns': {'type': 'cronjob', 'desc': 'The ``cronjob``', }}}, + + {'name': 'kill', 'desc': 'If the job is currently running, terminate the task.', + 'type': {'type': 'function', '_funcname': '_methCronJobKill', + 'returns': {'type': 'boolean', 'desc': 'A boolean value which is true if the task was terminated.'}}}, + {'name': 'pack', 'desc': 'Get the Cronjob definition.', 'type': {'type': 'function', '_funcname': '_methCronJobPack', - 'returns': {'type': 'dict', 'desc': 'The definition.', }}}, + 'returns': {'type': 'dict', 'desc': 'The definition.'}}}, {'name': 'pprint', 'desc': 'Get a dictionary containing user friendly strings for printing the CronJob.', 'type': {'type': 'function', '_funcname': '_methCronJobPprint', 'returns': {'type': 'dict', - 'desc': 'A dictionary containing structured data about a cronjob for display purposes.', }}}, + 'desc': 'A dictionary containing structured data about a cronjob for display purposes.'}}}, ) _storm_typename = 'cronjob' _ismutable = False @@ -9300,10 +9305,16 @@ def __hash__(self): def getObjLocals(self): return { 'set': self._methCronJobSet, + 'kill': self._methCronJobKill, 'pack': self._methCronJobPack, 'pprint': self._methCronJobPprint, } + async def _methCronJobKill(self): + iden = self.valu.get('iden') + self.runt.confirm(('cron', 'kill'), gateiden=iden) + return await self.runt.snap.core.killCronTask(iden) + async def _methCronJobSet(self, name, valu): name = await tostr(name) valu = await toprim(valu) @@ -9312,9 +9323,9 @@ async def _methCronJobSet(self, name, valu): if name == 'creator': # this permission must be granted cortex wide # to prevent abuse... - self.runt.user.confirm(('cron', 'set', 'creator')) + self.runt.confirm(('cron', 'set', 'creator')) else: - self.runt.user.confirm(('cron', 'set', name), gateiden=iden) + self.runt.confirm(('cron', 'set', name), gateiden=iden) self.valu = await self.runt.snap.core.editCronJob(iden, name, valu) diff --git a/synapse/tests/test_lib_agenda.py b/synapse/tests/test_lib_agenda.py index 9b085aa7d8..cf0f1a1ed6 100644 --- a/synapse/tests/test_lib_agenda.py +++ b/synapse/tests/test_lib_agenda.py @@ -331,7 +331,9 @@ def looptime(): appt = await agenda.get(guid) self.eq(appt.isrunning, True) self.eq(core.view.iden, appt.task.info.get('view')) - await appt.task.kill() + + self.true(await core._killCronTask(guid)) + self.false(await core._killCronTask(guid)) appt = await agenda.get(guid) self.eq(appt.isrunning, False) diff --git a/synapse/tests/test_lib_stormtypes.py b/synapse/tests/test_lib_stormtypes.py index 77af2ebdda..4308fdf6ae 100644 --- a/synapse/tests/test_lib_stormtypes.py +++ b/synapse/tests/test_lib_stormtypes.py @@ -4642,6 +4642,11 @@ async def test_storm_lib_cron_notime(self): opts = {'vars': {'iden': iden0}} + # for coverage... + self.false(await core.killCronTask('newp')) + self.false(await core._killCronTask('newp')) + self.false(await core.callStorm(f'return($lib.cron.get({iden0}).kill())')) + cdef = await core.callStorm('return($lib.cron.get($iden).pack())', opts=opts) self.eq('mydoc', cdef.get('doc')) self.eq('myname', cdef.get('name')) From bd8f8247fd79bd1abb27cfa0dca61aa29e8abc99 Mon Sep 17 00:00:00 2001 From: visi Date: Tue, 2 Jul 2024 17:58:45 -0400 Subject: [PATCH 2/7] Unified IP Address Type --- synapse/lib/layer.py | 78 +++++++++++- synapse/models/inet.py | 205 +++++++++++++++++++++++++++++++ synapse/tests/test_model_inet.py | 12 ++ 3 files changed, 294 insertions(+), 1 deletion(-) diff --git a/synapse/lib/layer.py b/synapse/lib/layer.py index ba9b00a804..deadb8e438 100644 --- a/synapse/lib/layer.py +++ b/synapse/lib/layer.py @@ -217,7 +217,7 @@ async def getIden(self): STOR_TYPE_LOC = 15 STOR_TYPE_TAG = 16 STOR_TYPE_FQDN = 17 -STOR_TYPE_IPV6 = 18 +STOR_TYPE_IPV6 = 18 # retired.... STOR_TYPE_U128 = 19 STOR_TYPE_I128 = 20 @@ -230,6 +230,8 @@ async def getIden(self): STOR_TYPE_MAXTIME = 24 STOR_TYPE_NDEF = 25 +STOR_TYPE_IPADDR = 26 + STOR_FLAG_ARRAY = 0x8000 # Edit types (etyp) @@ -1378,6 +1380,79 @@ async def _liftMsgpEq(self, liftby, valu, reverse=False): def indx(self, valu): return (s_common.buid(valu),) +class StorTypeIPAddr(StorType): + + def __init__(self, layr): + StorType.__init__(self, layr, STOR_TYPE_IPADDR) + self.lifters.update({ + '=': self._liftAddrEq, + '<': self._liftAddrLt, + '>': self._liftAddrGt, + '<=': self._liftAddrLe, + '>=': self._liftAddrGe, + 'range=': self._liftAddrRange, + }) + + async def _liftAddrEq(self, liftby, valu, reverse=False): + indx = self._getIndxByts(valu) + for item in liftby.keyNidsByDups(indx, reverse=reverse): + yield item + + def _getMaxIndx(self, valu): + + if valu[0] == 4: + return b'\x04\xff\xff\xff\xff' + + return b'\x06\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' + + def _getMinIndx(self, valu): + + if valu[0] == 4: + return b'\x04\x00\x00\x00\x00' + + return b'\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + + async def _liftAddrLe(self, liftby, valu, reverse=False): + minindx = self._getMinIndx(valu) + maxindx = self._getIndxByts(valu) + for item in liftby.keyNidsByRange(minindx, maxindx, reverse=reverse): + yield item + + async def _liftAddrGe(self, liftby, valu, reverse=False): + minindx = self._getIndxByts(valu) + maxindx = self._getMaxIndx(valu) + for item in liftby.keyNidsByRange(minindx, maxindx, reverse=reverse): + yield item + + async def _liftAddrLt(self, liftby, valu, reverse=False): + async for item in self._liftAddrLe(liftby, (valu[0], valu[1] - 1), reverse=reverse): + yield item + + async def _liftAddrGt(self, liftby, valu, reverse=False): + async for item in self._liftAddrGe(liftby, (valu[0], valu[1] + 1), reverse=reverse): + yield item + + async def _liftAddrRange(self, liftby, valu, reverse=False): + + minindx = self._getIndxByts(valu[0]) + maxindx = self._getIndxByts(valu[1]) + for item in liftby.keyNidsByRange(minindx, maxindx, reverse=reverse): + yield item + + def indx(self, valu): + return (self._getIndxByts(valu),) + + def _getIndxByts(self, valu): + + if valu[0] == 4: + return b'\x04' + valu[1].to_bytes(4, 'big') + + if valu[0] == 6: + return b'\x06' + valu[1].to_bytes(16, 'big') + + mesg = 'Invalid STOR_TYPE_IPADDR: {valu}' + raise s_exc.BadTypeValu(mesg=mesg) + class StorTypeNdef(StorType): def __init__(self, layr): @@ -1566,6 +1641,7 @@ async def __anit__(self, core, layrinfo): StorTypeTime(self), # STOR_TYPE_MAXTIME StorTypeNdef(self), + StorTypeIPAddr(self), ] self.ivaltimetype = self.stortypes[STOR_TYPE_IVAL].timetype diff --git a/synapse/models/inet.py b/synapse/models/inet.py index abcf6c9c8b..f254cea4ca 100644 --- a/synapse/models/inet.py +++ b/synapse/models/inet.py @@ -276,6 +276,204 @@ def _normPyStr(self, valu): } return norm, info +class IPAddr(s_types.Type): + + stortype = s_layer.STOR_TYPE_IPADDR + + def postTypeInit(self): + + self.setCmprCtor('>=', self._ctorCmprGe) + self.setCmprCtor('<=', self._ctorCmprLe) + self.setCmprCtor('>', self._ctorCmprGt) + self.setCmprCtor('<', self._ctorCmprLt) + + self.setNormFunc(str, self._normPyStr) + self.setNormFunc(list, self._normPyTuple) + self.setNormFunc(tuple, self._normPyTuple) + + self.storlifts.update({ + '=': self._storLiftEq, + '<': self._storLiftNorm, + '>': self._storLiftNorm, + '<=': self._storLiftNorm, + '>=': self._storLiftNorm, + }) + + def _ctorCmprEq(self, valu): + + if isinstance(valu, str): + + if valu.find('/') != -1: + minv, maxv = self.getCidrRange(valu) + + def cmpr(norm): + return norm >= minv and norm < maxv + return cmpr + + if valu.find('-') != -1: + minv, maxv = self.getNetRange(valu) + + def cmpr(norm): + return norm >= minv and norm <= maxv + return cmpr + + return s_types.Type._ctorCmprEq(self, valu) + + def getTypeVals(self, valu): + + if isinstance(valu, str): + + if valu.find('/') != -1: + + minv, maxv = self.getCidrRange(valu) + while minv < maxv: + yield minv + minv += 1 + + return + + if valu.find('-') != -1: + + minv, maxv = self.getNetRange(valu) + + while minv <= maxv: + yield minv + minv += 1 + + return + + yield valu + + def _normPyTuple(self, valu): + + if any((len(valu) != 2, + type(valu[0]) is int, + type(valu[1]) is int)): + + mesg = f'Invalid IP address tuple: {valu}' + raise s_exc.BadTypeValu(mesg=mesg) + + def _normPyStr(self, text): + + valu = text.replace('[.]', '.') + valu = valu.replace('(.)', '.') + + valu = s_chop.printables(valu) + info = {'subs': {}} + + print(f'VALU {valu}') + if valu.find(':') != -1: + try: + byts = socket.inet_pton(socket.AF_INET6, valu) + addr = (6, int.from_bytes(byts, 'big')) + ipaddr = ipaddress.IPv6Address(addr[1]) + # v4 = v6.ipv4_mapped + except OSError as e: + mesg = f'Invalid IP Address: {text}' + raise s_exc.BadTypeValu(mesg=mesg) from None + else: + try: + byts = socket.inet_pton(socket.AF_INET, valu) + addr = (4, int.from_bytes(byts, 'big')) + ipaddr = ipaddress.IPv4Address(addr[1]) + except OSError as e: + mesg = f'Invalid IP Address: {text}' + raise s_exc.BadTypeValu(mesg=mesg) from None + + info['subs']['type'] = getAddrType(ipaddr) + info['subs']['scope'] = getAddrScope(ipaddr) + + return addr, info + + def repr(self, norm): + + vers, addr = norm + + if vers == 4: + byts = addr.to_bytes(4, 'big') + return socket.inet_ntop(socket.AF_INET, byts) + + if vers == 6: + # FIXME TODO + byts = addr.to_bytes(16, 'big') + return socket.inet_ntop(socket.AF_INET6, byts) + + mesg = 'IP proto {vers} is not supported!' + raise s_exc.BadTypeValu(mesg=mesg) + + def getNetRange(self, text): + minstr, maxstr = text.split('-', 1) + minv, info = self.norm(minstr) + maxv, info = self.norm(maxstr) + return minv, maxv + + def getCidrRange(self, text): + addr, mask_str = text.split('/', 1) + norm, info = self.norm(addr) + + try: + mask_int = int(mask_str) + except ValueError: + raise s_exc.BadTypeValu(valu=text, name=self.name, + mesg=f'Invalid CIDR Mask "{text}"') + + if mask_int > 32 or mask_int < 0: + raise s_exc.BadTypeValu(valu=text, name=self.name, + mesg=f'Invalid CIDR Mask "{text}"') + + mask = cidrmasks[mask_int] + + minv = norm & mask[0] + return minv, minv + mask[1] + + def _storLiftEq(self, cmpr, valu): + + if isinstance(valu, str): + + if valu.find('/') != -1: + minv, maxv = self.getCidrRange(valu) + maxv -= 1 + return ( + ('range=', (minv, maxv), self.stortype), + ) + + if valu.find('-') != -1: + minv, maxv = self.getNetRange(valu) + return ( + ('range=', (minv, maxv), self.stortype), + ) + + return self._storLiftNorm(cmpr, valu) + + def _ctorCmprGe(self, text): + norm, info = self.norm(text) + + def cmpr(valu): + return valu >= norm + return cmpr + + def _ctorCmprLe(self, text): + norm, info = self.norm(text) + + def cmpr(valu): + return valu <= norm + return cmpr + + def _ctorCmprGt(self, text): + norm, info = self.norm(text) + + def cmpr(valu): + return valu > norm + return cmpr + + def _ctorCmprLt(self, text): + norm, info = self.norm(text) + + def cmpr(valu): + return valu < norm + return cmpr + + class Fqdn(s_types.Type): stortype = s_layer.STOR_TYPE_FQDN @@ -1174,6 +1372,11 @@ def getModelDefs(self): 'ctors': ( + ('inet:ip', 'synapse.models.inet.IPAddr', {}, { + 'doc': 'An IPv4 or IPv6 address.', + 'ex': '1.2.3.4', + }), + ('inet:addr', 'synapse.models.inet.Addr', {}, { 'doc': 'A network layer URL-like format to represent tcp/udp/icmp clients and servers.', 'ex': 'tcp://1.2.3.4:80' @@ -1732,6 +1935,8 @@ def getModelDefs(self): 'forms': ( + ('inet:ip', {}, ()), + ('inet:proto', {}, ( ('port', ('inet:port', {}), { 'doc': 'The default port this protocol typically uses if applicable.'}), diff --git a/synapse/tests/test_model_inet.py b/synapse/tests/test_model_inet.py index e5a414d4a9..350869889e 100644 --- a/synapse/tests/test_model_inet.py +++ b/synapse/tests/test_model_inet.py @@ -8,6 +8,18 @@ class InetModelTest(s_t_utils.SynTest): + async def test_model_inet_ipaddr(self): + + async with self.getTestCore() as core: + iptype = core.model.type('inet:ip') + print(f'{iptype.norm("1.2.3.4")}') + + nodes = await core.nodes('[ inet:ip=1.2.3.4 inet:ip=ffff::ffff ]') + + self.len(2, nodes) + print(repr(nodes[0].pack())) + print(repr(nodes[1].pack())) + async def test_model_inet_basics(self): async with self.getTestCore() as core: self.len(1, await core.nodes('[ inet:web:hashtag="#hehe" ]')) From 6fa014a729a8c12b68a94b8a05c4a519df48c2f4 Mon Sep 17 00:00:00 2001 From: visi Date: Wed, 3 Jul 2024 16:09:16 -0400 Subject: [PATCH 3/7] wip --- synapse/models/inet.py | 22 ++++++++++------------ synapse/models/infotech.py | 6 +++--- synapse/tests/test_model_inet.py | 15 ++++++++++++--- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/synapse/models/inet.py b/synapse/models/inet.py index 75f32e6ab3..7d09c95c77 100644 --- a/synapse/models/inet.py +++ b/synapse/models/inet.py @@ -129,7 +129,7 @@ def _normPyStr(self, valu): if proto not in ('tcp', 'udp', 'icmp', 'host'): raise s_exc.BadTypeValu(valu=orig, name=self.name, - mesg='inet:addr protocol must be in: tcp, udp, icmp, host') + mesg='inet:sockaddr protocol must be in: tcp, udp, icmp, host') subs['proto'] = proto valu = valu.strip().strip('/') @@ -361,7 +361,6 @@ def _normPyStr(self, text): valu = s_chop.printables(valu) info = {'subs': {}} - print(f'VALU {valu}') if valu.find(':') != -1: try: byts = socket.inet_pton(socket.AF_INET6, valu) @@ -394,11 +393,10 @@ def repr(self, norm): return socket.inet_ntop(socket.AF_INET, byts) if vers == 6: - # FIXME TODO byts = addr.to_bytes(16, 'big') return socket.inet_ntop(socket.AF_INET6, byts) - mesg = 'IP proto {vers} is not supported!' + mesg = f'IP proto version ({vers}) is not supported!' raise s_exc.BadTypeValu(mesg=mesg) def getNetRange(self, text): @@ -1377,7 +1375,7 @@ def getModelDefs(self): 'ex': '1.2.3.4', }), - ('inet:addr', 'synapse.models.inet.Addr', {}, { + ('inet:sockaddr', 'synapse.models.inet.Addr', {}, { 'doc': 'A network layer URL-like format to represent tcp/udp/icmp clients and servers.', 'ex': 'tcp://1.2.3.4:80' }), @@ -1461,7 +1459,7 @@ def getModelDefs(self): 'ex': '(54959, (ff::00, ff::02))', }), - ('inet:client', ('inet:addr', {}), { + ('inet:client', ('inet:sockaddr', {}), { 'doc': 'A network client address.' }), @@ -1540,7 +1538,7 @@ def getModelDefs(self): 'ex': '80' }), - ('inet:server', ('inet:addr', {}), { + ('inet:server', ('inet:sockaddr', {}), { 'doc': 'A network server address.' }), @@ -1829,7 +1827,7 @@ def getModelDefs(self): ('flow', ('inet:flow', {}), { 'doc': 'The raw inet:flow containing the request.'}), ('client', ('inet:client', {}), { - 'doc': 'The inet:addr of the client.'}), + 'doc': 'The socket address of the client.'}), ('client:ipv4', ('inet:ipv4', {}), { 'doc': 'The server IPv4 address that the request was sent from.'}), ('client:ipv6', ('inet:ipv6', {}), { @@ -1837,7 +1835,7 @@ def getModelDefs(self): ('client:host', ('it:host', {}), { 'doc': 'The host that the request was sent from.'}), ('server', ('inet:server', {}), { - 'doc': 'The inet:addr of the server.'}), + 'doc': 'The socket address of the server.'}), ('server:ipv4', ('inet:ipv4', {}), { 'doc': 'The server IPv4 address that the request was sent to.'}), ('server:ipv6', ('inet:ipv6', {}), { @@ -2129,7 +2127,7 @@ def getModelDefs(self): 'doc': 'The file that was downloaded.' }), ('server', ('inet:server', {}), { - 'doc': 'The inet:addr of the server.' + 'doc': 'The socket address of the server.' }), ('server:host', ('it:host', {}), { 'doc': 'The it:host node for the server.' @@ -2147,7 +2145,7 @@ def getModelDefs(self): 'doc': 'The server network layer protocol.' }), ('client', ('inet:client', {}), { - 'doc': 'The inet:addr of the client.' + 'doc': 'The socket address of the client.' }), ('client:host', ('it:host', {}), { 'doc': 'The it:host node for the client.' @@ -2611,7 +2609,7 @@ def getModelDefs(self): }), ('server', ('inet:server', {}), { 'ro': True, - 'doc': 'The inet:addr of the server.' + 'doc': 'The listening socket address of the server.' }), ('server:proto', ('str', {'lower': True}), { 'ro': True, diff --git a/synapse/models/infotech.py b/synapse/models/infotech.py index 0e71035e1f..8ebe72b091 100644 --- a/synapse/models/infotech.py +++ b/synapse/models/infotech.py @@ -2664,7 +2664,7 @@ def getModelDefs(self): 'doc': 'The time the port was bound.', }), ('server', ('inet:server', {}), { - 'doc': 'The inet:addr of the server when binding the port.' + 'doc': 'The sock address of the server when binding the port.' }), ('server:ipv4', ('inet:ipv4', {}), { 'doc': 'The IPv4 address specified to bind().' @@ -2957,7 +2957,7 @@ def getModelDefs(self): 'doc': 'The snort rule that matched the file.'}), ('flow', ('inet:flow', {}), { 'doc': 'The inet:flow that matched the snort rule.'}), - ('src', ('inet:addr', {}), { + ('src', ('inet:sockaddr', {}), { 'doc': 'The source address of flow that caused the hit.'}), ('src:ipv4', ('inet:ipv4', {}), { 'doc': 'The source IPv4 address of the flow that caused the hit.'}), @@ -2965,7 +2965,7 @@ def getModelDefs(self): 'doc': 'The source IPv6 address of the flow that caused the hit.'}), ('src:port', ('inet:port', {}), { 'doc': 'The source port of the flow that caused the hit.'}), - ('dst', ('inet:addr', {}), { + ('dst', ('inet:sockaddr', {}), { 'doc': 'The destination address of the trigger.'}), ('dst:ipv4', ('inet:ipv4', {}), { 'doc': 'The destination IPv4 address of the flow that caused the hit.'}), diff --git a/synapse/tests/test_model_inet.py b/synapse/tests/test_model_inet.py index 350869889e..77bf9c2293 100644 --- a/synapse/tests/test_model_inet.py +++ b/synapse/tests/test_model_inet.py @@ -12,13 +12,22 @@ async def test_model_inet_ipaddr(self): async with self.getTestCore() as core: iptype = core.model.type('inet:ip') - print(f'{iptype.norm("1.2.3.4")}') nodes = await core.nodes('[ inet:ip=1.2.3.4 inet:ip=ffff::ffff ]') self.len(2, nodes) - print(repr(nodes[0].pack())) - print(repr(nodes[1].pack())) + + self.len(1, await core.nodes('inet:ip>1.2.3.0')) + self.len(1, await core.nodes('inet:ip>=1.2.3.0')) + self.len(1, await core.nodes('inet:ip<2.0.0.0')) + self.len(1, await core.nodes('inet:ip<=2.0.0.0')) + self.len(1, await core.nodes('inet:ip*range=(1.0.0.0, 2.0.0.0)')) + + self.len(1, await core.nodes('inet:ip>ff::00')) + self.len(1, await core.nodes('inet:ip>=ff::00')) + self.len(1, await core.nodes('inet:ip Date: Wed, 3 Jul 2024 20:26:02 -0400 Subject: [PATCH 4/7] begin 3.x model --- synapse/models/auth.py | 98 +- synapse/models/dns.py | 16 +- synapse/models/geospace.py | 28 + synapse/models/inet.py | 2286 ++++++++++++++++++------------------ synapse/models/infotech.py | 844 +++++++------ synapse/models/person.py | 687 ++++++----- synapse/models/risk.py | 442 +++---- synapse/models/telco.py | 196 ++-- 8 files changed, 2420 insertions(+), 2177 deletions(-) diff --git a/synapse/models/auth.py b/synapse/models/auth.py index ad9d1eb190..24217cb12d 100644 --- a/synapse/models/auth.py +++ b/synapse/models/auth.py @@ -6,6 +6,7 @@ def getModelDefs(self): modl = { 'types': ( + # FIXME i think we can do away with this whole model prefix ('auth:creds', ('guid', {}), { 'doc': 'A unique set of credentials used to access a resource.', }), @@ -14,54 +15,57 @@ def getModelDefs(self): }), ), 'forms': ( - ('auth:creds', {}, ( - ('email', ('inet:email', {}), { - 'doc': 'The email address used to identify the user.', - }), - ('user', ('inet:user', {}), { - 'doc': 'The user name used to identify the user.', - }), - ('phone', ('tel:phone', {}), { - 'doc': 'The phone number used to identify the user.', - }), - ('passwd', ('inet:passwd', {}), { - 'doc': 'The password used to authenticate.', - }), - ('passwdhash', ('it:auth:passwdhash', {}), { - 'doc': 'The password hash used to authenticate.', - }), - ('account', ('it:account', {}), { - 'doc': 'The account that the creds allow access to.', - }), - ('website', ('inet:url', {}), { - 'doc': 'The base URL of the website that the credentials allow access to.', - }), - ('host', ('it:host', {}), { - 'doc': 'The host that the credentials allow access to.', - }), - ('wifi:ssid', ('inet:wifi:ssid', {}), { - 'doc': 'The WiFi SSID that the credentials allow access to.', - }), - ('web:acct', ('inet:web:acct', {}), { - 'doc': 'The web account that the credentials allow access to.', - }), - # TODO x509, rfid, mat:item locks/keys - )), - ('auth:access', {}, ( - ('creds', ('auth:creds', {}), { - 'doc': 'The credentials used to attempt access.', - }), - ('time', ('time', {}), { - 'doc': 'The time of the access attempt.', - }), - ('success', ('bool', {}), { - 'doc': 'Set to true if the access was successful.', - }), - ('person', ('ps:person', {}), { - 'doc': 'The person who attempted access.', - }), - )), + # FIXME deprecate + #('auth:creds', {}, ( + # ('email', ('inet:email', {}), { + # 'doc': 'The email address used to identify the user.', + # }), + # ('user', ('inet:user', {}), { + # 'doc': 'The user name used to identify the user.', + # }), + # ('phone', ('tel:phone', {}), { + # 'doc': 'The phone number used to identify the user.', + # }), + # ('passwd', ('inet:passwd', {}), { + # 'doc': 'The password used to authenticate.', + # }), + # ('passwdhash', ('it:auth:passwdhash', {}), { + # 'doc': 'The password hash used to authenticate.', + # }), + # ('account', ('it:account', {}), { + # 'doc': 'The account that the creds allow access to.', + # }), + # ('website', ('inet:url', {}), { + # 'doc': 'The base URL of the website that the credentials allow access to.', + # }), + # ('host', ('it:host', {}), { + # 'doc': 'The host that the credentials allow access to.', + # }), + # ('wifi:ssid', ('inet:wifi:ssid', {}), { + # 'doc': 'The WiFi SSID that the credentials allow access to.', + # }), + # #('web:acct', ('inet:web:acct', {}), { + # #'doc': 'The web account that the credentials allow access to.', + # #}), + # # TODO x509, rfid, mat:item locks/keys + #)), + + # FIXME deprecate + #('auth:access', {}, ( + # ('creds', ('auth:creds', {}), { + # 'doc': 'The credentials used to attempt access.', + # }), + # ('time', ('time', {}), { + # 'doc': 'The time of the access attempt.', + # }), + # ('success', ('bool', {}), { + # 'doc': 'Set to true if the access was successful.', + # }), + # ('person', ('ps:person', {}), { + # 'doc': 'The person who attempted access.', + # }), + #)), ), } name = 'auth' diff --git a/synapse/models/dns.py b/synapse/models/dns.py index 6c304092db..48387970a7 100644 --- a/synapse/models/dns.py +++ b/synapse/models/dns.py @@ -91,6 +91,7 @@ def getModelDefs(self): 'types': ( + # FIXME how to limit use of inet:ip to specific versions? ('inet:dns:a', ('comp', {'fields': (('fqdn', 'inet:fqdn'), ('ipv4', 'inet:ipv4'))}), { 'ex': '(vertex.link,1.2.3.4)', 'doc': 'The result of a DNS A record lookup.'}), @@ -214,8 +215,9 @@ def getModelDefs(self): ('inet:dns:query', {}, ( ('client', ('inet:client', {}), {'ro': True, }), ('name', ('inet:dns:name', {}), {'ro': True, }), - ('name:ipv4', ('inet:ipv4', {}), {}), - ('name:ipv6', ('inet:ipv6', {}), {}), + ('name:ip', ('inet:ip', {}), {}), + #('name:ipv4', ('inet:ipv4', {}), {}), + #('name:ipv6', ('inet:ipv6', {}), {}), ('name:fqdn', ('inet:fqdn', {}), {}), ('type', ('int', {}), {'ro': True, }), )), @@ -250,6 +252,7 @@ def getModelDefs(self): )), + # FIXME should requests contain answers rather than both existing? ('inet:dns:answer', {}, ( ('ttl', ('int', {}), {}), @@ -308,6 +311,7 @@ def getModelDefs(self): ('fqdn', ('inet:fqdn', {}), { 'doc': 'The FQDN registered within a dynamic DNS provider.'}), + # FIXME entity ('provider', ('ou:org', {}), { 'doc': 'The organization which provides the dynamic DNS FQDN.'}), @@ -326,11 +330,11 @@ def getModelDefs(self): ('client', ('inet:client', {}), { 'doc': 'The network client address used to register the dynamic FQDN.'}), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The client IPv4 address used to register the dynamic FQDN.'}), + #('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The client IPv4 address used to register the dynamic FQDN.'}), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The client IPv6 address used to register the dynamic FQDN.'}), + #('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The client IPv6 address used to register the dynamic FQDN.'}), )), ) diff --git a/synapse/models/geospace.py b/synapse/models/geospace.py index db86138eba..bccb5a0e8a 100644 --- a/synapse/models/geospace.py +++ b/synapse/models/geospace.py @@ -440,6 +440,34 @@ def getModelDefs(self): }), ), + 'interfaces': ( + # FIXME name + ('geo:placed', { + 'doc': 'Properties shared by nodes which can occupy a geographic location.', + 'props': ( + + ('place', ('geo:place', {}), { + 'doc': 'The place where the {form} is located.'}), + + # FIXME should we even keep loc? + ('place:loc', ('geo:name', {}), { + 'doc': 'The loc of the place where the {form} is located.'}), + + ('place:country:code', ('pol:iso2', {}), { + 'doc': 'The country code of the place where {form} is located.'}) + + ('place:name', ('geo:name', {}), { + 'doc': 'The name of the place where the {form} is located.'}), + + ('place:latlong', ('geo:latlong', {}), { + 'doc': 'The latlong of the place where the {form} is located.'}), + + ('place:address', ('geo:address', {}), { + 'doc': 'The address of the place where the {form} is located.'}), + ), + }), + ), + 'edges': ( ((None, 'seenat', 'geo:telem'), { 'doc': 'The source node was seen at the geo:telem node place and time.'}), diff --git a/synapse/models/inet.py b/synapse/models/inet.py index 7d09c95c77..9013f09652 100644 --- a/synapse/models/inet.py +++ b/synapse/models/inet.py @@ -189,63 +189,63 @@ def _normPyStr(self, valu): return f'{proto}://{ipv4_repr}{pstr}', {'subs': subs} -class Cidr4(s_types.Str): - - def postTypeInit(self): - s_types.Str.postTypeInit(self) - self.setNormFunc(str, self._normPyStr) - - def _normPyStr(self, valu): - - try: - ip_str, mask_str = valu.split('/', 1) - mask_int = int(mask_str) - except ValueError: - raise s_exc.BadTypeValu(valu=valu, name=self.name, - mesg='Invalid/Missing CIDR Mask') - - if mask_int > 32 or mask_int < 0: - raise s_exc.BadTypeValu(valu=valu, name=self.name, - mesg='Invalid CIDR Mask') - - ip_int = self.modl.type('inet:ipv4').norm(ip_str)[0] - - mask = cidrmasks[mask_int] - network = ip_int & mask[0] - broadcast = network + mask[1] - 1 - network_str = self.modl.type('inet:ipv4').repr(network) - - norm = f'{network_str}/{mask_int}' - info = { - 'subs': { - 'broadcast': broadcast, - 'mask': mask_int, - 'network': network, - } - } - return norm, info - -class Cidr6(s_types.Str): - - def postTypeInit(self): - s_types.Str.postTypeInit(self) - self.setNormFunc(str, self._normPyStr) - - def _normPyStr(self, valu): - try: - network = ipaddress.IPv6Network(valu) - except Exception as e: - raise s_exc.BadTypeValu(valu=valu, name=self.name, mesg=str(e)) from None - - norm = str(network) - info = { - 'subs': { - 'broadcast': str(network.broadcast_address), - 'mask': network.prefixlen, - 'network': str(network.network_address), - } - } - return norm, info +#class Cidr4(s_types.Str): +# +# def postTypeInit(self): +# s_types.Str.postTypeInit(self) +# self.setNormFunc(str, self._normPyStr) +# +# def _normPyStr(self, valu): +# +# try: +# ip_str, mask_str = valu.split('/', 1) +# mask_int = int(mask_str) +# except ValueError: +# raise s_exc.BadTypeValu(valu=valu, name=self.name, +# mesg='Invalid/Missing CIDR Mask') +# +# if mask_int > 32 or mask_int < 0: +# raise s_exc.BadTypeValu(valu=valu, name=self.name, +# mesg='Invalid CIDR Mask') +# +# ip_int = self.modl.type('inet:ipv4').norm(ip_str)[0] +# +# mask = cidrmasks[mask_int] +# network = ip_int & mask[0] +# broadcast = network + mask[1] - 1 +# network_str = self.modl.type('inet:ipv4').repr(network) +# +# norm = f'{network_str}/{mask_int}' +# info = { +# 'subs': { +# 'broadcast': broadcast, +# 'mask': mask_int, +# 'network': network, +# } +# } +# return norm, info +# +#class Cidr6(s_types.Str): +# +# def postTypeInit(self): +# s_types.Str.postTypeInit(self) +# self.setNormFunc(str, self._normPyStr) +# +# def _normPyStr(self, valu): +# try: +# network = ipaddress.IPv6Network(valu) +# except Exception as e: +# raise s_exc.BadTypeValu(valu=valu, name=self.name, mesg=str(e)) from None +# +# norm = str(network) +# info = { +# 'subs': { +# 'broadcast': str(network.broadcast_address), +# 'mask': network.prefixlen, +# 'network': str(network.network_address), +# } +# } +# return norm, info class Email(s_types.Str): @@ -1542,10 +1542,12 @@ def getModelDefs(self): 'doc': 'A network server address.' }), + # FIXME still want OTK banner? ('inet:banner', ('comp', {'fields': (('server', 'inet:server'), ('text', 'it:dev:str'))}), { 'doc': 'A network protocol banner string presented by a server.', }), + # FIXME deprecate? ('inet:servfile', ('comp', {'fields': (('server', 'inet:server'), ('file', 'file:bytes'))}), { 'doc': 'A file hosted on a server for access over a network protocol.', }), @@ -1644,10 +1646,11 @@ def getModelDefs(self): 'doc': 'An individual contact from a domain whois record.' }), - ('inet:whois:rar', ('str', {'lower': True}), { - 'doc': 'A domain registrar.', - 'ex': 'godaddy, inc.' - }), + # FIXME deprecate ( entity:name ) + #('inet:whois:rar', ('str', {'lower': True}), { + # 'doc': 'A domain registrar.', + # 'ex': 'godaddy, inc.' + #}), ('inet:whois:rec', ('comp', {'fields': (('fqdn', 'inet:fqdn'), ('asof', 'time'))}), { 'doc': 'A domain whois record.' @@ -1657,10 +1660,11 @@ def getModelDefs(self): 'doc': 'A nameserver associated with a domain whois record.' }), - ('inet:whois:reg', ('str', {'lower': True}), { - 'doc': 'A domain registrant.', - 'ex': 'woot hostmaster' - }), + # FIXME deprecate entity:name? + #('inet:whois:reg', ('str', {'lower': True}), { + # 'doc': 'A domain registrant.', + # 'ex': 'woot hostmaster' + #}), ('inet:whois:email', ('comp', {'fields': (('fqdn', 'inet:fqdn'), ('email', 'inet:email'))}), { 'doc': 'An email address associated with an FQDN via whois registration text.', @@ -1828,18 +1832,18 @@ def getModelDefs(self): 'doc': 'The raw inet:flow containing the request.'}), ('client', ('inet:client', {}), { 'doc': 'The socket address of the client.'}), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The server IPv4 address that the request was sent from.'}), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The server IPv6 address that the request was sent from.'}), + #('client:ipv4', ('inet:ipv4', {}), { + #'doc': 'The server IPv4 address that the request was sent from.'}), + #('client:ipv6', ('inet:ipv6', {}), { + #'doc': 'The server IPv6 address that the request was sent from.'}), ('client:host', ('it:host', {}), { 'doc': 'The host that the request was sent from.'}), ('server', ('inet:server', {}), { 'doc': 'The socket address of the server.'}), - ('server:ipv4', ('inet:ipv4', {}), { - 'doc': 'The server IPv4 address that the request was sent to.'}), - ('server:ipv6', ('inet:ipv6', {}), { - 'doc': 'The server IPv6 address that the request was sent to.'}), + #('server:ipv4', ('inet:ipv4', {}), { + #'doc': 'The server IPv4 address that the request was sent to.'}), + #('server:ipv6', ('inet:ipv6', {}), { + #'doc': 'The server IPv6 address that the request was sent to.'}), ('server:port', ('inet:port', {}), { 'doc': 'The server port that the request was sent to.'}), ('server:host', ('it:host', {}), { @@ -1971,11 +1975,12 @@ def getModelDefs(self): ('headers', ('array', {'type': 'inet:email:header'}), { 'doc': 'An array of email headers from the message.'}), - ('received:from:ipv4', ('inet:ipv4', {}), { - 'doc': 'The sending SMTP server IPv4, potentially from the Received: header.'}), + #('received:from:ipv4', ('inet:ipv4', {}), { + ('received:from:ip', ('inet:ip', {}), { + 'doc': 'The IP address of the sending SMTP server. Likely from the Received: header.'}), - ('received:from:ipv6', ('inet:ipv6', {}), { - 'doc': 'The sending SMTP server IPv6, potentially from the Received: header.'}), + #('received:from:ipv6', ('inet:ipv6', {}), { + #'doc': 'The sending SMTP server IPv6, potentially from the Received: header.'}), ('received:from:fqdn', ('inet:fqdn', {}), { 'doc': 'The sending server FQDN, potentially from the Received: header.'}), @@ -2025,95 +2030,102 @@ def getModelDefs(self): }), )), - ('inet:asnet4', {}, ( - ('asn', ('inet:asn', {}), { - 'ro': True, - 'doc': 'The Autonomous System Number (ASN) of the netblock.' - }), - ('net4', ('inet:net4', {}), { - 'ro': True, - 'doc': 'The IPv4 address range assigned to the ASN.' - }), - ('net4:min', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The first IPv4 in the range assigned to the ASN.' - }), - ('net4:max', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The last IPv4 in the range assigned to the ASN.' - }), - )), - - ('inet:asnet6', {}, ( - ('asn', ('inet:asn', {}), { - 'ro': True, - 'doc': 'The Autonomous System Number (ASN) of the netblock.' - }), - ('net6', ('inet:net6', {}), { - 'ro': True, - 'doc': 'The IPv6 address range assigned to the ASN.' - }), - ('net6:min', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The first IPv6 in the range assigned to the ASN.' - }), - ('net6:max', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The last IPv6 in the range assigned to the ASN.' - }), - )), - - ('inet:cidr4', {}, ( - ('broadcast', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The broadcast IP address from the CIDR notation.' - }), - ('mask', ('int', {}), { - 'ro': True, - 'doc': 'The mask from the CIDR notation.' - }), - ('network', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The network IP address from the CIDR notation.' - }), - )), - - ('inet:cidr6', {}, ( - ('broadcast', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The broadcast IP address from the CIDR notation.' - }), - ('mask', ('int', {}), { - 'ro': True, - 'doc': 'The mask from the CIDR notation.' - }), - ('network', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The network IP address from the CIDR notation.' - }), - )), + ('inet:as:net', {}, ( + )), + + #('inet:asnet4', {}, ( + # ('asn', ('inet:asn', {}), { + # 'ro': True, + # 'doc': 'The Autonomous System Number (ASN) of the netblock.' + # }), + # ('net4', ('inet:net4', {}), { + # 'ro': True, + # 'doc': 'The IPv4 address range assigned to the ASN.' + # }), + # ('net4:min', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The first IPv4 in the range assigned to the ASN.' + # }), + # ('net4:max', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The last IPv4 in the range assigned to the ASN.' + # }), + #)), + + #('inet:asnet6', {}, ( + # ('asn', ('inet:asn', {}), { + # 'ro': True, + # 'doc': 'The Autonomous System Number (ASN) of the netblock.' + # }), + # ('net6', ('inet:net6', {}), { + # 'ro': True, + # 'doc': 'The IPv6 address range assigned to the ASN.' + # }), + # ('net6:min', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The first IPv6 in the range assigned to the ASN.' + # }), + # ('net6:max', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The last IPv6 in the range assigned to the ASN.' + # }), + #)), + + #('inet:cidr4', {}, ( + # ('broadcast', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The broadcast IP address from the CIDR notation.' + # }), + # ('mask', ('int', {}), { + # 'ro': True, + # 'doc': 'The mask from the CIDR notation.' + # }), + # ('network', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The network IP address from the CIDR notation.' + # }), + #)), + + #('inet:cidr6', {}, ( + # ('broadcast', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The broadcast IP address from the CIDR notation.' + # }), + # ('mask', ('int', {}), { + # 'ro': True, + # 'doc': 'The mask from the CIDR notation.' + # }), + # ('network', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The network IP address from the CIDR notation.' + # }), + #)), ('inet:client', {}, ( + ('proto', ('str', {'lower': True}), { 'ro': True, - 'doc': 'The network protocol of the client.' - }), - ('ipv4', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The IPv4 of the client.' - }), - ('ipv6', ('inet:ipv6', {}), { + 'doc': 'The network protocol of the client.'}), + + ('ip', ('inet:ip', {}), { 'ro': True, - 'doc': 'The IPv6 of the client.' - }), + 'doc': 'The IP address of the client.'}), + #('ipv4', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The IPv4 of the client.' + #}), + #('ipv6', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The IPv6 of the client.' + #}), ('host', ('it:host', {}), { 'ro': True, - 'doc': 'The it:host node for the client.' - }), + 'doc': 'The it:host node for the client.'}), + ('port', ('inet:port', {}), { - 'doc': 'The client tcp/udp port.' - }), + 'doc': 'The client tcp/udp port.'}), + )), ('inet:download', {}, ( @@ -2129,45 +2141,47 @@ def getModelDefs(self): ('server', ('inet:server', {}), { 'doc': 'The socket address of the server.' }), - ('server:host', ('it:host', {}), { - 'doc': 'The it:host node for the server.' - }), - ('server:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 of the server.' - }), - ('server:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 of the server.' - }), - ('server:port', ('inet:port', {}), { - 'doc': 'The server tcp/udp port.' - }), - ('server:proto', ('str', {'lower': True}), { - 'doc': 'The server network layer protocol.' - }), + #('server:host', ('it:host', {}), { + # 'doc': 'The it:host node for the server.' + #}), + #('server:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 of the server.' + #}), + #('server:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 of the server.' + #}), + #('server:port', ('inet:port', {}), { + # 'doc': 'The server tcp/udp port.' + #}), + #('server:proto', ('str', {'lower': True}), { + # 'doc': 'The server network layer protocol.' + #}), ('client', ('inet:client', {}), { 'doc': 'The socket address of the client.' }), - ('client:host', ('it:host', {}), { - 'doc': 'The it:host node for the client.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 of the client.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 of the client.' - }), - ('client:port', ('inet:port', {}), { - 'doc': 'The client tcp/udp port.' - }), - ('client:proto', ('str', {'lower': True}), { - 'doc': 'The client network layer protocol.' - }), + #('client:host', ('it:host', {}), { + # 'doc': 'The it:host node for the client.' + #}), + #('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 of the client.' + #}), + #('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 of the client.' + #}), + #('client:port', ('inet:port', {}), { + # 'doc': 'The client tcp/udp port.' + #}), + #('client:proto', ('str', {'lower': True}), { + # 'doc': 'The client network layer protocol.' + #}), )), ('inet:email', {}, ( + ('user', ('inet:user', {}), { 'ro': True, 'doc': 'The username of the email address.'}), + ('fqdn', ('inet:fqdn', {}), { 'ro': True, 'doc': 'The domain of the email address.'}), @@ -2183,24 +2197,28 @@ def getModelDefs(self): ('from', ('guid', {}), { 'doc': 'The ingest source file/iden. Used for reparsing.' }), + # FIXME make these more consistent ('dst', ('inet:server', {}), { 'doc': 'The destination address / port for a connection.' }), - ('dst:ipv4', ('inet:ipv4', {}), { - 'doc': 'The destination IPv4 address.' - }), - ('dst:ipv6', ('inet:ipv6', {}), { - 'doc': 'The destination IPv6 address.' - }), - ('dst:port', ('inet:port', {}), { - 'doc': 'The destination port.' - }), - ('dst:proto', ('str', {'lower': True}), { - 'doc': 'The destination protocol.' - }), - ('dst:host', ('it:host', {}), { - 'doc': 'The guid of the destination host.' - }), + #('dst:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The destination IPv4 address.' + #}), + #('dst:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The destination IPv4 address.' + #}), + #('dst:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The destination IPv6 address.' + #}), + #('dst:port', ('inet:port', {}), { + # 'doc': 'The destination port.' + #}), + #('dst:proto', ('str', {'lower': True}), { + # 'doc': 'The destination protocol.' + #}), + #('dst:host', ('it:host', {}), { + # 'doc': 'The guid of the destination host.' + #}), ('dst:proc', ('it:exec:proc', {}), { 'doc': 'The guid of the destination process.' }), @@ -2220,21 +2238,21 @@ def getModelDefs(self): ('src', ('inet:client', {}), { 'doc': 'The source address / port for a connection.' }), - ('src:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address.' - }), - ('src:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address.' - }), - ('src:port', ('inet:port', {}), { - 'doc': 'The source port.' - }), - ('src:proto', ('str', {'lower': True}), { - 'doc': 'The source protocol.' - }), - ('src:host', ('it:host', {}), { - 'doc': 'The guid of the source host.' - }), + #('src:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address.' + #}), + #('src:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address.' + #}), + #('src:port', ('inet:port', {}), { + # 'doc': 'The source port.' + #}), + #('src:proto', ('str', {'lower': True}), { + # 'doc': 'The source protocol.' + #}), + #('src:host', ('it:host', {}), { + # 'doc': 'The guid of the source host.' + #}), ('src:proc', ('it:exec:proc', {}), { 'doc': 'The guid of the source process.' }), @@ -2326,11 +2344,11 @@ def getModelDefs(self): ('client', ('inet:client', {}), { 'doc': 'The client address the host used as a network egress.'}), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The client IPv4 address the host used as a network egress.'}), + #('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The client IPv4 address the host used as a network egress.'}), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The client IPv6 address the host used as a network egress.'}), + #('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The client IPv6 address the host used as a network egress.'}), )), ('inet:fqdn', {}, ( @@ -2453,12 +2471,16 @@ def getModelDefs(self): ('mac', ('inet:mac', {}), { 'doc': 'The ethernet (MAC) address of the interface.' }), - ('ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 address of the interface.' - }), - ('ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 address of the interface.' - }), + + ('ip', ('inet:ip', {}), { + 'doc': 'The IP address of the interface.'}) + + #('ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 address of the interface.' + #}), + #('ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 address of the interface.' + #}), ('phone', ('tel:phone', {}), { 'doc': 'The telephone number of the interface.' }), @@ -2479,54 +2501,54 @@ def getModelDefs(self): }), )), - ('inet:ipv4', {}, ( + #('inet:ipv4', {}, ( - ('asn', ('inet:asn', {}), { - 'doc': 'The ASN to which the IPv4 address is currently assigned.'}), + # ('asn', ('inet:asn', {}), { + # 'doc': 'The ASN to which the IPv4 address is currently assigned.'}), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The best known latitude/longitude for the node.'}), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The best known latitude/longitude for the node.'}), - ('loc', ('loc', {}), { - 'doc': 'The geo-political location string for the IPv4.'}), + # ('loc', ('loc', {}), { + # 'doc': 'The geo-political location string for the IPv4.'}), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place associated with the latlong property.'}), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place associated with the latlong property.'}), - ('type', ('str', {}), { - 'doc': 'The type of IP address (e.g., private, multicast, etc.).'}), + # ('type', ('str', {}), { + # 'doc': 'The type of IP address (e.g., private, multicast, etc.).'}), - ('dns:rev', ('inet:fqdn', {}), { - 'doc': 'The most current DNS reverse lookup for the IPv4.'}), - )), + # ('dns:rev', ('inet:fqdn', {}), { + # 'doc': 'The most current DNS reverse lookup for the IPv4.'}), + #)), - ('inet:ipv6', {}, ( + #('inet:ipv6', {}, ( - ('asn', ('inet:asn', {}), { - 'doc': 'The ASN to which the IPv6 address is currently assigned.'}), + # ('asn', ('inet:asn', {}), { + # 'doc': 'The ASN to which the IPv6 address is currently assigned.'}), - ('ipv4', ('inet:ipv4', {}), { - 'doc': 'The mapped ipv4.'}), + # ('ipv4', ('inet:ipv4', {}), { + # 'doc': 'The mapped ipv4.'}), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The last known latitude/longitude for the node.'}), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The last known latitude/longitude for the node.'}), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place associated with the latlong property.'}), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place associated with the latlong property.'}), - ('dns:rev', ('inet:fqdn', {}), { - 'doc': 'The most current DNS reverse lookup for the IPv6.'}), + # ('dns:rev', ('inet:fqdn', {}), { + # 'doc': 'The most current DNS reverse lookup for the IPv6.'}), - ('loc', ('loc', {}), { - 'doc': 'The geo-political location string for the IPv6.'}), + # ('loc', ('loc', {}), { + # 'doc': 'The geo-political location string for the IPv6.'}), - ('type', ('str', {}), { - 'doc': 'The type of IP address (e.g., private, multicast, etc.).'}), + # ('type', ('str', {}), { + # 'doc': 'The type of IP address (e.g., private, multicast, etc.).'}), - ('scope', ('str', {'enums': scopes_enum}), { - 'doc': 'The IPv6 scope of the address (e.g., global, link-local, etc.).'}), + # ('scope', ('str', {'enums': scopes_enum}), { + # 'doc': 'The IPv6 scope of the address (e.g., global, link-local, etc.).'}), - )), + #)), ('inet:mac', {}, ( ('vendor', ('str', {}), { @@ -2535,18 +2557,18 @@ def getModelDefs(self): )), ('inet:passwd', {}, ( + ('md5', ('hash:md5', {}), { 'ro': True, - 'doc': 'The MD5 hash of the password.' - }), + 'doc': 'The MD5 hash of the password.'}), + ('sha1', ('hash:sha1', {}), { 'ro': True, - 'doc': 'The SHA1 hash of the password.' - }), + 'doc': 'The SHA1 hash of the password.'}), + ('sha256', ('hash:sha256', {}), { 'ro': True, - 'doc': 'The SHA256 hash of the password.' - }), + 'doc': 'The SHA256 hash of the password.'}), )), ('inet:rfc2822:addr', {}, ( @@ -2563,23 +2585,25 @@ def getModelDefs(self): ('inet:server', {}, ( ('proto', ('str', {'lower': True}), { 'ro': True, - 'doc': 'The network protocol of the server.' - }), - ('ipv4', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The IPv4 of the server.' - }), - ('ipv6', ('inet:ipv6', {}), { + 'doc': 'The network protocol of the server.'}), + + ('ip', ('inet:ip', {}), { 'ro': True, - 'doc': 'The IPv6 of the server.' - }), + 'doc': 'The IP address of the server.'}), + #('ipv4', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The IPv4 of the server.' + #}), + #('ipv6', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The IPv6 of the server.' + #}), ('host', ('it:host', {}), { 'ro': True, - 'doc': 'The it:host node for the server.' - }), + 'doc': 'The it:host node for the server.'}), + ('port', ('inet:port', {}), { - 'doc': 'The server tcp/udp port.' - }), + 'doc': 'The server tcp/udp port.'}), )), ('inet:banner', {}, ( @@ -2587,14 +2611,13 @@ def getModelDefs(self): ('server', ('inet:server', {}), {'ro': True, 'doc': 'The server which presented the banner string.'}), - ('server:ipv4', ('inet:ipv4', {}), {'ro': True, - 'doc': 'The IPv4 address of the server.'}), + #('server:ipv4', ('inet:ipv4', {}), {'ro': True, + # 'doc': 'The IPv4 address of the server.'}), - ('server:ipv6', ('inet:ipv6', {}), {'ro': True, - 'doc': 'The IPv6 address of the server.'}), - - ('server:port', ('inet:port', {}), {'ro': True, - 'doc': 'The network port.'}), + #('server:ipv6', ('inet:ipv6', {}), {'ro': True, + # 'doc': 'The IPv6 address of the server.'}), + #('server:port', ('inet:port', {}), {'ro': True, + #'doc': 'The network port.'}), ('text', ('it:dev:str', {}), {'ro': True, 'doc': 'The banner text.', @@ -2602,112 +2625,119 @@ def getModelDefs(self): }), )), + # FIXME deprecate? ('inet:servfile', {}, ( - ('file', ('file:bytes', {}), { - 'ro': True, - 'doc': 'The file hosted by the server.' - }), - ('server', ('inet:server', {}), { - 'ro': True, - 'doc': 'The listening socket address of the server.' - }), - ('server:proto', ('str', {'lower': True}), { - 'ro': True, - 'doc': 'The network protocol of the server.' - }), - ('server:ipv4', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The IPv4 of the server.' - }), - ('server:ipv6', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The IPv6 of the server.' - }), - ('server:host', ('it:host', {}), { - 'ro': True, - 'doc': 'The it:host node for the server.' - }), - ('server:port', ('inet:port', {}), { - 'doc': 'The server tcp/udp port.' - }), - )), - ('inet:ssl:cert', {}, ( ('file', ('file:bytes', {}), { 'ro': True, - 'doc': 'The file bytes for the SSL certificate.' - }), + 'doc': 'The file hosted by the server.'}), + ('server', ('inet:server', {}), { 'ro': True, - 'doc': 'The server that presented the SSL certificate.' - }), - ('server:ipv4', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The SSL server IPv4 address.' - }), - ('server:ipv6', ('inet:ipv6', {}), { - 'ro': True, - 'doc': 'The SSL server IPv6 address.' - }), - ('server:port', ('inet:port', {}), { - 'ro': True, - 'doc': 'The SSL server listening port.' - }), - )), + 'doc': 'The listening socket address of the server.'}), + + #('server:proto', ('str', {'lower': True}), { + # 'ro': True, + # 'doc': 'The network protocol of the server.' + #}), + #('server:ipv4', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The IPv4 of the server.' + #}), + #('server:ipv6', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The IPv6 of the server.' + #}), + #('server:host', ('it:host', {}), { + # 'ro': True, + # 'doc': 'The it:host node for the server.' + #}), + #('server:port', ('inet:port', {}), { + # 'doc': 'The server tcp/udp port.' + #}), + )), + + #('inet:ssl:cert', {}, ( + # ('file', ('file:bytes', {}), { + # 'ro': True, + # 'doc': 'The file bytes for the SSL certificate.' + # }), + # ('server', ('inet:server', {}), { + # 'ro': True, + # 'doc': 'The server that presented the SSL certificate.' + # }), + # ('server:ipv4', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The SSL server IPv4 address.' + # }), + # ('server:ipv6', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The SSL server IPv6 address.' + # }), + # ('server:port', ('inet:port', {}), { + # 'ro': True, + # 'doc': 'The SSL server listening port.' + # }), + #)), ('inet:url', {}, ( + ('fqdn', ('inet:fqdn', {}), { 'ro': True, - 'doc': 'The fqdn used in the URL (e.g., http://www.woot.com/page.html).' - }), - ('ipv4', ('inet:ipv4', {}), { - 'ro': True, - 'doc': 'The IPv4 address used in the URL (e.g., http://1.2.3.4/page.html).' - }), - ('ipv6', ('inet:ipv6', {}), { + 'doc': 'The fqdn used in the URL (e.g., http://www.woot.com/page.html).'}), + + ('ip', ('inet:ip', {}), { 'ro': True, - 'doc': 'The IPv6 address used in the URL.' - }), + 'doc': 'The IP address used in the URL.'}), + + #('ipv4', ('inet:ipv4', {}), { + # 'ro': True, + # 'doc': 'The IPv4 address used in the URL (e.g., http://1.2.3.4/page.html).' + #}), + #('ipv6', ('inet:ipv6', {}), { + # 'ro': True, + # 'doc': 'The IPv6 address used in the URL.' + #}), ('passwd', ('inet:passwd', {}), { 'ro': True, - 'doc': 'The optional password used to access the URL.' - }), + 'doc': 'The optional password used to access the URL.'}), + ('base', ('str', {}), { 'ro': True, - 'doc': 'The base scheme, user/pass, fqdn, port and path w/o parameters.' - }), + 'doc': 'The base scheme, user/pass, fqdn, port and path w/o parameters.'}), + ('path', ('str', {}), { 'ro': True, - 'doc': 'The path in the URL w/o parameters.' - }), + 'doc': 'The path in the URL w/o parameters.'}), + ('params', ('str', {}), { 'ro': True, - 'doc': 'The URL parameter string.' - }), + 'doc': 'The URL parameter string.'}), + ('port', ('inet:port', {}), { 'ro': True, 'doc': 'The port of the URL. URLs prefixed with http will be set to port 80 and ' - 'URLs prefixed with https will be set to port 443 unless otherwise specified.' - }), + 'URLs prefixed with https will be set to port 443 unless otherwise specified.'}), + ('proto', ('str', {'lower': True}), { 'ro': True, - 'doc': 'The protocol in the URL.' - }), + 'doc': 'The protocol in the URL.'}), + ('user', ('inet:user', {}), { 'ro': True, - 'doc': 'The optional username used to access the URL.' - }), + 'doc': 'The optional username used to access the URL.'}), + )), ('inet:urlfile', {}, ( + ('url', ('inet:url', {}), { 'ro': True, - 'doc': 'The URL where the file was hosted.' - }), + 'doc': 'The URL where the file was hosted.'}), + ('file', ('file:bytes', {}), { 'ro': True, - 'doc': 'The file that was hosted at the URL.' - }), + 'doc': 'The file that was hosted at the URL.'}), )), ('inet:urlredir', {}, ( @@ -2715,56 +2745,58 @@ def getModelDefs(self): 'ro': True, 'doc': 'The original/source URL before redirect.' }), - ('src:fqdn', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The FQDN within the src URL (if present).' - }), + #('src:fqdn', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The FQDN within the src URL (if present).' + #}), ('dst', ('inet:url', {}), { 'ro': True, 'doc': 'The redirected/destination URL.' }), - ('dst:fqdn', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The FQDN within the dst URL (if present).' - }), + #('dst:fqdn', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The FQDN within the dst URL (if present).' + #}), )), ('inet:url:mirror', {}, ( + ('of', ('inet:url', {}), { 'ro': True, - 'doc': 'The URL being mirrored.', - }), + 'doc': 'The URL being mirrored.'}), + ('at', ('inet:url', {}), { 'ro': True, - 'doc': 'The URL of the mirror.', - }), + 'doc': 'The URL of the mirror.'}), )), ('inet:user', {}, ()), + # FIXME unify with it:exec:query? ('inet:search:query', {}, ( ('text', ('str', {}), { - 'doc': 'The search query text.', 'disp': {'hint': 'text'}, - }), + 'doc': 'The search query text.'}), + ('time', ('time', {}), { - 'doc': 'The time the web search was issued.', - }), + 'doc': 'The time the web search was issued.'}), + ('acct', ('inet:web:acct', {}), { - 'doc': 'The account that the query was issued as.', - }), + 'doc': 'The account that the query was issued as.'}), + ('host', ('it:host', {}), { - 'doc': 'The host that issued the query.', - }), + 'doc': 'The host that issued the query.'}), + ('engine', ('str', {'lower': True}), { 'ex': 'google', - 'doc': 'A simple name for the search engine used.', - }), + 'doc': 'A simple name for the search engine used.'}), + ('request', ('inet:http:request', {}), { 'doc': 'The HTTP request used to issue the query.'}), )), + # FIXME eliminate? ('inet:search:result', {}, ( ('query', ('inet:search:query', {}), { @@ -2784,787 +2816,778 @@ def getModelDefs(self): )), - ('inet:web:acct', {}, ( - ('avatar', ('file:bytes', {}), { - 'doc': 'The file representing the avatar (e.g., profile picture) for the account.' - }), - ('banner', ('file:bytes', {}), { - 'doc': 'The file representing the banner for the account.' - }), - ('dob', ('time', {}), { - 'doc': 'A self-declared date of birth for the account (if the account belongs to a person).' - }), - ('email', ('inet:email', {}), { - 'doc': 'The email address associated with the account.' - }), - ('linked:accts', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True}), { - 'doc': 'Linked accounts specified in the account profile.', - }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The last known latitude/longitude for the node.' - }), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place associated with the latlong property.' - }), - ('loc', ('loc', {}), { - 'doc': 'A self-declared location for the account.' - }), - ('name', ('inet:user', {}), { - 'doc': 'The localized name associated with the account (may be different from the ' - 'account identifier, e.g., a display name).' - }), - ('name:en', ('inet:user', {}), { - 'doc': 'The English version of the name associated with the (may be different from ' - 'the account identifier, e.g., a display name).', - 'deprecated': True, - }), - ('aliases', ('array', {'type': 'inet:user', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of alternate names for the user.', - }), - ('occupation', ('str', {'lower': True}), { - 'doc': 'A self-declared occupation for the account.' - }), - ('passwd', ('inet:passwd', {}), { - 'doc': 'The current password for the account.' + #('inet:web:acct', {}, ( + # ('avatar', ('file:bytes', {}), { + # 'doc': 'The file representing the avatar (e.g., profile picture) for the account.' + # }), + # ('banner', ('file:bytes', {}), { + # 'doc': 'The file representing the banner for the account.' + # }), + # ('dob', ('time', {}), { + # 'doc': 'A self-declared date of birth for the account (if the account belongs to a person).' + # }), + # ('email', ('inet:email', {}), { + # 'doc': 'The email address associated with the account.' + # }), + # ('linked:accts', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True}), { + # 'doc': 'Linked accounts specified in the account profile.', + # }), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The last known latitude/longitude for the node.' + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place associated with the latlong property.' + # }), + # ('loc', ('loc', {}), { + # 'doc': 'A self-declared location for the account.' + # }), + # ('name', ('inet:user', {}), { + # 'doc': 'The localized name associated with the account (may be different from the ' + # 'account identifier, e.g., a display name).' + # }), + # ('name:en', ('inet:user', {}), { + # 'doc': 'The English version of the name associated with the (may be different from ' + # 'the account identifier, e.g., a display name).', + # 'deprecated': True, + # }), + # ('aliases', ('array', {'type': 'inet:user', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of alternate names for the user.', + # }), + # ('occupation', ('str', {'lower': True}), { + # 'doc': 'A self-declared occupation for the account.' + # }), + # ('passwd', ('inet:passwd', {}), { + # 'doc': 'The current password for the account.' + # }), + # ('phone', ('tel:phone', {}), { + # 'doc': 'The phone number associated with the account.' + # }), + # ('realname', ('ps:name', {}), { + # 'doc': 'The localized version of the real name of the account owner / registrant.' + # }), + # ('realname:en', ('ps:name', {}), { + # 'doc': 'The English version of the real name of the account owner / registrant.', + # 'deprecated': True, + # }), + # ('signup', ('time', {}), { + # 'doc': 'The date and time the account was registered.' + # }), + # ('signup:client', ('inet:client', {}), { + # 'doc': 'The client address used to sign up for the account.' + # }), + # ('signup:client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 address used to sign up for the account.' + # }), + # ('signup:client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 address used to sign up for the account.' + # }), + # ('site', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The site or service associated with the account.' + # }), + # ('tagline', ('str', {}), { + # 'doc': 'The text of the account status or tag line.' + # }), + # ('url', ('inet:url', {}), { + # 'doc': 'The service provider URL where the account is hosted.' + # }), + # ('user', ('inet:user', {}), { + # 'ro': True, + # 'doc': 'The unique identifier for the account (may be different from the common ' + # 'name or display name).' + # }), + # ('webpage', ('inet:url', {}), { + # 'doc': 'A related URL specified by the account (e.g., a personal or company web ' + # 'page, blog, etc.).' + # }), + # ('recovery:email', ('inet:email', {}), { + # 'doc': 'An email address registered as a recovery email address for the account.', + # }), + #)), + + #('inet:web:action', {}, ( + # ('act', ('str', {'lower': True, 'strip': True}), { + # 'doc': 'The action performed by the account.' + # }), + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The web account associated with the action.' + # }), + # ('acct:site', ('inet:fqdn', {}), { + # 'doc': 'The site or service associated with the account.' + # }), + # ('acct:user', ('inet:user', {}), { + # 'doc': 'The unique identifier for the account.' + # }), + # ('time', ('time', {}), { + # 'doc': 'The date and time the account performed the action.' + # }), + # ('client', ('inet:client', {}), { + # 'doc': 'The source client address of the action.' + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address of the action.' + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address of the action.' + # }), + # ('loc', ('loc', {}), { + # 'doc': 'The location of the user executing the web action.', + # }), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The latlong of the user when executing the web action.', + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place of the user when executing the web action.', + # }), + #)), + + #('inet:web:chprofile', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The web account associated with the change.' + # }), + # ('acct:site', ('inet:fqdn', {}), { + # 'doc': 'The site or service associated with the account.' + # }), + # ('acct:user', ('inet:user', {}), { + # 'doc': 'The unique identifier for the account.' + # }), + # ('client', ('inet:client', {}), { + # 'doc': 'The source address used to make the account change.' + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address used to make the account change.' + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address used to make the account change.' + # }), + # ('time', ('time', {}), { + # 'doc': 'The date and time when the account change occurred.' + # }), + # ('pv', ('nodeprop', {}), { + # 'doc': 'The prop=valu of the account property that was changed. Valu should be ' + # 'the old / original value, while the new value should be updated on the ' + # 'inet:web:acct form.'}), + # ('pv:prop', ('str', {}), { + # 'doc': 'The property that was changed.' + # }), + #)), + + #('inet:web:file', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The account that owns or is associated with the file.' + # }), + # ('acct:site', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The site or service associated with the account.' + # }), + # ('acct:user', ('inet:user', {}), { + # 'ro': True, + # 'doc': 'The unique identifier for the account.' + # }), + # ('file', ('file:bytes', {}), { + # 'ro': True, + # 'doc': 'The file owned by or associated with the account.' + # }), + # ('name', ('file:base', {}), { + # 'doc': 'The name of the file owned by or associated with the account.' + # }), + # ('posted', ('time', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), + + # ('client', ('inet:client', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), + + # ('client:ipv4', ('inet:ipv4', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), + + # ('client:ipv6', ('inet:ipv6', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), + #)), + + #('inet:web:attachment', {}, ( + + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The account that uploaded the file.'}), + + # ('post', ('inet:web:post', {}), { + # 'doc': 'The optional web post that the file was attached to.'}), + + # ('mesg', ('inet:web:mesg', {}), { + # 'doc': 'The optional web message that the file was attached to.'}), + + # ('proto', ('inet:proto', {}), { + # 'ex': 'https', + # 'doc': 'The protocol used to transmit the file to the web service.'}), + + # ('interactive', ('bool', {}), { + # 'doc': 'Set to true if the upload was interactive. False if automated.'}), + + # ('file', ('file:bytes', {}), { + # 'doc': 'The file that was sent.'}), + + # ('name', ('file:path', {}), { + # 'doc': 'The name of the file at the time it was sent.'}), + + # ('time', ('time', {}), { + # 'doc': 'The time the file was sent.'}), + + # ('client', ('inet:client', {}), { + # 'doc': 'The client address which initiated the upload.'}), + + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 address of the client that initiated the upload.'}), + + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 address of the client that initiated the upload.'}), + + # ('place', ('geo:place', {}), { + # 'doc': 'The place the file was sent from.'}), + + # ('place:loc', ('loc', {}), { + # 'doc': 'The geopolitical location that the file was sent from.'}), + + # ('place:name', ('geo:name', {}), { + # 'doc': 'The reported name of the place that the file was sent from.'}), + #)), + + #('inet:web:follows', {}, ( + # ('follower', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The account following an account.' + # }), + # ('followee', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The account followed by an account.' + # }), + #)), + + #('inet:web:group', {}, ( + # ('site', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The site or service associated with the group.' + # }), + # ('id', ('inet:group', {}), { + # 'ro': True, + # 'doc': 'The site-specific unique identifier for the group (may be different from ' + # 'the common name or display name).' + # }), + # ('name', ('inet:group', {}), { + # 'doc': 'The localized name associated with the group (may be different from ' + # 'the account identifier, e.g., a display name).' + # }), + # ('aliases', ('array', {'type': 'inet:group', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of alternate names for the group.', + # }), + # ('name:en', ('inet:group', {}), { + # 'doc': 'The English version of the name associated with the group (may be different ' + # 'from the localized name).', + # 'deprecated': True, + # }), + # ('url', ('inet:url', {}), { + # 'doc': 'The service provider URL where the group is hosted.' + # }), + # ('avatar', ('file:bytes', {}), { + # 'doc': 'The file representing the avatar (e.g., profile picture) for the group.' + # }), + # ('desc', ('str', {}), { + # 'doc': 'The text of the description of the group.' + # }), + # ('webpage', ('inet:url', {}), { + # 'doc': 'A related URL specified by the group (e.g., primary web site, etc.).' + # }), + # ('loc', ('str', {'lower': True}), { + # 'doc': 'A self-declared location for the group.' + # }), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The last known latitude/longitude for the node.' + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place associated with the latlong property.' + # }), + # ('signup', ('time', {}), { + # 'doc': 'The date and time the group was created on the site.' + # }), + # ('signup:client', ('inet:client', {}), { + # 'doc': 'The client address used to create the group.' + # }), + # ('signup:client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 address used to create the group.' + # }), + # ('signup:client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 address used to create the group.' + # }), + #)), + + #('inet:web:logon', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The web account associated with the logon event.' + # }), + # ('acct:site', ('inet:fqdn', {}), { + # 'doc': 'The site or service associated with the account.' + # }), + # ('acct:user', ('inet:user', {}), { + # 'doc': 'The unique identifier for the account.' + # }), + # ('time', ('time', {}), { + # 'doc': 'The date and time the account logged into the service.' + # }), + # ('client', ('inet:client', {}), { + # 'doc': 'The source address of the logon.' + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address of the logon.' + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address of the logon.' + # }), + # ('logout', ('time', {}), { + # 'doc': 'The date and time the account logged out of the service.' + # }), + # ('loc', ('loc', {}), { + # 'doc': 'The location of the user executing the logon.', + # }), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The latlong of the user executing the logon.', + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The geo:place of the user executing the logon.', + # }), + #)), + + #('inet:web:memb', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The account that is a member of the group.' + # }), + # ('group', ('inet:web:group', {}), { + # 'ro': True, + # 'doc': 'The group that the account is a member of.' + # }), + # ('title', ('str', {'lower': True}), { + # 'doc': 'The title or status of the member (e.g., admin, new member, etc.).' + # }), + # ('joined', ('time', {}), { + # 'doc': 'The date / time the account joined the group.' + # }), + #)), + #('inet:web:member', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The account that is a member of the group or channel.' + # }), + # ('group', ('inet:web:group', {}), { + # 'doc': 'The group that the account is a member of.' + # }), + # ('channel', ('inet:web:channel', {}), { + # 'doc': 'The channel that the account is a member of.' + # }), + # ('added', ('time', {}), { + # 'doc': 'The date / time the account was added to the group or channel.' + # }), + # ('removed', ('time', {}), { + # 'doc': 'The date / time the account was removed from the group or channel.' + # }), + #)), + #('inet:web:mesg', {}, ( + # ('from', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The web account that sent the message.' + # }), + # ('to', ('inet:web:acct', {}), { + # 'ro': True, + # 'doc': 'The web account that received the message.' + # }), + # ('client', ('inet:client', {}), { + # 'doc': 'The source address of the message.' + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address of the message.' + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address of the message.' + # }), + # ('time', ('time', {}), { + # 'ro': True, + # 'doc': 'The date and time at which the message was sent.' + # }), + # ('url', ('inet:url', {}), { + # 'doc': 'The URL where the message is posted / visible.' + # }), + # ('text', ('str', {}), { + # 'doc': 'The text of the message.', + # 'disp': {'hint': 'text'}, + # }), + # ('deleted', ('bool', {}), { + # 'doc': 'The message was deleted.', + # }), + # ('file', ('file:bytes', {}), { + # 'doc': 'The file attached to or sent with the message.' + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The place that the message was reportedly sent from.', + # }), + # ('place:name', ('geo:name', {}), { + # 'doc': 'The name of the place that the message was reportedly sent from. Used for entity resolution.', + # }), + # ('instance', ('inet:web:instance', {}), { + # 'doc': 'The instance where the message was sent.', + # }), + #)), + + #('inet:web:post', {}, ( + # ('acct', ('inet:web:acct', {}), { + # 'doc': 'The web account that made the post.' + # }), + # ('acct:site', ('inet:fqdn', {}), { + # 'doc': 'The site or service associated with the account.' + # }), + # ('client', ('inet:client', {}), { + # 'doc': 'The source address of the post.' + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address of the post.' + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address of the post.' + # }), + # ('acct:user', ('inet:user', {}), { + # 'doc': 'The unique identifier for the account.' + # }), + # ('text', ('str', {}), { + # 'doc': 'The text of the post.', + # 'disp': {'hint': 'text'}, + # }), + # ('time', ('time', {}), { + # 'doc': 'The date and time that the post was made.' + # }), + # ('deleted', ('bool', {}), { + # 'doc': 'The message was deleted by the poster.', + # }), + # ('url', ('inet:url', {}), { + # 'doc': 'The URL where the post is published / visible.' + # }), + # ('file', ('file:bytes', {}), { + # 'doc': 'The file that was attached to the post.' + # }), + # ('replyto', ('inet:web:post', {}), { + # 'doc': 'The post that this post is in reply to.' + # }), + # ('repost', ('inet:web:post', {}), { + # 'doc': 'The original post that this is a repost of.' + # }), + # ('hashtags', ('array', {'type': 'inet:web:hashtag', 'uniq': True, 'sorted': True, 'split': ','}), { + # 'doc': 'Hashtags mentioned within the post.', + # }), + # ('mentions:users', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True, 'split': ','}), { + # 'doc': 'Accounts mentioned within the post.', + # }), + # ('mentions:groups', ('array', {'type': 'inet:web:group', 'uniq': True, 'sorted': True, 'split': ','}), { + # 'doc': 'Groups mentioned within the post.', + # }), + # # location protocol... + # ('loc', ('loc', {}), { + # 'doc': 'The location that the post was reportedly sent from.', + # }), + # ('place', ('geo:place', {}), { + # 'doc': 'The place that the post was reportedly sent from.', + # }), + # ('place:name', ('geo:name', {}), { + # 'doc': 'The name of the place that the post was reportedly sent from. Used for entity resolution.', + # }), + # ('latlong', ('geo:latlong', {}), { + # 'doc': 'The place that the post was reportedly sent from.', + # }), + # ('channel', ('inet:web:channel', {}), { + # 'doc': 'The channel where the post was made.', + # }), + #)), + + #('inet:web:post:link', {}, ( + # ('post', ('inet:web:post', {}), { + # 'doc': 'The post containing the embedded link.'}), + # ('url', ('inet:url', {}), { + # 'doc': 'The url that the link forwards to.'}), + # ('text', ('str', {}), { + # 'doc': 'The displayed hyperlink text if it was not the raw URL.'}), + #)), + + #('inet:web:instance', {}, ( + # ('url', ('inet:url', {}), { + # 'ex': 'https://app.slack.com/client/T2XK1223Y', + # 'doc': 'The primary URL used to identify the instance.', + # }), + # ('id', ('str', {'strip': True}), { + # 'ex': 'T2XK1223Y', + # 'doc': 'The operator specified ID of this instance.', + # }), + # ('name', ('str', {'strip': True}), { + # 'ex': 'vertex synapse', + # 'doc': 'The visible name of the instance.', + # }), + # ('created', ('time', {}), { + # 'doc': 'The time the instance was created.', + # }), + # ('creator', ('inet:web:acct', {}), { + # 'doc': 'The account which created the instance.', + # }), + # ('owner', ('ou:org', {}), { + # 'doc': 'The organization which created the instance.', + # }), + # ('owner:fqdn', ('inet:fqdn', {}), { + # 'ex': 'vertex.link', + # 'doc': 'The FQDN of the organization which created the instance. Used for entity resolution.', + # }), + # ('owner:name', ('ou:name', {}), { + # 'ex': 'the vertex project, llc.', + # 'doc': 'The name of the organization which created the instance. Used for entity resolution.', + # }), + # ('operator', ('ou:org', {}), { + # 'doc': 'The organization which operates the instance.', + # }), + # ('operator:name', ('ou:name', {}), { + # 'ex': 'slack', + # 'doc': 'The name of the organization which operates the instance. Used for entity resolution.', + # }), + # ('operator:fqdn', ('inet:fqdn', {}), { + # 'ex': 'slack.com', + # 'doc': 'The FQDN of the organization which operates the instance. Used for entity resolution.', + # }), + #)), + + #('inet:web:channel', {}, ( + # ('url', ('inet:url', {}), { + # 'ex': 'https://app.slack.com/client/T2XK1223Y/C2XHHNDS7', + # 'doc': 'The primary URL used to identify the channel.', + # }), + # ('id', ('str', {'strip': True}), { + # 'ex': 'C2XHHNDS7', + # 'doc': 'The operator specified ID of this channel.'}), + # ('instance', ('inet:web:instance', {}), { + # 'doc': 'The instance which contains the channel.', + # }), + # ('name', ('str', {'strip': True}), { + # 'ex': 'general', + # 'doc': 'The visible name of the channel.', + # }), + # ('topic', ('str', {'strip': True}), { + # 'ex': 'Synapse Discussion - Feel free to invite others!', + # 'doc': 'The visible topic of the channel.', + # }), + # ('created', ('time', {}), { + # 'doc': 'The time the channel was created.', + # }), + # ('creator', ('inet:web:acct', {}), { + # 'doc': 'The account which created the channel.', + # }), + #)), + + # FIXME rename? ( last surviving inet:web:* + ('inet:web:hashtag', {}, ()), + + #('inet:whois:contact', {}, ( + # ('rec', ('inet:whois:rec', {}), { + # 'ro': True, + # 'doc': 'The whois record containing the contact data.' + # }), + # ('rec:fqdn', ('inet:fqdn', {}), { + # 'ro': True, + # 'doc': 'The domain associated with the whois record.' + # }), + # ('rec:asof', ('time', {}), { + # 'ro': True, + # 'doc': 'The date of the whois record.' + # }), + # ('type', ('str', {'lower': True}), { + # 'doc': 'The contact type (e.g., registrar, registrant, admin, billing, tech, etc.).', + # 'ro': True, + # }), + # ('id', ('str', {'lower': True}), { + # 'doc': 'The ID associated with the contact.' + # }), + # ('name', ('str', {'lower': True}), { + # 'doc': 'The name of the contact.' + # }), + # ('email', ('inet:email', {}), { + # 'doc': 'The email address of the contact.' + # }), + # ('orgname', ('ou:name', {}), { + # 'doc': 'The name of the contact organization.' + # }), + # ('address', ('str', {'lower': True}), { + # 'doc': 'The content of the street address field(s) of the contact.' + # }), + # ('city', ('str', {'lower': True}), { + # 'doc': 'The content of the city field of the contact.' + # }), + # ('state', ('str', {'lower': True}), { + # 'doc': 'The content of the state field of the contact.' + # }), + # ('country', ('str', {'lower': True}), { + # 'doc': 'The two-letter country code of the contact.' + # }), + # ('phone', ('tel:phone', {}), { + # 'doc': 'The content of the phone field of the contact.' + # }), + # ('fax', ('tel:phone', {}), { + # 'doc': 'The content of the fax field of the contact.' + # }), + # ('url', ('inet:url', {}), { + # 'doc': 'The URL specified for the contact.' + # }), + # ('whois:fqdn', ('inet:fqdn', {}), { + # 'doc': 'The whois server FQDN for the given contact (most likely a registrar).' + # }), + #)), + + #('inet:whois:rar', {}, ()), + + # FIXME migrate to guid + ('inet:whois:rec', {}, ( + ('fqdn', ('inet:fqdn', {}), { + 'ro': True, + 'doc': 'The domain associated with the whois record.' }), - ('phone', ('tel:phone', {}), { - 'doc': 'The phone number associated with the account.' + ('asof', ('time', {}), { + 'ro': True, + 'doc': 'The date of the whois record.' }), - ('realname', ('ps:name', {}), { - 'doc': 'The localized version of the real name of the account owner / registrant.' + ('text', ('str', {'lower': True}), { + 'doc': 'The full text of the whois record.', + 'disp': {'hint': 'text'}, }), - ('realname:en', ('ps:name', {}), { - 'doc': 'The English version of the real name of the account owner / registrant.', - 'deprecated': True, + ('created', ('time', {}), { + 'doc': 'The "created" time from the whois record.' }), - ('signup', ('time', {}), { - 'doc': 'The date and time the account was registered.' + ('updated', ('time', {}), { + 'doc': 'The "last updated" time from the whois record.' }), - ('signup:client', ('inet:client', {}), { - 'doc': 'The client address used to sign up for the account.' + ('expires', ('time', {}), { + 'doc': 'The "expires" time from the whois record.' }), - ('signup:client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 address used to sign up for the account.' + #('registrar', ('inet:whois:rar', {}), { + ('registrar', ('entity:name', {}), { + 'doc': 'The registrar name from the whois record.' }), - ('signup:client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 address used to sign up for the account.' + #('registrant', ('inet:whois:reg', {}), { + ('registrant', ('entity:name', {}), { + 'doc': 'The registrant name from the whois record.' }), - ('site', ('inet:fqdn', {}), { + )), + + ('inet:whois:recns', {}, ( + ('ns', ('inet:fqdn', {}), { 'ro': True, - 'doc': 'The site or service associated with the account.' + 'doc': 'A nameserver for a domain as listed in the domain whois record.' }), - ('tagline', ('str', {}), { - 'doc': 'The text of the account status or tag line.' + ('rec', ('inet:whois:rec', {}), { + 'ro': True, + 'doc': 'The whois record containing the nameserver data.' }), - ('url', ('inet:url', {}), { - 'doc': 'The service provider URL where the account is hosted.' + ('rec:fqdn', ('inet:fqdn', {}), { + 'ro': True, + 'doc': 'The domain associated with the whois record.' }), - ('user', ('inet:user', {}), { + ('rec:asof', ('time', {}), { 'ro': True, - 'doc': 'The unique identifier for the account (may be different from the common ' - 'name or display name).' - }), - ('webpage', ('inet:url', {}), { - 'doc': 'A related URL specified by the account (e.g., a personal or company web ' - 'page, blog, etc.).' - }), - ('recovery:email', ('inet:email', {}), { - 'doc': 'An email address registered as a recovery email address for the account.', + 'doc': 'The date of the whois record.' }), )), - ('inet:web:action', {}, ( - ('act', ('str', {'lower': True, 'strip': True}), { - 'doc': 'The action performed by the account.' - }), - ('acct', ('inet:web:acct', {}), { - 'doc': 'The web account associated with the action.' - }), - ('acct:site', ('inet:fqdn', {}), { - 'doc': 'The site or service associated with the account.' - }), - ('acct:user', ('inet:user', {}), { - 'doc': 'The unique identifier for the account.' - }), - ('time', ('time', {}), { - 'doc': 'The date and time the account performed the action.' - }), - ('client', ('inet:client', {}), { - 'doc': 'The source client address of the action.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address of the action.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address of the action.' - }), - ('loc', ('loc', {}), { - 'doc': 'The location of the user executing the web action.', - }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The latlong of the user when executing the web action.', - }), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place of the user when executing the web action.', - }), - )), + #('inet:whois:reg', {}, ()), - ('inet:web:chprofile', {}, ( - ('acct', ('inet:web:acct', {}), { - 'doc': 'The web account associated with the change.' - }), - ('acct:site', ('inet:fqdn', {}), { - 'doc': 'The site or service associated with the account.' - }), - ('acct:user', ('inet:user', {}), { - 'doc': 'The unique identifier for the account.' - }), - ('client', ('inet:client', {}), { - 'doc': 'The source address used to make the account change.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address used to make the account change.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address used to make the account change.' - }), - ('time', ('time', {}), { - 'doc': 'The date and time when the account change occurred.' - }), - ('pv', ('nodeprop', {}), { - 'doc': 'The prop=valu of the account property that was changed. Valu should be ' - 'the old / original value, while the new value should be updated on the ' - 'inet:web:acct form.'}), - ('pv:prop', ('str', {}), { - 'doc': 'The property that was changed.' - }), - )), + # FIXME still want? + #('inet:whois:email', {}, ( + # ('fqdn', ('inet:fqdn', {}), {'ro': True, + # 'doc': 'The domain with a whois record containing the email address.', + # }), + # ('email', ('inet:email', {}), {'ro': True, + # 'doc': 'The email address associated with the domain whois record.', + # }), + #)), - ('inet:web:file', {}, ( - ('acct', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The account that owns or is associated with the file.' - }), - ('acct:site', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The site or service associated with the account.' - }), - ('acct:user', ('inet:user', {}), { - 'ro': True, - 'doc': 'The unique identifier for the account.' - }), - ('file', ('file:bytes', {}), { - 'ro': True, - 'doc': 'The file owned by or associated with the account.' - }), - ('name', ('file:base', {}), { - 'doc': 'The name of the file owned by or associated with the account.' - }), - ('posted', ('time', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), - - ('client', ('inet:client', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), - - ('client:ipv4', ('inet:ipv4', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), - - ('client:ipv6', ('inet:ipv6', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Instance data belongs on inet:web:attachment.'}), - )), - - ('inet:web:attachment', {}, ( - - ('acct', ('inet:web:acct', {}), { - 'doc': 'The account that uploaded the file.'}), - - ('post', ('inet:web:post', {}), { - 'doc': 'The optional web post that the file was attached to.'}), - - ('mesg', ('inet:web:mesg', {}), { - 'doc': 'The optional web message that the file was attached to.'}), - - ('proto', ('inet:proto', {}), { - 'ex': 'https', - 'doc': 'The protocol used to transmit the file to the web service.'}), - - ('interactive', ('bool', {}), { - 'doc': 'Set to true if the upload was interactive. False if automated.'}), - - ('file', ('file:bytes', {}), { - 'doc': 'The file that was sent.'}), - - ('name', ('file:path', {}), { - 'doc': 'The name of the file at the time it was sent.'}), - - ('time', ('time', {}), { - 'doc': 'The time the file was sent.'}), - - ('client', ('inet:client', {}), { - 'doc': 'The client address which initiated the upload.'}), - - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 address of the client that initiated the upload.'}), - - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 address of the client that initiated the upload.'}), - - ('place', ('geo:place', {}), { - 'doc': 'The place the file was sent from.'}), - - ('place:loc', ('loc', {}), { - 'doc': 'The geopolitical location that the file was sent from.'}), - - ('place:name', ('geo:name', {}), { - 'doc': 'The reported name of the place that the file was sent from.'}), - )), - - ('inet:web:follows', {}, ( - ('follower', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The account following an account.' - }), - ('followee', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The account followed by an account.' - }), - )), - - ('inet:web:group', {}, ( - ('site', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The site or service associated with the group.' - }), - ('id', ('inet:group', {}), { - 'ro': True, - 'doc': 'The site-specific unique identifier for the group (may be different from ' - 'the common name or display name).' - }), - ('name', ('inet:group', {}), { - 'doc': 'The localized name associated with the group (may be different from ' - 'the account identifier, e.g., a display name).' - }), - ('aliases', ('array', {'type': 'inet:group', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of alternate names for the group.', - }), - ('name:en', ('inet:group', {}), { - 'doc': 'The English version of the name associated with the group (may be different ' - 'from the localized name).', - 'deprecated': True, - }), - ('url', ('inet:url', {}), { - 'doc': 'The service provider URL where the group is hosted.' - }), - ('avatar', ('file:bytes', {}), { - 'doc': 'The file representing the avatar (e.g., profile picture) for the group.' - }), - ('desc', ('str', {}), { - 'doc': 'The text of the description of the group.' - }), - ('webpage', ('inet:url', {}), { - 'doc': 'A related URL specified by the group (e.g., primary web site, etc.).' - }), - ('loc', ('str', {'lower': True}), { - 'doc': 'A self-declared location for the group.' - }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The last known latitude/longitude for the node.' - }), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place associated with the latlong property.' - }), - ('signup', ('time', {}), { - 'doc': 'The date and time the group was created on the site.' - }), - ('signup:client', ('inet:client', {}), { - 'doc': 'The client address used to create the group.' - }), - ('signup:client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 address used to create the group.' - }), - ('signup:client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 address used to create the group.' - }), - )), - - ('inet:web:logon', {}, ( - ('acct', ('inet:web:acct', {}), { - 'doc': 'The web account associated with the logon event.' - }), - ('acct:site', ('inet:fqdn', {}), { - 'doc': 'The site or service associated with the account.' - }), - ('acct:user', ('inet:user', {}), { - 'doc': 'The unique identifier for the account.' - }), - ('time', ('time', {}), { - 'doc': 'The date and time the account logged into the service.' - }), - ('client', ('inet:client', {}), { - 'doc': 'The source address of the logon.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address of the logon.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address of the logon.' - }), - ('logout', ('time', {}), { - 'doc': 'The date and time the account logged out of the service.' - }), - ('loc', ('loc', {}), { - 'doc': 'The location of the user executing the logon.', - }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The latlong of the user executing the logon.', - }), - ('place', ('geo:place', {}), { - 'doc': 'The geo:place of the user executing the logon.', - }), - )), - - ('inet:web:memb', {}, ( - ('acct', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The account that is a member of the group.' - }), - ('group', ('inet:web:group', {}), { - 'ro': True, - 'doc': 'The group that the account is a member of.' - }), - ('title', ('str', {'lower': True}), { - 'doc': 'The title or status of the member (e.g., admin, new member, etc.).' - }), - ('joined', ('time', {}), { - 'doc': 'The date / time the account joined the group.' - }), - )), - ('inet:web:member', {}, ( - ('acct', ('inet:web:acct', {}), { - 'doc': 'The account that is a member of the group or channel.' - }), - ('group', ('inet:web:group', {}), { - 'doc': 'The group that the account is a member of.' - }), - ('channel', ('inet:web:channel', {}), { - 'doc': 'The channel that the account is a member of.' - }), - ('added', ('time', {}), { - 'doc': 'The date / time the account was added to the group or channel.' - }), - ('removed', ('time', {}), { - 'doc': 'The date / time the account was removed from the group or channel.' - }), - )), - ('inet:web:mesg', {}, ( - ('from', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The web account that sent the message.' - }), - ('to', ('inet:web:acct', {}), { - 'ro': True, - 'doc': 'The web account that received the message.' - }), - ('client', ('inet:client', {}), { - 'doc': 'The source address of the message.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address of the message.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address of the message.' - }), - ('time', ('time', {}), { - 'ro': True, - 'doc': 'The date and time at which the message was sent.' - }), - ('url', ('inet:url', {}), { - 'doc': 'The URL where the message is posted / visible.' - }), - ('text', ('str', {}), { - 'doc': 'The text of the message.', - 'disp': {'hint': 'text'}, - }), - ('deleted', ('bool', {}), { - 'doc': 'The message was deleted.', - }), - ('file', ('file:bytes', {}), { - 'doc': 'The file attached to or sent with the message.' - }), - ('place', ('geo:place', {}), { - 'doc': 'The place that the message was reportedly sent from.', - }), - ('place:name', ('geo:name', {}), { - 'doc': 'The name of the place that the message was reportedly sent from. Used for entity resolution.', - }), - ('instance', ('inet:web:instance', {}), { - 'doc': 'The instance where the message was sent.', - }), - )), + ('inet:whois:ipquery', {}, ( - ('inet:web:post', {}, ( - ('acct', ('inet:web:acct', {}), { - 'doc': 'The web account that made the post.' - }), - ('acct:site', ('inet:fqdn', {}), { - 'doc': 'The site or service associated with the account.' - }), - ('client', ('inet:client', {}), { - 'doc': 'The source address of the post.' - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address of the post.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address of the post.' - }), - ('acct:user', ('inet:user', {}), { - 'doc': 'The unique identifier for the account.' - }), - ('text', ('str', {}), { - 'doc': 'The text of the post.', - 'disp': {'hint': 'text'}, - }), ('time', ('time', {}), { - 'doc': 'The date and time that the post was made.' - }), - ('deleted', ('bool', {}), { - 'doc': 'The message was deleted by the poster.', - }), - ('url', ('inet:url', {}), { - 'doc': 'The URL where the post is published / visible.' - }), - ('file', ('file:bytes', {}), { - 'doc': 'The file that was attached to the post.' - }), - ('replyto', ('inet:web:post', {}), { - 'doc': 'The post that this post is in reply to.' - }), - ('repost', ('inet:web:post', {}), { - 'doc': 'The original post that this is a repost of.' - }), - ('hashtags', ('array', {'type': 'inet:web:hashtag', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'Hashtags mentioned within the post.', - }), - ('mentions:users', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'Accounts mentioned within the post.', - }), - ('mentions:groups', ('array', {'type': 'inet:web:group', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'Groups mentioned within the post.', - }), - # location protocol... - ('loc', ('loc', {}), { - 'doc': 'The location that the post was reportedly sent from.', - }), - ('place', ('geo:place', {}), { - 'doc': 'The place that the post was reportedly sent from.', - }), - ('place:name', ('geo:name', {}), { - 'doc': 'The name of the place that the post was reportedly sent from. Used for entity resolution.', - }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The place that the post was reportedly sent from.', - }), - ('channel', ('inet:web:channel', {}), { - 'doc': 'The channel where the post was made.', - }), - )), + 'doc': 'The time the request was made.'}), - ('inet:web:post:link', {}, ( - ('post', ('inet:web:post', {}), { - 'doc': 'The post containing the embedded link.'}), ('url', ('inet:url', {}), { - 'doc': 'The url that the link forwards to.'}), - ('text', ('str', {}), { - 'doc': 'The displayed hyperlink text if it was not the raw URL.'}), - )), + 'doc': 'The query URL when using the HTTP RDAP Protocol.'}), - ('inet:web:instance', {}, ( - ('url', ('inet:url', {}), { - 'ex': 'https://app.slack.com/client/T2XK1223Y', - 'doc': 'The primary URL used to identify the instance.', - }), - ('id', ('str', {'strip': True}), { - 'ex': 'T2XK1223Y', - 'doc': 'The operator specified ID of this instance.', - }), - ('name', ('str', {'strip': True}), { - 'ex': 'vertex synapse', - 'doc': 'The visible name of the instance.', - }), - ('created', ('time', {}), { - 'doc': 'The time the instance was created.', - }), - ('creator', ('inet:web:acct', {}), { - 'doc': 'The account which created the instance.', - }), - ('owner', ('ou:org', {}), { - 'doc': 'The organization which created the instance.', - }), - ('owner:fqdn', ('inet:fqdn', {}), { - 'ex': 'vertex.link', - 'doc': 'The FQDN of the organization which created the instance. Used for entity resolution.', - }), - ('owner:name', ('ou:name', {}), { - 'ex': 'the vertex project, llc.', - 'doc': 'The name of the organization which created the instance. Used for entity resolution.', - }), - ('operator', ('ou:org', {}), { - 'doc': 'The organization which operates the instance.', - }), - ('operator:name', ('ou:name', {}), { - 'ex': 'slack', - 'doc': 'The name of the organization which operates the instance. Used for entity resolution.', - }), - ('operator:fqdn', ('inet:fqdn', {}), { - 'ex': 'slack.com', - 'doc': 'The FQDN of the organization which operates the instance. Used for entity resolution.', - }), - )), - - ('inet:web:channel', {}, ( - ('url', ('inet:url', {}), { - 'ex': 'https://app.slack.com/client/T2XK1223Y/C2XHHNDS7', - 'doc': 'The primary URL used to identify the channel.', - }), - ('id', ('str', {'strip': True}), { - 'ex': 'C2XHHNDS7', - 'doc': 'The operator specified ID of this channel.'}), - ('instance', ('inet:web:instance', {}), { - 'doc': 'The instance which contains the channel.', - }), - ('name', ('str', {'strip': True}), { - 'ex': 'general', - 'doc': 'The visible name of the channel.', - }), - ('topic', ('str', {'strip': True}), { - 'ex': 'Synapse Discussion - Feel free to invite others!', - 'doc': 'The visible topic of the channel.', - }), - ('created', ('time', {}), { - 'doc': 'The time the channel was created.', - }), - ('creator', ('inet:web:acct', {}), { - 'doc': 'The account which created the channel.', - }), - )), - - ('inet:web:hashtag', {}, ()), - - ('inet:whois:contact', {}, ( - ('rec', ('inet:whois:rec', {}), { - 'ro': True, - 'doc': 'The whois record containing the contact data.' - }), - ('rec:fqdn', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The domain associated with the whois record.' - }), - ('rec:asof', ('time', {}), { - 'ro': True, - 'doc': 'The date of the whois record.' - }), - ('type', ('str', {'lower': True}), { - 'doc': 'The contact type (e.g., registrar, registrant, admin, billing, tech, etc.).', - 'ro': True, - }), - ('id', ('str', {'lower': True}), { - 'doc': 'The ID associated with the contact.' - }), - ('name', ('str', {'lower': True}), { - 'doc': 'The name of the contact.' - }), - ('email', ('inet:email', {}), { - 'doc': 'The email address of the contact.' - }), - ('orgname', ('ou:name', {}), { - 'doc': 'The name of the contact organization.' - }), - ('address', ('str', {'lower': True}), { - 'doc': 'The content of the street address field(s) of the contact.' - }), - ('city', ('str', {'lower': True}), { - 'doc': 'The content of the city field of the contact.' - }), - ('state', ('str', {'lower': True}), { - 'doc': 'The content of the state field of the contact.' - }), - ('country', ('str', {'lower': True}), { - 'doc': 'The two-letter country code of the contact.' - }), - ('phone', ('tel:phone', {}), { - 'doc': 'The content of the phone field of the contact.' - }), - ('fax', ('tel:phone', {}), { - 'doc': 'The content of the fax field of the contact.' - }), - ('url', ('inet:url', {}), { - 'doc': 'The URL specified for the contact.' - }), - ('whois:fqdn', ('inet:fqdn', {}), { - 'doc': 'The whois server FQDN for the given contact (most likely a registrar).' - }), - )), - - ('inet:whois:rar', {}, ()), - - ('inet:whois:rec', {}, ( ('fqdn', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The domain associated with the whois record.' - }), - ('asof', ('time', {}), { - 'ro': True, - 'doc': 'The date of the whois record.' - }), - ('text', ('str', {'lower': True}), { - 'doc': 'The full text of the whois record.', - 'disp': {'hint': 'text'}, - }), - ('created', ('time', {}), { - 'doc': 'The "created" time from the whois record.' - }), - ('updated', ('time', {}), { - 'doc': 'The "last updated" time from the whois record.' - }), - ('expires', ('time', {}), { - 'doc': 'The "expires" time from the whois record.' - }), - ('registrar', ('inet:whois:rar', {}), { - 'doc': 'The registrar name from the whois record.' - }), - ('registrant', ('inet:whois:reg', {}), { - 'doc': 'The registrant name from the whois record.' - }), - )), - - ('inet:whois:recns', {}, ( - ('ns', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'A nameserver for a domain as listed in the domain whois record.' - }), - ('rec', ('inet:whois:rec', {}), { - 'ro': True, - 'doc': 'The whois record containing the nameserver data.' - }), - ('rec:fqdn', ('inet:fqdn', {}), { - 'ro': True, - 'doc': 'The domain associated with the whois record.' - }), - ('rec:asof', ('time', {}), { - 'ro': True, - 'doc': 'The date of the whois record.' - }), - )), - - ('inet:whois:reg', {}, ()), + 'doc': 'The FQDN of the host server when using the legacy WHOIS Protocol.'}), - ('inet:whois:email', {}, ( - ('fqdn', ('inet:fqdn', {}), {'ro': True, - 'doc': 'The domain with a whois record containing the email address.', - }), - ('email', ('inet:email', {}), {'ro': True, - 'doc': 'The email address associated with the domain whois record.', - }), - )), + ('ip', ('inet:ip', {}), { + 'doc': 'The IP address queried.'}), - ('inet:whois:ipquery', {}, ( - ('time', ('time', {}), { - 'doc': 'The time the request was made.' - }), - ('url', ('inet:url', {}), { - 'doc': 'The query URL when using the HTTP RDAP Protocol.' - }), - ('fqdn', ('inet:fqdn', {}), { - 'doc': 'The FQDN of the host server when using the legacy WHOIS Protocol.' - }), - ('ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 address queried.' - }), - ('ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 address queried.' - }), + #('ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 address queried.' + #}), + #('ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 address queried.' + #}), ('success', ('bool', {}), { - 'doc': 'Whether the host returned a valid response for the query.' - }), + 'doc': 'Set to true if the server returned a valid response.'}), + ('rec', ('inet:whois:iprec', {}), { - 'doc': 'The resulting record from the query.' - }), + 'doc': 'The resulting record from the query.'}), )), ('inet:whois:iprec', {}, ( - ('net4', ('inet:net4', {}), { - 'doc': 'The IPv4 address range assigned.' - }), - ('net4:min', ('inet:ipv4', {}), { - 'doc': 'The first IPv4 in the range assigned.' - }), - ('net4:max', ('inet:ipv4', {}), { - 'doc': 'The last IPv4 in the range assigned.' - }), - ('net6', ('inet:net6', {}), { - 'doc': 'The IPv6 address range assigned.' - }), - ('net6:min', ('inet:ipv6', {}), { - 'doc': 'The first IPv6 in the range assigned.' - }), - ('net6:max', ('inet:ipv6', {}), { - 'doc': 'The last IPv6 in the range assigned.' - }), + #('net4', ('inet:net4', {}), { + # 'doc': 'The IPv4 address range assigned.' + #}), + #('net4:min', ('inet:ipv4', {}), { + # 'doc': 'The first IPv4 in the range assigned.' + #}), + #('net4:max', ('inet:ipv4', {}), { + # 'doc': 'The last IPv4 in the range assigned.' + #}), + #('net6', ('inet:net6', {}), { + # 'doc': 'The IPv6 address range assigned.' + #}), + #('net6:min', ('inet:ipv6', {}), { + # 'doc': 'The first IPv6 in the range assigned.' + #}), + #('net6:max', ('inet:ipv6', {}), { + # 'doc': 'The last IPv6 in the range assigned.' + #}), ('asof', ('time', {}), { - 'doc': 'The date of the record.' - }), + 'doc': 'The date of the record.'}), ('created', ('time', {}), { - 'doc': 'The "created" time from the record.' - }), + 'doc': 'The "created" time from the record.'}), ('updated', ('time', {}), { - 'doc': 'The "last updated" time from the record.' - }), + 'doc': 'The "last updated" time from the record.'}), ('text', ('str', {'lower': True}), { - 'doc': 'The full text of the record.', 'disp': {'hint': 'text'}, - }), + 'doc': 'The full text of the record.'}), ('desc', ('str', {'lower': True}), { - 'doc': 'Notes concerning the record.', 'disp': {'hint': 'text'}, - }), + 'doc': 'Notes concerning the record.'}), ('asn', ('inet:asn', {}), { - 'doc': 'The associated Autonomous System Number (ASN).' - }), + 'doc': 'The associated Autonomous System Number (ASN).'}), ('id', ('inet:whois:regid', {}), { - 'doc': 'The registry unique identifier (e.g. NET-74-0-0-0-1).' - }), + 'doc': 'The registry unique identifier (e.g. NET-74-0-0-0-1).'}), ('name', ('str', {}), { - 'doc': 'The name assigned to the network by the registrant.' - }), + 'doc': 'The name assigned to the network by the registrant.'}), ('parentid', ('inet:whois:regid', {}), { - 'doc': 'The registry unique identifier of the parent whois record (e.g. NET-74-0-0-0-0).' - }), - ('registrant', ('inet:whois:ipcontact', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Add the registrant inet:whois:ipcontact to the :contacts array.' - }), + 'doc': 'The registry unique identifier of the parent whois record (e.g. NET-74-0-0-0-0).'}), ('contacts', ('array', {'type': 'inet:whois:ipcontact', 'uniq': True, 'sorted': True}), { - 'doc': 'Additional contacts from the record.', - }), + 'doc': 'Additional contacts from the record.'}), ('country', ('str', {'lower': True, 'regex': '^[a-z]{2}$'}), { - 'doc': 'The two-letter ISO 3166 country code.' - }), + 'doc': 'The two-letter ISO 3166 country code.'}), ('status', ('str', {'lower': True}), { - 'doc': 'The state of the registered network.' - }), + 'doc': 'The state of the registered network.'}), ('type', ('str', {'lower': True}), { - 'doc': 'The classification of the registered network (e.g. direct allocation).' - }), + 'doc': 'The classification of the registered network (e.g. direct allocation).'}), ('links', ('array', {'type': 'inet:url', 'uniq': True, 'sorted': True}), { - 'doc': 'URLs provided with the record.', - }), + 'doc': 'URLs provided with the record.'}), )), + # FIXME de-duplicate with entity:contact use case ('inet:whois:ipcontact', {}, ( ('contact', ('ps:contact', {}), { 'doc': 'Contact information associated with a registration.' @@ -3611,23 +3634,24 @@ def getModelDefs(self): ('bssid', ('inet:mac', {}), { 'doc': 'The MAC address for the wireless access point.', 'ro': True, }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The best known latitude/longitude for the wireless access point.'}), + # FIXME place protocol? + #('latlong', ('geo:latlong', {}), { + #'doc': 'The best known latitude/longitude for the wireless access point.'}), ('accuracy', ('geo:dist', {}), { - 'doc': 'The reported accuracy of the latlong telemetry reading.', - }), + 'doc': 'The reported accuracy of the latlong telemetry reading.'}), + ('channel', ('int', {}), { - 'doc': 'The WIFI channel that the AP was last observed operating on.', - }), + 'doc': 'The WIFI channel that the AP was last observed operating on.'}), + ('encryption', ('str', {'lower': True, 'strip': True}), { - 'doc': 'The type of encryption used by the WIFI AP such as "wpa2".', - }), + 'doc': 'The type of encryption used by the WIFI AP such as "wpa2".'}), + ('place', ('geo:place', {}), { 'doc': 'The geo:place associated with the latlong property.'}), - ('loc', ('loc', {}), { - 'doc': 'The geo-political location string for the wireless access point.'}), + #('loc', ('loc', {}), { + #'doc': 'The geo-political location string for the wireless access point.'}), ('org', ('ou:org', {}), { 'doc': 'The organization that owns/operates the access point.'}), @@ -3636,9 +3660,11 @@ def getModelDefs(self): ('inet:wifi:ssid', {}, ()), ('inet:ssl:jarmhash', {}, ( + ('ciphers', ('str', {'lower': True, 'strip': True, 'regex': '^[0-9a-f]{30}$'}), { 'ro': True, 'doc': 'The encoded cipher and TLS version of the server.'}), + ('extensions', ('str', {'lower': True, 'strip': True, 'regex': '^[0-9a-f]{32}$'}), { 'ro': True, 'doc': 'The truncated SHA256 of the TLS server extensions.'}), @@ -3647,40 +3673,52 @@ def getModelDefs(self): ('jarmhash', ('inet:ssl:jarmhash', {}), { 'ro': True, 'doc': 'The JARM hash computed from the server responses.'}), + ('server', ('inet:server', {}), { 'ro': True, 'doc': 'The server that was sampled to compute the JARM hash.'}), )), ('inet:tls:handshake', {}, ( + ('time', ('time', {}), { 'doc': 'The time the handshake was initiated.'}), + ('flow', ('inet:flow', {}), { 'doc': 'The raw inet:flow associated with the handshake.'}), + ('server', ('inet:server', {}), { 'doc': 'The TLS server during the handshake.'}), + ('server:cert', ('crypto:x509:cert', {}), { 'doc': 'The x509 certificate sent by the server during the handshake.'}), + ('server:fingerprint:ja3', ('hash:md5', {}), { 'doc': 'The JA3S finger of the server.'}), + ('client', ('inet:client', {}), { 'doc': 'The TLS client during the handshake.'}), + ('client:cert', ('crypto:x509:cert', {}), { 'doc': 'The x509 certificate sent by the client during the handshake.'}), + ('client:fingerprint:ja3', ('hash:md5', {}), { 'doc': 'The JA3 fingerprint of the client.'}), )), ('inet:tls:ja3s:sample', {}, ( + ('server', ('inet:server', {}), { 'ro': True, 'doc': 'The server that was sampled to produce the JA3S hash.'}), + ('ja3s', ('hash:md5', {}), { 'ro': True, 'doc': "The JA3S hash computed from the server's TLS hello packet."}) )), ('inet:tls:ja3:sample', {}, ( + ('client', ('inet:client', {}), { 'ro': True, 'doc': 'The client that was sampled to produce the JA3 hash.'}), @@ -3690,9 +3728,11 @@ def getModelDefs(self): )), ('inet:tls:servercert', {}, ( + ('server', ('inet:server', {}), { 'ro': True, 'doc': 'The server associated with the x509 certificate.'}), + ('cert', ('crypto:x509:cert', {}), { 'ro': True, 'doc': 'The x509 certificate sent by the server.'}) @@ -3702,10 +3742,12 @@ def getModelDefs(self): ('client', ('inet:client', {}), { 'ro': True, 'doc': 'The client associated with the x509 certificate.'}), + ('cert', ('crypto:x509:cert', {}), { 'ro': True, 'doc': 'The x509 certificate sent by the client.'}) )), + ('inet:service:platform', {}, ( ('url', ('inet:url', {}), { diff --git a/synapse/models/infotech.py b/synapse/models/infotech.py index 8ebe72b091..159b6eb04b 100644 --- a/synapse/models/infotech.py +++ b/synapse/models/infotech.py @@ -572,6 +572,7 @@ def bruteVersionStr(self, valu): subs = info.get('subs') return valu, subs + # FIXME discuss case insensitive string indexing async def _onFormItDevStr(self, node): await node.set('norm', node.ndef[1]) @@ -889,24 +890,24 @@ def getModelDefs(self): 'doc': 'Deprecated. Please use it:av:scan:result.'}), ('it:auth:passwdhash', ('guid', {}), { - 'doc': 'An instance of a password hash.', - }), + 'doc': 'An instance of a password hash.'}), + ('it:exec:proc', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A process executing on a host. May be an actual (e.g., endpoint) or virtual (e.g., malware sandbox) host.', - }), + 'doc': 'A process executing on a host. May be an actual (e.g., endpoint) or virtual (e.g., malware sandbox) host.'}), + ('it:exec:thread', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A thread executing in a process.', - }), + 'doc': 'A thread executing in a process.'}), + ('it:exec:loadlib', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A library load event in a process.', - }), + 'doc': 'A library load event in a process.'}), + ('it:exec:mmap', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A memory mapped segment located in a process.', - }), + 'doc': 'A memory mapped segment located in a process.'}), + ('it:cmd', ('str', {'strip': True}), { 'doc': 'A unique command-line string.', 'ex': 'foo.exe --dostuff bar'}), @@ -918,93 +919,97 @@ def getModelDefs(self): 'doc': 'A single command executed within a session.'}), ('it:query', ('str', {'strip': True}), { - 'doc': 'A unique query string.', - }), + 'doc': 'A unique query string.'}), + ('it:exec:query', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of an executed query.', - }), + 'doc': 'An instance of an executed query.'}), + ('it:exec:mutex', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A mutex created by a process at runtime.', - }), + 'doc': 'A mutex created by a process at runtime.'}), + ('it:exec:pipe', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'A named pipe created by a process at runtime.', - }), + 'doc': 'A named pipe created by a process at runtime.'}), + ('it:exec:url', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host requesting a URL.', - }), + 'doc': 'An instance of a host requesting a URL.'}), + ('it:exec:bind', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host binding a listening port.', - }), + 'doc': 'An instance of a host binding a listening port.'}), + ('it:fs:file', ('guid', {}), { - 'doc': 'A file on a host.' - }), + 'doc': 'A file on a host.'}), + ('it:exec:file:add', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host adding a file to a filesystem.', - }), + 'doc': 'An instance of a host adding a file to a filesystem.'}), + ('it:exec:file:del', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host deleting a file from a filesystem.', - }), + 'doc': 'An instance of a host deleting a file from a filesystem.'}), + ('it:exec:file:read', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host reading a file from a filesystem.', - }), + 'doc': 'An instance of a host reading a file from a filesystem.'}), + ('it:exec:file:write', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host writing a file to a filesystem.', - }), + 'doc': 'An instance of a host writing a file to a filesystem.'}), + ('it:exec:reg:get', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host getting a registry key.', - }), + 'doc': 'An instance of a host getting a registry key.'}), + ('it:exec:reg:set', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host creating or setting a registry key.', - }), + 'doc': 'An instance of a host creating or setting a registry key.'}), + ('it:exec:reg:del', ('guid', {}), { 'interfaces': ('it:host:activity',), - 'doc': 'An instance of a host deleting a registry key.', - }), + 'doc': 'An instance of a host deleting a registry key.'}), + ('it:app:yara:rule', ('guid', {}), { - 'doc': 'A YARA rule unique identifier.', - }), + 'doc': 'A YARA rule unique identifier.'}), + ('it:sec:stix:bundle', ('guid', {}), { - 'doc': 'A STIX bundle.', - }), + 'doc': 'A STIX bundle.'}), + ('it:sec:stix:indicator', ('guid', {}), { - 'doc': 'A STIX indicator pattern.', - }), + 'doc': 'A STIX indicator pattern.'}), + + # FIXME undo comp and make match target an ndef ('it:app:yara:match', ('comp', {'fields': (('rule', 'it:app:yara:rule'), ('file', 'file:bytes'))}), { - 'doc': 'A YARA rule match to a file.', - }), + 'doc': 'A YARA rule match to a file.'}), + + # FIXME deprecate ('it:app:yara:procmatch', ('guid', {}), { - 'doc': 'An instance of a YARA rule match to a process.', - }), + 'doc': 'An instance of a YARA rule match to a process.'}), + ('it:app:snort:rule', ('guid', {}), { - 'doc': 'A snort rule.', - }), + 'doc': 'A snort rule.'}), + ('it:app:snort:hit', ('guid', {}), { - 'doc': 'An instance of a snort rule hit.', - }), + 'doc': 'An instance of a snort rule hit.'}), + + # FIXME convert it:reveng -> it:dev ('it:reveng:function', ('guid', {}), { - 'doc': 'A function inside an executable.', - }), + 'doc': 'A function inside an executable.'}), + + # FIXME deprecate. This can go away. should use light edge ( one time knowledge ) ('it:reveng:filefunc', ('comp', {'fields': (('file', 'file:bytes'), ('function', 'it:reveng:function'))}), { - 'doc': 'An instance of a function in an executable.', - }), - ('it:reveng:funcstr', ('comp', {'fields': (('function', 'it:reveng:function'), ('string', 'str'))}), { - 'deprecated': True, - 'doc': 'A reference to a string inside a function.', - }), + 'doc': 'An instance of a function in an executable.'}), + + #('it:reveng:funcstr', ('comp', {'fields': (('function', 'it:reveng:function'), ('string', 'str'))}), { + #'deprecated': True, + #'doc': 'A reference to a string inside a function.', + #}), ('it:reveng:impfunc', ('str', {'lower': 1}), { - 'doc': 'A function from an imported library.', - }), + 'doc': 'A function from an imported library.'}), + ('it:sec:c2:config', ('guid', {}), { 'doc': 'An extracted C2 config from an executable.'}), @@ -1036,16 +1041,22 @@ def getModelDefs(self): ('it:host:activity', { 'doc': 'Properties common to instances of activity on a host.', 'props': ( + ('exe', ('file:bytes', {}), { 'doc': 'The executable file which caused the activity.'}), + ('proc', ('it:exec:proc', {}), { 'doc': 'The host process which caused the activity.'}), + ('thread', ('it:exec:thread', {}), { 'doc': 'The host thread which caused the activity.'}), + ('host', ('it:host', {}), { 'doc': 'The host on which the activity occurred.'}), + ('time', ('time', {}), { 'doc': 'The time that the activity started.'}), + ('sandbox:file', ('file:bytes', {}), { 'doc': 'The initial sample given to a sandbox environment to analyze.'}), ), @@ -1074,17 +1085,21 @@ def getModelDefs(self): ('domain', ('it:domain', {}), { 'doc': 'The authentication domain that the host is a member of.'}), - ('ipv4', ('inet:ipv4', {}), { - 'doc': 'The last known ipv4 address for the host.'}), + ('ip', ('inet:ip', {}), { + 'doc': 'The current IP address of the host.'}), + + #('ipv4', ('inet:ipv4', {}), { + #'doc': 'The last known ipv4 address for the host.'}), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The last known location for the host.'}), + # FIXME place protocol + #('latlong', ('geo:latlong', {}), { + #'doc': 'The last known location for the host.'}), ('place', ('geo:place', {}), { 'doc': 'The place where the host resides.'}), - ('loc', ('loc', {}), { - 'doc': 'The geo-political location string for the node.'}), + #('loc', ('loc', {}), { + #'doc': 'The geo-political location string for the node.'}), ('os', ('it:prod:softver', {}), { 'doc': 'The operating system of the host.'}), @@ -1095,13 +1110,13 @@ def getModelDefs(self): ('hardware', ('it:prod:hardware', {}), { 'doc': 'The hardware specification for this host.'}), - ('manu', ('str', {}), { - 'deprecated': True, - 'doc': 'Please use :hardware::manufacturer:name.'}), + #('manu', ('str', {}), { + # 'deprecated': True, + # 'doc': 'Please use :hardware::manufacturer:name.'}), - ('model', ('str', {}), { - 'deprecated': True, - 'doc': 'Please use :hardware::model.'}), + #('model', ('str', {}), { + # 'deprecated': True, + # 'doc': 'Please use :hardware::model.'}), ('serial', ('str', {}), { 'doc': 'The serial number of the host.'}), @@ -1204,17 +1219,19 @@ def getModelDefs(self): 'doc': 'The software which produced the log entry.'}), )), + ('it:domain', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The name of the domain.', - }), + 'doc': 'The name of the domain.'}), + ('desc', ('str', {}), { - 'doc': 'A brief description of the domain.', - }), + 'doc': 'A brief description of the domain.'}), + ('org', ('ou:org', {}), { - 'doc': 'The org that operates the given domain.', - }), + 'doc': 'The org that operates the given domain.'}), )), + ('it:network:type:taxonomy', {}, ()), ('it:network', {}, ( @@ -1230,13 +1247,15 @@ def getModelDefs(self): ('org', ('ou:org', {}), { 'doc': 'The org that owns/operates the network.'}), - ('net4', ('inet:net4', {}), { - 'doc': 'The optional contiguous IPv4 address range of this network.'}), + # FIXME array of new inet:ipnet or whatever + #('net4', ('inet:net4', {}), { + # 'doc': 'The optional contiguous IPv4 address range of this network.'}), - ('net6', ('inet:net6', {}), { - 'doc': 'The optional contiguous IPv6 address range of this network.'}), + #('net6', ('inet:net6', {}), { + # 'doc': 'The optional contiguous IPv6 address range of this network.'}), )), + # FIXME decide what to do about it:account ('it:account', {}, ( ('user', ('inet:user', {}), { 'doc': 'The username associated with the account', @@ -1276,73 +1295,80 @@ def getModelDefs(self): 'doc': 'An array of groups that the account is a member of.', }), )), + # FIXME decide what to do with this ('it:group', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The name of the group.', - }), + 'doc': 'The name of the group.'}), + ('desc', ('str', {}), { - 'doc': 'A brief description of the group.', - }), + 'doc': 'A brief description of the group.'}), + ('host', ('it:host', {}), { - 'doc': 'The host where the group is registered.', - }), + 'doc': 'The host where the group is registered.'}), + ('domain', ('it:domain', {}), { - 'doc': 'The authentication domain where the group is registered.', - }), + 'doc': 'The authentication domain where the group is registered.'}), + ('groups', ('array', {'type': 'it:group', 'uniq': True, 'sorted': True}), { - 'doc': 'Groups that are a member of this group.', - }), + 'doc': 'Groups that are a member of this group.'}), + ('posix:gid', ('int', {}), { - 'doc': 'The primary group ID of the account.', 'ex': '1001', - }), + 'doc': 'The primary group ID of the account.'}), + ('windows:sid', ('it:os:windows:sid', {}), { - 'doc': 'The Microsoft Windows Security Identifier of the group.', - }), - )), - ('it:logon', {}, ( - ('time', ('time', {}), { - 'doc': 'The time the logon occurred.', - }), - ('success', ('bool', {}), { - 'doc': 'Set to false to indicate an unsuccessful logon attempt.', - }), - ('logoff:time', ('time', {}), { - 'doc': 'The time the logon session ended.', - }), - ('host', ('it:host', {}), { - 'doc': 'The host that the account logged in to.', - }), - ('account', ('it:account', {}), { - 'doc': 'The account that logged in.', - }), - ('creds', ('auth:creds', {}), { - 'doc': 'The credentials that were used for the logon.', - }), - ('duration', ('duration', {}), { - 'doc': 'The duration of the logon session.', - }), - ('client:host', ('it:host', {}), { - 'doc': 'The host where the logon originated.', - }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 where the logon originated.', - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 where the logon originated.', - }), - )), - ('it:hosturl', {}, ( - ('host', ('it:host', {}), { - 'ro': True, - 'doc': 'Host serving a url.', - }), - ('url', ('inet:url', {}), { - 'ro': True, - 'doc': 'URL available on the host.', - }), - )), + 'doc': 'The Microsoft Windows Security Identifier of the group.'}), + + )), + # FIXME deprecate? + #('it:logon', {}, ( + # ('time', ('time', {}), { + # 'doc': 'The time the logon occurred.', + # }), + # ('success', ('bool', {}), { + # 'doc': 'Set to false to indicate an unsuccessful logon attempt.', + # }), + # ('logoff:time', ('time', {}), { + # 'doc': 'The time the logon session ended.', + # }), + # ('host', ('it:host', {}), { + # 'doc': 'The host that the account logged in to.', + # }), + # ('account', ('it:account', {}), { + # 'doc': 'The account that logged in.', + # }), + # ('creds', ('auth:creds', {}), { + # 'doc': 'The credentials that were used for the logon.', + # }), + # ('duration', ('duration', {}), { + # 'doc': 'The duration of the logon session.', + # }), + # ('client:host', ('it:host', {}), { + # 'doc': 'The host where the logon originated.', + # }), + # ('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 where the logon originated.', + # }), + # ('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 where the logon originated.', + # }), + #)), + + # FIXME deprecate? + #('it:hosturl', {}, ( + # ('host', ('it:host', {}), { + # 'ro': True, + # 'doc': 'Host serving a url.', + # }), + # ('url', ('inet:url', {}), { + # 'ro': True, + # 'doc': 'URL available on the host.', + # }), + #)), + ('it:screenshot', {}, ( + # FIXME needs :host or even host:activity? ('image', ('file:bytes', {}), { 'doc': 'The image file.'}), ('desc', ('str', {}), { @@ -1371,65 +1397,76 @@ def getModelDefs(self): )), ('it:sec:cpe', {}, ( ('v2_2', ('it:sec:cpe:v2_2', {}), { - 'doc': 'The CPE 2.2 string which is equivalent to the primary property.', - }), + 'doc': 'The CPE 2.2 string which is equivalent to the primary property.'}), + ('part', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "part" field from the CPE 2.3 string.'}), + ('vendor', ('ou:name', {}), { 'ro': True, 'doc': 'The "vendor" field from the CPE 2.3 string.'}), + ('product', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "product" field from the CPE 2.3 string.'}), + ('version', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "version" field from the CPE 2.3 string.'}), + ('update', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "update" field from the CPE 2.3 string.'}), + ('edition', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "edition" field from the CPE 2.3 string.'}), + ('language', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "language" field from the CPE 2.3 string.'}), + ('sw_edition', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "sw_edition" field from the CPE 2.3 string.'}), + ('target_sw', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "target_sw" field from the CPE 2.3 string.'}), + ('target_hw', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "target_hw" field from the CPE 2.3 string.'}), + ('other', ('str', {'lower': True, 'strip': True}), { 'ro': True, 'doc': 'The "other" field from the CPE 2.3 string.'}), )), ('it:sec:cwe', {}, ( + ('name', ('str', {}), { 'doc': 'The CWE description field.', - 'ex': 'Buffer Copy without Checking Size of Input (Classic Buffer Overflow)', - }), + 'ex': 'Buffer Copy without Checking Size of Input (Classic Buffer Overflow)'}), + ('desc', ('str', {}), { - 'doc': 'The CWE description field.', 'disp': {'hint': 'text'}, - }), + 'doc': 'The CWE description field.'}), + ('url', ('inet:url', {}), { - 'doc': 'A URL linking this CWE to a full description.', - }), + 'doc': 'A URL linking this CWE to a full description.'}), + ('parents', ('array', {'type': 'it:sec:cwe', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ChildOf CWE Relationships.' - }), + 'doc': 'An array of ChildOf CWE Relationships.'}), )), ('it:sec:metrics', {}, ( + # FIXME entity / org protocol / interface? ('org', ('ou:org', {}), { 'doc': 'The organization whose security program is being measured.'}), - + ('org:name', ('ou:name', {}), { 'doc': 'The organization name. Used for entity resolution.'}), @@ -1534,53 +1571,54 @@ def getModelDefs(self): )), ('it:mitre:attack:group', {}, ( + ('org', ('ou:org', {}), { - 'doc': 'Used to map an ATT&CK group to a synapse ou:org.', - }), + 'doc': 'Used to map an ATT&CK group to a synapse ou:org.'}), + ('name', ('ou:name', {}), { - 'doc': 'The primary name for the ATT&CK group.', - }), + 'doc': 'The primary name for the ATT&CK group.'}), + ('names', ('array', {'type': 'ou:name', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of alternate names for the ATT&CK group.', - }), + 'doc': 'An array of alternate names for the ATT&CK group.'}), + ('desc', ('str', {}), { - 'doc': 'A description of the ATT&CK group.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK group.'}), + ('isnow', ('it:mitre:attack:group', {}), { - 'doc': 'If deprecated, this field may contain the current value for the group.', - }), + 'doc': 'If deprecated, this field may contain the current value for the group.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL that documents the ATT&CK group.', - }), + 'doc': 'The URL that documents the ATT&CK group.'}), ('tag', ('syn:tag', {}), { 'deprecated': True, 'doc': 'Deprecated. Please use a risk:threat:tag.'}), ('references', ('array', {'type': 'inet:url', 'uniq': True}), { - 'doc': 'An array of URLs that document the ATT&CK group.', - }), + 'doc': 'An array of URLs that document the ATT&CK group.'}), + ('techniques', ('array', {'type': 'it:mitre:attack:technique', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK technique IDs used by the group.', - }), + 'doc': 'An array of ATT&CK technique IDs used by the group.'}), + ('software', ('array', {'type': 'it:mitre:attack:software', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK software IDs used by the group.', - }), + 'doc': 'An array of ATT&CK software IDs used by the group.'}), )), + ('it:mitre:attack:tactic', {}, ( + ('name', ('str', {'strip': True}), { - 'doc': 'The primary name for the ATT&CK tactic.', - }), + 'doc': 'The primary name for the ATT&CK tactic.'}), + ('matrix', ('it:mitre:attack:matrix', {}), { - 'doc': 'The ATT&CK matrix which defines the tactic.', - }), + 'doc': 'The ATT&CK matrix which defines the tactic.'}), + ('desc', ('str', {}), { - 'doc': 'A description of the ATT&CK tactic.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK tactic.'}), + ('url', ('inet:url', {}), { 'doc': 'The URL that documents the ATT&CK tactic.'}), @@ -1589,71 +1627,72 @@ def getModelDefs(self): 'doc': 'Deprecated.'}), ('references', ('array', {'type': 'inet:url', 'uniq': True}), { - 'doc': 'An array of URLs that document the ATT&CK tactic.', - }), + 'doc': 'An array of URLs that document the ATT&CK tactic.'}), + )), + ('it:mitre:attack:technique', {}, ( ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The primary name for the ATT&CK technique.', - }), + 'doc': 'The primary name for the ATT&CK technique.'}), + ('matrix', ('it:mitre:attack:matrix', {}), { - 'doc': 'The ATT&CK matrix which defines the technique.', - }), + 'doc': 'The ATT&CK matrix which defines the technique.'}), + ('status', ('it:mitre:attack:status', {}), { - 'doc': 'The status of this ATT&CK technique.', - }), + 'doc': 'The status of this ATT&CK technique.'}), + ('isnow', ('it:mitre:attack:technique', {}), { - 'doc': 'If deprecated, this field may contain the current value for the technique.', - }), + 'doc': 'If deprecated, this field may contain the current value for the technique.'}), + ('desc', ('str', {'strip': True}), { - 'doc': 'A description of the ATT&CK technique.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK technique.'}), + ('url', ('inet:url', {}), { 'doc': 'The URL that documents the ATT&CK technique.'}), - ('tag', ('syn:tag', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:technique:tag.'}), + #('tag', ('syn:tag', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use ou:technique:tag.'}), ('references', ('array', {'type': 'inet:url', 'uniq': True}), { - 'doc': 'An array of URLs that document the ATT&CK technique.', - }), + 'doc': 'An array of URLs that document the ATT&CK technique.'}), + ('parent', ('it:mitre:attack:technique', {}), { - 'doc': 'The parent ATT&CK technique on this sub-technique.', - }), + 'doc': 'The parent ATT&CK technique on this sub-technique.'}), + ('tactics', ('array', {'type': 'it:mitre:attack:tactic', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK tactics that include this technique.', - }), + 'doc': 'An array of ATT&CK tactics that include this technique.'}), + ('data:components', ('array', {'type': 'it:mitre:attack:data:component', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of MITRE ATT&CK data components that detect the ATT&CK technique.', - }), + 'doc': 'An array of MITRE ATT&CK data components that detect the ATT&CK technique.'}), )), + ('it:mitre:attack:software', {}, ( ('software', ('it:prod:soft', {}), { - 'doc': 'Used to map an ATT&CK software to a synapse it:prod:soft.', - }), + 'doc': 'Used to map an ATT&CK software to a synapse it:prod:soft.'}), + ('name', ('it:prod:softname', {}), { - 'doc': 'The primary name for the ATT&CK software.', - }), + 'doc': 'The primary name for the ATT&CK software.'}), + ('names', ('array', {'type': 'it:prod:softname', 'uniq': True, 'sorted': True}), { - 'doc': 'Associated names for the ATT&CK software.', - }), + 'doc': 'Associated names for the ATT&CK software.'}), + ('desc', ('str', {'strip': True}), { - 'doc': 'A description of the ATT&CK software.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK software.'}), + ('isnow', ('it:mitre:attack:software', {}), { - 'doc': 'If deprecated, this field may contain the current value for the software.', - }), + 'doc': 'If deprecated, this field may contain the current value for the software.'}), + ('url', ('inet:url', {}), { 'doc': 'The URL that documents the ATT&CK software.'}), - ('tag', ('syn:tag', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use risk:tool:software:tag.'}), + #('tag', ('syn:tag', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use risk:tool:software:tag.'}), ('references', ('array', {'type': 'inet:url', 'uniq': True}), { 'doc': 'An array of URLs that document the ATT&CK software.', @@ -1666,106 +1705,122 @@ def getModelDefs(self): ('it:mitre:attack:mitigation', {}, ( # TODO map to an eventual risk:mitigation ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The primary name for the ATT&CK mitigation.', - }), + 'doc': 'The primary name for the ATT&CK mitigation.'}), + ('matrix', ('it:mitre:attack:matrix', {}), { - 'doc': 'The ATT&CK matrix which defines the mitigation.', - }), + 'doc': 'The ATT&CK matrix which defines the mitigation.'}), + ('desc', ('str', {'strip': True}), { - 'doc': 'A description of the ATT&CK mitigation.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK mitigation.'}), + ('url', ('inet:url', {}), { 'doc': 'The URL that documents the ATT&CK mitigation.'}), - ('tag', ('syn:tag', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use risk:mitigation:tag.'}), + #('tag', ('syn:tag', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use risk:mitigation:tag.'}), ('references', ('array', {'type': 'inet:url', 'uniq': True}), { - 'doc': 'An array of URLs that document the ATT&CK mitigation.', - }), + 'doc': 'An array of URLs that document the ATT&CK mitigation.'}), + ('addresses', ('array', {'type': 'it:mitre:attack:technique', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK technique IDs addressed by the mitigation.', - }), + 'doc': 'An array of ATT&CK technique IDs addressed by the mitigation.'}), )), + ('it:mitre:attack:campaign', {}, ( + ('name', ('ou:campname', {}), { - 'doc': 'The primary name for the ATT&CK campaign.', - }), + 'doc': 'The primary name for the ATT&CK campaign.'}), + ('names', ('array', {'type': 'ou:campname', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of alternate names for the ATT&CK campaign.', - }), + 'doc': 'An array of alternate names for the ATT&CK campaign.'}), + ('desc', ('str', {'strip': True}), { - 'doc': 'A description of the ATT&CK campaign.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the ATT&CK campaign.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL that documents the ATT&CK campaign.', - }), + 'doc': 'The URL that documents the ATT&CK campaign.'}), + ('groups', ('array', {'type': 'it:mitre:attack:group', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK group IDs attributed to the campaign.', - }), + 'doc': 'An array of ATT&CK group IDs attributed to the campaign.'}), + ('software', ('array', {'type': 'it:mitre:attack:software', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK software IDs used in the campaign.', - }), + 'doc': 'An array of ATT&CK software IDs used in the campaign.'}), + ('techniques', ('array', {'type': 'it:mitre:attack:technique', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'An array of ATT&CK technique IDs used in the campaign.', - }), + 'doc': 'An array of ATT&CK technique IDs used in the campaign.'}), + ('matrices', ('array', {'type': 'it:mitre:attack:matrix', 'uniq': True, 'sorted': True, 'split': ','}), { - 'doc': 'The ATT&CK matrices which define the campaign.', - }), + 'doc': 'The ATT&CK matrices which define the campaign.'}), + ('references', ('array', {'type': 'inet:url', 'uniq': True}), { - 'doc': 'An array of URLs that document the ATT&CK campaign.', - }), + 'doc': 'An array of URLs that document the ATT&CK campaign.'}), + ('period', ('ival', {}), { 'doc': 'The time interval when the campaign was active.'}), + ('created', ('time', {}), { 'doc': 'The time that the campaign was created by MITRE.'}), + ('updated', ('time', {}), { 'doc': 'The time that the campaign was last updated by MITRE.'}), - ('tag', ('syn:tag', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:campaign:tag.'}), + #('tag', ('syn:tag', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use ou:campaign:tag.'}), )), ('it:mitre:attack:flow', {}, ( + ('name', ('str', {}), { 'doc': 'The name of the attack-flow diagram.'}), + ('data', ('data', {'schema': attack_flow_schema_2_0_0}), { 'doc': 'The ATT&CK Flow diagram. Schema version 2.0.0 enforced.'}), + ('created', ('time', {}), { 'doc': 'The time that the diagram was created.'}), + ('updated', ('time', {}), { 'doc': 'The time that the diagram was last updated.'}), + ('author:user', ('syn:user', {}), { 'doc': 'The Synapse user that created the node.'}), + ('author:contact', ('ps:contact', {}), { 'doc': 'The contact information for the author of the ATT&CK Flow diagram.'}), + )), ('it:mitre:attack:datasource', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { 'doc': 'The name of the datasource.'}), + ('description', ('str', {}), { 'disp': {'hint': 'text'}, 'doc': 'A description of the datasource.'}), + ('references', ('array', {'type': 'inet:url', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of URLs that document the datasource.', - }), + 'doc': 'An array of URLs that document the datasource.'}), )), + ('it:mitre:attack:data:component', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { 'ro': True, 'doc': 'The name of the data component.'}), + ('description', ('str', {}), { 'disp': {'hint': 'text'}, 'doc': 'A description of the data component.'}), + ('datasource', ('it:mitre:attack:datasource', {}), { 'ro': True, 'doc': 'The datasource this data component belongs to.'}), @@ -1792,212 +1847,216 @@ def getModelDefs(self): # TODO: all of the `id:dev:repo` forms need to be tied to the TBD inet:service model ('it:dev:repo:type:taxonomy', {}, ()), ('it:dev:repo', {}, ( + ('name', ('str', {'lower': True, 'strip': True}), { - 'doc': 'The name of the repository.', - }), + 'doc': 'The name of the repository.'}), + ('desc', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'A free-form description of the repository.', - }), + 'doc': 'A free-form description of the repository.'}), + ('created', ('time', {}), { - 'doc': 'When the repository was created.', - }), + 'doc': 'When the repository was created.'}), + ('url', ('inet:url', {}), { - 'doc': 'A URL where the repository is hosted.', - }), + 'doc': 'A URL where the repository is hosted.'}), + ('type', ('it:dev:repo:type:taxonomy', {}), { - 'doc': 'The type of the version control system used.', - 'ex': 'svn' - }), + 'ex': 'svn', + 'doc': 'The type of the version control system used.'}), + ('submodules', ('array', {'type': 'it:dev:repo:commit'}), { - 'doc': "An array of other repos that this repo has as submodules, pinned at specific commits.", - }), + 'doc': "An array of other repos that this repo has as submodules, pinned at specific commits."}), )), ('it:dev:repo:remote', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The name the repo is using for the remote repo.', - 'ex': 'origin' - }), + 'ex': 'origin', + 'doc': 'The name the repo is using for the remote repo.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL the repo is using to access the remote repo.', - }), + 'doc': 'The URL the repo is using to access the remote repo.'}), + ('repo', ('it:dev:repo', {}), { - 'doc': 'The repo that is tracking the remote repo.', - }), + 'doc': 'The repo that is tracking the remote repo.'}), + ('remote', ('it:dev:repo', {}), { - 'doc': 'The instance of the remote repo.', - }), + 'doc': 'The instance of the remote repo.'}), )), ('it:dev:repo:branch', {}, ( + ('parent', ('it:dev:repo:branch', {}), { - 'doc': 'The branch this branch was branched from.', - }), + 'doc': 'The branch this branch was branched from.'}), + ('start', ('it:dev:repo:commit', {}), { - 'doc': 'The commit in the parent branch this branch was created at.' - }), + 'doc': 'The commit in the parent branch this branch was created at.'}), + ('name', ('str', {'strip': True}), { - 'doc': 'The name of the branch.', - }), + 'doc': 'The name of the branch.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the branch is hosted.', - }), + 'doc': 'The URL where the branch is hosted.'}), + ('created', ('time', {}), { - 'doc': 'The time this branch was created', - }), + 'doc': 'The time this branch was created'}), + ('merged', ('time', {}), { - 'doc': 'The time this branch was merged back into its parent.', - }), + 'doc': 'The time this branch was merged back into its parent.'}), + ('deleted', ('time', {}), { - 'doc': 'The time this branch was deleted.', - }), + 'doc': 'The time this branch was deleted.'}), + )), ('it:dev:repo:commit', {}, ( + ('repo', ('it:dev:repo', {}), { - 'doc': 'The repository the commit lives in.', - }), + 'doc': 'The repository the commit lives in.'}), + ('parents', ('array', {'type': 'it:dev:repo:commit'}), { - 'doc': 'The commit or commits this commit is immediately based on.', - }), + 'doc': 'The commit or commits this commit is immediately based on.'}), + ('branch', ('it:dev:repo:branch', {}), { - 'doc': 'The name of the branch the commit was made to.', - }), + 'doc': 'The name of the branch the commit was made to.'}), + ('mesg', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'The commit message describing the changes in the commit.', - }), + 'doc': 'The commit message describing the changes in the commit.'}), + ('id', ('str', {}), { - 'doc': 'The version control system specific commit identifier.', - }), + 'doc': 'The version control system specific commit identifier.'}), + ('created', ('time', {}), { - 'doc': 'The time the commit was made.', - }), + 'doc': 'The time the commit was made.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the commit is hosted.', - }), + 'doc': 'The URL where the commit is hosted.'}), )), ('it:dev:repo:diff', {}, ( + ('commit', ('it:dev:repo:commit', {}), { - 'doc': 'The commit that produced this diff.', - }), + 'doc': 'The commit that produced this diff.'}), + ('file', ('file:bytes', {}), { - 'doc': 'The file after the commit has been applied', - }), + 'doc': 'The file after the commit has been applied'}), + ('path', ('file:path', {}), { - 'doc': 'The path to the file in the repo that the diff is being applied to.', - }), + 'doc': 'The path to the file in the repo that the diff is being applied to.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the diff is hosted.', - }), + 'doc': 'The URL where the diff is hosted.'}), + )), ('it:dev:repo:issue', {}, ( + ('repo', ('it:dev:repo', {}), { - 'doc': 'The repo where the issue was logged.', - }), + 'doc': 'The repo where the issue was logged.'}), + ('title', ('str', {'lower': True, 'strip': True}), { - 'doc': 'The title of the issue.' - }), + 'doc': 'The title of the issue.'}), + ('desc', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'The text describing the issue.' - }), + 'doc': 'The text describing the issue.'}), + ('created', ('time', {}), { - 'doc': 'The time the issue was created.', - }), + 'doc': 'The time the issue was created.'}), + ('updated', ('time', {}), { - 'doc': 'The time the issue was updated.', - }), + 'doc': 'The time the issue was updated.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the issue is hosted.', - }), + 'doc': 'The URL where the issue is hosted.'}), + ('id', ('str', {'strip': True}), { - 'doc': 'The ID of the issue in the repository system.', - }), + 'doc': 'The ID of the issue in the repository system.'}), )), ('it:dev:repo:label', {}, ( + ('id', ('str', {'strip': True}), { - 'doc': 'The ID of the label.', - }), + 'doc': 'The ID of the label.'}), + ('title', ('str', {'lower': True, 'strip': True}), { - 'doc': 'The human friendly name of the label.', - }), + 'doc': 'The human friendly name of the label.'}), + ('desc', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'The description of the label.', - }), + 'doc': 'The description of the label.'}), )), ('it:dev:repo:issue:label', {}, ( + ('issue', ('it:dev:repo:issue', {}), { - 'doc': 'The issue the label was applied to.', - }), + 'doc': 'The issue the label was applied to.'}), + ('label', ('it:dev:repo:label', {}), { - 'doc': 'The label that was applied to the issue.', - }), + 'doc': 'The label that was applied to the issue.'}), + ('applied', ('time', {}), { - 'doc': 'The time the label was applied.', - }), + 'doc': 'The time the label was applied.'}), + ('removed', ('time', {}), { - 'doc': 'The time the label was removed.', - }), + 'doc': 'The time the label was removed.'}), + )), + # FIXME migrate all this to ine:service ('it:dev:repo:issue:comment', {}, ( + ('issue', ('it:dev:repo:issue', {}), { - 'doc': 'The issue thread that the comment was made in.', - }), + 'doc': 'The issue thread that the comment was made in.'}), + ('text', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'The body of the comment.', - }), + 'doc': 'The body of the comment.'}), + ('replyto', ('it:dev:repo:issue:comment', {}), { - 'doc': 'The comment that this comment is replying to.', - }), + 'doc': 'The comment that this comment is replying to.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the comment is hosted.', - }), + 'doc': 'The URL where the comment is hosted.'}), + ('created', ('time', {}), { - 'doc': 'The time the comment was created.', - }), + 'doc': 'The time the comment was created.'}), + ('updated', ('time', {}), { - 'doc': 'The time the comment was updated.', - }), + 'doc': 'The time the comment was updated.'}), )), ('it:dev:repo:diff:comment', {}, ( ('diff', ('it:dev:repo:diff', {}), { - 'doc': 'The diff the comment is being added to.', - }), + 'doc': 'The diff the comment is being added to.'}), + ('text', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'The body of the comment.', - }), + 'doc': 'The body of the comment.'}), + ('replyto', ('it:dev:repo:diff:comment', {}), { - 'doc': 'The comment that this comment is replying to.', - }), + 'doc': 'The comment that this comment is replying to.'}), + ('line', ('int', {}), { - 'doc': 'The line in the file that is being commented on.', - }), + 'doc': 'The line in the file that is being commented on.'}), + ('offset', ('int', {}), { - 'doc': 'The offset in the line in the file that is being commented on.', - }), + 'doc': 'The offset in the line in the file that is being commented on.'}), + ('url', ('inet:url', {}), { - 'doc': 'The URL where the comment is hosted.', - }), + 'doc': 'The URL where the comment is hosted.'}), + ('created', ('time', {}), { - 'doc': 'The time the comment was created.', - }), + 'doc': 'The time the comment was created.'}), + ('updated', ('time', {}), { - 'doc': 'The time the comment was updated.', - }), + 'doc': 'The time the comment was updated.'}), )), ('it:prod:hardwaretype', {}, ()), + # FIXME it:prod -> it ('it:prod:hardware', {}, ( ('name', ('str', {'lower': True, 'onespace': True}), { 'doc': 'The display name for this hardware specification.'}), @@ -2012,9 +2071,9 @@ def getModelDefs(self): 'doc': 'The organization that manufactures this hardware.'}), ('manufacturer:name', ('ou:name', {}), { 'doc': 'The name of the organization that manufactures this hardware.'}), - ('make', ('ou:name', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :manufacturer:name.'}), + #('make', ('ou:name', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use :manufacturer:name.'}), ('model', ('str', {'lower': True, 'onespace': True}), { 'doc': 'The model name or number for this hardware specification.'}), ('version', ('str', {'lower': True, 'onespace': True}), { @@ -2087,6 +2146,8 @@ def getModelDefs(self): 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), )), + # FIXME deprecate. entity:name + # FIXME entity:name -> proper noun? ('it:prod:softname', {}, ()), ('it:prod:softid', {}, ( @@ -2104,8 +2165,12 @@ def getModelDefs(self): )), ('it:adid', {}, ()), - ('it:os:ios:idfa', {}, ()), - ('it:os:android:aaid', {}, ()), + + # FIXME deprecate + #('it:os:ios:idfa', {}, ()), + #('it:os:android:aaid', {}, ()), + + # FIXME refactor? ('it:os:android:perm', {}, ()), ('it:os:android:intent', {}, ()), @@ -2118,6 +2183,7 @@ def getModelDefs(self): 'doc': 'The android permission requested by the app.'}), )), + # FIXME yuck ('it:prod:softos', {}, ( ('soft', ('it:prod:softver', {}), {'ro': True, @@ -2146,6 +2212,7 @@ def getModelDefs(self): )), + # FIXME it:software ('it:prod:softver', {}, ( ('software', ('it:prod:soft', {}), { @@ -2206,6 +2273,7 @@ def getModelDefs(self): }), )), + # FIXME yuck.. ('it:prod:softlib', {}, ( ('soft', ('it:prod:softver', {}), {'ro': True, @@ -2637,15 +2705,15 @@ def getModelDefs(self): ('client', ('inet:client', {}), { 'doc': 'The address of the client during the URL retrieval.' }), - ('client:ipv4', ('inet:ipv4', {}), { - 'doc': 'The IPv4 of the client during the URL retrieval.' - }), - ('client:ipv6', ('inet:ipv6', {}), { - 'doc': 'The IPv6 of the client during the URL retrieval.' - }), - ('client:port', ('inet:port', {}), { - 'doc': 'The client port during the URL retrieval.' - }), + #('client:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The IPv4 of the client during the URL retrieval.' + #}), + #('client:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The IPv6 of the client during the URL retrieval.' + #}), + #('client:port', ('inet:port', {}), { + # 'doc': 'The client port during the URL retrieval.' + #}), ('sandbox:file', ('file:bytes', {}), { 'doc': 'The initial sample given to a sandbox environment to analyze.' }), @@ -2959,20 +3027,20 @@ def getModelDefs(self): 'doc': 'The inet:flow that matched the snort rule.'}), ('src', ('inet:sockaddr', {}), { 'doc': 'The source address of flow that caused the hit.'}), - ('src:ipv4', ('inet:ipv4', {}), { - 'doc': 'The source IPv4 address of the flow that caused the hit.'}), - ('src:ipv6', ('inet:ipv6', {}), { - 'doc': 'The source IPv6 address of the flow that caused the hit.'}), - ('src:port', ('inet:port', {}), { - 'doc': 'The source port of the flow that caused the hit.'}), + #('src:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The source IPv4 address of the flow that caused the hit.'}), + #('src:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The source IPv6 address of the flow that caused the hit.'}), + #('src:port', ('inet:port', {}), { + # 'doc': 'The source port of the flow that caused the hit.'}), ('dst', ('inet:sockaddr', {}), { 'doc': 'The destination address of the trigger.'}), - ('dst:ipv4', ('inet:ipv4', {}), { - 'doc': 'The destination IPv4 address of the flow that caused the hit.'}), - ('dst:ipv6', ('inet:ipv6', {}), { - 'doc': 'The destination IPv4 address of the flow that caused the hit.'}), - ('dst:port', ('inet:port', {}), { - 'doc': 'The destination port of the flow that caused the hit.'}), + #('dst:ipv4', ('inet:ipv4', {}), { + # 'doc': 'The destination IPv4 address of the flow that caused the hit.'}), + #('dst:ipv6', ('inet:ipv6', {}), { + # 'doc': 'The destination IPv4 address of the flow that caused the hit.'}), + #('dst:port', ('inet:port', {}), { + # 'doc': 'The destination port of the flow that caused the hit.'}), ('time', ('time', {}), { 'doc': 'The time of the network flow that caused the hit.'}), ('sensor', ('it:host', {}), { diff --git a/synapse/models/person.py b/synapse/models/person.py index 6530552867..ef90b08cfe 100644 --- a/synapse/models/person.py +++ b/synapse/models/person.py @@ -5,44 +5,46 @@ def getModelDefs(self): modl = { 'types': ( ('edu:course', ('guid', {}), { - 'doc': 'A course of study taught by an org.', - }), + 'doc': 'A course of study taught by an org.'}), + ('edu:class', ('guid', {}), { - 'doc': 'An instance of an edu:course taught at a given time.', - }), + 'interfaces': ('geo:placed',), + 'doc': 'An instance of an edu:course taught at a given time.'}), + ('ps:education', ('guid', {}), { - 'doc': 'A period of education for an individual.', - }), + 'doc': 'A period of education for an individual.'}), + ('ps:achievement', ('guid', {}), { - 'doc': 'An instance of an individual receiving an award.', - }), - ('ps:tokn', ('str', {'lower': True, 'strip': True}), { - 'doc': 'A single name element (potentially given or sur).', - 'ex': 'robert' - }), - ('ps:name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'An arbitrary, lower spaced string with normalized whitespace.', - 'ex': 'robert grey' - }), + 'doc': 'An instance of an individual receiving an award.'}), + + #('ps:tokn', ('str', {'lower': True, 'strip': True}), { + # 'doc': 'A single name element (potentially given or sur).', + # 'ex': 'robert' + #}), + #('ps:name', ('str', {'lower': True, 'onespace': True}), { + # 'doc': 'An arbitrary, lower spaced string with normalized whitespace.', + # 'ex': 'robert grey' + #}), ('ps:person', ('guid', {}), { - 'doc': 'A GUID for a person.', - }), - ('ps:persona', ('guid', {}), { - 'deprecated': True, - 'doc': 'A GUID for a suspected person.', - }), - ('ps:person:has', ('comp', {'fields': (('person', 'ps:person'), ('node', 'ndef'))}), { - 'deprecated': True, - 'doc': 'A person owns, controls, or has exclusive use of an object or' - ' resource, potentially during a specific period of time.' - }), - ('ps:persona:has', ('comp', {'fields': (('persona', 'ps:persona'), ('node', 'ndef'))}), { - 'deprecated': True, - 'doc': 'A persona owns, controls, or has exclusive use of an object or' - ' resource, potentially during a specific period of time.'}), + 'doc': 'A GUID for a person.'}), + + #('ps:persona', ('guid', {}), { + # 'deprecated': True, + # 'doc': 'A GUID for a suspected person.', + #}), + #('ps:person:has', ('comp', {'fields': (('person', 'ps:person'), ('node', 'ndef'))}), { + # 'deprecated': True, + # 'doc': 'A person owns, controls, or has exclusive use of an object or' + # ' resource, potentially during a specific period of time.' + #}), + #('ps:persona:has', ('comp', {'fields': (('persona', 'ps:persona'), ('node', 'ndef'))}), { + # 'deprecated': True, + # 'doc': 'A persona owns, controls, or has exclusive use of an object or' + # ' resource, potentially during a specific period of time.'}), ('ps:contact', ('guid', {}), { 'doc': 'A GUID for a contact info record.', + 'interfaces': ('entity:contact:info',), 'display': { 'columns': ( {'type': 'prop', 'opts': {'name': 'name'}}, @@ -52,20 +54,23 @@ def getModelDefs(self): ), }}), - ('ps:contact:type:taxonomy', ('taxonomy', {}), { - 'interfaces': ('meta:taxonomy',), - 'doc': 'A taxonomy of contact types.', - }), - ('ps:contactlist', ('guid', {}), { - 'doc': 'A GUID for a list of associated contacts.', - }), + #('ps:contact:type:taxonomy', ('taxonomy', {}), { + # 'interfaces': ('meta:taxonomy',), + # 'doc': 'A taxonomy of contact types.', + #}), + + # FIXME deprecate + #('ps:contactlist', ('guid', {}), { + # 'doc': 'A GUID for a list of associated contacts.', + #}), ('ps:workhist', ('guid', {}), { - 'doc': "A GUID representing entry in a contact's work history.", - }), + 'doc': "A GUID representing entry in a contact's work history."}), + ('ps:vitals', ('guid', {}), { - 'doc': 'Statistics and demographic data about a person or contact.'}), + 'doc': 'Statistics and demographic data about an individual'}), ('ps:skill', ('guid', {}), { + # FIXME should orgs have skills? Update to entity? 'doc': 'A specific skill which a person or organization may have.', 'display': { 'columns': ( @@ -102,268 +107,297 @@ def getModelDefs(self): ('contact', ('ps:contact', {}), { 'doc': 'The contact which has the work history.', }), + + # FIXME does one always work for an org? + # FIXME rename to :employer in any case ('org', ('ou:org', {}), { - 'doc': 'The org that this work history orgname refers to.', - }), - ('orgname', ('ou:name', {}), { - 'doc': 'The reported name of the org the contact worked for.', - }), - ('orgfqdn', ('inet:fqdn', {}), { - 'doc': 'The reported fqdn of the org the contact worked for.', - }), + 'doc': 'The org that this work history refers to.'}), + + ('org:name', ('entity:name', {}), { + 'doc': 'The name of the org that this work history refers to.'}), + # FIXME other entity res props... + + # FIXME deprecate + #('orgname', ('ou:name', {}), { + # 'doc': 'The reported name of the org the contact worked for.', + #}), + #('orgfqdn', ('inet:fqdn', {}), { + # 'doc': 'The reported fqdn of the org the contact worked for.', + #}), + ('jobtype', ('ou:jobtype', {}), { - 'doc': 'The type of job.', - }), + 'doc': 'The type of job.'}), + ('employment', ('ou:employment', {}), { - 'doc': 'The type of employment.', - }), + 'doc': 'The type of employment.'}), + ('jobtitle', ('ou:jobtitle', {}), { - 'doc': 'The job title.', - }), - ('started', ('time', {}), { - 'doc': 'The date that the contact began working.', - }), - ('ended', ('time', {}), { - 'doc': 'The date that the contact stopped working.', - }), - ('duration', ('duration', {}), { - 'doc': 'The duration of the period of work.', - }), + 'doc': 'The job title.'}), + + ('period', ('ival', {}), { + 'doc': 'The period when the contact worked for the employer.'}), + + # FIXME deprecate + #('started', ('time', {}), { + # 'doc': 'The date that the contact began working.'}), + + #('ended', ('time', {}), { + # 'doc': 'The date that the contact stopped working.'}), + + #('duration', ('duration', {}), { + # 'doc': 'The duration of the period of work.', + #}), + + # FIXME should these be part of an interface? ('pay', ('econ:price', {}), { - 'doc': 'The estimated/average yearly pay for the work.', - }), + 'doc': 'The estimated/average yearly pay for the work.'}), + ('currency', ('econ:currency', {}), { - 'doc': 'The currency that the yearly pay was delivered in.', - }), + 'doc': 'The currency that the yearly pay was delivered in.'}), )), ('edu:course', {}, ( + ('name', ('str', {'lower': True, 'onespace': True}), { 'ex': 'organic chemistry for beginners', - 'doc': 'The name of the course.', - }), + 'doc': 'The name of the course.'}), + ('desc', ('str', {}), { - 'doc': 'A brief course description.', - }), + 'doc': 'A brief course description.'}), + ('code', ('str', {'lower': True, 'strip': True}), { 'ex': 'chem101', - 'doc': 'The course catalog number or designator.', - }), + 'doc': 'The course catalog number or designator.'}), + ('institution', ('ps:contact', {}), { - 'doc': 'The org or department which teaches the course.', - }), + 'doc': 'The org or department which teaches the course.'}), + ('prereqs', ('array', {'type': 'edu:course', 'uniq': True, 'sorted': True}), { - 'doc': 'The pre-requisite courses for taking this course.', - }), + 'doc': 'The pre-requisite courses for taking this course.'}), + )), ('edu:class', {}, ( + ('course', ('edu:course', {}), { - 'doc': 'The course being taught in the class.', - }), + 'doc': 'The course being taught in the class.'}), + ('instructor', ('ps:contact', {}), { - 'doc': 'The primary instructor for the class.', - }), + 'doc': 'The primary instructor for the class.'}), + ('assistants', ('array', {'type': 'ps:contact', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of assistant/co-instructor contacts.', - }), - ('date:first', ('time', {}), { - 'doc': 'The date of the first day of class.' - }), - ('date:last', ('time', {}), { - 'doc': 'The date of the last day of class.' - }), + 'doc': 'An array of assistant/co-instructor contacts.'}), + + ('period', ('ival', {}), { + 'doc': 'The time period where the class was run.'}), + + #('date:first', ('time', {}), { + # 'doc': 'The date of the first day of class.' + #}), + #('date:last', ('time', {}), { + # 'doc': 'The date of the last day of class.' + #}), ('isvirtual', ('bool', {}), { - 'doc': 'Set if the class is known to be virtual.', - }), + 'doc': 'Set if the class is known to be virtual.'}), + ('virtual:url', ('inet:url', {}), { - 'doc': 'The URL a student would use to attend the virtual class.', - }), + 'doc': 'The URL a student would use to attend the virtual class.'}), + + # FIXME inet:service:platform? ('virtual:provider', ('ps:contact', {}), { - 'doc': 'Contact info for the virtual infrastructure provider.', - }), - ('place', ('geo:place', {}), { - 'doc': 'The place that the class is held.', - }), + 'doc': 'Contact info for the virtual infrastructure provider.'}), + + # geo:placed + #('place', ('geo:place', {}), { + #'doc': 'The place that the class is held.', + #}), )), ('ps:education', {}, ( ('student', ('ps:contact', {}), { - 'doc': 'The contact of the person being educated.', - }), + 'doc': 'The contact of the person being educated.'}), + ('institution', ('ps:contact', {}), { - 'doc': 'The contact info for the org providing educational services.', - }), - ('attended:first', ('time', {}), { - 'doc': 'The first date the student attended a class.', - }), - ('attended:last', ('time', {}), { - 'doc': 'The last date the student attended a class.', - }), + 'doc': 'The contact info for the org providing educational services.'}), + + ('period', ('ival', {}), { + 'doc': 'The period where the student attended classes.'}), + + # FIXME deprecate + #('attended:first', ('time', {}), { + # 'doc': 'The first date the student attended a class.', + #}), + #('attended:last', ('time', {}), { + # 'doc': 'The last date the student attended a class.', + #}), ('classes', ('array', {'type': 'edu:class', 'uniq': True, 'sorted': True}), { - 'doc': 'The classes attended by the student', - }), + 'doc': 'The classes attended by the student'}), + ('achievement', ('ps:achievement', {}), { - 'doc': 'The achievement awarded to the individual.', - }), + 'doc': 'The achievement awarded to the individual.'}), )), ('ps:achievement', {}, ( ('awardee', ('ps:contact', {}), { - 'doc': 'The recipient of the award.', - }), + 'doc': 'The recipient of the award.'}), ('award', ('ou:award', {}), { - 'doc': 'The award bestowed on the awardee.', - }), + 'doc': 'The award bestowed on the awardee.'}), + ('awarded', ('time', {}), { - 'doc': 'The date the award was granted to the awardee.', - }), + 'doc': 'The date the award was granted to the awardee.'}), + ('expires', ('time', {}), { - 'doc': 'The date the award or certification expires.', - }), + 'doc': 'The date the award or certification expires.'}), + ('revoked', ('time', {}), { - 'doc': 'The date the award was revoked by the org.', - }), - )), - ('ps:tokn', {}, ()), - ('ps:name', {}, ( - ('sur', ('ps:tokn', {}), { - 'doc': 'The surname part of the name.' - }), - ('middle', ('ps:tokn', {}), { - 'doc': 'The middle name part of the name.' - }), - ('given', ('ps:tokn', {}), { - 'doc': 'The given name part of the name.' - }), + 'doc': 'The date the award was revoked by the org.'}), )), + # FIXME words and tokens + #('ps:tokn', {}, ()), + #('ps:name', {}, ( + # ('sur', ('ps:tokn', {}), { + # 'doc': 'The surname part of the name.' + # }), + # ('middle', ('ps:tokn', {}), { + # 'doc': 'The middle name part of the name.' + # }), + # ('given', ('ps:tokn', {}), { + # 'doc': 'The given name part of the name.' + # }), + #)), ('ps:person', {}, ( ('dob', ('time', {}), { - 'doc': 'The date on which the person was born.', - }), + 'doc': 'The date on which the person was born.'}), + ('dod', ('time', {}), { - 'doc': 'The date on which the person died.', - }), - ('img', ('file:bytes', {}), { - 'deprecated': True, - 'doc': 'Deprecated: use ps:person:photo.' - }), - ('photo', ('file:bytes', {}), { - 'doc': 'The primary image of a person.' - }), + 'doc': 'The date on which the person died.'}), + + #('img', ('file:bytes', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated: use ps:person:photo.' + #}), + # entity:contact:inco + #('photo', ('file:bytes', {}), { + # 'doc': 'The primary image of a person.' + #}), ('nick', ('inet:user', {}), { 'doc': 'A username commonly used by the person.', }), ('vitals', ('ps:vitals', {}), { 'doc': 'The most recent known vitals for the person.', }), - ('name', ('ps:name', {}), { - 'doc': 'The localized name for the person.', - }), - ('name:sur', ('ps:tokn', {}), { - 'doc': 'The surname of the person.' - }), - ('name:middle', ('ps:tokn', {}), { - 'doc': 'The middle name of the person.' - }), - ('name:given', ('ps:tokn', {}), { - 'doc': 'The given name of the person.' - }), + #('name', ('ps:name', {}), { + # 'doc': 'The localized name for the person.', + #}), + # FIXME deprecate + #('name:sur', ('ps:tokn', {}), { + # 'doc': 'The surname of the person.' + #}), + #('name:middle', ('ps:tokn', {}), { + # 'doc': 'The middle name of the person.' + #}), + #('name:given', ('ps:tokn', {}), { + # 'doc': 'The given name of the person.' + #}), ('names', ('array', {'type': 'ps:name', 'uniq': True, 'sorted': True}), { - 'doc': 'Variations of the name for the person.' - }), + # 'doc': 'Variations of the name for the person.' + #}), ('nicks', ('array', {'type': 'inet:user', 'uniq': True, 'sorted': True}), { 'doc': 'Usernames used by the person.' }), )), - ('ps:persona', {}, ( - ('person', ('ps:person', {}), { - 'doc': 'The real person behind the persona.', - }), - ('dob', ('time', {}), { - 'doc': 'The Date of Birth (DOB) if known.', - }), - ('img', ('file:bytes', {}), { - 'doc': 'The primary image of a suspected person.' - }), - ('nick', ('inet:user', {}), { - 'doc': 'A username commonly used by the suspected person.', - }), - ('name', ('ps:name', {}), { - 'doc': 'The localized name for the suspected person.', - }), - ('name:sur', ('ps:tokn', {}), { - 'doc': 'The surname of the suspected person.' - }), - ('name:middle', ('ps:tokn', {}), { - 'doc': 'The middle name of the suspected person.' - }), - ('name:given', ('ps:tokn', {}), { - 'doc': 'The given name of the suspected person.' - }), - ('names', ('array', {'type': 'ps:name', 'uniq': True, 'sorted': True}), { - 'doc': 'Variations of the name for a persona.' - }), - ('nicks', ('array', {'type': 'inet:user', 'uniq': True, 'sorted': True}), { - 'doc': 'Usernames used by the persona.' - }), - )), - ('ps:person:has', {}, ( - ('person', ('ps:person', {}), { - 'ro': True, - 'doc': 'The person who owns or controls the object or resource.', - }), - ('node', ('ndef', {}), { - 'ro': True, - 'doc': 'The object or resource that is owned or controlled by the person.', - }), - ('node:form', ('str', {}), { - 'ro': True, - 'doc': 'The form of the object or resource that is owned or controlled by the person.', - }), - )), - ('ps:persona:has', {}, ( - ('persona', ('ps:persona', {}), { - 'ro': True, - 'doc': 'The persona who owns or controls the object or resource.', - }), - ('node', ('ndef', {}), { - 'ro': True, - 'doc': 'The object or resource that is owned or controlled by the persona.', - }), - ('node:form', ('str', {}), { - 'ro': True, - 'doc': 'The form of the object or resource that is owned or controlled by the persona.', - }), - )), + #('ps:persona', {}, ( + # ('person', ('ps:person', {}), { + # 'doc': 'The real person behind the persona.', + # }), + # ('dob', ('time', {}), { + # 'doc': 'The Date of Birth (DOB) if known.', + # }), + # ('img', ('file:bytes', {}), { + # 'doc': 'The primary image of a suspected person.' + # }), + # ('nick', ('inet:user', {}), { + # 'doc': 'A username commonly used by the suspected person.', + # }), + # ('name', ('ps:name', {}), { + # 'doc': 'The localized name for the suspected person.', + # }), + # ('name:sur', ('ps:tokn', {}), { + # 'doc': 'The surname of the suspected person.' + # }), + # ('name:middle', ('ps:tokn', {}), { + # 'doc': 'The middle name of the suspected person.' + # }), + # ('name:given', ('ps:tokn', {}), { + # 'doc': 'The given name of the suspected person.' + # }), + # ('names', ('array', {'type': 'ps:name', 'uniq': True, 'sorted': True}), { + # 'doc': 'Variations of the name for a persona.' + # }), + # ('nicks', ('array', {'type': 'inet:user', 'uniq': True, 'sorted': True}), { + # 'doc': 'Usernames used by the persona.' + # }), + #)), + #('ps:person:has', {}, ( + # ('person', ('ps:person', {}), { + # 'ro': True, + # 'doc': 'The person who owns or controls the object or resource.', + # }), + # ('node', ('ndef', {}), { + # 'ro': True, + # 'doc': 'The object or resource that is owned or controlled by the person.', + # }), + # ('node:form', ('str', {}), { + # 'ro': True, + # 'doc': 'The form of the object or resource that is owned or controlled by the person.', + # }), + #)), + #('ps:persona:has', {}, ( + # ('persona', ('ps:persona', {}), { + # 'ro': True, + # 'doc': 'The persona who owns or controls the object or resource.', + # }), + # ('node', ('ndef', {}), { + # 'ro': True, + # 'doc': 'The object or resource that is owned or controlled by the persona.', + # }), + # ('node:form', ('str', {}), { + # 'ro': True, + # 'doc': 'The form of the object or resource that is owned or controlled by the persona.', + # }), + #)), ('ps:contact:type:taxonomy', {}, ()), ('ps:contact', {}, ( - ('org', ('ou:org', {}), { - 'doc': 'The org which this contact represents.', - }), - ('type', ('ps:contact:type:taxonomy', {}), { - 'doc': 'The type of contact which may be used for entity resolution.', - }), + # FIXME ps:contact no longer represents a person + #('org', ('ou:org', {}), { + #'doc': 'The org which this contact represents.', + #}), + # FIXME port all old contact types to unified taxonomy + #('type', ('ps:contact:type:taxonomy', {}), { + #'doc': 'The type of contact which may be used for entity resolution.'}), + ('asof', ('time', {}), { - 'date': 'The time this contact was created or modified.', - }), + 'date': 'The time this contact was created or modified.'}), + ('person', ('ps:person', {}), { - 'doc': 'The ps:person GUID which owns this contact.', - }), + 'doc': 'The ps:person GUID which owns this contact.'}), + ('vitals', ('ps:vitals', {}), { - 'doc': 'The most recent known vitals for the contact.', - }), - ('name', ('ps:name', {}), { - 'doc': 'The person name listed for the contact.', - }), + 'doc': 'The most recent known vitals for the contact.'}), + + #('name', ('ps:name', {}), { + # 'doc': 'The person name listed for the contact.', + #}), ('desc', ('str', {}), { - 'doc': 'A description of this contact.', - }), + 'doc': 'A description of this contact.'}), + ('title', ('ou:jobtitle', {}), { 'doc': 'The job/org title listed for this contact.'}), ('titles', ('array', {'type': 'ou:jobtitle', 'sorted': True, 'uniq': True}), { 'doc': 'An array of alternate titles for the contact.'}), - ('photo', ('file:bytes', {}), { - 'doc': 'The photo listed for this contact.', - }), + #('photo', ('file:bytes', {}), { + # 'doc': 'The photo listed for this contact.', + #}), + + # FIXME does this become "employer" and use entity protocol? ('orgname', ('ou:name', {}), { 'doc': 'The listed org/company name for this contact.', }), @@ -373,70 +407,80 @@ def getModelDefs(self): ('user', ('inet:user', {}), { 'doc': 'The username or handle for this contact.', }), - ('web:acct', ('inet:web:acct', {}), { - 'doc': 'The social media account for this contact.', - }), - ('web:group', ('inet:web:group', {}), { - 'doc': 'A web group representing this contact.', - }), + #('web:acct', ('inet:web:acct', {}), { + # 'doc': 'The social media account for this contact.', + #}), + #('web:group', ('inet:web:group', {}), { + # 'doc': 'A web group representing this contact.', + #}), ('birth:place', ('geo:place', {}), { - 'doc': 'A fully resolved place of birth for this contact.', - }), + 'doc': 'A fully resolved place of birth for this contact.'}), + ('birth:place:loc', ('loc', {}), { - 'doc': 'The loc of the place of birth of this contact.', - }), + 'doc': 'The loc of the place of birth of this contact.'}), + ('birth:place:name', ('geo:name', {}), { - 'doc': 'The name of the place of birth of this contact.', - }), + 'doc': 'The name of the place of birth of this contact.'}), + ('death:place', ('geo:place', {}), { - 'doc': 'A fully resolved place of death for this contact.', - }), + 'doc': 'A fully resolved place of death for this contact.'}), + ('death:place:loc', ('loc', {}), { - 'doc': 'The loc of the place of death of this contact.', - }), + 'doc': 'The loc of the place of death of this contact.'}), + ('death:place:name', ('geo:name', {}), { - 'doc': 'The name of the place of death of this contact.', - }), + 'doc': 'The name of the place of death of this contact.'}), + ('dob', ('time', {}), { - 'doc': 'The date of birth for this contact.', - }), + 'doc': 'The date of birth for this contact.'}), + ('dod', ('time', {}), { - 'doc': 'The date of death for this contact.', - }), - ('url', ('inet:url', {}), { - 'doc': 'The home or main site for this contact.', - }), - ('email', ('inet:email', {}), { - 'doc': 'The main email address for this contact.', - }), - ('email:work', ('inet:email', {}), { - 'doc': 'The work email address for this contact.' - }), - ('loc', ('loc', {}), { - 'doc': 'Best known contact geopolitical location.' - }), - ('address', ('geo:address', {}), { - 'doc': 'The street address listed for the contact.', - 'disp': {'hint': 'text'} - }), - ('place', ('geo:place', {}), { - 'doc': 'The place associated with this contact.', - }), - ('place:name', ('geo:name', {}), { - 'doc': 'The reported name of the place associated with this contact.', - }), + 'doc': 'The date of death for this contact.'}), + + #('url', ('inet:url', {}), { + # 'doc': 'The home or main site for this contact.', + #}), + #('email', ('inet:email', {}), { + # 'doc': 'The main email address for this contact.', + #}), + + # FIXME trash + #('email:work', ('inet:email', {}), { + # 'doc': 'The work email address for this contact.' + #}), + + # geo:placed + #('loc', ('loc', {}), { + # 'doc': 'Best known contact geopolitical location.' + #}), + #('address', ('geo:address', {}), { + # 'doc': 'The street address listed for the contact.', + # 'disp': {'hint': 'text'} + #}), + #('place', ('geo:place', {}), { + # 'doc': 'The place associated with this contact.', + #}), + #('place:name', ('geo:name', {}), { + # 'doc': 'The reported name of the place associated with this contact.', + #}), + ('phone', ('tel:phone', {}), { 'doc': 'The main phone number for this contact.', }), - ('phone:fax', ('tel:phone', {}), { - 'doc': 'The fax number for this contact.', - }), - ('phone:work', ('tel:phone', {}), { - 'doc': 'The work phone number for this contact.', - }), + # FIXME trash + #('phone:fax', ('tel:phone', {}), { + # 'doc': 'The fax number for this contact.', + #}), + #('phone:work', ('tel:phone', {}), { + # 'doc': 'The work phone number for this contact.', + #}), + + # FIXME perhaps we should invert and make an id:number an entity:contact:info? ('id:number', ('ou:id:number', {}), { 'doc': 'An ID number issued by an org and associated with this contact.', }), + + # FIXME are these still how we want to track this? maybe tel:subscriber? ('adid', ('it:adid', {}), { 'doc': 'A Advertising ID associated with this contact.', }), @@ -450,18 +494,18 @@ def getModelDefs(self): 'doc': 'An IMSI associated with the contact.', }), # A few probable multi-fields for entity resolution - ('names', ('array', {'type': 'ps:name', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of associated names/aliases for the person.', - }), - ('orgnames', ('array', {'type': 'ou:name', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of associated names/aliases for the organization.', - }), - ('emails', ('array', {'type': 'inet:email', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of secondary/associated email addresses.', - }), - ('web:accts', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of secondary/associated web accounts.', - }), + #('names', ('array', {'type': 'ps:name', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of associated names/aliases for the person.', + #}), + #('orgnames', ('array', {'type': 'ou:name', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of associated names/aliases for the organization.', + #}), + #('emails', ('array', {'type': 'inet:email', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of secondary/associated email addresses.', + #}), + #('web:accts', ('array', {'type': 'inet:web:acct', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of secondary/associated web accounts.', + #}), ('id:numbers', ('array', {'type': 'ou:id:number', 'uniq': True, 'sorted': True}), { 'doc': 'An array of secondary/associated IDs.', }), @@ -479,38 +523,48 @@ def getModelDefs(self): 'doc': 'An array of alternative languages specified for the contact.'}), )), ('ps:vitals', {}, ( + ('asof', ('time', {}), { 'doc': 'The time the vitals were gathered or computed.'}), + ('contact', ('ps:contact', {}), { 'doc': 'The contact that the vitals are about.'}), + ('person', ('ps:person', {}), { 'doc': 'The person that the vitals are about.'}), + ('height', ('geo:dist', {}), { 'doc': 'The height of the person or contact.'}), + ('weight', ('mass', {}), { 'doc': 'The weight of the person or contact.'}), + ('econ:currency', ('econ:currency', {}), { 'doc': 'The currency that the price values are recorded using.'}), + ('econ:net:worth', ('econ:price', {}), { 'doc': 'The net worth of the contact.'}), + ('econ:annual:income', ('econ:price', {}), { 'doc': 'The yearly income of the contact.'}), # TODO: eye color etc. color names / rgb values? )), - ('ps:contactlist', {}, ( - ('contacts', ('array', {'type': 'ps:contact', 'uniq': True, 'split': ',', 'sorted': True}), { - 'doc': 'The array of contacts contained in the list.' - }), - ('source:host', ('it:host', {}), { - 'doc': 'The host from which the contact list was extracted.', - }), - ('source:file', ('file:bytes', {}), { - 'doc': 'The file from which the contact list was extracted.', - }), - ('source:acct', ('inet:web:acct', {}), { - 'doc': 'The web account from which the contact list was extracted.', - }), - )), + + # FIXME this is trash too... + #('ps:contactlist', {}, ( + # ('contacts', ('array', {'type': 'ps:contact', 'uniq': True, 'split': ',', 'sorted': True}), { + # 'doc': 'The array of contacts contained in the list.' + # }), + # ('source:host', ('it:host', {}), { + # 'doc': 'The host from which the contact list was extracted.', + # }), + # ('source:file', ('file:bytes', {}), { + # 'doc': 'The file from which the contact list was extracted.', + # }), + # ('source:acct', ('inet:web:acct', {}), { + # 'doc': 'The web account from which the contact list was extracted.', + # }), + #)), ('ps:skill:type:taxonomy', {}, ()), ('ps:skill', {}, ( @@ -524,6 +578,7 @@ def getModelDefs(self): ('ps:proficiency', {}, ( + # TODO rating / period ('skill', ('ps:skill', {}), { 'doc': 'The skill in which the contact is proficient.'}), diff --git a/synapse/models/risk.py b/synapse/models/risk.py index fbdd253b63..1bc16e2b5b 100644 --- a/synapse/models/risk.py +++ b/synapse/models/risk.py @@ -59,9 +59,9 @@ def getModelDefs(self): ('risk:vuln:soft:range', ('guid', {}), { 'doc': 'A contiguous range of software versions which contain a vulnerability.'}), - ('risk:hasvuln', ('guid', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use risk:vulnerable.'}), + #('risk:hasvuln', ('guid', {}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use risk:vulnerable.'}), ('risk:vulnerable', ('guid', {}), { 'doc': 'Indicates that a node is susceptible to a vulnerability.'}), @@ -266,9 +266,9 @@ def getModelDefs(self): ('sophistication', ('meta:sophistication', {}), { 'doc': "The reporting organization's assessed sophistication of the threat cluster."}), - ('techniques', ('array', {'type': 'ou:technique', 'sorted': True, 'uniq': True}), { - 'deprecated': True, - 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), + #('techniques', ('array', {'type': 'ou:technique', 'sorted': True, 'uniq': True}), { + #'deprecated': True, + #'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), ('merged:time', ('time', {}), { 'doc': 'The time that the reporting organization merged this threat cluster into another.'}), @@ -326,9 +326,9 @@ def getModelDefs(self): ('soft:names', ('array', {'type': 'it:prod:softname', 'uniq': True, 'sorted': True}), { 'doc': 'An array of alternate names for the tool, according to the reporting organization.'}), - ('techniques', ('array', {'type': 'ou:technique', 'uniq': True, 'sorted': True}), { - 'deprecated': True, - 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), + #('techniques', ('array', {'type': 'ou:technique', 'uniq': True, 'sorted': True}), { + #'deprecated': True, + #'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), ('mitre:attack:software', ('it:mitre:attack:software', {}), { 'doc': 'A mapping to a MITRE ATT&CK software if applicable.'}), @@ -421,181 +421,183 @@ def getModelDefs(self): ('cve', ('it:sec:cve', {}), { 'doc': 'The CVE ID of the vulnerability.'}), - ('cve:desc', ('str', {}), { - 'disp': {'hint': 'text'}, - 'doc': 'The description of the vulnerability according to the CVE database.'}), + # FIXME deprecate? + #('cve:desc', ('str', {}), { + # 'disp': {'hint': 'text'}, + # 'doc': 'The description of the vulnerability according to the CVE database.'}), - ('cve:url', ('inet:url', {}), { - 'doc': 'A URL linking this vulnerability to the CVE description.'}), + #('cve:url', ('inet:url', {}), { + # 'doc': 'A URL linking this vulnerability to the CVE description.'}), - ('cve:references', ('array', {'type': 'inet:url', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of documentation URLs provided by the CVE database.'}), + #('cve:references', ('array', {'type': 'inet:url', 'uniq': True, 'sorted': True}), { + # 'doc': 'An array of documentation URLs provided by the CVE database.'}), - ('nist:nvd:source', ('ou:name', {}), { - 'doc': 'The name of the organization which reported the vulnerability to NIST.'}), + #('nist:nvd:source', ('ou:name', {}), { + # 'doc': 'The name of the organization which reported the vulnerability to NIST.'}), - ('nist:nvd:published', ('time', {}), { - 'doc': 'The date the vulnerability was first published in the NVD.'}), + #('nist:nvd:published', ('time', {}), { + # 'doc': 'The date the vulnerability was first published in the NVD.'}), - ('nist:nvd:modified', ('time', {"ismax": True}), { - 'doc': 'The date the vulnerability was last modified in the NVD.'}), + #('nist:nvd:modified', ('time', {"ismax": True}), { + # 'doc': 'The date the vulnerability was last modified in the NVD.'}), - ('cisa:kev:name', ('str', {}), { - 'doc': 'The name of the vulnerability according to the CISA KEV database.'}), + #('cisa:kev:name', ('str', {}), { + # 'doc': 'The name of the vulnerability according to the CISA KEV database.'}), - ('cisa:kev:desc', ('str', {}), { - 'doc': 'The description of the vulnerability according to the CISA KEV database.'}), + #('cisa:kev:desc', ('str', {}), { + # 'doc': 'The description of the vulnerability according to the CISA KEV database.'}), - ('cisa:kev:action', ('str', {}), { - 'doc': 'The action to mitigate the vulnerability according to the CISA KEV database.'}), + #('cisa:kev:action', ('str', {}), { + # 'doc': 'The action to mitigate the vulnerability according to the CISA KEV database.'}), - ('cisa:kev:vendor', ('ou:name', {}), { - 'doc': 'The vendor name listed in the CISA KEV database.'}), + #('cisa:kev:vendor', ('ou:name', {}), { + # 'doc': 'The vendor name listed in the CISA KEV database.'}), - ('cisa:kev:product', ('it:prod:softname', {}), { - 'doc': 'The product name listed in the CISA KEV database.'}), + #('cisa:kev:product', ('it:prod:softname', {}), { + # 'doc': 'The product name listed in the CISA KEV database.'}), - ('cisa:kev:added', ('time', {}), { - 'doc': 'The date the vulnerability was added to the CISA KEV database.'}), + #('cisa:kev:added', ('time', {}), { + # 'doc': 'The date the vulnerability was added to the CISA KEV database.'}), - ('cisa:kev:duedate', ('time', {}), { - 'doc': 'The date the action is due according to the CISA KEV database.'}), + #('cisa:kev:duedate', ('time', {}), { + # 'doc': 'The date the action is due according to the CISA KEV database.'}), - ('cvss:v2', ('cvss:v2', {}), { - 'doc': 'The CVSS v2 vector for the vulnerability.'}), + #('cvss:v2', ('cvss:v2', {}), { + # 'doc': 'The CVSS v2 vector for the vulnerability.'}), - ('cvss:v2_0:score', ('float', {}), { - 'doc': 'The CVSS v2.0 overall score for the vulnerability.'}), + #('cvss:v2_0:score', ('float', {}), { + # 'doc': 'The CVSS v2.0 overall score for the vulnerability.'}), - ('cvss:v2_0:score:base', ('float', {}), { - 'doc': 'The CVSS v2.0 base score for the vulnerability.'}), + #('cvss:v2_0:score:base', ('float', {}), { + # 'doc': 'The CVSS v2.0 base score for the vulnerability.'}), - ('cvss:v2_0:score:temporal', ('float', {}), { - 'doc': 'The CVSS v2.0 temporal score for the vulnerability.'}), + #('cvss:v2_0:score:temporal', ('float', {}), { + # 'doc': 'The CVSS v2.0 temporal score for the vulnerability.'}), - ('cvss:v2_0:score:environmental', ('float', {}), { - 'doc': 'The CVSS v2.0 environmental score for the vulnerability.'}), + #('cvss:v2_0:score:environmental', ('float', {}), { + # 'doc': 'The CVSS v2.0 environmental score for the vulnerability.'}), + # FIXME virtual props? ('cvss:v3', ('cvss:v3', {}), { 'doc': 'The CVSS v3 vector for the vulnerability.'}), - ('cvss:v3_0:score', ('float', {}), { - 'doc': 'The CVSS v3.0 overall score for the vulnerability.'}), + #('cvss:v3_0:score', ('float', {}), { + # 'doc': 'The CVSS v3.0 overall score for the vulnerability.'}), - ('cvss:v3_0:score:base', ('float', {}), { - 'doc': 'The CVSS v3.0 base score for the vulnerability.'}), + #('cvss:v3_0:score:base', ('float', {}), { + # 'doc': 'The CVSS v3.0 base score for the vulnerability.'}), - ('cvss:v3_0:score:temporal', ('float', {}), { - 'doc': 'The CVSS v3.0 temporal score for the vulnerability.'}), + #('cvss:v3_0:score:temporal', ('float', {}), { + # 'doc': 'The CVSS v3.0 temporal score for the vulnerability.'}), - ('cvss:v3_0:score:environmental', ('float', {}), { - 'doc': 'The CVSS v3.0 environmental score for the vulnerability.'}), + #('cvss:v3_0:score:environmental', ('float', {}), { + # 'doc': 'The CVSS v3.0 environmental score for the vulnerability.'}), - ('cvss:v3_1:score', ('float', {}), { - 'doc': 'The CVSS v3.1 overall score for the vulnerability.'}), + #('cvss:v3_1:score', ('float', {}), { + # 'doc': 'The CVSS v3.1 overall score for the vulnerability.'}), - ('cvss:v3_1:score:base', ('float', {}), { - 'doc': 'The CVSS v3.1 base score for the vulnerability.'}), + #('cvss:v3_1:score:base', ('float', {}), { + # 'doc': 'The CVSS v3.1 base score for the vulnerability.'}), - ('cvss:v3_1:score:temporal', ('float', {}), { - 'doc': 'The CVSS v3.1 temporal score for the vulnerability.'}), + #('cvss:v3_1:score:temporal', ('float', {}), { + # 'doc': 'The CVSS v3.1 temporal score for the vulnerability.'}), - ('cvss:v3_1:score:environmental', ('float', {}), { - 'doc': 'The CVSS v3.1 environmental score for the vulnerability.'}), + #('cvss:v3_1:score:environmental', ('float', {}), { + # 'doc': 'The CVSS v3.1 environmental score for the vulnerability.'}), - ('cvss:av', ('str', {'enums': 'N,A,P,L'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:av', ('str', {'enums': 'N,A,P,L'}), { + #'deprecated': True, + #'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ac', ('str', {'enums': 'L,H'}), { - 'disp': {'enums': (('Low', 'L'), ('High', 'H'))}, - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), - - ('cvss:pr', ('str', {'enums': 'N,L,H'}), { - 'disp': {'enums': ( - {'title': 'None', 'value': 'N', 'doc': 'FIXME privs stuff'}, - {'title': 'Low', 'value': 'L', 'doc': 'FIXME privs stuff'}, - {'title': 'High', 'value': 'H', 'doc': 'FIXME privs stuff'}, - )}, - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:ac', ('str', {'enums': 'L,H'}), { + # 'disp': {'enums': (('Low', 'L'), ('High', 'H'))}, + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ui', ('str', {'enums': 'N,R'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:pr', ('str', {'enums': 'N,L,H'}), { + # 'disp': {'enums': ( + # {'title': 'None', 'value': 'N', 'doc': 'FIXME privs stuff'}, + # {'title': 'Low', 'value': 'L', 'doc': 'FIXME privs stuff'}, + # {'title': 'High', 'value': 'H', 'doc': 'FIXME privs stuff'}, + # )}, + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:s', ('str', {'enums': 'U,C'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:ui', ('str', {'enums': 'N,R'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:c', ('str', {'enums': 'N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:s', ('str', {'enums': 'U,C'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:i', ('str', {'enums': 'N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:c', ('str', {'enums': 'N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:a', ('str', {'enums': 'N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:i', ('str', {'enums': 'N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:e', ('str', {'enums': 'X,U,P,F,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:a', ('str', {'enums': 'N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:rl', ('str', {'enums': 'X,O,T,W,U'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:e', ('str', {'enums': 'X,U,P,F,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:rc', ('str', {'enums': 'X,U,R,C'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:rl', ('str', {'enums': 'X,O,T,W,U'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mav', ('str', {'enums': 'X,N,A,L,P'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:rc', ('str', {'enums': 'X,U,R,C'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mac', ('str', {'enums': 'X,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mav', ('str', {'enums': 'X,N,A,L,P'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mpr', ('str', {'enums': 'X,N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mac', ('str', {'enums': 'X,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mui', ('str', {'enums': 'X,N,R'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mpr', ('str', {'enums': 'X,N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ms', ('str', {'enums': 'X,U,C'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mui', ('str', {'enums': 'X,N,R'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mc', ('str', {'enums': 'X,N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:ms', ('str', {'enums': 'X,U,C'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:mi', ('str', {'enums': 'X,N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mc', ('str', {'enums': 'X,N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ma', ('str', {'enums': 'X,N,L,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:mi', ('str', {'enums': 'X,N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:cr', ('str', {'enums': 'X,L,M,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:ma', ('str', {'enums': 'X,N,L,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ir', ('str', {'enums': 'X,L,M,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:cr', ('str', {'enums': 'X,L,M,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), - ('cvss:ar', ('str', {'enums': 'X,L,M,H'}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :cvss:v3.'}), + #('cvss:ir', ('str', {'enums': 'X,L,M,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), + + #('cvss:ar', ('str', {'enums': 'X,L,M,H'}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :cvss:v3.'}), ('cvss:score', ('float', {}), { 'deprecated': True, @@ -626,32 +628,35 @@ def getModelDefs(self): 'doc': 'The maximum version which is vulnerable in this range.'}), )), - ('risk:hasvuln', {}, ( - ('vuln', ('risk:vuln', {}), { - 'doc': 'The vulnerability present in the target.'}), - ('person', ('ps:person', {}), { - 'doc': 'The vulnerable person.'}), - ('org', ('ou:org', {}), { - 'doc': 'The vulnerable org.'}), - ('place', ('geo:place', {}), { - 'doc': 'The vulnerable place.'}), - ('software', ('it:prod:softver', {}), { - 'doc': 'The vulnerable software.'}), - ('hardware', ('it:prod:hardware', {}), { - 'doc': 'The vulnerable hardware.'}), - ('spec', ('mat:spec', {}), { - 'doc': 'The vulnerable material specification.'}), - ('item', ('mat:item', {}), { - 'doc': 'The vulnerable material item.'}), - ('host', ('it:host', {}), { - 'doc': 'The vulnerable host.'}) - )), + #('risk:hasvuln', {}, ( + # ('vuln', ('risk:vuln', {}), { + # 'doc': 'The vulnerability present in the target.'}), + # ('person', ('ps:person', {}), { + # 'doc': 'The vulnerable person.'}), + # ('org', ('ou:org', {}), { + # 'doc': 'The vulnerable org.'}), + # ('place', ('geo:place', {}), { + # 'doc': 'The vulnerable place.'}), + # ('software', ('it:prod:softver', {}), { + # 'doc': 'The vulnerable software.'}), + # ('hardware', ('it:prod:hardware', {}), { + # 'doc': 'The vulnerable hardware.'}), + # ('spec', ('mat:spec', {}), { + # 'doc': 'The vulnerable material specification.'}), + # ('item', ('mat:item', {}), { + # 'doc': 'The vulnerable material item.'}), + # ('host', ('it:host', {}), { + # 'doc': 'The vulnerable host.'}) + #)), ('risk:vulnerable', {}, ( + ('vuln', ('risk:vuln', {}), { 'doc': 'The vulnerability that the node is susceptible to.'}), + ('period', ('ival', {}), { 'doc': 'The time window where the node was vulnerable.'}), + ('node', ('ndef', {}), { 'doc': 'The node which is vulnerable.'}), )), @@ -659,6 +664,7 @@ def getModelDefs(self): ('risk:alert:taxonomy', {}, {}), ('risk:alert:verdict:taxonomy', {}, {}), ('risk:alert', {}, ( + ('type', ('risk:alert:taxonomy', {}), { 'doc': 'A type for the alert, as a taxonomy entry.'}), @@ -805,11 +811,13 @@ def getModelDefs(self): 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), )), ('risk:attacktype', {}, ()), + ('risk:attack', {}, ( + ('desc', ('str', {}), { - 'doc': 'A description of the attack.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the attack.'}), + ('type', ('risk:attacktype', {}), { 'ex': 'cno.phishing', 'doc': 'A type for the attack, as a taxonomy entry.'}), @@ -850,88 +858,90 @@ def getModelDefs(self): ('prev', ('risk:attack', {}), { 'doc': 'The previous/parent attack in a list or hierarchy.'}), - ('actor:org', ('ou:org', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :attacker to allow entity resolution.'}), + #('actor:org', ('ou:org', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :attacker to allow entity resolution.'}), - ('actor:person', ('ps:person', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use :attacker to allow entity resolution.'}), + #('actor:person', ('ps:person', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use :attacker to allow entity resolution.'}), + # FIXME entity interface via ndef ('attacker', ('ps:contact', {}), { 'doc': 'Contact information representing the attacker.'}), - ('target', ('ps:contact', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), + #('target', ('ps:contact', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), - ('target:org', ('ou:org', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), + #('target:org', ('ou:org', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), - ('target:host', ('it:host', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), + #('target:host', ('it:host', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), - ('target:person', ('ps:person', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), + #('target:person', ('ps:person', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), - ('target:place', ('geo:place', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), + #('target:place', ('geo:place', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(targets)> light weight edges.'}), - ('via:ipv4', ('inet:ipv4', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('via:ipv4', ('inet:ipv4', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('via:ipv6', ('inet:ipv6', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('via:ipv6', ('inet:ipv6', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('via:email', ('inet:email', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('via:email', ('inet:email', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('via:phone', ('tel:phone', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('via:phone', ('tel:phone', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:vuln', ('risk:vuln', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:vuln', ('risk:vuln', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:url', ('inet:url', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:url', ('inet:url', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:host', ('it:host', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:host', ('it:host', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:email', ('inet:email', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:email', ('inet:email', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:file', ('file:bytes', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:file', ('file:bytes', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:server', ('inet:server', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:server', ('inet:server', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('used:software', ('it:prod:softver', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), + #('used:software', ('it:prod:softver', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use -(uses)> light weight edges.'}), - ('techniques', ('array', {'type': 'ou:technique', 'sorted': True, 'uniq': True}), { - 'deprecated': True, - 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), + #('techniques', ('array', {'type': 'ou:technique', 'sorted': True, 'uniq': True}), { + # 'deprecated': True, + # 'doc': 'Deprecated for scalability. Please use -(uses)> ou:technique.'}), ('url', ('inet:url', {}), { 'doc': 'A URL which documents the attack.'}), + # FIXME debate use of :ext ('ext:id', ('str', {}), { 'doc': 'An external unique ID for the attack.'}), @@ -1053,12 +1063,16 @@ def getModelDefs(self): 'doc': 'Payments made from the target to the attacker.'}), )), ('risk:technique:masquerade', {}, ( + ('node', ('ndef', {}), { 'doc': 'The node masquerading as another.'}), + ('period', ('ival', {}), { 'doc': 'The time period when the masquerading was active.'}), + ('target', ('ndef', {}), { 'doc': 'The being masqueraded as.'}), + ('technique', ('ou:technique', {}), { 'doc': 'The specific technique which describes the type of masquerading.'}), )), diff --git a/synapse/models/telco.py b/synapse/models/telco.py index 99b2119089..251c341334 100644 --- a/synapse/models/telco.py +++ b/synapse/models/telco.py @@ -153,6 +153,7 @@ def getModelDefs(self): ('tel:call', ('guid', {}), { 'doc': 'A guid for a telephone call record.'}), + # FIXME tel:text? tel:message? inet:service:message? ('tel:txtmesg', ('guid', {}), { 'doc': 'A guid for an individual text message.'}), @@ -160,6 +161,7 @@ def getModelDefs(self): 'ex': '49015420', 'doc': 'A mobile Type Allocation Code.'}), + # FIXME audit for comp types still being OK ('tel:mob:imid', ('comp', {'fields': (('imei', 'tel:mob:imei'), ('imsi', 'tel:mob:imsi'))}), { 'ex': '(490154203237518, 310150123456789)', 'doc': 'Fused knowledge of an IMEI/IMSI used together.'}), @@ -172,16 +174,13 @@ def getModelDefs(self): 'doc': 'A single mobile telemetry measurement.'}), ('tel:mob:mcc', ('str', {'regex': '^[0-9]{3}$', 'strip': 1}), { - 'doc': 'ITU Mobile Country Code.', - }), + 'doc': 'ITU Mobile Country Code.'}), ('tel:mob:mnc', ('str', {'regex': '^[0-9]{2,3}$', 'strip': 1}), { - 'doc': 'ITU Mobile Network Code.', - }), + 'doc': 'ITU Mobile Network Code.'}), ('tel:mob:carrier', ('comp', {'fields': (('mcc', 'tel:mob:mcc'), ('mnc', 'tel:mob:mnc'))}), { - 'doc': 'The fusion of a MCC/MNC.' - }), + 'doc': 'The fusion of a MCC/MNC.'}), ('tel:mob:cell', ('comp', {'fields': (('carrier', 'tel:mob:carrier'), ('lac', ('int', {})), @@ -193,97 +192,109 @@ def getModelDefs(self): 'forms': ( ('tel:phone', {}, ( - ('loc', ('loc', {}), { - 'doc': 'The location associated with the number.', - }), + # FIXME geo:placed? + #('loc', ('loc', {}), { + # 'doc': 'The location associated with the number.', + #}), )), ('tel:call', {}, ( + # FIXME src/dst -> source/target? ('src', ('tel:phone', {}), { - 'doc': 'The source phone number for a call.' - }), + 'doc': 'The source phone number for a call.'}), + ('dst', ('tel:phone', {}), { - 'doc': 'The destination phone number for a call.' - }), - ('time', ('time', {}), { - 'doc': 'The time the call was initiated.' - }), - ('duration', ('int', {}), { - 'doc': 'The duration of the call in seconds.' - }), + 'doc': 'The destination phone number for a call.'}), + + ('period', ('ival', {}), { + 'doc': 'The period of the phone call.'}), + + # FIXME deprecate + #('time', ('time', {}), { + #'doc': 'The time the call was initiated.'}), + + #('duration', ('int', {}), { + #'doc': 'The duration of the call in seconds.' + #}), ('connected', ('bool', {}), { - 'doc': 'Indicator of whether the call was connected.', - }), + 'doc': 'Indicator of whether the call was connected.'}), + ('text', ('str', {}), { - 'doc': 'The text transcription of the call.', 'disp': {'hint': 'text'}, - }), + 'doc': 'The text transcription of the call.'}), + ('file', ('file:bytes', {}), { - 'doc': 'A file containing related media.', - }), + 'doc': 'A file containing related media.'}), )), + ('tel:txtmesg', {}, ( ('from', ('tel:phone', {}), { - 'doc': 'The phone number assigned to the sender.' - }), + 'doc': 'The phone number assigned to the sender.'}), + ('to', ('tel:phone', {}), { - 'doc': 'The phone number assigned to the primary recipient.' - }), + 'doc': 'The phone number assigned to the primary recipient.'}), + ('recipients', ('array', {'type': 'tel:phone', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of phone numbers for additional recipients of the message.', - }), + 'doc': 'An array of phone numbers for additional recipients of the message.'}), + ('svctype', ('str', {'enums': 'sms,mms,rcs', 'strip': 1, 'lower': 1}), { - 'doc': 'The message service type (sms, mms, rcs).', - }), + 'doc': 'The message service type (sms, mms, rcs).'}), + ('time', ('time', {}), { - 'doc': 'The time the message was sent.' - }), + 'doc': 'The time the message was sent.'}), + ('text', ('str', {}), { - 'doc': 'The text of the message.', 'disp': {'hint': 'text'}, - }), + 'doc': 'The text of the message.'}), + ('file', ('file:bytes', {}), { - 'doc': 'A file containing related media.', - }), + 'doc': 'A file containing related media.' }), + )), + ('tel:mob:tac', {}, ( + #FIXME refactor! ('org', ('ou:org', {}), { - 'doc': 'The org guid for the manufacturer.', - }), + 'doc': 'The org guid for the manufacturer.' }), + ('manu', ('str', {'lower': 1}), { - 'doc': 'The TAC manufacturer name.', - }), + 'doc': 'The TAC manufacturer name.'}), + ('model', ('str', {'lower': 1}), { - 'doc': 'The TAC model name.', - }), + 'doc': 'The TAC model name.'}), + ('internal', ('str', {'lower': 1}), { - 'doc': 'The TAC internal model name.', - }), + 'doc': 'The TAC internal model name.'}), + )), + ('tel:mob:imei', {}, ( + ('tac', ('tel:mob:tac', {}), { 'ro': True, - 'doc': 'The Type Allocate Code within the IMEI.' - }), + 'doc': 'The Type Allocate Code within the IMEI.'}), + ('serial', ('int', {}), { 'ro': True, - 'doc': 'The serial number within the IMEI.', - }) + 'doc': 'The serial number within the IMEI.' }) )), + ('tel:mob:imsi', {}, ( + ('mcc', ('tel:mob:mcc', {}), { 'ro': True, - 'doc': 'The Mobile Country Code.', - }), + 'doc': 'The Mobile Country Code.'}), + )), ('tel:mob:imid', {}, ( + ('imei', ('tel:mob:imei', {}), { 'ro': True, - 'doc': 'The IMEI for the phone hardware.' - }), + 'doc': 'The IMEI for the phone hardware.'}), + ('imsi', ('tel:mob:imsi', {}), { 'ro': True, - 'doc': 'The IMSI for the phone subscriber.' - }), + 'doc': 'The IMSI for the phone subscriber.'}), + )), ('tel:mob:imsiphone', {}, ( ('phone', ('tel:phone', {}), { @@ -296,30 +307,40 @@ def getModelDefs(self): }), )), ('tel:mob:mcc', {}, ( - ('loc', ('loc', {}), {'doc': 'Location assigned to the MCC.'}), + # FIXME geo:placed + #('loc', ('loc', {}), {'doc': 'Location assigned to the MCC.'}), )), ('tel:mob:carrier', {}, ( + ('mcc', ('tel:mob:mcc', {}), { - 'ro': True, - }), + 'ro': True}), + ('mnc', ('tel:mob:mnc', {}), { - 'ro': True, - }), + 'ro': True}), + + # FIXME operator ('org', ('ou:org', {}), { - 'doc': 'Organization operating the carrier.' - }), - ('loc', ('loc', {}), { - 'doc': 'Location the carrier operates from.' - }), + 'doc': 'Organization operating the carrier.'}), + + # FIXME trash + #('loc', ('loc', {}), { + # 'doc': 'Location the carrier operates from.'}), )), + + # FIXME to guid ('tel:mob:cell', {}, ( ('carrier', ('tel:mob:carrier', {}), {'doc': 'Mobile carrier.', 'ro': True, }), - ('carrier:mcc', ('tel:mob:mcc', {}), {'doc': 'Mobile Country Code.', 'ro': True, }), - ('carrier:mnc', ('tel:mob:mnc', {}), {'doc': 'Mobile Network Code.', 'ro': True, }), - ('lac', ('int', {}), {'doc': 'Location Area Code. LTE networks may call this a TAC.', - 'ro': True, }), + # FIXME deprecate + #('carrier:mcc', ('tel:mob:mcc', {}), {'doc': 'Mobile Country Code.', 'ro': True, }), + #('carrier:mnc', ('tel:mob:mnc', {}), {'doc': 'Mobile Network Code.', 'ro': True, }), + ('lac', ('int', {}), { + 'ro': True, + 'doc': 'Location Area Code. LTE networks may call this a TAC.'}), + ('cid', ('int', {}), {'doc': 'The Cell ID.', 'ro': True, }), ('radio', ('str', {'lower': 1, 'onespace': 1}), {'doc': 'Cell radio type.'}), + + # FIXME geo:placed ('latlong', ('geo:latlong', {}), {'doc': 'Last known location of the cell site.'}), ('loc', ('loc', {}), { @@ -332,21 +353,24 @@ def getModelDefs(self): ('tel:mob:telem', {}, ( ('time', ('time', {}), {}), - ('latlong', ('geo:latlong', {}), {}), - ('http:request', ('inet:http:request', {}), { - 'doc': 'The HTTP request that the telemetry was extracted from.', - }), + # FIXME <(refs)- + #('http:request', ('inet:http:request', {}), { + #'doc': 'The HTTP request that the telemetry was extracted from.', + #}), + # FIXME it:host:activity? ('host', ('it:host', {}), { 'doc': 'The host that generated the mobile telemetry data.'}), - ('place', ('geo:place', {}), { - 'doc': 'The place representing the location of the mobile telemetry sample.'}), + # FIXME geo:placed + #('place', ('geo:place', {}), { + # 'doc': 'The place representing the location of the mobile telemetry sample.'}), - ('loc', ('loc', {}), { - 'doc': 'The geo-political location of the mobile telemetry sample.', - }), + #('latlong', ('geo:latlong', {}), {}), + #('loc', ('loc', {}), { + # 'doc': 'The geo-political location of the mobile telemetry sample.', + #}), ('accuracy', ('geo:dist', {}), { 'doc': 'The reported accuracy of the latlong telemetry reading.', @@ -360,9 +384,10 @@ def getModelDefs(self): ('phone', ('tel:phone', {}), {}), # inet protocol addresses + ('ip', ('inet:ip', {}), {}), ('mac', ('inet:mac', {}), {}), - ('ipv4', ('inet:ipv4', {}), {}), - ('ipv6', ('inet:ipv6', {}), {}), + #('ipv4', ('inet:ipv4', {}), {}), + #('ipv6', ('inet:ipv6', {}), {}), ('wifi', ('inet:wifi:ap', {}), {}), ('wifi:ssid', ('inet:wifi:ssid', {}), {}), @@ -370,10 +395,13 @@ def getModelDefs(self): # host specific data ('adid', ('it:adid', {}), {}), - ('aaid', ('it:os:android:aaid', {}), {}), - ('idfa', ('it:os:ios:idfa', {}), {}), + + # FIXME deprecated + #('aaid', ('it:os:android:aaid', {}), {}), + #('idfa', ('it:os:ios:idfa', {}), {}), # User related data + # FIXME contact ('name', ('ps:name', {}), {}), ('email', ('inet:email', {}), {}), ('acct', ('inet:web:acct', {}), {}), From 89edc16f9ee3c23ae3b8f4fd96664b4bfc399dfe Mon Sep 17 00:00:00 2001 From: visi Date: Wed, 3 Jul 2024 21:14:00 -0400 Subject: [PATCH 5/7] wip --- synapse/models/orgs.py | 267 +++++++++++++++++++++++------------------ 1 file changed, 148 insertions(+), 119 deletions(-) diff --git a/synapse/models/orgs.py b/synapse/models/orgs.py index 83d784adb4..d435e26d2f 100644 --- a/synapse/models/orgs.py +++ b/synapse/models/orgs.py @@ -45,21 +45,25 @@ def getModelDefs(self): ), }}), - ('ou:orgtype', ('taxonomy', {}), { - 'doc': 'An org type taxonomy.', + # FIXME + #('ou:orgtype', ('taxonomy', {}), { + ('ou:org:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), + 'doc': 'An org type taxonomy.'}), + ('ou:contract', ('guid', {}), { - 'doc': 'An contract between multiple entities.', - }), - ('ou:conttype', ('taxonomy', {}), { - 'doc': 'A contract type taxonomy.', + 'doc': 'An contract between multiple entities.'}), + + #FIXME + #('ou:conttype', ('taxonomy', {}), { + ('ou:contract:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), - ('ou:contract:type', ('str', {'enum': contracttypes}), { - 'deprecated': True, - 'doc': 'A pre-defined set of contract types.', - }), + 'doc': 'A contract type taxonomy.'}), + + #('ou:contract:type', ('str', {'enum': contracttypes}), { + # 'deprecated': True, + # 'doc': 'A pre-defined set of contract types.', + #}), ('ou:industry', ('guid', {}), { 'doc': 'An industry classification type.', 'display': { @@ -70,65 +74,74 @@ def getModelDefs(self): }), ('ou:industry:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - 'doc': 'An industry type taxonomy.', - }), - ('ou:industryname', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The name of an industry.', - }), + 'doc': 'An industry type taxonomy.'}), + + # FIXME entity:name + #('ou:industryname', ('str', {'lower': True, 'onespace': True}), { + #'doc': 'The name of an industry.'}), + + # FIXME i think we should get rid of this... ('ou:alias', ('str', {'lower': True, 'regex': r'^[0-9a-z_]+$'}), { - 'doc': 'An alias for the org GUID.', 'ex': 'vertexproject', - }), - ('ou:hasalias', ('comp', {'fields': (('org', 'ou:org'), ('alias', 'ou:alias'))}), { - 'deprecated': True, - 'doc': 'The knowledge that an organization has an alias.', - }), + 'doc': 'An alias for the org GUID.'}), + + #('ou:hasalias', ('comp', {'fields': (('org', 'ou:org'), ('alias', 'ou:alias'))}), { + # 'deprecated': True, + # 'doc': 'The knowledge that an organization has an alias.', + #}), ('ou:orgnet4', ('comp', {'fields': (('org', 'ou:org'), ('net', 'inet:net4'))}), { 'doc': "An organization's IPv4 netblock.", }), ('ou:orgnet6', ('comp', {'fields': (('org', 'ou:org'), ('net', 'inet:net6'))}), { 'doc': "An organization's IPv6 netblock.", }), + + # FIXME entity:name ('ou:name', ('str', {'lower': True, 'strip': True}), { 'doc': 'The name of an organization. This may be a formal name or informal name of the ' 'organization.', 'ex': 'acme corporation', }), - ('ou:member', ('comp', {'fields': (('org', 'ou:org'), ('person', 'ps:person'))}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:position.', - }), + + #('ou:member', ('comp', {'fields': (('org', 'ou:org'), ('person', 'ps:person'))}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use ou:position.', + #}), ('ou:position', ('guid', {}), { 'doc': 'A position within an org. May be organized into an org chart.', }), ('ou:suborg', ('comp', {'fields': (('org', 'ou:org'), ('sub', 'ou:org'))}), { 'doc': 'Any parent/child relationship between two orgs. May represent ownership, organizational structure, etc.', }), - ('ou:org:has', ('comp', {'fields': (('org', 'ou:org'), ('node', 'ndef'))}), { - 'deprecated': True, - 'doc': 'An org owns, controls, or has exclusive use of an object or resource, ' - 'potentially during a specific period of time.', - }), - ('ou:user', ('comp', {'fields': (('org', 'ou:org'), ('user', 'inet:user'))}), { - 'doc': 'A user name within an organization.', - }), - ('ou:role', ('str', {'lower': True, 'regex': r'^\w+$'}), { - 'ex': 'staff', - 'doc': 'A named role when participating in an event.', - }), + #('ou:org:has', ('comp', {'fields': (('org', 'ou:org'), ('node', 'ndef'))}), { + # 'deprecated': True, + # 'doc': 'An org owns, controls, or has exclusive use of an object or resource, ' + # 'potentially during a specific period of time.', + #}), + + # FIXME ditch this trash + #('ou:user', ('comp', {'fields': (('org', 'ou:org'), ('user', 'inet:user'))}), { + # 'doc': 'A user name within an organization.', + #}), + #('ou:role', ('str', {'lower': True, 'regex': r'^\w+$'}), { + # 'ex': 'staff', + # 'doc': 'A named role when participating in an event.', + #}), + + # FIXME "attendable" interface? ('ou:attendee', ('guid', {}), { - 'doc': 'A node representing a person attending a meeting, conference, or event.', - }), + 'doc': 'A node representing a person attending a meeting, conference, or event.'}), + ('ou:meet', ('guid', {}), { - 'doc': 'An informal meeting of people which has no title or sponsor. See also: ou:conference.', - }), + 'doc': 'An informal meeting of people which has no title or sponsor. See also: ou:conference.'}), + ('ou:preso', ('guid', {}), { - 'doc': 'A webinar, conference talk, or other type of presentation.', - }), - ('ou:meet:attendee', ('comp', {'fields': (('meet', 'ou:meet'), ('person', 'ps:person'))}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:attendee.', - }), + 'doc': 'A webinar, conference talk, or other type of presentation.'}), + + #('ou:meet:attendee', ('comp', {'fields': (('meet', 'ou:meet'), ('person', 'ps:person'))}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use ou:attendee.', + #}), ('ou:conference', ('guid', {}), { 'doc': 'A conference with a name and sponsoring org.', 'display': { @@ -138,23 +151,27 @@ def getModelDefs(self): ), }, }), - ('ou:conference:attendee', ('comp', {'fields': (('conference', 'ou:conference'), ('person', 'ps:person'))}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:attendee.', - }), + #('ou:conference:attendee', ('comp', {'fields': (('conference', 'ou:conference'), ('person', 'ps:person'))}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use ou:attendee.', + #}), + # FIXME "attendable" ('ou:conference:event', ('guid', {}), { 'doc': 'A conference event with a name and associated conference.', }), - ('ou:conference:event:attendee', ('comp', {'fields': (('conference', 'ou:conference:event'), ('person', 'ps:person'))}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:attendee.', - }), + #('ou:conference:event:attendee', ('comp', {'fields': (('conference', 'ou:conference:event'), ('person', 'ps:person'))}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use ou:attendee.', + #}), + # FIXME "attendable" ('ou:contest', ('guid', {}), { - 'doc': 'A competitive event resulting in a ranked set of participants.', - }), + 'doc': 'A competitive event resulting in a ranked set of participants.'}), + ('ou:contest:result', ('comp', {'fields': (('contest', 'ou:contest'), ('participant', 'ps:contact'))}), { 'doc': 'The results from a single contest participant.', }), + + # FIXME entity:goal? something else? doesn't belong in ou: ('ou:goal', ('guid', {}), { 'doc': 'An assessed or stated goal which may be abstract or org specific.', 'display': { @@ -163,23 +180,27 @@ def getModelDefs(self): ), }, }), - ('ou:goalname', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'A goal name.', - }), + # FIXME entity:name + #('ou:goalname', ('str', {'lower': True, 'onespace': True}), { + # 'doc': 'A goal name.', + #}), ('ou:goal:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), 'doc': 'A taxonomy of goal types.', }), - ('ou:hasgoal', ('comp', {'fields': (('org', 'ou:org'), ('goal', 'ou:goal'))}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use ou:org:goals.', - }), - ('ou:camptype', ('taxonomy', {}), { - 'doc': 'An campaign type taxonomy.', + #('ou:hasgoal', ('comp', {'fields': (('org', 'ou:org'), ('goal', 'ou:goal'))}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use ou:org:goals.', + #}), + # FIXME + #('ou:camptype', ('taxonomy', {}), { + ('ou:campaign:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), - ('ou:campname', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'A campaign name.'}), + 'doc': 'An campaign type taxonomy.'}), + + # FIXME entity:name + #('ou:campname', ('str', {'lower': True, 'onespace': True}), { + #'doc': 'A campaign name.'}), ('ou:campaign', ('guid', {}), { 'doc': "Represents an org's activity in pursuit of a goal.", @@ -193,8 +214,8 @@ def getModelDefs(self): }}), ('ou:conflict', ('guid', {}), { - 'doc': 'Represents a conflict where two or more campaigns have mutually exclusive goals.', - }), + 'doc': 'Represents a conflict where two or more campaigns have mutually exclusive goals.'}), + ('ou:contribution', ('guid', {}), { 'doc': 'Represents a specific instance of contributing material support to a campaign.'}), @@ -210,8 +231,9 @@ def getModelDefs(self): ('ou:technique:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - 'doc': 'An analyst defined taxonomy to classify techniques in different disciplines.', - }), + 'doc': 'An analyst defined taxonomy to classify techniques in different disciplines.'}), + + # FIXME discuss... Might be best to use an `:id` field on entity:contact ('ou:id:type', ('guid', {}), { 'doc': 'A type of id number issued by an org.', }), @@ -225,27 +247,28 @@ def getModelDefs(self): 'doc': 'A status update to an org:id:number.', }), ('ou:award', ('guid', {}), { - 'doc': 'An award issued by an organization.', - }), + 'doc': 'An award issued by an organization.'}), + ('ou:vitals', ('guid', {}), { - 'doc': 'Vital statistics about an org for a given time period.', - }), + 'doc': 'Vital statistics about an org for a given time period.'}), + ('ou:opening', ('guid', {}), { - 'doc': 'A job/work opening within an org.', - }), + 'doc': 'A job/work opening within an org.'}), + ('ou:jobtype', ('taxonomy', {}), { 'ex': 'it.dev.python', - 'doc': 'A taxonomy of job types.', 'interfaces': ('meta:taxonomy',), - }), + 'doc': 'A taxonomy of job types.'}), + ('ou:employment', ('taxonomy', {}), { 'ex': 'fulltime.salary', - 'doc': 'An employment type taxonomy.', 'interfaces': ('meta:taxonomy',), - }), + 'doc': 'An employment type taxonomy.'}), + + # FIXME entity:name? ('ou:jobtitle', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'A title for a position within an org.', - }), + 'doc': 'A title for a position within an org.'}), + ('ou:requirement', ('guid', {}), { 'doc': 'A specific requirement.'}), ), @@ -1136,56 +1159,62 @@ def getModelDefs(self): )), ('ou:contest', {}, ( ('name', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The name of the contest.', 'ex': 'defcon ctf 2020', - }), + 'doc': 'The name of the contest.'}), + ('type', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'The type of contest.', 'ex': 'cyber ctf', - }), + 'doc': 'The type of contest.'}), + ('family', ('str', {'lower': True, 'onespace': True}), { - 'doc': 'A name for a series of recurring contests.', 'ex': 'defcon ctf', - }), + 'doc': 'A name for a series of recurring contests.'}), + ('desc', ('str', {'lower': True}), { - 'doc': 'A description of the contest.', 'ex': 'the capture-the-flag event hosted at defcon 2020', 'disp': {'hint': 'text'}, - }), + 'doc': 'A description of the contest.'}), + ('url', ('inet:url', {}), { - 'doc': 'The contest website URL.' - }), - ('start', ('time', {}), { - 'doc': 'The contest start date / time.', - }), - ('end', ('time', {}), { - 'doc': 'The contest end date / time.', - }), - ('loc', ('loc', {}), { - 'doc': 'The geopolitical affiliation of the contest.', - }), + 'doc': 'The contest website URL.'}), + + ('period', ('ival', {}), { + 'doc': 'The time period where the contest was running.'}), + # FIXME deprecate + #('start', ('time', {}), { + # 'doc': 'The contest start date / time.', + #}), + #('end', ('time', {}), { + # 'doc': 'The contest end date / time.', + #}), + + # FIXME geo:placed ('place', ('geo:place', {}), { 'doc': 'The geo:place where the contest was held.', }), - ('latlong', ('geo:latlong', {}), { - 'doc': 'The latlong where the contest was held.', - }), + #('loc', ('loc', {}), { + # 'doc': 'The geopolitical affiliation of the contest.', + #}), + #('latlong', ('geo:latlong', {}), { + # 'doc': 'The latlong where the contest was held.', + #}), + ('conference', ('ou:conference', {}), { - 'doc': 'The conference that the contest is associated with.', - }), + 'doc': 'The conference that the contest is associated with.'}), + ('contests', ('array', {'type': 'ou:contest', 'split': ',', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of sub-contests that contributed to the rankings.', - }), + 'doc': 'An array of sub-contests that contributed to the rankings.'}), + ('sponsors', ('array', {'type': 'ps:contact', 'split': ',', 'uniq': True, 'sorted': True}), { - 'doc': 'Contact information for contest sponsors.', - }), + 'doc': 'Contact information for contest sponsors.'}), + ('organizers', ('array', {'type': 'ps:contact', 'split': ',', 'uniq': True, 'sorted': True}), { - 'doc': 'Contact information for contest organizers.', - }), + 'doc': 'Contact information for contest organizers.'}), + ('participants', ('array', {'type': 'ps:contact', 'split': ',', 'uniq': True, 'sorted': True}), { - 'doc': 'Contact information for contest participants.', - }), + 'doc': 'Contact information for contest participants.'}), )), + # FIXME unify the use case between results and participant ('ou:contest:result', {}, ( ('contest', ('ou:contest', {}), { 'ro': True, From 29285fd84f22f14614892375e3bea40faf5e45bd Mon Sep 17 00:00:00 2001 From: visi Date: Wed, 3 Jul 2024 21:36:06 -0400 Subject: [PATCH 6/7] wip --- synapse/models/biz.py | 372 +++++++++++++++++++++++------------------- 1 file changed, 200 insertions(+), 172 deletions(-) diff --git a/synapse/models/biz.py b/synapse/models/biz.py index a89c20c868..a7323ddef5 100644 --- a/synapse/models/biz.py +++ b/synapse/models/biz.py @@ -9,176 +9,196 @@ def getModelDefs(self): modl = { 'types': ( ('biz:rfp', ('guid', {}), { - 'doc': 'An RFP (Request for Proposal) soliciting proposals.', - }), + 'doc': 'An RFP (Request for Proposal) soliciting proposals.'}), + ('biz:deal', ('guid', {}), { - 'doc': 'A sales or procurement effort in pursuit of a purchase.', - }), + 'doc': 'A sales or procurement effort in pursuit of a purchase.'}), + ('biz:stake', ('guid', {}), { - 'doc': 'A stake or partial ownership in a company.', - }), + 'doc': 'A stake or partial ownership in a company.'}), + ('biz:listing', ('guid', {}), { - 'doc': 'A product or service being listed for sale at a given price by a specific seller.', - }), + 'doc': 'A product or service being listed for sale at a given price by a specific seller.'}), + + # FIXME deprecate and allow product trees ('biz:bundle', ('guid', {}), { - 'doc': 'A bundle allows construction of products which bundle instances of other products.', - }), + 'doc': 'A bundle allows construction of products which bundle instances of other products.'}), + ('biz:product', ('guid', {}), { - 'doc': 'A product which is available for purchase.', - }), + 'doc': 'A product which is available for purchase.'}), + ('biz:service', ('guid', {}), { - 'doc': 'A service which is performed by a specific organization.', - }), + 'doc': 'A service which is performed by a specific organization.'}), + ('biz:service:type:taxonomy', ('taxonomy', {}), { - 'doc': 'A taxonomy of service offering types.', 'interfaces': ('meta:taxonomy',), - }), - ('biz:dealstatus', ('taxonomy', {}), { - 'doc': 'A deal/rfp status taxonomy.', + 'doc': 'A taxonomy of service offering types.'}), + + #FIXME + #('biz:dealstatus', ('taxonomy', {}), { + ('biz:deal:status:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), - ('biz:dealtype', ('taxonomy', {}), { - 'doc': 'A deal type taxonomy.', + 'doc': 'A deal/rfp status taxonomy.'}), + + # FIXME + #('biz:dealtype', ('taxonomy', {}), { + ('biz:deal:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), - ('biz:prodtype', ('taxonomy', {}), { - 'doc': 'A product type taxonomy.', + 'doc': 'A deal type taxonomy.'}), + + # FIXME + #('biz:prodtype', ('taxonomy', {}), { + ('biz:product:type:taxonomy', ('taxonomy', {}), { 'interfaces': ('meta:taxonomy',), - }), + 'doc': 'A product type taxonomy.'}), + ), 'forms': ( - ('biz:dealtype', {}, ()), - ('biz:prodtype', {}, ()), - ('biz:dealstatus', {}, ()), + # FIXME + #('biz:dealtype', {}, ()), + #('biz:prodtype', {}, ()), + #('biz:dealstatus', {}, ()), + + ('biz:deal:type:taxonomy', {}, ()), + ('biz:product:type:taxonomy', {}, ()), + ('biz:deal:status:taxonomy', {}, ()), + ('biz:rfp', {}, ( ('ext:id', ('str', {}), { - 'doc': 'An externally specified identifier for the RFP.', - }), + 'doc': 'An externally specified identifier for the RFP.'}), + ('title', ('str', {}), { - 'doc': 'The title of the RFP.', - }), + 'doc': 'The title of the RFP.'}), + ('summary', ('str', {}), { 'disp': {'hint': 'text'}, - 'doc': 'A brief summary of the RFP.', - }), - ('status', ('biz:dealstatus', {}), { + 'doc': 'A brief summary of the RFP.'}), + + ('status', ('biz:deal:status:taxonomy', {}), { 'disp': {'hint': 'enum'}, - 'doc': 'The status of the RFP.', - }), + 'doc': 'The status of the RFP.'}), + ('url', ('inet:url', {}), { - 'doc': 'The official URL for the RFP.', - }), + 'doc': 'The official URL for the RFP.'}), + ('file', ('file:bytes', {}), { - 'doc': 'The RFP document.', - }), + 'doc': 'The RFP document.'}), + + # FIXME timeline interface with named events for things like this? + # biz:rfp:milestone? ('posted', ('time', {}), { - 'doc': 'The date/time that the RFP was posted.', - }), + 'doc': 'The date/time that the RFP was posted.'}), + ('quesdue', ('time', {}), { - 'doc': 'The date/time that questions are due.', - }), + 'doc': 'The date/time that questions are due.'}), + ('propdue', ('time', {}), { 'doc': 'The date/time that proposals are due.', }), ('contact', ('ps:contact', {}), { - 'doc': 'The contact information given for the org requesting offers.', - }), + 'doc': 'The contact information given for the org requesting offers.'}), + ('purchases', ('array', {'type': 'econ:purchase', 'uniq': True, 'sorted': True}), { - 'doc': 'Any known purchases that resulted from the RFP.', - }), - ('requirements', ('array', {'type': 'ou:goal', 'uniq': True, 'sorted': True}), {}), + 'doc': 'Any known purchases that resulted from the RFP.'}), + + # FIXME ou:goal -> ou:requirement + #('requirements', ('array', {'type': 'ou:goal', 'uniq': True, 'sorted': True}), {}), + ('requirements', ('array', {'type': 'ou:requirement', 'uniq': True, 'sorted': True}), {}), )), ('biz:deal', {}, ( ('title', ('str', {}), { - 'doc': 'A title for the deal.', - }), - ('type', ('biz:dealtype', {}), { - 'doc': 'The type of deal.', + 'doc': 'A title for the deal.'}), + + ('type', ('biz:deal:type:taxonomy', {}), { 'disp': {'hint': 'taxonomy'}, - }), - ('status', ('biz:dealstatus', {}), { - 'doc': 'The status of the deal.', + 'doc': 'The type of deal.'}), + + ('status', ('biz:deal:status:taxonomy', {}), { 'disp': {'hint': 'taxonomy'}, - }), + 'doc': 'The status of the deal.'}), + ('updated', ('time', {}), { - 'doc': 'The last time the deal had a significant update.', - }), + 'doc': 'The last time the deal had a significant update.'}), + ('contacted', ('time', {}), { - 'doc': 'The last time the contacts communicated about the deal.', - }), + 'doc': 'The last time the contacts communicated about the deal.'}), + ('rfp', ('biz:rfp', {}), { - 'doc': 'The RFP that the deal is in response to.', - }), + 'doc': 'The RFP that the deal is in response to.'}), + + # FIXME entity:contact protocol ('buyer', ('ps:contact', {}), { - 'doc': 'The primary contact information for the buyer.', - }), - ('buyer:org', ('ou:org', {}), { - 'doc': 'The buyer org.', - }), - ('buyer:orgname', ('ou:name', {}), { - 'doc': 'The reported ou:name of the buyer org.', - }), - ('buyer:orgfqdn', ('inet:fqdn', {}), { - 'doc': 'The reported inet:fqdn of the buyer org.', - }), + 'doc': 'The primary contact information for the buyer.'}), + #('buyer:org', ('ou:org', {}), { + # 'doc': 'The buyer org.', + #}), + #('buyer:orgname', ('ou:name', {}), { + # 'doc': 'The reported ou:name of the buyer org.', + #}), + #('buyer:orgfqdn', ('inet:fqdn', {}), { + # 'doc': 'The reported inet:fqdn of the buyer org.', + #}), + + # FIXME entity:contact protocol ('seller', ('ps:contact', {}), { - 'doc': 'The primary contact information for the seller.', - }), - ('seller:org', ('ou:org', {}), { - 'doc': 'The seller org.', - }), - ('seller:orgname', ('ou:name', {}), { - 'doc': 'The reported ou:name of the seller org.', - }), - ('seller:orgfqdn', ('inet:fqdn', {}), { - 'doc': 'The reported inet:fqdn of the seller org.', - }), + 'doc': 'The primary contact information for the seller.'}), + + #('seller:org', ('ou:org', {}), { + # 'doc': 'The seller org.', + #}), + #('seller:orgname', ('ou:name', {}), { + # 'doc': 'The reported ou:name of the seller org.', + #}), + #('seller:orgfqdn', ('inet:fqdn', {}), { + # 'doc': 'The reported inet:fqdn of the seller org.', + #}), ('currency', ('econ:currency', {}), { - 'doc': 'The currency of econ:price values associated with the deal.', - }), + 'doc': 'The currency of econ:price values associated with the deal.'}), + ('buyer:budget', ('econ:price', {}), { - 'doc': 'The buyers budget for the eventual purchase.', - }), + 'doc': 'The buyers budget for the eventual purchase.'}), + ('buyer:deadline', ('time', {}), { - 'doc': 'When the buyer intends to make a decision.', - }), + 'doc': 'When the buyer intends to make a decision.'}), + ('offer:price', ('econ:price', {}), { - 'doc': 'The total price of the offered products.', - }), + 'doc': 'The total price of the offered products.'}), + ('offer:expires', ('time', {}), { - 'doc': 'When the offer expires.', - }), - ('purchase', ('econ:purchase', {}), { - 'doc': 'Records a purchase resulting from the deal.', - }), - )), - ('biz:bundle', {}, ( - ('count', ('int', {}), { - 'doc': 'The number of instances of the product or service included in the bundle.', - }), - ('price', ('econ:price', {}), { - 'doc': 'The price of the bundle.', - }), - ('product', ('biz:product', {}), { - 'doc': 'The product included in the bundle.', - }), - ('service', ('biz:service', {}), { - 'doc': 'The service included in the bundle.', - }), - ('deal', ('biz:deal', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use econ:receipt:item for instances of bundles being sold.', - }), + 'doc': 'When the offer expires.'}), + ('purchase', ('econ:purchase', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use econ:receipt:item for instances of bundles being sold.', - }), + 'doc': 'Records a purchase resulting from the deal.'}), )), + # FIXME trash this? + #('biz:bundle', {}, ( + # ('count', ('int', {}), { + # 'doc': 'The number of instances of the product or service included in the bundle.', + # }), + # ('price', ('econ:price', {}), { + # 'doc': 'The price of the bundle.', + # }), + # ('product', ('biz:product', {}), { + # 'doc': 'The product included in the bundle.', + # }), + # ('service', ('biz:service', {}), { + # 'doc': 'The service included in the bundle.', + # }), + # ('deal', ('biz:deal', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use econ:receipt:item for instances of bundles being sold.', + # }), + # ('purchase', ('econ:purchase', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use econ:receipt:item for instances of bundles being sold.', + # }), + #)), ('biz:listing', {}, ( ('seller', ('ps:contact', {}), { 'doc': 'The contact information for the seller.'}), + # FIXME convert product/service to an ndef and :selling (or something) ('product', ('biz:product', {}), { 'doc': 'The product being offered.'}), @@ -206,98 +226,106 @@ def getModelDefs(self): ('count:remaining', ('int', {'min': 0}), { 'doc': 'The current remaining number of instances for sale.'}), )), + ('biz:service', {}, ( + ('provider', ('ps:contact', {}), { 'doc': 'The contact info of the entity which performs the service.'}), + ('name', ('str', {'lower': True, 'onespace': True}), { 'doc': 'The name of the service being performed.'}), + ('summary', ('str', {}), { 'disp': {'hint': 'text'}, 'doc': 'A brief summary of the service.'}), + ('type', ('biz:service:type:taxonomy', {}), { 'doc': 'A taxonomy of service types.'}), + ('launched', ('time', {}), { 'doc': 'The time when the operator first made the service available.'}), # TODO: billing types (fixed, hourly, subscription, etc) )), + ('biz:product', {}, ( ('name', ('str', {}), { - 'doc': 'The name of the product.', - }), + 'doc': 'The name of the product.'}), + ('type', ('biz:prodtype', {}), { - 'doc': 'The type of product.', 'disp': {'hint': 'taxonomy'}, - }), + 'doc': 'The type of product.'}), + # TODO ('upc', ('biz:upc', {}), {}), ('summary', ('str', {}), { - 'doc': 'A brief summary of the product.', 'disp': {'hint': 'text'}, - }), + 'doc': 'A brief summary of the product.'}), + ('maker', ('ps:contact', {}), { - 'doc': 'A contact for the maker of the product.', - }), - ('madeby:org', ('ou:org', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use biz:product:maker.', - }), - ('madeby:orgname', ('ou:name', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use biz:product:maker.', - }), - ('madeby:orgfqdn', ('inet:fqdn', {}), { - 'deprecated': True, - 'doc': 'Deprecated. Please use biz:product:maker.', - }), + 'doc': 'A contact for the maker of the product.'}), + + #('madeby:org', ('ou:org', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use biz:product:maker.', + #}), + #('madeby:orgname', ('ou:name', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use biz:product:maker.', + #}), + #('madeby:orgfqdn', ('inet:fqdn', {}), { + # 'deprecated': True, + # 'doc': 'Deprecated. Please use biz:product:maker.', + #}), ('price:retail', ('econ:price', {}), { - 'doc': 'The MSRP price of the product.', - }), + 'doc': 'The MSRP price of the product.'}), + ('price:bottom', ('econ:price', {}), { - 'doc': 'The minimum offered or observed price of the product.', - }), + 'doc': 'The minimum offered or observed price of the product.'}), + ('price:currency', ('econ:currency', {}), { - 'doc': 'The currency of the retail and bottom price properties.', - }), + 'doc': 'The currency of the retail and bottom price properties.'}), + + # FIXME move to :includes as an array of ndefs? ('bundles', ('array', {'type': 'biz:bundle', 'uniq': True, 'sorted': True}), { - 'doc': 'An array of bundles included with the product.', - }), + 'doc': 'An array of bundles included with the product.'}), + )), ('biz:stake', {}, ( ('vitals', ('ou:vitals', {}), { - 'doc': 'The ou:vitals snapshot this stake is part of.', - }), + 'doc': 'The ou:vitals snapshot this stake is part of.'}), + + # FIXME org entity protocol ('org', ('ou:org', {}), { - 'doc': 'The resolved org.', - }), + 'doc': 'The resolved org.'}), + ('orgname', ('ou:name', {}), { - 'doc': 'The org name as reported by the source of the vitals.', - }), + 'doc': 'The org name as reported by the source of the vitals.'}), + ('orgfqdn', ('inet:fqdn', {}), { - 'doc': 'The org FQDN as reported by the source of the vitals.', - }), + 'doc': 'The org FQDN as reported by the source of the vitals.'}), + ('name', ('str', {}), { - 'doc': 'An arbitrary name for this stake. Can be non-contact like "pool".', - }), + 'doc': 'An arbitrary name for this stake. Can be non-contact like "pool".'}), + ('asof', ('time', {}), { - 'doc': 'The time the stake is being measured. Likely as part of an ou:vitals.', - }), + 'doc': 'The time the stake is being measured. Likely as part of an ou:vitals.'}), + ('shares', ('int', {}), { - 'doc': 'The number of shares represented by the stake.', - }), + 'doc': 'The number of shares represented by the stake.'}), + ('invested', ('econ:price', {}), { - 'doc': 'The amount of money invested in the cap table iteration.', - }), + 'doc': 'The amount of money invested in the cap table iteration.'}), + ('value', ('econ:price', {}), { - 'doc': 'The monetary value of the stake.', - }), + 'doc': 'The monetary value of the stake.'}), + ('percent', ('hugenum', {}), { - 'doc': 'The percentage ownership represented by this stake.', - }), + 'doc': 'The percentage ownership represented by this stake.'}), + ('owner', ('ps:contact', {}), { - 'doc': 'Contact information of the owner of the stake.', - }), + 'doc': 'Contact information of the owner of the stake.'}), + ('purchase', ('econ:purchase', {}), { - 'doc': 'The purchase event for the stake.', - }), + 'doc': 'The purchase event for the stake.'}), )), ), } From 27279f22e3fc680d08d9686e979e97a1eaa63daf Mon Sep 17 00:00:00 2001 From: visi Date: Fri, 5 Jul 2024 14:33:11 -0400 Subject: [PATCH 7/7] wip --- synapse/models/entity.py | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 synapse/models/entity.py diff --git a/synapse/models/entity.py b/synapse/models/entity.py new file mode 100644 index 0000000000..a7cc4ed86f --- /dev/null +++ b/synapse/models/entity.py @@ -0,0 +1,99 @@ +import synapse.lib.module as s_module + +class EntityModule(s_module.CoreModule): + + def getModelDefs(self): + return (('entity', { + + 'types': ( + + # TODO eventually migrate ps:name / ou:name / it:prod:softname / etc + ('entity:name', ('str', {'onespace': True, 'lower': True}), { + 'doc': 'A name used to refer to an entity.'}), + + ('entity:contact:type:taxonomy', ('taxonomy', {}), { + 'interfaces': ('meta:taxonomy',), + 'doc': 'A taxonomy of contact types.'}), + + ('entity:contact', ('guid', {}), { + 'doc': 'A grouping of contact info associated with an entity.'}) + + ('entity:identity', ('ndef', {'interfaces': ('entity:contact:info',)}), { + 'doc': 'A reference to various entity types.'}), + + # FIXME this will replace most uses of :contact= + ('entity:actor', ('ndef', {'forms': ('ou:org', 'risk:threat', 'ps:person', 'ps:contact')}), { + 'doc': 'A subset of entities which have intent.'}), + + ('entity:affiliation:type:taxonomy', ('taxonomy', {}), { + 'interfaces': ('meta:taxonomy',), + 'doc': 'A taxonomy of affiliation types.'}), + + ('entity:affiliation', ('guid', {}), { + 'interfaces': ('entity:contact:info',), + 'doc': 'A non-directional relationship between multiple entities.'}), + + ('entity:relationship:type:taxonomy', ('taxonomy', {}), { + 'interfaces': ('meta:taxonomy',), + 'doc': 'A taxonomy of relationship types.'}), + + ('entity:relationship', ('guid', {}), { + 'doc': 'A directional relationship between 2 entities.'}), + + ), + + # FIXME can we currently declare edges based on interfaces? + 'edges': ( + + # FIXME maybe entity has/owns should be a form? + (('entity:contact:info', 'has', None), { + 'doc': 'The entity is or was in posession of the target node.'}), + + (('entity:contact:info', 'owns', None), { + 'doc': 'The entity owns or owned the target node.'}), + ), + + 'interfaces': ( + ('entity:contact:info', { + 'doc': '', + 'interfaces': ('geo:placed',), + 'props': ( + + ('name', ('entity:name', {}), { + #FIXME allow docs to swap in form names? + 'doc': 'The primary name of the {form}.'}), + + ('names', ('array', {'type': 'entity:name', 'sorted': True, 'uniq': True}), { + 'doc': 'An array of alternate names for the {form}.'}), + + ('email', ('inet:email', {}), { + 'doc': 'The primary email address associated with the {form}.'}), + + ('emails', ('array', {'type': 'entity:name', 'sorted': True, 'uniq': True}), { + 'doc': 'An array of alternate email addresses assciated with the {form}.'}), + + ('type', ('entity:contact:type:taxonomy', {}), { + 'doc': 'The type of entity.'}), + + ('photo', ('file:bytes', {}), { + 'doc': 'The primary image of the {form}.'}), + + ('url', ('inet:url', {}), { + 'doc': 'The primary URL assocated with the {form}.'}), + ), + }), + ), + + 'forms': ( + ('entity:name', {}, ()), + + ('entity:contact:type:taxonomy', {}, ()), + ('entity:contact', {}, ( + + ('name', ('entity:name', {}), { + 'doc': 'The name of the entity.'}), + + # + )), + ), + }),)