Example #1
0
def edit_profile():

    if loggedin():
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        msg = ''

        if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:
            username = request.form['username']
            password = request.form['password']
            email = request.form['email']
            # Hash password
            #hash = password + app.secret_key
            #hash = hashlib.sha1(hash.encode())
            #password = hash.hexdigest()

            # Scrypt password hashing and random salt generation
            salt = generate_random_salt()
            password_hash = generate_password_hash(password, salt)

            # Update account with new info
            cursor.execute(
                'UPDATE accounts SET username = %s, password = %s, salt = %s, email = %s WHERE id = %s',
                (username, password_hash, salt, email, session['id']))
            mysql.connection.commit()
            msg = '업데이트 성공!'

        cursor.execute('SELECT * FROM accounts WHERE id = %s',
                       (session['id'], ))
        account = cursor.fetchone()

        return render_template('profile-edit.html', account=account, msg=msg)
    return redirect(url_for('login'))
def signup():
    if request.method == 'POST':
        salt = generate_random_salt(
        )  # generate random salt for the new users password

        # check if user exists in DB. This is done to enforce unique usernames.
        user_exists = mongo.db.usersDB.find_one(
            {'username': request.form['inputUsername']})

        if user_exists is None:
            username = request.form[
                'inputUsername']  # take in the username from form input
            email = request.form[
                'inputEmail']  # take in the email from form selection
            password = request.form[
                'inputPassword']  # take in the password from form selection
            pass_hash = generate_password_hash(
                password.encode('Utf-8'),
                salt)  # generate password hash that will get stored in the DB
            # create user account
            createuser(username, email, pass_hash, salt)
            session['currentUser'] = request.form['inputUsername']
            return redirect(url_for('home'))
        return 'User with such name exists!!!'  # if username is found in database the message is shown
    else:
        return render_template(
            'signUp.html'
        )  # if no form details present then normal signup page is shown
Example #3
0
def new_user(login, password):
    user = User()
    user.login = login

    # generate a strong cryptographic hash from the password
    salt = generate_random_salt(byte_size = 64)
    phash = generate_password_hash(password, salt,
                                   N=16384, r=8, p=1, buflen=64)
    user.password = phash + salt

    return user
Example #4
0
def validate_credentials(username, password):
    user = load_username(username)
    if user != None:
        if validate_password(user, password):
            return user
        else: 
            return None
    else: 
        salt = generate_random_salt(salt_size)
        generate_password_hash(password, salt, N=cpu_cost, r=memory_cost)
        return None
Example #5
0
 def password(self, password):
     """
     Setter for _password, saves hashed password, salt and reset_password string
     :param password:
     :return:
     """
     salt = str(generate_random_salt(), 'utf-8')
     self._password = str(generate_password_hash(password, salt), 'utf-8')
     hash_ = random.getrandbits(128)
     self.reset_password = str(hash_)
     self.salt = salt
Example #6
0
 def clean(self):
     if self.email:
         self.email = self.email.lower()
     if not self.email or not self.password:
         raise OAuth2Error('invalid_client', 'Invalid email or password.')
     if self.role and self.role not in ('admin', ):
         raise OAuth2Error('invalid_client', 'Invalid role provided.')
     if User.objects(email=self.email).first():
         raise NotUniqueError()
     self._salt = generate_random_salt()
     self.password = generate_password_hash(self.password, self._salt)
Example #7
0
 def password(self, password):
     """
     Setter for _password, saves hashed password, salt and reset_password string
     :param password:
     :return:
     """
     salt = str(generate_random_salt(), 'utf-8')
     self._password = str(generate_password_hash(password, salt), 'utf-8')
     hash_ = random.getrandbits(128)
     self.reset_password = str(hash_)
     self.salt = salt
Example #8
0
def registerProcessing():
    # server-side validation
    username = request.form['username']
    if username in session['users'].keys():
        errormsg = "Username already taken."
        return render_template('register.html', error=errormsg)
    if len(username) < 4:
        errormsg = "Username is too short. Must be more than 3 characters."
        return render_template('register.html', error=errormsg)
    elif len(username) > 50:
        errormsg = "Username and/or other fields are too long. 50 characters max."
        return render_template('register.html', error=errormsg)

    password = request.form['password']
    if len(password) < 4:
        errormsg = "Password is too short (needs to be greater than 3 characters)."
        return render_template('register.html', error=errormsg)
    elif len(password) > 50:
        errormsg = "Password is too long. 50 characters max."
        return render_template('register.html', error=errormsg)
    retype = request.form['retype']
    if retype != password:
        errormsg = "Passwords do not match."
        return render_template('register.html', error=errormsg)

    # Add salt and hash password prior to inserting to DB.
    salt = generate_random_salt(
    )  # base64 encoded random bytes, default len=64
    password_hash = generate_password_hash(password, salt)

    firstname = request.form['firstname']
    lastname = request.form['lastname']
    cursor = conn.cursor()
    query = 'INSERT INTO person (username, password, salt, first_name, last_name) VALUES (%s, %s, %s, %s, %s)'
    cursor.execute(query, (username, password_hash, salt, firstname, lastname))
    conn.commit()
    cursor.close()

    query = "INSERT INTO profile (username, bio, file_path) VALUES (%s, '', '')"
    cursor = conn.cursor()
    cursor.execute(query, (username))
    conn.commit()
    cursor.close()

    session['logged_in'] = True
    session['username'] = username
    session['users'][username] = {}
    session['users'][username]['groups'] = []
    session['users'][username]['first_name'] = firstname
    session['users'][username]['last_name'] = lastname

    return redirect(url_for('main', username=session['username']))
