From 3711f10e5c49b40e2b180db9b1e65e842db24cb0 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sat, 14 Nov 2015 15:22:35 +0000
Subject: [PATCH] Add option to require login before viewing pages. Currently
 halfway through #38.

---
 build/index.php        | 27 ++++++++++++++++++++++++---
 core.php               | 21 +++++++++++++++++++--
 module_index.json      |  2 +-
 modules/page-login.php | 14 +++++++++++---
 settings.fragment.php  |  2 ++
 5 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/build/index.php b/build/index.php
index 173d926..3ebdc2c 100644
--- a/build/index.php
+++ b/build/index.php
@@ -109,6 +109,8 @@ $settings->users = [
 	"user" => "873ac9ffea4dd04fa719e8920cd6938f0c23cd678af330939cff53c3d2855f34" //cheese
 ];
 
+$settings->require_login_view = true;
+
 // Whether to use the new sha3 hashing algorithm that was standardised on the
 // 8th August 2015. Only works if you have strawbrary's sha3 extension
 // installed. Get it here: https://github.com/strawbrary/php-sha3
@@ -881,6 +883,7 @@ if(makepathsafe($_GET["page"]) !== $_GET["page"])
 	exit();
 }
 
+// Finish setting up the environment object
 $env->page = $_GET["page"];
 $env->action = strtolower($_GET["action"]);
 
@@ -1034,8 +1037,7 @@ class page_renderer
 	{
 		return self::render($title, $content, self::$minimal_content_template);
 	}
