lingthio / Flask-User

Customizable User Authorization & User Management: Register, Confirm, Login, Change username/password, Forgot password and more.
http://flask-user.readthedocs.io/
MIT License
1.06k stars 294 forks source link

Not possible to create custom adapter. #277

Open molitoris opened 4 years ago

molitoris commented 4 years ago

I would like to use MongoEngine instead of Flask_MongoEngine since the second seems unsupported.

The documentation explained how to create a custom db_adapter. It my case, it should look like this:

import mongoengine
from flask_user.db_adapters import MongoDbAdapter

class MyMongoAdapter(MongoDbAdapter):

    def __init__(self, app, db):
        super(MyMongoAdapter, self).__init__(app, db)

app = Flask(__name__)

mongoengine.connect()
db = mongoengine.get_db()

# User is an instance of mongoengine.Document
user_manager = UserManager(app, db.get_db(), User) # raises ConfigError
user_manager.db_manager.db_adapter = MyMongoAdapter(app, db.get_db())

Unfortunately, I could not find a way how to add my own adapter. I think the problem is in UserManager. In the constructor of UserManager an instance of DbManager is created. The constructor of DbManager compares the passed database argument against the supported databases. In case it is not one of the supported databases, it throws an error. The error prevents the constructor of UserManager to complete.

Solution

I think one could overcome this by adding an optional attribute custom_db_adapter to the constructor of DbManager. After checking if the adapter is an instance of db_adapter_interface, the custom_db_adapter is passed to adpater.

Let me know and I will implement it and add a PR.

PS: Flask-User is an amazing library. All the adapters make a lot of sense and the documentation makes it very clear.

Chaostheorie commented 4 years ago

Please use the answer by @michaelbukachi cause mine was deprecated.

michaelbukachi commented 4 years ago

You could implement the adapter in the libary or create a custom db adapter. Example Custom DB Adapter:

# Define a CustomDbAdapter
from flask_user.db_adapters import DbAdapterInterface
class CustomDbAdapter(DbAdapterInterface):
    ...

# Setup Flask-User
user_manager = UserManager(app, db, User)

# Customize Flask-User
user_manager.db_adapter = CustomDbAdapter(app)

I've gone through the source code and the db_adapter is not used anywhere in UserManager. This is the workaround I had to use:

 user_manager.init_app(app, db, User)
 db_manager = DBManager(app, db, User)
 db_manager.db_adapter = CustomDbAdapter(app, db)
 user_manager.db_manager = db_manager