diff --git a/backend/danswer/db/connector_credential_pair.py b/backend/danswer/db/connector_credential_pair.py
index a44182d254b..6df56966d7f 100644
--- a/backend/danswer/db/connector_credential_pair.py
+++ b/backend/danswer/db/connector_credential_pair.py
@@ -76,8 +76,10 @@ def _add_user_filters(
.where(~UG__CCpair.user_group_id.in_(user_groups))
.correlate(ConnectorCredentialPair)
)
+ where_clause |= ConnectorCredentialPair.access_type == AccessType.SYNC
else:
where_clause |= ConnectorCredentialPair.access_type == AccessType.PUBLIC
+ where_clause |= ConnectorCredentialPair.access_type == AccessType.SYNC
return stmt.where(where_clause)
diff --git a/backend/danswer/server/documents/cc_pair.py b/backend/danswer/server/documents/cc_pair.py
index 4b38eec7f71..55808ebcee7 100644
--- a/backend/danswer/server/documents/cc_pair.py
+++ b/backend/danswer/server/documents/cc_pair.py
@@ -387,6 +387,7 @@ def associate_credential_to_connector(
user=user,
target_group_ids=metadata.groups,
object_is_public=metadata.access_type == AccessType.PUBLIC,
+ object_is_perm_sync=metadata.access_type == AccessType.SYNC,
)
try:
diff --git a/backend/danswer/server/documents/connector.py b/backend/danswer/server/documents/connector.py
index 24f9920ac74..cc6b1419bae 100644
--- a/backend/danswer/server/documents/connector.py
+++ b/backend/danswer/server/documents/connector.py
@@ -81,7 +81,6 @@
from danswer.db.models import IndexingStatus
from danswer.db.models import SearchSettings
from danswer.db.models import User
-from danswer.db.models import UserRole
from danswer.db.search_settings import get_current_search_settings
from danswer.db.search_settings import get_secondary_search_settings
from danswer.file_store.file_store import get_default_file_store
@@ -665,7 +664,8 @@ def create_connector_from_model(
db_session=db_session,
user=user,
target_group_ids=connector_data.groups,
- object_is_public=connector_data.is_public,
+ object_is_public=connector_data.access_type == AccessType.PUBLIC,
+ object_is_perm_sync=connector_data.access_type == AccessType.SYNC,
)
connector_base = connector_data.to_connector_base()
return create_connector(
@@ -683,32 +683,31 @@ def create_connector_with_mock_credential(
user: User = Depends(current_curator_or_admin_user),
db_session: Session = Depends(get_session),
) -> StatusResponse:
- if user and user.role != UserRole.ADMIN:
- if connector_data.is_public:
- raise HTTPException(
- status_code=401,
- detail="User does not have permission to create public credentials",
- )
- if not connector_data.groups:
- raise HTTPException(
- status_code=401,
- detail="Curators must specify 1+ groups",
- )
+ fetch_ee_implementation_or_noop(
+ "danswer.db.user_group", "validate_user_creation_permissions", None
+ )(
+ db_session=db_session,
+ user=user,
+ target_group_ids=connector_data.groups,
+ object_is_public=connector_data.access_type == AccessType.PUBLIC,
+ object_is_perm_sync=connector_data.access_type == AccessType.SYNC,
+ )
try:
_validate_connector_allowed(connector_data.source)
connector_response = create_connector(
- db_session=db_session, connector_data=connector_data
+ db_session=db_session,
+ connector_data=connector_data,
)
mock_credential = CredentialBase(
- credential_json={}, admin_public=True, source=connector_data.source
+ credential_json={},
+ admin_public=True,
+ source=connector_data.source,
)
credential = create_credential(
- mock_credential, user=user, db_session=db_session
- )
-
- access_type = (
- AccessType.PUBLIC if connector_data.is_public else AccessType.PRIVATE
+ credential_data=mock_credential,
+ user=user,
+ db_session=db_session,
)
response = add_credential_to_connector(
@@ -716,7 +715,7 @@ def create_connector_with_mock_credential(
user=user,
connector_id=cast(int, connector_response.id), # will aways be an int
credential_id=credential.id,
- access_type=access_type,
+ access_type=connector_data.access_type,
cc_pair_name=connector_data.name,
groups=connector_data.groups,
)
@@ -741,7 +740,8 @@ def update_connector_from_model(
db_session=db_session,
user=user,
target_group_ids=connector_data.groups,
- object_is_public=connector_data.is_public,
+ object_is_public=connector_data.access_type == AccessType.PUBLIC,
+ object_is_perm_sync=connector_data.access_type == AccessType.SYNC,
)
connector_base = connector_data.to_connector_base()
except ValueError as e:
diff --git a/backend/danswer/server/documents/models.py b/backend/danswer/server/documents/models.py
index a541ae92c48..07610984515 100644
--- a/backend/danswer/server/documents/models.py
+++ b/backend/danswer/server/documents/models.py
@@ -64,11 +64,11 @@ class ConnectorBase(BaseModel):
class ConnectorUpdateRequest(ConnectorBase):
- is_public: bool = True
+ access_type: AccessType
groups: list[int] = Field(default_factory=list)
def to_connector_base(self) -> ConnectorBase:
- return ConnectorBase(**self.model_dump(exclude={"is_public", "groups"}))
+ return ConnectorBase(**self.model_dump(exclude={"access_type", "groups"}))
class ConnectorSnapshot(ConnectorBase):
diff --git a/backend/ee/danswer/db/user_group.py b/backend/ee/danswer/db/user_group.py
index 470a46e688b..0ba4e3bd49b 100644
--- a/backend/ee/danswer/db/user_group.py
+++ b/backend/ee/danswer/db/user_group.py
@@ -124,16 +124,21 @@ def _cleanup_document_set__user_group_relationships__no_commit(
def validate_user_creation_permissions(
db_session: Session,
user: User | None,
- target_group_ids: list[int] | None,
- object_is_public: bool | None,
+ target_group_ids: list[int] | None = None,
+ object_is_public: bool | None = None,
+ object_is_perm_sync: bool | None = None,
) -> None:
"""
+ All users can create/edit permission synced objects if they don't specify a group
All admin actions are allowed.
Prevents non-admins from creating/editing:
- public objects
- objects with no groups
- objects that belong to a group they don't curate
"""
+ if object_is_perm_sync and not target_group_ids:
+ return
+
if not user or user.role == UserRole.ADMIN:
return
diff --git a/web/src/app/admin/connector/[ccPairId]/page.tsx b/web/src/app/admin/connector/[ccPairId]/page.tsx
index 9e6deefc1c4..33cbfe5207f 100644
--- a/web/src/app/admin/connector/[ccPairId]/page.tsx
+++ b/web/src/app/admin/connector/[ccPairId]/page.tsx
@@ -214,9 +214,11 @@ function Main({ ccPairId }: { ccPairId: number }) {
{!ccPair.is_editable_for_current_user && (
- {ccPair.is_public
+ {ccPair.access_type === "public"
? "Public connectors are not editable by curators."
- : "This connector belongs to groups where you don't have curator permissions, so it's not editable."}
+ : ccPair.access_type === "sync"
+ ? "Sync connectors are not editable by curators."
+ : "This connector belongs to groups where you don't have curator permissions, so it's not editable."}