Ejemplo n.º 1
0
    async def handleRequest(self, request):
        rUrl = request.requestUrl()
        if not rUrl.isValid():
            return self.urlInvalid(request)

        domain = rUrl.host()
        uPath = rUrl.path()

        if not domain or len(domain) > 512 or not domainValid(domain):
            log.info('EthDNS: invalid domain request')
            return self.urlInvalid(request)

        pathRaw = await self.ethResolver.resolveEnsDomain(domain)
        path = IPFSPath(pathRaw, autoCidConv=True)

        if path and path.valid:
            await ensDomainResolved.emit(domain, path)

            sPath = path.child(uPath) if uPath else path
            log.debug('EthDNS: {domain} resolved to {res}'.format(
                domain=domain, res=sPath.ipfsUrl))
            return request.redirect(QUrl(sPath.dwebUrl))
        else:
            log.info('EthDNS: {domain} resolve failed'.format(domain=domain))
            return self.urlNotFound(request)
Ejemplo n.º 2
0
    async def openWithExternal(self, ipfsop, rscPath, progArgs):
        filePath = os.path.join(self.app.tempDir.path(),
                                os.path.basename(rscPath))

        if not os.path.exists(filePath):
            try:
                await ipfsop.client.get(rscPath,
                                        dstdir=self.app.tempDir.path())
            except aioipfs.APIError as err:
                log.debug(err.message)
                return

        if not os.path.isfile(filePath):
            # Bummer
            return

        if not self.app.windowsSystem:
            filePathEsc = filePath.replace('"', r'\"')
            args = progArgs.replace('%f', filePathEsc)
        else:
            args = progArgs.replace('%f', filePath)

        log.info('Object opener: executing: {}'.format(args))

        try:
            proc = await asyncio.create_subprocess_shell(
                args, stdout=asyncio.subprocess.PIPE)
            stdout, stderr = await proc.communicate()
        except BaseException as err:
            os.unlink(filePath)
            log.debug(str(err))
        else:
            os.unlink(filePath)
Ejemplo n.º 3
0
    async def sync(self):
        _count, _scount = 0, 0

        await self.syncing.emit(True)

        log.info('Synchronizing hashmarks database ...')

        sources = await database.hashmarkSourceAll()

        for source in sources:
            if source.type == HashmarkSource.TYPE_PYMODULE:
                loader = ModuleCatalogLoader()
            elif source.type == HashmarkSource.TYPE_GITREPOS:
                loader = GitCatalogLoader()
            elif source.type == HashmarkSource.TYPE_IPFSMARKS_LEGACY:
                loader = IPFSMarksCatalogLoader()
            else:
                continue

            log.info('Synchronizing: {}'.format(source))
            _count += await loader.load(source)

            if _count >= 0:
                _scount += 1
                source.syncedlast = datetime.now()
                await source.save()

        shistory = database.HashmarkSyncHistory(
            hashmarkstotal=await database.hashmarksCount(),
            hashmarksadded=_count,
            srcsynccount=_scount
        )
        await shistory.save()

        await self.syncing.emit(False)