Example #9
0
 def password(self, pw):
     pw_bin = pw.encode('utf-8')
     salt_bin = generate_random_salt(64)
     self.password_salt = salt_bin.decode('ascii')
     hash_bin = generate_password_hash(
         pw_bin,
         salt_bin,
         # use defaults, but specify explicitly here
         N=1 << 14,
         r=8,
         p=1,
         buflen=64)
     self.password_hash = hash_bin.decode('ascii')
Example #10
0
def new_user(login, password):
    user = User()
    user.login = login

    # generate a strong cryptographic hash from the password
    salt = generate_random_salt(byte_size=64)
    phash = generate_password_hash(password,
                                   salt,
                                   N=16384,
                                   r=8,
                                   p=1,
                                   buflen=64)
    user.password = phash + salt

    return user
Example #11
0
def signup_post():
    email = request.form.get('email')
    name = request.form.get('name')
    password = request.form.get('password')
    phone = request.form.get('phone')
    address = request.form.get('address')

    user = User.query.filter_by(email=email).first()

    if user:
        flash('Email address already exists')
        return redirect(url_for('auth.signup'))
    if len(name) > 10:
        flash('Allowed max length of name is 10')
        return redirect(url_for('auth.signup'))
    while True:
        if re.search('[0-9]', password) is None:
            flash('Make sure your password has a number in it')
            return redirect(url_for('auth.signup'))
        elif re.search('[A-Z]', password) is None:
            flash('Make sure your password has a capital letter in it')
            return redirect(url_for(auth.signup))
        elif re.search('[@_!#$%^&*()<>?/|]', password) is None:
            flash('Make sure your password has a special character')
            return redirect(url_for('auth.signup'))
        else:
            break

    new_user = User(email=email, name=name, address=address, phone=phone)

    db.session.add(new_user)
    db.session.commit()

    salt = generate_random_salt()
    password_full = str(salt) + str(password)
    new_password = Password(user_id=new_user.id,
                            salt=salt,
                            password=generate_password_hash(password_full,
                                                            method='sha256'))

    db.session.add(new_password)
    db.session.commit()
    return redirect(url_for('auth.login'))
Example #12
0
 def register(self, password: str, email: str):
     self.password = password
     self.email = email
     salt = generate_random_salt()
     accounts.insert_one({
         "name":
         self.name,
         "password":
         generate_password_hash(self.password, salt),
         "email":
         self.email,
         "salt":
         salt,
     })
     msg = Message(
         self.name + ", your FUTURE account has been created",
         sender="*****@*****.**",
         recipients=[self.email],
     )
     msg.html = open("./templates/confirmation.html",
                     encoding='utf8').read()
     mail.send(msg)
Example #13
0
 def set_password(self, ptext):
     self.passsalt = flask_scrypt.generate_random_salt()
     self.passhash = flask_scrypt.generate_password_hash(
       ptext,
       self.passsalt)
Example #14
0
 def password(self, password):
     self.password_salt = generate_random_salt()
     self.password_hash = generate_password_hash(password,
                                                 self.password_salt)
