From ca2ba0f681a3d389955982e009b0e9ba0fd5baf9 Mon Sep 17 00:00:00 2001
From: Christian Boettcher <c.boettcher@fz-juelich.de>
Date: Thu, 4 Nov 2021 09:29:08 +0100
Subject: [PATCH] start adding secrets which are only available to some users

---
 apiserver/security/user.py                  |  1 +
 apiserver/storage/JsonFileStorageAdapter.py |  2 +-
 apiserver/storage/LocationStorage.py        |  4 ++++
 userdb-cli.py                               | 20 +++++++++++++++++---
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/apiserver/security/user.py b/apiserver/security/user.py
index 0643504..2225d20 100644
--- a/apiserver/security/user.py
+++ b/apiserver/security/user.py
@@ -34,6 +34,7 @@ class Token(BaseModel):
 class User(BaseModel):
     username: str
     email: str = None
+    has_secrets_access: Optional[bool] = False
 
 
 class UserInDB(User):
diff --git a/apiserver/storage/JsonFileStorageAdapter.py b/apiserver/storage/JsonFileStorageAdapter.py
index 45404e5..02aecc3 100644
--- a/apiserver/storage/JsonFileStorageAdapter.py
+++ b/apiserver/storage/JsonFileStorageAdapter.py
@@ -9,7 +9,7 @@ from pydantic import BaseModel
 from apiserver.config import ApiserverSettings
 
 from .LocationStorage import (AbstractLocationDataStorageAdapter, LocationData,
-                              LocationDataType)
+                              LocationDataType, LocationDataWithSecrets)
 
 
 log = logging.getLogger(__name__)
diff --git a/apiserver/storage/LocationStorage.py b/apiserver/storage/LocationStorage.py
index 03b4bed..ebe86d5 100644
--- a/apiserver/storage/LocationStorage.py
+++ b/apiserver/storage/LocationStorage.py
@@ -8,6 +8,7 @@ from pydantic import BaseModel
 class LocationDataType(Enum):
     DATASET = 'dataset'
     STORAGETARGET = 'storage_target'
+    AIRFLOW_CONNECTIONS = 'airflow_connections'
 
 
 class LocationData(BaseModel):
@@ -15,6 +16,9 @@ class LocationData(BaseModel):
     url: str
     metadata: Optional[Dict[str, str]]
 
+class LocationDataWithSecrets(LocationData):
+    secrets: Optional[Dict[str, str]]
+
 
 class AbstractLocationDataStorageAdapter:
     """
diff --git a/userdb-cli.py b/userdb-cli.py
index b17226f..54f5958 100755
--- a/userdb-cli.py
+++ b/userdb-cli.py
@@ -2,7 +2,7 @@
 import os, json, argparse, abc
 
 from pydantic import BaseModel
-from typing import List
+from typing import List, Optional
 from passlib.context import CryptContext
 
 
@@ -10,6 +10,7 @@ from passlib.context import CryptContext
 class User(BaseModel):
     username: str
     email: str = None
+    has_secrets_access: Optional[bool] = False
 
 
 class UserInDB(User):
@@ -106,7 +107,7 @@ def main(args):
                 raise ValueError("No Password or hash given!")
             hash = get_password_hash(args.password)
         
-        user = UserInDB(username=args.username, email=args.mail, hashed_password=hash)
+        user = UserInDB(username=args.username, email=args.mail, hashed_password=hash, has_secrets_access=args.secret_access)
         userdb.add(user)
         print("new User added:")
         print(user)
@@ -122,6 +123,16 @@ def main(args):
         print("Deleting the following user:")
         print(user)
         userdb.delete(args.username)
+    elif 'give_secret' in args.operation:
+        user = userdb.get(args.username)
+        user.has_secrets_access = True
+        userdb.delete(args.username)
+        userdb.add(user)
+    elif 'remove_secret' in args.operation:
+        user = userdb.get(args.username)
+        user.has_secrets_access = False
+        userdb.delete(args.username)
+        userdb.add(user)
 
 
 if __name__ == "__main__":
@@ -129,14 +140,17 @@ if __name__ == "__main__":
     parser.add_argument("operation", type=str, nargs=1, help="\
 hash \tReturn a bcrypt hash for the given password. Requires -p. \n\
 ls \tLists all Users in the userdb. \n\
-add \tAdds a new user to the userdb. Requires -u, -m and either -p or -b. \n\
+add \tAdds a new user to the userdb. Requires -u, -m and either -p or -b. -s is optional.\n\
 show \tShows a single user from the userdb. Requires -u. \n\
+give_secret \tGives the given user access to secrets. Requires -u. \n\
+remove_secret \tRemove the given users access to secrets. Requires -u. \n\
 rm \tDeletes a single user from the userdb. Requires -u. \
 ")
     parser.add_argument("-u", "--username", help="The username that should be modified")
     parser.add_argument("-m", "--mail", help="The email of a newly created user.")
     parser.add_argument("-p", "--password", help="The password of a newly created user.")
     parser.add_argument("-b", "--bcrypt-hash", help="The bcrypt password-hash of a newly created user.")
+    parser.add_argument("-s", "--secret-access", action="store_true", help="Give the new user access to secrets.")
     parser.add_argument("userdb_path", type=str, nargs='?', help="The path to the userdb to be modified or created.", default="./userdb.json")
     args = parser.parse_args()
     main(args)
\ No newline at end of file
-- 
GitLab