Skip to content

Commit

Permalink
Cosmos-DB compatability (#25)
Browse files Browse the repository at this point in the history
Cosmos-DB compatability (#25)

Azure Cosmos DB for MongoDB neither supports creating unique index on non-empty collections nor collation, which leads to exceptions in fastapi-users.

Introduce a setting COSMOSDB_COMPAT which, when set, replaces MongoDBUserDatabase with a subclass with the incompatible function calls patched out:

    only set indexes if they do not exist on the collection (so they are set only once, before documents are inserted)
    do not use collation when storing/querying the email field

Skipping the collation means that email addressess (usernames) are not case-insensitive anymore - i.e. my@user.de and My@user.de are treated as different accounts.
  • Loading branch information
jthurner authored Jun 30, 2023
1 parent fab1546 commit f40324e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
23 changes: 22 additions & 1 deletion pandahub/api/internal/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,29 @@


async def get_user_db():
yield MongoDBUserDatabase(UserDB, collection)
if settings.COSMOSDB_COMPAT:
yield MongoDBUserDatabaseCosmos(UserDB, collection)
else:
yield MongoDBUserDatabase(UserDB, collection)


async def get_access_token_db():
yield MongoDBAccessTokenDatabase(AccessToken, access_tokens_collection)

class MongoDBUserDatabaseCosmos(MongoDBUserDatabase):
from typing import Optional
from fastapi_users.models import UD
async def get_by_email(self, email: str) -> Optional[UD]:
await self._initialize()

user = await self.collection.find_one(
{"email": email}
)
return self.user_db_model(**user) if user else None

async def _initialize(self):
if not self.initialized:
if "email_1" not in await self.collection.index_information():
await self.collection.create_index("id", unique=True)
await self.collection.create_index("email", unique=True)
self.initialized = True
1 change: 1 addition & 0 deletions pandahub/api/internal/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ def get_secret(key, default=None):
REGISTRATION_ADMIN_APPROVAL = settings_bool("REGISTRATION_ADMIN_APPROVAL", default=False)

DATATYPES_MODULE = os.getenv("DATATYPES_MODULE") or "pandahub.lib.datatypes"
COSMOSDB_COMPAT = settings_bool("COSMOSDB_COMPAT", default=False)

0 comments on commit f40324e

Please sign in to comment.