def test_lib_crypto_tnfl_cryptseq(self):
        txk = s_common.buid()
        rxk = s_common.buid()

        crypter1 = s_tinfoil.CryptSeq(rxk, txk)
        crypter2 = s_tinfoil.CryptSeq(txk, rxk)
        mesg = ('hehe', {'key': 'valu'})

        self.eq(str(crypter1._tx_sn), 'count(0)')
        self.eq(str(crypter2._rx_sn), 'count(0)')
        ct = crypter1.encrypt(mesg)
        self.isinstance(ct, bytes)
        self.eq(str(crypter1._tx_sn), 'count(1)')

        pt = crypter2.decrypt(ct)
        self.eq(str(crypter2._rx_sn), 'count(1)')
        self.eq(mesg, pt)

        self.raises(s_exc.CryptoErr, crypter1.decrypt, ct)
        self.eq(str(crypter1._rx_sn), 'count(0)')

        self.raises(s_exc.CryptoErr, crypter2.decrypt, ct)
        self.eq(
            str(crypter2._rx_sn),
            'count(2)')  # even though we fail, we've incremented the seqn valu
Beispiel #2
0
    async def test_axon_wput(self):

        async with self.getTestCore() as core:

            axon = core.axon
            axon.addHttpApi('/api/v1/pushfile', HttpPushFile, {'cell': axon})

            async with await axon.upload() as fd:
                await fd.write(b'asdfasdf')
                size, sha256 = await fd.save()

            host, port = await axon.addHttpsPort(0, host='127.0.0.1')

            async with axon.getLocalProxy() as proxy:

                resp = await proxy.wput(sha256, f'https://127.0.0.1:{port}/api/v1/pushfile', method='PUT', ssl=False)
                self.eq(True, resp['ok'])
                self.eq(200, resp['code'])

            opts = {'vars': {'sha256': s_common.ehex(sha256)}}
            q = f'return($lib.axon.wput($sha256, "https://127.0.0.1:{port}/api/v1/pushfile", ssl=(0)))'
            resp = await core.callStorm(q, opts=opts)
            self.eq(True, resp['ok'])
            self.eq(200, resp['code'])

            opts = {'vars': {'sha256': s_common.ehex(s_common.buid())}}
            resp = await core.callStorm(q, opts=opts)
            self.eq(False, resp['ok'])
            self.isin('Axon does not contain the requested file.', resp.get('mesg'))

            q = f'''
            $fields = $lib.list(
                $lib.dict(name=file, sha256=$sha256, filename=file),
                $lib.dict(name=zip_password, value=test)
            )
            $resp = $lib.inet.http.post("https://127.0.0.1:{port}/api/v1/pushfile",
                                        fields=$fields, ssl_verify=(0))
            return($resp)
            '''
            opts = {'vars': {'sha256': s_common.ehex(sha256)}}
            resp = await core.callStorm(q, opts=opts)
            self.true(resp['ok'])
            self.eq(200, resp['code'])

            opts = {'vars': {'sha256': s_common.ehex(s_common.buid())}}
            resp = await core.callStorm(q, opts=opts)
            self.false(resp['ok'])
            self.isin('Axon does not contain the requested file.', resp.get('err'))

            async with axon.getLocalProxy() as proxy:
                resp = await proxy.postfiles(fields, f'https://127.0.0.1:{port}/api/v1/pushfile', ssl=False)
                self.true(resp['ok'])
                self.eq(200, resp['code'])

        conf = {'http:proxy': 'socks5://user:[email protected]:1'}
        async with self.getTestAxon(conf=conf) as axon:
            async with axon.getLocalProxy() as proxy:
                resp = await proxy.postfiles(fields, f'https://127.0.0.1:{port}/api/v1/pushfile', ssl=False)
                self.false(resp['ok'])
                self.isin('Can not connect to proxy 127.0.0.1:1', resp.get('err', ''))
Beispiel #3
0
    def test_common_buid(self):
        byts = b'deadb33f00010203'

        iden = s_common.buid()
        self.isinstance(iden, bytes)
        self.len(32, iden)
        # Buids are random by default
        iden2 = s_common.buid()
        self.ne(iden, iden2)

        # buids may be derived from any msgpackable valu which is stable
        iden3 = s_common.buid(byts)
        evalu = b'\xde\x8a\x8a\x88\xbc \xd4\xc1\x81J\xf5\xc7\xbf\xbc\xd2T6\xba\xd0\xf1\x10\xaa\x07<\xfa\xe5\xfc\x8c\x93\xeb\xb4 '
        self.len(32, iden3)
        self.eq(iden3, evalu)
