Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
3 changes: 2 additions & 1 deletion Backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .routes.chat import router as chat_router
from .routes.match import router as match_router
from sqlalchemy.exc import SQLAlchemyError
from .routes.collaboration import router as collaboration_router
import logging
import os
from dotenv import load_dotenv
Expand Down Expand Up @@ -56,7 +57,7 @@ async def lifespan(app: FastAPI):
app.include_router(match_router)
app.include_router(ai.router)
app.include_router(ai.youtube_router)

app.include_router(collaboration_router)

@app.get("/")
async def home():
Expand Down
18 changes: 18 additions & 0 deletions Backend/app/routes/collaboration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import update
from ..db.db import get_db
from ..models.models import Collaboration # Verify this name in models/models.py
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

router = APIRouter(prefix="/collaboration", tags=["Collaboration"])

@router.put("/update-status/{collab_id}")
async def update_collab_status(collab_id: str, status: str, db: AsyncSession = Depends(get_db)):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Missing authentication/authorization — any caller can update any collaboration record

The endpoint has no auth dependency (e.g., get_current_user). An unauthenticated request to PUT /collaboration/update-status/{collab_id} can flip the status of any collaboration row without proving the caller is a party to it. This should also verify the requesting user is creator_1_id or creator_2_id of the target record.

🧰 Tools
🪛 Ruff (0.15.1)

[warning] 10-10: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Backend/app/routes/collaboration.py` at line 10, Add authentication and
authorization to update_collab_status: require the current user via a dependency
(e.g., add Depends(get_current_user) parameter) and after loading the
collaboration record inside update_collab_status verify that current_user.id
matches either collaboration.creator_1_id or collaboration.creator_2_id; if no
match, raise an HTTPException(403). Ensure you import/get_current_user and use
the existing get_db AsyncSession dependency, and return/continue only when the
authorization check passes.

if status not in ["accepted", "denied"]:
raise HTTPException(status_code=400, detail="Invalid status")

# This matches the 'status' column in your sql.txt collaborations table
query = update(Collaboration).where(Collaboration.id == collab_id).values(status=status)
await db.execute(query)
await db.commit()
return {"message": f"Collaboration {status} successfully"}
Comment on lines +23 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Silent no-op when collab_id doesn't exist — returns 200 instead of 404

db.execute(update(...)) succeeds even when zero rows match. The response always reports success. Check result.rowcount and raise a 404 if nothing was updated.

🐛 Proposed fix
     query = update(Collaboration).where(Collaboration.id == collab_id).values(status=status)
-    await db.execute(query)
+    result = await db.execute(query)
     await db.commit()
+    if result.rowcount == 0:
+        raise HTTPException(status_code=404, detail="Collaboration not found")
     return {"message": f"Collaboration {status} successfully"}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
query = update(Collaboration).where(Collaboration.id == collab_id).values(status=status)
await db.execute(query)
await db.commit()
return {"message": f"Collaboration {status} successfully"}
query = update(Collaboration).where(Collaboration.id == collab_id).values(status=status)
result = await db.execute(query)
await db.commit()
if result.rowcount == 0:
raise HTTPException(status_code=404, detail="Collaboration not found")
return {"message": f"Collaboration {status} successfully"}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Backend/app/routes/collaboration.py` around lines 15 - 18, The handler
currently calls db.execute(update(Collaboration)... ) and always returns
success; change it to capture the execution result (e.g., result = await
db.execute(query)), check result.rowcount, and if rowcount == 0 raise an
HTTPException(status_code=404, detail=f"Collaboration {collab_id} not found");
only call await db.commit() and return the success message when rowcount > 0.
Make sure to import HTTPException from fastapi if not already present.

23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Use a stable Python base image
FROM python:3.10-slim
Comment on lines +1 to +2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Container runs as root — add a non-root USER.

Running the application as root inside the container is a security risk. If the process is compromised, the attacker has full root privileges within the container. This was also flagged by Trivy (DS-0002).

Proposed fix — add a non-root user at the end
+# Create a non-root user
+RUN useradd --create-home appuser
+USER appuser
+
 # Change to the Backend directory to run the application
 WORKDIR /app/Backend
🧰 Tools
🪛 Trivy (0.69.1)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 1 - 2, The container currently runs as root; add a
non-root user and switch to it at the end of the Dockerfile: create a user and
group (e.g., appuser/appgroup) with non-root UID/GID, ensure application
files/directories are owned by that user (chown relevant paths), set appropriate
permissions, and add a USER appuser (or UID:GID) instruction as the final step
so the process runs unprivileged; reference the Dockerfile and the USER
directive when making the changes.


# Set the working directory
WORKDIR /app

# Install system-level dependencies for building Python packages
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
Comment on lines +8 to +10
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add --no-install-recommends to reduce image bloat.

