mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e604455332 |
@@ -1,7 +1,7 @@
|
||||
"""OAuth authentication provider for Basic Memory MCP server."""
|
||||
|
||||
import secrets
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Dict, Optional
|
||||
|
||||
import jwt
|
||||
@@ -92,7 +92,7 @@ class BasicMemoryOAuthProvider(
|
||||
self.authorization_codes[auth_code] = BasicMemoryAuthorizationCode(
|
||||
code=auth_code,
|
||||
scopes=params.scopes or [],
|
||||
expires_at=(datetime.utcnow() + timedelta(minutes=10)).timestamp(),
|
||||
expires_at=(datetime.now(timezone.utc) + timedelta(minutes=10)).timestamp(),
|
||||
client_id=client.client_id,
|
||||
code_challenge=params.code_challenge,
|
||||
redirect_uri=params.redirect_uri,
|
||||
@@ -119,7 +119,7 @@ class BasicMemoryOAuthProvider(
|
||||
|
||||
if code and code.client_id == client.client_id:
|
||||
# Check if expired
|
||||
if datetime.utcnow().timestamp() > code.expires_at:
|
||||
if datetime.now(timezone.utc).timestamp() > code.expires_at:
|
||||
del self.authorization_codes[authorization_code]
|
||||
return None
|
||||
return code
|
||||
@@ -135,7 +135,7 @@ class BasicMemoryOAuthProvider(
|
||||
refresh_token = secrets.token_urlsafe(32)
|
||||
|
||||
# Store tokens
|
||||
expires_at = (datetime.utcnow() + timedelta(hours=1)).timestamp()
|
||||
expires_at = (datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()
|
||||
|
||||
self.access_tokens[access_token] = BasicMemoryAccessToken(
|
||||
token=access_token,
|
||||
@@ -187,7 +187,7 @@ class BasicMemoryOAuthProvider(
|
||||
new_refresh_token = secrets.token_urlsafe(32)
|
||||
|
||||
# Store new tokens
|
||||
expires_at = (datetime.utcnow() + timedelta(hours=1)).timestamp()
|
||||
expires_at = (datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()
|
||||
|
||||
self.access_tokens[new_access_token] = BasicMemoryAccessToken(
|
||||
token=new_access_token,
|
||||
@@ -220,7 +220,7 @@ class BasicMemoryOAuthProvider(
|
||||
|
||||
if access_token:
|
||||
# Check if expired
|
||||
if access_token.expires_at and datetime.utcnow().timestamp() > access_token.expires_at:
|
||||
if access_token.expires_at and datetime.now(timezone.utc).timestamp() > access_token.expires_at:
|
||||
logger.debug("Token found in memory but expired, removing")
|
||||
del self.access_tokens[token]
|
||||
return None
|
||||
@@ -262,8 +262,8 @@ class BasicMemoryOAuthProvider(
|
||||
"iss": self.issuer_url,
|
||||
"sub": client_id,
|
||||
"aud": "basic-memory",
|
||||
"exp": datetime.utcnow() + timedelta(hours=1),
|
||||
"iat": datetime.utcnow(),
|
||||
"exp": datetime.now(timezone.utc) + timedelta(hours=1),
|
||||
"iat": datetime.now(timezone.utc),
|
||||
"scopes": scopes,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import os
|
||||
import secrets
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
import httpx
|
||||
@@ -123,7 +123,7 @@ class SupabaseOAuthProvider(
|
||||
self.pending_auth_codes[state] = SupabaseAuthorizationCode(
|
||||
code=state,
|
||||
scopes=params.scopes or [],
|
||||
expires_at=(datetime.utcnow() + timedelta(minutes=10)).timestamp(),
|
||||
expires_at=(datetime.now(timezone.utc) + timedelta(minutes=10)).timestamp(),
|
||||
client_id=client.client_id,
|
||||
code_challenge=params.code_challenge,
|
||||
redirect_uri=params.redirect_uri,
|
||||
@@ -218,7 +218,7 @@ class SupabaseOAuthProvider(
|
||||
|
||||
if code and code.client_id == client.client_id:
|
||||
# Check expiration
|
||||
if datetime.utcnow().timestamp() > code.expires_at:
|
||||
if datetime.now(timezone.utc).timestamp() > code.expires_at:
|
||||
del self.pending_auth_codes[authorization_code]
|
||||
return None
|
||||
return code
|
||||
@@ -453,8 +453,8 @@ class SupabaseOAuthProvider(
|
||||
"email": email,
|
||||
"scopes": scopes,
|
||||
"supabase_token": supabase_access_token[:10] + "...", # Reference only
|
||||
"exp": datetime.utcnow() + timedelta(hours=1),
|
||||
"iat": datetime.utcnow(),
|
||||
"exp": datetime.now(timezone.utc) + timedelta(hours=1),
|
||||
"iat": datetime.now(timezone.utc),
|
||||
}
|
||||
|
||||
# Use Supabase JWT secret if available
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Project model for Basic Memory."""
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import (
|
||||
@@ -52,9 +52,9 @@ class Project(Base):
|
||||
is_default: Mapped[Optional[bool]] = mapped_column(Boolean, default=None, nullable=True)
|
||||
|
||||
# Timestamps
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
|
||||
DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
# Define relationships to entities, observations, and relations
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Tests for OAuth authentication provider."""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from mcp.server.auth.provider import AuthorizationParams
|
||||
from mcp.shared.auth import OAuthClientInformationFull
|
||||
from pydantic import AnyHttpUrl
|
||||
@@ -185,7 +185,7 @@ class TestBasicMemoryOAuthProvider:
|
||||
token=token_str,
|
||||
client_id=client.client_id,
|
||||
scopes=["read", "write"],
|
||||
expires_at=int((datetime.utcnow() + timedelta(hours=1)).timestamp()),
|
||||
expires_at=int((datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()),
|
||||
)
|
||||
provider.access_tokens[token_str] = access_token
|
||||
|
||||
@@ -226,7 +226,7 @@ class TestBasicMemoryOAuthProvider:
|
||||
provider.authorization_codes[auth_code] = BasicMemoryAuthorizationCode(
|
||||
code=auth_code,
|
||||
scopes=["read"],
|
||||
expires_at=(datetime.utcnow() - timedelta(minutes=1)).timestamp(),
|
||||
expires_at=(datetime.now(timezone.utc) - timedelta(minutes=1)).timestamp(),
|
||||
client_id=client.client_id,
|
||||
code_challenge="challenge",
|
||||
redirect_uri=AnyHttpUrl("http://localhost:3000/callback"),
|
||||
@@ -288,7 +288,7 @@ class TestBasicMemoryOAuthProvider:
|
||||
token=expired_token_str,
|
||||
client_id="test-client",
|
||||
scopes=["read"],
|
||||
expires_at=int((datetime.utcnow() - timedelta(minutes=1)).timestamp()), # Expired
|
||||
expires_at=int((datetime.now(timezone.utc) - timedelta(minutes=1)).timestamp()), # Expired
|
||||
)
|
||||
provider.access_tokens[expired_token_str] = expired_access_token
|
||||
|
||||
|
||||
Reference in New Issue
Block a user