Exemplo n.º 1
0
def create_api_key():
    form = ApiKeyForm()
    if form.validate_on_submit():
        user_id = current_user.id
        exchange_id = request.form.get('exchange_id')
        public_key = request.form.get('public_key')
        private_key = request.form.get('private_key')

        api_key = ApiKey.query.filter_by(user_id=user_id,
                                         exchange_id=exchange_id,
                                         public_key=public_key).first()

        if api_key:  # leave a message if the public key already exists
            flash(Markup('Public key already exists.'))
            return redirect(url_for('user.create_api_key'))

        # noinspection PyArgumentList
        new_api_key = ApiKey(user_id=user_id,
                             exchange_id=exchange_id,
                             public_key=public_key,
                             private_key=encrypt(private_key,
                                                 session['token']))
        # add the new user to the database
        new_api_key.save()
        return redirect('/api-key/')
    return render_template('add.html',
                           form=form,
                           action=url_for('user.create_api_key'),
                           title="Add API key pair")
Exemplo n.º 2
0
def signup():
    form = SignupForm()
    if form.validate_on_submit():
        email = request.form.get('email')
        username = request.form.get('username')
        password = request.form.get('password')
        session_token = Fernet.generate_key()

        user = User.query.filter_by(
            email=email).first()  # check if email address exists in database
        if user:  # leave a message if the email address exists
            flash(
                Markup(
                    'Email address already exists. Go to the <a href="login">login page</a>.'
                ), 'danger')
            return redirect(url_for('auth.signup'))

        # noinspection PyArgumentList
        new_user = User(email=email,
                        username=username,
                        password=generate_password_hash(password,
                                                        method='sha256'),
                        token=encrypt(session_token, password))
        session_token = decrypt(new_user.token, password)
        session['token'] = session_token

        if 'token' in session and session['token']:
            # add the new user to the database
            new_user.save()
            login_user(new_user)
            return redirect(url_for('user.index'))
        else:
            return render_template('signup.html', form=form)

    return render_template('signup.html', form=form)
Exemplo n.º 3
0
def profile():
    form = ProfileForm()

    # set the form's data with current_user's data
    user_profile = User.query.filter_by(id=current_user.id).first()

    form.username.data = user_profile.username
    form.email.data = user_profile.email
    form.theme.data = user_profile.theme or 'moon-base-alpha'
    set_boolean_values(form, user_profile)

    # add 'was-validated' tag to form in order to display hints and/or (error) messages
    if request.method == 'POST':
        form.extra_classes = "was-validated"

    if form.validate_on_submit():
        user_profile.email = request.form.get('email')
        user_profile.username = request.form.get('username')
        user_profile.email_verified = request.form.get(
            'email_verified') is not None
        user_profile.theme = request.form.get('theme')

        # save new password (if any) and generate a new token if necessary
        old_password = request.form.get('current_password')
        new_password = request.form.get('password')
        if new_password:
            if check_password_hash(user_profile.password, old_password):

                if 'token' in session and session['token']:
                    # hash the new password
                    user_profile.password = generate_password_hash(
                        new_password, method='sha256')
                    # hash the user's token data with the new password, so that we may continue to use the token to for decryption and encryption purposes
                    session_token = decrypt(session['token'], old_password)
                    user_profile.token = encrypt(session_token, new_password)
                    session['token'] = decrypt(user_profile.token,
                                               new_password)
                else:
                    flash(
                        "Your session is transpired. You have been logged out for security reasons.",
                        "danger")
                    redirect(url_for('auth.logout'))
            else:
                flash("Invalid password", "danger")
                return redirect(url_for('user.profile'))
        # save model
        user_profile.save()

        # save theme to a cookie
        resp = make_response(redirect(redirect_url()))
        resp.set_cookie('chronos-preference-theme', user_profile.theme)
        return resp

    return render_template('profile.html', form=form)
