protected override async Task HandleChallengeAsync(AuthenticationProperties properties) { Response.StatusCode = StatusCodes.Status401Unauthorized; Response.ContentType = ProblemDetailsContentType; var problemDetails = _problemDetailsFactory.CreateProblemDetails(Request.HttpContext, StatusCodes.Status401Unauthorized, nameof(HttpStatusCode.Unauthorized), detail: "Bad API key."); await Response.WriteAsync(JsonSerializer.Serialize(problemDetails)); }
private static ProblemDetails HandleDefault(Exception ex) { var problemDetails = _problemDetailsFactory.CreateProblemDetails( _context, detail: _includeStackTrace ? ex.ToString() : ex.Message ); return(problemDetails); }
public Task OnExceptionAsync(ExceptionContext context) { var errors = new ModelStateDictionary(); switch (context.Exception) { case EntityNotFoundException exception: errors.AddModelError(exception.ParamName, exception.Message); context.Result = new NotFoundObjectResult(_pdFactory.CreateValidationProblemDetails(context.HttpContext, errors, StatusCodes.Status404NotFound)) { StatusCode = StatusCodes.Status404NotFound }; break; case InvalidArgumentException exception: errors.AddModelError(exception.ParamName, exception.Message); context.Result = new BadRequestObjectResult(_pdFactory.CreateValidationProblemDetails(context.HttpContext, errors, StatusCodes.Status400BadRequest)); break; case EntityExistException exception: errors.AddModelError(exception.ParamName, exception.Message); context.Result = new UnprocessableEntityObjectResult(_pdFactory.CreateValidationProblemDetails(context.HttpContext, errors, StatusCodes.Status422UnprocessableEntity)) { StatusCode = StatusCodes.Status422UnprocessableEntity }; break; case InvalidUserInputException exception: context.Result = new UnprocessableEntityObjectResult(_pdFactory.CreateProblemDetails(context.HttpContext, StatusCodes.Status422UnprocessableEntity, null, null, exception.Message)); break; case InvalidOperationException exception: context.Result = new UnprocessableEntityObjectResult(_pdFactory.CreateProblemDetails(context.HttpContext, StatusCodes.Status422UnprocessableEntity, null, null, exception.Message)); break; case InternalException exception: goto default; default: var message = ""; if (!_env.IsProduction()) { message += $"{context.Exception.Message}: {context.Exception.InnerException?.Message}"; } context.Result = new ObjectResult(_pdFactory.CreateProblemDetails(context.HttpContext, StatusCodes.Status500InternalServerError, null, null, $"Unhandled exception. {message}")) { StatusCode = StatusCodes.Status500InternalServerError }; break; } return(Task.CompletedTask); }
public ActionResult <APITokenViewModelGet> GetAPIToken( string accountid, // only used for documentation string channelid, // only used for documentation string tokenid) { logger.LogInformation($"Get API token by tokenid: {tokenid} for account {accountid} and {channelid}."); var error = SPVChannelsHTTPError.NotFound; if (!long.TryParse(tokenid, out long id)) { return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } var apiToken = apiTokenRepository.GetAPITokenById(id); if (apiToken == null) { logger.LogInformation($"API token with tokenid: {tokenid} does not exist."); return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } logger.LogInformation($"Returning API token by tokenid: {tokenid}."); return(Ok(new APITokenViewModelGet(apiToken))); }
public ActionResult <APITokenViewModelGet> Post(string accountid, string channelid, [FromBody] APITokenViewModelCreate data) { logger.LogInformation($"Generate API Token for accountid: {accountid} and channel: {channelid}."); if (!long.TryParse(accountid, out long aid)) { var error = SPVChannelsHTTPError.NotFound; return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } var channel = channelRepository.GetChannelByExternalId(channelid); if (channel == null) { var error = SPVChannelsHTTPError.NotFound; return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } var newAPIToken = apiTokenRepository.CreateAPIToken(data.ToDomainObject(aid, channel.Id)); var returnResult = new APITokenViewModelGet(newAPIToken); logger.LogInformation($"API Token(id) {returnResult.Id} was generated."); return(Ok(returnResult)); }
private ObjectResult Problem(bool dumpStack) { var ex = HttpContext.Features.Get <IExceptionHandlerPathFeature>().Error; string title = string.Empty; var statusCode = (int)HttpStatusCode.InternalServerError; if (ex is DomainException) { title = "Internal system error occurred"; statusCode = (int)HttpStatusCode.InternalServerError; } if (ex is BadRequestException) { title = "Bad client request"; statusCode = (int)HttpStatusCode.BadRequest; } var pd = ProblemDetailsFactory.CreateProblemDetails( HttpContext, statusCode: statusCode, title: title, detail: ex.Message); if (dumpStack) { pd.Extensions.Add("stackTrace", ex.ToString()); } var result = new ObjectResult(pd) { StatusCode = statusCode }; return(result); }
/// <inheritdoc /> public void OnException(ExceptionContext context) { if (context.Exception is T exception) { context.ExceptionHandled = true; var problemDetails = _problemDetailsFactory.CreateProblemDetails( context.HttpContext, _statusCode, detail: exception.Message, title: exception.Title, type: exception.Link, instance: exception.Instance ); foreach (var item in exception.Properties) { if (problemDetails.Extensions.ContainsKey(item.Key)) { continue; } problemDetails.Extensions.Add(item); } problemDetails = CustomizeProblemDetails(problemDetails); context.Result = new ObjectResult(problemDetails) { StatusCode = _statusCode }; } }
public async Task <ActionResult <FeeQuoteConfigViewModelGet> > Post([FromBody] FeeQuoteViewModelCreate data) { logger.LogInformation($"Create new FeeQuote form data: {data} ."); data.CreatedAt = clock.UtcNow(); var domainModel = data.ToDomainObject(clock.UtcNow()); var br = this.ReturnBadRequestIfInvalid(domainModel); if (br != null) { return(br); } var newFeeQuote = await feeQuoteRepository.InsertFeeQuoteAsync(domainModel); if (newFeeQuote == null) { var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Status = (int)HttpStatusCode.BadRequest; problemDetail.Title = $"FeeQuote not created. Check errors."; return(BadRequest(problemDetail)); } var returnResult = new FeeQuoteConfigViewModelGet(newFeeQuote); logger.LogInformation($"FeeQuote(id) {returnResult.Id} was generated."); return(CreatedAtAction(nameof(GetFeeQuoteById), new { id = returnResult.Id }, returnResult)); }
public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { if (context.Response.HasStarted) { _logger.LogWarning("The response has already started, the error handler will not be executed."); } context.Response.Clear(); context.Response.Headers.Clear(); context.Response.StatusCode = 500; var problemDetails = _problemDetailsFactory.CreateProblemDetails( context, statusCode: 500, title: "Internal Server Error"); await context.Response.WriteAsync(JsonConvert.SerializeObject(problemDetails, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore })); } }
public ActionResult DeleteMessage(string channelid, string sequence) { logger.LogInformation($"Deleting message(sequence): {sequence} in channel(id): {channelid}."); Message message; SPVChannelsHTTPError error; if (!long.TryParse(sequence, out long seq) || (message = messageRepository.GetMessageMetaData(channelid, seq)) == null) { error = SPVChannelsHTTPError.NotFound; return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } var channel = channelRepository.GetChannelByExternalId(channelid); if (channel.MinAgeDays.HasValue && message.ReceivedTS.AddDays(channel.MinAgeDays.Value).Date.CompareTo(DateTime.UtcNow) > 0) { error = SPVChannelsHTTPError.RetentionNotExpired; return(BadRequest(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } messageRepository.DeleteMessage(message.Id); logger.LogInformation($"Message deleted."); return(NoContent()); }
public async Task <ActionResult <IEnumerable <MessageViewModelGet> > > MarkMessage(string channelid, long sequence, [FromQuery] bool?older, [FromBody] MessageViewModelMark data) { logger.LogInformation($"Flag message {sequence} from {channelid} as {(data.Read ? "read" : "unread")}."); // Retrieve token information from identity APIToken apiToken = await authRepository.GetAPITokenAsync(HttpContext.User.Identity.Name); // Validate that sequence exists if (!messageRepository.SequenceExists(apiToken.Id, sequence)) { logger.LogInformation($"Sequence {sequence} not found for API Token {apiToken.Id}."); return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.NotFound, $"Sequence not found."))); } // Mark messages messageRepository.MarkMessages(channelid, apiToken.Id, sequence, older ?? false, data.Read); logger.LogInformation($"Message {sequence} was flagged as {(data.Read ? "read" : "unread")}."); return(Ok()); }
public void CreateProblemDetails_DefaultValues() { // Act var problemDetails = Factory.CreateProblemDetails(GetHttpContext()); // Assert Assert.Equal(500, problemDetails.Status); Assert.Equal("An error occurred while processing your request.", problemDetails.Title); Assert.Equal("https://tools.ietf.org/html/rfc7231#section-6.6.1", problemDetails.Type); Assert.Null(problemDetails.Instance); Assert.Null(problemDetails.Detail); Assert.Collection( problemDetails.Extensions, kvp => { Assert.Equal("traceId", kvp.Key); Assert.Equal("some-trace", kvp.Value); }); }
public async Task InvokeAsync(HttpContext context, ProblemDetailsFactory problemDetailsFactory) { await this.next(context).ConfigureAwait(true); if (context.Response.StatusCode == (int)HttpStatusCode.NotFound || context.Response.ContentLength is null or 0) { var notFoundProblemDetails = problemDetailsFactory.CreateProblemDetails(context, (int)HttpStatusCode.NotFound); await context.Response.WriteAsJsonAsync(notFoundProblemDetails).ConfigureAwait(true); } }
public async Task MergeStudent([FromRoute] int id, [FromBody] StudentMerge data) { var student = await _context.Students .FirstOrDefaultAsync(it => it.ID == id); if (student == null) { throw new ProblemDetailsException(ProblemDetailsFactory.CreateProblemDetails(this.HttpContext, 404)); } data.AdaptTo(student); await _context.SaveChangesAsync(); }
public async Task <ActionResult <SubmitTransactionResponseViewModel> > SubmitTxsRawAsync( [FromQuery] string callbackUrl, [FromQuery] string callbackEncryption, [FromQuery] string callbackToken, [FromQuery] bool merkleProof, [FromQuery] bool dsCheck ) { if (!IdentityProviderStore.GetUserAndIssuer(User, Request.Headers, out var identity)) { return(Unauthorized("Incorrectly formatted token")); } // callbackUrl is validated as part of domainObject - no special validation here byte[] data; using (var ms = new MemoryStream()) { await Request.Body.CopyToAsync(ms); data = ms.ToArray(); } byte[][] transactionAsBytes; try { // This is not very efficient, since we will reparse bytes into NBitcoin.Transaction later again transactionAsBytes = HelperTools.ParseTransactionsIntoBytes(data); } catch (Exception) { var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Title = "Unable to parse incoming stream of transactions"; return(BadRequest(problemDetail)); } var request = transactionAsBytes.Select( t => new SubmitTransaction { RawTx = t, CallbackUrl = callbackUrl, CallbackEncryption = callbackEncryption, CallbackToken = callbackToken, MerkleProof = merkleProof, DsCheck = dsCheck }).ToArray(); var result = new SubmitTransactionsResponseViewModel( await mapi.SubmitTransactionsAsync(request, identity)); return(await SignIfRequiredAsync(result, result.MinerId)); }
public async Task UpdateStudent([FromRoute] int id, [FromBody] StudentDto data) { var student = await _context.Students.Include(it => it.Enrollments) .FirstOrDefaultAsync(it => it.ID == id); if (student == null) { throw new ProblemDetailsException(ProblemDetailsFactory.CreateProblemDetails(this.HttpContext, 404)); } _mapper.From(data) .EntityFromContext(_context) .AdaptTo(student); await _context.SaveChangesAsync(); }
public IActionResult GetClientError(ActionContext actionContext, IClientErrorActionResult clientError) { var problemDetails = _problemDetailsFactory.CreateProblemDetails(actionContext.HttpContext, clientError.StatusCode); return(new ObjectResult(problemDetails) { StatusCode = problemDetails.Status, ContentTypes = { "application/problem+json", "application/problem+xml", }, }); }
private ProblemDetails BuildProblemDetails <TEx>(TEx ex, int status, HttpContext context) where TEx : Exception { if (ex is ValidationException valEx) { var state = new ModelStateDictionary(); foreach (var err in valEx.Errors) { state.AddModelError(err.Context, err.Message); } return(_problemDetailsFactory.CreateValidationProblemDetails(context, state, status, ex.Message, null, null, context.Request.Path)); } return(_problemDetailsFactory.CreateProblemDetails(context, status, ex.Message, null, null, context.Request.Path)); }
private ProblemDetails HandleException(ExceptionContext context) { switch (context.Exception) { case ArgumentException argumentException: { if (!string.IsNullOrEmpty(argumentException.ParamName)) { context.ModelState.AddModelError(argumentException.ParamName, argumentException.Message); } var problemDetails = _problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState); problemDetails.Detail = argumentException.Message; return(problemDetails); } case InvalidOperationException invalidOperationException: { var problemDetails = _problemDetailsFactory.CreateProblemDetails(context.HttpContext); problemDetails.Detail = invalidOperationException.Message; return(problemDetails); } case ValidationException validationException: { foreach (var item in validationException.Errors) { context.ModelState.AddModelError(item.PropertyName, item.ErrorMessage); } var problemDetails = _problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState); problemDetails.Detail = "Your request cannot pass our validations. Sorry"; return(problemDetails); } case ApiErrorException apiErrorException: { var detail = apiErrorException.Body.Error.Message; var problemDetails = _problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState); problemDetails.Detail = detail; return(problemDetails); } default: return(default); } }
/// <summary> /// Creates a <see cref="ProblemDetails" /> instance that configures defaults based on values specified in <see cref="ApiBehaviorOptions" />. /// </summary> /// <param name="httpContext">The <see cref="HttpContext" />.</param> /// <param name="statusCode">The value for <see cref="ProblemDetails.Status" />.</param> /// <param name="title">The value for <see cref="ProblemDetails.Title" />.</param> /// <param name="type">The value for <see cref="ProblemDetails.Type" />.</param> /// <param name="detail">The value for <see cref="ProblemDetails.Detail" />.</param> /// <param name="instance">The value for <see cref="ProblemDetails.Instance" />.</param> /// <returns>The <see cref="ProblemDetails" /> instance.</returns> public override ProblemDetails CreateProblemDetails( HttpContext httpContext, int?statusCode = null, string title = null, string type = null, string detail = null, string instance = null) { return(ReplaceTraceId(_inner.CreateProblemDetails(httpContext, statusCode, title, type, detail, instance))); }
public async Task <ActionResult> Put(string id, NodeViewModelCreate data) { if (!string.IsNullOrEmpty(data.Id) && data.Id.ToLower() != id.ToLower()) { var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Title = "The public id does not match the one from message body"; return(BadRequest(problemDetail)); } if (!await nodes.UpdateNodeAsync(data.ToDomainObject())) { return(NotFound()); } return(NoContent()); }
public ActionResult <ChannelViewModelList> GetChannels(string accountid) { logger.LogInformation($"Get list of channels for account(id) {accountid}."); if (!long.TryParse(accountid, out long id)) { var error = SPVChannelsHTTPError.NotFound; return(BadRequest(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } var channelList = channelRepository.GetChannels(id); logger.LogInformation($"Returning {channelList.Count()} channels for account(id): {id}."); return(Ok(new ChannelViewModelList(channelList.Select(x => new ChannelViewModelGet(x, Url.Link("GetMessages", new { channelid = x.ExternalId })))))); }
public async Task <ActionResult <NodeViewModelGet> > Post(NodeViewModelCreate data) { var created = await nodes.CreateNodeAsync(data.ToDomainObject()); if (created == null) { var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Status = (int)HttpStatusCode.Conflict; problemDetail.Title = $"Node '{data.Id}' already exists"; return(Conflict(problemDetail)); } // if this node is first being added on empty DB it will insert bestblockhash await blockParser.InitializeDB(); return(CreatedAtAction(nameof(Get), new { id = created.ToExternalId() }, new NodeViewModelGet(created))); }
private ProblemDetails ErrorDetails(Exception error) { if (error is InvalidOperationException) { var invalidOperationError = (InvalidOperationException)error; var errorMessages = new Dictionary <string, string[]>() { { "failureReason", new string[] { invalidOperationError.Message } } }; return(new ValidationProblemDetails(errorMessages) { Status = StatusCodes.Status400BadRequest }); } return(ProblemDetailsFactory.CreateProblemDetails(HttpContext)); }
public async Task <ActionResult <QueryTransactionStatusResponseViewModel> > QueryTransactionStatus(string id) { if (!IdentityProviderStore.GetUserAndIssuer(User, Request.Headers, out _)) { return(Unauthorized("Incorrectly formatted token")); } if (!uint256.TryParse(id, out _)) { var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Title = "Invalid format of TransactionId"; return(BadRequest(problemDetail)); } var result = new QueryTransactionStatusResponseViewModel( await mapi.QueryTransaction(id)); return(await SignIfRequiredAsync(result, result.MinerId)); }
public ActionResult RevokeAPIToken( string accountid, // only used for documentation string channelid, // only used for documentation string tokenid) { logger.LogInformation($"API Token(id) {tokenid} for account(id) {accountid} and channel(id) {channelid} is being revoked."); if (!long.TryParse(tokenid, out long id)) { var error = SPVChannelsHTTPError.NotFound; return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } apiTokenRepository.RevokeAPIToken(id); logger.LogInformation($"API Token(id) {tokenid} was revoked."); return(NoContent()); }
public async Task ExecuteAsync(ExceptionHandlingContext ctx) { var problemDetails = _problemDetailsFactory.CreateProblemDetails( ctx.HttpContext, title: ctx.Error.Message, statusCode: ctx.HttpContext.Response.StatusCode ); var displayDebugInformation = _options.DisplayDebugInformation?.Invoke() ?? false; if (displayDebugInformation || _hostEnvironment.IsDevelopment()) { var errorType = ctx.Error.GetType(); problemDetails.Extensions.Add( "debug", new { type = new { name = errorType.Name, fullName = errorType.FullName, }, stackTrace = ctx.Error.StackTrace, } ); } ctx.HttpContext.Response.ContentType = _options.ContentType; if (_options.JsonSerializerOptions is null) { await JsonSerializer.SerializeAsync( ctx.HttpContext.Response.Body, problemDetails ); } else { await JsonSerializer.SerializeAsync( ctx.HttpContext.Response.Body, problemDetails, _options.JsonSerializerOptions ); } }
public async Task <ActionResult <SubmitTransactionResponseViewModel> > SubmitTxsAsync( SubmitTransactionViewModel[] data, [FromQuery] string defaultCallbackUrl, [FromQuery] string defaultCallbackToken, [FromQuery] string defaultCallbackEncryption, [FromQuery] bool defaultMerkleProof, [FromQuery] string defaultMerkleFormat, [FromQuery] bool defaultDsCheck) { if (!IdentityProviderStore.GetUserAndIssuer(User, Request.Headers, out var identity)) { return(Unauthorized("Incorrectly formatted token")); } var domainModel = data.Select(x => x.ToDomainModel(defaultCallbackUrl, defaultCallbackToken, defaultCallbackEncryption, defaultMerkleProof, defaultMerkleFormat, defaultDsCheck)).ToArray(); SubmitTransactionsResponseViewModel result; try { result = new SubmitTransactionsResponseViewModel( await mapi.SubmitTransactionsAsync(domainModel, identity)); } catch (BadRequestException ex) { logger.LogError($"Error while submiting transactions. {ex.Message}."); var problemDetail = ProblemDetailsFactory.CreateProblemDetails(HttpContext, (int)HttpStatusCode.BadRequest); problemDetail.Title = ex.Message; return(BadRequest(problemDetail)); } return(await SignIfRequiredAsync(result, result.MinerId)); }
public ActionResult <ChannelViewModelGet> GetChannel( string accountid, // only used for documentation string channelid) { logger.LogInformation($"Get channel by channel(id) {channelid} for account(id) {accountid}."); var error = SPVChannelsHTTPError.NotFound; var channel = channelRepository.GetChannelByExternalId(channelid); if (channel == null) { logger.LogInformation($"Channel with channelid: {channelid} does not exist."); return(NotFound(ProblemDetailsFactory.CreateProblemDetails(HttpContext, error.Code, error.Description))); } logger.LogInformation($"Returning channel by channelid: {channelid}."); return(Ok(new ChannelViewModelGet(channel, Url.Link("GetMessages", new { channelid = channel.ExternalId })))); }
public ObjectResult NotFoundProblem(string detail) { if (string.IsNullOrWhiteSpace(detail)) { throw new ArgumentException($"'{nameof(detail)}' cannot be null or whitespace", nameof(detail)); } var problemDetails = ProblemDetailsFactory.CreateProblemDetails( HttpContext, statusCode: StatusCodes.Status404NotFound, title: "Not Found", type: "https://tools.ietf.org/html/rfc7231#section-6.5.4", detail: detail, instance: UriHelper.GetDisplayUrl(Request)); return(new ObjectResult(problemDetails) { StatusCode = problemDetails.Status }); }