def start_game(db_session, user_session): if user_session.get("lobby_id", None) is not None: lobby_id = user_session["lobby_id"] lobby = db_session.query(Lobby).get(lobby_id) else: raise NotFound("User is not in a lobby.") if user_session.get("round_id", None) is not None: raise Conflict("User is already in a game.") if not len(lobby.players) > 2: raise Conflict("Lobby must have at least 2 players to start game.") new_round = lobby.start_new_game(db_session) user_session["round_id"] = new_round.id return { "round_id": new_round.id }
def patch(self, document_guid=None): if document_guid is None: raise BadRequest('Must specify document GUID in PATCH') file_path = cache.get(FILE_UPLOAD_PATH(document_guid)) if file_path is None or not os.path.lexists(file_path): raise NotFound('PATCH sent for a upload that does not exist') request_offset = int(request.headers.get('Upload-Offset', 0)) file_offset = cache.get(FILE_UPLOAD_OFFSET(document_guid)) if request_offset != file_offset: raise Conflict( "Offset in request does not match uploaded file's offset") chunk_size = request.headers.get('Content-Length') if chunk_size is None: raise BadRequest('No Content-Length header in request') chunk_size = int(chunk_size) new_offset = file_offset + chunk_size file_size = cache.get(FILE_UPLOAD_SIZE(document_guid)) if new_offset > file_size: raise RequestEntityTooLarge( 'The uploaded chunk would put the file above its declared file size.' ) try: with open(file_path, "r+b") as f: f.seek(file_offset) f.write(request.data) except IOError as e: raise InternalServerError('Unable to write to file') if new_offset == file_size: # File transfer complete. doc = DocumentManager.find_by_document_manager_guid(document_guid) doc.upload_completed_date = datetime.utcnow() doc.save() cache.delete(FILE_UPLOAD_SIZE(document_guid)) cache.delete(FILE_UPLOAD_OFFSET(document_guid)) cache.delete(FILE_UPLOAD_PATH(document_guid)) else: # File upload still in progress cache.set(FILE_UPLOAD_OFFSET(document_guid), new_offset, TIMEOUT_24_HOURS) response = make_response('', 204) response.headers['Tus-Resumable'] = TUS_API_VERSION response.headers['Tus-Version'] = TUS_API_SUPPORTED_VERSIONS response.headers['Upload-Offset'] = new_offset response.headers[ 'Access-Control-Expose-Headers'] = "Tus-Resumable,Tus-Version,Upload-Offset" return response
def delete(environment_id): with make_session() as session: data = session.query(Environment).filter( Environment.id == environment_id).first() # type: Environment if data is None: raise NotFound("Requested environment does not exist") if data.in_use(): raise Conflict("Requested environment is in use") session.delete(data) return make_empty_response()
def post(state): assert isinstance(state, State) with get_cursor() as cursor: conflicts = StateTag.__get_name_conflicts(state, cursor) if len(conflicts): report = ', by '.join([ f'{c.state_id} from {c.validity_start.year} to {c.validity_end.year}' for c in conflicts ]) raise Conflict(f'names are already taken by {report} ') return StateCRUD.add(cursor, state)
def update_user(username, data): user = db.session.query(User).filter( User.username == username).first_or_404() if data['email'] != user.email: conflict = User.query.filter(User.email == data['email']).first() if conflict: raise Conflict('Email %s is existed' % data['email']) for key, value in data.items(): setattr(user, key, value) db.session.flush() return user
def post(self, name): """ --- summary: Create a new group description: | Creates a new group. Requires `manage_users` capability. security: - bearerAuth: [] tags: - group parameters: - in: path name: name schema: type: string description: Group name responses: 200: description: When group was created successfully 400: description: When group name or request body is invalid 403: description: When user doesn't have `manage_users` capability 409: description: When group exists yet """ schema = GroupSchema() obj = schema.loads(request.get_data(as_text=True)) if obj.errors: return {"errors": obj.errors}, 400 group_name_obj = GroupNameSchemaBase().load({"name": name}) if group_name_obj.errors: return {"errors": group_name_obj.errors}, 400 if db.session.query(exists().where(Group.name == name)).scalar(): raise Conflict("Group exists yet") group = Group() group.name = name group.capabilities = obj.data.get("capabilities") or [] db.session.add(group) db.session.commit() logger.info('group created', extra={ 'group': group.name, 'capabilities': group.capabilities }) schema = GroupSchema() return schema.dump({"name": obj.data.get("name")})
def post(self) -> dict[str, Union[list[dict], dict[str, str]]]: data = UserSchema().load(request.json) # Check if user already exists if UserModel.query.filter_by(username=data['username']).first(): raise Conflict( f"User with username '{data['username']}' already exists.") elif UserModel.query.filter_by(email=data['email']).first(): raise Conflict(f"User with email {data['email']} already exists.") password = data.pop('password') user = UserModel(**data) user.password = password db.session.add(user) db.session.commit() return { 'data': [user.to_dict()], 'message': { 'text': f'Registered user "{user.username}" Successfully!!', 'priority': 'success' } }
def update(company: m_Company): try: if 'id' in request.json: company.id = request.json['id'] if 'user_id' in request.json: company.user_id = request.json['user_id'] db.session.commit() return m_company_schema.dump(company) except IntegrityError as e: raise Conflict(e.orig.args[1]) except SQLAlchemyError as e: raise InternalServerError(e.orig.args[1])
def change_respondent(payload, session): """ Modify an existing respondent's email address, identified by their current email address. """ v = Validator(Exists('email_address', 'new_email_address')) if not v.validate(payload): logger.info("Payload for change respondent was invalid", errors=v.errors) raise BadRequest(v.errors, 400) email_address = payload['email_address'] new_email_address = payload['new_email_address'] respondent = query_respondent_by_email(email_address, session) if not respondent: logger.info("Respondent does not exist") raise NotFound("Respondent does not exist") if new_email_address == email_address: return respondent.to_respondent_dict() respondent_with_new_email = query_respondent_by_email( new_email_address, session) if respondent_with_new_email: logger.info("Respondent with email already exists") raise Conflict("New email address already taken") respondent.pending_email_address = new_email_address # check if respondent has initiated this request if 'change_requested_by_respondent' in payload: verification_url = PublicWebsite().confirm_account_email_change_url( new_email_address) personalisation = { 'CONFIRM_EMAIL_URL': verification_url, 'FIRST_NAME': respondent.first_name } logger.info('Account change email URL for party_id', party_id=str(respondent.party_uuid), url=verification_url) _send_account_email_change_email( personalisation, template='verify_account_email_change', email=new_email_address, party_id=respondent.party_uuid) else: _send_email_verification(respondent.party_uuid, new_email_address) logger.info('Verification email sent for changing respondents email', respondent_id=str(respondent.party_uuid)) return respondent.to_respondent_dict()
def validate_audit_boards( audit_boards: List[JSONDict], election: Election, jurisdiction: Jurisdiction, round: Round, ): current_round = get_current_round(election) if not current_round or round.id != current_round.id: raise Conflict(f"Round {round.round_num} is not the current round") if any(ab for ab in jurisdiction.audit_boards if ab.round_id == round.id): raise Conflict( f"Audit boards already created for round {round.round_num}") validate(audit_boards, { "type": "array", "items": CREATE_AUDIT_BOARD_REQUEST_SCHEMA }) if len(set(ab["name"] for ab in audit_boards)) != len(audit_boards): raise BadRequest("Audit board names must be unique")
def post(territory): assert isinstance(territory, Territory) with get_cursor() as cursor: state = StateCRUD.get(cursor, territory.state_id) if territory.validity_start < state.validity_start or territory.validity_end > state.validity_end: raise Conflict( f"Cannot add territory ({territory.validity_start} , {territory.validity_end}) to state ({state.validity_start}, {state.validity_end}) : period overflows" ) potentially_intersecting = TerritoryCRUD.get_within_bbox_in_period( cursor, territory.bounding_box, territory.validity_start, territory.validity_end, 0) t_conflict_ids = [ other.territory_id for other in potentially_intersecting if territories_conflict(territory, other) ] if len(t_conflict_ids): raise Conflict( f"Cannot add the territory : it conflicts with territories {t_conflict_ids}" ) compressed_territory = compress_territory(territory) return TerritoryCRUD.add(cursor, compressed_territory)
def post(self): """ --- summary: Register new OIDC provider description: | Register new OpenID Connect provider security: - bearerAuth: [] tags: - auth requestBody: description: OpenID Connect configuration content: application/json: schema: OpenIDProviderCreateRequestSchema responses: 200: description: When provider is successfully added 409: description: | This OIDC provider is already registered. 503: description: | Request canceled due to database statement timeout. """ schema = OpenIDProviderCreateRequestSchema() obj = loads_schema(request.get_data(as_text=True), schema) client_secret = None if obj["client_secret"]: client_secret = obj["client_secret"] jwks_endpoint = None if obj["jwks_endpoint"]: jwks_endpoint = obj["jwks_endpoint"] if db.session.query(exists().where( and_(OpenIDProvider.name == obj["name"]))).scalar(): raise Conflict( "The identity provider is already registered with the given name" ) provider = OpenIDProvider( name=obj["name"], client_id=obj["client_id"], client_secret=client_secret, authorization_endpoint=obj["authorization_endpoint"], token_endpoint=obj["token_endpoint"], userinfo_endpoint=obj["userinfo_endpoint"], jwks_endpoint=jwks_endpoint, ) db.session.add(provider) db.session.commit()
def create_event(): """ Creates a new event. --- tags: - event summary: Creates event requestBody: content: application/json: schema: $ref: '#/components/schemas/Event' description: Created event object required: true responses: 201: description: OK 400: description: Bad request. 5XX: description: Unexpected error (the API issue). """ data = request.get_json() if not data: raise BadRequest() if data.get("date_time"): try: data["date_time"] = dateutil.parser.parse(data["date_time"]) except ParserError: raise BadRequest() if data.get("end_date_time"): try: data["end_date_time"] = dateutil.parser.parse( data["end_date_time"]) # noqa: E501 except ParserError: raise BadRequest() new_data = {} for field in EVENT_FIELDS: new_data[field] = data.pop(field, None) try: Event.createOne(**new_data) except NotUniqueError: raise Conflict("The event name already exists.") res = {"status": "success", "message": "Event was created!"} return res, 201
def update(product: m_Product): try: if 'id' in request.json: product.id = request.json['id'] if 'value' in request.json: product.value = request.json['value'] db.session.commit() return m_product_schema.dump(product) except IntegrityError as e: raise Conflict(e.orig.args[1]) except SQLAlchemyError as e: raise InternalServerError(e.orig.args[1])
def _create_object(self, spec, parent, share_with, metakeys): try: return TextBlob.get_or_create( spec["content"], spec["blob_name"], spec["blob_type"], parent=parent, share_with=share_with, metakeys=metakeys, ) except ObjectTypeConflictError: raise Conflict("Object already exists and is not a blob")
def update_container(self, account_id, name, mtime, dtime, object_count, bytes_used, autocreate_account=None, autocreate_container=True): conn = self.conn if not account_id or not name: raise BadRequest("Missing account or container") if autocreate_account is None: autocreate_account = self.autocreate if mtime is None: mtime = '0' else: mtime = Timestamp(float(mtime)).normal if dtime is None: dtime = '0' else: dtime = Timestamp(float(dtime)).normal if object_count is None: object_count = 0 if bytes_used is None: bytes_used = 0 keys = [ account_id, AccountBackend.ckey(account_id, name), ("containers:%s" % (account_id)), ("account:%s" % (account_id)) ] args = [ name, mtime, dtime, object_count, bytes_used, autocreate_account, Timestamp(time()).normal, EXPIRE_TIME, autocreate_container ] try: self.script_update_container(keys=keys, args=args, client=conn) except redis.exceptions.ResponseError as exc: if str(exc) == "no_account": raise NotFound("Account %s not found" % account_id) if str(exc) == "no_container": raise NotFound("Container %s not found" % name) elif str(exc) == "no_update_needed": raise Conflict("No update needed, " "event older than last container update") else: raise return name
def delete(self, api_key=None, **kwargs): """Delete an existing token. --- tags: - admins summary: deletes an existing token operationId: deleteToken description: > Delete an existing API token. produces: - application/json parameters: - in: header name: Authorization description: the API key bearer type: string format: uuid required: true - in: path name: api_key description: the API key of the token to delete required: true type: string format: uuid responses: 204: description: token deleted successfully 404: description: token to delete not found 405: description: 'method not allowed: `api_key` not specified' """ if not api_key: raise MethodNotAllowed token = Token.query.filter_by(api_key=api_key).one_or_none() if not token: raise NotFound({ 'message': 'API key does not exist', 'args': ['api_key'] }) try: db.session.delete(token) db.session.commit() except IntegrityError: raise Conflict({ 'message': 'There are URLs associated with the token specified for deletion', 'args': ['api_key'] }) current_app.logger.info('Token deleted by %s: %s', g.token.name, token.name) return Response(status=204)
def update_item(self, item, name): # Check the actual size of the file on the server against limit # Either 0 if new file or n bytes of already uploaded file Upload.filter_size(item.data.size) # Check Content-Range. Needs to be specified, even if only one chunk if not request.headers.get("Content-Range"): raise BadRequest(description='Content-Range not specified') # Get Content-Range and check if Range is consistent with server state file_range = ContentRange.from_request() if not item.data.size == file_range.begin: raise Conflict( description= 'Content-Range inconsistent. Last byte on Server: %d' % item.data.size) # Decode Base64 encoded request data try: raw_data = base64.b64decode(request.data) file_data = BytesIO(raw_data) except (base64.binascii.Error, TypeError): raise BadRequest(description='Could not decode data body') # Write data chunk to item Upload.data(item, file_data, len(raw_data), file_range.begin) # Make a Response and create Transaction-ID from ItemName response = make_response() response.headers['Content-Type'] = 'application/json' response.data = '{}' name_b = name if isinstance(name, bytes) else name.encode() trans_id_b = base64.b64encode(name_b) trans_id_s = trans_id_b if isinstance(trans_id_b, str) else trans_id_b.decode() response.headers[TRANSACTION_ID] = trans_id_s # Check if file is completely uploaded and set meta if file_range.is_complete: Upload.meta_complete(item, '') item.meta[SIZE] = item.data.size item.close() background_compute_hash(current_app.storage, name) # Set status 'successful' and return the new URL for the uploaded file response.status = '201' response.headers["Content-Location"] = url_for( 'bepasty_apis.items_detail', name=name) else: item.close() response.status = '200' return response
def _create_object(self, spec, parent, share_with, metakeys): try: return File.get_or_create( request.files["file"].filename, request.files["file"].stream, parent=parent, share_with=share_with, metakeys=metakeys, ) except ObjectTypeConflictError: raise Conflict("Object already exists and is not a file") except EmptyFileError: raise BadRequest("File cannot be empty")
def post(self): payload = request.get_json() try: subscription = Subscription(**payload) db.session.add(subscription) db.session.commit() except AssertionError as err: raise UnprocessableEntity() from err except sqlalchemy.exc.IntegrityError: raise Conflict() return subscription, 201
def create_map_data(): data = request.get_json() if not data: raise BadRequest() try: location = Maps.createOne(**data) except NotUniqueError: raise Conflict("Sorry this location already exists") res = { "status": "Success", "message": "Location has been successfully created!" } return res, 201
def cognito_signup(signup_user): user = signup_user msg = '{0}{1}'.format(user['email'], app.config['COGNITO_CLIENT_ID']) dig = hmac.new(app.config['COGNITO_CLIENT_SECRET'].encode('utf-8'), msg=msg.encode('utf-8'), digestmod=hashlib.sha256).digest() # TODO 7: Implement following solution code to sign up user into cognito user pool try: return solution_signup_cognito(user, dig) except ClientError as e: if e.response['Error']['Code'] == 'UsernameExistsException': raise Conflict('ERROR: Existed user!') except Exception as e: raise BadRequest(e.response['Error']['Message'])
def _preprocess_post_data(self, data): project_id = data["project_id"] info = data["info"] duplicate = task_repo.find_duplicate(project_id=project_id, info=info) if duplicate: message = {'reason': 'DUPLICATE_TASK', 'task_id': duplicate} raise Conflict(json.dumps(message)) if 'n_answers' not in data: project = Project(**get_project_data(project_id)) data['n_answers'] = project.get_default_n_answers() invalid_fields = validate_required_fields(info) if invalid_fields: raise BadRequest('Missing or incorrect required fields: {}'.format( ','.join(invalid_fields)))
def validate_round(round: dict, election: Election): validate(round, CREATE_ROUND_REQUEST_SCHEMA) current_round = get_current_round(election) next_round_num = current_round.round_num + 1 if current_round else 1 if round["roundNum"] != next_round_num: raise BadRequest( f"The next round should be round number {next_round_num}") if current_round and not current_round.ended_at: raise Conflict("The current round is not complete") if round["roundNum"] == 1 and "sampleSize" not in round: raise BadRequest("Sample size is required for round 1")
def post(self): args = utils.cut_to_model(request.get_json(), item_add_fields) old_item = Item.query.filter_by(name=args['name']).first() if old_item is not None: raise Conflict('item already exists') item = Item(**args) db.session.add(item) db.session.commit() return item
def update(user: m_User): try: if 'password' in request.json: password = request.json['password'] password_hash = generate_password_hash(password) user.password = password_hash if 'username' in request.json: user.username = request.json['username'] db.session.commit() return m_user_schema.dump(user) except IntegrityError as e: raise Conflict(e.orig.args[1]) except SQLAlchemyError as e: raise InternalServerError(e.orig.args[1])
def get_sample(session: DatabaseSession, barcode: str, barcode_type: str) -> Any: """ Fetch the sample with identifier or collection identifier matching *barcode* from the backing database using *session*. Returns a named tuple with ``identifier``, ``collection_identifier``, ``encounter_id``, ``details``, ``created``, ``modified``, and ``collected`` attributes. If the identifier barcode or sample doesn't exist, raises a :class:`~werkzeug.exceptions.NotFound` exception. If the identifier barcode exists but is not from a sample or collection identifier set, raises a :class:`~werkzeug.exceptions.Conflict` exception. """ with session: identifier = find_identifier(session, barcode) or None if not identifier: LOG.info(f"Identifier barcode «{barcode}» not found") raise NotFound(f"Identifier barcode «{barcode}» not found") elif identifier.set_use != barcode_type and identifier.set_use in ( 'sample', 'collection'): raise NotFound( f"Identifier use «{barcode_type}» does not match identifier use «{identifier.set_use}» of barcode" ) elif identifier.set_use == 'sample': identifier_field = sql.Identifier('identifier') elif identifier.set_use == 'collection': identifier_field = sql.Identifier('collection_identifier') else: error_msg = f"Identifier barcode «{barcode}» has use type «{identifier.set_use}» instead of expected use type «sample» or «collection»" LOG.info(error_msg) raise Conflict(error_msg) query = sql.SQL(""" select identifier, collection_identifier, encounter_id, details, created::text, modified::text, collected::text from warehouse.sample where {field} = %s """).format(field=identifier_field) sample = session.fetch_row(query, (identifier.uuid, )) if not sample: raise NotFound( f"Sample record with {identifier.set_use} identifier barcode «{barcode}» not found" ) else: return sample
def post(self, remote_name, identifier): """ --- summary: Pulls text blob from remote to local instance description: | Pulls text blob from the remote instance to the local instance security: - bearerAuth: [] tags: - remotes parameters: - in: path name: remote_name description: Name of remote instance schema: type: string - in: path name: identifier description: Blob identifier schema: type: string responses: 200: description: Information about pulled text blob content: application/json: schema: BlobItemResponseSchema description: | When the name of the remote instance is not figured in the application config 409: description: Object exists yet but has different type """ remote = RemoteAPI(remote_name) spec = remote.request("GET", f"blob/{identifier}").json() try: item, is_new = TextBlob.get_or_create( content=spec["content"], blob_name=spec["blob_name"], blob_type=spec["blob_type"], share_with=[ group for group in g.auth_user.groups if group.name != "public" ], ) except ObjectTypeConflictError: raise Conflict("Object already exists and is not a config") return self.create_pulled_object(item, is_new)
def map_remote_api_error(response): if response.status_code == 200: return None elif response.status_code == 404: raise NotFound("Remote object not found") elif response.status_code == 403: raise Forbidden( "You are not permitted to perform this action on remote instance" ) elif response.status_code == 409: raise Conflict( "Remote object already exists in remote instance and has different type" ) else: response.raise_for_status()
def create_subscriber(): data = request.get_json() if not data: raise BadRequest() if(data.get("vaccine_site")): data["vaccine_site"] = list(map(lambda lameName: Maps.objects(name=lameName).first(), data["vaccine_site"])) try: sub = Subscriber.createOne(**data) except NotUniqueError: raise Conflict("Unfortunately, there exist data for this subscriber!") res = { "status": "success", "message": "Successfully added a subscriber to the database" } return res, 201