예제 #1
0
def remove_ag():
    """Remove the access group from the approvers approval area"""

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {
        "approver": {
            "type": "integer"
        },  ## varför är det integer här? är det approver_id?
        "ag": {
            "type": "integer"
        }
    }

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    approver_id = request.json.get("approver")
    ag_id = request.json.get("ag")

    responsible_for_ag = ResponsibleForAg.query.filter_by(
        approver_id=approver_id, ag_id=ag_id).first()

    if not responsible_for_ag:
        return bad_request(
            "No approver {} is responsible for access group {}.".format(
                approver_id, ag_id))

    db.session.delete(responsible_for_ag)
    db.session.commit()

    return ok("Access group removed from approver.")
예제 #2
0
def remove_room():
    """Remove the room from the approvers approval area"""

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {
        "approver": {
            "type": "integer"
        },  ## varför är det integer här? är det approver_id?
        "room": {
            "type": "string"
        }
    }

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    approver_id = request.json.get("approver")
    room_text_id = request.json.get("room")

    responsible_for_room = ResponsibleForRoom.query \
     .join(Room, Room.id == ResponsibleForRoom.room_id) \
     .filter(ResponsibleForRoom.approver_id == approver_id, Room.text_id == room_text_id).first()

    if not responsible_for_room:
        return bad_request("No approver {} is responsible for room {}.".format(
            approver_id, room_text_id))

    db.session.delete(responsible_for_room)
    db.session.commit()

    return ok("Room removed from approver.")
예제 #3
0
def revoke_ag_access():
    """Revokes a readers access to a access group"""
    schema = {"ag_id": {"type": "integer"}, "email": {"type": "string"}}

    email = request.json.get("email")
    ag_id = request.json.get("ag_id")

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    # Checks if the reader exists in the database
    reader = Reader.query.filter_by(email=email).first()
    if not reader:
        return bad_request("Reader does not exist!")

    gives_access = db.session.query(gives_access_to, BelongsTo).filter(
        gives_access_to.c.ag_id == BelongsTo.ag_id, BelongsTo.ag_id == ag_id,
        BelongsTo.reader_id == reader.id).all()

    if not gives_access:
        return bad_request(
            "The reader does not have access to this access group")

    BelongsTo.query.filter_by(reader_id=reader.id, ag_id=ag_id).delete()

    db.session.commit()
    return ok("Access to {0} has been removed for {1}".format(ag_id, email))
예제 #4
0
def upgrade_to_approver():
    schema = {
        "email": {
            "type": "string"
        },
    }

    email = request.json.get("email")

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    reader_to_upgrade = Reader.query.filter_by(email=email).first()

    if not reader_to_upgrade:
        return bad_request("No user with email {0} exists.".format(email))

    if Approver.query.filter_by(
            reader_id=reader_to_upgrade.id).first() is not None:
        return bad_request(
            "User with email {0} already have the role of approver (at least)."
            .format(email))

    # Insert a new row in the Approver table, where reader_id is set to that of the specified reader.
    # To circumvent Flask object problems (inheritance etc.), this is done in "pure" SQL syntax.
    db.session.execute("INSERT INTO approver (reader_id) VALUES ({0});".format(
        reader_to_upgrade.id))
    db.session.commit()

    return ok("Reader is now an approver!")
예제 #5
0
def order_room():
    """Order access to a room for the logged in user"""
    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {
        "room_text_id": {
            "type": "string"
        },
        "justification": {
            "type": "string",
            "maxlength": 800
        }
    }

    # Get the email, room and the justification for the access to said room.
    email = get_jwt_identity()
    room_text_id = request.json.get("room_text_id")
    justification = request.json.get("justification")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    # Checks if the reader exists in the database
    reader = Reader.query.filter_by(email=email).first()
    if not reader:
        return bad_request("Reader does not exist." "")

    # Checks if the room exists in the database
    room = Room.query.filter_by(text_id=room_text_id).first()
    if not room:
        return bad_request("Room: {} does not exist." "".format(room_text_id))

    # Checks if the reader has already sent a request for this room
    rr = RoomRequest.query.filter_by(reader_id=reader.id,
                                     room_id=room.id,
                                     status=RequestStatus.PENDING).first()
    if rr:
        return bad_request("A request for this room already exists." "")

    # Gets the approver with the highest priority for this room
    rfr = ResponsibleForRoom.query \
     .filter_by(room_id=room.id) \
     .order_by(ResponsibleForRoom.priority) \
     .first()
    if rfr is None:
        return bad_request("There is no approver in charge of this room")

    # Creates a new request for the room
    room_request = RoomRequest(reader=reader,
                               room=room,
                               justification=justification)
    approves_room_request = ApprovesRoomRequest(room_request=room_request,
                                                approver=rfr.approver)
    db.session.add(room_request)
    db.session.add(approves_room_request)
    db.session.commit()
    return ok("Request for room {} has been sent." "".format(room_text_id))
