🔀 chore(api_key): update import and export names in __init__.py for better clarity and consistency
🔀 chore(api_key): add UnmaskedApiKeyRead model to represent an unmasked API key 🔀 chore(api_key): add user relationship to ApiKey model for easier access to associated user 🔀 chore(api_key): add user_id field to ApiKeyBase and ApiKeyCreate models for easier user association 🔀 chore(api_key): add mask_api_key validator to ApiKeyRead model to mask the API key for security reasons
This commit is contained in:
parent
edd58705e4
commit
82fbeace06
2 changed files with 26 additions and 6 deletions
|
|
@ -1,3 +1,3 @@
|
||||||
from .api_key import ApiKey, ApiKeyCreate, ApiKeyRead
|
from .api_key import ApiKey, ApiKeyCreate, UnmaskedApiKeyRead, ApiKeyRead
|
||||||
|
|
||||||
__all__ = ["ApiKey", "ApiKeyCreate", "ApiKeyRead"]
|
__all__ = ["ApiKey", "ApiKeyCreate", "UnmaskedApiKeyRead", "ApiKeyRead"]
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,44 @@
|
||||||
from sqlmodel import Field
|
from pydantic import validator
|
||||||
|
from sqlmodel import Field, Relationship
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
from typing import Optional
|
from typing import Optional, TYPE_CHECKING
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from langflow.services.database.models.base import SQLModelSerializable
|
from langflow.services.database.models.base import SQLModelSerializable
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from langflow.services.database.models.user import User
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyBase(SQLModelSerializable):
|
class ApiKeyBase(SQLModelSerializable):
|
||||||
api_key: str = Field(index=True, unique=True)
|
api_key: str = Field(index=True, unique=True)
|
||||||
name: Optional[str] = Field(index=True)
|
name: Optional[str] = Field(index=True)
|
||||||
create_at: datetime = Field(default_factory=datetime.utcnow)
|
created_at: datetime = Field(default_factory=datetime.utcnow)
|
||||||
last_used_at: Optional[datetime] = Field(default=None)
|
last_used_at: Optional[datetime] = Field(default=None)
|
||||||
|
user_id: UUID = Field()
|
||||||
|
|
||||||
|
|
||||||
class ApiKey(ApiKeyBase, table=True):
|
class ApiKey(ApiKeyBase, table=True):
|
||||||
id: UUID = Field(default_factory=uuid4, primary_key=True, unique=True)
|
id: UUID = Field(default_factory=uuid4, primary_key=True, unique=True)
|
||||||
|
# User relationship
|
||||||
|
user_id: UUID = Field(index=True, foreign_key="user.id")
|
||||||
|
user: "User" = Relationship(back_populates="api_keys")
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyCreate(ApiKeyBase):
|
class ApiKeyCreate(ApiKeyBase):
|
||||||
pass
|
api_key: Optional[str] = None
|
||||||
|
user_id: Optional[UUID] = None
|
||||||
|
|
||||||
|
|
||||||
|
class UnmaskedApiKeyRead(ApiKeyBase):
|
||||||
|
id: UUID
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyRead(ApiKeyBase):
|
class ApiKeyRead(ApiKeyBase):
|
||||||
id: UUID
|
id: UUID
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
user_id: Optional[UUID] = None
|
||||||
|
|
||||||
|
@validator("api_key", always=True)
|
||||||
|
def mask_api_key(cls, v):
|
||||||
|
# This validator will always run, and will mask the API key
|
||||||
|
return f"{'*' * 8}{v[-4:]}"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue