changeset 3425:461429e0db58

mod_http_pep_avatar: Provides PEP avatars via HTTP
author Kim Alvefur <zash@zash.se>
date Thu, 03 Jan 2019 11:46:51 +0100
parents 6ae875c98daf
children f72aa8840042
files mod_http_pep_avatar/README.markdown mod_http_pep_avatar/mod_http_pep_avatar.lua
diffstat 2 files changed, 82 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_http_pep_avatar/README.markdown	Thu Jan 03 11:46:51 2019 +0100
@@ -0,0 +1,33 @@
+---
+summary: Serve PEP avatars from HTTP
+---
+
+# Introduction
+
+This module serves avatars from local users who have published
+[XEP-0084: User Avatar] via [PEP][doc:modules:mod_pep].
+
+# Configuring
+
+Simply load the module. Avatars are then available at
+http://<host>:5280/pep_avatar/<username>
+
+    modules_enabled = {
+        ...
+        "http_avatar";
+    }
+
+# Access
+
+Users must [configure] their Avatar PEP nodes to be public, otherwise
+access is denied.
+
+# Compatibility
+
+  ------- ---------------
+  trunk   Works
+  0.11    Works
+  0.10    Does not work
+  ------- ---------------
+
+[configure]: https://xmpp.org/extensions/xep-0060.html#owner-configure
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_http_pep_avatar/mod_http_pep_avatar.lua	Thu Jan 03 11:46:51 2019 +0100
@@ -0,0 +1,49 @@
+-- HTTP Access to PEP Avatar
+-- By Kim Alvefur <zash@zash.se>
+
+local mod_pep = module:depends"pep";
+
+local um = require "core.usermanager";
+local nodeprep = require "util.encodings".stringprep.nodeprep;
+local base64_decode = require "util.encodings".base64.decode;
+
+module:depends("http")
+module:provides("http", {
+	route = {
+		["GET /*"] = function (event, user)
+			local request, response = event.request, event.response;
+			local actor = request.ip;
+
+			user = nodeprep(user);
+			if not user then return 400; end
+			if not um.user_exists(user, module.host) then
+				return 404;
+			end
+
+			local pep_service = mod_pep.get_pep_service(user);
+
+			local ok, avatar_hash, avatar_meta = pep_service:get_last_item("urn:xmpp:avatar:metadata", actor);
+
+			if not ok or not avatar_hash then
+				return 404;
+			end
+
+			if avatar_hash == request.headers.if_none_match then
+				return 304;
+			end
+
+			local data_ok, avatar_data = pep_service:get_items("urn:xmpp:avatar:data", actor, avatar_hash);
+			if not data_ok or type(avatar_data) ~= "table" or not avatar_data[avatar_hash] then
+				return 404;
+			end
+
+			response.headers.etag = avatar_hash;
+
+			local info = avatar_meta.tags[1]:get_child("info");
+			response.headers.content_type = info and info.attr.type or "application/octet-stream";
+
+			local data = avatar_data[avatar_hash];
+			return base64_decode(data.tags[1]:get_text());
+		end;
+	}
+});