Example #15
0
def init(args):
    import configparser
    import datetime
    import logging
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask_scrypt import generate_random_salt

    import pajbot.web.common
    import pajbot.web.routes
    from pajbot.bot import Bot
    from pajbot.managers.db import DBManager
    from pajbot.managers.redis import RedisManager
    from pajbot.managers.time import TimeManager
    from pajbot.models.module import ModuleManager
    from pajbot.models.sock import SocketClientManager
    from pajbot.streamhelper import StreamHelper
    from pajbot.utils import load_config
    from pajbot.web.models import errors
    from pajbot.web.utils import download_logo

    log = logging.getLogger(__name__)

    config = configparser.ConfigParser()

    config = load_config(args.config)
    config.read('webconfig.ini')

    if 'web' not in config:
        log.error('Missing [web] section in config.ini')
        sys.exit(1)

    if 'pleblist_password_salt' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'pleblist_password_salt', salt.decode('utf-8'))

    if 'pleblist_password' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'pleblist_password', salt.decode('utf-8'))

    if 'secret_key' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'secret_key', salt.decode('utf-8'))

    if 'logo' not in config['web']:
        res = download_logo(config['webtwitchapi']['client_id'], config['main']['streamer'])
        if res:
            config.set('web', 'logo', 'set')

    StreamHelper.init_web(config['main']['streamer'])

    redis_options = {}
    if 'redis' in config:
        redis_options = config._sections['redis']

    RedisManager.init(**redis_options)

    with open(args.config, 'w') as configfile:
        config.write(configfile)

    app.bot_modules = config['web'].get('modules', '').split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config['web']['secret_key']

    if 'sock' in config and 'sock_file' in config['sock']:
        SocketClientManager.init(config['sock']['sock_file'])

    DBManager.init(config['main']['db'])
    TimeManager.init_timezone(config['main'].get('timezone', 'UTC'))

    app.module_manager = ModuleManager(None).load()

    pajbot.web.routes.admin.init(app)
    pajbot.web.routes.api.init(app)
    pajbot.web.routes.base.init(app)

    pajbot.web.common.filters.init(app)
    pajbot.web.common.assets.init(app)
    pajbot.web.common.tasks.init(app)
    pajbot.web.common.menu.init(app)

    app.register_blueprint(pajbot.web.routes.clr.page)

    errors.init(app, config)
    pajbot.web.routes.clr.config = config

    version = Bot.version
    last_commit = ''
    commit_number = 0
    try:
        current_branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).decode('utf8').strip()
        latest_commit = subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('utf8').strip()[:8]
        commit_number = subprocess.check_output(['git', 'rev-list', 'HEAD', '--count']).decode('utf8').strip()
        last_commit = subprocess.check_output(['git', 'log', '-1', '--format=%cd']).decode('utf8').strip()
        version = '{0} DEV ({1}, {2}, commit {3})'.format(version, current_branch, latest_commit, commit_number)
    except:
        pass

    default_variables = {
            'version': version,
            'last_commit': last_commit,
            'commit_number': commit_number,
            'bot': {
                'name': config['main']['nickname'],
                },
            'site': {
                'domain': config['web']['domain'],
                'deck_tab_images': config.getboolean('web', 'deck_tab_images'),
                'websocket': {
                    'host': config['websocket'].get('host', config['web']['domain']),
                    'port': config['websocket']['port'],
                    'ssl': config.getboolean('websocket', 'ssl')
                    }
                },
            'streamer': {
                'name': config['web']['streamer_name'],
                'full_name': config['main']['streamer']
                },
            'modules': app.bot_modules,
            'request': request,
            'session': session,
            'google_analytics': config['web'].get('google_analytics', None),
            }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time['current_time'] = datetime.datetime.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables
Example #16
0
 def _set_salt(self):
     self.salt = generate_random_salt().decode()
Example #17
0
def create_password_hash(password):
    pwdhash = {'salt':None, 'password':None}
    pwdhash['salt'] = generate_random_salt(salt_size)
    pwdhash['password'] = generate_password_hash(password, pwdhash['salt'], N=cpu_cost, r=memory_cost, buflen=hash_size)
    return pwdhash
Example #18
0
def register():
    msg = ''
    # Check if "username" and "password" POST requests exist (user submitted form)
    if register.method == 'POST' and 'username' in request.form and 'password' in request.form and 'email' in request.form:
        username = request.form['username']
        password = request.form['password']
        email = request.form['email']
        # Check if account exists using MySQL
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM accounts WHERE username = %s',
                       (username))
        account = cursor.fetchone()
        # If account exists show error and validation checks
        if account:
            msg = '이미 등록한 회원입니다!'
        elif not re.match(r'[^@]+@[^@]+\.[^@]+', email):
            msg = '유효하지 않은 이메일 주소입니다!'
        elif not re.match(r'[A-Za-z0-9]+', username):
            msg = '아이디는 숫자와 문자로만 이루어져야합니다!'
        elif not username or not password or not email:
            msg = '입력 칸을 채워주세요!'
        elif account_activation_required:
            # Account activation enabled

            # Generate a random unique id for activation code
            activation_code = uuid.uuid4()

            # Scrypt password hashing and random salt generation
            salt = generate_random_salt()
            password_hash = generate_password_hash(password, salt)

            cursor.execute(
                'INSERT INTO accounts VALUES (NULL, %s, %s, %s, %s, %s,"")',
                (username, password_hash, salt, email, activation_code))
            mysql.connection.commit()

            email = Message('Account Activation Required',
                            sender='*****@*****.**',
                            recipients=[email])

            activate_link = 'http://localhost:5000/pythonlogin/activate/' + str(
                email) + '/' + str(activation_code)

            email.body = '<p>아래 링크를 클릭하여 이메일을 인증하세요: <a hredf="' + str(
                activate_link) + '">' + str(activate_link) + '</a></p>'
            mail.send(email)
            return '이메일이 발송되었습니다. 계정을 활성화하려면 이메일을 인증하세요!'
        else:
            # Account doesn't exist and the form data is valid. Insert new Account
            cursor.execute('INSERT INTO accounts VALUES (NULL, %s, %s, %s)',
                           (username, password, email))
            mysql.connection.commit()
            msg = '회원 등록 성공!'

        cursor.close()
        mysql.connection.close()
    elif request.method == 'POST':
        # Form is empty
        msg = '회원 등록 정보를 입력해주세요'

    return render_template('register.html', msg=msg)
