Example #1
0
def delete_user(reader_email):
    """Permanently deletes a reader, approver or admin and all attached information from the database."""
    reader = Reader.query.filter_by(email=reader_email).first()
    email = get_jwt_identity()

    if not reader:
        return bad_request("Reader {} does not exist.".format(reader_email))

    if reader_email == email:
        return bad_request(
            "Deleting own account not allowed."
        )  # a safety to prevent the system from having no admins

    approver = Approver.query.filter_by(reader_id=reader.id).first()
    admin = Admin.query.filter_by(approver_id=reader.id).first()

    if admin:
        db.session.delete(admin)
    elif approver:
        db.session.delete(approver)  # TODO move approvals to next approver
    else:
        db.session.delete(reader)

    db.session.commit()

    return ok("Reader was successfully deleted")
Example #2
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))
Example #3
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!")
Example #4
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.")
Example #5
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.")
Example #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()))
Example #7
0
def is_admin():
    """ Checks if the request comes from a user that is admin."""
    try:
        email = decode_token(
            request.headers.get('Authorization')[7:])["identity"]

        current_admin = Admin.query.filter_by(email=email).first()
    except IndexError:
        return bad_request("User is not an admin")

    if current_admin is None:
        return bad_request("User is not an admin")
Example #8
0
def remove_card(email):

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

    if not reader:
        return bad_request("No reader with email {}.".format(email))

    if not reader.card_id:
        return bad_request("Card has already been cleared.")

    reader.block_card()
    db.session.commit()

    return ok("Card for reader was cleared.")
Example #9
0
def approve_ag_request(current_approver, ag_request_id):
    """Approves a request to an access group"""

    # get the approves_ag_request, access_group_request and reader objects related to the given access_group_request
    res = db.session.query(ApprovesAgRequest, AccessGroupRequest, AccessGroup, Reader) \
     .join(AccessGroupRequest, AccessGroupRequest.id == ApprovesAgRequest.ag_request_id) \
     .join(AccessGroup, AccessGroup.id == AccessGroupRequest.ag_id) \
     .join(Reader, Reader.id == AccessGroupRequest.reader_id) \
     .filter(ApprovesAgRequest.approver_id == current_approver.id,
       AccessGroupRequest.id == ag_request_id, AccessGroupRequest.status == RequestStatus.PENDING).first()

    if res is None:
        return bad_request(
            "{} not a valid ag request for approver.".format(ag_request_id))

    approves_request = res[0]
    ag_req = res[1]
    ag = res[2]
    reader = res[3]

    expire_date = date.today() + timedelta(days=HALF_YEAR)

    new_belongs_to = BelongsTo(reader, ag, expire_date)

    db.session.add(new_belongs_to)
    db.session.delete(approves_request)
    ag_req.status = RequestStatus.APPROVED
    db.session.commit()

    return ok('Request for ag was approved')
Example #10
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))
Example #11
0
def save_map():
    """Saves the representation of the map in locale file"""
    # Checks if the request is a json
    if not request.is_json:
        return bad_request("Missing JSON in request")

    pickle.dump(request.json, open("map_repr.pickle", "wb"))
    return ok("File has been saved!")
Example #12
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})
Example #13
0
def get_reader(reader_id):
    """Returns a reader with given id."""

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

    return reader.serialize