Without this flag, apt-get install pulls in recommended (but unnecessary) packages, increasing image size. Also flagged by Trivy (DS-0029).

Proposed fix
-RUN apt-get update && apt-get install -y \
+RUN apt-get update && apt-get install -y --no-install-recommends \
     build-essential \
     && rm -rf /var/lib/apt/lists/*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
🧰 Tools
🪛 Trivy (0.69.1)

[error] 8-10: 'apt-get' missing '--no-install-recommends'

'--no-install-recommends' flag is missed: 'apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*'

Rule: DS-0029

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 8 - 10, The apt-get install invocation in the
Dockerfile (the RUN line that performs "apt-get update && apt-get install -y
build-essential && rm -rf /var/lib/apt/lists/*") should include
--no-install-recommends to avoid installing unnecessary recommended packages;
update that RUN command to use "apt-get install -y --no-install-recommends
build-essential" (keeping the existing apt-get update and the rm -rf
/var/lib/apt/lists/* cleanup) so the image size is reduced and Trivy DS-0029 is
addressed.


# Copy requirements from the Backend folder and install
COPY Backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the entire project into the container
COPY . .

# Set environment variables (standard for AI platforms)
ENV PYTHONUNBUFFERED=1

# Change to the Backend directory to run the application
WORKDIR /app/Backend
Comment on lines +1 to +23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

No CMD or ENTRYPOINT — the container has no default run command.

The Dockerfile sets up the environment but never declares what to run. Without a CMD or ENTRYPOINT, docker run on this image will drop into a shell (inherited from the base image) rather than starting the backend service. This makes the image unusable out of the box.

Add an appropriate entrypoint, e.g.:

Proposed fix
 # Change to the Backend directory to run the application
 WORKDIR /app/Backend
+
+# Run the application
+CMD ["python", "main.py"]

Adjust main.py to whatever the actual entry point script is.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Use a stable Python base image
FROM python:3.10-slim
# Set the working directory
WORKDIR /app
# Install system-level dependencies for building Python packages
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements from the Backend folder and install
COPY Backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the entire project into the container
COPY . .
# Set environment variables (standard for AI platforms)
ENV PYTHONUNBUFFERED=1
# Change to the Backend directory to run the application
WORKDIR /app/Backend
# Use a stable Python base image
FROM python:3.10-slim
# Set the working directory
WORKDIR /app
# Install system-level dependencies for building Python packages
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements from the Backend folder and install
COPY Backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the entire project into the container
COPY . .
# Set environment variables (standard for AI platforms)
ENV PYTHONUNBUFFERED=1
# Change to the Backend directory to run the application
WORKDIR /app/Backend
# Run the application
CMD ["python", "main.py"]
🧰 Tools
🪛 Trivy (0.69.1)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[error] 8-10: 'apt-get' missing '--no-install-recommends'

'--no-install-recommends' flag is missed: 'apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*'

Rule: DS-0029

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 1 - 23, The Dockerfile currently misses a default
runtime command; add an ENTRYPOINT or CMD in the Dockerfile to start the backend
service (e.g., invoke Python on your app entrypoint or start Uvicorn for an ASGI
app). Update the Dockerfile to include a final line that runs the correct
entrypoint (reference the project's actual startup target such as main.py or the
ASGI app module) and ensure the referenced script/module (e.g., main.py or
app:app) is present in Backend and executable; adjust the entrypoint string to
match that symbol.

29 changes: 22 additions & 7 deletions Frontend/src/components/collaboration-hub/CollabRequests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,31 @@ const mockRequests = [
const CollabRequests: React.FC = () => {
const [requests, setRequests] = useState(mockRequests);

const handleAccept = (id: number) => {
setRequests(prev => prev.filter(req => req.id !== id));
// TODO: Integrate with backend to accept request
const handleAccept = async (id: number) => {
try {
const response = await fetch(`http://localhost:8000/collaboration/update-status/${id}?status=accepted`, {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
method: 'PUT',
});
if (response.ok) {
setRequests(prev => prev.filter(req => req.id !== id));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
} catch (error) {
console.error("Failed to accept request:", error);
}
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

const handleDeny = (id: number) => {
setRequests(prev => prev.filter(req => req.id !== id));
// TODO: Integrate with backend to deny request
const handleDeny = async (id: number) => {
try {
const response = await fetch(`http://localhost:8000/collaboration/update-status/${id}?status=denied`, {
method: 'PUT',
});
if (response.ok) {
setRequests(prev => prev.filter(req => req.id !== id));
}
} catch (error) {
console.error("Failed to deny request:", error);
}
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

const handleMessage = (id: number) => {
// TODO: Open message modal or redirect to chat
alert("Open chat with sender (not implemented)");
Expand Down