Ejemplo n.º 4
0
    async def _accept(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
        addr_repr = ':'.join(map(str, writer.get_extra_info('peername')))
        logger.info('accepted connection from %s', addr_repr)

        try:
            writer.write(ControlServer.HANDSHAKE_MESSAGE)

            while True:
                # FIXME: maybe do not allow to execute arbitrary object
                action = cast(Callable[[ControlManager], Any], await ControlServer.receive_object(reader))

                try:
                    result = action(self._control)
                    if asyncio.iscoroutine(result):
                        result = await result
                except asyncio.CancelledError:
                    raise
                except Exception as e:
                    result = e

                ControlServer.send_object(result, writer)

                if isinstance(result, DaemonExit):
                    logger.info('stop command received')
                    if self._daemon_stop_handler is not None:
                        self._daemon_stop_handler(self)
                    return
        except asyncio.IncompleteReadError:
            pass
        except asyncio.CancelledError:
            raise
        except Exception as e:
            logger.warning('%s disconnected because of %r', addr_repr, e)
        finally:
            writer.close()
Ejemplo n.º 5
0
    async def browseIpService(self, ipfsop, serviceId, serviceCtx=None):
        """
        Browse/open an IP service registered on an IPID
        """

        log.info('Accessing IP service {}'.format(serviceId))

        pService = await ipfsop.ipidManager.getServiceById(serviceId)
        if not pService:
            return

        endpoint = pService.endpoint

        if pService.type == IPService.SRV_TYPE_ATOMFEED:
            await self.app.mainWindow.atomButton.atomFeedSubscribe(
                str(endpoint))
        elif pService.type == IPService.SRV_TYPE_VIDEOCALL:
            from galacteek.ui.videocall import VideoCallInitiator

            vc = VideoCallInitiator(pService)
            await vc.start()

        elif isinstance(endpoint, str):
            path = IPFSPath(endpoint, autoCidConv=True)
            await self.open(path)
Ejemplo n.º 6
0
    async def sendIdent(self, op, profile):
        if not profile.initialized:
            logger.debug('Profile not initialized, ident message not sent')
            return

        nodeId = op.ctx.node.id
        uInfo = profile.userInfo

        ipid = await op.ipidManager.load(profile.userInfo.personDid,
                                         localIdentifier=True)

        if not ipid:
            logger.info('Failed to load local DID')
            return
        else:
            logger.debug('Local IPID ({did}) load: OK, dagCID is {cid}'.format(
                did=profile.userInfo.personDid, cid=ipid.docCid))

        msg = await PeerIdentMessageV3.make(nodeId, profile.dagUser.dagCid,
                                            profile.keyRootId, uInfo,
                                            profile.userInfo.personDid,
                                            ipid.docCid)

        logger.debug('Sending ident message')
        await self.send(str(msg))
Ejemplo n.º 7
0
    async def onJoinChannel(self, ipfsop, channel):
        log.info(f'Joining channel: {channel}')

        widget = await self.chans.joinChannel(channel)
        self.app.mainWindow.registerTab(widget,
                                        name=channel,
                                        icon=getIcon('qta:mdi.chat-outline'),
                                        current=True)
Ejemplo n.º 8
0
    async def onJoinChannel(self, ipfsop, channel):
        log.info(f'Joining channel: {channel}')

        widget = await self.chans.joinChannel(channel)
        self.app.mainWindow.registerTab(widget,
                                        name=channel,
                                        icon=getIcon('chat.png'),
                                        current=True,
                                        workspace=WS_PEERS)
Ejemplo n.º 9
0
    async def seedAppImage(self, ipfsop):
        # Automatic AppImage seeding

        if os.path.isfile(self.cmdArgs.binarypath):
            log.info(
                'AppImage seeding: {img}'.format(img=self.cmdArgs.binarypath))

            ensure(ipfsop.addPath(self.cmdArgs.binarypath, wrap=True),
                   futcallback=self.onAppSeed)
Ejemplo n.º 10
0
def dappsRegisterSchemes():
    # Called early (register dapps schemes before app creation)

    for dappName, dappPath in availableDapps():
        mod = dappGetModule(dappName)
        if mod:
            log.debug(f'Registering ipdapp schemes for {dappName}')
            mod.declareUrlSchemes()
        else:
            log.info(f'Cannot load dapp {dappName}')
Ejemplo n.º 11
0
    def onAppSeed(self, future):
        try:
            replResult = future.result()
        except Exception as err:
            log.debug('AppImage seed: failed', exc_info=err)
        else:
            if isinstance(replResult, dict):
                cid = replResult.get('Hash')

                self.appImageImported.emit(cid)

                log.info('AppImage seed OK: CID {cid}'.format(cid=cid))
Ejemplo n.º 12
0
 async def profileNew(self, pName, emitavail=False):
     profile = UserProfile(self, pName, os.path.join(
         GFILES_ROOT_PATH, 'profile.{}'.format(pName)))
     try:
         await profile.init()
     except Exception as e:
         log.info('Could not initialize profile: {}'.format(
             str(e)), exc_info=True)
         return None
     self.profiles[pName] = profile
     if emitavail is True:
         self.profileEmitAvail()
     return profile
Ejemplo n.º 13
0
 async def start(self):
     for port in ControlServer.PORT_RANGE:
         try:
             self._server = await asyncio.start_server(
                 self._accept, host=ControlServer.HOST, port=port)
         except asyncio.CancelledError:
             raise
         except Exception as e:
             logger.debug(f'exception on starting server on port {port}: {e}')
         else:
             logger.info(f'server started on port {port}')
             return
     else:
         raise RuntimeError('Failed to start a control server')
Ejemplo n.º 14
0
def mimeTypeProcess(mTypeText, buff, info=None):
    if mTypeText == 'text/xml':
        # If it's an XML, check if it's an Atom feed from the buffer
        # Can't call feedparser here cause we only got a partial buffer
        atomized = re.search('<feed xmlns="http://www.w3.org/[0-9]+/Atom".*>',
                             buff.decode())
        if atomized:
            return MIMEType('application/atom+xml')
    elif mTypeText == 'application/octet-stream':
        # Check for WASM magic number
        wasmMagic = binascii.unhexlify(b'0061736d')

        if buff[0:4] == wasmMagic:
            version = struct.unpack('<I', buff[4:8])[0]
            log.info('Detected WASM binary, version {}'.format(version))
            return mimeTypeWasm

    return MIMEType(mTypeText)
Ejemplo n.º 15
0
    async def profileLoad(self, ipfsop, pName):
        if await self.profileExists(pName):
            profile = UserProfile(self, pName, posixIpfsPath.join(
                GFILES_ROOT_PATH, 'profile.{}'.format(pName))
            )

            if pName not in self.profiles:
                self.profiles[pName] = profile
                self.currentProfile = profile

            try:
                async for msg in profile.init(ipfsop):
                    yield msg
            except Exception as e:
                log.info('Could not initialize profile: {}'.format(
                    str(e)), exc_info=True)
                raise e

            self.profileEmitAvail()
            self.profileChange(pName)
Ejemplo n.º 16
0
    async def sendIdent(self, op, profile):
        if not profile.initialized:
            logger.debug('Profile not initialized, ident message not sent')
            return

        await self.gHubPublish(keyTokensIdent, {'token': self.__identToken})

        nodeId = op.ctx.node.id
        uInfo = profile.userInfo

        ipid = await op.ipidManager.load(
            profile.userInfo.personDid,
            localIdentifier=True
        )

        if not ipid:
            logger.info('Failed to load local DID')
            return
        else:
            logger.debug('Local IPID ({did}) load: OK, dagCID is {cid}'.format(
                did=profile.userInfo.personDid, cid=ipid.docCid))

        pssSigCurDid = await self.didSigCache(
            op, profile.userInfo.personDid)

        msg = await PeerIdentMessageV4.make(
            nodeId,
            self.__identToken,
            profile.dagUser.dagCid,
            profile.keyRootId,
            uInfo,
            profile.userInfo.personDid,
            ipid.docCid,
            await op.rsaAgent.pubKeyCid(),
            await op.curve25519Agent.pubKeyCid(),
            pssSigCurDid,
            profile.dagNetwork.dagCid
        )

        logger.debug('Sending ident message')
        await self.send(str(msg))
Ejemplo n.º 17
0
    async def profileNew(self, ipfsop, pName,
                         initOptions=None, emitavail=True):
        profile = UserProfile(self, pName, posixIpfsPath.join(
            GFILES_ROOT_PATH, 'profile.{}'.format(pName)),
            initOptions=initOptions
        )

        if not self.currentProfile:
            self.currentProfile = profile

        try:
            async for msg in profile.init(ipfsop):
                yield msg
        except Exception as e:
            log.info('Could not initialize profile: {}'.format(
                str(e)), exc_info=True)
            raise e

        self.profiles[pName] = profile
        self.profileChange(pName)
        self.profileEmitAvail()
Ejemplo n.º 18
0
    async def openIpServiceObject(self, ipfsop, serviceId, objectId):
        log.info('Accessing IP service object {}'.format(objectId))

        pService = await ipfsop.ipidManager.getServiceById(serviceId)
        if not pService:
            log.info('Cannot find service {}'.format(serviceId))
            return

        obj = await pService.getObjectWithId(objectId)
        if obj:
            path = IPFSPath(obj['path'], autoCidConv=True)
            await self.open(path)
        else:
            log.info('Cannot find object {}'.format(objectId))
Ejemplo n.º 19
0
 def info(self, msg):
     logger.info('PS[{0}]: {1}'.format(self.topic, msg))
Ejemplo n.º 20
0
    async def start(self):
        # Set the IPFS_PATH environment variable
        os.environ['IPFS_PATH'] = self.repopath

        log.debug('Using go-ipfs binary: {}'.format(self.goIpfsPath))

        if not os.path.isdir(self.repopath):
            os.mkdir(self.repopath)

        if not os.path.exists(os.path.join(self.repopath, 'config')) or \
                not os.path.isdir(os.path.join(self.repopath, 'datastore')):
            # Pretty sure this is an empty repository path

            log.info('Initializing IPFS repository: {repo}'.format(
                repo=self.repopath))

            await shell('ipfs init')

        apifile = os.path.join(self.repopath, 'api')
        if os.path.exists(apifile):
            os.unlink(apifile)

        # API & gateway multiaddrs
        await self.ipfsConfig('Addresses.API',
                              '/ip4/127.0.0.1/tcp/{0}'.format(self.apiport))
        await self.ipfsConfig(
            'Addresses.Gateway',
            '/ip4/127.0.0.1/tcp/{0}'.format(self.gatewayport))

        # Swarm multiaddrs (ipv4 and ipv6), TCP and quic
        swarmAddrs = []

        if 'quic' in self.swarmProtos:
            swarmAddrs += [
                '/ip4/0.0.0.0/udp/{swarmport}/quic'.format(
                    swarmport=self.swarmportQuic),
                '/ip6/::/udp/{swarmport}/quic'.format(
                    swarmport=self.swarmportQuic)
            ]

        if 'tcp' in self.swarmProtos or not swarmAddrs:
            swarmAddrs += [
                '/ip4/0.0.0.0/tcp/{swarmport}'.format(
                    swarmport=self.swarmport),
                '/ip6/::/tcp/{swarmport}'.format(swarmport=self.swarmport)
            ]

        await self.ipfsConfigJson('Addresses.Swarm', json.dumps(swarmAddrs))

        # Swarm connection manager parameters
        await self.ipfsConfigJson('Swarm.ConnMgr.LowWater', self.swarmLowWater)
        await self.ipfsConfigJson('Swarm.ConnMgr.HighWater',
                                  self.swarmHighWater)
        await self.ipfsConfig('Swarm.ConnMgr.GracePeriod', '60s')

        await self.ipfsConfig('Routing.Type', self.routingMode)

        if self.pubsubRouter in ['floodsub', 'gossipsub']:
            await self.ipfsConfig('Pubsub.Router', self.pubsubRouter)

        await self.ipfsConfigJson('Pubsub.DisableSigning',
                                  boolarg(not self.pubsubSigning))

        await self.ipfsConfigJson('Swarm.DisableBandwidthMetrics', 'false')

        # Maximum storage
        await self.ipfsConfig('Datastore.StorageMax',
                              '{0}GB'.format(self.storageMax))

        # P2P streams
        await self.ipfsConfigJson('Experimental.Libp2pStreamMounting',
                                  boolarg(self.p2pStreams))

        await self.ipfsConfigJson('Experimental.FilestoreEnabled',
                                  boolarg(self.fileStore))

        # CORS
        if self.corsEnable:
            await self.ipfsConfigJson(
                'API.HTTPHeaders.Access-Control-Allow-Credentials', '["true"]')
            await self.ipfsConfigJson(
                'API.HTTPHeaders.Access-Control-Allow-Methods',
                '["GET", "POST"]')
            await self.ipfsConfigJson(
                'API.HTTPHeaders.Access-Control-Allow-Origin', '["*"]')

        if self.noBootstrap:
            await self.ipfsConfigJson('Bootstrap', '[]')

        await self.ipfsConfigJson('Gateway.Writable', self.gwWritable)

        args = [self.goIpfsPath, 'daemon']

        if self.pubsubEnable:
            args.append('--enable-pubsub-experiment')

        if self.namesysPubsub:
            args.append('--enable-namesys-pubsub')

        if self.migrateRepo:
            args.append('--migrate')

        if self.offline:
            args.append('--offline')

        f = self.loop.subprocess_exec(lambda: IPFSDProtocol(
            self.loop, self.exitFuture, self.startedFuture, debug=self.debug),
                                      *args,
                                      stdout=asyncio.subprocess.PIPE,
                                      stderr=asyncio.subprocess.PIPE)
        self.transport, self.proto = await f

        self._procPid = self.transport.get_pid()
        self.setProcLimits(self.pid, nice=self.nice)
        return True
Ejemplo n.º 21
0
 async def stop(self):
     if self._server is not None:
         self._server.close()
         await self._server.wait_closed()
         logger.info('server stopped')