fix: onedrive orgs selection

This commit is contained in:
hurxxxx 2025-04-15 00:27:59 +09:00
parent 5fd794612e
commit 2d7062fc99
4 changed files with 56 additions and 34 deletions

View File

@ -1760,6 +1760,13 @@ ONEDRIVE_CLIENT_ID = PersistentConfig(
os.environ.get("ONEDRIVE_CLIENT_ID", ""),
)
ONEDRIVE_SHAREPOINT_URL = PersistentConfig(
"ONEDRIVE_SHAREPOINT_URL",
"onedrive.sharepoint_url",
os.environ.get("ONEDRIVE_SHAREPOINT_URL", ""),
)
# RAG Content Extraction
CONTENT_EXTRACTION_ENGINE = PersistentConfig(
"CONTENT_EXTRACTION_ENGINE",

View File

@ -100,6 +100,7 @@ from open_webui.config import (
# OpenAI
ENABLE_OPENAI_API,
ONEDRIVE_CLIENT_ID,
ONEDRIVE_SHAREPOINT_URL,
OPENAI_API_BASE_URLS,
OPENAI_API_KEYS,
OPENAI_API_CONFIGS,
@ -240,6 +241,7 @@ from open_webui.config import (
GOOGLE_DRIVE_CLIENT_ID,
GOOGLE_DRIVE_API_KEY,
ONEDRIVE_CLIENT_ID,
ONEDRIVE_SHAREPOINT_URL,
ENABLE_RAG_HYBRID_SEARCH,
ENABLE_RAG_LOCAL_WEB_FETCH,
ENABLE_WEB_LOADER_SSL_VERIFICATION,
@ -1327,7 +1329,10 @@ async def get_app_config(request: Request):
"client_id": GOOGLE_DRIVE_CLIENT_ID.value,
"api_key": GOOGLE_DRIVE_API_KEY.value,
},
"onedrive": {"client_id": ONEDRIVE_CLIENT_ID.value},
"onedrive": {
"client_id": ONEDRIVE_CLIENT_ID.value,
"sharepoint_url": ONEDRIVE_SHAREPOINT_URL.value,
},
"license_metadata": app.state.LICENSE_METADATA,
**(
{

View File

@ -1063,9 +1063,9 @@
);
}
}}
uploadOneDriveHandler={async () => {
uploadOneDriveHandler={async (authorityType) => {
try {
const fileData = await pickAndDownloadFile();
const fileData = await pickAndDownloadFile(authorityType);
if (fileData) {
const file = new File([fileData.blob], fileData.name, {
type: fileData.blob.type || 'application/octet-stream'

View File

@ -8,6 +8,7 @@ class OneDriveConfig {
private authorityType: 'personal' | 'organizations' = 'personal';
private sharepointUrl: string = '';
private msalInstance: PublicClientApplication | null = null;
private currentAuthorityType: 'personal' | 'organizations' = 'personal';
private constructor() {}
@ -18,20 +19,35 @@ class OneDriveConfig {
return OneDriveConfig.instance;
}
public async initialize(selectedAuthorityType?: 'personal' | 'organizations'): Promise<void> {
await this.getCredentials(selectedAuthorityType);
public async initialize(authorityType?: 'personal' | 'organizations'): Promise<void> {
if (authorityType && this.currentAuthorityType !== authorityType) {
console.log('Authority type changed, resetting msalInstance');
this.currentAuthorityType = authorityType;
this.msalInstance = null;
}
await this.getCredentials();
}
public async ensureInitialized(selectedAuthorityType?: 'personal' | 'organizations'): Promise<void> {
await this.initialize(selectedAuthorityType);
public async ensureInitialized(authorityType?: 'personal' | 'organizations'): Promise<void> {
await this.initialize(authorityType);
}
private async getCredentials(selectedAuthorityType?: 'personal' | 'organizations'): Promise<void> {
let response;
const headers: HeadersInit = {
'Content-Type': 'application/json'
};
if(window.location.hostname === 'localhost') {
response = await fetch('http://localhost:8080/api/config');
response = await fetch('http://localhost:8080/api/config', {
headers,
credentials: 'include'
});
} else {
response = await fetch('/api/config');
response = await fetch('/api/config', {
headers,
credentials: 'include'
});
}
if (!response.ok) {
@ -46,25 +62,16 @@ class OneDriveConfig {
if (!newClientId) {
throw new Error('OneDrive configuration is incomplete');
}
// Reset MSAL instance if config changes
if (this.clientId &&
(this.clientId !== newClientId ||
this.authorityType !== selectedAuthorityType ||
this.sharepointUrl !== newSharepointUrl)) {
this.msalInstance = null;
}
this.clientId = newClientId;
this.authorityType = selectedAuthorityType || 'personal';
this.sharepointUrl = newSharepointUrl;
}
public async getMsalInstance(): Promise<PublicClientApplication> {
await this.ensureInitialized();
public async getMsalInstance(authorityType?: 'personal' | 'organizations'): Promise<PublicClientApplication> {
await this.ensureInitialized(authorityType);
if (!this.msalInstance) {
const authorityEndpoint = this.authorityType === 'organizations' ? 'common' : 'consumers';
const authorityEndpoint = this.currentAuthorityType === 'organizations' ? 'common' : 'consumers';
const msalParams = {
auth: {
authority: `https://login.microsoftonline.com/${authorityEndpoint}`,
@ -82,7 +89,7 @@ class OneDriveConfig {
}
public getAuthorityType(): 'personal' | 'organizations' {
return this.authorityType;
return this.currentAuthorityType;
}
public getSharepointUrl(): string {
@ -90,7 +97,7 @@ class OneDriveConfig {
}
public getBaseUrl(): string {
if (this.authorityType === 'organizations') {
if (this.currentAuthorityType === 'organizations') {
if (!this.sharepointUrl || this.sharepointUrl === '') {
throw new Error('Sharepoint URL not configured');
}
@ -107,25 +114,27 @@ class OneDriveConfig {
// Retrieve OneDrive access token
async function getToken(resource?: string): Promise<string> {
async function getToken(resource?: string, authorityType?: 'personal' | 'organizations'): Promise<string> {
const config = OneDriveConfig.getInstance();
await config.ensureInitialized();
await config.ensureInitialized(authorityType);
const authorityType = config.getAuthorityType();
const currentAuthorityType = config.getAuthorityType();
const scopes = authorityType === 'organizations'
const scopes = currentAuthorityType === 'organizations'
? [`${resource || config.getBaseUrl()}/.default`]
: ['OneDrive.ReadWrite'];
console.log('scopes', scopes);
const authParams: PopupRequest = { scopes };
let accessToken = '';
try {
const msalInstance = await config.getMsalInstance();
const msalInstance = await config.getMsalInstance(authorityType);
const resp = await msalInstance.acquireTokenSilent(authParams);
accessToken = resp.accessToken;
} catch (err) {
const msalInstance = await config.getMsalInstance();
const msalInstance = await config.getMsalInstance(authorityType);
try {
const resp = await msalInstance.loginPopup(authParams);
msalInstance.setActiveAccount(resp.account);
@ -212,8 +221,8 @@ function getPickerParams(): {
}
// Download file from OneDrive
async function downloadOneDriveFile(fileInfo: Record<string, any>): Promise<Blob> {
const accessToken = await getToken();
async function downloadOneDriveFile(fileInfo: Record<string, any>, authorityType?: 'personal' | 'organizations'): Promise<Blob> {
const accessToken = await getToken(undefined, authorityType);
if (!accessToken) {
throw new Error('Unable to retrieve OneDrive access token.');
}
@ -409,7 +418,8 @@ export async function openOneDrivePicker(): Promise<PickerResult | null> {
}
// Pick and download file from OneDrive
export async function pickAndDownloadFile(authorityType: 'personal' | 'organizations' = 'personal'): Promise<{ blob: Blob; name: string } | null> {
export async function pickAndDownloadFile(authorityType?: 'personal' | 'organizations'): Promise<{ blob: Blob; name: string } | null> {
// Force reinitialization with selected authority type
const config = OneDriveConfig.getInstance();
await config.initialize(authorityType);
@ -420,7 +430,7 @@ export async function pickAndDownloadFile(authorityType: 'personal' | 'organizat
}
const selectedFile = pickerResult.items[0];
const blob = await downloadOneDriveFile(selectedFile);
const blob = await downloadOneDriveFile(selectedFile, authorityType);
return { blob, name: selectedFile.name };
}