user_id=new_user.user_id, location_string="Timbuktu", active=True, date_time=datetime.datetime.now() ) models.db.session.add(new_location) new_location2 = models.Location( user_id=new_user.user_id, location_string="Stanford", active=True, date_time=datetime.datetime.now() - datetime.timedelta(500), ) models.db.session.add(new_location2) new_location3 = models.Location( user_id=new_user.user_id, location_string="Secret Location", active=False, date_time=datetime.datetime.now() - datetime.timedelta(50), ) models.db.session.add(new_location3) models.db.session.commit() print(new_user.user_id) models.db.create_all() jwt = JWT(app=None, authentication_handler=authenticate, identity_handler=identity) jwt.app = app jwt.auth_request_callback = jwt_handlers.auth_request_handler jwt.jwt_encode_callback = jwt_handlers.encode_handler jwt.jwt_payload_callback = jwt_handlers.payload_handler jwt.auth_response_callback = jwt_handlers.auth_response_handler jwt.init_app(jwt.app)
class Auth(object): def __init__(self, app=None): self.app = app if app: self.init_app(app) def init_app(self, app): app.config['SECRET_KEY'] = 'super-secret' app.config['JWT_AUTH_URL_RULE'] = '/login' app.config['JWT_EXPIRATION_DELTA'] = timedelta(days=30) # Register callbacks self.jwt = JWT(app, self.authenticate, self.identity) if not hasattr(app, 'extensions'): # pragma: no cover app.extensions = {} app.extensions['auth'] = self global auth with app.app_context(): app.register_blueprint(auth) def create_user(self, username, password): # Hash password conn = rethink_conn.conn() hashed_pass = bcrypt.hashpw(password, bcrypt.gensalt(8)) user = {} user['email'] = username user['password'] = hashed_pass created = r.table("users").insert(user).run(conn) assert created['inserted'] == 1 # Generate token user_id = created['generated_keys'][0] user = User(user_id, username, hashed_pass) return self.jwt.jwt_encode_callback(user) def login(self, username, password): user = self.authenticate(username, password) return self.jwt.jwt_encode_callback(user) def authenticate(self, username, password): conn = rethink_conn.conn() username, password = username.encode('utf-8'), password.encode('utf-8') cursor = r.table("users").filter(r.row["email"] == username).run(conn) try: user = cursor.next() if not user: return None email = user['email'] hashed_pass = user['password'] if username == email and hashed_pass == bcrypt.hashpw( password.encode('utf-8'), hashed_pass.encode('utf-8')): # return User(id=user['id'], username=email) return User(user['id'], email, hashed_pass) except r.ReqlCursorEmpty: return None def identity(self, payload): conn = rethink_conn.conn() print payload cursor = r.table("users").filter( r.row["id"] == payload['identity']).run(conn) try: user = cursor.next() # return User(id=user['id'], username=user['email']) print user return User(user['id'], user['email'], user["password"]) except r.ReqlCursorEmpty: return None
from flask import jsonify from sqlalchemy.exc import SQLAlchemyError from flask_jwt import JWT from user_api.resources.user import UserResource from user_api import (user_api_app, api, db) from user_api.auth import (generate_jwt_token, generate_jwt_payload, generate_jwt_headers, generate_auth_response, generate_error_response, authenticate, load_identity) api.add_resource(UserResource, "/users", "/users/<int:id>") jwt = JWT(user_api_app, authenticate, load_identity) jwt.jwt_encode_callback = generate_jwt_token jwt.jwt_payload_callback = generate_jwt_payload jwt.jwt_headers_callback = generate_jwt_headers jwt.auth_response_callback = generate_auth_response @jwt.jwt_error_handler def error_handler(e): return generate_error_response(e) @user_api_app.route("/api/healthcheck") def healthcheck(): try: db.engine.execute("SELECT 1;").fetchone() return jsonify({"status": "OK"}) except SQLAlchemyError: return jsonify({"status": "DOWN"})
class BaseTest(TestCase): SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" TESTING = True ENCRYPT_SECRET_KEY = "tests" app: Flask db: SQLAlchemy jwt: JWT token: str def create_app(self): self.app = Flask(__name__) self.app.config['TESTING'] = True self.app.config[ 'SQLALCHEMY_DATABASE_URI'] = self.SQLALCHEMY_DATABASE_URI self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False self.app.config['SECRET_KEY'] = self.ENCRYPT_SECRET_KEY self.app.config['JWT_AUTH_URL_RULE'] = "/api/auth/authenticate" controllers_register.register_controllers(self.app) def authenticate(login: str, password: str): user_service = self.dependency_injector.get(UserService) return authentication_utils.authenticate(login, password, user_service) def identity(payload: dict): user_service = self.dependency_injector.get(UserService) return authentication_utils.identity(payload, user_service) self.db = SQLAlchemy(self.app, session_options={"autoflush": False}) self.jwt = JWT(self.app, authenticate, identity) self.dependency_injector = Injector([AppModule(self.app, self.db)]) FlaskInjector(app=self.app, injector=self.dependency_injector) return self.app def setUp(self): Base.metadata.create_all(self.db.get_engine()) default_user = BaseTest.__get_default_user() self.db.session.add(default_user.user_group) self.db.session.add(default_user) self.initial_load() self.db.session.commit() self.token = "JWT " + self.jwt.jwt_encode_callback( default_user).decode() AuthenticationContext.init_context(default_user) def initial_load(self): # /home/vitor/git/my-home-server/my_home_server//my_home_server/tests/resources/initial_load.sql file_path = BaseTest.get_current_dir( ) + "tests/resources/initial_load.sql" file = open(file_path) for query in file.read().split(";"): if query.strip(): self.db.session.execute(query.strip()) file.close() def tearDown(self): self.db.session.remove() self.db.drop_all() @staticmethod def __get_default_user_group(): user_group = UserGroup() user_group.id = 1 user_group.name = "Default" return user_group @staticmethod def __get_default_user(): user = User() user.id = 1 user.name = "Default" user.login = "******" user.password = PasswordEncryption.encrypt_password("default") user.user_group = BaseTest.__get_default_user_group() return user @staticmethod def get_current_dir(): path = os.getcwd() if "my_home_server/tests" in path: index = path.index("my_home_server/tests") path = path[:index] return path + "/" if path.endswith( "/my_home_server") else path + "/my_home_server/" def get_authentication_header(self) -> dict: return {"Authorization": self.token}
class Auth(object): def __init__(self, app=None): self.app = app if app: self.init_app(app) def init_app(self, app): app.config['SECRET_KEY'] = 'super-secret' app.config['JWT_AUTH_URL_RULE'] = '/login' app.config['JWT_EXPIRATION_DELTA'] = timedelta(days=30) # Register callbacks self.jwt = JWT(app, self.authenticate, self.identity) if not hasattr(app, 'extensions'): # pragma: no cover app.extensions = {} app.extensions['auth'] = self global auth with app.app_context(): app.register_blueprint(auth) def create_user(self, username, password): # Hash password conn = rethink_conn.conn() hashed_pass = bcrypt.hashpw(password, bcrypt.gensalt(8)) user = {} user['email'] = username user['password'] = hashed_pass created = r.table("users").insert(user).run(conn) assert created['inserted'] == 1 # Generate token user_id = created['generated_keys'][0] user = User(user_id, username, hashed_pass) return self.jwt.jwt_encode_callback(user) def login(self, username, password): user = self.authenticate(username, password) return self.jwt.jwt_encode_callback(user) def authenticate(self, username, password): conn = rethink_conn.conn() username, password = username.encode('utf-8'), password.encode('utf-8') cursor = r.table("users").filter(r.row["email"] == username).run(conn) try: user = cursor.next() if not user: return None email = user['email'] hashed_pass = user['password'] if username == email and hashed_pass == bcrypt.hashpw(password.encode('utf-8'), hashed_pass.encode('utf-8')): # return User(id=user['id'], username=email) return User(user['id'], email, hashed_pass) except r.ReqlCursorEmpty: return None def identity(self, payload): conn = rethink_conn.conn() print payload cursor = r.table("users").filter(r.row["id"] == payload['identity']).run(conn) try: user = cursor.next() # return User(id=user['id'], username=user['email']) print user return User(user['id'], user['email'], user["password"]) except r.ReqlCursorEmpty: return None