Exemple #1
0
 def test_auth(self):
     print("Checking authentication to Specter with credentials:")
     print(f"url: {self.config['SPECTER'].get('specter_url')}")
     print(f"username: {self.config['SPECTER'].get('specter_login')}")
     print(f"password: {self.config['SPECTER'].get('specter_password')}")
     specter = Specter()
     session = specter.init_session()
     print(session)
Exemple #2
0
 def test_home(self):
     print("Reaching Specter and getting main page data")
     print("Checks the integrity of parser data")
     specter = Specter()
     data = specter.home_parser()
     self.assertNotIn('error', data)
     # check data does not return an error
     checker_list = ['bitcoin_core_data', 'version']
     for element in checker_list:
         self.assertNotIn('error', data[element])
Exemple #3
0
def specter_auth():
    if request.method == 'GET':

        templateData = {
            "title": "Login to Specter",
            "current_app": current_app,
            "current_user": current_user
        }
        return (render_template('warden/specter_auth.html', **templateData))

    if request.method == 'POST':
        from message_handler import Message
        current_app.message_handler.clean_category('Specter Connection')
        url = request.form.get('url')
        url = url_parser(url)

        # Try to ping this url
        if 'onion' not in url:
            try:
                status_code = requests.head(url).status_code
            except Exception as e:
                flash(f'Please check Specter URL. Error: {e}', 'danger')
        else:
            try:
                status_code = tor_request(url).status_code
            except Exception as e:
                flash(f'Please check Specter URL. Error: {e}', 'danger')

        try:
            if int(status_code) < 400:
                message = Message(
                    category='Specter Connection',
                    message_txt='Pinging URL',
                    notes=
                    f"{url}<br> ping <span class='text-success'>✅ Success</span>"
                )
                current_app.message_handler.add_message(message)
            else:
                flash('Please check Specter URL (unreacheable)', 'danger')
                return redirect(url_for('warden.specter_auth'))
        except Exception as e:
            flash(f'Error Connecting. Error: {e}', 'danger')
            return redirect(url_for('warden.specter_auth'))

        # Try to authenticate
        try:
            current_app.specter.base_url = url
            current_app.specter.login_url = url + 'auth/login'
            current_app.specter.tx_url = url + 'wallets/wallets_overview/txlist'
            current_app.specter.core_url = url + 'settings/bitcoin_core?'
            current_app.specter.login_payload = {
                'username': request.form.get('username'),
                'password': request.form.get('password')
            }
            session = current_app.specter.init_session()
            session.close()
        except Exception as e:
            flash(f'Error logging in to Specter: {e}', 'danger')
            return redirect(url_for('warden.specter_auth'))

        current_app.downloading = True
        current_app.settings['SPECTER']['specter_url'] = url
        current_app.settings['SPECTER']['specter_login'] = request.form.get(
            'username')
        current_app.settings['SPECTER']['specter_password'] = request.form.get(
            'password')
        update_config()

        current_app.specter = Specter()
        current_app.specter.refresh_txs(load=False)

        flash("Success. Connected to Specter Server.", "success")
        # Now allow download of all txs in background on next run
        return redirect(url_for('warden.warden_page'))
