-
Notifications
You must be signed in to change notification settings - Fork 494
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c89c2d6
commit 0566abc
Showing
9 changed files
with
168 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
`cloudsync` plugin: Cloud Sync | ||
============================== | ||
|
||
.. contents:: Table of Contents | ||
:depth: 3 | ||
|
||
OAuth | ||
----- | ||
|
||
Some cloud providers offer the option to configure access using the standard OAuth flow through the user's browser. | ||
The process works as follows: | ||
|
||
* The UI opens a pop-up window with the URL: `https://truenas.com/oauth/<provider>?origin=<NAS IP>` | ||
* The `truenas.com` web server proxies this request to an installation of the | ||
`oauth-portal <https://github.com/ixsystems/oauth-portal>`_. | ||
* The OAuth portal forwards the request to the corresponding OAuth provider, retrieves the tokens, and returns them to | ||
the UI using `window.opener.postMessage`. | ||
* The UI receives the tokens and populates the corresponding Cloud Credentials configuration form. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,5 @@ Middleware Plugins | |
:caption: Contents: | ||
|
||
alert.rst | ||
cloudsync.rst | ||
migration.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
Simulating real-world conditions | ||
Simulating Real-World Conditions | ||
================================ | ||
|
||
.. toctree:: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import json | ||
|
||
import requests | ||
|
||
from middlewared.api import api_method | ||
from middlewared.api.current import CloudSyncOneDriveListDrivesArgs, CloudSyncOneDriveListDrivesResult | ||
from middlewared.rclone.base import BaseRcloneRemote | ||
from middlewared.utils.microsoft import get_microsoft_access_token | ||
|
||
DRIVES_TYPES = { | ||
"PERSONAL": "personal", | ||
"BUSINESS": "business", | ||
"DOCUMENT_LIBRARY": "documentLibrary", | ||
} | ||
DRIVES_TYPES_INV = {v: k for k, v in DRIVES_TYPES.items()} | ||
|
||
|
||
class OneDriveRcloneRemote(BaseRcloneRemote): | ||
name = "ONEDRIVE" | ||
title = "Microsoft OneDrive" | ||
|
||
rclone_type = "onedrive" | ||
|
||
credentials_oauth = True | ||
refresh_credentials = ["token"] | ||
|
||
extra_methods = ["list_drives"] | ||
|
||
async def get_task_extra(self, task): | ||
return { | ||
"drive_type": DRIVES_TYPES.get(task["credentials"]["attributes"]["drive_type"], ""), | ||
# Subject to change as Microsoft changes rate limits; please watch `forum.rclone.org` | ||
"checkers": "1", | ||
"tpslimit": "10", | ||
} | ||
|
||
@api_method(CloudSyncOneDriveListDrivesArgs, CloudSyncOneDriveListDrivesResult, roles=["CLOUD_SYNC_WRITE"]) | ||
def list_drives(self, credentials): | ||
""" | ||
Lists all available drives and their types for given Microsoft OneDrive credentials. | ||
""" | ||
self.middleware.call_sync("network.general.will_perform_activity", "cloud_sync") | ||
|
||
if not credentials["client_id"]: | ||
credentials["client_id"] = "b15665d9-eda6-4092-8539-0eec376afd59" | ||
if not credentials["client_secret"]: | ||
credentials["client_secret"] = "qtyfaBBYA403=unZUP40~_#" | ||
|
||
token = json.loads(credentials["token"]) | ||
|
||
r = requests.get( | ||
"https://graph.microsoft.com/v1.0/me/drives", | ||
headers={"Authorization": f"Bearer {token['access_token']}"}, | ||
timeout=10, | ||
) | ||
if r.status_code == 401: | ||
token = get_microsoft_access_token( | ||
credentials["client_id"], | ||
credentials["client_secret"], | ||
token["refresh_token"], | ||
"Files.Read Files.ReadWrite Files.Read.All Files.ReadWrite.All Sites.Read.All offline_access", | ||
) | ||
r = requests.get( | ||
"https://graph.microsoft.com/v1.0/me/drives", | ||
headers={"Authorization": f"Bearer {token['access_token']}"}, | ||
timeout=10, | ||
) | ||
r.raise_for_status() | ||
|
||
def process_drive(drive): | ||
return { | ||
"drive_type": DRIVES_TYPES_INV.get(drive["driveType"], ""), | ||
"drive_id": drive["id"], | ||
} | ||
|
||
result = [] | ||
for drive in r.json()["value"]: | ||
result.append(process_drive(drive)) | ||
# Also call /me/drive as sometimes /me/drives doesn't return it | ||
# see https://github.com/rclone/rclone/issues/4068 | ||
r = requests.get( | ||
"https://graph.microsoft.com/v1.0/me/drive", | ||
headers={"Authorization": f"Bearer {token['access_token']}"}, | ||
timeout=10, | ||
) | ||
r.raise_for_status() | ||
me_drive = process_drive(r.json()) | ||
if me_drive not in result: | ||
result.insert(0, me_drive) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import requests | ||
|
||
|
||
def get_microsoft_access_token(client_id: str, client_secret: str, refresh_token: str, scope: str) -> dict: | ||
r = requests.post( | ||
"https://login.microsoftonline.com/common/oauth2/v2.0/token", | ||
data={ | ||
"grant_type": "refresh_token", | ||
"client_id": client_id, | ||
"client_secret": client_secret, | ||
"refresh_token": refresh_token, | ||
"scope": scope, | ||
}, | ||
timeout=10, | ||
) | ||
r.raise_for_status() | ||
return r.json() |