def getAccountsList(userDict=None): if current_user.accounts is None and userDict is None: return [['', 'Please open an account', '']] if userDict is None: userDict = redis.get(current_user.email) userDict = json.loads(userDict) i = 0 account_list = [] # Denne fungerer men må ryddes opp i, gjør det om til en funksjon elns. for accountnr in userDict['accounts']: numberUsr = int(accountnr) # Navnet ligger i 0te index [navn,kontonr,secret] name = userDict['accounts'][accountnr][0] # Hent kontobalanse fra accounts database accountDB = Account.query.filter_by(number=numberUsr).first() if accountDB: balance = accountDB.balance account_list.append([name, numberUsr, balance]) else: return None i += 1 return account_list
def is_active(self): # Check if the current_user is logged in if redis.get(self.email): # If so set data to expire 10 minutes from now redis.expire(self.email, 900) # return true return True return False
def is_authenticated(self): # Check if the current_user is logged in if redis.get(self.email): # If so set data to expire 10 minutes from now redis.expire(self.email, 900) # return true to the flask login manager return True return False
def getAccountsList(): # Hent account info fra redis userDict = redis.get(current_user.email) # Konverter til dictionary userDict = json.loads(userDict) try: # Checking if user has any accounts userDict['accounts'] except: # #if the user does not have any accounts return None i = 0 account_list = [] for accountnr in userDict[ 'accounts']: # Denne fungerer men må ryddes opp i, gjør det om til en funksjon elns. # accountnumber is a string so convert back to an int numberUsr = int(accountnr) # Henter første verdi fra accounts listen til accountnummer name = userDict['accounts'][accountnr][0] # Hent kontobalansen fra accounts database accountDB = Account.query.filter_by(number=numberUsr).first() # dersom verdien eksisterer if accountDB: balance = accountDB.balance # Formater info og legg dette i en liste account_list.append([name, numberUsr, balance]) else: # Dersom vi søker på en konto som ikke ligger i databasen skal vi returnere umiddelbart # Hvordan fikk brukeren denne i listen sin # TODO Vurder om det skal logges # Kontoen ligger ikke i kontodatabasen return None i += 1 return account_list
def QueryToList(query, accountList, currentAccount): user_dict = json.loads(redis.get(current_user.email)) listTrans = [] for i in query: if i.accountFrom in str(accountList): name = user_dict['accounts'][i.accountFrom][0] accountFrom = f'{name} ( {format_account_number(i.accountFrom)} )' else: accountFrom = i.accountFrom if i.accountTo in str(accountList): name = user_dict['accounts'][i.accountTo][0] accountTo = f'{name} ( {format_account_number(i.accountTo)} )' else: accountTo = i.accountTo amount = format_account_balance(i.amount) in_ = "──" out = "──" if str(i.accountFrom) == str(currentAccount): out = amount in_ = "──" if str(i.accountTo) == str(currentAccount): out = "──" in_ = amount message = i.message time = str(i.time)[:-7] listTrans.append([accountFrom, accountTo, message, in_, out, time]) return listTrans
def getCurUsersEmail(): user_dict = json.loads(redis.get(current_user.email)) return user_dict['email']
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