Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions backend/airweave/api/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,9 @@ async def _authenticate_auth0_user(
logger.error(f"User {auth0_user.email} not found in database")
return None, AuthMethod.AUTH0, {}

# Update last active timestamp using CRUD module
user = await crud.user.update(
db=db,
db_obj=user,
obj_in={"last_active_at": datetime.utcnow()},
current_user=user, # User updating their own record
)
# Update last active timestamp directly (can't use CRUD during auth flow)
user.last_active_at = datetime.utcnow()
user = await crud.user.update_user_no_auth(db, id=user.id, obj_in=user)
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing the ORM user into update_user_no_auth will crash this auth path because the method expects a UserUpdate schema and calls model_dump() on it; authentication will fail here.

Prompt for AI agents
Address the following comment on backend/airweave/api/deps.py at line 55:

<comment>Passing the ORM user into update_user_no_auth will crash this auth path because the method expects a UserUpdate schema and calls model_dump() on it; authentication will fail here.</comment>

<file context>
@@ -50,13 +50,9 @@ async def _authenticate_auth0_user(
-    )
+    # Update last active timestamp directly (can&#39;t use CRUD during auth flow)
+    user.last_active_at = datetime.utcnow()
+    user = await crud.user.update_user_no_auth(db, id=user.id, obj_in=user)
 
     user_context = schemas.User.model_validate(user)
</file context>
Suggested change
user = await crud.user.update_user_no_auth(db, id=user.id, obj_in=user)
user = await crud.user.update_user_no_auth(db, id=user.id, obj_in=schemas.UserUpdate(last_active_at=user.last_active_at))
Fix with Cubic


user_context = schemas.User.model_validate(user)
return user_context, AuthMethod.AUTH0, {"auth0_id": auth0_user.id}
Expand Down
23 changes: 23 additions & 0 deletions backend/airweave/crud/crud_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ async def get_by_email(self, db: AsyncSession, *, email: str) -> Optional[User]:
raise NotFoundException(f"User with email {email} not found")
return db_obj

async def update_user_no_auth(self, db: AsyncSession, *, id: UUID, obj_in: UserUpdate) -> User:
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule violated: Check for Cursor Rules Drift

Documenting this unauthenticated update path is required: the new update_user_no_auth method bypasses the CRUD invariant that every operation requires an ApiContext, so .cursor/rules/crud-layer.mdc must be updated to describe this exception to keep Cursor guidance accurate.

Prompt for AI agents
Address the following comment on backend/airweave/crud/crud_user.py at line 54:

<comment>Documenting this unauthenticated update path is required: the new `update_user_no_auth` method bypasses the CRUD invariant that every operation requires an ApiContext, so `.cursor/rules/crud-layer.mdc` must be updated to describe this exception to keep Cursor guidance accurate.</comment>

<file context>
@@ -51,6 +51,29 @@ async def get_by_email(self, db: AsyncSession, *, email: str) -&gt; Optional[User]:
             raise NotFoundException(f&quot;User with email {email} not found&quot;)
         return db_obj
 
+    async def update_user_no_auth(self, db: AsyncSession, *, id: UUID, obj_in: UserUpdate) -&gt; User:
+        &quot;&quot;&quot;Update a user without authentication.
+
</file context>
Fix with Cubic

"""Update a user without authentication.

Important: this method is not part of the regular CRUD operations.
This is a custom method for updating a user, that does not
require a current user. Use responsibly.

Args:
db (AsyncSession): The database session.
id (UUID): The UUID of the user to update.
obj_in (UserUpdate): The updated user object.
"""
user = await self.get(db, id=id)
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling self.get here omits the required current_user argument, so update_user_no_auth will raise a TypeError and never reach the commit/refresh.

Prompt for AI agents
Address the following comment on backend/airweave/crud/crud_user.py at line 66:

<comment>Calling self.get here omits the required current_user argument, so update_user_no_auth will raise a TypeError and never reach the commit/refresh.</comment>

<file context>
@@ -51,6 +51,29 @@ async def get_by_email(self, db: AsyncSession, *, email: str) -&gt; Optional[User]:
+            id (UUID): The UUID of the user to update.
+            obj_in (UserUpdate): The updated user object.
+        &quot;&quot;&quot;
+        user = await self.get(db, id=id)
+        if not user:
+            raise NotFoundException(f&quot;User with ID {id} not found&quot;)
</file context>
Fix with Cubic

if not user:
raise NotFoundException(f"User with ID {id} not found")

for field, value in obj_in.model_dump(exclude_unset=True).items():
setattr(user, field, value)

await db.commit()
await db.refresh(user)
return user

async def get(self, db: AsyncSession, id: UUID, current_user: User) -> Optional[User]:
"""Get a single object by ID.

Expand Down
Loading