def create_event(current_admin: Administrator): """Create a new event""" # pylint: disable=unused-argument body = flask_rebar.get_validated_body() name = body["name"] teams = body["teams"] is_open = body["is_open"] is_visible = body["is_visible"] front_page = body["front_page"] if "front_page" in body else "" flag_format = body["flag_format"] if "flag_format" in body else "" event = Event.query.filter_by(name=name).first() if event: raise errors.UnprocessableEntity( "An event with that name already exists") event = Event(name=name, front_page=front_page, flag_format=flag_format, is_open=is_open, is_visible=is_visible, teams=teams) DB.session.add(event) DB.session.commit() return event
def send_team_request(current_participant: Participant): """Request to join a team.""" body = flask_rebar.get_validated_body() team_id = body["team_id"] team_member = current_participant.get_team() if team_member is not None: raise errors.UnprocessableEntity( "You cannot request to join a team if you already are in a team.") team = Team.query.filter_by(id=team_id).first() if team is None: raise errors.UnprocessableEntity("The team doesn't exist.") # FIXMEFUTURE: If team is not already full # (on a pas de configuration pour le nombre de membres d'une équipe for now) team_request = TeamRequest.query.filter_by( participant_id=current_participant.id).first() if team_request is not None: raise errors.UnprocessableEntity( "You already have requested to join a team.") team_request = TeamRequest(team_id=team_id, participant_id=current_participant.id) DB.session.add(team_request) DB.session.commit() return ""
def create_category(current_admin: Administrator): """Add a category """ body = flask_rebar.get_validated_body() name = body["name"] event_id = body["event_id"] event = Event.query.filter_by(id=event_id).first() if event is None: raise errors.NotFound(f'Event with id "{event_id}" not found.') if not current_admin.is_admin_of_event(event_id): raise errors.Unauthorized( "You do not have the permission to administer this event.") category = Category.query.filter_by(name=name, event_id=event_id).first() if category is not None: raise errors.UnprocessableEntity( "A category with that name already exists") category = Category(name=name, event_id=event_id) DB.session.add(category) DB.session.commit() return category
def create_item(): validated_body = get_validated_body() tags = [] for tag_detail in validated_body.pop("tags"): tag, _ = TagModel.get_or_create(value=tag_detail["value"]) tags.append(tag) try: category_id = validated_body.pop("category")["id"] category = CategoryModel.get(id=category_id) except CategoryModel.DoesNotExist: raise NotFound(f"Category {category_id} does not exist") try: brand_id = validated_body.pop("brand")["id"] brand = BrandModel.get(id=brand_id) except BrandModel.DoesNotExist: raise NotFound(f"Brand {brand_id} does not exist") item = ItemModel.create( user=current_user.id, brand=brand.id, category=category.id, **validated_body, ) item.tags.add(tags) return item
def submit_flag(challenge: Challenge, event: Event): """Submit a flag for a given challenge""" body = flask_rebar.get_validated_body() submitted_flag = body["flag"] team = current_user.get_team() if team is None: raise errors.NotFound(f'Current user has no team.') if event.id != team.event_id: raise errors.UnprocessableEntity( f'Team "{team.name}" and challenge "{challenge.id}" are not part of the same event') submission = Submission(team_id=team.id, challenge_id=challenge.id, input=submitted_flag) flags = Flag.query.filter_by(challenge_id=challenge.id).all() is_correct = any(validate_flag(x, submitted_flag) for x in flags) submission.is_correct = is_correct DB.session.add(submission) DB.session.commit() return {'correct': is_correct}
def register_administrator(): """Register a new user""" body = flask_rebar.get_validated_body() email = body["email"] username = body["username"] password = body["password"] # Validate user uniqueness constraint. user = User.query.filter_by(email=email).first() if user is not None: administrator = user.get_administrator() if administrator is not None: raise errors.UnprocessableEntity("An administrator with that email already exists") user = User.query.filter_by(username=username).first() if user is not None: administrator = user.get_administrator() if administrator: raise errors.UnprocessableEntity("An administrator with that username already exists for this event") user = User(email=email, username=username) user.set_password(password) administrator = Administrator(is_platform_admin=False, user=user) DB.session.add(administrator) DB.session.commit() return administrator, 201
def post_documents(): ### # Receive a posted document, and return the document id ## errors = [] request = flask_rebar.get_validated_body() app.logger.debug(request) rc = 201 if not request.get('title').strip(): raise err.BadRequest('Empty title is not allowed') # The API will be responsible for generating the document ID ## Normalize name. Note: this also commits the record, to avoid a race doc_id = normalize_doc_id(request['title']) # Create a new doc doc = Document( doc_id=doc_id, title=request['title'], text=request['text'] ) db.session.add(doc) db.session.commit() return { 'document': doc, 'errors': errors, }, rc
def accept_team_request(current_participant: Participant): """Accepts a team request. Only captains can accept a request.""" body = flask_rebar.get_validated_body() participant_id = body["participant_id"] current_member = TeamMember.query.filter_by( participant_id=current_participant.id).first() if not current_member or not current_member.captain: raise errors.Unauthorized( "You don't have the rights to accept this request.") # Remove TeamRequest and add the new member team_request = TeamRequest.query.filter_by( team_id=current_member.team_id, participant_id=participant_id).first() if team_request is None: raise errors.UnprocessableEntity("The request doesn't exist.") new_member = TeamMember(participant_id=participant_id, team_id=current_member.team_id) DB.session.delete(team_request) DB.session.add(new_member) DB.session.commit() return ""
def create_team(current_participant: Participant): """Create a team for a given event.""" body = flask_rebar.get_validated_body() team_name = body["team_name"] if not team_name: raise errors.UnprocessableEntity("Please choose a team name") team = current_participant.get_team() if team is not None: raise errors.UnprocessableEntity( "You cannot create a team if you already are in a team.") team = Team.query.filter_by(name=team_name).first() if team is not None: raise errors.UnprocessableEntity( "A team with that name already exists.") team = Team(name=team_name, event_id=current_participant.event_id, members=[ TeamMember(participant_id=current_participant.id, captain=True) ]) DB.session.add(team) DB.session.commit() return team
def recognize(): """ Face Recognition REST API Parameters: refFaceImage (string): Base64 string data of reference image (or, first image) unknownFaceImage (string): Base64 string data of unknown image (or, second image) detectionModel (string): Model name for face detection. Expected values: hog, cnn. Default: hog landmarkModel (string): Model name for landmark detection. Expected values: large, small. Default: large detectionUpsampleCount (int): Detection up-sample count. Default: 1 landmarkJittersCount (int): Landmark jitter count. Default: 10 Returns: matching (boolean): The two faces match or not. distance (float): Distance of the two faces. (0-1) """ body = flask_rebar.get_validated_body() logging.info("Detection Model: %s, Landmark Model: %s", body['detectionModel'], body['landmarkModel']) tolerance = current_app.config['FACE_RECOGNITION_DLIB_DISTANCE_TOLERANCE'] face_distance = recognition.distance( reference_image=body['refFaceImage'], unknown_image=body['unknownFaceImage'], image_format="base64", detection_number_of_times_to_upsample=body['detectionUpsampleCount'], detection_model=body['detectionModel'], num_jitters=body['landmarkJittersCount'], landmark_model=body['landmarkModel']) distance = BaseFaceRecognitionResponseSchema() distance.distance = face_distance distance.matching = face_distance < tolerance return distance, 200
def create_account(): body = flask_rebar.get_validated_body() account = Account(**body) db.session.add(account) db.session.commit() return account, 201
def replace_account(account_id: UUID): body = flask_rebar.get_validated_body() account = Account.query.filter_by(id=account_id).update(body) if account is None: raise errors.NotFound() db.session.commit() return "", 204
def update_list_item(id): data = get_validated_body() updated_items = (ListModel.update(**data).where( ListModel.id == id, ListModel.is_deleted == False).execute()) if not updated_items: raise NotFound return ListModel.get(id=id, is_deleted=False)
def edit_challenge(current_admin: Administrator, challenge_id: int): """Edit a challenge and its associated ressources (flags, links, files)""" body = flask_rebar.get_validated_body() name = body["name"] points = body["points"] hidden = body["hidden"] description = body["description"] category_id = body["category_id"] flags = body["flags"] editable_challenge = Challenge.query.filter_by(id=challenge_id).first() if editable_challenge is None: raise errors.UnprocessableEntity("This challenge does not exist.") if not current_admin.is_admin_of_event( editable_challenge.category.event_id): raise errors.Unauthorized( "You do not have the permission to administer this challenge.") if category_id != editable_challenge.category_id: category = Category.query.filter_by( id=category_id, event_id=editable_challenge.category.event_id).first() if category is None: raise errors.UnprocessableEntity("The category doesn't exist.") if name != editable_challenge.name: if not name: raise errors.UnprocessableEntity("Name must not be empty.") challenge = Challenge.query.filter_by(name=name).first() if challenge is not None: raise errors.UnprocessableEntity( "A challenge with that name already exists.") if points != editable_challenge.points and points <= 0: raise errors.UnprocessableEntity("Points must be positive.") editable_challenge.name = name editable_challenge.points = points editable_challenge.hidden = hidden editable_challenge.description = description editable_challenge.category_id = category_id flag_objects = list( map(lambda flag: Flag(is_regex=flag['is_regex'], value=flag['value']), flags)) editable_challenge.flags = flag_objects DB.session.commit() return editable_challenge
def update_author(author_id: int): body = flask_rebar.get_validated_body() author = author_service.update(author_id, body) if author is None: logging.error("Author is not found for [author_id=%s]", author_id) raise errors.NotFound( msg="Author is not found for [author_id={}]".format(author_id), additional_data={ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") }) return author, 200
def network_copy(device_id): body = flask_rebar.get_validated_body() to_host_device = body["toHost"] payload = {"from_host_id": device_id, "to_host_device": to_host_device} function_name = f"{constants.STAGE}-vdo-ops-network_copy" response = lambda_client.invoke(FunctionName=function_name, Payload=json.dumps(payload)) if "FunctionError" in response: raise errors.InternalError(response["FunctionError"]) return {"success": "successfully copied network settings"}, 202
def login(): validated_body = get_validated_body() try: user = UserModel.get(username=validated_body.get("username"), is_deleted=False) except UserModel.DoesNotExist: raise NotFound if user.key.tobytes() != get_hash(password=validated_body.get("password"), salt=user.salt): raise Unauthorized login_user(user=user) return user
def create_user(): validated_body = get_validated_body() salt = os.urandom(32) try: user = UserModel.create( username=validated_body.get("username"), email_address=validated_body.get("email_address"), salt=salt, key=get_hash(password=validated_body.get("password"), salt=salt), ) except IntegrityError: raise BadRequest() except Exception as e: pass return user, 201
def register_participant(event: Event): """Register a new user""" body = flask_rebar.get_validated_body() email = body["email"] username = body["username"] password = body["password"] if not username: raise errors.UnprocessableEntity("Please choose a username") # Validate user uniqueness constraint. user = User.query.filter_by(email=email).first() if user is not None: participant = user.get_participant() if user is not None and participant and participant.event_id == event.id: raise errors.UnprocessableEntity("A participant with that email already exists for this event") user = User.query.filter_by(username=username).first() if user is not None: participant = user.get_participant() if user is not None and participant and participant.event_id == event.id: raise errors.UnprocessableEntity("A participant with that username already exists for this event") user = User(email=email, username=username) user.set_password(password) participant = Participant(event_id=event.id, user=user) DB.session.add(participant) if not event.teams: # means that its a solo event, need to create a team with the participant in it. team = Team(event_id=event.id, name=user.username, members=[TeamMember(participant=participant, captain=True)]) DB.session.add(team) DB.session.commit() login_user(participant.user, remember=True) return participant, 201
def login_administrator(): """Login an administrator""" body = flask_rebar.get_validated_body() email = body["email"] password = body["password"] remember = body["remember"] if "remember" in body else False user = User.query.filter_by(email=email).first() if user is None or not user.check_password(password): raise errors.UnprocessableEntity("Invalid email or password.") administrator = user.get_administrator() if administrator is None: raise errors.Unauthorized("You must be an administrator to access this resource.") login_user(user, remember=remember) return administrator
def login(event: Event): """Login a participant""" body = flask_rebar.get_validated_body() email = body["email"] password = body["password"] remember = body["remember"] participant = Participant.query\ .join(Participant.user) \ .filter(User.email == email, Participant.event_id == event.id)\ .first() if participant is None or participant.user is None or not participant.user.check_password(password): raise errors.UnprocessableEntity("Invalid email or password.") login_user(participant.user, remember=remember) return participant
def kick_team_member(current_participant: Participant): """Kick a member of the team. Only captains can kick a team member""" body = flask_rebar.get_validated_body() participant_id = body["participant_id"] current_member = TeamMember.query.filter_by( participant_id=current_participant.id).first() if not current_member or not current_member.captain: raise errors.Unauthorized( "You don't have the rights to kick a team member.") if participant_id == current_participant.id: raise errors.UnprocessableEntity( "You cannot kick yourself from a team.") team_member = TeamMember.query.filter_by( participant_id=participant_id).first() DB.session.delete(team_member) DB.session.commit() return ""
def put_document(doc_id: str): ### # Update a document by doc_id ## errors = [] request = flask_rebar.get_validated_body() app.logger.debug(request) rc = 204 # Get the document from the store by ID doc = Document.query.get(doc_id) if not doc: # Create a new doc app.logger.debug(f'Creating new doc via PUT: {doc_id}') doc = Document( doc_id = doc_id, title = request['title'], text = request['text'], created = datetime.utcnow() ) db.session.add(doc) db.session.commit() rc = 201 else: # Update existing app.logger.debug(f'Updated existing doc via PUT: {doc_id}') doc.title = request['title'] doc.text = request['text'] doc.updated = datetime.utcnow() db.session.add(doc) db.session.commit() return { 'errors': errors, }, rc
def edit_event(current_admin: Administrator, event_id: int): """Edit an new event""" # pylint: disable=unused-argument body = flask_rebar.get_validated_body() name = body["name"] teams = body["teams"] is_open = body["is_open"] is_visible = body["is_visible"] front_page = body["front_page"] if "front_page" in body else "" flag_format = body["flag_format"] if "flag_format" in body else "" editable_event = Event.query.filter_by(id=event_id).first() if editable_event is None: raise errors.NotFound(f'Event with id "{event_id}" not found.') if name != editable_event.name: if not name: raise errors.UnprocessableEntity("Name must not be empty.") event = Event.query.filter_by(name=name).first() if event is not None: raise errors.UnprocessableEntity( "An event with that name already exists.") editable_event.name = name editable_event.front_page = front_page editable_event.flag_format = flag_format editable_event.is_open = is_open editable_event.is_visible = is_visible editable_event.teams = teams DB.session.commit() return editable_event
def change_role(current_participant: Participant): """Change the role of a team member. Only captains can change a team member's role""" body = flask_rebar.get_validated_body() participant_id = body["participant_id"] new_role = body["captain"] current_member = TeamMember.query.filter_by( participant_id=current_participant.id).first() if not current_member or not current_member.captain: raise errors.Unauthorized( "You don't have the rights to change a team member's role.") if participant_id == current_participant.id: # In order to avoid a team "bricking" itself raise errors.UnprocessableEntity( "You cannot remove your own privileges.") team_member = TeamMember.query.filter_by( participant_id=participant_id).first() team_member.captain = new_role DB.session.commit() return ""
def create_list(): data = get_validated_body() list_item = ListModel.create(author=current_user.id, **data) return list_item
def create_author(): body = flask_rebar.get_validated_body() author = Author(**body) author = author_service.save(author) return author, 201
def create_book(): body = flask_rebar.get_validated_body() book = Book(**body) book = book_service.save(book) return book, 201