예제 #1
0
파일: auth.py 프로젝트: puhlenbruck/CPPA
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
예제 #2
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'))
예제 #3
0
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
예제 #4
0
def generate_hash(key):
    """
    Generate hash for key
    """
    phash = generate_password_hash(key, get_settings()['secret'])
    return str(b64encode(phash),
               'utf-8')[:10]  # limit len to 10, is sufficient
예제 #5
0
def generate_hash(key, salt=None):
    """
    Generate hash for key
    """
    if not salt:
        salt = app.secret_key
    phash = generate_password_hash(key, salt)
    return str(b64encode(phash), 'utf-8')[:10]  # limit len to 10, is sufficient
예제 #6
0
파일: utils.py 프로젝트: jardg/pajbot
def pleblist_login(in_password, bot_config):
    """ Throws an InvalidLogin exception if the login was not good """
    salted_password = generate_password_hash(bot_config['web']['pleblist_password'], bot_config['web']['pleblist_password_salt'])

    try:
        user_password = base64.b64decode(in_password)
    except binascii.Error:
        raise pajbot.exc.InvalidLogin('Invalid password')
    if not user_password == salted_password:
        raise pajbot.exc.InvalidLogin('Invalid password')
예제 #7
0
파일: admin.py 프로젝트: feuloren/nylog
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
예제 #8
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)
예제 #9
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
예제 #10
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
예제 #11
0
파일: utils.py 프로젝트: uFloppyDisk/pajbot
def pleblist_login(in_password, bot_config):
    """ Throws an InvalidLogin exception if the login was not good """
    salted_password = generate_password_hash(
        bot_config['web']['pleblist_password'],
        bot_config['web']['pleblist_password_salt'])

    try:
        user_password = base64.b64decode(in_password)
    except binascii.Error:
        raise pajbot.exc.InvalidLogin('Invalid password')
    if not user_password == salted_password:
        raise pajbot.exc.InvalidLogin('Invalid password')
예제 #12
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']))
예제 #13
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')
예제 #14
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
예제 #15
0
    def validate_login(self, field):
        """
        validate login
        :param field:
        :return:
        """
        user = self.get_user()

        if user is None:
            raise validators.ValidationError('User does not exist.')

        if user.password != generate_password_hash(self.password.data, user.salt):
            raise validators.ValidationError('Credentials incorrect.')

        if not user.is_admin and not user.is_super_admin:
            raise validators.ValidationError('Access Forbidden. Admin Rights Required')
예제 #16
0
    def validate_login(self, field):
        """
        validate login
        :param field:
        :return:
        """
        user = self.get_user()

        if user is None:
            raise validators.ValidationError('User does not exist.')

        if user.password != generate_password_hash(self.password.data, user.salt):
            raise validators.ValidationError('Credentials incorrect.')

        if not user.is_admin and not user.is_super_admin:
            raise validators.ValidationError('Access Forbidden. Admin Rights Required')
예제 #17
0
def verifyUser(email, password, addToActive=False):
    # hash the email
    if email is None:
        hashed_email = current_user.email
    else:
        hashed_email = flask_scrypt.generate_password_hash(email, "")

    # create user class with information from database
    userDB = User.query.filter_by(email=hashed_email).first()

    # if the user doesnt exist in database
    if userDB is None:
        return False, None, None

    # format password from database
    DBpw = userDB.password.encode('utf-8')

    # check if the hashed email is the same ass the one in the database, just a double check.
    # Strictly not nececairy, but just seems logical to do.
    emailOK = hashed_email.decode('utf-8') == userDB.email.decode(
        'utf-8')  # boolean to compare with

    # Verify that the password is correct
    pwOK = flask_scrypt.check_password_hash(password.encode('utf-8'),
                                            DBpw[:88], DBpw[88:176])

    # Check if the password is correct and email exists in the database
    if emailOK and pwOK:

        # decrypte the users encryption key
        decryptKey = decrypt(password, userDB.enKey.encode('utf-8'), True)

        # Decrypt the secret key
        secret_key = decrypt(decryptKey, userDB.secret.encode('utf-8'))

        if addToActive:
            # sync with redis!
            redis_sync(decryptKey, hashed_email)

        return True, userDB, secret_key

    return False, userDB, None
예제 #18
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)
예제 #19
0
def login():
    if request.method == 'POST':
        # find the user in database by username entered
        returning_user = mongo.db.usersDB.find_one(
            {'username': request.form['inputName']})
        if returning_user is not None:
            saltUsed = returning_user[
                'salt']  # get the salt used for password for this user
            passCheck = returning_user[
                'password']  # get the password hash from database to compare passwords
            # next need to check that password entered corresponds to password that exists in the database for this user
            if generate_password_hash(request.form['inputPassword'],
                                      saltUsed) == passCheck:
                session['currentUser'] = returning_user['username']
                return redirect(url_for('home'))
            return render_template(
                'WrongDetails.html'
            )  # template with message is returned if username doesn't match
        return render_template(
            'WrongDetails.html'
        )  # template with message is returned if password doesn't match

    return render_template('login.html')
