Esempio n. 1
0
    async def ipIdentifierInit(self, ipfsop, ipid: IPIdentifier):
        # Register the blog as an IP service on the DID
        blogPath = IPFSPath(joinIpns(self.keyRootId)).child('blog')
        await ipid.addServiceRaw(
            {
                'id': ipid.didUrl(path='/blog'),
                'type': IPService.SRV_TYPE_DWEBBLOG,
                'serviceEndpoint': blogPath.ipfsUrl
            },
            publish=False)

        # Register the Atom feed as an IP service on the DID
        feedPath = IPFSPath(joinIpns(self.keyRootId)).child('dfeed.atom')
        await ipid.addServiceRaw(
            {
                'id': ipid.didUrl(path='/feed'),
                'type': IPService.SRV_TYPE_ATOMFEED,
                'serviceEndpoint': feedPath.ipfsUrl,
                'description': 'Dweb Atom feed'
            },
            publish=False)

        await ipid.addServiceCollection('default')

        entry = await self.ctx.app.importQtResource('/share/icons/helmet.png')

        if entry:
            defAvatar = IPFSPath(entry['Hash'])
            await ipid.avatarSet(defAvatar.objPath)
Esempio n. 2
0
    async def resolve(self, ipfsop, resolveTimeout=None):
        resolveTimeout = resolveTimeout if resolveTimeout else \
            cGet('resolve.timeout')

        if self.local:
            hours = cGet('resolve.cacheLifetime.local.hours')
        else:
            hours = cGet('resolve.cacheLifetime.default.hours')

        maxLifetime = hours * 3600

        useCache = 'always'
        cache = 'always'

        self.message('DID resolve: {did} (using cache: {usecache})'.format(
            did=self.ipnsKey, usecache=useCache))

        return await ipfsop.nameResolveStreamFirst(
            joinIpns(self.ipnsKey),
            count=1,
            timeout=resolveTimeout,
            useCache=useCache,
            cache=cache,
            cacheOrigin='ipidmanager',
            maxCacheLifetime=maxLifetime
        )
Esempio n. 3
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
Esempio n. 4
0
    async def handleRequest(self, ipfsop, request, uid):
        rUrl = request.requestUrl()
        scheme = rUrl.scheme()
        host = rUrl.host()

        if not host:
            return self.urlInvalid(request)

        if scheme == SCHEME_IPFS:
            # hostname = base32-encoded CID or FQDN
            #
            # We keep a list (deque) of CIDs that have been validated.
            # If you hit a page which references a lot of other resources
            # for instance, this should be faster than regexp

            if domainValid(host):
                ipfsPathS = joinIpns(host) + rUrl.path()
            else:
                if host not in self.validCids:
                    if not ipfsRegSearchCid32(host):
                        return self.urlInvalid(request)

                    self.validCids.append(host)

                ipfsPathS = joinIpfs(host) + rUrl.path()
        elif scheme == SCHEME_IPNS:
            ipfsPathS = joinIpns(host) + rUrl.path()
        else:
            return self.urlInvalid(request)

        ipfsPath = IPFSPath(ipfsPathS)
        if not ipfsPath.valid:
            return self.urlInvalid(request)

        try:
            with async_timeout.timeout(self.requestTimeout):
                return await self.fetchFromPath(ipfsop, request, ipfsPath, uid)
        except asyncio.TimeoutError:
            return self.reqFailed(request)
        except Exception as err:
            # Any other error

            traceback.print_exc()
            self.debug(f'Unknown error while serving request: {err}')

            return self.reqFailed(request)
Esempio n. 5
0
    async def ipIdentifierInit(self, ipfsop, ipid: IPIdentifier):
        # Register the blog as an IP service on the DID
        blogPath = IPFSPath(joinIpns(self.keyRootId)).child('blog')
        await ipid.addServiceRaw({
            'id': ipid.didUrl(path='/blog'),
            'type': IPService.SRV_TYPE_DWEBBLOG,
            'serviceEndpoint': blogPath.ipfsUrl
        }, publish=False)

        # Register the Atom feed as an IP service on the DID
        feedPath = IPFSPath(joinIpns(self.keyRootId)).child('dfeed.atom')
        await ipid.addServiceRaw({
            'id': ipid.didUrl(path='/feed'),
            'type': IPService.SRV_TYPE_ATOMFEED,
            'serviceEndpoint': feedPath.ipfsUrl,
            'description': 'Dweb Atom feed'
        }, publish=False)

        await ipid.addServiceCollection('default')
Esempio n. 6
0
    async def resolve(self, ipfsop, resolveTimeout=30):
        useCache = 'always' if self.local else 'never'
        maxLifetime = 86400 * 7 if self.local else 60 * 10

        self.message('DID resolve: {did} (using cache: {usecache})'.format(
            did=self.ipnsKey, usecache=useCache))

        return await ipfsop.nameResolveStreamFirst(
            joinIpns(self.ipnsKey),
            timeout=resolveTimeout,
            useCache=useCache,
            maxCacheLifetime=maxLifetime)
