mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
Refactor: rename user secrets table to custom secrets (#11525)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -9,8 +9,8 @@ from openhands.integrations.provider import (
|
||||
ProviderToken,
|
||||
ProviderType,
|
||||
)
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
|
||||
|
||||
def test_provider_token_immutability():
|
||||
@@ -34,8 +34,8 @@ def test_provider_token_immutability():
|
||||
|
||||
|
||||
def test_secret_store_immutability():
|
||||
"""Test that UserSecrets is immutable"""
|
||||
store = UserSecrets(
|
||||
"""Test that Secrets is immutable"""
|
||||
store = Secrets(
|
||||
provider_tokens={ProviderType.GITHUB: ProviderToken(token=SecretStr('test'))}
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ def test_secret_store_immutability():
|
||||
def test_settings_immutability():
|
||||
"""Test that Settings secrets_store is immutable"""
|
||||
settings = Settings(
|
||||
secrets_store=UserSecrets(
|
||||
secrets_store=Secrets(
|
||||
provider_tokens={
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('test'))
|
||||
}
|
||||
@@ -78,7 +78,7 @@ def test_settings_immutability():
|
||||
|
||||
# Test direct modification of secrets_store
|
||||
with pytest.raises(ValidationError):
|
||||
settings.secrets_store = UserSecrets()
|
||||
settings.secrets_store = Secrets()
|
||||
|
||||
# Test nested modification attempts
|
||||
with pytest.raises((TypeError, AttributeError)):
|
||||
@@ -87,7 +87,7 @@ def test_settings_immutability():
|
||||
)
|
||||
|
||||
# Test model_copy creates new instance
|
||||
new_store = UserSecrets(
|
||||
new_store = Secrets(
|
||||
provider_tokens={
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('new_token'))
|
||||
}
|
||||
@@ -140,10 +140,10 @@ def test_provider_handler_immutability():
|
||||
|
||||
|
||||
def test_token_conversion():
|
||||
"""Test token conversion in UserSecrets.create"""
|
||||
"""Test token conversion in Secrets.create"""
|
||||
# Test with string token
|
||||
store1 = Settings(
|
||||
secrets_store=UserSecrets(
|
||||
secrets_store=Secrets(
|
||||
provider_tokens={
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('test_token'))
|
||||
}
|
||||
@@ -159,7 +159,7 @@ def test_token_conversion():
|
||||
assert store1.secrets_store.provider_tokens[ProviderType.GITHUB].user_id is None
|
||||
|
||||
# Test with dict token
|
||||
store2 = UserSecrets(
|
||||
store2 = Secrets(
|
||||
provider_tokens={'github': {'token': 'test_token', 'user_id': 'user1'}}
|
||||
)
|
||||
assert (
|
||||
@@ -170,14 +170,14 @@ def test_token_conversion():
|
||||
|
||||
# Test with ProviderToken
|
||||
token = ProviderToken(token=SecretStr('test_token'), user_id='user2')
|
||||
store3 = UserSecrets(provider_tokens={ProviderType.GITHUB: token})
|
||||
store3 = Secrets(provider_tokens={ProviderType.GITHUB: token})
|
||||
assert (
|
||||
store3.provider_tokens[ProviderType.GITHUB].token.get_secret_value()
|
||||
== 'test_token'
|
||||
)
|
||||
assert store3.provider_tokens[ProviderType.GITHUB].user_id == 'user2'
|
||||
|
||||
store4 = UserSecrets(
|
||||
store4 = Secrets(
|
||||
provider_tokens={
|
||||
ProviderType.GITHUB: 123 # Invalid type
|
||||
}
|
||||
@@ -186,10 +186,10 @@ def test_token_conversion():
|
||||
assert ProviderType.GITHUB not in store4.provider_tokens
|
||||
|
||||
# Test with empty/None token
|
||||
store5 = UserSecrets(provider_tokens={ProviderType.GITHUB: None})
|
||||
store5 = Secrets(provider_tokens={ProviderType.GITHUB: None})
|
||||
assert ProviderType.GITHUB not in store5.provider_tokens
|
||||
|
||||
store6 = UserSecrets(
|
||||
store6 = Secrets(
|
||||
provider_tokens={
|
||||
'invalid_provider': 'test_token' # Invalid provider type
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ def test_client():
|
||||
def create_new_test_conversation(
|
||||
test_request: InitSessionRequest, auth_type: AuthType | None = None
|
||||
):
|
||||
# Create a mock UserSecrets object with the required custom_secrets attribute
|
||||
# Create a mock Secrets object with the required custom_secrets attribute
|
||||
mock_user_secrets = MagicMock()
|
||||
mock_user_secrets.custom_secrets = MappingProxyType({})
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from openhands.server.routes.secrets import (
|
||||
app as secrets_app,
|
||||
)
|
||||
from openhands.storage import get_file_store
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
from openhands.storage.secrets.file_secrets_store import FileSecretsStore
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ async def test_load_custom_secrets_names(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(
|
||||
user_secrets = Secrets(
|
||||
custom_secrets=custom_secrets, provider_tokens=provider_tokens
|
||||
)
|
||||
|
||||
@@ -101,7 +101,7 @@ async def test_load_custom_secrets_names_empty(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens, custom_secrets={})
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens, custom_secrets={})
|
||||
|
||||
# Store the initial settings
|
||||
await file_secrets_store.store(user_secrets)
|
||||
@@ -123,7 +123,7 @@ async def test_add_custom_secret(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens)
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens)
|
||||
|
||||
# Store the initial settings
|
||||
await file_secrets_store.store(user_secrets)
|
||||
@@ -184,7 +184,7 @@ async def test_update_existing_custom_secret(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(
|
||||
user_secrets = Secrets(
|
||||
custom_secrets=custom_secrets, provider_tokens=provider_tokens
|
||||
)
|
||||
|
||||
@@ -223,7 +223,7 @@ async def test_add_multiple_custom_secrets(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(
|
||||
user_secrets = Secrets(
|
||||
custom_secrets=custom_secrets, provider_tokens=provider_tokens
|
||||
)
|
||||
|
||||
@@ -285,7 +285,7 @@ async def test_delete_custom_secret(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(
|
||||
user_secrets = Secrets(
|
||||
custom_secrets=custom_secrets, provider_tokens=provider_tokens
|
||||
)
|
||||
|
||||
@@ -323,7 +323,7 @@ async def test_delete_nonexistent_custom_secret(test_client, file_secrets_store)
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(
|
||||
user_secrets = Secrets(
|
||||
custom_secrets=custom_secrets, provider_tokens=provider_tokens
|
||||
)
|
||||
|
||||
@@ -355,7 +355,7 @@ async def test_add_git_providers_with_host(test_client, file_secrets_store):
|
||||
provider_tokens = {
|
||||
ProviderType.GITHUB: ProviderToken(token=SecretStr('github-token'))
|
||||
}
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens)
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens)
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
# Mock check_provider_tokens to return empty string (no error)
|
||||
@@ -394,7 +394,7 @@ async def test_add_git_providers_update_host_only(test_client, file_secrets_stor
|
||||
token=SecretStr('github-token'), host='github.com'
|
||||
)
|
||||
}
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens)
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens)
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
# Mock check_provider_tokens to return empty string (no error)
|
||||
@@ -433,7 +433,7 @@ async def test_add_git_providers_invalid_token_with_host(
|
||||
):
|
||||
"""Test adding an invalid token with a host."""
|
||||
# Create initial user secrets
|
||||
user_secrets = UserSecrets()
|
||||
user_secrets = Secrets()
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
# Mock validate_provider_token to return None (invalid token)
|
||||
@@ -456,7 +456,7 @@ async def test_add_git_providers_invalid_token_with_host(
|
||||
async def test_add_multiple_git_providers_with_hosts(test_client, file_secrets_store):
|
||||
"""Test adding multiple git providers with different hosts."""
|
||||
# Create initial user secrets
|
||||
user_secrets = UserSecrets()
|
||||
user_secrets = Secrets()
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
# Mock check_provider_tokens to return empty string (no error)
|
||||
|
||||
@@ -9,7 +9,7 @@ from pydantic import SecretStr
|
||||
from openhands.integrations.provider import ProviderToken, ProviderType
|
||||
from openhands.server.app import app
|
||||
from openhands.server.user_auth.user_auth import UserAuth
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
from openhands.storage.memory import InMemoryFileStore
|
||||
from openhands.storage.secrets.secrets_store import SecretsStore
|
||||
from openhands.storage.settings.file_settings_store import FileSettingsStore
|
||||
@@ -43,7 +43,7 @@ class MockUserAuth(UserAuth):
|
||||
async def get_secrets_store(self) -> SecretsStore | None:
|
||||
return None
|
||||
|
||||
async def get_user_secrets(self) -> UserSecrets | None:
|
||||
async def get_secrets(self) -> Secrets | None:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -14,8 +14,8 @@ from openhands.server.routes.secrets import (
|
||||
from openhands.server.routes.settings import store_llm_settings
|
||||
from openhands.server.settings import POSTProviderModel
|
||||
from openhands.storage import get_file_store
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
from openhands.storage.data_models.settings import Settings
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.secrets.file_secrets_store import FileSecretsStore
|
||||
|
||||
|
||||
@@ -220,9 +220,9 @@ async def test_store_provider_tokens_new_tokens(test_client, file_secrets_store)
|
||||
mock_store = MagicMock()
|
||||
mock_store.load = AsyncMock(return_value=None) # No existing settings
|
||||
|
||||
UserSecrets()
|
||||
Secrets()
|
||||
|
||||
user_secrets = await file_secrets_store.store(UserSecrets())
|
||||
user_secrets = await file_secrets_store.store(Secrets())
|
||||
|
||||
response = test_client.post('/api/add-git-providers', json=provider_tokens)
|
||||
assert response.status_code == 200
|
||||
@@ -242,8 +242,8 @@ async def test_store_provider_tokens_update_existing(test_client, file_secrets_s
|
||||
github_token = ProviderToken(token=SecretStr('old-token'))
|
||||
provider_tokens = {ProviderType.GITHUB: github_token}
|
||||
|
||||
# Create a UserSecrets with the provider tokens
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens)
|
||||
# Create a Secrets with the provider tokens
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens)
|
||||
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
@@ -268,7 +268,7 @@ async def test_store_provider_tokens_keep_existing(test_client, file_secrets_sto
|
||||
# Create existing secrets with a GitHub token
|
||||
github_token = ProviderToken(token=SecretStr('existing-token'))
|
||||
provider_tokens = {ProviderType.GITHUB: github_token}
|
||||
user_secrets = UserSecrets(provider_tokens=provider_tokens)
|
||||
user_secrets = Secrets(provider_tokens=provider_tokens)
|
||||
|
||||
await file_secrets_store.store(user_secrets)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from pydantic import SecretStr
|
||||
from openhands.integrations.provider import ProviderToken, ProviderType
|
||||
from openhands.server.app import app
|
||||
from openhands.server.user_auth.user_auth import UserAuth
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
from openhands.storage.memory import InMemoryFileStore
|
||||
from openhands.storage.secrets.secrets_store import SecretsStore
|
||||
from openhands.storage.settings.file_settings_store import FileSettingsStore
|
||||
@@ -43,7 +43,7 @@ class MockUserAuth(UserAuth):
|
||||
async def get_secrets_store(self) -> SecretsStore | None:
|
||||
return None
|
||||
|
||||
async def get_user_secrets(self) -> UserSecrets | None:
|
||||
async def get_secrets(self) -> Secrets | None:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -10,12 +10,12 @@ from openhands.integrations.provider import (
|
||||
ProviderToken,
|
||||
ProviderType,
|
||||
)
|
||||
from openhands.storage.data_models.user_secrets import UserSecrets
|
||||
from openhands.storage.data_models.secrets import Secrets
|
||||
|
||||
|
||||
class TestUserSecrets:
|
||||
class TestSecrets:
|
||||
def test_adding_only_provider_tokens(self):
|
||||
"""Test adding only provider tokens to the UserSecrets."""
|
||||
"""Test adding only provider tokens to the Secrets."""
|
||||
# Create provider tokens
|
||||
github_token = ProviderToken(
|
||||
token=SecretStr('github-token-123'), user_id='user1'
|
||||
@@ -31,7 +31,7 @@ class TestUserSecrets:
|
||||
}
|
||||
|
||||
# Initialize the store with a dict that will be converted to MappingProxyType
|
||||
store = UserSecrets(provider_tokens=provider_tokens)
|
||||
store = Secrets(provider_tokens=provider_tokens)
|
||||
|
||||
# Verify the tokens were added correctly
|
||||
assert isinstance(store.provider_tokens, MappingProxyType)
|
||||
@@ -52,7 +52,7 @@ class TestUserSecrets:
|
||||
assert len(store.custom_secrets) == 0
|
||||
|
||||
def test_adding_only_custom_secrets(self):
|
||||
"""Test adding only custom secrets to the UserSecrets."""
|
||||
"""Test adding only custom secrets to the Secrets."""
|
||||
# Create custom secrets
|
||||
custom_secrets = {
|
||||
'API_KEY': CustomSecret(
|
||||
@@ -64,7 +64,7 @@ class TestUserSecrets:
|
||||
}
|
||||
|
||||
# Initialize the store with custom secrets
|
||||
store = UserSecrets(custom_secrets=custom_secrets)
|
||||
store = Secrets(custom_secrets=custom_secrets)
|
||||
|
||||
# Verify the custom secrets were added correctly
|
||||
assert isinstance(store.custom_secrets, MappingProxyType)
|
||||
@@ -95,7 +95,7 @@ class TestUserSecrets:
|
||||
custom_secrets_proxy = MappingProxyType({'API_KEY': custom_secret})
|
||||
|
||||
# Test with dict for provider_tokens and MappingProxyType for custom_secrets
|
||||
store1 = UserSecrets(
|
||||
store1 = Secrets(
|
||||
provider_tokens=provider_tokens_dict, custom_secrets=custom_secrets_proxy
|
||||
)
|
||||
|
||||
@@ -120,7 +120,7 @@ class TestUserSecrets:
|
||||
'API_KEY': {'secret': 'api-key-123', 'description': 'API key'}
|
||||
}
|
||||
|
||||
store2 = UserSecrets(
|
||||
store2 = Secrets(
|
||||
provider_tokens=provider_tokens_proxy, custom_secrets=custom_secrets_dict
|
||||
)
|
||||
|
||||
@@ -146,7 +146,7 @@ class TestUserSecrets:
|
||||
)
|
||||
}
|
||||
|
||||
initial_store = UserSecrets(
|
||||
initial_store = Secrets(
|
||||
provider_tokens=MappingProxyType({ProviderType.GITHUB: github_token}),
|
||||
custom_secrets=MappingProxyType(custom_secret),
|
||||
)
|
||||
@@ -212,7 +212,7 @@ class TestUserSecrets:
|
||||
)
|
||||
|
||||
def test_serialization_with_expose_secrets(self):
|
||||
"""Test serializing the UserSecrets with expose_secrets=True."""
|
||||
"""Test serializing the Secrets with expose_secrets=True."""
|
||||
# Create a store with both provider tokens and custom secrets
|
||||
github_token = ProviderToken(
|
||||
token=SecretStr('github-token-123'), user_id='user1'
|
||||
@@ -223,7 +223,7 @@ class TestUserSecrets:
|
||||
)
|
||||
}
|
||||
|
||||
store = UserSecrets(
|
||||
store = Secrets(
|
||||
provider_tokens=MappingProxyType({ProviderType.GITHUB: github_token}),
|
||||
custom_secrets=MappingProxyType(custom_secrets),
|
||||
)
|
||||
@@ -290,7 +290,7 @@ class TestUserSecrets:
|
||||
}
|
||||
|
||||
# Initialize the store
|
||||
store = UserSecrets(provider_tokens=mixed_provider_tokens)
|
||||
store = Secrets(provider_tokens=mixed_provider_tokens)
|
||||
|
||||
# Verify all tokens are converted to SecretStr
|
||||
assert isinstance(store.provider_tokens, MappingProxyType)
|
||||
@@ -322,7 +322,7 @@ class TestUserSecrets:
|
||||
}
|
||||
|
||||
# Initialize the store
|
||||
store = UserSecrets(custom_secrets=custom_secrets_dict)
|
||||
store = Secrets(custom_secrets=custom_secrets_dict)
|
||||
|
||||
# Verify all secrets are converted to CustomSecret objects
|
||||
assert isinstance(store.custom_secrets, MappingProxyType)
|
||||
|
||||
Reference in New Issue
Block a user