Added json validation of formats to check IPv4
refactored files and calls to be api_server worked down satisfying review comments of last commit
This commit is contained in:
parent
7caf8a46d4
commit
40db83c24c
@ -6,7 +6,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from typing import Optional, Dict, Any
|
from typing import Optional, Dict, Any
|
||||||
from jsonschema import Draft4Validator, validate
|
from jsonschema import Draft4Validator, validate, draft4_format_checker
|
||||||
from jsonschema.exceptions import ValidationError, best_match
|
from jsonschema.exceptions import ValidationError, best_match
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ class Configuration(object):
|
|||||||
:return: Returns the config if valid, otherwise throw an exception
|
:return: Returns the config if valid, otherwise throw an exception
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
validate(conf, constants.CONF_SCHEMA)
|
validate(conf, constants.CONF_SCHEMA, format_checker=draft4_format_checker)
|
||||||
return conf
|
return conf
|
||||||
except ValidationError as exception:
|
except ValidationError as exception:
|
||||||
logger.critical(
|
logger.critical(
|
||||||
@ -217,7 +217,9 @@ class Configuration(object):
|
|||||||
exception
|
exception
|
||||||
)
|
)
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
|
best_match(Draft4Validator(constants.CONF_SCHEMA,
|
||||||
|
format_checker=draft4_format_checker)
|
||||||
|
.iter_errors(conf)).message
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_config(self) -> Dict[str, Any]:
|
def get_config(self) -> Dict[str, Any]:
|
||||||
|
@ -85,6 +85,19 @@ CONF_SCHEMA = {
|
|||||||
},
|
},
|
||||||
'required': ['enabled', 'token', 'chat_id']
|
'required': ['enabled', 'token', 'chat_id']
|
||||||
},
|
},
|
||||||
|
'api_server': {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'enabled': {'type': 'boolean'},
|
||||||
|
'listen_ip_address': { "format": "ipv4"},
|
||||||
|
'listen_port': {
|
||||||
|
'type': 'integer',
|
||||||
|
"minimum": 1024,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'required': ['enabled', 'listen_ip_address', 'listen_port']
|
||||||
|
},
|
||||||
'db_url': {'type': 'string'},
|
'db_url': {'type': 'string'},
|
||||||
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
|
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
|
||||||
'internals': {
|
'internals': {
|
||||||
|
@ -6,26 +6,25 @@ from flask import Flask, request
|
|||||||
from flask_restful import Resource, Api
|
from flask_restful import Resource, Api
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from freqtrade.rpc.rpc import RPC, RPCException
|
from freqtrade.rpc.rpc import RPC, RPCException
|
||||||
|
from ipaddress import IPv4Address
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
class LocalRestSuperWrap(RPC):
|
class ApiServerSuperWrap(RPC):
|
||||||
"""
|
"""
|
||||||
This class is for REST cmd line client
|
This class is for REST calls across api server
|
||||||
"""
|
"""
|
||||||
def __init__(self, freqtrade) -> None:
|
def __init__(self, freqtrade) -> None:
|
||||||
"""
|
"""
|
||||||
Init the LocalRestServer call, and init the super class RPC
|
Init the api server, and init the super class RPC
|
||||||
:param freqtrade: Instance of a freqtrade bot
|
:param freqtrade: Instance of a freqtrade bot
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
super().__init__(freqtrade)
|
super().__init__(freqtrade)
|
||||||
""" Constructor
|
|
||||||
:type interval: int
|
self.interval = 1
|
||||||
:param interval: Check interval, in seconds
|
|
||||||
"""
|
|
||||||
self.interval = int(1)
|
|
||||||
|
|
||||||
thread = threading.Thread(target=self.run, args=(freqtrade,)) # extra comma as ref ! Tuple
|
thread = threading.Thread(target=self.run, args=(freqtrade,)) # extra comma as ref ! Tuple
|
||||||
thread.daemon = True # Daemonize thread
|
thread.daemon = True # Daemonize thread
|
||||||
@ -35,7 +34,6 @@ class LocalRestSuperWrap(RPC):
|
|||||||
def run(self, freqtrade):
|
def run(self, freqtrade):
|
||||||
""" Method that runs forever """
|
""" Method that runs forever """
|
||||||
self._config = freqtrade.config
|
self._config = freqtrade.config
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Define the application routes here
|
Define the application routes here
|
||||||
@ -97,17 +95,14 @@ class LocalRestSuperWrap(RPC):
|
|||||||
Section to handle configuration and running of the Rest serve
|
Section to handle configuration and running of the Rest serve
|
||||||
also to check and warn if not bound to 127.0.0.1 as a security risk.
|
also to check and warn if not bound to 127.0.0.1 as a security risk.
|
||||||
"""
|
"""
|
||||||
|
rest_ip = self._config['api_server']['listen_ip_address']
|
||||||
|
rest_port = self._config['api_server']['listen_port']
|
||||||
|
|
||||||
rest_ip = self._config['rest_cmd_line']['listen_ip_address']
|
if not IPv4Address(rest_ip).is_loopback :
|
||||||
rest_port = self._config['rest_cmd_line']['listen_port']
|
logger.info("SECURITY WARNING - Local Rest Server listening to external connections")
|
||||||
|
logger.info("SECURITY WARNING - This is insecure please set to your loopback, e.g 127.0.0.1 in config.json")
|
||||||
if rest_ip != "127.0.0.1":
|
|
||||||
i=0
|
|
||||||
while i < 10:
|
|
||||||
logger.info("SECURITY WARNING - Local Rest Server listening to external connections")
|
|
||||||
logger.info("SECURITY WARNING - This is insecure please set to 127.0.0.1 in config.json")
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
# Run the Server
|
# Run the Server
|
||||||
logger.info('Starting Local Rest Server')
|
logger.info('Starting Local Rest Server')
|
||||||
app.run(host=rest_ip, port=rest_port)
|
app.run(host=rest_ip, port=rest_port)
|
||||||
|
|
@ -23,11 +23,12 @@ class RPCManager(object):
|
|||||||
from freqtrade.rpc.telegram import Telegram
|
from freqtrade.rpc.telegram import Telegram
|
||||||
self.registered_modules.append(Telegram(freqtrade))
|
self.registered_modules.append(Telegram(freqtrade))
|
||||||
|
|
||||||
# Enable local rest server for cmd line control
|
# Enable local rest api server for cmd line control
|
||||||
if freqtrade.config['rest_cmd_line'].get('enabled', False):
|
if freqtrade.config['api_server'].get('enabled', False):
|
||||||
logger.info('Enabling rpc.local_rest_server ...')
|
logger.info('Enabling rpc.api_server')
|
||||||
from freqtrade.rpc.local_rest_server import LocalRestSuperWrap
|
from freqtrade.rpc.api_server import ApiServerSuperWrap
|
||||||
self.registered_modules.append(LocalRestSuperWrap(freqtrade))
|
self.registered_modules.append(ApiServerSuperWrap(freqtrade))
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self) -> None:
|
def cleanup(self) -> None:
|
||||||
""" Stops all enabled rpc modules """
|
""" Stops all enabled rpc modules """
|
||||||
|
Loading…
Reference in New Issue
Block a user