-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
218 lines (181 loc) · 8.17 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
from cs50 import SQL #TODO: Remove, use other SQL tool
from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from functools import wraps
import rsa
from werkzeug.security import check_password_hash, generate_password_hash
from cryptography.fernet import Fernet
# Configure application
app = Flask(__name__)
# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True
# Configure CS50 Library to use SQLite database
db = SQL("sqlite:///passwords.db") #Ändra
# Configure session
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#publicKey, privateKey = rsa.newkeys(2048)
#key = Fernet.generate_key()
#fernet = Fernet(key)
# Define login_required
def login_required(f):
"""
Decorate routes to require login.
http://flask.pocoo.org/docs/0.12/patterns/viewdecorators/
"""
@wraps(f)
def decorated_function(*args, **kwargs):
if session.get("user_id") is None:
return redirect("/login")
return f(*args, **kwargs)
return decorated_function
@app.route("/")
@login_required
def index():
# Get username
name = db.execute("SELECT username FROM users WHERE id = ?",
session["user_id"])[0]['username']
# Get passwords
passwords = db.execute("SELECT website, username, password FROM passwords WHERE id = ?", session["user_id"])
if len(passwords) == 0:
return render_template("index.html")
return render_template("index.html", username=name, passwords=passwords)#, decrypted=decrypted) #TODO: Handle Decryption
@app.route("/create", methods = ["GET", "POST"])
@login_required
def create():
if request.method == "GET":
return render_template("create.html")
else:
# If website was not submitted
if not request.form.get("website"):
return render_template("create.html", errorText = "Need to enter website")
# If username not submitted
if not request.form.get("username"):
return render_template("create.html", errorText = "Need to enter username")
# If username not submitted
elif not request.form.get("password"):
return render_template("create.html", errorText = "Need to enter password")
if 0 != len(db.execute("SELECT * FROM passwords WHERE website = ? AND id = ?", request.form.get("website"), session["user_id"])):
return render_template("create.html", errorText = "Password for this website already registered")
#TODO: Time
# Insert new password to
db.execute("INSERT INTO passwords (id, username, website, password)VALUES (?, ?, ?, ?)",
session["user_id"],
request.form.get("username"),
request.form.get("website"),
request.form.get("password")
#rsa.encrypt(request.form.get("password").encode(), publicKey)
#fernet.encrypt(request.form.get("password").encode())
)
return redirect("/")
@app.route("/change", methods = ["GET", "POST"])
@login_required
def change():
if request.method == "GET":
return redirect("/")
else:
# Check if value is correct
if len(db.execute("SELECT * FROM passwords WHERE website = ? AND id = ?", request.form["change_button"], session["user_id"])) != 1:
return redirect("/")
return render_template("change.html", website=request.form["change_button"])
@app.route("/changed", methods = ["GET", "POST"])
@login_required
def changed():
if request.method == "GET":
return redirect("/")
else:
# If website was not submitted
if not request.form.get("website"):
return render_template("create.html", errorText = "Need to enter website")
# If username not submitted
if not request.form.get("username"):
return render_template("create.html", errorText = "Need to enter username")
# If username not submitted
elif not request.form.get("password"):
return render_template("create.html", errorText = "Need to enter password")
# Make sure it exists
if len(db.execute("SELECT * FROM passwords WHERE website = ? AND id = ?", request.form.get("website"), session["user_id"])) != 1:
return render_template("create.html", errorText = "Incorrect") #TODO: Handle correct
# Change
db.execute("UPDATE passwords SET username = ?, password = ? WHERE website = ? AND id = ?",
request.form.get("username"),
request.form.get("password"), #TODO: Encrypt
#rsa.encrypt(request.form.get("password").encode(), publicKey),
#fernet.encrypt(request.form.get("password").encode()),
request.form.get("website"),
session['user_id'])
return redirect("/")
#@app.route("/decrypt", methods = ["GET", "POST"])
#@login_required
#def decrypt():
#if request.method == "GET":
#return redirect("/")
#else:
#return render_template("index.html",)
@app.route("/login", methods = ["GET", "POST"])
def login():
session.clear()
if request.method == "GET":
return render_template("login.html")
else:
# If username not submitted
if not request.form.get("username"):
return render_template("login.html", errorText = "Need to enter username")
# If username not submitted
elif not request.form.get("password"):
return render_template("login.html", errorText = "Need to enter password")
# Get user details
users = db.execute(
"SELECT * FROM users WHERE username = ?",
request.form.get("username")
)
# Check if user exists and password is correct
if len(users) != 1 or not check_password_hash(users[0]["password"], request.form.get("password")):
return render_template("login.html", errorText="invalid username and/or password")
# Start session for user
session["user_id"] = users[0]["id"]
return redirect("/")
@app.route("/logout")
def logout():
session["user_id"] = None
return redirect("/login")
@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "GET":
return render_template("register.html")
else:
# If not username is submitted
if not request.form.get("username"):
return render_template("register.html", errorText = "Need to enter username")
# If not password was submitted
elif not request.form.get("password"):
return render_template("register.html", errorText = "Need to enter password")
# If password was not submitted
elif not request.form.get("password2"):
return render_template("register.html", errorText = "Need to enter password confirmation")
# If any credentials are too long
elif ( len(request.form.get("password")) > 20 or len(request.form.get("username")) > 15 ):
return render_template("register.html", errorText = "Password or Username is too long.")
# Ensure the password and confirmation is the same
elif request.form.get("password") != request.form.get("password2"):
return render_template("register.html", errorText = "The passwords are not identical")
# Ensure the username is unique
elif (
len(db.execute("SELECT * FROM users WHERE username = ?",
request.form.get("username"),)) > 0 ):
return render_template("register.html", errorText = "Username already taken, choose another")
# Save user to the database
db.execute("INSERT INTO users (username, password)VALUES (?, ?)",
request.form.get("username"),
#hash
#argon2.hash_password(bytes(request.form.get("password"),"utf-8")),)
generate_password_hash(request.form.get("password")))
# Get the users credentials
rows = db.execute(
"SELECT * FROM users WHERE username = ?", request.form.get("username")
)
# Remember which user has logged in
session["user_id"] = rows[0]["id"]
# Redirect user to home page
return redirect("/")