-
-
+    
 	public static function get_css_as_html()
 	{
 		global $settings;
@@ -1140,6 +1142,7 @@ class page_renderer
 //////////////////////////////////////
 ///// Extra consistency measures /////
 //////////////////////////////////////
+// Redirect to the search page if there isn't a page with the requested name
 if(!isset($pageindex->{$env->page}) and isset($_GET["search-redirect"]))
 {
 	http_response_code(307);
@@ -1148,6 +1151,22 @@ if(!isset($pageindex->{$env->page}) and isset($_GET["search-redirect"]))
 	exit(page_renderer::render("Non existent page - $settings->sitename", "<p>There isn't a page on $settings->sitename with that name. However, you could <a href='$url'>search for this page name</a> in other pages.</p>
 		<p>Alternatively, you could <a href='?action=edit&page=" . rawurlencode($env->page) . "&create=true'>create this page</a>.</p>"));
 }
+
+// Redirect the user to the login page if:
+//  - A login is required to view this wiki
+//  - The user isn't already requesting the login page
+// Note we use $_GET here because $env->action isn't populated at this point
+if($settings->require_login_view === true && // If this site requires a login in order to view pages
+   !$env->is_logged_in && // And the user isn't logged in
+   $_GET["action"] !== "login") // And the user isn't requesting the login page
+{
+    // Redirect the user to the login page
+    http_response_code(307);
+    $url = "?action=login&returnto=" . rawurlencode($_SERVER["REQUEST_URI"]) . "&required=true";
+    header("location: $url");
+    exit(page_renderer::render("Login required - $settings->sitename", "<p>$settings->sitename requires that you login before you are able to access it.</p>
+        <p><a href='$url'>Login</a>.</p>"));
+}
 //////////////////////////////////////
 //////////////////////////////////////
 
@@ -2839,6 +2858,8 @@ register_module([
 			$content = "<h1>Login to $settings->sitename</h1>\n";
 			if(isset($_GET["failed"]))
 				$content .= "\t\t<p><em>Login failed.</em></p>\n";
+			if(isset($_GET["required"]))
+				$content .= "\t\t<p><em>$settings->sitename requires that you login before continuing.</em></p>\n";
 			$content .= "\t\t<form method='post' action='index.php?action=checklogin&returnto=" . rawurlencode($_SERVER['REQUEST_URI']) . "'>
 				<label for='user'>Username:</label>
 				<input type='text' name='user' id='user' />
@@ -2847,7 +2868,7 @@ register_module([
 				<input type='password' name='pass' id='pass' />
 				<br />
 				<input type='submit' value='Login' />
-			</form>";
+			</form>\n";
 			exit(page_renderer::render_main($title, $content));
 		});
 		
diff --git a/core.php b/core.php
index 174212d..98aba4e 100644
--- a/core.php
+++ b/core.php
@@ -543,6 +543,7 @@ if(makepathsafe($_GET["page"]) !== $_GET["page"])
 	exit();
 }
 
+// Finish setting up the environment object
 $env->page = $_GET["page"];
 $env->action = strtolower($_GET["action"]);
 
@@ -696,8 +697,7 @@ class page_renderer
 	{
 		return self::render($title, $content, self::$minimal_content_template);
 	}
-
-
+    
 	public static function get_css_as_html()
 	{
 		global $settings;
@@ -802,6 +802,7 @@ class page_renderer
 //////////////////////////////////////
 ///// Extra consistency measures /////
 //////////////////////////////////////
+// Redirect to the search page if there isn't a page with the requested name
 if(!isset($pageindex->{$env->page}) and isset($_GET["search-redirect"]))
 {
 	http_response_code(307);
@@ -810,6 +811,22 @@ if(!isset($pageindex->{$env->page}) and isset($_GET["search-redirect"]))
 	exit(page_renderer::render("Non existent page - $settings->sitename", "<p>There isn't a page on $settings->sitename with that name. However, you could <a href='$url'>search for this page name</a> in other pages.</p>
 		<p>Alternatively, you could <a href='?action=edit&page=" . rawurlencode($env->page) . "&create=true'>create this page</a>.</p>"));
 }
+
+// Redirect the user to the login page if:
+//  - A login is required to view this wiki
+//  - The user isn't already requesting the login page
+// Note we use $_GET here because $env->action isn't populated at this point
+if($settings->require_login_view === true && // If this site requires a login in order to view pages
+   !$env->is_logged_in && // And the user isn't logged in
+   $_GET["action"] !== "login") // And the user isn't requesting the login page
+{
+    // Redirect the user to the login page
+    http_response_code(307);
+    $url = "?action=login&returnto=" . rawurlencode($_SERVER["REQUEST_URI"]) . "&required=true";
+    header("location: $url");
+    exit(page_renderer::render("Login required - $settings->sitename", "<p>$settings->sitename requires that you login before you are able to access it.</p>
+        <p><a href='$url'>Login</a>.</p>"));
+}
 //////////////////////////////////////
 //////////////////////////////////////
 
diff --git a/module_index.json b/module_index.json
index 434f091..f2c6080 100644
--- a/module_index.json
+++ b/module_index.json
@@ -122,7 +122,7 @@
         "author": "Starbeamrainbowlabs",
         "description": "Adds a pair of actions (login and checklogin) that allow users to login. You need this one if you want your users to be able to login.",
         "id": "page-login",
-        "lastupdate": 1445170746,
+        "lastupdate": 1447514093,
         "optional": false
     },
     {
diff --git a/modules/page-login.php b/modules/page-login.php
index 745dd8e..29a7f09 100644
--- a/modules/page-login.php
+++ b/modules/page-login.php
@@ -16,11 +16,19 @@ register_module([
 		 */
 		add_action("login", function() {
 			global $settings;
+			
+			// Build the action url that will actually perform the login
+			$login_form_action_url = "index.php?action=checklogin"
+			if(isset($_GET["returnto"]))
+				$login_form_action_url .= "&returnto=" . rawurlencode($_SERVER['REQUEST_URI']);
+			
 			$title = "Login to $settings->sitename";
 			$content = "<h1>Login to $settings->sitename</h1>\n";
 			if(isset($_GET["failed"]))
 				$content .= "\t\t<p><em>Login failed.</em></p>\n";
-			$content .= "\t\t<form method='post' action='index.php?action=checklogin&returnto=" . rawurlencode($_SERVER['REQUEST_URI']) . "'>
+			if(isset($_GET["required"]))
+				$content .= "\t\t<p><em>$settings->sitename requires that you login before continuing.</em></p>\n";
+			$content .= "\t\t<form method='post' action='$login_form_action_url'>
 				<label for='user'>Username:</label>
 				<input type='text' name='user' id='user' />
 				<br />
@@ -28,7 +36,7 @@ register_module([
 				<input type='password' name='pass' id='pass' />
 				<br />
 				<input type='submit' value='Login' />
-			</form>";
+			</form>\n";
 			exit(page_renderer::render_main($title, $content));
 		});
 		
@@ -58,7 +66,7 @@ register_module([
 					$_SESSION["$settings->sessionprefix-expiretime"] = $expiretime;
 					//redirect to wherever the user was going
 					http_response_code(302);
-					if(isset($_POST["goto"]))
+					if(isset($_POST["returnto"]))
 						header("location: " . $_POST["returnto"]);
 					else
 						header("location: index.php");
diff --git a/settings.fragment.php b/settings.fragment.php
index 0f4d8ff..420cf85 100644
--- a/settings.fragment.php
+++ b/settings.fragment.php
@@ -98,6 +98,8 @@ $settings->users = [
 	"user" => "873ac9ffea4dd04fa719e8920cd6938f0c23cd678af330939cff53c3d2855f34" //cheese
 ];
 
+$settings->require_login_view = true;
+
 // Whether to use the new sha3 hashing algorithm that was standardised on the
 // 8th August 2015. Only works if you have strawbrary's sha3 extension
 // installed. Get it here: https://github.com/strawbrary/php-sha3
