about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-03-03 10:51:15 +0300
committerFrederick Muriuki Muriithi2023-03-03 10:51:46 +0300
commitf6aefe82ad1eb1163cdaadf598dc2cebe91569b4 (patch)
treedee8e1923dac9cac205472fe7909b60f32c0cd8c
parent45856ad45a84f75c361396477946de7bd46a64f5 (diff)
downloadgenenetwork2-f6aefe82ad1eb1163cdaadf598dc2cebe91569b4.tar.gz
oauth2: enable creation and listing of group roles.
-rw-r--r--wqflask/wqflask/oauth2/roles.py76
-rw-r--r--wqflask/wqflask/templates/oauth2/create-role.html46
-rw-r--r--wqflask/wqflask/templates/oauth2/list_roles.html58
3 files changed, 174 insertions, 6 deletions
diff --git a/wqflask/wqflask/oauth2/roles.py b/wqflask/wqflask/oauth2/roles.py
index 0b181264..c9493a1e 100644
--- a/wqflask/wqflask/oauth2/roles.py
+++ b/wqflask/wqflask/oauth2/roles.py
@@ -1,22 +1,38 @@
 """Handle role endpoints"""
 import uuid
 
-from flask import Blueprint, render_template
+from flask import flash, request, url_for, redirect, Blueprint, render_template
 
 from .checks import require_oauth2
 from .client import oauth2_get, oauth2_post
-from .request_utils import request_error
+from .request_utils import request_error, process_error
 
 roles = Blueprint("role", __name__)
 
 @roles.route("/user", methods=["GET"])
 @require_oauth2
 def user_roles():
-    def __success__(roles):
-        return render_template("oauth2/list_roles.html", roles=roles)
+    def  __grerror__(roles, user_privileges, error):
+        return render_template(
+            "oauth2/list_roles.html", roles=roles,
+            user_privileges=user_privileges,
+            group_roles_error=process_error(error))
+
+    def  __grsuccess__(roles, user_privileges, group_roles):
+        return render_template(
+            "oauth2/list_roles.html", roles=roles,
+            user_privileges=user_privileges, group_roles=group_roles)
+
+    def __role_success__(roles):
+        uprivs = tuple(
+            privilege["privilege_id"] for role in roles
+            for privilege in role["privileges"])
+        return oauth2_get("oauth2/group/roles").either(
+            lambda err: __grerror__(roles, uprivs, err),
+            lambda groles: __grsuccess__(roles, uprivs, groles))
 
     return oauth2_get("oauth2/user/roles").either(
-        request_error, __success__)
+        request_error, __role_success__)
 
 @roles.route("/role/<uuid:role_id>", methods=["GET"])
 @require_oauth2
@@ -26,3 +42,53 @@ def role(role_id: uuid.UUID):
 
     return oauth2_get(f"oauth2/role/view/{role_id}").either(
         request_error, __success__)