Example #19
0
def init(args):
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask_scrypt import generate_random_salt

    import greenbot.utils
    import greenbot.web.common
    import greenbot.web.routes

    from greenbot.managers.db import DBManager
    from greenbot.managers.redis import RedisManager
    from greenbot.managers.schedule import ScheduleManager
    from greenbot.models.module import ModuleManager
    from greenbot.models.sock import SocketClientManager
    from greenbot.utils import load_config
    from greenbot.web.models import errors
    from greenbot.bothelper import BotHelper

    ScheduleManager.init()

    config = load_config(args.config)

    redis_options = {}
    if "redis" in config:
        redis_options = dict(config["redis"])

    RedisManager.init(**redis_options)

    if "web" not in config:
        log.error("Missing [web] section in config.ini")
        sys.exit(1)

    if "secret_key" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "secret_key", salt.decode("utf-8"))

        with open(args.config, "w") as configfile:
            config.write(configfile)

    bot_name = config["main"]["bot_name"]
    BotHelper.set_bot_name(bot_name)
    SocketClientManager.init(bot_name)

    app.bot_modules = config["web"].get("modules", "").split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config["web"]["secret_key"]
    app.config["DISCORD_CLIENT_ID"] = app.bot_config["discord"]["client_id"]
    app.config["DISCORD_CLIENT_SECRET"] = app.bot_config["discord"][
        "client_secret"]
    app.config["DISCORD_REDIRECT_URI"] = app.bot_config["discord"][
        "redirect_uri"]
    app.bot_dev = ("flags" in config and "dev" in config["flags"]
                   and config["flags"]["dev"] == "1")

    DBManager.init(config["main"]["db"])

    app.module_manager = ModuleManager(None).load()

    greenbot.web.routes.admin.init(app)
    greenbot.web.routes.api.init(app)
    greenbot.web.routes.base.init(app)

    greenbot.web.common.filters.init(app)
    greenbot.web.common.assets.init(app)
    greenbot.web.common.menu.init(app)

    errors.init(app, config)

    last_commit = None
    if app.bot_dev:
        try:
            last_commit = (subprocess.check_output(
                ["git", "log", "-1", "--format=%cd"]).decode("utf8").strip())
        except:
            log.exception(
                "Failed to get last_commit, will not show last commit")

    default_variables = {
        "last_commit": last_commit,
        "version": "v1.0",
        "bot": {
            "name": config["main"]["bot_name"]
        },
        "site": {
            "domain": config["web"]["domain"]
        },
        "modules": app.bot_modules,
        "request": request,
        "session": session,
        "google_analytics": config["web"].get("google_analytics", None),
    }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time["current_time"] = greenbot.utils.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables
Example #20
0
 def test_accept_unicode_str_python2(self):
     salt = generate_random_salt()
     password = unicode(self.password)
     password_hash = generate_password_hash(password, salt)
     self.assertTrue(check_password_hash(password, password_hash, salt))
Example #21
0
 def test_password_fail_with_incorrect_salt(self):
     password = self.password
     password_hash = self.password_hash
     salt = generate_random_salt()
     self.assertFalse(check_password_hash(password, password_hash, salt))
Example #22
0
 def setUp(self):
     self.salt = generate_random_salt()
     self.password = '******'
     self.password_hash = generate_password_hash(self.password, self.salt)
Example #23
0
def init(args):
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask import g
    from flask_scrypt import generate_random_salt

    import pajbot.utils
    import pajbot.web.common
    import pajbot.web.routes

    from pajbot.managers.db import DBManager
    from pajbot.managers.redis import RedisManager
    from pajbot.managers.schedule import ScheduleManager
    from pajbot.managers.songrequest_queue_manager import SongRequestQueueManager
    from pajbot.models.module import ModuleManager
    from pajbot.models.sock import SocketClientManager
    from pajbot.streamhelper import StreamHelper
    from pajbot.utils import load_config
    from pajbot.web.models import errors
    from pajbot.web.utils import download_logo
    from pajbot.web.utils import download_sub_badge

    ScheduleManager.init()

    config = load_config(args.config)
    # ScheduleManager.init()
    api_client_credentials = ClientCredentials(
        config["twitchapi"]["client_id"], config["twitchapi"]["client_secret"], config["twitchapi"]["redirect_uri"]
    )

    redis_options = {}
    if "redis" in config:
        redis_options = dict(config["redis"])

    RedisManager.init(**redis_options)

    id_api = TwitchIDAPI(api_client_credentials)
    app_token_manager = AppAccessTokenManager(id_api, RedisManager.get())
    twitch_helix_api = TwitchHelixAPI(RedisManager.get(), app_token_manager)
    twitch_badges_api = TwitchBadgesAPI(RedisManager.get())

    if "web" not in config:
        log.error("Missing [web] section in config.ini")
        sys.exit(1)

    if "secret_key" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "secret_key", salt.decode("utf-8"))

        with open(args.config, "w") as configfile:
            config.write(configfile)

    streamer = config["main"]["streamer"]
    SongRequestQueueManager.init(streamer)
    streamer_user_id = twitch_helix_api.get_user_id(streamer)
    if streamer_user_id is None:
        raise ValueError("The streamer login name you entered under [main] does not exist on twitch.")
    StreamHelper.init_streamer(streamer, streamer_user_id)

    try:
        download_logo(twitch_helix_api, streamer, streamer_user_id)
    except:
        log.exception("Error downloading the streamers profile picture")

    subscriber_badge_version = config["web"].get("subscriber_badge_version", "0")

    # Specifying a value of -1 in the config will disable sub badge downloading. Useful if you want to keep a custom version of a sub badge for a streamer
    if subscriber_badge_version != "-1":
        try:
            download_sub_badge(twitch_badges_api, streamer, streamer_user_id, subscriber_badge_version)
        except:
            log.exception("Error downloading the streamers subscriber badge")

    SocketClientManager.init(streamer)

    app.bot_modules = config["web"].get("modules", "").split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config["web"]["secret_key"]
    app.bot_dev = "flags" in config and "dev" in config["flags"] and config["flags"]["dev"] == "1"

    DBManager.init(config["main"]["db"])

    app.module_manager = ModuleManager(None).load()

    pajbot.web.routes.admin.init(app)
    pajbot.web.routes.api.init(app)
    pajbot.web.routes.base.init(app)

    pajbot.web.common.filters.init(app)
    pajbot.web.common.assets.init(app)
    pajbot.web.common.menu.init(app)

    app.register_blueprint(pajbot.web.routes.clr.page)

    errors.init(app, config)
    pajbot.web.routes.clr.config = config

    version = VERSION
    last_commit = None

    if app.bot_dev:
        version = extend_version_if_possible(VERSION)

        try:
            last_commit = subprocess.check_output(["git", "log", "-1", "--format=%cd"]).decode("utf8").strip()
        except:
            log.exception("Failed to get last_commit, will not show last commit")

    default_variables = {
        "version": version,
        "last_commit": last_commit,
        "bot": {"name": config["main"]["nickname"]},
        "site": {
            "domain": config["web"]["domain"],
            "deck_tab_images": config.getboolean("web", "deck_tab_images"),
            "websocket": {"host": config["websocket"].get("host", f"wss://{config['web']['domain']}/clrsocket")},
            "songrequestWS": {
                "host": config["songrequest-websocket"].get(
                    "host", f"wss://{config['web']['domain']}/songrequest_websocket"
                )
            },
        },
        "streamer": {"name": config["web"]["streamer_name"], "full_name": config["main"]["streamer"]},
        "modules": app.bot_modules,
        "request": request,
        "session": session,
        "google_analytics": config["web"].get("google_analytics", None),
    }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time["current_time"] = pajbot.utils.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables
