GT AI OS Community v2.0.33 - Add NVIDIA NIM and Nemotron agents

- Updated python_coding_microproject.csv to use NVIDIA NIM Kimi K2
- Updated kali_linux_shell_simulator.csv to use NVIDIA NIM Kimi K2
  - Made more general-purpose (flexible targets, expanded tools)
- Added nemotron-mini-agent.csv for fast local inference via Ollama
- Added nemotron-agent.csv for advanced reasoning via Ollama
- Added wiki page: Projects for NVIDIA NIMs and Nemotron
This commit is contained in:
HackWeasel
2025-12-12 17:47:14 -05:00
commit 310491a557
750 changed files with 232701 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
"""
Authentication and authorization utilities
"""
import jwt
from datetime import datetime, timedelta, timezone
from typing import Optional, Dict, Any
from fastapi import HTTPException, Security, Depends, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.core.config import settings
from app.core.database import get_db
from app.models.user import User
security = HTTPBearer()
class JWTHandler:
"""JWT token handler"""
@staticmethod
def create_access_token(
user_id: int,
user_email: str,
user_type: str,
current_tenant: Optional[dict] = None,
available_tenants: Optional[list] = None,
capabilities: Optional[list] = None,
# For token refresh: preserve original login time and absolute expiry
original_iat: Optional[datetime] = None,
original_absolute_exp: Optional[float] = None,
# Server-side session token (Issue #264)
session_token: Optional[str] = None
) -> str:
"""Create a JWT access token with tenant context
NIST SP 800-63B AAL2 Compliant Session Management (Issues #242, #264):
- exp: 12 hours (matches absolute timeout) - serves as JWT-level backstop
- absolute_exp: Absolute timeout (12 hours) - NOT refreshable, forces re-login
- iat: Original login time - preserved across token refreshes
- session_id: Server-side session token for authoritative validation
The server-side session (via SessionService) enforces the 30-minute idle timeout
by tracking last_activity_at. JWT exp is set to 12 hours so it doesn't block
requests before the server-side session validation can check activity-based idle timeout.
"""
now = datetime.now(timezone.utc)
# Use original iat if refreshing, otherwise current time (new login)
iat = original_iat if original_iat else now
# Calculate absolute expiry: iat + absolute timeout hours (only set on initial login)
if original_absolute_exp is not None:
absolute_exp = original_absolute_exp
else:
absolute_exp = (iat + timedelta(hours=settings.JWT_ABSOLUTE_TIMEOUT_HOURS)).timestamp()
payload = {
"sub": str(user_id),
"email": user_email,
"user_type": user_type,
# Current tenant context (most important)
"current_tenant": current_tenant or {},
# Available tenants for switching
"available_tenants": available_tenants or [],
# Base capabilities (rarely used - tenant-specific capabilities are in current_tenant)
"capabilities": capabilities or [],
# NIST/OWASP Session Timeouts (Issues #242, #264)
# exp: Idle timeout - 4 hours from now (refreshable)
"exp": now + timedelta(minutes=settings.JWT_EXPIRES_MINUTES),
# iat: Original login time (preserved across refreshes)
"iat": iat,
# absolute_exp: Absolute timeout from original login (NOT refreshable)
"absolute_exp": absolute_exp,
# session_id: Server-side session token for authoritative validation (Issue #264)
# The server-side session is the source of truth - JWT expiry is secondary
"session_id": session_token
}
# Use HS256 with JWT_SECRET from settings (auto-generated by installer)
return jwt.encode(payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM)
@staticmethod
def decode_token(token: str) -> Dict[str, Any]:
"""Decode and validate a JWT token"""
try:
# Use HS256 with JWT_SECRET from settings (auto-generated by installer)
payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token has expired"
)
except jwt.InvalidTokenError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
)
async def get_current_user(
credentials: HTTPAuthorizationCredentials = Security(security),
db: AsyncSession = Depends(get_db)
) -> User:
"""Get the current authenticated user"""
token = credentials.credentials
payload = JWTHandler.decode_token(token)
user_id = int(payload["sub"])
# Get user from database
result = await db.execute(
select(User).where(User.id == user_id)
)
user = result.scalar_one_or_none()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
if not user.is_active:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="User account is inactive"
)
return user
async def require_admin(current_user: User = Depends(get_current_user)) -> User:
"""Require the current user to be a super admin (control panel access)"""
if current_user.user_type != "super_admin":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Super admin access required"
)
return current_user
async def require_super_admin(current_user: User = Depends(get_current_user)) -> User:
"""Require the current user to be a super admin"""
if current_user.user_type != "super_admin":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Super admin access required"
)
return current_user