예제 #6
0
def create_user(Role):
    """Creates a new user and adds to the database if correct input is given."""

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {
        "email": {
            "type": "string",
            "regex": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
        },
        "name": {
            "type": "string",
            "regex": "[a-zA-Z]+$",
            "minlength": 2,
            "maxlength": 12
        },
        "surname": {
            "type": "string",
            "regex": "[a-zA-Z]+$",
            "minlength": 2,
            "maxlength": 12
        },
        "password": {
            "type": "string"
        }
    }

    # Checks if input is illegal
    if not validator(request.json, schema):
        s = validator
        return bad_request(validator.errors)

    # Get the email, password, name and surname from the client
    email = request.json.get("email")
    password = request.json.get("password")
    name = request.json.get("name")
    surname = request.json.get("surname")

    # Checks if the email already is in use
    if Reader.query.filter_by(email=email).first() is not None:
        return bad_request("This email is already in use!")

    # Checks if the password is illegal
    not_fulfilled = validate_password(password)
    if not_fulfilled:
        return bad_request({"password": not_fulfilled})

    # Returns a new user
    new_user = Role(email=email, password=password, name=name, surname=surname)
    db.session.add(new_user)
    db.session.commit()
    return created("{} successfully created!".format(
        Role.__tablename__.capitalize()))
예제 #7
0
def approve_request():
    """Approves or denies a request to a room or an access group"""

    schema = {
        "request_id": {
            "type": "integer"
        },
        "type": {
            "type": "string"
        },
        "is_access_granted": {
            "type": "boolean"
        }
    }

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    request_id = request.json.get("request_id")
    type = request.json.get("type")
    is_access_granted = request.json.get("is_access_granted")

    # Checks if the approver exists in the database
    email = get_jwt_identity()
    current_approver = Approver.query.filter_by(email=email).first()

    if current_approver is None:
        return bad_request("{} is not in the database.".format(email))

    if type == "Room":
        if is_access_granted:
            return approve_room_request(current_approver, request_id)
        else:
            return deny_room_request(current_approver, request_id)
    elif type == "AG":
        if is_access_granted:
            return approve_ag_request(current_approver, request_id)
        else:
            return deny_ag_request(current_approver, request_id)
    else:
        return bad_request("{} is not a valid type.".format(type))
예제 #8
0
def get_readers_for_room():
    """Get all the readers with access to a room."""

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {"room_text_id": {"type": "string"}}

    # Get the email for the access to said room.
    email = get_jwt_identity()
    room_text_id = request.json.get("room_text_id")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    # Checks if the approver exists in the database
    approver = Approver.query.filter_by(email=email).first()
    if not approver:
        return bad_request("Approver does not exist!")

    # Checks if the room exists in the database
    room = Room.query.filter_by(text_id=room_text_id).first()
    if not room:
        return bad_request("Room: {} does not exist!".format(room_text_id))

    # Query
    reader_access = db.session.query(
        Room, CardReader, HasAccessTo, Reader).filter(
            HasAccessTo.card_reader_id == CardReader.id,
            HasAccessTo.reader_id == Reader.id,
            CardReader.room_b_id == Room.id,
            Room.text_id == room_text_id,
        ).all()

    # Format return message
    reader_order = [{
        "name": x.Reader.name,
        "surname": x.Reader.surname,
        "email": x.Reader.email,
        "id": x.Reader.id
    } for x in reader_access]

    return ok({"reader_access": reader_order})
예제 #9
0
def revoke_room_access():
    """Revokes a readers access to a room """
    schema = {"room_text_id": {"type": "string"}, "email": {"type": "string"}}

    email = request.json.get("email")
    room_text_id = request.json.get("room_text_id")

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    # Checks if the reader exists in the database
    reader = Reader.query.filter_by(email=email).first()
    if not reader:
        return bad_request("Reader does not exist!")

    has_access = db.session.query(Room, CardReader, HasAccessTo).filter(
        Room.text_id == room_text_id,
        or_(CardReader.room_b_id == Room.id, CardReader.room_a_id == Room.id),
        HasAccessTo.card_reader_id == CardReader.id,
        HasAccessTo.reader_id == reader.id).all()

    if not has_access:
        return bad_request("The reader does not have access to this room")

    for a in has_access:
        cr_id = a.CardReader.id
        # Delete access
        HasAccessTo.query.filter_by(card_reader_id=cr_id,
                                    reader_id=reader.id).delete()

    db.session.commit()
    return ok("Access to {0} has been removed for {1}".format(
        room_text_id, email))