Example #24
0
def init(args):
    import configparser
    import logging
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask_scrypt import generate_random_salt

    import pajbot.utils
    import pajbot.web.common
    import pajbot.web.routes
    from pajbot import constants
    from pajbot.managers.db import DBManager
    from pajbot.managers.redis import RedisManager
    from pajbot.managers.time import TimeManager
    from pajbot.models.module import ModuleManager
    from pajbot.models.sock import SocketClientManager
    from pajbot.streamhelper import StreamHelper
    from pajbot.utils import load_config
    from pajbot.web.models import errors
    from pajbot.web.utils import download_logo

    log = logging.getLogger(__name__)

    config = configparser.ConfigParser()

    config = load_config(args.config)
    config.read("webconfig.ini")

    api_client_credentials = ClientCredentials(
        config["twitchapi"]["client_id"], config["twitchapi"]["client_secret"], config["twitchapi"]["redirect_uri"]
    )

    redis_options = {}
    if "redis" in config:
        redis_options = dict(config["redis"])

    RedisManager.init(**redis_options)

    id_api = TwitchIDAPI(api_client_credentials)
    app_token_manager = AppAccessTokenManager(id_api, RedisManager.get())
    twitch_helix_api = TwitchHelixAPI(RedisManager.get(), app_token_manager)

    if "web" not in config:
        log.error("Missing [web] section in config.ini")
        sys.exit(1)

    if "pleblist_password_salt" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "pleblist_password_salt", salt.decode("utf-8"))

    if "pleblist_password" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "pleblist_password", salt.decode("utf-8"))

    if "secret_key" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "secret_key", salt.decode("utf-8"))

    if "logo" not in config["web"]:
        try:
            download_logo(twitch_helix_api, config["main"]["streamer"])
            config.set("web", "logo", "set")
        except:
            log.exception("Error downloading logo")

    StreamHelper.init_web(config["main"]["streamer"])
    SocketClientManager.init(config["main"]["streamer"])

    with open(args.config, "w") as configfile:
        config.write(configfile)

    app.bot_modules = config["web"].get("modules", "").split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config["web"]["secret_key"]

    DBManager.init(config["main"]["db"])
    TimeManager.init_timezone(config["main"].get("timezone", "UTC"))

    app.module_manager = ModuleManager(None).load()

    pajbot.web.routes.admin.init(app)
    pajbot.web.routes.api.init(app)
    pajbot.web.routes.base.init(app)

    pajbot.web.common.filters.init(app)
    pajbot.web.common.assets.init(app)
    pajbot.web.common.menu.init(app)

    app.register_blueprint(pajbot.web.routes.clr.page)

    errors.init(app, config)
    pajbot.web.routes.clr.config = config

    version = extend_version_if_possible(VERSION)

    try:
        last_commit = subprocess.check_output(["git", "log", "-1", "--format=%cd"]).decode("utf8").strip()
    except:
        log.exception("Failed to get last_commit, will not show last commit")
        last_commit = None

    default_variables = {
        "version": version,
        "last_commit": last_commit,
        "bot": {"name": config["main"]["nickname"]},
        "site": {
            "domain": config["web"]["domain"],
            "deck_tab_images": config.getboolean("web", "deck_tab_images"),
            "websocket": {
                "host": config["websocket"].get("host", "wss://{}/clrsocket".format(config["web"]["domain"]))
            },
        },
        "streamer": {"name": config["web"]["streamer_name"], "full_name": config["main"]["streamer"]},
        "modules": app.bot_modules,
        "request": request,
        "session": session,
        "google_analytics": config["web"].get("google_analytics", None),
    }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time["current_time"] = pajbot.utils.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables
