Пример #1
0
    async def validateQr(self, ipfsop, qrCid, iMsg):
        validCodes = 0
        try:
            codes = await self.app.rscAnalyzer.decodeQrCodes(qrCid)

            if not codes:
                # QR decoder not available, or invalid QR
                return False

            if len(codes) not in range(2, 4):
                return False

            for code in codes:
                if isinstance(code, IPFSPath):
                    if code.isIpns and str(code) == joinIpns(iMsg.peer):
                        validCodes += 1

                    if code.isIpfs:
                        computed = await ipfsop.hashComputeString(
                            iMsg.iphandle)

                        if computed['Hash'] == stripIpfs(code.objPath):
                            validCodes += 1
                elif isinstance(code, str) and ipidFormatValid(code) and \
                        code == iMsg.personDid:
                    validCodes += 1
        except Exception as e:
            log.debug('QR decode error: {}'.format(str(e)))
            return False
        else:
            # Just use 3 min codes here when we want the DID to be required
            return validCodes >= 2

        return False
Пример #2
0
    async def rpsUnpin(self, ipfsop, service, ipfsPath: IPFSPath):
        resolved = await ipfsop.resolve(ipfsPath.objPath, recursive=True)

        if not resolved:
            return False

        cid = stripIpfs(resolved)

        return await ipfsop.pinRemoteRemove(service.serviceName, cid=[cid])
Пример #3
0
    def path(self, rscPath):
        if isinstance(rscPath, str) and isIpfsPath(rscPath):
            path = stripIpfs(rscPath.rstrip('/')).replace('/', '_')
            comps = path.split('/')

            if len(comps) > 0:
                containerId = comps[0][0:8]
                containerPath = os.path.join(self.metaDbPath, containerId)
                metaPath = os.path.join(containerPath, path)
                return containerPath, metaPath, os.path.exists(metaPath)

        return None, None, False
Пример #4
0
    async def onIpldExplore(self, *args):
        """
        Open the IPLD explorer application for the current clipboard item
        """
        if not self.item:
            return

        mark = await database.hashmarksByObjTagLatest('#dapp-ipldexplorer')
        if mark:
            link = os.path.join(
                mark.path, '#', 'explore', stripIpfs(self.item.path))
            self.app.mainWindow.addBrowserTab().browseFsPath(link)
        else:
            messageBox('IPLD explorer hashmark not found')
Пример #5
0
    async def load(self, ipfsop, pin=True, initialCid=None,
                   resolveTimeout=30):
        if not initialCid:
            resolved = await self.resolve()

            if not resolved:
                self.message('Failed to resolve ?')
                return False

            dagCid = stripIpfs(resolved['Path'])
        else:
            self.message('Loading from initial CID: {}'.format(initialCid))
            dagCid = initialCid

        self.message('DID resolves to {}'.format(dagCid))

        if self.docCid == dagCid:
            # We already have this one

            self.message('DID document already at latest iteration')
            return False

        self._lastResolve = loopTime()

        if pin is True:
            await ipfsop.ctx.pin(dagCid, qname='ipid')

        self.message('Load: IPNS key resolved to {}'.format(dagCid))

        doc = await ipfsop.dagGet(dagCid)

        if doc:
            self._document = doc
            self._latestModified = doc.get('modified')
            self.docCid = dagCid
            await self.sChanged.emit(dagCid)

            if self.local:
                # Local IPID: propagate did services
                async for service in self.discoverServices():
                    await self.sServiceAvailable.emit(self, service)

            # Graph it
            await self.rdfPush()

            return True

        return False
Пример #6
0
    def hashmark(self, path):
        hashV = stripIpfs(path)
        hit = self.findByHash(hashV)

        title = hit.get('title', iUnknown()) if hit else hashV
        descr = hit.get('description', iUnknown()) if hit else ''
        type = hit.get('type') if hit else None
        pinSingle = (type == 'file')
        pinRecursive = (type == 'directory')

        ensure(
            addHashmarkAsync(path,
                             title=title,
                             description=descr,
                             pin=pinSingle,
                             pinRecursive=pinRecursive))
Пример #7
0
    async def load(self, ipfsop, pin=True, initialCid=None, resolveTimeout=30):
        if not initialCid:
            resolved = await self.resolve(resolveTimeout=resolveTimeout)

            if not resolved:
                self.message('Failed to resolve ?')
                return False

            dagCid = stripIpfs(resolved['Path'])
        else:
            self.message('Loading from initial CID: {}'.format(initialCid))
            dagCid = initialCid

        self.message('DID resolves to {}'.format(dagCid))

        if self.docCid == dagCid:
            # We already have this one

            self.message('DID document already at latest iteration')
            return False

        self._lastResolve = time.time()

        if pin is True:
            await ipfsop.ctx.pin(dagCid, qname='ipid')

        self.message('Load: IPNS key resolved to {}'.format(dagCid))

        doc = await ipfsop.dagGet(dagCid)

        if doc:
            self._document = doc
            self._latestModified = doc.get('modified')
            self.docCid = dagCid
            await self.sChanged.emit(dagCid)
            return True

        return False