Example #14
0
def get_all_access_helper(email, room_filter=None):
    """ Returns a list of all access of the reader with the given email"""

    # 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.")

    # get room and belongsto for all rooms current user has access to from access groups as a list of tuples
    ag_access = db.session.query(Room, BelongsTo) \
     .join(CardReader, CardReader.room_b_id == Room.id) \
     .join(gives_access_to, gives_access_to.c.cr_id == CardReader.id) \
     .join(AccessGroup, AccessGroup.id == gives_access_to.c.ag_id) \
     .join(BelongsTo, BelongsTo.ag_id == AccessGroup.id) \
     .filter_by(reader_id=reader.id) \
     .all()

    # get room and belongs to for all rooms current user has access to as a list of tuples
    room_access = db.session.query(Room, HasAccessTo) \
     .join(CardReader, CardReader.room_b_id == Room.id) \
     .join(HasAccessTo, HasAccessTo.card_reader_id == CardReader.id) \
     .filter_by(reader_id=reader.id) \
     .all()

    # build a dict to return in JSON format
    return_dict = {}

    date_next_month = date.today() + relativedelta(months=+1)

    all_rooms = Room.query.all()
    if room_filter == None:  # equals is intended, empty list should not enter.
        room_filter = [r.text_id for r in all_rooms]

    for room in all_rooms:
        ag = _find_room_helper(ag_access, room)
        r = _find_room_helper(room_access, room)

        has_access = ((ag is not None) or
                      (r is not None)) and room.text_id in room_filter
        # python or takes object when using "ag or r"...

        room_json = {}  # dictionay object for this room's metadata
        #room_json["approvers"] = [approver.approver.serialize for approver in room.approvers]
        room_json["access"] = has_access
        room_json["name"] = room.name
        if has_access:
            if ag:
                room_json["expires"] = ag.expiration_datetime
                room_json["ag_id"] = ag.ag_id
            else:
                room_json["expires"] = r.expiration_datetime
            if room_json["expires"].date() < date_next_month:
                room_json["warn_date"] = True
        return_dict[room.text_id] = room_json

    return ok(return_dict)
Example #15
0
def get_current_reader():
    """Returns the current users data"""

    # Get the email from the reader
    email = get_jwt_identity()
    current_reader = Reader.query.filter_by(email=email).first()

    # Checks if the reader is in the database
    if current_reader is None:
        return bad_request("{} is not in the database.".format(email))

    return ok(current_reader.serialize)
Example #16
0
def get_responsibilities():
    """Returns a list of the rooms in the approvers responsibility."""
    email = get_jwt_identity()

    # Checks if the reader is an approver
    approver = Approver.query.filter_by(email=email).first()
    if not approver:
        return bad_request("This user does not have the approver role!")

    room_list = get_responsibilites_helper(approver)

    return ok({"responsibilities": room_list})
Example #17
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))
Example #18
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))
Example #19
0
def get_all_access_for_reader(email):
    """Get a list of all access the reader with the given email has."""

    approver_email = get_jwt_identity()
    approver = Approver.query.filter_by(email=approver_email).first()
    if not approver:
        return bad_request("This user does not have the approver role!")

    # if the user is an admin display all rooms regardless
    admin = Admin.query.filter_by(approver_id=approver.id).first()
    if admin:
        return get_all_access_helper(email)

    # display all rooms that the approver has responsibility over
    approver_rooms = get_responsibilites_helper(approver)
    return get_all_access_helper(email, approver_rooms)
Example #20
0
def approve_room_request(current_approver, room_request_id):
    """Approves a request to a room"""

    # get the approves_room_request, room_request and reader objects related to the given room_request
    res = db.session.query(ApprovesRoomRequest, RoomRequest, Reader) \
     .join(RoomRequest, RoomRequest.id == ApprovesRoomRequest.room_request_id) \
     .join(Reader, Reader.id == RoomRequest.reader_id) \
     .filter(ApprovesRoomRequest.approver_id == current_approver.id,
       RoomRequest.id == room_request_id, RoomRequest.status == RequestStatus.PENDING).first()

    if res is None:
        return bad_request("{} not a valid room request for approver.".format(
            room_request_id))

    approves_request = res[0]
    room_req = res[1]
    reader = res[2]

    # request is valid, add access to card readers for the user that lead to the room

    reader_ids = _find_accesible_doors_to_room_helper(reader.id,
                                                      room_req.room_id)
    opposites = _find_opposite_reader_helper(reader_ids)

    expire_date = date.today() + timedelta(days=HALF_YEAR)

    for card_reader_pair in opposites:
        reader_to = card_reader_pair[0]
        reader_from = card_reader_pair[1]
        new_access_to = HasAccessTo(reader, reader_to, expire_date)
        new_access_from = HasAccessTo(reader, reader_from, expire_date)
        db.session.add(new_access_to)
        db.session.add(new_access_from)

    for card_reader in CardReader.query.filter_by(room_b_id=room_req.room_id,
                                                  room_a_id=None).all():
        new_access_to = HasAccessTo(reader, card_reader, expire_date)
        db.session.add(new_access_to)

    db.session.delete(approves_request)
    room_req.status = RequestStatus.APPROVED

    db.session.commit()

    return ok('Request for room was approved')
