Skip to content

Commit 6c5f543

Browse files
committed
implement user auth with app password in bearer
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
1 parent d99f46e commit 6c5f543

2 files changed

Lines changed: 23 additions & 6 deletions

File tree

appinfo/info.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Positive:
5050
<route>
5151
<url>mcp</url>
5252
<verb>POST,GET,DELETE</verb>
53-
<access_level>PUBLIC</access_level>
53+
<access_level>USER</access_level>
5454
<headers_to_exclude>[]</headers_to_exclude>
5555
</route>
5656
</routes>

ex_app/lib/mcp_server.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,32 @@
99
from fastmcp.tools import Tool
1010
from mcp import types as mt
1111
from ex_app.lib.tools import get_tools
12+
import requests
13+
14+
def get_user(authorization_header: str, nc: NextcloudApp) -> str:
15+
print(f"http://{nc.app_cfg.endpoint}/ocs/v2.php/cloud/user")
16+
response = requests.get(
17+
f"{nc.app_cfg.endpoint}/ocs/v2.php/cloud/user",
18+
headers={
19+
"Accept": "application/json",
20+
"Ocs-Apirequest": "1",
21+
"Authorization": authorization_header,
22+
},
23+
)
24+
if response.status_code != 200:
25+
raise Exception("Failed to get user info")
26+
return response.json()["ocs"]["data"]["id"]
27+
1228

1329
class UserAuthMiddleware(Middleware):
1430
async def on_message(self, context: MiddlewareContext, call_next):
1531
# Middleware stores user info in context state
16-
user = context.fastmcp_context.request_context.request.headers.get("Authorization")
17-
if user is None:
32+
authorization_header = context.fastmcp_context.request_context.request.headers.get("Authorization")
33+
if authorization_header is None:
1834
raise Exception("Authorization header is missing/invalid")
19-
if user.startswith("Bearer "):
20-
user = user[len("Bearer "):]
2135
nc = NextcloudApp()
36+
user = get_user(authorization_header, nc)
37+
print(user)
2238
nc.set_user(user)
2339
context.fastmcp_context.set_state("nextcloud", nc)
2440
return await call_next(context)
@@ -57,7 +73,8 @@ async def wrapper(*args, **kwargs):
5773
ctx = get_context()
5874
nc = ctx.get_state('nextcloud')
5975
safe, dangerous = await get_tools(nc)
60-
for t in safe + dangerous:
76+
tools = safe + dangerous
77+
for t in tools:
6178
if hasattr(t, "func") and t.func and t.name == tool.__name__:
6279
return t.func(*args, **kwargs)
6380
raise RuntimeError("Tool not found")

0 commit comments

Comments
 (0)