Пример #8
0
 def explore(self, path):
     hashV = stripIpfs(path)
     if hashV:
         self.app.mainWindow.explore(hashV)
Пример #9
0
    async def link(self,
                   ipfsop,
                   peerId: str,
                   dagUid: str,
                   dagCid: str,
                   signerPubKeyCid: str,
                   local=False):

        self.debug(f'Branching for {peerId}')

        if not local:
            if not await ipfsop.pin(dagCid, recursive=False, timeout=120):
                self.debug(f'Branching for {peerId}: PIN {dagCid}: FAILED')
                return False
            else:
                self.debug(f'Branching for {peerId}: PIN {dagCid}: OK')

        pubKeyStatInfo = await ipfsop.objStatInfo(signerPubKeyCid)
        if not pubKeyStatInfo.valid or \
                pubKeyStatInfo.dataLargerThan(kilobytes(32)):
            return False

        pubKeyPem = await ipfsop.catObject(signerPubKeyCid, timeout=10)

        if not pubKeyPem:
            raise Exception(f'Cannot fetch pubkey with CID: {signerPubKeyCid}')

        # Keep it
        await ipfsop.pin(signerPubKeyCid, recursive=False, timeout=5)

        valid = await ipfsop.waitFor(self.analyze(peerId, dagCid, pubKeyPem),
                                     60)

        if not valid:
            self.debug(f'Invalid DAG: {dagCid}')
            return False
        else:
            self.debug(f'DAG is valid: {dagCid}')

        linkId = self.udbHash(peerId, dagUid)

        r = await self.resolve(f'nodes/{linkId}/link')
        self.debug(f'Branching for {peerId}: has {r}')

        if r and stripIpfs(r) == dagCid:
            self.debug(f'Branching for {peerId}: already at latest')
            return False

        # Link it
        async with self as dag:
            dag.root['nodes'][linkId] = {
                'datebranched': utcDatetimeIso(),
                'signerpubkey': self.ipld(signerPubKeyCid),
                'link': self.ipld(dagCid)
            }

            dag.root['data']['aggiter_uid'] = str(uuid.uuid4())
            sig = await ipfsop.ctx.rsaAgent.pssSign64(
                dag.root['data']['aggiter_uid'].encode())

            if sig:
                dag.root['signatures']['aggiter'] = sig

        # Link OK
        return True
Пример #10
0
    async def blogPost(self,
                       ipfsop,
                       title,
                       msg,
                       category=None,
                       tags=None,
                       author=None):
        async with self.edag:
            sHandle = self.profile.userInfo.spaceHandle

            username = sHandle.human
            uid = str(uuid.uuid4())
            postName = titleToPostName(title.strip().lower())

            exEntries = await self.blogEntries()
            if not postName or postName in exEntries:
                raise Exception('A blog post with this name already exists')

            now = datetime.now(timezone.utc)

            postObject = {
                'blogpost': {
                    'authordid': self.profile.userInfo.personDid,
                    'body': msg,
                    'title': title,
                    'uuid': uid,
                    'postname': postName,  # name of the post's DAG node
                    'tags': tags if tags else [],
                    'category': None,
                    'author': author if author else username,
                    'date_published': isoformat(now),
                    'date_modified': isoformat(now)
                }
            }

            # Create the DAG node for this post
            # Its view will be rendered later on

            self.dagBlog[postName] = {POST_NODEKEY: postObject}

        await ipfsop.sleep(2)
        await self.update()
        await ipfsop.sleep(1)

        result = await self.dagUser.resolve(
            posixIpfsPath.join(BLOG_NODEKEY, postName, 'view'))
        resolved = IPFSPath(result, autoCidConv=True)

        if isinstance(tags, list) and resolved.isIpfsRoot and resolved.valid:
            # Register the post by tag

            async with self.edag as dag:
                byTags = dag.root[BLOG_NODEKEY][TAGS_NODEKEY]

                for tag in tags:
                    if tag is None:
                        continue

                    planet, ptag = tag.split('#')
                    if not planet or not ptag:
                        continue

                    planet = planet.replace('@', '')

                    byTags.setdefault(planet, {})
                    byTags[planet].setdefault(ptag, {'_posts': []})

                    byTags[planet][ptag]['_posts'].append({
                        'name': postName,
                        'title': title,
                        'view': {
                            '/': stripIpfs(str(resolved))
                        }
                    })
                    byTags[planet][ptag]['index.html'] = await self.renderLink(
                        'usersite/bytag.html',
                        contained=True,
                        tag=tag,
                        tagposts=byTags[planet][ptag]['_posts'])

        logUser.info('Your blog post is online')
        return True