예제 #20
0
 def password(self, password):
     self.password_salt = generate_random_salt()
     self.password_hash = generate_password_hash(password,
                                                 self.password_salt)
예제 #21
0
 def set_password(self, password):
     self._set_salt()
     self.password_hash = generate_password_hash(
         password, self.salt.encode()
     ).decode()
예제 #22
0
파일: auth.py 프로젝트: puhlenbruck/CPPA
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
예제 #23
0
def startpage():
    print("3")
    resp1 = make_response()  # Ønsket side for når vi er innlogget
    resp2 = redirect(url_for('index'),
                     code=302)  # Side for når en ikke er innlogget

    session_cookie = get_valid_cookie()
    if session_cookie is not None:
        cookie = Cookies.query.filter_by(session_cookie=session_cookie).first()
        user = User.query.filter_by(user_id=cookie.user_id).first()
        accounts = Account.query.filter_by(user_id=user.user_id).all()

        ac_name = []
        ac_nr = []
        ac_balance = []
        btn = []

        transactions = set()  # Bruker set for å fjerne duplikater

        for account in accounts:
            ac_name.append(account.account_name)
            ac_nr.append(account.account_number)
            btn.append(
                generate_password_hash(account.account_number,
                                       '').decode('utf-8'))
            ac_balance.append(account.balance)

            for transaction in Transaction.query.filter_by(
                    to_acc=account.account_number).all():
                transactions.add(transaction)

            for transaction in Transaction.query.filter_by(
                    from_acc=account.account_number).all():
                transactions.add(transaction)

        transactions_list = []

        for transaction in transactions:
            transactions_list.append(transaction)

        insertion_sort_transactions(
            transactions_list)  # Sorterer transaksjonene, synkende rekkefølge

        transfer_time = []
        From = []
        To = []
        Msg = []
        Inn = []
        Out = []

        for transaction in transactions_list:
            for account in accounts:
                if transaction.to_acc == account.account_number:
                    transfer_time.append(
                        str(
                            datetime.strptime(transaction.transfer_time,
                                              "%Y-%m-%d %H:%M:%S.%f").strftime(
                                                  "%Y-%m-%d, %H:%M:%S")))
                    Msg.append(transaction.message)
                    From.append(transaction.from_acc)
                    To.append(transaction.to_acc)
                    Inn.append(transaction.amount)
                    Out.append("")
                if transaction.from_acc == account.account_number:
                    Inn.append("")
                    Out.append(transaction.amount)
                    transfer_time.append(
                        str(
                            datetime.strptime(transaction.transfer_time,
                                              "%Y-%m-%d %H:%M:%S.%f").strftime(
                                                  "%Y-%m-%d, %H:%M:%S")))
                    Msg.append(transaction.message)
                    From.append(transaction.from_acc)
                    To.append(transaction.to_acc)

        account_num_error = request.args.get('account_num_error')
        account_balance_error = request.args.get('account_balance_error')
        amount_error = request.args.get('amount_error')
        kid_error = request.args.get('kid_error')
        auth_error = request.args.get('auth_error')

        resp1 = make_response(
            render_template("pages/startside.html",
                            len=len(transactions_list),
                            transfer_time=transfer_time,
                            From=From,
                            To=To,
                            Msg=Msg,
                            Inn=Inn,
                            Out=Out,
                            account=accounts[0].account_number,
                            ac_name=ac_name,
                            ac_nr=ac_nr,
                            ac_balance=ac_balance,
                            account_num_error=account_num_error,
                            account_balance_error=account_balance_error,
                            amount_error=amount_error,
                            kid_error=kid_error,
                            auth_error=auth_error,
                            btn=btn))

    try:
        return signed_in(resp1, resp2)
    except jinja2.exceptions.TemplateNotFound:  # Hvis siden/html filen ikke blir funnet
        abort(404)  # Returner feilmelding 404
예제 #24
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))
예제 #25
0
def generate_hash(key):
    """
    Generate hash for key
    """
    phash = generate_password_hash(key, get_settings()['secret'])
    return b64encode(phash)[:10]  # limit len to 10, is sufficient
예제 #26
0
파일: utils.py 프로젝트: jardg/pajbot
def create_pleblist_login(bot_config):
    """ Throws an InvalidLogin exception if the login was not good """
    salted_password = generate_password_hash(bot_config['web']['pleblist_password'], bot_config['web']['pleblist_password_salt'])
    return base64.b64encode(salted_password).decode('utf8')