Example #25
0
def register():
    if RegistrationForm().email:
        carryOverEmail = RegistrationForm().email.data
    form = RegistrationForm()
    form2 = TwoFactorAuthRegForm()

    # form er den første formen som er på /register, som per nå bare inneholder email, passord og en submit-knapp

    # form2 er den andre formen du kommer til etter du submitter "form". Denne nye siden vil da inneholde QR-koden
    # for å legge 2fa-nøkkelen inn i din valgte 2fa app. Denne siden har også et passord felt, 2fa felt (for koden du nå kan generere i appen),
    # og et "read-only" som inneholder eposten du skrev inn på forrige side.
    if form.validate_on_submit():
        errList = []
        getPasswordViolations(errList, form.password.data,
                              form.confirm_password.data, form.email.data)

        # Is there any error in the generated information
        if len(errList) == 0:

            # ─── HASHED EMAIL IS USER ID ─────────────────────────────────────
            hashed_email = flask_scrypt.generate_password_hash(
                form.email.data, "")

            # Key MUST have register keyword appended so as not to mix user keys in redis server
            registerRedisKey = hashed_email + "register".encode('utf-8')

            # ─── CHECK IF THE EMAIL EXISTS IN DATABASE OR REDIS ───────────────────────
            if User.query.filter_by(email=hashed_email.decode(
                    "utf-8")).first() or redis.get(registerRedisKey):
                flash("Couldn't continue, due to an error", "error")
                return render_template("register.html",
                                       form=form), disable_caching

            # ─── IF THE USER DOES NOT EXIST IN THE DATABASE ──────────────────
            # Create a user dictionairy for redis.
            userDict = {}

            # add hashed email as key to cleartext email
            # This can be directly saved to database later as user email
            userDict['email'] = hashed_email.decode("utf-8")

            # We need to temporarily keep the users email in plaintext while in redis

            userDict["PlainEmail"] = form.email.data

            # ─── SALT AND HASH PASSWORD ──────────────────────────────────────
            salt = flask_scrypt.generate_random_salt()

            # add hashed password to user dictionairy
            # This can be directly saved to database later
            userDict['password'] = flask_scrypt.generate_password_hash(
                form.password.data, salt) + salt

            # ─── GENERATE USER ENCRYPTION KEY ────────────────────────────────

            # generate new encrypted key with users password
            encryptedKey = encrypt(form.password.data, 'generate', True)

            # decrypt the key again, serves as a double check
            deKey = decrypt(form.password.data, encryptedKey, True)

            # If deKey, explicitly show what you are testing this against none.
            if deKey is not None:
                userDict['enKey'] = encryptedKey

            # encrypt the email and add it to userDict
            userDict['enEmail'] = encrypt(deKey, form.email.data)

            # ─── TESTING 2-FACTOR AUTHENTICATION ───────────────────────────────────────────────────#

            # Lager en relativt simpel secret_key. Har kompatibilitet med Google Authenticator.
            secret_key = pyotp.random_base32()

            # denne maa tas vare på til neste side, krypteres med kundes passord
            userDict['secret'] = encrypt(deKey, secret_key)

            # Genererer link for kundes qr kode
            qr_link = pyotp.totp.TOTP(secret_key).provisioning_uri(
                name=form.email.data, issuer_name="Safecoin.tech")

            # json generate string from dict overwrite the dict from before
            userDict = dictToStr(userDict)

            # Add it to the redis server
            redis.set(registerRedisKey, userDict)
            # Set session timeout of user at 600 seconds, 10 minutes
            redis.expire(registerRedisKey, 600)
            log_startregister(hashed_email)
            return render_template(
                'TwoFactor.html', form2=form2, qr_link=qr_link
            ), disable_caching  # Vi må dra med inn qr_linken for å generere qr_koden korrekt

        # ─── DERSOM FEIL VED REGISTEREING ───────────────────────────────────────────────
        for err in errList:
            flash(err, "error")
    elif form.submit.data and not form2.is_submitted():
        flash("Couldn't continue, due to an error", "error")

    if form2.validate_on_submit():

        # Regenerate hashed email from last page
        hashed_email = flask_scrypt.generate_password_hash(carryOverEmail, "")

        # Key MUST have register keyword appended so as not to mix user keys in redis server
        registerRedisKey = hashed_email + "register".encode('utf-8')

        # retrive information from redis
        userDict = redis.get(registerRedisKey)

        # delete user from redis
        redis.delete(registerRedisKey.decode("utf-8"))

        # Format back to dictionairy
        userDict = json.loads(userDict)

        # Check password correctness
        pwOK = flask_scrypt.check_password_hash(
            form2.password_2fa.data.encode('utf-8'),
            userDict['password'][:88].encode('utf-8'),
            userDict['password'][88:176].encode('utf-8'))
        if pwOK:
            # Decrypt the users decryption key
            decryptionKey = decrypt(form2.password_2fa.data.encode('utf-8'),
                                    userDict['enKey'].encode('utf-8'), True)

            # Decrypt 2FA key with user decryption key
            twoFAkey = decrypt(decryptionKey, userDict['secret'])

            # add key to the Timed One Timed Passwords class so it can verify
            totp = pyotp.totp.TOTP(twoFAkey)

            # Hvis brukeren scanner qrkoden (som genereres i html) vil koden som vises i appen deres matche koden til totp.now()
            if totp.verify(form2.otp.data):
                # user = User(email=hashed_email.decode("utf-8"), enEmail=mailEncrypted, password=(hashed_pw+salt).decode("utf-8"),enKey=encryptedKey, secret=secret_key)

                # Create user class
                user = User()
                user.email = hashed_email
                user.enEmail = userDict['enEmail']
                user.password = userDict['password']
                user.enKey = userDict['enKey']
                user.accounts = None
                user.secret = userDict['secret']

                db.session.add(user)
                db.session.commit()

                flash(
                    'Your account has been created! You are now able to log in.',
                    'success')
                log_register(True, hashed_email)

                # ─── ADD ACCOUNT WITH MONEY TO USER ─────────────────────────────────────────────
                # You start with an account that we add so that we and
                # Whomever is going to thest our site can work with it
                addNewAccountToCurUser(
                    password=form2.password_2fa.data,
                    otp='',
                    user=User.query.filter_by(email=hashed_email).first(),
                    money=True,
                    isCurrentUser=False)
                # ─── ADD ACCOUNT WITH MONEY TO USER ─────────────────────────────────────────────

                return redirect(url_for('home'))

        flash("Couldn't register user, due to an error", "error")
        log_register(False, hashed_email)

    return render_template("register.html", form=form), disable_caching
