From 950c3694559d6b35c23a980d6e8e1140135b6427 Mon Sep 17 00:00:00 2001 From: cellarspoon Date: Mon, 10 Jan 2022 16:20:47 +0100 Subject: [PATCH] feat: resource map --- .drone.yml | 1 + .env.sample | 4 ++++ compose.yml | 5 +++++ entrypoint.sh.tmpl | 4 ++-- makefile | 7 +------ members_lumbung_space/config.py | 5 +++++ members_lumbung_space/dependencies.py | 9 +++++++++ members_lumbung_space/main.py | 23 ++++++++-------------- members_lumbung_space/nextcloud.py | 20 +++++++++++++++++++ members_lumbung_space/redis.py | 9 +++++++++ members_lumbung_space/routes/root.py | 14 +++++++++++-- members_lumbung_space/templates/admin.html | 9 +++++++-- poetry.lock | 22 ++++++++++++++++++++- pyproject.toml | 1 + 14 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 members_lumbung_space/nextcloud.py diff --git a/.drone.yml b/.drone.yml index dba14a6..9ec0c2f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -32,6 +32,7 @@ steps: LETS_ENCRYPT_ENV: production SECRET_APP_SECRET_KEY_VERSION: v1 SECRET_KEYCLOAK_CLIENT_SECRET_VERSION: v1 + SECRET_NEXTCLOUD_APP_SECRET_VERSION: v1 STACK_NAME: members_lumbung_space trigger: branch: diff --git a/.env.sample b/.env.sample index 2b9079b..0ab8f22 100644 --- a/.env.sample +++ b/.env.sample @@ -9,9 +9,13 @@ KEYCLOAK_CLIENT_SECRET=barfoo KEYCLOAK_DOMAIN=login.lumbung.space KEYCLOAK_REALM=lumbung-space LETS_ENCRYPT_ENV=production +NEXTCLOUD_API_BASE_URL=cloud.lumbung.space +NEXTCLOUD_APP_PASSWORD=fizzbang +NEXTCLOUD_USER=decentral1se REDIS_DB=0 REDIS_HOST=localhost REDIS_PORT=6379 SECRET_APP_SECRET_KEY_VERSION=v1 SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1 +SECRET_NEXTCLOUD_APP_SECRET_VERSION=v1 STACK_NAME=foo_example_com diff --git a/compose.yml b/compose.yml index 8d4c291..94d73ee 100644 --- a/compose.yml +++ b/compose.yml @@ -13,12 +13,14 @@ services: - KEYCLOAK_CLIENT_SECRET_FILE=/run/secrets/keycloak_client_secret - KEYCLOAK_DOMAIN - KEYCLOAK_REALM + - NEXTCLOUD_APP_SECRET_FILE=/run/secrets/nextcloud_app_secret - REDIS_DB=0 - REDIS_HOST=cache - REDIS_PORT=6379 secrets: - app_secret_key - keycloak_client_secret + - nextcloud_app_secret networks: - proxy - internal @@ -72,6 +74,9 @@ secrets: keycloak_client_secret: external: true name: ${STACK_NAME}_keycloak_client_secret_${SECRET_KEYCLOAK_CLIENT_SECRET_VERSION} + nextcloud_app_secret: + external: true + name: ${STACK_NAME}_nextcloud_app_secret_${SECRET_NEXTCLOUD_APP_SECRET_VERSION} volumes: redis: diff --git a/entrypoint.sh.tmpl b/entrypoint.sh.tmpl index 9ad6599..7c3b79f 100644 --- a/entrypoint.sh.tmpl +++ b/entrypoint.sh.tmpl @@ -23,8 +23,8 @@ file_env() { unset "$fileVar" } -file_env "KEYCLOAK_CLIENT_SECRET" +file_end "NEXTCLOUD_APP_SECRET" file_env "APP_SECRET_KEY" +file_env "KEYCLOAK_CLIENT_SECRET" -echo "Passing it back to the upstream ENTRYPOINT/CMD..." exec "$@" diff --git a/makefile b/makefile index 916788c..d493c4f 100644 --- a/makefile +++ b/makefile @@ -3,12 +3,7 @@ .PHONY: run redis deploy run: - @if [ ! -d ".venv" ]; then \ - python3 -m venv .venv && \ - .venv/bin/pip install -U pip setuptools wheel poetry && \ - .venv/bin/poetry install; \ - fi - .venv/bin/poetry run uvicorn members_lumbung_space.main:app --reload + poetry run uvicorn members_lumbung_space.main:app --reload redis: @docker run -p 6379:6379 --name redis -d redis:6-alpine diff --git a/members_lumbung_space/config.py b/members_lumbung_space/config.py index 43e2806..0f12ec7 100644 --- a/members_lumbung_space/config.py +++ b/members_lumbung_space/config.py @@ -41,3 +41,8 @@ else: # Automatically log folks in or show the default log in page? AUTOMATICALLY_LOG_IN = environ.get("AUTOMATICALLY_LOG_IN", False) + +# Nextcloud integration +NEXTCLOUD_API_BASE_URL = environ.get("NEXTCLOUD_API_BASE_URL") +NEXTCLOUD_APP_PASSWORD = environ.get("NEXTCLOUD_APP_PASSWORD") +NEXTCLOUD_USER = environ.get("NEXTCLOUD_USER") diff --git a/members_lumbung_space/dependencies.py b/members_lumbung_space/dependencies.py index 439b772..95938d1 100644 --- a/members_lumbung_space/dependencies.py +++ b/members_lumbung_space/dependencies.py @@ -3,6 +3,7 @@ from datetime import datetime as dt from datetime import timedelta +import owncloud from fastapi import Depends, Request from humanize import naturaldelta @@ -38,6 +39,9 @@ async def get_invites(request: Request, user=Depends(get_user)): all_invites = {} for username in await request.app.state.redis.keys("*"): + if username == "resource_map": + continue + invites = await request.app.state.redis.get(username) for invite in invites: @@ -49,3 +53,8 @@ async def get_invites(request: Request, user=Depends(get_user)): all_invites[username] = invites return all_invites + + +async def get_resource_map(request: Request): + """Retrieve the resource map listing.""" + return await request.app.state.redis.get("resource_map") diff --git a/members_lumbung_space/main.py b/members_lumbung_space/main.py index c0f71f3..e924c70 100644 --- a/members_lumbung_space/main.py +++ b/members_lumbung_space/main.py @@ -13,23 +13,15 @@ from members_lumbung_space.config import ( APP_LOG_LEVEL, APP_SECRET_KEY, APP_THEME, - REDIS_DB, - REDIS_HOST, - REDIS_PORT, STATIC_DIR, TEMPLATE_DIR, ) from members_lumbung_space.exceptions import RequiresLoginException from members_lumbung_space.keycloak import init_keycloak +from members_lumbung_space.nextcloud import init_resource_map from members_lumbung_space.oidc import init_oidc -from members_lumbung_space.redis import Redis -from members_lumbung_space.routes import ( - health, - invite, - oidc, - register, - root, -) +from members_lumbung_space.redis import Redis, init_redis +from members_lumbung_space.routes import health, invite, oidc, register, root log = logging.getLogger("uvicorn") log.setLevel(APP_LOG_LEVEL) @@ -50,10 +42,11 @@ async def http_exception_handler(request, exc): @app.on_event("startup") async def startup_event(): - redis = Redis() - app.state.redis = await redis.create_pool( - f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}?encoding=utf-8" - ) + await init_redis(app) + log.info("Initialised redis connection") + + await init_resource_map(app) + log.info("Initialised the resource map") @app.on_event("shutdown") diff --git a/members_lumbung_space/nextcloud.py b/members_lumbung_space/nextcloud.py new file mode 100644 index 0000000..4f18cb1 --- /dev/null +++ b/members_lumbung_space/nextcloud.py @@ -0,0 +1,20 @@ +"""Nextcloud logic.""" + +import owncloud + + +async def init_resource_map(app): + """Initialise resource map listing.""" + from members_lumbung_space.config import ( + NEXTCLOUD_API_BASE_URL, + NEXTCLOUD_APP_PASSWORD, + NEXTCLOUD_USER, + ) + + nextcloud = owncloud.Client(f"https://{NEXTCLOUD_API_BASE_URL}") + nextcloud.login(NEXTCLOUD_USER, NEXTCLOUD_APP_PASSWORD) + + await app.state.redis.set( + "resource_map", + [f.get_name() for f in nextcloud.list("/", depth="infinity")], + ) diff --git a/members_lumbung_space/redis.py b/members_lumbung_space/redis.py index b5902e3..23b700a 100644 --- a/members_lumbung_space/redis.py +++ b/members_lumbung_space/redis.py @@ -5,6 +5,15 @@ import json from aioredis import create_redis_pool +async def init_redis(app): + from members_lumbung_space.config import REDIS_DB, REDIS_HOST, REDIS_PORT + + redis = Redis() + app.state.redis = await redis.create_pool( + f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}?encoding=utf-8" + ) + + class Redis: """Redis cache.""" diff --git a/members_lumbung_space/routes/root.py b/members_lumbung_space/routes/root.py index 98e28b7..16564f1 100644 --- a/members_lumbung_space/routes/root.py +++ b/members_lumbung_space/routes/root.py @@ -4,6 +4,7 @@ from fastapi import APIRouter, Depends, Request from members_lumbung_space.dependencies import ( get_invites, + get_resource_map, get_user, logged_in, ) @@ -13,9 +14,18 @@ router = APIRouter() @router.get("/", dependencies=[Depends(logged_in)]) async def home( - request: Request, user=Depends(get_user), invites=Depends(get_invites) + request: Request, + user=Depends(get_user), + invites=Depends(get_invites), + resource_map=Depends(get_resource_map), ): - context = {"request": request, "user": user, "invites": invites} + context = { + "request": request, + "user": user, + "invites": invites, + "resource_map": resource_map, + } + return request.app.state.templates.TemplateResponse( "admin.html", context=context ) diff --git a/members_lumbung_space/templates/admin.html b/members_lumbung_space/templates/admin.html index e244157..9b55dab 100644 --- a/members_lumbung_space/templates/admin.html +++ b/members_lumbung_space/templates/admin.html @@ -2,7 +2,6 @@ {% block content %}

