Skip to content

Commit 2e63c71

Browse files
authored
Merge pull request #47 from HumanBrainProject/fix/seafile11-token-auth
Fix authentication for Seafile 11 by replacing Bearer tokens with Sea…
2 parents 67db940 + d7f99cf commit 2e63c71

1 file changed

Lines changed: 29 additions & 6 deletions

File tree

‎ebrains_drive/client.py‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ def put(self, *args, **kwargs):
7171
def delete(self, *args, **kwargs):
7272
return self.send_request("DELETE", *args, **kwargs)
7373

74+
def _exchange_oidc_for_seafile_token(self):
75+
url = self.server.rstrip("/") + "/api2/account/token/"
76+
headers = {"Authorization": f"Bearer {self._token}"}
77+
78+
resp = self.session.get(url, headers=headers)
79+
80+
if resp.status_code != 200:
81+
raise Exception(f"Failed to exchange OIDC token for Seafile token: {resp.status_code} {resp.text}")
82+
83+
self._seafile_token = resp.text.strip()
84+
return self._seafile_token
85+
7486
def send_request(self, method: str, url: str, *args, **kwargs):
7587
if not url.startswith("http"):
7688
# sanity checks.
@@ -82,21 +94,31 @@ def send_request(self, method: str, url: str, *args, **kwargs):
8294
# We cannot deepcopy the whole thing, because some values (e.g. BufferedReader objects)
8395
# cannot be pickled
8496
kwargs = copy(kwargs)
85-
headers = deepcopy(kwargs.get("headers", {}))
86-
headers.setdefault("Authorization", "Bearer " + self._token)
87-
kwargs["headers"] = headers
97+
headers = kwargs.pop("headers", {}).copy()
98+
99+
if self._seafile_token:
100+
headers.setdefault("Authorization", "Token " + self._seafile_token)
101+
else:
102+
headers.setdefault("Authorization", "Bearer " + self._token)
88103

89104
expected = kwargs.pop("expected", 200)
90105
if not hasattr(expected, "__iter__"):
91106
expected = (expected,)
92-
resp = self.session.request(method, url, *args, **kwargs)
107+
108+
resp = self.session.request(method, url, headers=headers, *args, **kwargs)
109+
110+
if resp.status_code == 401 and not self._seafile_token:
111+
self._seafile_token = self._exchange_oidc_for_seafile_token()
112+
113+
headers["Authorization"] = "Token " + self._seafile_token
114+
resp = self.session.request(method, url, headers=headers, *args, **kwargs)
115+
93116
if resp.status_code not in expected:
94-
msg = "Expected %s, but get %s" % (" or ".join(map(str, expected)), resp.status_code)
117+
msg = f"Expected {expected}, but got {resp.status_code}"
95118
raise ClientHttpError(resp.status_code, msg)
96119

97120
return resp
98121

99-
100122
class DriveApiClient(ClientBase):
101123
"""Wraps seafile web api"""
102124

@@ -110,6 +132,7 @@ def __init__(self, username=None, password=None, token=None, env=""):
110132
self.repos = Repos(self)
111133
self.groups = Groups(self)
112134
self.file = File(self)
135+
self._seafile_token = None
113136

114137
def _set_env(self, env=""):
115138
super()._set_env(env)

0 commit comments

Comments
 (0)