Nits, niceties, randomized secret

This commit is contained in:
zoffline
2020-11-08 13:43:49 -05:00
parent 1100580ce2
commit 7f37ccfe83
4 changed files with 38 additions and 33 deletions

View File

@@ -24,6 +24,12 @@
<input type="password" id="password" name="password" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label>Confirm Password</label>
<input type="password" id="confirm_password" name="confirm_password" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-4">
<label>First name</label>

View File

@@ -19,8 +19,6 @@
<a href="{{ url_for('logout', username=username) }}" class="btn btn-outline-secondary">Logout</a>
</div>
</div>
{% else %}
<a href="{{ url_for('upload', username=username) }}" class="btn btn-outline-success">Upload</a>
{% endif %}
<form method="POST" action="/start-zwift">
<div class="row">

View File

@@ -298,11 +298,14 @@ class UDPHandler(socketserver.BaseRequestHandler):
data = self.request[0]
socket = self.request[1]
recv = udp_node_msgs_pb2.ClientToServer()
try:
recv.ParseFromString(data[:-4])
except:
recv.ParseFromString(data[3:-4])
try:
recv.ParseFromString(data[3:-4])
except:
return
client_address = self.client_address
player_id = recv.player_id

View File

@@ -76,6 +76,7 @@ DATABASE_CUR_VER = 2
# For auth server
AUTOLAUNCH_FILE = "%s/auto_launch.txt" % STORAGE_DIR
SERVER_IP_FILE = "%s/server-ip.txt" % STORAGE_DIR
SECRET_KEY_FILE = "%s/secret-key.txt" % STORAGE_DIR
MULTIPLAYER = False
if os.path.exists("%s/multiplayer.txt" % STORAGE_DIR):
MULTIPLAYER = True
@@ -87,7 +88,11 @@ AUTH_PATH = "%s/auth.db" % STORAGE_DIR
app = Flask(__name__, static_folder='%s/cdn/gameassets' % SCRIPT_DIR, static_url_path='/gameassets', template_folder='%s/cdn/static/web/launcher' % SCRIPT_DIR)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{db}'.format(db=AUTH_PATH)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'zoffline'
if not os.path.exists(SECRET_KEY_FILE):
with open(SECRET_KEY_FILE, 'wb') as f:
f.write(os.urandom(16))
with open(SECRET_KEY_FILE, 'rb') as f:
app.config['SECRET_KEY'] = f.read()
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
db = SQLAlchemy(app)
@@ -240,12 +245,16 @@ def signup():
if request.method == "POST":
username = request.form['username']
password = request.form['password']
confirm_password = request.form['confirm_password']
first_name = request.form['first_name']
last_name = request.form['last_name']
if not (username and password and first_name and last_name):
if not (username and password and confirm_password and first_name and last_name):
flash("All fields are required.")
return redirect(url_for('signup'))
if password != confirm_password:
flash("Passwords did not match.")
return redirect(url_for('signup'))
hashed_pwd = generate_password_hash(password, 'sha256')
@@ -301,7 +310,7 @@ def upload(username):
os.makedirs(profile_dir)
except IOError as e:
logger.error("failed to create profile dir (%s): %s", profile_dir, str(e))
sys.exit(1)
return '', 500
if request.method == 'POST':
uploaded_file = request.files['file']
@@ -327,7 +336,7 @@ def upload(username):
stat = os.stat(token_file)
token = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(stat.st_mtime))
return render_template("upload.html", username=username, profile=profile, name=name, token=token)
return render_template("upload.html", username=current_user.username, profile=profile, name=name, token=token)
@app.route("/logout/<username>")
@@ -514,7 +523,7 @@ def api_profiles_me():
os.makedirs(profile_dir)
except IOError as e:
logger.error("failed to create profile dir (%s): %s", profile_dir, str(e))
sys.exit(1)
return '', 500
profile = profile_pb2.Profile()
profile_file = '%s/profile.bin' % profile_dir
if not os.path.isfile(profile_file):
@@ -527,6 +536,17 @@ def api_profiles_me():
with open(profile_file, 'rb') as fd:
profile.ParseFromString(fd.read())
if MULTIPLAYER:
# For newly added existing profiles, User's player id likely differs from profile's player id.
# If there's existing data in db for this profile, update it for the newly assigned player id.
# XXX: Users can maliciously abuse this by intentionally uploading a profile with another user's current player id.
# However, without it, anyone "upgrading" to multiplayer mode will lose their existing data.
# TODO: need a warning in README that switching to multiplayer mode and back to single player will lose your existing data.
if profile.id != profile_id:
cur = g.db.cursor()
cur.execute('UPDATE activity SET player_id = ? WHERE player_id = ?', (str(profile_id), str(profile.id)))
cur.execute('UPDATE goal SET player_id = ? WHERE player_id = ?', (str(profile_id), str(profile.id)))
cur.execute('UPDATE segment_result SET player_id = ? WHERE player_id = ?', (str(profile_id), str(profile.id)))
g.db.commit()
profile.id = profile_id
elif current_user.player_id != profile.id:
# Update AnonUser's player_id to match
@@ -1328,28 +1348,6 @@ def static_web_launcher(filename):
return render_template(filename)
def check_columns():
time.sleep(3)
result = db.engine.execute(sqlalchemy.text("PRAGMA table_info(user)"))
should_have_columns = User.metadata.tables['user'].columns
current_columns = list()
for row in result:
current_columns.append(row[1])
for column in should_have_columns:
if not column.name in current_columns:
nulltext = None
if column.nullable:
nulltext = "NULL"
else:
nulltext = "NOT NULL"
defaulttext = None
if column.default == None:
defaulttext = ""
else:
defaulttext = " DEFAULT %s" % column.default.arg
db.engine.execute(sqlalchemy.text("ALTER TABLE user ADD %s %s %s%s;" % (column.name, str(column.type), nulltext, defaulttext)))
def run_standalone(passedOnline, passedGhostsEnabled, passedSaveGhost, passedPlayerUpdateQueue):
global online
global ghostsEnabled
@@ -1363,11 +1361,11 @@ def run_standalone(passedOnline, passedGhostsEnabled, passedSaveGhost, passedPla
login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.session_protection = None
db.create_all(app=app)
db.session.commit()
if not MULTIPLAYER:
login_manager.anonymous_user = AnonUser
login_manager.init_app(app)
db.create_all(app=app)
db.session.commit()
@login_manager.user_loader
def load_user(uid):