From abc10e93d714bd44a8693be357b76ae1fda06537 Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 12:11:50 +0100 Subject: Decrease database reconnection timer --- src/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.py b/src/main.py index c3e5ad9..1340ba6 100755 --- a/src/main.py +++ b/src/main.py @@ -40,7 +40,7 @@ for i in range(10): f'Database not responding, will try again soon. Attempt {i + 1} of 10.') else: break - time.sleep(10) + time.sleep(1) else: print('Database did not respond after 10 attempts, quitting.') sys.exit(-1) -- cgit v1.1 From 5048ec216ffc8bc797186886cb52141f96207931 Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 12:56:35 +0100 Subject: quickstart_test: Remove unused env var JWT_TOKEN --- src/quickstart_test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/quickstart_test.sh b/src/quickstart_test.sh index e81024f..604e684 100755 --- a/src/quickstart_test.sh +++ b/src/quickstart_test.sh @@ -5,7 +5,6 @@ export COUCHDB_PASSWORD=test export DOCKER_JWT_PUBKEY_PATH="`pwd`/test/unittest_cert/" export JWT_PUBKEY_PATH="`pwd`/test/unittest_cert/public.pem" -export JWT_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJ0eXBlIjoiYWNjZXNzIiwiZG9tYWlucyI6WyJzdW5ldC5zZSJdfQ._emWyVw-6qer5u65SitS8bZJas7l8bw4almnI1TB7DBnzNsch8ctU4btlgBpfJ2jbrvXZTIl8jXIcykO4crUrQ" virtualenv=no couchdb=no -- cgit v1.1 From bb1d91b8e87c7019574b01bbf44dbff83d8bae52 Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 13:04:14 +0100 Subject: Move userdb.yaml to mounted volume --- auth-server-poc/src/app.py | 3 ++- auth-server-poc/src/userdb.yaml | 23 ----------------------- auth-server-poc/userdb.yaml | 23 +++++++++++++++++++++++ quickstart.sh | 4 ++++ 4 files changed, 29 insertions(+), 24 deletions(-) delete mode 100644 auth-server-poc/src/userdb.yaml create mode 100644 auth-server-poc/userdb.yaml diff --git a/auth-server-poc/src/app.py b/auth-server-poc/src/app.py index c7ba0d1..37a7030 100644 --- a/auth-server-poc/src/app.py +++ b/auth-server-poc/src/app.py @@ -16,6 +16,7 @@ jwt = JWTManager(app) PEM_PRIVATE = "/opt/auth-server-poc/cert/private.pem" PEM_PUBLIC = "/opt/auth-server-poc/cert/public.pem" +USERDB_YAML = "/opt/auth-server-poc/userdb/userdb.yaml" app.config["JWT_PRIVATE_KEY"] = open(PEM_PRIVATE).read() app.config["JWT_PUBLIC_KEY"] = open(PEM_PUBLIC).read() @@ -28,7 +29,7 @@ class AuthApi(Resource): def post(self): identity = request.environ.get("REMOTE_USER") - db = authn.UserDB("userdb.yaml") + db = authn.UserDB(USERDB_YAML) additional_claims = { "type": "access", "read": db.read_perms(identity), diff --git a/auth-server-poc/src/userdb.yaml b/auth-server-poc/src/userdb.yaml deleted file mode 100644 index c55773b..0000000 --- a/auth-server-poc/src/userdb.yaml +++ /dev/null @@ -1,23 +0,0 @@ -user1: - authz: - sunet.se: r - su.se: r - kth.se: r - -user2: - authz: - sunet.se: w - su.se: w - kth.se: w - -user3: - authz: - sunet.se: rw - su.se: rw - kth.se: rw - -user4: - authz: - sunet.se: rw - su.se: r - kth.se: w diff --git a/auth-server-poc/userdb.yaml b/auth-server-poc/userdb.yaml new file mode 100644 index 0000000..c55773b --- /dev/null +++ b/auth-server-poc/userdb.yaml @@ -0,0 +1,23 @@ +user1: + authz: + sunet.se: r + su.se: r + kth.se: r + +user2: + authz: + sunet.se: w + su.se: w + kth.se: w + +user3: + authz: + sunet.se: rw + su.se: rw + kth.se: rw + +user4: + authz: + sunet.se: rw + su.se: r + kth.se: w diff --git a/quickstart.sh b/quickstart.sh index edf8c43..0f5a1ac 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -28,6 +28,10 @@ if [ ! -f ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd ]; then htpasswd -b ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user4 pwd fi +if [ ! -f ${DOCKER_JWT_HTPASSWD_PATH}/userdb.yaml ]; then + cp auth-server-poc/userdb.yaml ${DOCKER_JWT_HTPASSWD_PATH}/userdb.yaml +fi + # Launch the containers. docker-compose -f docker/docker-compose-dev.yaml up -d docker-compose -f auth-server-poc/docker-compose.yml up -d -- cgit v1.1 From e623a6a7a65639e280b6b3ed8513fb932c8a41eb Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 13:24:28 +0100 Subject: REDAME: Add tip about JWT decoding --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 40fdb1f..144f9a3 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,13 @@ We can also limit the number of results and skip N results forward with the para curl -s -H "Authorization: Bearer $JWT" 'http://localhost:80/sc/v0/get?limit=5&skip=2' | json_pp -json_opt utf8,pretty -There is also a convenience script `do-as` which simplifies performing actions as a particular user. +## Tips and tricks + +There is a convenience script `do-as` which simplifies performing actions as a particular user. + +You can decode a JWT using jq by piping to `jq -r '.access_token | split(".") | .[0],.[1] | @base64d' | jq`. Full example: + + curl http://localhost:8000/api/v1.0/auth -X POST -p -u user1:pwd | jq -r '.access_token | split(".") | .[0],.[1] | @base64d' | jq ## Development -- cgit v1.1 From 09355bbb7041023efb445d57277634e5061b9cec Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 16:37:07 +0100 Subject: Update test JWT + cert --- src/quickstart_test.sh | 4 ++-- src/test/test_api.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/quickstart_test.sh b/src/quickstart_test.sh index 604e684..3d4945e 100755 --- a/src/quickstart_test.sh +++ b/src/quickstart_test.sh @@ -48,8 +48,8 @@ mkdir test/unittest_cert cat < test/unittest_cert/public.pem -----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPW8bkkVIq4BX8eWwlUOUYbJhiGDv -K/6xY5T0BsvV6pbMoIUfgeThVOq5I3CmXxLt+qyPska6ol9fTN7woZLsCg== +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGHX8ipqVWtr49TXyX0f/L4GPhEpg +N0Erzy7hHkXVrkgKpnHSRLYWgbW4rscLoJAJeEv7Be5iH0TM8l09w8Q3wQ== -----END PUBLIC KEY----- EOF diff --git a/src/test/test_api.py b/src/test/test_api.py index cabe101..9d76e5e 100644 --- a/src/test/test_api.py +++ b/src/test/test_api.py @@ -9,9 +9,7 @@ from fastapi import FastAPI from fastapi import testclient client = testclient.TestClient(app) -JWT_TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJ0eXBlIjoiYWNjZXNzIiwi' + \ - 'ZG9tYWlucyI6WyJzdW5ldC5zZSJdfQ._emWyVw-6qer5u65SitS8bZJas7l8bw4almnI1' + \ - 'TB7DBnzNsch8ctU4btlgBpfJ2jbrvXZTIl8jXIcykO4crUrQ' +JWT_TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY0MjE2ODkyMCwianRpIjoiNjM0NGFiNjEtMTIzZC00YWMyLTk3YjMtYmVlYTE2M2JiMWMwIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6InVzZXIxIiwibmJmIjoxNjQyMTY4OTIwLCJyZWFkIjpbInN1bmV0LnNlIl0sIndyaXRlIjpbInN1bmV0LnNlIl19._bX9EHI9h0Vjw75UvYvypqaH3AmsgaATFSUSOT-cYLZHrfMlxios3emr7cyKw-OV_BN5h_XNyrMBV1gIoqAk3A' JWT_HEADER = {'Authorization': f'Bearer {JWT_TOKEN}'} -- cgit v1.1 From f5001fc965eae9748e089f36a6017674ca3be839 Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 16:37:20 +0100 Subject: Bugfix --- src/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.py b/src/main.py index 1340ba6..fb359df 100755 --- a/src/main.py +++ b/src/main.py @@ -152,7 +152,7 @@ async def get_key(key=None, Authorize: AuthJWT = Depends()): data = get_data(key) - if data["domain"] not in allowed_domains: + if data and data["domain"] not in allowed_domains: return JSONResponse( content={ "status": "error", @@ -198,7 +198,7 @@ async def delete(key, Authorize: AuthJWT = Depends()): data = get_data(key) - if data["domain"] not in allowed_domains: + if data and data["domain"] not in allowed_domains: return JSONResponse( content={ "status": "error", -- cgit v1.1 From 58721b01153b29be32422ce56aca9e180b33fca3 Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Fri, 14 Jan 2022 16:45:09 +0100 Subject: Update README --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 144f9a3..d39b006 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,3 @@ There are two docker-compose files used for development: - `auth-server-poc/docker-compose.yml` for the JWT server. To apply changes, `source env-vars.sh` and do e.g. `docker-compose -f docker/docker-compose-dev.yaml up -d --build collector`. - -## JWT mechanics (work in progress) - -2021-11-24: Currently no checks except that the JWT is valid are performed when -adding observations. When retrieving observations, the JWTs "domains" claim is -used. In auth-server-poc, domains is hard-coded to `["sunet.se"]` as an example. -- cgit v1.1 From ba4183e8dc5ba23ad3e60f34260f242f4339b19c Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Mon, 17 Jan 2022 09:03:02 +0100 Subject: Readd a default user `usr` --- auth-server-poc/userdb.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/auth-server-poc/userdb.yaml b/auth-server-poc/userdb.yaml index c55773b..937328c 100644 --- a/auth-server-poc/userdb.yaml +++ b/auth-server-poc/userdb.yaml @@ -1,3 +1,9 @@ +usr: + authz: + sunet.se: rw + su.se: rw + kth.se: rw + user1: authz: sunet.se: r -- cgit v1.1 From 55b8d76d1871d55930654ea753b599ee8234ae95 Mon Sep 17 00:00:00 2001 From: Kristofer Hallin Date: Mon, 17 Jan 2022 16:43:01 +0100 Subject: New claims etc. --- tools/jwt_producer.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tools/jwt_producer.py b/tools/jwt_producer.py index 3f8094d..a8f9ded 100644 --- a/tools/jwt_producer.py +++ b/tools/jwt_producer.py @@ -1,20 +1,24 @@ +import getopt import sys + import jwt -import getopt def usage(): progname = sys.argv[0] - print(f'{progname} -p -s ' + - '-d , for example sunet.se>') + print(f'Usage: {progname} [-p ] [-w ] [-r ]\n' + + ' -p \n' + + ' -w \n' + + ' -r ') sys.exit(0) -def create_token(private_key, domain): +def create_token(private_key, write_domain, read_domain): payload = { 'type': 'access', - 'domains': [domain] # We'll just do one domain now + 'write': [write_domain], + 'read': [read_domain] } with open(private_key, "r") as fd: @@ -24,8 +28,11 @@ def create_token(private_key, domain): if __name__ == '__main__': + read_domain = '' + write_domain = '' + try: - opts, args = getopt.getopt(sys.argv[1:], 'p:d:') + opts, args = getopt.getopt(sys.argv[1:], 'p:w:r:h') except getopt.GetoptError: usage() @@ -35,11 +42,16 @@ if __name__ == '__main__': for opt, arg in opts: if opt == '-p': private_key = arg - elif opt == '-d': - domain = arg + elif opt == '-w': + write_domain = arg + elif opt == '-r': + read_domain = arg + elif opt == '-h': + usage() else: usage() - token = create_token(private_key, domain).decode('utf-8') + token = create_token(private_key, write_domain, + read_domain).decode('utf-8') print(f'{token}') -- cgit v1.1 From f56ff9b7c60fc92e2add84a10f300a8f5ff1f0af Mon Sep 17 00:00:00 2001 From: Ernst Widerberg Date: Mon, 17 Jan 2022 16:46:11 +0100 Subject: Fix: Add password for `usr` --- quickstart.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstart.sh b/quickstart.sh index 0f5a1ac..950475b 100755 --- a/quickstart.sh +++ b/quickstart.sh @@ -22,7 +22,8 @@ fi # Generate a default htpasswd file with a user "usr:pwd". if [ ! -f ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd ]; then - htpasswd -b -c ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user1 pwd + htpasswd -b -c ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd usr pwd + htpasswd -b ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user1 pwd htpasswd -b ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user2 pwd htpasswd -b ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user3 pwd htpasswd -b ${DOCKER_JWT_HTPASSWD_PATH}/.htpasswd user4 pwd -- cgit v1.1 From 870381f29b0992d5dcf12a0a5fbb756ccd66b269 Mon Sep 17 00:00:00 2001 From: Kristofer Hallin Date: Mon, 17 Jan 2022 17:01:43 +0100 Subject: Updated JWT producer. --- tools/jwt_producer.py | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/tools/jwt_producer.py b/tools/jwt_producer.py index a8f9ded..9f30439 100644 --- a/tools/jwt_producer.py +++ b/tools/jwt_producer.py @@ -14,11 +14,22 @@ def usage(): sys.exit(0) -def create_token(private_key, write_domain, read_domain): +def create_token(private_key, write_domains, read_domains): + write_claim = list() + read_claim = list() + + if write_domains: + write_claim = write_domains.split(',') + + if read_domains: + read_claim = read_domains.split(',') + payload = { + 'sub': 'test', + 'fresh': False, 'type': 'access', - 'write': [write_domain], - 'read': [read_domain] + 'write': write_claim, + 'read': read_claim } with open(private_key, "r") as fd: @@ -28,30 +39,34 @@ def create_token(private_key, write_domain, read_domain): if __name__ == '__main__': - read_domain = '' - write_domain = '' + read_domains = None + write_domains = None + private_key = None try: opts, args = getopt.getopt(sys.argv[1:], 'p:w:r:h') except getopt.GetoptError: usage() - if len(sys.argv) != 5: - usage() - for opt, arg in opts: if opt == '-p': private_key = arg elif opt == '-w': - write_domain = arg + write_domains = arg elif opt == '-r': - read_domain = arg + read_domains = arg elif opt == '-h': usage() else: usage() - token = create_token(private_key, write_domain, - read_domain).decode('utf-8') + if not private_key: + usage() + + if not write_domains and not read_domains: + usage() + + token = create_token(private_key, write_domains, + read_domains) print(f'{token}') -- cgit v1.1 From 88b1a1aa213cc70443254a05f2a8968fb7c43a48 Mon Sep 17 00:00:00 2001 From: Kristofer Hallin Date: Tue, 18 Jan 2022 10:42:14 +0100 Subject: Added -e flag to jwt_producer. --- tools/jwt_producer.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/jwt_producer.py b/tools/jwt_producer.py index 9f30439..a024c13 100644 --- a/tools/jwt_producer.py +++ b/tools/jwt_producer.py @@ -10,7 +10,8 @@ def usage(): print(f'Usage: {progname} [-p ] [-w ] [-r ]\n' + ' -p \n' + ' -w \n' + - ' -r ') + ' -r \n' + + ' -e