Exemplo n.º 4
0
def login():
    session_token = None

    form = LoginForm()
    if form.remember.data:
        form.email.data = request.form.get('email')

    if form.validate_on_submit():
        email = request.form.get('email')
        password = request.form.get('password')
        remember = True if request.form.get('remember') else False
        user = User.query.filter_by(email=email).first()
        if not user or not check_password_hash(user.password, password):
            flash('Please check your login details and try again.', 'danger')
            return redirect(
                url_for('auth.login')
            )  # if user doesn't exist or password is wrong, reload the page
        login_user(user, remember=remember, force=True)

        # load/generate token to encrypt sensitive date with
        if user.token is None:  # if the user doesn't have a token, then save it
            session_token = Fernet.generate_key()
            user.token = encrypt(session_token, password)
            user.save()
        else:
            try:
                session_token = decrypt(user.token, password)
            except InvalidToken as e:
                log.exception(e)
                pass

        log.info("session_token: {}".format(session_token))
        session['token'] = session_token
        assert ('token' in session and session['token'])

        # redirect to the previous page (if any), or to the user role's default
        if user.is_admin:
            next_page = redirect_url(url_for('admin.dashboard'))
            # exclude auth.login as referrer
            if next_page.endswith(url_for('auth.login')):
                next_page = url_for('admin.dashboard')
        else:
            next_page = redirect_url(url_for('user.index'))
            # exclude auth.login as referrer
            if next_page.endswith(url_for('auth.login')):
                next_page = url_for('user.index')
        resp = make_response(redirect(next_page))

        # update user preferences cookies
        if user.theme:
            resp.set_cookie('chronos-preference-theme', user.theme)
        return resp
    return render_template('login.html', form=form)
Exemplo n.º 5
0
def webhook():
    """
    Expected request data in JSON format for CCXT:
        chronos_id: int
        exchange: Kraken, Binance, etc
        symbol: symbol or asset ID
        quantity: int
        side: buy or sell
        type: LIMIT, MARKET, STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT, LIMIT_MAKER
        price: limit price

    Expected request data in JSON format for Alpaca:
        chronos_id: int
        exchange: Alpaca or AlpacaPaper
        symbol: symbol or asset ID
        quantity: int
        side: buy or sell
        type: market, limit, stop, stop_limit or trailing_stop
        limit_price: str of float
        stop_price: str of float
        time_in_force: day, gtc, opg, cls, ioc, fok
        client_order_id:
        extended_hours: bool. If true, order will be eligible to execute in premarket/afterhours.
        order_class: simple, bracket, oco or oto
        take_profit: dict with field "limit_price" e.g {"limit_price": "298.95"}
        stop_loss: dict with fields "stop_price" and "limit_price" e.g {"stop_price": "297.95", "limit_price": "298.95"}
        trail_price: str of float
        trail_percent: str of float
        instructions: str

    """
    # password = config.get('authentication', 'password')
    password = config.get('security', 'webhook_password')
    if request.method == 'POST':
        # Parse the string data from tradingview into a python dict
        log.info(request.get_data(as_text=True))
        data = data_helper.parse_webhook(request.get_data(as_text=True))

        # Check that the key is correct
        if (not password) or tools.get_token(password) == data['key']:
            if not ('pwd' in data):
                return "Missing attribute 'pwd'", 401
            if not ('chronos_id' in data):
                return "Missing attribute 'chronos_id'", 401
            # If the user has no session, create a session token
            pwd = data['pwd']
            if isinstance(current_user,
                          mixins.AnonymousUserMixin) or isinstance(
                              current_user, local.LocalProxy):
                session_token = None
                webhook_user = User.query.filter_by(
                    id=data['chronos_id']).first()
                login_user(webhook_user, force=True)

                # load/generate token to encrypt sensitive date with
                if webhook_user.token is None:  # if the user doesn't have a token, then save it
                    session_token = Fernet.generate_key()
                    webhook_user.token = encrypt(session_token, pwd)
                    webhook_user.save()
                else:
                    try:
                        session_token = decrypt(webhook_user.token, pwd)
                    except InvalidToken as e:
                        log.exception(e)
                        pass

                session['token'] = session_token
                assert ('token' in session and session['token'])

            # log.info('POST Received: {}'.format(data))
            data_helper.send_order(data)
            return '', 200
        else:
            abort(403)
    else:
        abort(400)