From f5ee91aeb3756b824aea32db8bfe72f8d4bb8604 Mon Sep 17 00:00:00 2001
From: Kyle Klaus <kklaus@indemnity83.com>
Date: Mon, 13 Apr 2020 23:31:44 -0700
Subject: [PATCH] write access list to proxy host config

---
 backend/internal/access-list.js      | 10 +++++-----
 backend/internal/proxy-host.js       |  6 +++---
 backend/models/access_list.js        |  4 ++++
 backend/models/access_list_client.js |  4 ++++
 backend/templates/proxy_host.conf    | 16 +++++++++++++---
 5 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js
index a640c1e..6de3310 100644
--- a/backend/internal/access-list.js
+++ b/backend/internal/access-list.js
@@ -71,7 +71,7 @@ const internalAccessList = {
 				// re-fetch with expansions
 				return internalAccessList.get(access, {
 					id:     data.id,
-					expand: ['owner', 'items', 'clients']
+					expand: ['owner', 'items', 'clients', 'proxy_hosts.access_list.clients']
 				}, true /* <- skip masking */);
 			})
 			.then((row) => {
@@ -81,7 +81,7 @@ const internalAccessList = {
 				return internalAccessList.build(row)
 					.then(() => {
 						if (row.proxy_host_count) {
-							return internalNginx.reload();
+							return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts);
 						}
 					})
 					.then(() => {
@@ -216,14 +216,14 @@ const internalAccessList = {
 				// re-fetch with expansions
 				return internalAccessList.get(access, {
 					id:     data.id,
-					expand: ['owner', 'items', 'clients']
+					expand: ['owner', 'items', 'clients', 'proxy_hosts.access_list.clients']
 				}, true /* <- skip masking */);
 			})
 			.then((row) => {
 				return internalAccessList.build(row)
 					.then(() => {
 						if (row.proxy_host_count) {
-							return internalNginx.reload();
+							return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts);
 						}
 					})
 					.then(() => {
@@ -254,7 +254,7 @@ const internalAccessList = {
 					.joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0')
 					.where('access_list.is_deleted', 0)
 					.andWhere('access_list.id', data.id)
-					.allowEager('[owner,items,clients,proxy_hosts]')
+					.allowEager('[owner,items,clients,proxy_hosts,proxy_hosts.access_list.clients]')
 					.omit(['access_list.is_deleted'])
 					.first();
 
diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js
index 0e9ced9..c27d0dd 100644
--- a/backend/internal/proxy-host.js
+++ b/backend/internal/proxy-host.js
@@ -73,7 +73,7 @@ const internalProxyHost = {
 				// re-fetch with cert
 				return internalProxyHost.get(access, {
 					id:     row.id,
-					expand: ['certificate', 'owner', 'access_list']
+					expand: ['certificate', 'owner', 'access_list.clients']
 				});
 			})
 			.then((row) => {
@@ -186,7 +186,7 @@ const internalProxyHost = {
 			.then(() => {
 				return internalProxyHost.get(access, {
 					id:     data.id,
-					expand: ['owner', 'certificate', 'access_list']
+					expand: ['owner', 'certificate', 'access_list.clients']
 				})
 					.then((row) => {
 						// Configure nginx
@@ -219,7 +219,7 @@ const internalProxyHost = {
 					.query()
 					.where('is_deleted', 0)
 					.andWhere('id', data.id)
-					.allowEager('[owner,access_list,certificate]')
+					.allowEager('[owner,access_list,access_list.clients,certificate]')
 					.first();
 
 				if (access_data.permission_visibility !== 'all') {
diff --git a/backend/models/access_list.js b/backend/models/access_list.js
index 43a2f12..482cfc4 100644
--- a/backend/models/access_list.js
+++ b/backend/models/access_list.js
@@ -88,6 +88,10 @@ class AccessList extends Model {
 			}
 		};
 	}
+
+	get satisfy() {
+		return this.satify_any ? 'satisfy any' : 'satisfy all';
+	}
 }
 
 module.exports = AccessList;
diff --git a/backend/models/access_list_client.js b/backend/models/access_list_client.js
index 1bee242..0386395 100644
--- a/backend/models/access_list_client.js
+++ b/backend/models/access_list_client.js
@@ -49,6 +49,10 @@ class AccessListClient extends Model {
 			}
 		};
 	}
+
+	get rule() {
+		return `${this.directive} ${this.address}`;
+	}
 }
 
 module.exports = AccessListClient;
diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf
index 6448dca..0da4bed 100644
--- a/backend/templates/proxy_host.conf
+++ b/backend/templates/proxy_host.conf
@@ -21,11 +21,21 @@ server {
 {% if use_default_location %}
 
   location / {
-    {%- if access_list_id > 0 -%}
-    # Access List
+
+    {% if access_list_id > 0 %}
+    # Authorization
     auth_basic            "Authorization required";
     auth_basic_user_file  /data/access/{{ access_list_id }};
-    {%- endif %}
+
+    # Access Rules
+    {% for client in access_list.clients %}
+    {{- client.rule -}};
+    {% endfor %}deny all;
+
+    # Access checks must...
+    {{ access_list.satisfy }};
+
+    {% endif %}
 
 {% include "_forced_ssl.conf" %}
 {% include "_hsts.conf" %}