Example #26
0
def init(args):
    import configparser
    import logging
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask_scrypt import generate_random_salt

    import pajbot.utils
    import pajbot.web.common
    import pajbot.web.routes
    from pajbot.bot import Bot
    from pajbot.managers.db import DBManager
    from pajbot.managers.redis import RedisManager
    from pajbot.managers.time import TimeManager
    from pajbot.models.module import ModuleManager
    from pajbot.models.sock import SocketClientManager
    from pajbot.models.sock import SocketManager
    from pajbot.streamhelper import StreamHelper
    from pajbot.utils import load_config
    from pajbot.web.models import errors
    from pajbot.web.utils import download_logo

    log = logging.getLogger(__name__)

    config = configparser.ConfigParser()

    config = load_config(args.config)
    config.read("webconfig.ini")

    if "web" not in config:
        log.error("Missing [web] section in config.ini")
        sys.exit(1)

    if "pleblist_password_salt" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "pleblist_password_salt", salt.decode("utf-8"))

    if "pleblist_password" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "pleblist_password", salt.decode("utf-8"))

    if "secret_key" not in config["web"]:
        salt = generate_random_salt()
        config.set("web", "secret_key", salt.decode("utf-8"))

    if "logo" not in config["web"]:
        res = download_logo(config["webtwitchapi"]["client_id"],
                            config["main"]["streamer"])
        if res:
            config.set("web", "logo", "set")

    StreamHelper.init_web(config["main"]["streamer"])
    SocketClientManager.init(config["main"]["streamer"])

    redis_options = {}
    if "redis" in config:
        redis_options = dict(config["redis"])

    RedisManager.init(**redis_options)

    with open(args.config, "w") as configfile:
        config.write(configfile)

    app.bot_modules = config["web"].get("modules", "").split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config["web"]["secret_key"]

    DBManager.init(config["main"]["db"])
    TimeManager.init_timezone(config["main"].get("timezone", "UTC"))

    app.module_manager = ModuleManager(None).load()

    pajbot.web.routes.admin.init(app)
    pajbot.web.routes.api.init(app)
    pajbot.web.routes.base.init(app)

    pajbot.web.common.filters.init(app)
    pajbot.web.common.assets.init(app)
    pajbot.web.common.menu.init(app)

    app.register_blueprint(pajbot.web.routes.clr.page)

    errors.init(app, config)
    pajbot.web.routes.clr.config = config

    version = Bot.version
    last_commit = ""
    commit_number = 0
    try:
        current_branch = subprocess.check_output(
            ["git", "rev-parse", "--abbrev-ref",
             "HEAD"]).decode("utf8").strip()
        latest_commit = subprocess.check_output(["git", "rev-parse", "HEAD"
                                                 ]).decode("utf8").strip()[:8]
        commit_number = subprocess.check_output(
            ["git", "rev-list", "HEAD", "--count"]).decode("utf8").strip()
        last_commit = subprocess.check_output(
            ["git", "log", "-1", "--format=%cd"]).decode("utf8").strip()
        version = "{0} DEV ({1}, {2}, commit {3})".format(
            version, current_branch, latest_commit, commit_number)
    except:
        pass

    default_variables = {
        "version": version,
        "last_commit": last_commit,
        "commit_number": commit_number,
        "bot": {
            "name": config["main"]["nickname"]
        },
        "site": {
            "domain": config["web"]["domain"],
            "deck_tab_images": config.getboolean("web", "deck_tab_images"),
            "websocket": {
                "host":
                config["websocket"].get(
                    "host",
                    "wss://{}/clrsocket".format(config["web"]["domain"]))
            },
        },
        "streamer": {
            "name": config["web"]["streamer_name"],
            "full_name": config["main"]["streamer"]
        },
        "modules": app.bot_modules,
        "request": request,
        "session": session,
        "google_analytics": config["web"].get("google_analytics", None),
    }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time["current_time"] = pajbot.utils.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables
