Myfe - 21/03/22
Tags: mongodb, python, github, gamedev
Published: 2022-03-22 17:10:54

So the day after I thought of the idea, I got to work.

## Starting

First I made a [repl](https://replit.com/@VulcanWM/myfe) as that’s where I’m going to code everything.
Then I make a MongoDB database so I could work on saving data. 
After that I made a [repo](https://github.com/VulcanWM/myfe) so I could track my code process.

---

## Format

Then I made a few files and folders:
- `main.py`
- `app.py`
- `functions.py`
- `templates/login.html`
- `templates/signup.html`

---

## Code

Then I started with the code.
I copied most of the code from other projects I’ve made with login and signup.

### `templates/login.html`

```html
<!DOCTYPE html>
<html lang="en-GB">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Myfe - Login</title>
  </head>
  <body>
    <h1>Myfe - Login</h1>
    {% if error != False and error != None and error != "" %}
      <p>{{error}}</p>
    {% endif %}
    <form method="POST" action="/login">
      <input placeholder="username" name="username" autocomplete="off" required><br>
      <input type="password" placeholder="password" name="password" autocomplete="off" required><br>
      <button class="login-form-button">submit</button>
    </form>
  </body>
</html>
```

### `templates/signup.html`

```html
 <!DOCTYPE html>
<html lang="en-GB">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Myfe - Signup</title>
  </head>
  <body>
    <h1>Myfe - Signup</h1>
    {% if error != False and error != None and error != "" %}
      <p>{{error}}</p>
    {% endif %}
    <form method="POST" action="/signup">
      <input placeholder="username" name="username" autocomplete="off" required><br>
      <input type="password" placeholder="password" name="password" autocomplete="off" required><br>
      <input type="password" placeholder="password again" name="passwordagain" autocomplete="off" required><br>
      <button class="login-form-button">submit</button>
    </form>
  </body>
</html>
```

### `functions.py`

```py
import pymongo
import os
from werkzeug.security import generate_password_hash, check_password_hash
from flask import session
import datetime
from string import printable
from html import escape as esc
import dns

clientm = pymongo.MongoClient(os.getenv("clientm"))
usersdb = clientm.Users
profilescol = usersdb.Profiles

def addcookie(key, value):
  session[key] = value

def delcookies():
  session.clear()

def getcookie(key):
  try:
    if (x := session.get(key)):
      return x
    else:
      return False
  except:
    return False

def makeaccount(username, password, passwordagain):
  if len(username) > 25:
    return "Your username cannot have more than 25 letters!"
  if len(username) < 2:
    return "You have to have more than 2 letters in your username!"
  if set(username).difference(printable) or esc(username) != username:
    return "Your username cannot contain any special characters!"
  if username != username.lower():
    return "Your username has to be all lowercase!"
  if checkusernamealready(username) == True:
    return "A user already has this username! Try another one."
  if password != passwordagain:
    return "The two passwords don't match!"
  if len(password) > 25:
    return "Your password cannot have more than 25 letters!"
  if len(password) < 2:
    return "You have to have more than 2 letters in your password!"
  if set(password).difference(printable):
    return "Your password cannot contain any special characters!"
  passhash = generate_password_hash(password)
  document = [{
    "Username": username,
    "Password": passhash,
    "Created": str(datetime.datetime.now()),
    "Money": 100,
    "XP": 0
  }]
  profilescol.insert_many(document)
  return True

def gethashpass(username):
  myquery = { "Username": username }
  mydoc = profilescol.find(myquery)
  for x in mydoc:
    return x['Password']
  return False

def getuserid(id):
  myquery = { "_id": int(id) }
  mydoc = profilescol.find(myquery)
  for x in mydoc:
    return True
  return False

def getuser(username):
  myquery = { "Username": username }
  mydoc = profilescol.find(myquery)
  for x in mydoc:
    if x.get("Deleted", None) == None:
      return x
    return False
  return False

def checkusernamealready(username):
  myquery = { "Username": username }
  mydoc = profilescol.find(myquery)
  for x in mydoc:
    return True
  return False
```

### `app.py`

```py
from flask import Flask, render_template, request, redirect
from functions import getcookie, addcookie, makeaccount, delcookies, getuser, gethashpass
from werkzeug.security import check_password_hash
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv("SECRET_KEY")

@app.route('/')
def index():
  if getcookie("User") == False:
    return 'Hello Myfe world!'
  else:
    return f'Hello {getcookie("User")}'

@app.route("/signup")
def signuppage():
  if getcookie("User") == False:
    return render_template("signup.html")
  else:
    return redirect("/")
  
@app.route("/signup", methods=['POST', 'GET'])
def signupfunc():
  if request.method == 'POST':
    if getcookie("User") != False:
      return redirect("/")
    username = request.form['username']
    password = request.form['password']
    passwordagain = request.form['passwordagain']
    func = makeaccount(username, password, passwordagain)
    if func == True:
      addcookie("User", username)
      return redirect("/")
    else:
      return render_template("signup.html", error=func)

@app.route("/logout")
def logout():
  delcookies()
  return redirect("/")

@app.route("/login")
def loginpage():
  if getcookie("User") == False:
    return render_template("login.html")
  else:
    return redirect("/")

@app.route("/login", methods=['POST', 'GET'])
def loginfunc():
  if request.method == 'POST':
    if getcookie("User") != False:
      return render_template("login.html", error="You have already logged in!")
    username = request.form['username']
    if getuser(username) == False:
      return render_template("login.html", error="That is not a username!")
    password = request.form['password']
    if check_password_hash(gethashpass(username), password) == False:
      return render_template("login.html", error="Wrong password!")
    addcookie("User", username)
    return redirect("/")
  else:
    return redirect("/")
```

### `main.py`

```py
from app import app

app.run(host='0.0.0.0', port=8080)
```

---

## How it turned out

After writing the code, I tested it out [here](https://myfe.vulcanwm.repl.co/) and saw that it had a fully functioning login and signup page!

Next I'll be working on a profile page, so if you want to see how that turns out, make sure to follow me!