예제 #27
0
파일: utils.py 프로젝트: uFloppyDisk/pajbot
def create_pleblist_login(bot_config):
    """ Throws an InvalidLogin exception if the login was not good """
    salted_password = generate_password_hash(
        bot_config['web']['pleblist_password'],
        bot_config['web']['pleblist_password_salt'])
    return base64.b64encode(salted_password).decode('utf8')
예제 #28
0
def transaction_overview(page=None):
    print("25")
    resp1 = redirect(url_for('startpage'),
                     code=302)  # Side for når en er innlogget
    resp2 = redirect(url_for('index'),
                     code=302)  # Side for når en ikke er innlogget

    # Les ut variabler
    account_number_hash = request.args.get('cnr')
    session_cookie = get_valid_cookie()

    if session_cookie is not None and contain_allowed_symbols(
            account_number_hash,
            whitelist=string.ascii_letters + string.digits +
            string.punctuation + ' '):
        cookie = Cookies.query.filter_by(session_cookie=session_cookie).first()
        user = User.query.filter_by(user_id=cookie.user_id).first()
        accounts = Account.query.filter_by(user_id=cookie.user_id).all()

        match = False
        for account in accounts:
            actuall_hash = generate_password_hash(account.account_number,
                                                  '').decode('utf-8').replace(
                                                      '+', ' ')
            if account_number_hash == actuall_hash:
                match = True
                break

        # Sjekker om dette er brukeren sin konto
        if account is not None and user is not None and account.user_id == user.user_id and match:

            transactions = Transaction.query.filter_by(
                to_acc=account.account_number).all(
                ) + Transaction.query.filter_by(
                    from_acc=account.account_number).all()

            transfer_time = []
            From = []
            To = []
            Msg = []
            Inn = []
            Out = []

            insertion_sort_transactions(
                transactions)  # Sorterer transaksjonene, synkende rekkefølge

            for transaction in transactions:
                transfer_time.append(
                    str(
                        datetime.strptime(transaction.transfer_time,
                                          "%Y-%m-%d %H:%M:%S.%f").strftime(
                                              "%Y-%m-%d, %H:%M:%S")))
                Msg.append(transaction.message)
                From.append(transaction.from_acc)
                To.append(transaction.to_acc)

                if transaction.to_acc == account.account_number:
                    Inn.append(transaction.amount)
                    Out.append("")

                if transaction.from_acc == account.account_number:
                    Inn.append("")
                    Out.append(transaction.amount)

            resp1 = make_response(
                render_template("pages/transaction_view.html",
                                len=len(transactions),
                                transfer_time=transfer_time,
                                From=From,
                                To=To,
                                Msg=Msg,
                                Inn=Inn,
                                Out=Out,
                                account=account.account_number,
                                name=account.account_name))
    try:
        return signed_in(resp1, resp2)
    except jinja2.exceptions.TemplateNotFound:  # Hvis siden/html filen ikke blir funnet
        abort(404)  # Returner feilmelding 404
예제 #29
0
파일: utils.py 프로젝트: sadlyfell/bullbot
def create_pleblist_login(bot_config):
    """ Throws an InvalidLogin exception if the login was not good """
    salted_password = generate_password_hash(
        bot_config["web"]["pleblist_password"],
        bot_config["web"]["pleblist_password_salt"])
    return base64.b64encode(salted_password).decode("utf8")
예제 #30
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)
예제 #31
0
 def validate_email(self, email):
     hashed_email = flask_scrypt.generate_password_hash(email.data, "")
     email = User.query.filter_by(email=hashed_email).first()
     if email:
         raise ValidationError("Couldn't continue, due to an error")
예제 #32
0
 def test_check_password_correct_with_none_default_params(self):
     password = '******'
     salt = self.salt
     password_hash = generate_password_hash(password, salt, r=10)
     self.assertTrue(check_password_hash(password, password_hash, salt, r=10))
예제 #33
0
 def is_correct_password(self, password):
     salt = self.salt
     password = str(generate_password_hash(password, salt), 'utf-8')
     if password == self._password:
         return True
     return False
예제 #34
0
 def setUp(self):
     self.salt = generate_random_salt()
     self.password = '******'
     self.password_hash = generate_password_hash(self.password, self.salt)
예제 #35
0
 def is_correct_password(self, password):
     salt = self.salt
     password = str(generate_password_hash(password, salt), 'utf-8')
     if password == self._password:
         return True
     return False
예제 #36
0
 def test_check_password_correct(self):
     password = '******'
     salt = self.salt
     password_hash = generate_password_hash(password, salt)
     self.assertTrue(check_password_hash(password, password_hash, salt))
예제 #37
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
예제 #38
0
 def set_password(self, ptext):
     self.passsalt = flask_scrypt.generate_random_salt()
     self.passhash = flask_scrypt.generate_password_hash(
       ptext,
       self.passsalt)