Beispiel #4
0
    def test_common_buid(self):
        byts = b'deadb33f00010203'

        iden = s_common.buid()
        self.isinstance(iden, bytes)
        self.len(32, iden)
        # Buids are random by default
        iden2 = s_common.buid()
        self.ne(iden, iden2)

        # buids may be derived from any msgpackable valu which is stable
        iden3 = s_common.buid(byts)
        evalu = b'\xde\x8a\x8a\x88\xbc \xd4\xc1\x81J\xf5\xc7\xbf\xbc\xd2T6\xba\xd0\xf1\x10\xaa\x07<\xfa\xe5\xfc\x8c\x93\xeb\xb4 '
        self.len(32, iden3)
        self.eq(iden3, evalu)
Beispiel #5
0
    async def test_axon_limits(self):

        async with self.getTestAxon(conf={'max:count': 10}) as axon:
            for i in range(10):
                await axon.put(s_common.buid())

            with self.raises(s_exc.HitLimit):
                await axon.put(s_common.buid())

        async with self.getTestAxon(conf={'max:bytes': 320}) as axon:
            for i in range(10):
                await axon.put(s_common.buid())

            with self.raises(s_exc.HitLimit):
                await axon.put(s_common.buid())
Beispiel #6
0
    def getLiftOpsV2(self, prop, valu, cmpr='='):

        if valu is None:
            iops = (('pref', b'\x00'),)
            return (
                ('indx', ('byprop', prop.pref, iops)),
            )

        if cmpr == '=':
            norm, info = self.norm(valu)
            iops = (
                ('eq', b'\x00' + s_common.buid(norm)),
            )
            return (
                ('indx', ('byprop', prop.pref, iops)),
            )

        if cmpr == 'contains=':
            norm, info = self.arraytype.norm(valu)
            byts = self.arraytype.indx(norm)
            iops = (
                ('eq', b'\x01' + self.arraytype.indx(norm)),
            )
            return (
                ('indx', ('byprop', prop.pref, iops)),
            )

        # TODO we *could* retrieve and munge the iops from arraytype...

        mesg = f'Array type has no lift by: {cmpr}.'
        raise s_exc.NoSuchCmpr(mesg=mesg)
Beispiel #7
0
    async def _getAddNodeEdits(self, name, valu, props=None):

        form = self.core.model.form(name)
        if form is None:
            raise s_exc.NoSuchForm(name=name)

        if form.isrunt:
            raise s_exc.IsRuntForm(mesg='Cannot make runt nodes.',
                                   form=form.full,
                                   prop=valu)

        if self.buidprefetch:
            norm, info = form.type.norm(valu)
            buid = s_common.buid((form.name, norm))
            node = await self.getNodeByBuid(buid)
            if node is not None:
                if props is not None:
                    return (node, await self.getNodeAdds(form,
                                                         valu,
                                                         props=props,
                                                         addnode=False))
                else:
                    return (node, [(buid, form.name, [])])

        return (None, await self.getNodeAdds(form, valu, props=props))
Beispiel #8
0
    def getStorNode(self, form):
        ndef = (form.name, form.type.norm(self.name)[0])
        buid = s_common.buid(ndef)

        ctor = '.'.join([self.__class__.__module__, self.__class__.__qualname__])
        props = {
            'doc': self.info.get('doc'),
            'ctor': ctor,
        }

        opts = {k: v for k, v in self.opts.items()}
        if opts:
            props['opts'] = opts

        if self.subof is not None:
            props['subof'] = self.subof

        pnorms = {}
        for prop, valu in props.items():
            formprop = form.props.get(prop)
            if formprop is not None and valu is not None:
                pnorms[prop] = formprop.type.norm(valu)[0]

        return (buid, {
            'ndef': ndef,
            'props': pnorms,
        })
 async def test_storm_node_iden(self):
     async with self.getTestCore() as core:
         nodes = await core.nodes(
             '[ test:int=10 test:str=$node.iden() ] +test:str')
         iden = s_common.ehex(s_common.buid(('test:int', 10)))
         self.eq(nodes[0].ndef, ('test:str', iden))
         self.len(1, nodes)
    async def test_cortex_remote_layer(self):

        async with self.getRemoteCores() as (directcore, core):
            # We write to directcore and make sure we can read from core

            await s_common.aspin(directcore.eval('[ test:str=woot :tick=2015 ]'))

            layr = core.view.layers[1]
            self.true(isinstance(layr, s_remotelayer.RemoteLayer))

            self.len(1, [x async for x in layr.iterFormRows('test:str')])
            self.len(1, [x async for x in layr.iterPropRows('test:str', 'tick')])

            iden = s_common.guid()

            buid = s_common.buid(('test:str', 'woot'))
            props = await layr.getBuidProps(buid)

            self.eq('woot', props.get('*test:str'))

            await layr.setOffset(iden, 200)
            self.eq(200, await layr.getOffset(iden))

            self.ne((), tuple([x async for x in layr.splices(0, 200)]))

            self.eq(s_modelrev.maxvers, await layr.getModelVers())
            await self.asyncraises(s_exc.SynErr, layr.setModelVers((9, 9, 9)))