+
+@roles.route("/create", methods=["GET", "POST"])
+@require_oauth2
+def create_role():
+    """Create a new role."""
+    def __roles_error__(error):
+        return render_template(
+            "oauth2/create-role.html", roles_error=process_error(error))
+
+    def __gprivs_error__(roles, error):
+        return render_template(
+            "oauth2/create-role.html", roles=roles,
+            group_privileges_error=process_error(error))
+
+    def __success__(roles, gprivs):
+        uprivs = tuple(
+            privilege["privilege_id"] for role in roles
+            for privilege in role["privileges"])
+        return render_template(
+            "oauth2/create-role.html", roles=roles, user_privileges=uprivs,
+            group_privileges=gprivs,
+            prev_role_name=request.args.get("role_name"))
+
+    def __fetch_gprivs__(roles):
+        return oauth2_get("oauth2/group/privileges").either(
+            lambda err: __gprivs_error__(roles, err),
+            lambda gprivs: __success__(roles, gprivs))
+
+    if request.method == "GET":
+        return oauth2_get("oauth2/user/roles").either(
+            __roles_error__, __fetch_gprivs__)
+
+    form = request.form
+    role_name = form.get("role_name")
+    privileges = form.getlist("privileges[]")
+    if len(privileges) == 0:
+        flash("You must assign at least one privilege to the role",
+              "alert-danger")
+        return redirect(url_for(
+            "oauth2.role.create_role", role_name=role_name))
+    def __create_error__(error):
+        err = process_error(error)
+        flash(f"{err['error']}: {err['error_description']}",
+              "alert-danger")
+        return redirect(url_for("oauth2.role.create_role"))
+    def __create_success__(*args):
+        flash("Role created successfully.", "alert-success")
+        return redirect(url_for("oauth2.role.user_roles"))
+    return oauth2_post("oauth2/group/role/create",data=form).either(
+        __create_error__,__create_success__)
diff --git a/wqflask/wqflask/templates/oauth2/create-role.html b/wqflask/wqflask/templates/oauth2/create-role.html
new file mode 100644
index 00000000..f2bff7b4
--- /dev/null
+++ b/wqflask/wqflask/templates/oauth2/create-role.html
@@ -0,0 +1,46 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+{%block title%}View User{%endblock%}
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+  {{profile_nav("roles", user_privileges)}}
+  <h3>Create Role</h3>
+
+  {{flash_me()}}
+
+  {%if group_privileges_error is defined%}
+  {{display_error("Group Privileges", group_privileges_error)}}
+  {%else%}
+  {%if "group:role:create-role" in user_privileges%}
+  <form method="POST" action="{{url_for('oauth2.role.create_role')}}">
+    <legend>Create Group Role</legend>
+    <div class="form-group">
+      <label for="role_name" class="form-label">Name</label>
+      <input type="text" id="role_name" name="role_name" required="required"
+	     class="form-control"
+	     {%if prev_role_name is defined and prev_role_name is not none%}
+	     value="{{prev_role_name}}"
+	     {%endif%} />
+    </div>
+    <label class="form-label">Privileges</label>
+    {%for priv in group_privileges%}
+    <div class="checkbox">
+      <label for="chk:{{priv.privilege_id}}">
+	<input type="checkbox" id="chk:{{priv.privilege_id}}"
+	       name="privileges[]" value={{priv.privilege_id}} />
+	<span style="text-transform: capitalize;">
+	  {{priv.privilege_description}}
+	</span> ({{priv.privilege_id}})
+      </label>
+    </div>
+    {%endfor%}
+
+    <input type="submit" class="btn btn-primary" value="Create" />
+  </form>
+  {%else%}
+  {{display_error("Privilege", {"error":"PrivilegeError", "error_description": "You do not have sufficient privileges to create a new role."})}}
+  {%endif%}
+  {%endif%}
+</div>
+{%endblock%}
diff --git a/wqflask/wqflask/templates/oauth2/list_roles.html b/wqflask/wqflask/templates/oauth2/list_roles.html
index 028d0a17..7d9c4ac2 100644
--- a/wqflask/wqflask/templates/oauth2/list_roles.html
+++ b/wqflask/wqflask/templates/oauth2/list_roles.html
@@ -1,15 +1,17 @@
 {%extends "base.html"%}
 {%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
 {%block title%}View User{%endblock%}
 {%block content%}
 <div class="container" style="min-width: 1250px;">
-  {{profile_nav("roles")}}
+  {{profile_nav("roles", user_privileges)}}
   <h3>Roles</h3>
 
   {{flash_me()}}
 
   <div class="container-fluid">
     <div class="row">
+      <h3>Your System-Level Roles</h3>
       <ul>
 	{%for role in roles %}
 	<li>
@@ -25,6 +27,60 @@
       </ul>
     </div>
 
+    <div class="row">
+      <h3>Group-Wide Roles</h3>
+
+      {%if "group:role:create-role" in user_privileges%}
+      <a href="{{url_for('oauth2.role.create_role')}}"
+	 title="Link to create a new group role"
+	 class="btn btn-info">New Group Role</a>
+      {%endif%}
+
+      {%if group_roles_error is defined%}
+      {{display_error("Group Roles", group_role_error)}}
+      {%else%}
+      <table class="table">
+	<caption>Group Roles</caption>
+	<thead>
+	  <tr>
+	    <th>Role Name</th>
+	    <th colspan="2">Actions</th>
+	  </tr>
+	</thead>
+	<tbody>
+	  {%for grole in group_roles%}
+	  <tr>
+	    <td>{{grole.role.role_name}}</td>
+	    <td>
+	      <a href="#/group/role/{{grole.group_role_id}}"
+		 title="Link to role {{grole.role.role_name}}"
+		 class="btn btn-info">
+		View
+	      </a>
+	    </td>
+	    <td>
+	      <a href="#/edit/role"
+		 title="Edit role {{grole.role.role_name}}"
+		 class="btn btn-warning">
+		Edit
+	      </a>
+	    </td>
+	  </tr>
+	  {%else%}
+	  <tr>
+	    <td colspan="3">
+	      <span class="glyphicon glyphicon-exclamation-sign text-info">
+	      </span>
+	      &nbsp;
+	      <span class="text-info">No group roles found</span>
+	    </td>
+	  </tr>
+	  {%endfor%}
+	</tbody>
+      </table>
+      {%endif%}
+    </div>
+
   </div>
 
 </div>