about summary refs log tree commit diff
path: root/gn_auth/auth/authorisation/users/masquerade/models.py
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-08-04 10:10:28 +0300
committerFrederick Muriuki Muriithi2023-08-04 10:20:09 +0300
commit8b7c598407a5fea9a3d78473e72df87606998cd4 (patch)
tree8526433a17eca6b511feb082a0574f9b15cb9469 /gn_auth/auth/authorisation/users/masquerade/models.py
parentf7fcbbcc014686ac597b783a8dcb38b43024b9d6 (diff)
downloadgn-auth-8b7c598407a5fea9a3d78473e72df87606998cd4.tar.gz
Copy over files from GN3 repository.
Diffstat (limited to 'gn_auth/auth/authorisation/users/masquerade/models.py')
-rw-r--r--gn_auth/auth/authorisation/users/masquerade/models.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/gn_auth/auth/authorisation/users/masquerade/models.py b/gn_auth/auth/authorisation/users/masquerade/models.py
new file mode 100644
index 0000000..9f24b6b
--- /dev/null
+++ b/gn_auth/auth/authorisation/users/masquerade/models.py
@@ -0,0 +1,67 @@
+"""Functions for handling masquerade."""
+from uuid import uuid4
+from functools import wraps
+from datetime import datetime
+
+from flask import current_app as app
+
+from gn3.auth import db
+
+from gn3.auth.authorisation.errors import ForbiddenAccess
+from gn3.auth.authorisation.roles.models import user_roles
+
+from gn3.auth.authentication.users import User
+from gn3.auth.authentication.oauth2.models.oauth2token import (
+    OAuth2Token, save_token)
+
+__FIVE_HOURS__ = (60 * 60 * 5)
+
+def can_masquerade(func):
+    """Security decorator."""
+    @wraps(func)
+    def __checker__(*args, **kwargs):
+        if len(args) == 3:
+            conn, token, _masq_user = args
+        elif len(args) == 2:
+            conn, token = args
+        elif len(args) == 1:
+            conn = args[0]
+            token = kwargs["original_token"]
+        else:
+            conn = kwargs["conn"]
+            token = kwargs["original_token"]
+
+        masq_privs = [priv for role in user_roles(conn, token.user)
+                      for priv in role.privileges
+                      if priv.privilege_id == "system:user:masquerade"]
+        if len(masq_privs) == 0:
+            raise ForbiddenAccess(
+                "You do not have the ability to masquerade as another user.")
+        return func(*args, **kwargs)
+    return __checker__
+
+@can_masquerade
+def masquerade_as(
+        conn: db.DbConnection,
+        original_token: OAuth2Token,
+        masqueradee: User) -> OAuth2Token:
+    """Get a token that enables `masquerader` to act as `masqueradee`."""
+    token_details = app.config["OAUTH2_SERVER"].generate_token(
+        client=original_token.client,
+        grant_type="authorization_code",
+        user=masqueradee,
+        expires_in=__FIVE_HOURS__,
+        include_refresh_token=True)
+    new_token = OAuth2Token(
+        token_id=uuid4(),
+        client=original_token.client,
+        token_type=token_details["token_type"],
+        access_token=token_details["access_token"],
+        refresh_token=token_details.get("refresh_token"),
+        scope=original_token.scope,
+        revoked=False,
+        issued_at=datetime.now(),
+        expires_in=token_details["expires_in"],
+        user=masqueradee)
+    save_token(conn, new_token)
+    return new_token