Beispiel #11
0
    async def test_it_reveng(self):

        async with self.getTestCore() as core:

            baseFile = s_common.ehex(s_common.buid())
            fva = 0x404438
            fopt = {'vars': {'file': baseFile,
                             'func': s_common.guid(),
                             'fva': fva}}
            vstr = 'VertexBrandArtisanalBinaries'
            sopt = {'vars': {'func': fopt['vars']['func'],
                             'string': vstr}}
            fnode = await core.eval('[it:reveng:filefunc=($file, $func) :va=$fva]', opts=fopt).list()
            snode = await core.eval('[it:reveng:funcstr=($func, $string)]', opts=sopt).list()
            self.len(1, fnode)
            self.eq(f'sha256:{baseFile}', fnode[0].get('file'))
            self.eq(fva, fnode[0].get('va'))

            self.len(1, snode)
            self.eq(fnode[0].get('function'), snode[0].get('function'))
            self.eq(vstr, snode[0].get('string'))

            funcnode = await core.eval('it:reveng:function [ :name="FunkyFunction" :description="Test Function" ]').list()
            self.len(1, funcnode)
            self.eq("FunkyFunction", funcnode[0].get('name'))
            self.eq("Test Function", funcnode[0].get('description'))

            nodes = await core.eval(f'file:bytes={baseFile} -> it:reveng:filefunc :function -> it:reveng:funcstr:function').list()
            self.len(1, nodes)
            self.eq(vstr, nodes[0].get('string'))
Beispiel #12
0
    def getStorNode(self, form):

        ndef = (form.name, form.type.norm(self.full)[0])

        buid = s_common.buid(ndef)
        props = {
            'doc': self.info.get('doc', ''),
            'type': self.type.name,
            'relname': self.name,
            'univ': self.isuniv,
            'base': self.name.split(':')[-1],
            'ro': int(self.info.get('ro', False)),
            'extmodel': self.isext,
        }

        if self.form is not None:
            props['form'] = self.form.name

        pnorms = {}
        for prop, valu in props.items():
            formprop = form.props.get(prop)
            if formprop is not None and valu is not None:
                pnorms[prop] = formprop.type.norm(valu)[0]

        return (buid, {'props': pnorms, 'ndef': ndef})
Beispiel #13
0
    async def test_cortex_remote_layer(self):

        async with self.getRemoteCores() as (directcore, core):
            # We write to directcore and make sure we can read from core

            await s_common.aspin(
                directcore.eval('[ test:str=woot :tick=2015 ]'))

            layr = core.view.layers[1]
            self.true(isinstance(layr, s_remotelayer.RemoteLayer))

            self.len(1, [x async for x in layr.iterFormRows('test:str')])
            self.len(1,
                     [x async for x in layr.iterPropRows('test:str', 'tick')])
            self.len(2, [x async for x in layr.iterUnivRows('.created')])

            iden = s_common.guid()

            buid = s_common.buid(('test:str', 'woot'))
            props = await layr.getBuidProps(buid)

            self.eq('woot', props.get('*test:str'))

            await layr.setOffset(iden, 200)
            self.eq(200, await layr.getOffset(iden))

            await layr.delOffset(iden)
            self.eq(0, await layr.getOffset(iden))

            self.ne((), tuple([x async for x in layr.splices(0, 200)]))

            self.eq(s_modelrev.maxvers, await layr.getModelVers())
            await self.asyncraises(s_exc.SynErr, layr.setModelVers((9, 9, 9)))
Beispiel #14
0
    def getStorNode(self, form):

        ndef = (form.name, form.type.norm(self.name)[0])
        buid = s_common.buid(ndef)

        props = {
            'doc': self.info.get('doc', self.type.info.get('doc', '')),
            'type': self.type.name,
        }

        if form.name == 'syn:form':
            props['runt'] = self.isrunt
        elif form.name == 'syn:prop':
            props['univ'] = False
            props['extmodel'] = False
            props['form'] = self.name

        pnorms = {}
        for prop, valu in props.items():
            formprop = form.props.get(prop)
            if formprop is not None and valu is not None:
                pnorms[prop] = formprop.type.norm(valu)[0]

        return (buid, {
            'ndef': ndef,
            'props': pnorms,
        })
