about summary refs log tree commit diff
path: root/gn3
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-02-07 13:00:56 +0300
committerFrederick Muriuki Muriithi2023-02-07 13:01:27 +0300
commit87586bd5270140bf52d39d3dc61c754dd13d4391 (patch)
tree86e4c36ce0fc3334bfbf6d421efb070dd5f3cfd2 /gn3
parent3cc5e7b57b0ca9bd5143d746022cb69349023a68 (diff)
downloadgenenetwork3-87586bd5270140bf52d39d3dc61c754dd13d4391.tar.gz
auth: groups: Enable users to request to join group.
Diffstat (limited to 'gn3')
-rw-r--r--gn3/auth/authorisation/groups/views.py47
-rw-r--r--gn3/auth/db_utils.py14
2 files changed, 60 insertions, 1 deletions
diff --git a/gn3/auth/authorisation/groups/views.py b/gn3/auth/authorisation/groups/views.py
index 02b3162..f6675ab 100644
--- a/gn3/auth/authorisation/groups/views.py
+++ b/gn3/auth/authorisation/groups/views.py
@@ -1,15 +1,21 @@
 """The views/routes for the `gn3.auth.authorisation.groups` package."""
 import uuid
+import datetime
+from functools import partial
 
 from flask import request, jsonify, Response, Blueprint, current_app
 
 from gn3.auth import db
 from gn3.auth.dictify import dictify
+from gn3.auth.db_utils import with_db_connection
 
 from .models import (
-    all_groups, GroupCreationError, group_users as _group_users,
+    user_group, all_groups, GroupCreationError, group_users as _group_users,
     create_group as _create_group)
 
+from ..errors import AuthorisationError
+
+from ...authentication.users import User
 from ...authentication.oauth2.resource_server import require_oauth
 
 groups = Blueprint("groups", __name__)
@@ -52,3 +58,42 @@ def group_members(group_id: uuid.UUID) -> Response:
         with db.connection(db_uri) as conn:
             return jsonify(tuple(
                 dictify(user) for user in _group_users(conn, group_id)))
+
+@groups.route("/requests/join/<uuid:group_id>", methods=["POST"])
+@require_oauth("profile group")
+def request_to_join(group_id: uuid.UUID) -> Response:
+    """Request to join a group."""
+    def __request__(conn: db.DbConnection, user: User, group_id: uuid.UUID,
+                    message: str):
+        with db.cursor(conn) as cursor:
+            group = user_group(cursor, user).maybe(# type: ignore[misc]
+                False, lambda grp: grp)# type: ignore[arg-type]
+            if group:
+                error = AuthorisationError(
+                    "You cannot request to join a new group while being a "
+                    "member of an existing group.")
+                error.error_code = 400
+                raise error
+            request_id = uuid.uuid4()
+            cursor.execute(
+                "INSERT INTO group_requests VALUES "
+                "(:request_id, :group_id, :user_id, :ts, :type, :msg)",
+                {
+                    "request_id": str(request_id),
+                    "group_id": str(group_id),
+                    "user_id": str(user.user_id),
+                    "ts": datetime.datetime.now().timestamp(),
+                    "type": "JOIN",
+                    "msg": message
+                })
+            return {
+                "request_id":  request_id,
+                "message": "Successfully sent the join request."
+            }
+
+    with require_oauth.acquire("profile group") as the_token:
+        form = request.form
+        results = with_db_connection(partial(
+            __request__, user=the_token.user, group_id=group_id, message=form.get(
+                "message", "I hereby request that you add me to your group.")))
+        return jsonify(results)
diff --git a/gn3/auth/db_utils.py b/gn3/auth/db_utils.py
new file mode 100644
index 0000000..c06b026
--- /dev/null
+++ b/gn3/auth/db_utils.py
@@ -0,0 +1,14 @@
+"""Some common auth db utilities"""
+from typing import Any, Callable
+from flask import current_app
+
+from . import db
+
+def with_db_connection(func: Callable[[db.DbConnection], Any]) -> Any:
+    """
+    Takes a function of one argument `func`, whose one argument is a database
+    connection.
+    """
+    db_uri = current_app.config["AUTH_DB"]
+    with db.connection(db_uri) as conn:
+        return func(conn)