Hello, {{ user.preferred_username }} 👋 - (logout)

@@ -43,8 +42,14 @@ {% endif %}

- Generate an invite link + Generate

+
+

Resource map

+

(i have no idea how to render this)

+

{{ resource_map }}
+
+ {% endblock %} diff --git a/poetry.lock b/poetry.lock index 739921f..006642f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -459,6 +459,25 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pyocclient" +version = "0.4" +description = "" +category = "main" +optional = false +python-versions = "*" +develop = false + +[package.dependencies] +requests = ">=2.0.1" +six = "*" + +[package.source] +type = "git" +url = "https://github.com/decentral1se/pyocclient.git" +reference = "patched-madcap-branch" +resolved_reference = "be63a32f520b887948f20ae57ca887d85555f720" + [[package]] name = "python-dotenv" version = "0.19.2" @@ -681,7 +700,7 @@ python-versions = ">=3.7" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "ecf2a823da9679d30575e15c6fcb2eac6f1d9c323870831ba8c2f1fdc47e4fd1" +content-hash = "0dc5935d876e202c05146d69858efaaf722d4a4ab91199b0634e40ef6cb209f3" [metadata.files] aiofiles = [ @@ -1055,6 +1074,7 @@ pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] +pyocclient = [] python-dotenv = [ {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, diff --git a/pyproject.toml b/pyproject.toml index 4191578..ce66328 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ python-multipart = "^0.0.5" python-keycloak = "^0.25.0" aiofiles = "^0.7.0" email-validator = "^1.1.3" +pyocclient = { git = "https://github.com/decentral1se/pyocclient.git", branch = "patched-madcap-branch" } [tool.poetry.dev-dependencies] black = "^21.6b0"