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
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
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
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
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)
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']))
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')
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
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'))
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)
def set_password(self, ptext): self.passsalt = flask_scrypt.generate_random_salt() self.passhash = flask_scrypt.generate_password_hash( ptext, self.passsalt)
def password(self, password): self.password_salt = generate_random_salt() self.password_hash = generate_password_hash(password, self.password_salt)
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
def _set_salt(self): self.salt = generate_random_salt().decode()
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
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)
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
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))
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))
def setUp(self): self.salt = generate_random_salt() self.password = '******' self.password_hash = generate_password_hash(self.password, self.salt)
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
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
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
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
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