You've already forked flask-mongo-api-boilerplate
mirror of
https://github.com/LukePeters/flask-mongo-api-boilerplate.git
synced 2026-05-06 02:11:18 +09:00
152 lines
4.5 KiB
Python
152 lines
4.5 KiB
Python
from flask import current_app as app
|
|
from flask import Flask, request
|
|
from passlib.hash import pbkdf2_sha256
|
|
from jose import jwt
|
|
from main import tools
|
|
from main import auth
|
|
import json
|
|
|
|
class User:
|
|
|
|
def __init__(self):
|
|
self.defaults = {
|
|
"id": tools.randID(),
|
|
"ip_addresses": [request.remote_addr],
|
|
"acct_active": True,
|
|
"date_created": tools.nowEpoch(),
|
|
"last_login": tools.nowEpoch(),
|
|
"first_name": "",
|
|
"last_name": "",
|
|
"email": "",
|
|
"plan": "free"
|
|
}
|
|
|
|
def get(self):
|
|
token_data = jwt.decode(request.headers.get('AccessToken'), app.config['SECRET_KEY'])
|
|
|
|
user = app.db.users.find_one({ "id": token_data['user_id'] }, {
|
|
"_id": 0,
|
|
"password": 0
|
|
})
|
|
|
|
if user:
|
|
resp = tools.JsonResp(user, 200)
|
|
else:
|
|
resp = tools.JsonResp({ "message": "User not found" }, 404)
|
|
|
|
return resp
|
|
|
|
def getAuth(self):
|
|
access_token = request.headers.get("AccessToken")
|
|
refresh_token = request.headers.get("RefreshToken")
|
|
|
|
resp = tools.JsonResp({ "message": "User not logged in" }, 401)
|
|
|
|
if access_token:
|
|
try:
|
|
decoded = jwt.decode(access_token, app.config["SECRET_KEY"])
|
|
resp = tools.JsonResp(decoded, 200)
|
|
except:
|
|
# If the access_token has expired, get a new access_token - so long as the refresh_token hasn't expired yet
|
|
resp = auth.refreshAccessToken(refresh_token)
|
|
|
|
return resp
|
|
|
|
def login(self):
|
|
resp = tools.JsonResp({ "message": "Invalid user credentials" }, 403)
|
|
|
|
try:
|
|
data = json.loads(request.data)
|
|
email = data["email"].lower()
|
|
user = app.db.users.find_one({ "email": email }, { "_id": 0 })
|
|
|
|
if user and pbkdf2_sha256.verify(data["password"], user["password"]):
|
|
access_token = auth.encodeAccessToken(user["id"], user["email"], user["plan"])
|
|
refresh_token = auth.encodeRefreshToken(user["id"], user["email"], user["plan"])
|
|
|
|
app.db.users.update({ "id": user["id"] }, { "$set": {
|
|
"refresh_token": refresh_token,
|
|
"last_login": tools.nowEpoch()
|
|
} })
|
|
|
|
resp = tools.JsonResp({
|
|
"id": user["id"],
|
|
"email": user["email"],
|
|
"first_name": user["first_name"],
|
|
"last_name": user["last_name"],
|
|
"plan": user["plan"],
|
|
"access_token": access_token,
|
|
"refresh_token": refresh_token
|
|
}, 200)
|
|
|
|
except Exception:
|
|
pass
|
|
|
|
return resp
|
|
|
|
def logout(self):
|
|
try:
|
|
tokenData = jwt.decode(request.headers.get("AccessToken"), app.config["SECRET_KEY"])
|
|
app.db.users.update({ "id": tokenData["user_id"] }, { '$unset': { "refresh_token": "" } })
|
|
# Note: At some point I need to implement Token Revoking/Blacklisting
|
|
# General info here: https://flask-jwt-extended.readthedocs.io/en/latest/blacklist_and_token_revoking.html
|
|
except:
|
|
pass
|
|
|
|
resp = tools.JsonResp({ "message": "User logged out" }, 200)
|
|
|
|
return resp
|
|
|
|
def add(self):
|
|
data = json.loads(request.data)
|
|
|
|
expected_data = {
|
|
"first_name": data['first_name'],
|
|
"last_name": data['last_name'],
|
|
"email": data['email'].lower(),
|
|
"password": data['password']
|
|
}
|
|
|
|
# Merge the posted data with the default user attributes
|
|
self.defaults.update(expected_data)
|
|
user = self.defaults
|
|
|
|
# Encrypt the password
|
|
user["password"] = pbkdf2_sha256.encrypt(user["password"], rounds=20000, salt_size=16)
|
|
|
|
# Make sure there isn"t already a user with this email address
|
|
existing_email = app.db.users.find_one({ "email": user["email"] })
|
|
|
|
if existing_email:
|
|
resp = tools.JsonResp({
|
|
"message": "There's already an account with this email address",
|
|
"error": "email_exists"
|
|
}, 400)
|
|
|
|
else:
|
|
if app.db.users.save(user):
|
|
|
|
# Log the user in (create and return tokens)
|
|
access_token = auth.encodeAccessToken(user["id"], user["email"], user["plan"])
|
|
refresh_token = auth.encodeRefreshToken(user["id"], user["email"], user["plan"])
|
|
|
|
app.db.users.update({ "id": user["id"] }, {
|
|
"$set": {
|
|
"refresh_token": refresh_token
|
|
}
|
|
})
|
|
|
|
resp = tools.JsonResp({
|
|
"id": user["id"],
|
|
"email": user["email"],
|
|
"first_name": user["first_name"],
|
|
"last_name": user["last_name"],
|
|
"plan": user["plan"],
|
|
"access_token": access_token,
|
|
"refresh_token": refresh_token
|
|
}, 200)
|
|
|
|
else:
|
|
resp = tools.JsonResp({ "message": "User could not be added" }, 400)
|
|
|
|
return resp |