From ce620edd94813d64dacd60b1b1baeb30d158e66a Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Fri, 17 Apr 2026 16:26:45 +0530 Subject: [PATCH 1/2] sharepoint UI --- backend/connector_v2/views.py | 7 +++++-- .../filesystems/sharepoint/sharepoint.py | 18 +++++++++--------- .../sharepoint/static/json_schema.json | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/backend/connector_v2/views.py b/backend/connector_v2/views.py index 09a33be983..a8268acb37 100644 --- a/backend/connector_v2/views.py +++ b/backend/connector_v2/views.py @@ -90,12 +90,15 @@ def _get_connector_metadata(self, connector_id: str) -> dict[str, str] | None: # Only use OAuth flow if connector supports it AND oauth_key is provided if ConnectorInstance.supportsOAuth(connector_id=connector_id) and oauth_key: - connector_metadata = ConnectorAuthHelper.get_oauth_creds_from_cache( + oauth_tokens = ConnectorAuthHelper.get_oauth_creds_from_cache( cache_key=oauth_key, delete_key=False, # Don't delete yet - wait for successful operation ) - if connector_metadata is None: + if oauth_tokens is None: raise MissingParamException(param=ConnectorAuthKey.OAUTH_KEY) + # Preserve non-secret form fields (e.g. site_url connector Sharepoint) + form_metadata = self.request.data.get(CIKey.CONNECTOR_METADATA) or {} + connector_metadata = {**form_metadata, **oauth_tokens} else: connector_metadata = self.request.data.get(CIKey.CONNECTOR_METADATA) return connector_metadata diff --git a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/sharepoint.py b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/sharepoint.py index 3eacdac30d..e8acd44f31 100644 --- a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/sharepoint.py +++ b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/sharepoint.py @@ -137,8 +137,8 @@ def _get_drive(self) -> Any: ctx = self._get_context() if self.drive_id: - # Specific drive by ID - self._drive = ctx.drives.get_by_id(self.drive_id) + # Specific drive by ID — EntityCollection uses bracket indexing. + self._drive = ctx.drives[self.drive_id] elif self.site_url and "sharepoint.com" in self.site_url.lower(): # SharePoint site - get default document library self._drive = self._get_sharepoint_site_drive(ctx) @@ -149,15 +149,15 @@ def _get_drive(self) -> Any: return self._drive def _get_sharepoint_site_drive(self, ctx: Any) -> Any: - """Get drive from SharePoint site URL.""" + """Get drive from SharePoint site URL. + + Uses the library's get_by_url, which maps an absolute site URL to the + Graph API's ``/sites/{hostname}:/{server-relative-path}`` addressing. + """ from urllib.parse import urlparse - parsed = urlparse(self.site_url) - # Extract site path from URL like - # https://tenant.sharepoint.com/sites/sitename - site_path = parsed.path.rstrip("/") - if site_path: - return ctx.sites.get_by_path(site_path).drive + if urlparse(self.site_url).path.strip("/"): + return ctx.sites.get_by_url(self.site_url).drive return ctx.sites.root.drive def _get_onedrive_drive(self, ctx: Any) -> Any: diff --git a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json index d83f84c8ae..5ede08913e 100644 --- a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json +++ b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json @@ -22,6 +22,7 @@ "drive_id": { "type": "string", "title": "Drive ID", + "format": "password", "description": "Specific Drive/Document Library ID. Leave empty to use the default drive." }, "auth_type": { From 0896b9179cf98e209ded4bf997664ce7826184ff Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Fri, 17 Apr 2026 19:46:59 +0530 Subject: [PATCH 2/2] sharepoint UI --- backend/connector_v2/serializers.py | 8 ++++---- .../filesystems/sharepoint/static/json_schema.json | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/backend/connector_v2/serializers.py b/backend/connector_v2/serializers.py index 5517bc5257..86e8734807 100644 --- a/backend/connector_v2/serializers.py +++ b/backend/connector_v2/serializers.py @@ -53,10 +53,10 @@ def save(self, **kwargs): # type: ignore oauth_credentials=kwargs[CIKey.CONNECTOR_METADATA], ) kwargs[CIKey.CONNECTOR_AUTH] = connector_oauth - ( - kwargs[CIKey.CONNECTOR_METADATA], - refresh_status, - ) = connector_oauth.get_and_refresh_tokens() + # Discard return value: ConnectorAuth.extra_data is shared across + # every connector with the same (provider, uid) and would overwrite + # this connector's form fields (site_url, drive_id). + connector_oauth.get_and_refresh_tokens() except Exception as exc: logger.error( "Error while obtaining ConnectorAuth for connector id " diff --git a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json index 5ede08913e..6070cbd840 100644 --- a/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json +++ b/unstract/connectors/src/unstract/connectors/filesystems/sharepoint/static/json_schema.json @@ -22,7 +22,6 @@ "drive_id": { "type": "string", "title": "Drive ID", - "format": "password", "description": "Specific Drive/Document Library ID. Leave empty to use the default drive." }, "auth_type": { @@ -64,8 +63,7 @@ "user_email": { "type": "string", "title": "User Email", - "format": "password", - "description": "User's email address. Required ONLY for OneDrive with Client Credentials (not needed for SharePoint).", + "description": "Required only to access OneDrive with Client Credentials (e.g., user@company.com). Leave empty when accessing a SharePoint site via Site URL.", "examples": [ "user@company.onmicrosoft.com", "user@company.com"