Esempio n. 7
0
    async def nsCacheSet(self, path, resolved, origin=None):
        self.cache[path] = {
            'resolved': resolved,
            'resolvedLast': int(time.time()),
            'cacheOrigin': origin
        }

        # Cache v1
        v1 = ipnsKeyCidV1(stripIpns(path))
        if v1:
            self.cache[joinIpns(v1)] = {
                'resolved': resolved,
                'resolvedLast': int(time.time()),
                'cacheOrigin': origin
            }

        await self.nsCacheSave()
Esempio n. 8
0
    async def async_loader(client, url):
        """
        :param url: the URL to retrieve.

        :return: the RemoteDocument.
        """
        try:
            if url.startswith('ipschema://'):
                o = urlparse(url)
                kList = await client.key.list()

                ipnsKey = None
                for key in kList['Keys']:
                    if key['Name'] == o.netloc:
                        ipnsKey = key['Id']

                if ipnsKey is None:
                    path = None
                else:
                    path = IPFSPath(joinIpns(ipnsKey)).child(o.path)
            else:
                path = IPFSPath(url)
                if not path.valid:
                    raise Exception('Not a valid path')

            if path and path.valid:
                data = await client.cat(path.objPath)

                return {
                    'document': json.loads(data.decode()),
                    'documentUrl': url,
                    'contextUrl': None
                }

        except aioipfs.APIError as e:
            log.debug(str(e))
            raise e
        except JsonLdError as e:
            log.debug(str(e))
            raise e
        except Exception as cause:
            raise JsonLdError(
                'Could not retrieve a JSON-LD document from the URL.',
                'jsonld.LoadDocumentError', code='loading document failed',
                cause=cause)
Esempio n. 9
0
    async def encodeIpHandleQr(self,
                               ipfsop,
                               iphandle,
                               format='raw',
                               filename=None):
        encoder = IPFSQrEncoder()

        try:
            entry = await ipfsop.addString(iphandle, only_hash=True)
            if not entry:
                return

            encoder.add(entry['Hash'])
            encoder.add(self.profile.userInfo.personDid)
            encoder.add(joinIpns(ipfsop.ctx.node.id))
            return await encoder.encodeAndStore(format=format)
        except Exception:
            # TODO
            pass
Esempio n. 10
0
    async def encodeIpHandleQr(self, ipfsop,
                               iphandle,
                               did,
                               format='png',
                               filename=None):
        encoder = IPFSQrEncoder()

        try:
            entry = await ipfsop.addString(iphandle, pin=True, only_hash=True)
            if not entry:
                return

            await ipfsop.sleep()

            encoder.add(joinIpfs(entry['Hash']))
            encoder.add(joinIpns(ipfsop.ctx.node.id))

            if didIdentRe.match(did):
                encoder.add(did)

            return await encoder.encodeAndStore(format=format)
        except Exception:
            pass
Esempio n. 11
0
    async def async_loader(client, url, options={}):
        """
        :param url: the URL to retrieve.

        :return: the RemoteDocument.
        """
        try:
            o = urlparse(url)
            if o.scheme in ['ipschema', 'ips']:
                ipsKey = o.netloc

                if ipsKey == 'galacteek.ld.contexts':
                    # Compat
                    ipsKey = 'galacteek.ld'

                if not o.path or o.path == '/':
                    return {
                        'contentType': 'application/ld+json',
                        'document': {},
                        'documentUrl': url,
                        'contextUrl': None
                    }

                    raise JsonLdError(f'Invalid context path for URL: {url}',
                                      'jsonld.InvalidUrl', {'url': url},
                                      code='loading document failed')

                kList = await client.key.list()

                ipnsKey = None
                for key in kList['Keys']:
                    if key['Name'] == ipsKey:
                        ipnsKey = key['Id']

                path = None if ipnsKey is None else IPFSPath(
                    joinIpns(ipnsKey)).child(o.path)
            else:
                path = IPFSPath(url)
                if not path.valid:
                    raise Exception(f'Not a valid path: {url}')

            if path and path.valid:
                data = await asyncio.wait_for(client.cat(path.objPath), 10)

                obj = orjson.loads(data.decode())
                assert obj is not None

                return {
                    'contentType': 'application/ld+json',
                    'document': obj,
                    'documentUrl': url,
                    'contextUrl': None
                }
        except asyncio.TimeoutError as terr:
            log.debug(str(terr))
            raise terr
        except aioipfs.APIError as e:
            log.debug(str(e))
            raise e
        except JsonLdError as e:
            log.debug(str(e))
            raise e
        except Exception as cause:
            raise JsonLdError(
                'Could not retrieve a JSON-LD document from the URL.',
                'jsonld.LoadDocumentError',
                code='loading document failed',
                cause=cause)
Esempio n. 12
0
 def sitePath(self):
     return IPFSPath(joinIpns(self.ipnsKey))