Beispiel #15
0
 def getRuntInfo(self):
     buid = s_common.buid(('syn:cron', self.iden))
     return buid, (
         ('*syn:cron', self.iden),
         ('doc', self.doc),
         ('name', self.name),
         ('storm', self.query),
     )
Beispiel #16
0
    async def test_stable_uids(self):
        with self.withStableUids():
            guid = s_common.guid()
            self.eq('000000', guid[:6])
            guid2 = s_common.guid()
            self.ne(guid, guid2)

            guid = s_common.guid(42)
            self.ne('000000', guid[:6])

            buid = s_common.buid()
            self.eq(b'\00\00\00\00\00\00', buid[:6])
            buid2 = s_common.buid()
            self.ne(buid, buid2)

            buid = s_common.buid(42)
            self.ne(b'\00\00\00\00\00\00', buid[:6])
Beispiel #17
0
 def indx(self, norm):
     # return a tuple of indx bytes and the layer will know what to do
     vals = []
     # prop=[foo,bar]
     vals.append(b'\x00' + s_common.buid(norm))
     # prop*contains=foo
     [vals.append(b'\x01' + self.arraytype.indx(v)) for v in norm]
     return vals
Beispiel #18
0
    async def addNode(self, name, valu, props=None):
        '''
        Add a node by form name and value with optional props.

        Args:
            name (str): The form of node to add.
            valu (obj): The value for the node.
            props (dict): Optional secondary properties for the node.

        Notes:
            If a props dictionary is provided, it may be mutated during node construction.

        Returns:
            s_node.Node: A Node object. It may return None if the snap is unable to add or lift the node.
        '''
        if self.readonly:
            mesg = 'The snapshot is in read-only mode.'
            raise s_exc.IsReadOnly(mesg=mesg)

        form = self.core.model.form(name)
        if form is None:
            raise s_exc.NoSuchForm(name=name)

        if form.isrunt:
            raise s_exc.IsRuntForm(mesg='Cannot make runt nodes.',
                                   form=form.full,
                                   prop=valu)

        try:

            if self.buidprefetch:
                norm, info = form.type.norm(valu)
                node = await self.getNodeByBuid(
                    s_common.buid((form.name, norm)))
                if node is not None:
                    # TODO implement node.setNodeProps()
                    if props is not None:
                        for p, v in props.items():
                            await node.set(p, v)
                    return node

            adds = await self.getNodeAdds(form, valu, props=props)

        except asyncio.CancelledError:  # pragma: no cover  TODO:  remove once >= py 3.8 only
            raise

        except Exception as e:
            if not self.strict:
                await self.warn(f'addNode: {e}')
                return None
            raise

        nodes = await self.applyNodeEdits(adds)
        assert len(nodes) >= 1

        # Adds is top-down, so the first node is what we want
        return nodes[0]
Beispiel #19
0
    async def getNodeByNdef(self, ndef):
        '''
        Return a single Node by (form,valu) tuple.

        Args:
            ndef ((str,obj)): A (form,valu) ndef tuple.

        Returns:
            (synapse.lib.node.Node): The Node or None.
        '''
        buid = s_common.buid(ndef)
        return await self.getNodeByBuid(buid)
Beispiel #20
0
    async def getNodeByNdef(self, ndef):
        '''
        Return a single Node by (form,valu) tuple.

        Args:
            ndef ((str,obj)): A (form,valu) ndef tuple.  valu must be
            normalized.

        Returns:
            (synapse.lib.node.Node): The Node or None.
        '''
        buid = s_common.buid(ndef)
        return await self.getNodeByBuid(buid)
