mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-06-14 01:50:53 +02:00
* first cut at slack oauth flow * fix usage of hooks * fix button spacing * add additional error logging * no dev redirect * early cut at google drive oauth * second pass * switch to production uri's * try handling oauth_interactive differently * pass through client id and secret if uploaded * fix call * fix test * temporarily disable check for testing * Revert "temporarily disable check for testing" This reverts commit 4b5a022a5fe38b05355a561616068af8e969def2. * support visibility in test * missed file * first cut at confluence oauth * work in progress * work in progress * work in progress * work in progress * work in progress * first cut at distributed locking * WIP to make test work * add some dev mode affordances and gate usage of redis behind dynamic credentials * mypy and credentials provider fixes * WIP * fix created at * fix setting initialValue on everything * remove debugging, fix ??? some TextFormField issues * npm fixes * comment cleanup * fix comments * pin the size of the card section * more review fixes * more fixes --------- Co-authored-by: Richard Kuo <rkuo@rkuo.com> Co-authored-by: Richard Kuo (Danswer) <rkuo@onyx.app>
113 lines
4.2 KiB
Python
113 lines
4.2 KiB
Python
from ee.onyx.db.external_perm import ExternalUserGroup
|
|
from ee.onyx.external_permissions.confluence.constants import ALL_CONF_EMAILS_GROUP_NAME
|
|
from onyx.background.error_logging import emit_background_error
|
|
from onyx.connectors.confluence.onyx_confluence import (
|
|
get_user_email_from_username__server,
|
|
)
|
|
from onyx.connectors.confluence.onyx_confluence import OnyxConfluence
|
|
from onyx.connectors.credentials_provider import OnyxDBCredentialsProvider
|
|
from onyx.db.models import ConnectorCredentialPair
|
|
from onyx.utils.logger import setup_logger
|
|
|
|
logger = setup_logger()
|
|
|
|
|
|
def _build_group_member_email_map(
|
|
confluence_client: OnyxConfluence, cc_pair_id: int
|
|
) -> dict[str, set[str]]:
|
|
group_member_emails: dict[str, set[str]] = {}
|
|
for user in confluence_client.paginated_cql_user_retrieval():
|
|
logger.debug(f"Processing groups for user: {user}")
|
|
|
|
email = user.email
|
|
if not email:
|
|
# This field is only present in Confluence Server
|
|
user_name = user.username
|
|
# If it is present, try to get the email using a Server-specific method
|
|
if user_name:
|
|
email = get_user_email_from_username__server(
|
|
confluence_client=confluence_client,
|
|
user_name=user_name,
|
|
)
|
|
|
|
if not email:
|
|
# If we still don't have an email, skip this user
|
|
msg = f"user result missing email field: {user}"
|
|
if user.type == "app":
|
|
logger.warning(msg)
|
|
else:
|
|
emit_background_error(msg, cc_pair_id=cc_pair_id)
|
|
logger.error(msg)
|
|
continue
|
|
|
|
all_users_groups: set[str] = set()
|
|
for group in confluence_client.paginated_groups_by_user_retrieval(user.user_id):
|
|
# group name uniqueness is enforced by Confluence, so we can use it as a group ID
|
|
group_id = group["name"]
|
|
group_member_emails.setdefault(group_id, set()).add(email)
|
|
all_users_groups.add(group_id)
|
|
|
|
if not all_users_groups:
|
|
msg = f"No groups found for user with email: {email}"
|
|
emit_background_error(msg, cc_pair_id=cc_pair_id)
|
|
logger.error(msg)
|
|
else:
|
|
logger.debug(f"Found groups {all_users_groups} for user with email {email}")
|
|
|
|
if not group_member_emails:
|
|
msg = "No groups found for any users."
|
|
emit_background_error(msg, cc_pair_id=cc_pair_id)
|
|
logger.error(msg)
|
|
|
|
return group_member_emails
|
|
|
|
|
|
def confluence_group_sync(
|
|
tenant_id: str,
|
|
cc_pair: ConnectorCredentialPair,
|
|
) -> list[ExternalUserGroup]:
|
|
provider = OnyxDBCredentialsProvider(tenant_id, "confluence", cc_pair.credential_id)
|
|
is_cloud = cc_pair.connector.connector_specific_config.get("is_cloud", False)
|
|
wiki_base: str = cc_pair.connector.connector_specific_config["wiki_base"]
|
|
url = wiki_base.rstrip("/")
|
|
|
|
probe_kwargs = {
|
|
"max_backoff_retries": 6,
|
|
"max_backoff_seconds": 10,
|
|
}
|
|
|
|
final_kwargs = {
|
|
"max_backoff_retries": 10,
|
|
"max_backoff_seconds": 60,
|
|
}
|
|
|
|
confluence_client = OnyxConfluence(is_cloud, url, provider)
|
|
confluence_client._probe_connection(**probe_kwargs)
|
|
confluence_client._initialize_connection(**final_kwargs)
|
|
|
|
group_member_email_map = _build_group_member_email_map(
|
|
confluence_client=confluence_client,
|
|
cc_pair_id=cc_pair.id,
|
|
)
|
|
onyx_groups: list[ExternalUserGroup] = []
|
|
all_found_emails = set()
|
|
for group_id, group_member_emails in group_member_email_map.items():
|
|
onyx_groups.append(
|
|
ExternalUserGroup(
|
|
id=group_id,
|
|
user_emails=list(group_member_emails),
|
|
)
|
|
)
|
|
all_found_emails.update(group_member_emails)
|
|
|
|
# This is so that when we find a public confleunce server page, we can
|
|
# give access to all users only in if they have an email in Confluence
|
|
if cc_pair.connector.connector_specific_config.get("is_cloud", False):
|
|
all_found_group = ExternalUserGroup(
|
|
id=ALL_CONF_EMAILS_GROUP_NAME,
|
|
user_emails=list(all_found_emails),
|
|
)
|
|
onyx_groups.append(all_found_group)
|
|
|
|
return onyx_groups
|