예제 #10
0
def create_ag():
    """Creates a new (or changes an already existing) access group"""
    # name: The (String) name of the access group, as will be displayed.
    # approvers: a list of email addresses belonging to approvers.
    # rooms: a list of room text_ids.
    schema = {
        "ag_name": {
            "type": "string",
            "minlength": 2
        },
        "approvers": {
            "type": "list",
            "schema": {
                "type": "string",
                "regex": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
            }
        },
        "room_text_ids": {
            "type": "list",
            "schema": {
                "type": "string",
                "minlength": 2
            }
        },
    }

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    ag_name = request.json.get("ag_name")
    approvers = request.json.get("approvers")
    room_text_ids = request.json.get("room_text_ids")

    if not approvers:
        return bad_request("The list of approvers can not be empty!")

    if not room_text_ids:
        return bad_request("The list of rooms can not be empty!")

    # If the access group DOES NOT exist create it
    ag = AccessGroup.query.filter_by(name=ag_name).first()
    if not ag:
        ag = AccessGroup(name=ag_name)
        db.session.add(ag)

    # If the access group DOES exist remove the existing card readers and approvers,
    # Move all currently tasked requests to the first new approver
    else:
        ag.card_readers.clear()
        ag.approvers.clear()
        approver = Approver.query.filter_by(email=approvers[0]).first()
        if not approver:
            return bad_request("Approver does not exist!")
        for agr in AccessGroupRequest.query.filter_by(ag_id=ag.id).all():
            aagr = ApprovesAgRequest.query.filter_by(
                ag_request_id=agr.id).first()
            aagr.approver_id = approver.id

    # update approves_ag_request by taking all request_ids from ag request with this ag_id
    # change the approver id in approves request to the new approver with the highest priority
    priority = 1  # First approver in list get highest priority, and so on.
    for approver_email in request.json.get("approvers"):
        approver = Approver.query.filter_by(email=approver_email).first()
        if not approver:
            return bad_request("Approver does not exist!")
        rfag = ResponsibleForAg(approver=approver, ag=ag,
                                priority=priority)  # Add and commit?
        db.session.add(rfag)
        priority += 1

    # Check if all rooms does exist
    list_of_rooms = []
    for room_text_id in room_text_ids:
        room = Room.query.filter_by(text_id=room_text_id).first()
        if not room:
            return bad_request("Room {} does not exist!".format(room_text_id))
        list_of_rooms.append(room)

    # Get a list of all card readers that link the rooms together
    list_of_room_ids = [room.id for room in list_of_rooms]
    list_of_card_readers = CardReader.query.filter(
        and_(CardReader.room_b_id.in_(list_of_room_ids),
             CardReader.room_a_id.in_(list_of_room_ids))).all()

    # Check if the rooms are connected to eachother by card readers
    temp_rooms = Room.query.filter(
        Room.id.in_([cr.room_b_id for cr in list_of_card_readers])).all()
    requested_rooms = [room.text_id for room in list_of_rooms]
    resulting_rooms = [room.text_id for room in temp_rooms]
    diff = [room for room in requested_rooms if room not in resulting_rooms]
    if diff:
        return bad_request(
            "The room(s) {} has no card readers connecting to the rest of the rooms!"
            .format(diff))

    ag.card_readers = list_of_card_readers
    db.session.commit()
    return ok("Access Group was successfully created!")
예제 #11
0
def order_ag():
    """Order access to a access group for the logged in user"""

    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    schema = {
        "ag_id": {
            "type": "integer"
        },
        "justification": {
            "type": "string",
            "maxlength": 220
        }
    }

    # Get the email, access group and the justification for the access to said access group.
    email = get_jwt_identity()
    ag_id = request.json.get("ag_id")
    justification = request.json.get("justification")

    # Checks if any of the input is illegal
    if not validator(request.json, schema):
        return bad_request(validator.errors)

    # Checks if the reader exists in the database
    reader = Reader.query.filter_by(email=email).first()
    if not reader:
        return bad_request("Reader does not exists.")

    # Checks if the access group exists in the database
    ag = AccessGroup.query.filter_by(id=ag_id).first()
    if not ag:
        return bad_request("Access group does not exist.".format(ag_id))

    # Checks if the reader has already sent a request for this access group
    agr = AccessGroupRequest.query.filter_by(
        ag_id=ag_id, reader_id=reader.id,
        status=RequestStatus.PENDING).first()
    if agr:
        return bad_request("A request for this access group already exists.")

    # Gets the approver with the highest priority for this access group
    rfag = ResponsibleForAg.query \
     .filter_by(ag_id=ag_id) \
     .order_by(ResponsibleForAg.priority) \
     .first()
    if rfag is None:
        return bad_request(
            "There is no approver in charge of this access group.")

    # Creates a new request for the access group
    ag_request = AccessGroupRequest(reader=reader,
                                    ag=ag,
                                    justification=justification)
    approves_ag_request = ApprovesAgRequest(ag_request=ag_request,
                                            approver=rfag.approver)
    db.session.add(ag_request)
    db.session.add(approves_ag_request)
    db.session.commit()
    return ok("Request for access group {} has been sent.".format(ag_id))