Skip to content

Commit

Permalink
NXDRIVE-2901: Authorization Error for OAuth (#4616)
Browse files Browse the repository at this point in the history
* NXDRIVE-2901: Authorization Error for OAuth
  • Loading branch information
gitofanindya authored Apr 3, 2024
1 parent bf8008c commit 74fc14e
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/changes/5.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Release date: `2024-xx-xx`
## Core

- [NXDRIVE-2882](https://jira.nuxeo.com/browse/NXDRIVE-2882): fix_db should create dump.sql in same dir as db
- [NXDRIVE-2901](https://jira.nuxeo.com/browse/NXDRIVE-2901): Authorization Error for OAuth
- [NXDRIVE-2](https://jira.nuxeo.com/browse/NXDRIVE-2):

### Direct Edit
Expand Down
6 changes: 4 additions & 2 deletions nxdrive/auth/oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ class OAuthentication(Authentication):
def __init__(self, *args: Any, dao: "BaseDAO" = None, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)

self.verification_needed = get_verify()
self._dao = dao
subclient_kwargs = kwargs.get("subclient_kwargs", {})
subclient_kwargs["verify"] = self.verification_needed
self.auth = OAuth2(
self.url,
client_id=Options.oauth2_client_id,
Expand All @@ -28,7 +31,7 @@ def __init__(self, *args: Any, dao: "BaseDAO" = None, **kwargs: Any) -> None:
redirect_uri=Options.oauth2_redirect_uri,
token_endpoint=Options.oauth2_token_endpoint,
token=self.token,
subclient_kwargs=kwargs.get("subclient_kwargs"),
subclient_kwargs=subclient_kwargs,
)

def connect_url(self) -> str:
Expand All @@ -49,7 +52,6 @@ def get_token(self, **kwargs: Any) -> "Token":
code_verifier=kwargs["code_verifier"],
code=kwargs["code"],
state=kwargs["state"],
verify=get_verify(),
)

self.token = token
Expand Down
24 changes: 23 additions & 1 deletion nxdrive/client/remote_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
from ..qt.imports import QApplication
from ..utils import (
compute_digest,
encrypt,
force_decode,
get_current_locale,
get_verify,
lock_path,
Expand Down Expand Up @@ -127,6 +129,8 @@ def __init__(
f"SSL verify: {verify}-> will be changed to {self.verification_needed}"
)

self.token = token

super().__init__(
auth=auth,
host=url,
Expand Down Expand Up @@ -289,12 +293,30 @@ def execute(self, /, **kwargs: Any) -> Any:
"""
# Unauthorized and Forbidden exceptions are handled by the Python client.
try:
return self.operations.execute(ssl_verify=Options.ssl_no_verify, **kwargs)
resp = self.operations.execute(ssl_verify=Options.ssl_no_verify, **kwargs)
if self.token and self.auth:
auth_token = self.auth.auth.token
if self.token != auth_token and self.dao:
self._store_token(auth_token)
self.token = auth_token

return resp
except HTTPError as e:
if e.status == requests.codes.not_found:
raise NotFound("Response code not found")
raise e

def _store_token(self, auth_token: Any) -> None:
remote_user = self.dao.get_config("remote_user")
server_url = self.dao.get_config("server_url")
key = f"{remote_user}{server_url}"
stored_token = (
json.dumps(auth_token) if isinstance(auth_token, dict) else auth_token
)
secure_token = force_decode(encrypt(stored_token, key))
self.dao.update_config("remote_token", secure_token)
log.info("Token Stored Successfully")

@staticmethod
def escape(path: str, /) -> str:
"""Escape any problematic character for a NXQL query.
Expand Down
4 changes: 2 additions & 2 deletions nxdrive/direct_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from nuxeo.models import Blob
from requests import codes
from watchdog.events import FileSystemEvent
from watchdog.observers import Observer
from watchdog.observers import Observer, api

from .client.local import LocalClient
from .client.remote_client import Remote
Expand Down Expand Up @@ -96,7 +96,7 @@ def __init__(self, manager: "Manager", folder: Path, /) -> None:

self._event_handler: Optional[DriveFSEventHandler] = None
self._metrics = {"edit_files": 0}
self._observer: Observer = None
self._observer: api.BaseObserver = None
self.local = LocalClient(self._folder)
self._upload_queue: Queue = Queue()
self.is_already_locked = False
Expand Down
4 changes: 2 additions & 2 deletions nxdrive/engine/watcher/local_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple

from watchdog.events import FileSystemEvent, PatternMatchingEventHandler
from watchdog.observers import Observer
from watchdog.observers import Observer, api

from ...client.local import FileInfo
from ...constants import LINUX, MAC, ROOT, UNACCESSIBLE_HASH, WINDOWS
Expand Down Expand Up @@ -90,7 +90,7 @@ def __init__(self, engine: "Engine", dao: "EngineDAO", /) -> None:
}

self._event_handler: Optional[DriveFSEventHandler] = None
self._observer: Optional[Observer] = None
self._observer: api.BaseObserver = None
self._delete_events: Dict[str, Tuple[int, DocPair]] = {}
self._folder_scan_events: Dict[Path, Tuple[float, DocPair]] = {}

Expand Down
9 changes: 9 additions & 0 deletions tests/functional/test_oauth2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from nxdrive.auth import OAuthentication


def test_oauthentication(manager_factory, nuxeo_url):
manager, engine = manager_factory()
remote = engine.remote
dao = remote.dao
oauth = OAuthentication(nuxeo_url, dao=dao, device_id=None)
assert oauth
50 changes: 50 additions & 0 deletions tests/functional/test_remote_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,53 @@ def get_download_(*args, **kwargs):
with patch.object(remote.dao, "get_download", new=get_download_):
returned_val = remote.transfer_end_callback(obj1_)
assert not returned_val


def test_store_refresh_token(manager_factory):
manager, engine = manager_factory()
remote = engine.remote
remote.token = {
"access_token": "D0QCbs1aJJsPDXzT\
1IrC4oKzjbFevn4s",
"refresh_token": "Fch4TbOM8okl8sLajlN\
37L8YHKMSfc9cFe7RMVWRG4ctNvBmSvn2SFXg5CtUJKS2",
"token_type": "bearer",
"expires_in": 3239,
"expires_at": 1711427876,
}
remote.auth = Mock()
remote.auth.auth = Mock()
remote.auth.auth.token = remote.token
old_remote_token = remote.token
with manager:
remote.execute(command="UserWorkspace.Get")
assert old_remote_token == remote.token

remote.auth.auth.token = {
"access_token": "D0QCbs1aJJsPDXzT\
1IrC4oKzjbFevn4s",
"refresh_token": "Fch4TbOM8okl8sLajlP\
37L8YHKMSfc9cFe7RMVWRG4ctNvBmSvn2SFXg5CtUJKS2",
"token_type": "bearer",
"expires_in": 3239,
"expires_at": 1711427876,
}
old_remote_token = remote.token
with manager:
remote.execute(command="UserWorkspace.Get")
assert remote.token == remote.auth.auth.token

remote.auth.auth.token = {
"access_token": "D0QCbs1aJJsPDXzT\
1IrC4oKzjbFevn4s",
"refresh_token": "Fch4TbOM8okl8sLajlP\
37L8YHKMSfc9cFe7RMVWRG4ctNvBmSvn2SFXg5CtUJKS2",
"token_type": "bearer",
"expires_in": 3239,
"expires_at": 1711427876,
}
old_remote_token = remote.token
remote.dao = None
with manager:
remote.execute(command="UserWorkspace.Get")
assert remote.token == old_remote_token

0 comments on commit 74fc14e

Please sign in to comment.