changeset 1608:f7e3adae4907

add BasicAuthHandler
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 01 May 2021 19:52:56 -0600
parents fa066aaa068c
children 268b2a26e8d7
files src/goodjava/webserver/Status.java src/goodjava/webserver/handlers/BasicAuthHandler.java src/goodjava/webserver/handlers/RegexHandler.java src/luan/host/WebHandler.java
diffstat 4 files changed, 85 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
diff -r fa066aaa068c -r f7e3adae4907 src/goodjava/webserver/Status.java
--- a/src/goodjava/webserver/Status.java	Fri Apr 30 20:23:28 2021 -0600
+++ b/src/goodjava/webserver/Status.java	Sat May 01 19:52:56 2021 -0600
@@ -39,6 +39,7 @@
 	public static final Status FOUND = newStatus(302,"Found");
 	public static final Status NOT_MODIFIED = newStatus(304,"Not Modified");
 	public static final Status BAD_REQUEST = newStatus(400,"Bad Request");
+	public static final Status UNAUTHORIZED = newStatus(401,"Unauthorized");
 	public static final Status NOT_FOUND = newStatus(404,"Not Found");
 	public static final Status INTERNAL_SERVER_ERROR = newStatus(500,"Internal Server Error");
 }
diff -r fa066aaa068c -r f7e3adae4907 src/goodjava/webserver/handlers/BasicAuthHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/webserver/handlers/BasicAuthHandler.java	Sat May 01 19:52:56 2021 -0600
@@ -0,0 +1,39 @@
+package goodjava.webserver.handlers;
+
+import goodjava.util.GoodUtils;
+import goodjava.webserver.Handler;
+import goodjava.webserver.Request;
+import goodjava.webserver.Response;
+import goodjava.webserver.Status;
+
+
+public class BasicAuthHandler implements Handler {
+	private final Handler handler;
+	private final String realm;
+	private final String match;
+
+	public BasicAuthHandler(Handler handler,String realm,String username,String password) {
+		this.handler = handler;
+		this.realm = realm;
+		this.match = GoodUtils.base64Encode(username+":"+password);
+	}
+
+	private Response unauthorized() {
+		Response response = new Response();
+		response.status = Status.UNAUTHORIZED;
+		response.headers.put("WWW-Authenticate","Basic realm=\""+realm+"\"");
+		return response;
+	}
+
+	public Response handle(Request request) {
+		String auth = (String)request.headers.get("Authorization");
+		if( auth==null )
+			return unauthorized();
+		String[] a = auth.split(" ");
+		if( a.length!=2 || !a[0].equals("Basic") || !a[1].equals(match) )
+			return unauthorized();
+		Response response = handler.handle(request);
+		response.headers.put("X-Accel-Expires","0");
+		return response;
+	}
+}
diff -r fa066aaa068c -r f7e3adae4907 src/goodjava/webserver/handlers/RegexHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/webserver/handlers/RegexHandler.java	Sat May 01 19:52:56 2021 -0600
@@ -0,0 +1,27 @@
+package goodjava.webserver.handlers;
+
+import java.util.regex.Pattern;
+import goodjava.webserver.Handler;
+import goodjava.webserver.Request;
+import goodjava.webserver.Response;
+
+
+public final class RegexHandler implements Handler {
+	private final Pattern ptn;
+	private final Handler ifMatch;
+	private final Handler ifNotMatch;
+
+	public RegexHandler(Pattern ptn,Handler ifMatch,Handler ifNotMatch) {
+		this.ptn = ptn;
+		this.ifMatch = ifMatch;
+		this.ifNotMatch = ifNotMatch;
+	}
+
+	public RegexHandler(String ptn,Handler ifMatch,Handler ifNotMatch) {
+		this(Pattern.compile(ptn),ifMatch,ifNotMatch);
+	}
+
+	public Response handle(Request request) {
+		return ptn.matcher(request.path).find() ? ifMatch.handle(request) : ifNotMatch.handle(request);
+	}
+}
diff -r fa066aaa068c -r f7e3adae4907 src/luan/host/WebHandler.java
--- a/src/luan/host/WebHandler.java	Fri Apr 30 20:23:28 2021 -0600
+++ b/src/luan/host/WebHandler.java	Sat May 01 19:52:56 2021 -0600
@@ -17,6 +17,8 @@
 import goodjava.webserver.handlers.FileHandler;
 import goodjava.webserver.handlers.DirHandler;
 import goodjava.webserver.handlers.HeadersHandler;
+import goodjava.webserver.handlers.BasicAuthHandler;
+import goodjava.webserver.handlers.RegexHandler;
 import luan.Luan;
 import luan.LuanException;
 import luan.LuanTable;
@@ -61,7 +63,20 @@
 			}
 
 			Luan luan = new Luan();
-			initLuan(luan,dirStr,domain);
+			String password;
+			LuanLogger.startThreadLogging(luan);
+			try {
+				LuanFunction fn = Luan.loadClasspath(luan,"luan/host/init.luan");
+				fn.call(luan,dirStr,domain);
+				LuanTable Io = (LuanTable)luan.require("luan:Io.luan");
+				password = (String)Io.get(luan,"password");
+				if( password==null )  throw new NullPointerException();
+			} catch(LuanException e) {
+				throw new LuanRuntimeException(e);
+			} finally {
+				LuanLogger.endThreadLogging();
+			}
+			security(luan,dirStr);
 			LuanHandler luanHandler = new LuanHandler(luan,domain);
 
 			FileHandler fileHandler = new FileHandler(dirStr+"/site/");
@@ -72,6 +87,8 @@
 			Handler notFoundHander = new NotFound(luanHandler);
 			notFoundHander = new ContentTypeHandler(notFoundHander);
 			handler = new ListHandler( handler, dirHandler, notFoundHander );
+			Handler auth = new BasicAuthHandler(handler,"Private","admin",password);
+			handler = new RegexHandler("^/private/",auth,handler);
 			handler = new HeadersHandler(handler);
 			handler = new SafeHandler(handler);
 			handler = new LogHandler(handler,LogHandler.dirLogger(new File(logDir),days30));
@@ -102,19 +119,6 @@
 		return handler.luanHandler.call_rpc(fnName,args);
 	}
 
-	private static void initLuan(Luan luan,String dir,String domain) {
-		LuanLogger.startThreadLogging(luan);
-		try {
-			LuanFunction fn = Luan.loadClasspath(luan,"luan/host/init.luan");
-			fn.call(luan,dir,domain);
-		} catch(LuanException e) {
-			throw new LuanRuntimeException(e);
-		} finally {
-			LuanLogger.endThreadLogging();
-		}
-		security(luan,dir);
-	}
-
 	public static void removeHandler(String domain) {
 		domainHandler.removeHandler(domain);
 	}