Skip to content

ccproxy.plugins.copilot.oauth.storage

ccproxy.plugins.copilot.oauth.storage

Storage implementation for GitHub Copilot OAuth credentials.

CopilotOAuthStorage

CopilotOAuthStorage(credentials_path=None)

Bases: BaseJsonStorage[CopilotCredentials]

Storage implementation for Copilot OAuth credentials.

Parameters:

Name Type Description Default
credentials_path Path | None

Path to credentials file (uses default if None)

None
Source code in ccproxy/plugins/copilot/oauth/storage.py
def __init__(self, credentials_path: Path | None = None) -> None:
    """Initialize storage with credentials path.

    Args:
        credentials_path: Path to credentials file (uses default if None)
    """
    if credentials_path is None:
        # Use standard GitHub Copilot storage location
        credentials_path = Path.home() / ".config" / "copilot" / "credentials.json"

    super().__init__(credentials_path)

save async

save(credentials)

Store Copilot credentials to file.

Parameters:

Name Type Description Default
credentials CopilotCredentials

Credentials to store

required
Source code in ccproxy/plugins/copilot/oauth/storage.py
async def save(self, credentials: CopilotCredentials) -> bool:
    """Store Copilot credentials to file.

    Args:
        credentials: Credentials to store
    """
    try:
        # Update timestamp
        credentials.refresh_updated_at()

        # Convert to dict for storage
        data = credentials.model_dump(mode="json", exclude_none=True)

        # Use parent class's atomic write with backup
        await self._write_json(data)

        logger.debug(
            "credentials_stored",
            path=str(self.file_path),
            account_type=credentials.account_type,
        )
        return True
    except Exception as e:
        logger.error("credentials_save_failed", error=str(e), exc_info=e)
        return False

load async

load()

Load Copilot credentials from file.

Returns:

Type Description
CopilotCredentials | None

Credentials if found and valid, None otherwise

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def load(self) -> CopilotCredentials | None:
    """Load Copilot credentials from file.

    Returns:
        Credentials if found and valid, None otherwise
    """
    try:
        # Use parent class's read method
        data = await self._read_json()
        if not data:
            logger.debug(
                "credentials_not_found",
                path=str(self.file_path),
            )
            return None

        credentials = CopilotCredentials.model_validate(data)
        logger.debug(
            "credentials_loaded",
            path=str(self.file_path),
            account_type=credentials.account_type,
            is_expired=credentials.is_expired(),
        )
        return credentials
    except Exception as e:
        logger.error(
            "credentials_load_failed",
            error=str(e),
            exc_info=e,
        )
        return None

delete async

delete()

Clear stored credentials.

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def delete(self) -> bool:
    """Clear stored credentials."""
    result = await super().delete()

    logger.debug(
        "credentials_cleared",
        path=str(self.file_path),
    )
    return result

update_oauth_token async

update_oauth_token(oauth_token)

Update OAuth token in stored credentials.

Parameters:

Name Type Description Default
oauth_token CopilotOAuthToken

New OAuth token to store

required
Source code in ccproxy/plugins/copilot/oauth/storage.py
async def update_oauth_token(self, oauth_token: CopilotOAuthToken) -> None:
    """Update OAuth token in stored credentials.

    Args:
        oauth_token: New OAuth token to store
    """
    credentials = await self.load()
    if not credentials:
        # Create new credentials with just the OAuth token
        credentials = CopilotCredentials(
            oauth_token=oauth_token, copilot_token=None
        )
    else:
        # Update existing credentials
        credentials.oauth_token = oauth_token

    await self.save(credentials)

update_copilot_token async

update_copilot_token(copilot_token)

Update Copilot service token in stored credentials.

Parameters:

Name Type Description Default
copilot_token CopilotTokenResponse

New Copilot token to store

required
Source code in ccproxy/plugins/copilot/oauth/storage.py
async def update_copilot_token(self, copilot_token: CopilotTokenResponse) -> None:
    """Update Copilot service token in stored credentials.

    Args:
        copilot_token: New Copilot token to store
    """
    credentials = await self.load()
    if not credentials:
        logger.warning(
            "no_oauth_credentials_for_copilot_token",
            message="Cannot store Copilot token without OAuth credentials",
        )
        raise ValueError(
            "OAuth credentials must exist before storing Copilot token"
        )

    credentials.copilot_token = copilot_token
    await self.save(credentials)

get_oauth_token async

get_oauth_token()

Get OAuth token from stored credentials.

Returns:

Type Description
CopilotOAuthToken | None

OAuth token if available, None otherwise

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def get_oauth_token(self) -> CopilotOAuthToken | None:
    """Get OAuth token from stored credentials.

    Returns:
        OAuth token if available, None otherwise
    """
    credentials = await self.load()
    return credentials.oauth_token if credentials else None

get_copilot_token async

get_copilot_token()

Get Copilot service token from stored credentials.

Returns:

Type Description
CopilotTokenResponse | None

Copilot token if available, None otherwise

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def get_copilot_token(self) -> CopilotTokenResponse | None:
    """Get Copilot service token from stored credentials.

    Returns:
        Copilot token if available, None otherwise
    """
    credentials = await self.load()
    return credentials.copilot_token if credentials else None

load_credentials async

load_credentials()

Legacy method name for backward compatibility.

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def load_credentials(self) -> CopilotCredentials | None:
    """Legacy method name for backward compatibility."""
    return await self.load()

store_credentials async

store_credentials(credentials)

Legacy method name for backward compatibility.

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def store_credentials(self, credentials: CopilotCredentials) -> None:
    """Legacy method name for backward compatibility."""
    await self.save(credentials)

save_credentials async

save_credentials(credentials)

Save credentials method for OAuth provider compatibility.

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def save_credentials(self, credentials: CopilotCredentials) -> None:
    """Save credentials method for OAuth provider compatibility."""
    await self.save(credentials)

clear_credentials async

clear_credentials()

Legacy method name for backward compatibility.

Source code in ccproxy/plugins/copilot/oauth/storage.py
async def clear_credentials(self) -> None:
    """Legacy method name for backward compatibility."""
    await self.delete()