Example #21
0
def get_orders():
    """Returns a list of all requests done"""

    # Get the email from the user making the request
    email = get_jwt_identity()

    # 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.")

    # Gets a list of all the users requested rooms
    room_relation = RoomRequest.query \
     .filter_by(reader_id=reader.id) \
     .join(Room, Room.id == RoomRequest.room_id) \
     .join(ApprovesRoomRequest, ApprovesRoomRequest.room_request_id == RoomRequest.id) \
     .join(Reader, Reader.id == ApprovesRoomRequest.approver_id) \
     .all()
    room_orders = [{
        "room_id": x.room_id,
        "name": x.room.name.capitalize(),
        "approver": x.request_approver.approver.email,
        "date": x.datetime_requested,
        "type": "Room"
    } for x in room_relation]

    # Gets a list of all the users requested access groups
    ag_relation = AccessGroupRequest.query \
     .filter_by(reader_id=reader.id) \
     .join(AccessGroup, AccessGroup.id == AccessGroupRequest.ag_id) \
     .join(ApprovesAgRequest, ApprovesAgRequest.ag_request_id == AccessGroupRequest.id) \
     .join(Reader, Reader.id == ApprovesAgRequest.approver_id) \
     .all()
    ag_orders = [{
        "ag_id": x.ag_id,
        "name": x.ag.name.capitalize(),
        "approver": x.request_approver.approver.email,
        "date": x.datetime_requested,
        "type": "Access group"
    } for x in ag_relation]

    return ok({"orders": room_orders + ag_orders})
Example #22
0
def deny_room_request(current_approver, room_request_id):
    """Denies a request to a room"""

    # get the approves_room_request, room_request and reader objects related to the given room_request
    res = db.session.query(ApprovesRoomRequest, RoomRequest) \
     .join(RoomRequest, RoomRequest.id == ApprovesRoomRequest.room_request_id) \
     .filter(ApprovesRoomRequest.approver_id == current_approver.id,
       RoomRequest.id == room_request_id, RoomRequest.status == RequestStatus.PENDING).first()

    if res is None:
        return bad_request("{} not a valid room request for approver.".format(
            room_request_id))

    approves_request = res[0]
    room_req = res[1]

    db.session.delete(approves_request)
    room_req.status = RequestStatus.DENIED
    db.session.commit()

    return ok('Request for room was denied')
Example #23
0
def deny_ag_request(current_approver, ag_request_id):
    """Denies a request to an access group"""

    # get the approves_ag_request, access_group_request and reader objects related to the given access_group_request
    res = db.session.query(ApprovesAgRequest, AccessGroupRequest) \
     .join(AccessGroupRequest, AccessGroupRequest.id == ApprovesAgRequest.ag_request_id) \
     .filter(ApprovesAgRequest.approver_id == current_approver.id,
       AccessGroupRequest.id == ag_request_id, AccessGroupRequest.status == RequestStatus.PENDING).first()

    if res is None:
        return bad_request(
            "{} not a valid ag request for approver.".format(ag_request_id))

    approves_request = res[0]
    ag_req = res[1]

    db.session.delete(approves_request)
    ag_req.status = RequestStatus.DENIED
    db.session.commit()

    return ok('Request for access group was denied')
Example #24
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))
Example #25
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!")