Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend] Implemented role request feature #129

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions flask-backend/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ def unauthorized_handler():
from .routes.extraction import extraction as extraction_blueprint
app.register_blueprint(extraction_blueprint)

from .routes.rolerequests import rolerequests as rolerequests_blueprint
app.register_blueprint(rolerequests_blueprint)

return app
32 changes: 32 additions & 0 deletions flask-backend/api/models/RoleRequest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import time
from flask_login import UserMixin

from .. import db, ma

class RoleRequest(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer)
admin_id = db.Column(db.Integer)
requested_role = db.Column(db.String(100))
timestamp = db.Column(db.Float)

def __init__(self, user_id, admin_id, requested_role):
self.user_id = user_id
self.admin_id = admin_id
self.requested_role = requested_role
self.timestamp = int(time.time())

# Return object is JSON format
def map(self):
return {
'id': self.id,
'user_id': self.user_id,
'admin_id': self.admin_id,
'requested_role': self.requested_role,
'timestamp': self.timestamp,
}


class RoleRequestSchema(ma.Schema):
class Meta:
fields = ('id', 'user_id', 'admin_id', 'requested_role', 'timestamp')
2 changes: 1 addition & 1 deletion flask-backend/api/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, case_name, data_size, timestamp, extractor_id, data_path):

class UserSchema(ma.Schema):
class Meta:
fields = ('name', 'email', 'role', 'timestamp', 'admin')
fields = ('id', 'name', 'email', 'role', 'timestamp', 'admin')

class CaseSchema(ma.Schema):
class Meta:
Expand Down
246 changes: 246 additions & 0 deletions flask-backend/api/routes/rolerequests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
from flask import Blueprint, jsonify, request
from flask_login import login_required, current_user

from .. import db
from ..models.models import User
from ..models.RoleRequest import RoleRequest, RoleRequestSchema

rolerequests = Blueprint('rolerequests', __name__, url_prefix='/rolerequests')

rolerequests_schema = RoleRequestSchema(many=True)

# Fetch all requests for an admin
@rolerequests.route('/', methods=['GET'])
@login_required
def get_all_rolerequests():

# Only admins can view role requests
if current_user.has_admin:
response = {
'success': False,
'msg': 'Role requests can only be viewed by an admin',
}
return jsonify(response), 400

# Admin can only see the requests of his created users
admin_id = current_user.id
rolerequests = RoleRequest.query.filter_by(admin_id=admin_id).order_by(RoleRequest.timestamp).all()
result = rolerequests_schema.dump(rolerequests)
response = {
'success': True,
'data': result,
'msg': 'Role requests fetched successfully'
}
return jsonify(response), 200

# Fetch a request by id
@rolerequests.route('/<id>', methods=['GET'])
@login_required
def get_rolerequest_by_id(id):

if not id:
response = {
'success': False,
'msg': 'Please provide an id',
}
return jsonify(response), 400

rolerequest = RoleRequest.query.filter_by(id=id).first()
if not rolerequest:
response = {
'success': False,
'msg': 'Role request not found',
}
return jsonify(response), 404

# Only the concerned admin or the user who posted this request should be able to access it
if rolerequest.admin_id != current_user.id and rolerequest.user_id != current_user.id:
response = {
'success': False,
'msg': 'Not authorized to view this request',
}
return jsonify(response), 401

response = {
'success': True,
'data': rolerequest,
'msg': 'Role requests fetched successfully',
}
return jsonify(response), 200

# submit a role request
@rolerequests.route('/', methods=['POST'])
@login_required
def submit_role_request():

# Only extractor or management can submit a role request
if not current_user.has_admin:
response = {
'success': False,
'msg': 'You\'re already an admin',
}
return jsonify(response), 400

# Check if requested role is provided or not
try:
req = request.get_json()
requested_role = str(req['requested_role'])
except:
response = {
'success': False,
'msg': 'Please provide a role',
}
return jsonify(response), 400

# Check if user already has the role he is requesting
if requested_role == current_user.role:
response = {
'success': False,
'msg': f'You are already {requested_role}',
}
return jsonify(response), 400

# Check if role provided is a valid one
if requested_role not in ['admin', 'extractor', 'management']:
response = {
'success': False,
'msg': 'Please provide a valid role',
}
return jsonify(response), 400

user_id = current_user.id

# Find admin using email
admin = User.query.filter_by(email=current_user.admin).first()

# If admin is absent
if not admin:
response = {
'success': False,
'msg': 'Error submiting the request',
}
return jsonify(response), 500

admin_id = admin.id
rolerequest = RoleRequest(user_id=user_id, admin_id=admin_id, requested_role=requested_role)
db.session.add(rolerequest)
db.session.commit()

response = {
'success': True,
'data': rolerequest.map(),
'msg': 'Requested successfully submitted',
}
return jsonify(response), 200

# Accept a role request by its id
@rolerequests.route('/accept/<id>', methods=['PUT'])
@login_required
def accept_rolerequest(id):

# Only admins can accept role requests
if current_user.has_admin:
response = {
'success': False,
'msg': 'Role requests can only be accepted by an admin',
}
return jsonify(response), 400

if not id:
response = {
'success': False,
'msg': 'Please provide an id',
}
return jsonify(response), 400

rolerequest = RoleRequest.query.filter_by(id=id).first()

# Check if request exists
if not rolerequest:
response = {
'success': False,
'msg': 'Role request not found',
}
return jsonify(response), 404

# Check if request belongs to this admin
if rolerequest.admin_id != current_user.id:
response = {
'success': False,
'msg': 'Not authorized to accept this request',
}
return jsonify(response), 401

requested_role = rolerequest.requested_role
user = User.query.filter_by(id=rolerequest.user_id).first()

# Check if user exists
if not user:
response = {
'success': False,
'msg': 'User not found',
}
return jsonify(response), 404

# Update user role
user.role = requested_role
db.session.commit()

# Delete the request as it is now resolved
db.session.delete(rolerequest)
db.session.commit()

response = {
'success': True,
'msg': 'Role request accepted',
}
return jsonify(response), 200

# Reject a role request by its id
@rolerequests.route('/reject/<id>', methods=['DELETE'])
@login_required
def reject_rolerequest(id):

# Only admins can reject role requests
if current_user.has_admin:
response = {
'success': False,
'msg': 'Role requests can only be rejected by an admin',
}
return jsonify(response), 400

if not id:
response = {
'success': False,
'msg': 'Please provide an id',
}
return jsonify(response), 400

rolerequest = RoleRequest.query.filter_by(id=id).first()

# Check if request exists
if not rolerequest:
response = {
'success': False,
'msg': 'Role request not found',
}
return jsonify(response), 404

# Check if request belongs to this admin
if rolerequest.admin_id != current_user.id:
response = {
'success': False,
'msg': 'Not authorized to accept this request',
}
return jsonify(response), 401

# Delete the request
db.session.delete(rolerequest)
db.session.commit()

response = {
'success': True,
'msg': 'Role request rejected',
}
return jsonify(response), 200

1 change: 1 addition & 0 deletions flask-backend/create_database.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from api.models.models import User
from api.models.RoleRequest import RoleRequest
from api import db, create_app

db.create_all(app=create_app())