Beispiel #21
0
    async def _initTestRunts(self):
        modl = self.core.model
        fnme = 'test:runt'
        form = modl.form(fnme)
        now = s_common.now()
        data = [
            (' BEEP ', {
                'tick': modl.type('time').norm('2001')[0],
                'lulz': 'beep.sys',
                '.created': now
            }),
            ('boop', {
                'tick': modl.type('time').norm('2010')[0],
                '.created': now
            }),
            ('blah', {
                'tick': modl.type('time').norm('2010')[0],
                'lulz': 'blah.sys'
            }),
            ('woah', {}),
        ]
        for pprop, propd in data:
            props = {}
            pnorm, _ = form.type.norm(pprop)

            for k, v in propd.items():
                prop = form.props.get(k)
                if prop:
                    norm, _ = prop.type.norm(v)
                    props[k] = norm

            props.setdefault('.created', s_common.now())

            rows = [('*' + fnme, pnorm)]
            for k, v in props.items():
                rows.append((k, v))

            buid = s_common.buid((fnme, pnorm))
            self._runtsByBuid[buid] = rows

            # Allow for indirect lookup to a set of buids
            self._runtsByPropValu[fnme].append(buid)
            self._runtsByPropValu[(fnme, pnorm)].append(buid)
            for k, propvalu in props.items():
                prop = fnme + ':' + k
                if k.startswith('.'):
                    prop = fnme + k
                self._runtsByPropValu[prop].append(buid)
                if modl.prop(prop).type.indx(propvalu):
                    # Can the secondary property be indexed for lift?
                    self._runtsByPropValu[(prop, propvalu)].append(buid)
    def test_lib_crypto_tnfl_cryptseq(self):
        txk = s_common.buid()
        rxk = s_common.buid()

        crypter1 = s_tinfoil.CryptSeq(rxk, txk)
        crypter2 = s_tinfoil.CryptSeq(txk, rxk)
        mesg = ('hehe', {'key': 'valu'})

        self.eq(str(crypter1._tx_sn), 'count(0)')
        self.eq(str(crypter2._rx_sn), 'count(0)')
        ct = crypter1.encrypt(mesg)
        self.isinstance(ct, bytes)
        self.eq(str(crypter1._tx_sn), 'count(1)')

        pt = crypter2.decrypt(ct)
        self.eq(str(crypter2._rx_sn), 'count(1)')
        self.eq(mesg, pt)

        self.raises(s_exc.CryptoErr, crypter1.decrypt, ct)
        self.eq(str(crypter1._rx_sn), 'count(0)')

        self.raises(s_exc.CryptoErr, crypter2.decrypt, ct)
        self.eq(str(crypter2._rx_sn), 'count(2)')  # even though we fail, we've incremented the seqn valu
Beispiel #23
0
    def _getNodeFnib(self, name, valu):
        '''
        return a form, norm, info, buid tuple
        '''
        form = self.model.form(name)
        if form is None:
            raise s_exc.NoSuchForm(name=name)

        try:
            norm, info = form.type.norm(valu)
        except Exception as e:
            raise s_exc.BadPropValu(prop=form.name, valu=valu, mesg=str(e))

        buid = s_common.buid((form.name, norm))
        return form, norm, info, buid
Beispiel #24
0
    def _getNodeFnib(self, name, valu):
        '''
        return a form, norm, info, buid tuple
        '''
        form = self.model.form(name)
        if form is None:
            raise s_exc.NoSuchForm(name=name)

        try:
            norm, info = form.type.norm(valu)
        except Exception as e:
            raise s_exc.BadPropValu(prop=form.name, valu=valu, mesg=str(e))

        buid = s_common.buid((form.name, norm))
        return form, norm, info, buid
Beispiel #25
0
    async def getNodeByNdef(self, ndef):
        '''
        Return a single Node() instance by (form,valu) tuple.
        '''
        name, valu = ndef

        form = self.model.forms.get(name)
        if form is None:
            raise s_exc.NoSuchForm(name=name)

        norm, info = form.type.norm(valu)

        buid = s_common.buid((form.name, norm))

        async with await self.snap() as snap:
            return await snap.getNodeByBuid(buid)
Beispiel #26
0
    def _filtSaveByts(self, files):

        todo = []
        with self.lenv.begin() as xact:

            curs = xact.cursor(db=self.blobhas)
            for byts in files:

                sha256 = hashlib.sha256(byts).digest()

                if curs.get(sha256):
                    continue

                todo.append((s_common.buid(), sha256, byts))

        return todo
Beispiel #27
0
    def getStorNode(self, form):

        ndef = (form.name, form.type.norm(self.name)[0])
        buid = s_common.buid(ndef)

        props = {
            'doc': self.info.get('doc', ''),
            'type': self.type.name,
        }

        pnorms = {}
        for prop, valu in props.items():
            formprop = form.props.get(prop)
            if formprop is not None and valu is not None:
                pnorms[prop] = formprop.type.norm(valu)[0]

        return (buid, {'ndef': ndef, 'props': pnorms})
Beispiel #28
0
    async def revModel20210528(self, layers):

        cmdtype = self.core.model.type('it:cmd')
        cmdprop = self.core.model.prop('it:exec:proc:cmd')

        for layr in layers:

            done = set()
            nodeedits = []

            meta = {
                'time': s_common.now(),
                'user': self.core.auth.rootuser.iden
            }

            async def save():
                await layr.storNodeEdits(nodeedits, meta)
                done.clear()
                nodeedits.clear()

            async for buid, propvalu in layr.iterPropRows(
                    'it:exec:proc', 'cmd'):

                cmdnorm = cmdtype.norm(propvalu)[0]

                if cmdnorm != propvalu:
                    nodeedits.append(
                        (buid, 'it:exec:proc',
                         ((s_layer.EDIT_PROP_SET,
                           ('cmd', cmdnorm, propvalu, s_layer.STOR_TYPE_UTF8),
                           ()), )), )

                if cmdnorm not in done:
                    cmdbuid = s_common.buid(('it:cmd', cmdnorm))
                    nodeedits.append(
                        (cmdbuid, 'it:cmd',
                         ((s_layer.EDIT_NODE_ADD,
                           (cmdnorm, s_layer.STOR_TYPE_UTF8), ()), )), )
                    done.add(cmdnorm)

                if len(nodeedits) >= 1000:
                    await save()

            if nodeedits:
                await save()
