changeset 2337:c6e86b74f62e

Add mod_http_authentication.lua
author JC Brand <jcbrand@minddistrict.com>
date Mon, 17 Oct 2016 13:03:38 +0000
parents 79432b859d21
children 51beecac93c2
files mod_http_authentication/README.markdown mod_http_authentication/mod_http_authentication.lua
diffstat 2 files changed, 54 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_http_authentication/README.markdown	Mon Oct 17 13:03:38 2016 +0000
@@ -0,0 +1,29 @@
+---
+labels:
+- 'Stage-Beta'
+summary: Enforces HTTP Basic authentication across all HTTP endpoints served by Prosody
+...
+
+# mod_http_authentication
+
+This module enforces HTTP Basic authentication across all HTTP endpoints served by Prosody.
+
+## Configuration
+
+Name                             Default                          Description
+-------------------------------  -------------------------------  -----------------------------
+minddistrict_http_credentials    "minddistrict:secretpassword"    The credentials that HTTP clients must provide to access the HTTP interface. Should be a string with the syntax "username:password".
+unauthenticated_http_endpoints   { "/http-bind", "/http-bind/" }  A list of paths that should be excluded from authentication.
+
+## Usage
+
+This is a global module, so should be added to the global `modules_enabled` option in your config file. It applies to all HTTP virtual hosts.
+
+## Known issues
+
+The module use a new API in Prosody 0.10. This API currently has an open issue ([issue #554](https://prosody.im/issues/issue/554)) 
+that means this module cannot be unloaded dynamically at runtime. In practice this shouldn't be an issue, and we will resolve the problem inside Prosody in due course.
+
+## Details
+
+By Kim Alvefur \<zash@zash.se\>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_http_authentication/mod_http_authentication.lua	Mon Oct 17 13:03:38 2016 +0000
@@ -0,0 +1,25 @@
+
+module:set_global();
+
+local b64_decode = require "util.encodings".base64.decode;
+local server = require "net.http.server";
+
+local credentials = module:get_option_string("http_credentials", "username:secretpassword");
+local unauthed_endpoints = module:get_option_set("unauthenticated_http_endpoints", { "/http-bind", "/http-bind/" })._items;
+
+module:wrap_object_event(server._events, false, function (handlers, event_name, event_data)
+	local request = event_data.request;
+	if request and not unauthed_endpoints[request.path] then
+		local response = event_data.response;
+		local headers = request.headers;
+		if not headers.authorization then
+			response.headers.www_authenticate = ("Basic realm=%q"):format(module.host.."/"..module.name);
+			return 401;
+		end
+		local user_password = b64_decode(headers.authorization:match("%s(%S*)$"));
+		if user_password ~= credentials then
+			return 401;
+		end
+	end
+	return handlers(event_name, event_data);
+end);