Example #27
0
def init(args):
    import configparser
    import datetime
    import logging
    import subprocess
    import sys

    from flask import request
    from flask import session
    from flask_scrypt import generate_random_salt

    import pajbot.web.common
    import pajbot.web.routes
    from pajbot.bot import Bot
    from pajbot.managers.db import DBManager
    from pajbot.managers.redis import RedisManager
    from pajbot.managers.time import TimeManager
    from pajbot.models.module import ModuleManager
    from pajbot.models.sock import SocketClientManager
    from pajbot.streamhelper import StreamHelper
    from pajbot.utils import load_config
    from pajbot.web.models import errors
    from pajbot.web.utils import download_logo

    log = logging.getLogger(__name__)

    config = configparser.ConfigParser()

    config = load_config(args.config)
    config.read('webconfig.ini')

    if 'web' not in config:
        log.error('Missing [web] section in config.ini')
        sys.exit(1)

    if 'pleblist_password_salt' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'pleblist_password_salt', salt.decode('utf-8'))

    if 'pleblist_password' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'pleblist_password', salt.decode('utf-8'))

    if 'secret_key' not in config['web']:
        salt = generate_random_salt()
        config.set('web', 'secret_key', salt.decode('utf-8'))

    if 'logo' not in config['web']:
        res = download_logo(config['webtwitchapi']['client_id'],
                            config['main']['streamer'])
        if res:
            config.set('web', 'logo', 'set')

    StreamHelper.init_web(config['main']['streamer'])

    redis_options = {}
    if 'redis' in config:
        redis_options = config._sections['redis']

    RedisManager.init(**redis_options)

    with open(args.config, 'w') as configfile:
        config.write(configfile)

    app.bot_modules = config['web'].get('modules', '').split()
    app.bot_commands_list = []
    app.bot_config = config
    app.secret_key = config['web']['secret_key']

    if 'sock' in config and 'sock_file' in config['sock']:
        SocketClientManager.init(config['sock']['sock_file'])

    DBManager.init(config['main']['db'])
    TimeManager.init_timezone(config['main'].get('timezone', 'UTC'))

    app.module_manager = ModuleManager(None).load()

    pajbot.web.routes.admin.init(app)
    pajbot.web.routes.api.init(app)
    pajbot.web.routes.base.init(app)
    pajbot.web.routes.playsound.init(app)

    pajbot.web.common.filters.init(app)
    pajbot.web.common.assets.init(app)
    pajbot.web.common.tasks.init(app)
    pajbot.web.common.menu.init(app)

    app.register_blueprint(pajbot.web.routes.clr.page)

    errors.init(app, config)
    pajbot.web.routes.clr.config = config

    version = Bot.version
    last_commit = ''
    commit_number = 0
    try:
        current_branch = subprocess.check_output(
            ['git', 'rev-parse', '--abbrev-ref',
             'HEAD']).decode('utf8').strip()
        latest_commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'
                                                 ]).decode('utf8').strip()[:8]
        commit_number = subprocess.check_output(
            ['git', 'rev-list', 'HEAD', '--count']).decode('utf8').strip()
        last_commit = subprocess.check_output(
            ['git', 'log', '-1', '--format=%cd']).decode('utf8').strip()
        version = '{0} DEV ({1}, {2}, commit {3})'.format(
            version, current_branch, latest_commit, commit_number)
    except:
        pass

    default_variables = {
        'version': version,
        'last_commit': last_commit,
        'commit_number': commit_number,
        'bot': {
            'name': config['main']['nickname'],
        },
        'site': {
            'domain': config['web']['domain'],
            'deck_tab_images': config.getboolean('web', 'deck_tab_images'),
            'websocket': {
                'host': config['websocket'].get('host',
                                                config['web']['domain']),
                'port': config['websocket']['port'],
                'ssl': config.getboolean('websocket', 'ssl')
            }
        },
        'streamer': {
            'name': config['web']['streamer_name'],
            'full_name': config['main']['streamer']
        },
        'modules': app.bot_modules,
        'request': request,
        'session': session,
        'google_analytics': config['web'].get('google_analytics', None),
    }

    @app.context_processor
    def current_time():
        current_time = {}
        current_time['current_time'] = datetime.datetime.now()
        return current_time

    @app.context_processor
    def inject_default_variables():
        return default_variables