Exemple #4
0
def init_app(app):
    from ansi_management import (warning, success, error)
    from utils import (create_config, runningInDocker)
    from config import Config
    from connections import tor_request
    warnings.filterwarnings('ignore')

    # Load config.ini into app
    # --------------------------------------------
    # Read Global Variables from warden.config(s)
    # Can be accessed like a dictionary like:
    # app.settings['PORTFOLIO']['RENEW_NAV']
    # --------------------------------------------
    config_file = Config.config_file
    app.warden_status = {}

    # Check for internet connection
    internet_ok = internet_connected()
    if internet_ok is True:
        print(success("✅ Internet Connection"))
    else:
        print(
            error(
                "[!] WARden needs internet connection. Check your connection.")
        )
        print(warning("[!] Exiting"))
        exit()

    # Config
    config_settings = configparser.ConfigParser()
    if os.path.isfile(config_file):
        config_settings.read(config_file)
        app.warden_status['initial_setup'] = False
        print(
            success(
                "✅ Config Loaded from config.ini - edit it for customization"
            ))
    else:
        print(
            error(
                "  Config File could not be loaded, created a new one with default values..."
            ))
        create_config(config_file)
        config_settings.read(config_file)
        app.warden_status['initial_setup'] = True

    table_error = False
    try:
        # create empty instance of LoginManager
        app.login_manager = LoginManager()
    except sqlite3.OperationalError:
        table_error = True

    # Create empty instance of SQLAlchemy
    app.db = SQLAlchemy()
    app.db.init_app(app)
    # Import models so tables are created
    from models import Trades, User, AccountInfo, TickerInfo, SpecterInfo
    app.db.create_all()

    #  There was an initial error on getting users
    #  probably because tables were not created yet.
    # The above create_all should have solved it so try again.
    if table_error:
        # create empty instance of LoginManager
        app.login_manager = LoginManager()

    # If login required - go to login:
    app.login_manager.login_view = "warden.login"
    # To display messages - info class (Bootstrap)
    app.login_manager.login_message_category = "secondary"
    app.login_manager.init_app(app)

    # Create empty instance of messagehandler
    from message_handler import MessageHandler
    app.message_handler = MessageHandler()
    app.message_handler.clean_all()

    # Get Version
    print("")
    try:
        version_file = Config.version_file
        with open(version_file, 'r') as file:
            current_version = file.read().replace('\n', '')
    except Exception:
        current_version = 'unknown'
    with app.app_context():
        app.version = current_version

    # Check if there are any users on database, if not, needs initial setup
    users = User.query.all()
    if users == []:
        app.warden_status['initial_setup'] = True

    # Check for Cryptocompare API Keys
    print("")
    check_cryptocompare()
    print("")

    print(f"[i] Running WARden version: {current_version}")
    app.warden_status['running_version'] = current_version

    # CHECK FOR UPGRADE
    repo_url = 'https://api.github.com/repos/pxsocs/warden/releases'
    try:
        github_version = tor_request(repo_url).json()[0]['tag_name']
    except Exception:
        github_version = None

    app.warden_status['github_version'] = github_version

    if github_version:
        print(f"[i] Newest WARden version available: {github_version}")
        parsed_github = version.parse(github_version)
        parsed_version = version.parse(current_version)

        app.warden_status['needs_upgrade'] = False
        if parsed_github > parsed_version:
            print(warning("  [i] Upgrade Available"))
            app.warden_status['needs_upgrade'] = True
        if parsed_github == parsed_version:
            print(success("✅ You are running the latest version"))
    else:
        print(warning("[!] Could not check GitHub for updates"))

    print("")
    # Check if config.ini exists
    with app.app_context():
        app.settings = config_settings
    with app.app_context():
        try:
            from utils import fxsymbol
            app.fx = fxsymbol(config_settings['PORTFOLIO']['base_fx'], 'all')
        except KeyError:  # Problem with this config, reset
            print(error("  [!] Config File needs to be rebuilt"))
            print("")
            create_config(config_file)

    # TOR Server through Onion Address --
    # USE WITH CAUTION - ONION ADDRESSES CAN BE EXPOSED!
    # WARden needs to implement authentication (coming soon)
    if app.settings['SERVER'].getboolean('onion_server'):
        from stem.control import Controller
        from urllib.parse import urlparse
        app.tor_port = app.settings['SERVER'].getint('onion_port')
        app.port = app.settings['SERVER'].getint('port')
        from warden_modules import home_path
        toraddr_file = os.path.join(home_path(), "onion.txt")
        app.save_tor_address_to = toraddr_file
        proxy_url = "socks5h://localhost:9050"
        tor_control_port = ""
        try:
            tor_control_address = urlparse(proxy_url).netloc.split(":")[0]
            if tor_control_address == "localhost":
                tor_control_address = "127.0.0.1"
            app.controller = Controller.from_port(
                address=tor_control_address,
                port=int(tor_control_port) if tor_control_port else "default",
            )
        except Exception:
            app.controller = None
        from tor import start_hidden_service
        start_hidden_service(app)

    from routes import warden
    from errors.handlers import errors
    from api.routes import api
    from csv_routes.routes import csv_routes
    from user_routes.routes import user_routes
    from simulator.routes import simulator
    app.register_blueprint(warden)
    app.register_blueprint(errors)
    app.register_blueprint(api)
    app.register_blueprint(csv_routes)
    app.register_blueprint(user_routes)
    app.register_blueprint(simulator)

    # Prepare app to receive Specter Server info
    # For the first load, just get a saved file if available
    # The background jobs will update later
    with app.app_context():
        from specter_importer import Specter
        app.specter = Specter()
        app.specter.refresh_txs(load=True)
        app.downloading = False

    with app.app_context():
        app.runningInDocker = runningInDocker()

    with app.app_context():
        app.tor = create_tor()

    # Check if home folder exists, if not create
    home = str(Path.home())
    home_path = os.path.join(home, 'warden/')
    try:
        os.makedirs(os.path.dirname(home_path))
    except Exception:
        pass

    # Start Schedulers
    from backgroundjobs import (background_settings_update,
                                background_specter_update,
                                background_scan_network,
                                background_specter_health,
                                background_mempool_seeker)

    def bk_su():
        with app.app_context():
            background_specter_update()

    def bk_stu():
        with app.app_context():
            background_settings_update()

    def bk_scan():
        with app.app_context():
            background_scan_network()

    def bk_specter_health():
        with app.app_context():
            background_specter_health()

    def bk_mempool_health():
        with app.app_context():
            background_mempool_seeker()

    app.scheduler = BackgroundScheduler()
    app.scheduler.add_job(bk_su, 'interval', seconds=1)
    app.scheduler.add_job(bk_stu, 'interval', seconds=1)
    app.scheduler.add_job(bk_scan, 'interval', seconds=1)
    app.scheduler.add_job(bk_specter_health, 'interval', seconds=1)
    app.scheduler.add_job(bk_mempool_health, 'interval', seconds=1)
    app.scheduler.start()
    print(success("✅ Background jobs running"))
    print("")
    app.app_context().push()

    print(success("✅ Application startup is complete"))

    return app