Beispiel #29
0
    async def editNodeNdef(self, oldv, newv):

        oldb = s_common.buid(oldv)

        for layr in self.layers:

            indx = await layr.getFormIndx(oldb)

            # save off any old indx valu so we can scan for them
            if indx is not None:
                self.slab.put(oldb, indx, overwrite=False, db=self.oldb2indx)

            await layr.editNodeNdef(oldv, newv)

        if self.ndefdelay is not None:
            self.ndefdelay.append((oldv, newv))
            return

        await self.editNdefProps(oldv, newv)
Beispiel #30
0
        async def walk(n, p):

            valu = n.props.get(p)
            if valu is None:
                return None

            prop = n.form.prop(p)
            if prop is None:
                return None

            if prop.modl.form(prop.type.name) is None:
                return None

            buid = s_common.buid((prop.type.name, valu))

            step = cache.get(buid, s_common.novalu)
            if step is s_common.novalu:
                step = cache[buid] = await node.snap.getNodeByBuid(buid)

            return step
Beispiel #31
0
    async def setNodeForm(self, layr, buid, name, oldv, newv):
        '''
        Reset the primary property for the given buid.
        '''
        form = self.core.model.form(name)

        norm, info = form.type.norm(newv)

        subtodo = []

        subs = info.get('subs')
        if subs is not None:
            subtodo = list(subs.items())

        newb = s_common.buid((name, norm))

        ops = []
        ops.extend(form.getDelOps(buid))
        ops.extend(form.getSetOps(newb, norm))

        # scoop up any set operations for form subs
        for subn, subv in subtodo:
            subp = self.core.model.prop(name + ':' + subn)
            if subp is None:
                continue

            ops.extend(subp.getDelOps(buid))
            ops.extend(subp.getSetOps(newb, subv))

        # rewrite the primary property and subs
        await layr.stor(ops)

        # update props in all layers
        await self.setNodeBuid(name, buid, newb)

        await self.setPropsByType(name, oldv, norm, info)

        oldndef = (name, oldv)
        newndef = (name, norm)

        await self.editNdefProps(oldndef, newndef)
Beispiel #32
0
    async def _initTestRunts(self):
        modl = self.core.model
        fnme = 'test:runt'
        form = modl.form(fnme)
        now = s_common.now()
        data = [(' BEEP ', {'tick': modl.type('time').norm('2001')[0], 'lulz': 'beep.sys', '.created': now}),
                ('boop', {'tick': modl.type('time').norm('2010')[0], '.created': now}),
                ('blah', {'tick': modl.type('time').norm('2010')[0], 'lulz': 'blah.sys'}),
                ('woah', {}),
                ]
        for pprop, propd in data:
            props = {}
            pnorm, _ = form.type.norm(pprop)

            for k, v in propd.items():
                prop = form.props.get(k)
                if prop:
                    norm, _ = prop.type.norm(v)
                    props[k] = norm

            props.setdefault('.created', s_common.now())

            rows = [('*' + fnme, pnorm)]
            for k, v in props.items():
                rows.append((k, v))

            buid = s_common.buid((fnme, pnorm))
            self._runtsByBuid[buid] = rows

            # Allow for indirect lookup to a set of buids
            self._runtsByPropValu[fnme].append(buid)
            self._runtsByPropValu[(fnme, pnorm)].append(buid)
            for k, propvalu in props.items():
                prop = fnme + ':' + k
                if k.startswith('.'):
                    prop = fnme + k
                self._runtsByPropValu[prop].append(buid)
                if modl.prop(prop).type.indx(propvalu):
                    # Can the secondary property be indexed for lift?
                    self._runtsByPropValu[(prop, propvalu)].append(buid)
Beispiel #33
0
    def _addRuntRows(self, form, valu, props, buidcache, propcache):
        buid = s_common.buid((form, valu))
        if buid in buidcache:
            return

        rows = [('*' + form, valu)]
        props.setdefault('.created', s_common.now())
        for k, v in props.items():
            rows.append((k, v))

        buidcache[buid] = rows

        propcache[form].append(buid)
        propcache[(form, valu)].append(buid)

        for k, propvalu in props.items():
            prop = form + ':' + k
            if k.startswith('.'):
                prop = form + k
            propcache[prop].append(buid)
            # Can the secondary property be indexed for lift?
            if self.model.prop(prop).type.indx(propvalu):
                propcache[(prop, propvalu)].append(buid)
