diff options
Diffstat (limited to 'auth-server-poc')
-rw-r--r-- | auth-server-poc/requirements.txt | 34 | ||||
-rw-r--r-- | auth-server-poc/src/app.py | 39 | ||||
-rwxr-xr-x | auth-server-poc/src/authn.py | 97 | ||||
-rw-r--r-- | auth-server-poc/src/userdb.yaml | 23 |
4 files changed, 179 insertions, 14 deletions
diff --git a/auth-server-poc/requirements.txt b/auth-server-poc/requirements.txt index 9927acb..fc8fc53 100644 --- a/auth-server-poc/requirements.txt +++ b/auth-server-poc/requirements.txt @@ -248,3 +248,37 @@ zipp==3.6.0 \ # via # -r requirements.txt # importlib-metadata +pyyaml==6.0 \ + --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ + --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ + --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ + --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ + --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ + --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ + --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ + --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ + --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ + --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ + --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ + --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ + --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ + --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ + --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ + --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ + --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ + --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ + --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ + --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ + --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ + --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ + --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ + --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ + --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ + --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ + --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ + --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ + --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ + --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ + --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ + --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ + --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 diff --git a/auth-server-poc/src/app.py b/auth-server-poc/src/app.py index 443eded..c7ba0d1 100644 --- a/auth-server-poc/src/app.py +++ b/auth-server-poc/src/app.py @@ -3,40 +3,51 @@ from flask_restful import Api, Resource from flask_jwt_extended import create_access_token, JWTManager from flask_cors import CORS +import authn + app = Flask(__name__) cors = CORS( app, resources={r"/api/*": {"origins": "*"}}, expose_headers=["Content-Type", "Authorization", "X-Total-Count"], ) -api = Api(app, prefix='/api/v1.0') +api = Api(app, prefix="/api/v1.0") jwt = JWTManager(app) -PEM_PRIVATE = '/opt/auth-server-poc/cert/private.pem' -PEM_PUBLIC = '/opt/auth-server-poc/cert/public.pem' +PEM_PRIVATE = "/opt/auth-server-poc/cert/private.pem" +PEM_PUBLIC = "/opt/auth-server-poc/cert/public.pem" -app.config['JWT_PRIVATE_KEY'] = open(PEM_PRIVATE).read() -app.config['JWT_PUBLIC_KEY'] = open(PEM_PUBLIC).read() -app.config['JWT_ALGORITHM'] = 'ES256' -app.config['JWT_IDENTITY_CLAIM'] = 'sub' -app.config['JWT_ACCESS_TOKEN_EXPIRES'] = False +app.config["JWT_PRIVATE_KEY"] = open(PEM_PRIVATE).read() +app.config["JWT_PUBLIC_KEY"] = open(PEM_PUBLIC).read() +app.config["JWT_ALGORITHM"] = "ES256" +app.config["JWT_IDENTITY_CLAIM"] = "sub" +app.config["JWT_ACCESS_TOKEN_EXPIRES"] = False class AuthApi(Resource): def post(self): - additional_claims = {"type": "access", "domains": ["sunet.se"]} + + identity = request.environ.get("REMOTE_USER") + db = authn.UserDB("userdb.yaml") + additional_claims = { + "type": "access", + "read": db.read_perms(identity), + "write": db.write_perms(identity), + } + access_token = create_access_token( - identity=request.environ.get('REMOTE_USER'), + identity=identity, additional_claims=additional_claims, ) - return {'access_token': access_token}, 200 + + return {"access_token": access_token}, 200 -@app.route('/') +@app.route("/") def index(): return "<p>Username: {}</p><p>Auth type: {}</p>".format( - request.environ.get('REMOTE_USER'), request.environ.get('AUTH_TYPE') + request.environ.get("REMOTE_USER"), request.environ.get("AUTH_TYPE") ) -api.add_resource(AuthApi, '/auth') +api.add_resource(AuthApi, "/auth") diff --git a/auth-server-poc/src/authn.py b/auth-server-poc/src/authn.py new file mode 100755 index 0000000..8b32cdc --- /dev/null +++ b/auth-server-poc/src/authn.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python3 + +import yaml + + +class Authz: + def __init__(self, org, perms): + self._org = org + self._perms = perms + + def dump(self): + return "{}: {}".format(self._org, self._perms) + + def read_p(self): + return "r" in self._perms + + def write_p(self): + return "w" in self._perms + + +class User: + def __init__(self, username, authz): + self._username = username + self._authz = {} + for org, perms in authz.items(): + self._authz[org] = Authz(org, perms) + + def dump(self): + return [ + "{}: {}".format(self._username, auth.dump()) + for auth in self._authz.values() + ] + + def orgnames(self): + return [x for x in self._authz.keys()] + + def read_perms(self): + acc = [] + for k, v in self._authz.items(): + if v.read_p(): + acc.append(k) + return acc + + def write_perms(self): + acc = [] + for k, v in self._authz.items(): + if v.write_p(): + acc.append(k) + return acc + + +class UserDB: + def __init__(self, yamlfile): + self._users = {} + for u, d in yaml.safe_load(open(yamlfile)).items(): + self._users[u] = User(u, d["authz"]) + + def dump(self): + return [u.dump() for u in self._users.values()] + + def orgs_for_user(self, username): + return self._users.get(username).orgnames() + + def read_perms(self, username): + user = self._users.get(username) + if not user: + return None + return user.read_perms() + + def write_perms(self, username): + user = self._users.get(username) + if not user: + return None + return user.write_perms() + + +def self_test(): + db = UserDB("userdb.yaml") + print(db.dump()) + + orgs = db.orgs_for_user("user3") + assert "sunet.se" in orgs + assert "su.se" in orgs + assert len(orgs) == 2 + + rp = db.read_perms("user3", "pw3") + assert len(rp) == 2 + assert "sunet.se" in rp + assert "su.se" in rp + + wp = db.write_perms("user3", "pw3") + assert len(wp) == 1 + assert "sunet.se" in wp + + +if __name__ == "__main__": + self_test() diff --git a/auth-server-poc/src/userdb.yaml b/auth-server-poc/src/userdb.yaml new file mode 100644 index 0000000..c55773b --- /dev/null +++ b/auth-server-poc/src/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 |