From 8e6f4ee3a95fbb6d4c5ae9b0a698c5fa3ea73cf4 Mon Sep 17 00:00:00 2001
From: John Estabrook <jestabro@vyos.io>
Date: Sun, 15 May 2022 13:28:06 -0500
Subject: graphql: T3993: use existing key auth from REST framework

---
 src/services/api/graphql/graphql/mutations.py          | 10 ++++++++++
 src/services/api/graphql/graphql/queries.py            | 10 ++++++++++
 .../api/graphql/graphql/schema/config_file.graphql     |  2 ++
 .../api/graphql/graphql/schema/dhcp_server.graphql     |  1 +
 .../api/graphql/graphql/schema/firewall_group.graphql  |  6 ++++++
 src/services/api/graphql/graphql/schema/image.graphql  |  2 ++
 .../graphql/graphql/schema/interface_ethernet.graphql  |  1 +
 src/services/api/graphql/graphql/schema/show.graphql   |  1 +
 .../api/graphql/graphql/schema/show_config.graphql     |  1 +
 src/services/api/graphql/key_auth.py                   | 18 ++++++++++++++++++
 10 files changed, 52 insertions(+)
 create mode 100644 src/services/api/graphql/key_auth.py

diff --git a/src/services/api/graphql/graphql/mutations.py b/src/services/api/graphql/graphql/mutations.py
index 0c3eb702a..93e046319 100644
--- a/src/services/api/graphql/graphql/mutations.py
+++ b/src/services/api/graphql/graphql/mutations.py
@@ -20,6 +20,7 @@ from graphql import GraphQLResolveInfo
 from makefun import with_signature
 
 from .. import state
+from .. import key_auth
 from api.graphql.recipes.session import Session
 
 mutation = ObjectType("Mutation")
@@ -53,6 +54,15 @@ def make_mutation_resolver(mutation_name, class_name, session_func):
                 }
 
             data = kwargs['data']
+            key = data['key']
+
+            auth = key_auth.auth_required(key)
+            if auth is None:
+                return {
+                     "success": False,
+                     "errors": ['invalid API key']
+                }
+
             session = state.settings['app'].state.vyos_session
 
             # one may override the session functions with a local subclass
diff --git a/src/services/api/graphql/graphql/queries.py b/src/services/api/graphql/graphql/queries.py
index e1868091e..ed94e4338 100644
--- a/src/services/api/graphql/graphql/queries.py
+++ b/src/services/api/graphql/graphql/queries.py
@@ -20,6 +20,7 @@ from graphql import GraphQLResolveInfo
 from makefun import with_signature
 
 from .. import state
+from .. import key_auth
 from api.graphql.recipes.session import Session
 
 query = ObjectType("Query")
@@ -53,6 +54,15 @@ def make_query_resolver(query_name, class_name, session_func):
                 }
 
             data = kwargs['data']
+            key = data['key']
+
+            auth = key_auth.auth_required(key)
+            if auth is None:
+                return {
+                     "success": False,
+                     "errors": ['invalid API key']
+                }
+
             session = state.settings['app'].state.vyos_session
 
             # one may override the session functions with a local subclass
diff --git a/src/services/api/graphql/graphql/schema/config_file.graphql b/src/services/api/graphql/graphql/schema/config_file.graphql
index 31ab26b9e..a7263114b 100644
--- a/src/services/api/graphql/graphql/schema/config_file.graphql
+++ b/src/services/api/graphql/graphql/schema/config_file.graphql
@@ -1,4 +1,5 @@
 input SaveConfigFileInput {
+    key: String!
     fileName: String
 }
 
@@ -13,6 +14,7 @@ type SaveConfigFileResult {
 }
 
 input LoadConfigFileInput {
+    key: String!
     fileName: String!
 }
 