Beispiel #34
0
    def _addModelRuntRows(self, form, valu, props):
        buid = s_common.buid((form, valu))
        if buid in self._modelRuntsByBuid:
            return

        rows = [('*' + form, valu)]
        props.setdefault('.created', s_common.now())
        for k, v in props.items():
            rows.append((k, v))

        self._modelRuntsByBuid[buid] = rows

        self._modelRuntsByPropValu[form].append(buid)
        self._modelRuntsByPropValu[(form, valu)].append(buid)

        for k, propvalu in props.items():
            prop = form + ':' + k
            if k.startswith('.'):
                prop = form + k
            self._modelRuntsByPropValu[prop].append(buid)
            # Can the secondary property be indexed for lift?
            if self.model.prop(prop).type.indx(propvalu):
                self._modelRuntsByPropValu[(prop, propvalu)].append(buid)
Beispiel #35
0
    def getStorNode(self, form):
        ndef = (form.name, form.type.norm(self.iden)[0])
        buid = s_common.buid(ndef)

        props = {
            'doc': self.tdef.get('doc', ''),
            'name': self.tdef.get('name', ''),
            'vers': self.tdef.get('ver', 1),
            'cond': self.tdef.get('cond'),
            'storm': self.tdef.get('storm'),
            'enabled': self.tdef.get('enabled'),
            'user': self.tdef.get('user'),
        }

        tag = self.tdef.get('tag')
        if tag is not None:
            props['tag'] = tag

        formprop = self.tdef.get('form')
        if formprop is not None:
            props['form'] = formprop

        prop = self.tdef.get('prop')
        if prop is not None:
            props['prop'] = prop

        pnorms = {}
        for prop, valu in props.items():
            formprop = form.props.get(prop)
            if formprop is not None and valu is not None:
                pnorms[prop] = formprop.type.norm(valu)[0]

        return (buid, {
            'ndef': ndef,
            'props': pnorms,
        })
Beispiel #36
0
    async def editNdefProps(self, oldndef, newndef):
        '''
        Change all props as a result of an ndef change.
        '''
        oldbuid = s_common.buid(oldndef)

        oldname, oldvalu = oldndef
        newname, newvalu = newndef

        rename = newname != oldname

        # we only need to update secondary props if they have diff vals
        # ( vs for example a pure rename )
        if oldvalu != newvalu:

            # get the indx bytes for the *value* of the ndef
            indx = self.slab.get(oldbuid, db=self.oldb2indx)
            if indx is not None:

                # the only way for indx to be None is if we dont have the node...
                for prop in self.core.model.getPropsByType(newname):

                    coff = prop.getCompOffs()

                    for layr in self.layers:

                        async for buid, valu in layr.iterPropIndx(prop.form.name, prop.name, indx):

                            await layr.storPropSet(buid, prop, newvalu)

                            # for now, assume any comp sub is on the same layer as it's form prop
                            if coff is not None:

                                ndef = await layr.getNodeNdef(buid)

                                edit = list(ndef[1])
                                edit[coff] = newvalu

                                await self.editNodeNdef(ndef, (ndef[0], edit))

        for prop in self.core.model.getPropsByType('ndef'):

            formsub = self.core.model.prop(prop.full + ':' + 'form')

            coff = prop.getCompOffs()

            for layr in self.layers:

                async for buid, valu in layr.iterPropIndx(prop.form.name, prop.name, oldbuid):

                    await layr.storPropSet(buid, prop, newndef)

                    if rename and formsub is not None:
                        await layr.storPropSet(buid, formsub, newname)

                    if coff is not None:

                        # for now, assume form and prop on the same layer...
                        ndef = await layr.getNodeNdef(buid)

                        edit = list(ndef[1])
                        edit[coff] = newndef

                        await self.editNodeNdef(ndef, (ndef[0], edit))
Beispiel #37
0
    async def _setops(self, name, valu, editatom, init=False):
        '''
        Generate operations to set a property on a node.
        '''
        prop = self.form.prop(name)
        if prop is None:

            if self.snap.strict:
                raise s_exc.NoSuchProp(name=name)

            await self.snap.warn(f'NoSuchProp: name={name}')
            return False

        if self.isrunt:
            if prop.info.get('ro'):
                raise s_exc.IsRuntForm(mesg='Cannot set read-only props on runt nodes',
                                       form=self.form.full, prop=name, valu=valu)
            return await self.snap.core.runRuntPropSet(self, prop, valu)

        curv = self.props.get(name)

        # normalize the property value...
        try:
            norm, info = prop.type.norm(valu)

        except Exception as e:
            mesg = f'Bad property value: {prop.full}={valu!r}'
            return await self.snap._raiseOnStrict(s_exc.BadPropValu, mesg, name=prop.name, valu=valu, emesg=str(e))

        # do we already have the value?
        if curv == norm:
            return False

        if curv is not None and not init:

            if prop.info.get('ro'):

                if self.snap.strict:
                    raise s_exc.ReadOnlyProp(name=prop.full)

                # not setting a set-once prop unless we are init...
                await self.snap.warn(f'ReadOnlyProp: name={prop.full}')
                return False

            # check for type specific merging...
            norm = prop.type.merge(curv, norm)
            if curv == norm:
                return False

        sops = prop.getSetOps(self.buid, norm)

        editatom.sops.extend(sops)

        # self.props[prop.name] = norm
        editatom.npvs.append((self, prop, curv, norm))

        # do we have any auto nodes to add?
        auto = self.snap.model.form(prop.type.name)
        if auto is not None:
            buid = s_common.buid((auto.name, norm))
            await self.snap._addNodeFnibOps((auto, norm, info, buid), editatom)

        # does the type think we have special auto nodes to add?
        # ( used only for adds which do not meet the above block )
        for autoname, autovalu in info.get('adds', ()):
            auto = self.snap.model.form(autoname)
            autonorm, autoinfo = auto.type.norm(autovalu)
            buid = s_common.buid((auto.name, autonorm))
            await self.snap._addNodeFnibOps((auto, autovalu, autoinfo, buid), editatom)

        # do we need to set any sub props?
        subs = info.get('subs')
        if subs is not None:

            for subname, subvalu in subs.items():

                full = prop.name + ':' + subname

                subprop = self.form.prop(full)
                if subprop is None:
                    continue

                await self._setops(full, subvalu, editatom, init=init)

        return True
Beispiel #38
0
    async def editNodeNdef(self, oldv, newv):
        '''
        Migration-only method

        Notes:
            Precondition: buid cache must be disabled
        '''
        assert self.buidcache.disabled

        oldb = s_common.buid(oldv)
        newb = s_common.buid(newv)

        pvoldval = s_msgpack.en((oldb,))
        pvnewval = s_msgpack.en((newb,))

        oldfenc = oldv[0].encode() + b'\x00'
        newfenc = newv[0].encode() + b'\x00'

        newprel = b'*' + newv[0].encode()

        newnindx = self.core.model.prop(newv[0]).type.indx(newv[1])

        # avoid any potential iter/edit issues...
        todo = list(self.layrslab.scanByPref(oldb, db=self.bybuid))

        for lkey, lval in todo:

            proputf8 = lkey[32:]
            valu, indx = s_msgpack.un(lval)

            # for the *<form> prop, the byprop index has <form><00><00><indx>
            if proputf8[0] == 42:

                newpropkey = newfenc + b'\x00' + newnindx

                if indx is not None:
                    oldpropkey = oldfenc + b'\x00' + indx
                    if not self.layrslab.delete(oldpropkey, pvoldval, db=self.byprop): # pragma: no cover
                        logger.warning(f'editNodeNdef del byprop missing for {repr(oldv)} {repr(oldpropkey)}')

                self.layrslab.put(newpropkey, pvnewval, dupdata=True, db=self.byprop)

                byts = s_msgpack.en((newv[1], newnindx))
                self.layrslab.put(newb + newprel, byts, db=self.bybuid)

            else:

                # <prop><00><indx>
                propindx = proputf8 + b'\x00' + indx

                if proputf8[0] in (46, 35): # ".univ" or "#tag"
                    self.layrslab.put(propindx, pvnewval, dupdata=True, db=self.byuniv)
                    self.layrslab.delete(propindx, pvoldval, db=self.byuniv)

                oldpropkey = oldfenc + propindx
                newpropkey = newfenc + propindx

                if not self.layrslab.delete(oldpropkey, pvoldval, db=self.byprop): # pragma: no cover
                    logger.warning(f'editNodeNdef del byprop missing for {repr(oldv)} {repr(oldpropkey)}')

                self.layrslab.put(newpropkey, pvnewval, dupdata=True, db=self.byprop)
                self.layrslab.put(newb + proputf8, lval, db=self.bybuid)

            self.layrslab.delete(lkey, db=self.bybuid)
Beispiel #39
0
 def indx(self, norm):
     return s_common.buid(norm)
Beispiel #40
0
 def getWaitFor(self, valu):
     norm, info = self.type.norm(valu)
     buid = s_common.buid((self.name, norm))
     evnt = asyncio.Event()
     self.waits[buid].append(evnt)
     return evnt