diff --git a/src/services/api/graphql/graphql/schema/dhcp_server.graphql b/src/services/api/graphql/graphql/schema/dhcp_server.graphql
index 25f091bfa..345c349ac 100644
--- a/src/services/api/graphql/graphql/schema/dhcp_server.graphql
+++ b/src/services/api/graphql/graphql/schema/dhcp_server.graphql
@@ -1,4 +1,5 @@
 input DhcpServerConfigInput {
+    key: String!
     sharedNetworkName: String
     subnet: String
     defaultRouter: String
diff --git a/src/services/api/graphql/graphql/schema/firewall_group.graphql b/src/services/api/graphql/graphql/schema/firewall_group.graphql
index d89904b9e..9454d2997 100644
--- a/src/services/api/graphql/graphql/schema/firewall_group.graphql
+++ b/src/services/api/graphql/graphql/schema/firewall_group.graphql
@@ -1,4 +1,5 @@
 input CreateFirewallAddressGroupInput {
+    key: String!
     name: String!
     address: [String]
 }
@@ -15,6 +16,7 @@ type CreateFirewallAddressGroupResult {
 }
 
 input UpdateFirewallAddressGroupMembersInput {
+    key: String!
     name: String!
     address: [String!]!
 }
@@ -31,6 +33,7 @@ type UpdateFirewallAddressGroupMembersResult {
 }
 
 input RemoveFirewallAddressGroupMembersInput {
+    key: String!
     name: String!
     address: [String!]!
 }
@@ -47,6 +50,7 @@ type RemoveFirewallAddressGroupMembersResult {
 }
 
 input CreateFirewallAddressIpv6GroupInput {
+    key: String!
     name: String!
     address: [String]
 }
@@ -63,6 +67,7 @@ type CreateFirewallAddressIpv6GroupResult {
 }
 
 input UpdateFirewallAddressIpv6GroupMembersInput {
+    key: String!
     name: String!
     address: [String!]!
 }
@@ -79,6 +84,7 @@ type UpdateFirewallAddressIpv6GroupMembersResult {
 }
 
 input RemoveFirewallAddressIpv6GroupMembersInput {
+    key: String!
     name: String!
     address: [String!]!
 }
diff --git a/src/services/api/graphql/graphql/schema/image.graphql b/src/services/api/graphql/graphql/schema/image.graphql
index 7d1b4f9d0..485033875 100644
--- a/src/services/api/graphql/graphql/schema/image.graphql
+++ b/src/services/api/graphql/graphql/schema/image.graphql
@@ -1,4 +1,5 @@
 input AddSystemImageInput {
+    key: String!
     location: String!
 }
 
@@ -14,6 +15,7 @@ type AddSystemImageResult {
 }
 
 input DeleteSystemImageInput {
+    key: String!
     name: String!
 }
 
diff --git a/src/services/api/graphql/graphql/schema/interface_ethernet.graphql b/src/services/api/graphql/graphql/schema/interface_ethernet.graphql
index 32438b315..8a17d919f 100644
--- a/src/services/api/graphql/graphql/schema/interface_ethernet.graphql
+++ b/src/services/api/graphql/graphql/schema/interface_ethernet.graphql
@@ -1,4 +1,5 @@
 input InterfaceEthernetConfigInput {
+    key: String!
     interface: String
     address: String
     replace: Boolean = true
diff --git a/src/services/api/graphql/graphql/schema/show.graphql b/src/services/api/graphql/graphql/schema/show.graphql
index c7709e48b..278ed536b 100644
--- a/src/services/api/graphql/graphql/schema/show.graphql
+++ b/src/services/api/graphql/graphql/schema/show.graphql
@@ -1,4 +1,5 @@
 input ShowInput {
+    key: String!
     path: [String!]!
 }
 
diff --git a/src/services/api/graphql/graphql/schema/show_config.graphql b/src/services/api/graphql/graphql/schema/show_config.graphql
index 34afd2aa9..fd54036a4 100644
--- a/src/services/api/graphql/graphql/schema/show_config.graphql
+++ b/src/services/api/graphql/graphql/schema/show_config.graphql
@@ -5,6 +5,7 @@ JSON-serialize in case of JSON output.
 scalar Generic
 
 input ShowConfigInput {
+    key: String!
     path: [String!]!
     configFormat: String
 }
diff --git a/src/services/api/graphql/key_auth.py b/src/services/api/graphql/key_auth.py
new file mode 100644
index 000000000..f756ed6d8
--- /dev/null
+++ b/src/services/api/graphql/key_auth.py
@@ -0,0 +1,18 @@
+
+from . import state
+
+def check_auth(key_list, key):
+    if not key_list:
+        return None
+    key_id = None
+    for k in key_list:
+        if k['key'] == key:
+            key_id = k['id']
+    return key_id
+
+def auth_required(key):
+    api_keys = None
+    api_keys = state.settings['app'].state.vyos_keys
+    key_id = check_auth(api_keys, key)
+    state.settings['app'].state.vyos_id = key_id
+    return key_id
-- 
cgit v1.2.3