public override void OnException(ExceptionContext context) { bool isDevelopment = _hostingEnv.IsDevelopment(); var ex = context.Exception; string stackTrace = (isDevelopment) ? context.Exception.StackTrace : string.Empty; string message = ex.Message; string error = string.Empty; IActionResult actionResult; switch (ex) { case DbUpdateConcurrencyException ce: // Returns a 400 error = "Concurrency Issue"; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksUniqueIndexException une: // Return 400 error = "Duplicate value detected!"; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidEntityIdException une: // Return 404 error = "Can't find entity; invalid primary key value given."; actionResult = new NotFoundObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidContactTypeException une: // Return 400 error = "Invalid ContactTypeID."; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidAddressTypeException une: // Return 400 error = "Invalid AddressTypeID."; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksNullEntityObjectException une: // Return 404 error = "Can't find entity; invalid primary key value given!"; actionResult = new NotFoundObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidStateProvinceIdException une: // Return 400 error = "Invalid state or province code."; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidPhoneTypeException une: // Return 400 error = "Invalid phone type ID."; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksInvalidDeleteOperationException une: // Return 400 error = "Invalid delete operation, would result in orphaned child records."; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; case AdventureWorksException awe: // Return 400 error = "AdventureWorksException"; actionResult = new BadRequestObjectResult(new { error = error, message = message, StackTrace = stackTrace }); _logger.LogError($"{error} : {message}"); break; default: error = "General Error"; actionResult = new ObjectResult(new { error = error, message = message, StackTrace = stackTrace }) { StatusCode = 500 }; _logger.LogError($"{error} : {message}"); break; } context.Result = actionResult; }
public async Task <ObjectResult> CreateInviteAsync( HouseInviteCreationRequestViewModel houseInviteCreationRequestViewModel, CancellationToken cancellationToken = default) { var userFromIdentity = GetUserFromIdentity(); var houseInviteCreationRequest = _mapper.Map <HouseInviteCreationRequest>(houseInviteCreationRequestViewModel); houseInviteCreationRequest.InvitedByUserId = userFromIdentity.GoogleId; HouseInviteSimpleInfo houseInvite; try { houseInvite = await _houseInviteService.CreateInviteAsync( houseInviteCreationRequest, cancellationToken); } catch (TooManyHouseInvitesException) { var modelState = new ModelStateDictionary(); modelState.AddModelError( nameof(houseInviteCreationRequestViewModel.HouseId), "Too many requests from you are still pending acceptance"); var badResult = new BadRequestObjectResult(modelState); return(badResult); } catch (HouseInviteDuplicateInsertionException) { var modelState = new ModelStateDictionary(); modelState.AddModelError( nameof(houseInviteCreationRequestViewModel.UserEmail), "User already invited"); var badResult = new BadRequestObjectResult(modelState); return(badResult); } catch (HouseNotFoundException) { var modelState = new ModelStateDictionary(); modelState.AddModelError( nameof(houseInviteCreationRequestViewModel.HouseId), "House not found"); var badResult = new BadRequestObjectResult(modelState); return(badResult); } catch (SelfReferencingHouseInviteException) { var modelState = new ModelStateDictionary(); modelState.AddModelError( nameof(houseInviteCreationRequestViewModel.UserEmail), "House owner can't invite himself"); var badResult = new BadRequestObjectResult(modelState); return(badResult); } var houseInviteViewModel = _mapper.Map <HouseInviteSimpleInfoViewModel>(houseInvite); var result = new OkObjectResult(houseInviteViewModel); return(result); }
public async Task <IActionResult> CreateRelationship(HttpRequest request) { string json = await request.GetRawBodyStringAsync(); CreateDefinitionSpecificationRelationshipModel model = JsonConvert.DeserializeObject <CreateDefinitionSpecificationRelationshipModel>(json); if (model == null) { _logger.Error("Null CreateDefinitionSpecificationRelationshipModel was provided to CreateRelationship"); return(new BadRequestObjectResult("Null CreateDefinitionSpecificationRelationshipModel was provided")); } BadRequestObjectResult validationResult = (await _relationshipModelValidator.ValidateAsync(model)).PopulateModelState(); if (validationResult != null) { return(validationResult); } DatasetDefinition definition = await _datasetRepository.GetDatasetDefinition(model.DatasetDefinitionId); if (definition == null) { _logger.Error($"Datset definition was not found for id {model.DatasetDefinitionId}"); return(new StatusCodeResult(412)); } SpecificationSummary specification = await _specificationsRepository.GetSpecificationSummaryById(model.SpecificationId); if (specification == null) { _logger.Error($"Specification was not found for id {model.SpecificationId}"); return(new StatusCodeResult(412)); } string relationshipId = Guid.NewGuid().ToString(); DefinitionSpecificationRelationship relationship = new DefinitionSpecificationRelationship { Name = model.Name, DatasetDefinition = new Reference(definition.Id, definition.Name), Specification = new Reference(specification.Id, specification.Name), Description = model.Description, Id = relationshipId, IsSetAsProviderData = model.IsSetAsProviderData, UsedInDataAggregations = model.UsedInDataAggregations }; HttpStatusCode statusCode = await _datasetRepository.SaveDefinitionSpecificationRelationship(relationship); if (!statusCode.IsSuccess()) { _logger.Error($"Failed to save relationship with status code: {statusCode.ToString()}"); return(new StatusCodeResult((int)statusCode)); } IDictionary <string, string> properties = request.BuildMessageProperties(); await _messengerService.SendToQueue(ServiceBusConstants.QueueNames.AddDefinitionRelationshipToSpecification, new AssignDefinitionRelationshipMessage { SpecificationId = specification.Id, RelationshipId = relationshipId }, properties); DatasetRelationshipSummary relationshipSummary = new DatasetRelationshipSummary { Name = relationship.Name, Id = Guid.NewGuid().ToString(), Relationship = new Reference(relationship.Id, relationship.Name), DatasetDefinition = definition, DatasetDefinitionId = definition.Id, DataGranularity = relationship.UsedInDataAggregations ? DataGranularity.MultipleRowsPerProvider : DataGranularity.SingleRowPerProvider, DefinesScope = relationship.IsSetAsProviderData }; BuildProject buildProject = await _calcsRepository.UpdateBuildProjectRelationships(specification.Id, relationshipSummary); await _cacheProvider.RemoveAsync <IEnumerable <DatasetSchemaRelationshipModel> >($"{CacheKeys.DatasetRelationshipFieldsForSpecification}{specification.Id}"); return(new OkObjectResult(relationship)); }
/// <summary> /// For WebHook providers with insufficient security considerations, the receiver can require that the WebHook /// URI must be an <c>https</c> URI and contain a 'code' query parameter with a value configured for that /// particular <c>id</c>. A sample WebHook URI is /// '<c>https://{host}/api/webhooks/incoming/{receiver name}?code=83699ec7c1d794c0c780e49a5c72972590571fd8</c>'. /// The 'code' parameter must be between 32 and 128 characters long. /// </summary> /// <param name="request">The current <see cref="HttpRequest"/>.</param> /// <param name="routeData"> /// The <see cref="RouteData"/> for this request. A (potentially empty) ID value in this data allows a /// <see cref="WebHookVerifyCodeFilter"/> to support multiple senders with individual configurations. /// </param> /// <param name="receiverName">The name of an available <see cref="IWebHookReceiver"/>.</param> /// <returns> /// <see langword="null"/> in the success case. When a check fails, an <see cref="IActionResult"/> that when /// executed will produce a response containing details about the problem. /// </returns> protected virtual IActionResult EnsureValidCode( HttpRequest request, RouteData routeData, string receiverName) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (routeData == null) { throw new ArgumentNullException(nameof(routeData)); } if (receiverName == null) { throw new ArgumentNullException(nameof(receiverName)); } var result = EnsureSecureConnection(receiverName, request); if (result != null) { return(result); } var code = request.Query[WebHookConstants.CodeQueryParameterName]; if (StringValues.IsNullOrEmpty(code)) { Logger.LogWarning( 400, "A '{ReceiverName}' WebHook verification request must contain a " + $"'{WebHookConstants.CodeQueryParameterName}' query " + "parameter.", receiverName); var message = string.Format( CultureInfo.CurrentCulture, Resources.General_NoQueryParameter, receiverName, WebHookConstants.CodeQueryParameterName); var noCode = new BadRequestObjectResult(message); return(noCode); } var secretKey = GetSecretKey(receiverName, routeData, WebHookConstants.CodeParameterMinLength); if (secretKey == null) { return(new NotFoundResult()); } if (!SecretEqual(code, secretKey)) { Logger.LogWarning( 401, $"The '{WebHookConstants.CodeQueryParameterName}' query parameter provided in the HTTP request " + "did not match the expected value."); var message = string.Format( CultureInfo.CurrentCulture, Resources.VerifyCode_BadCode, WebHookConstants.CodeQueryParameterName); var invalidCode = new BadRequestObjectResult(message); return(invalidCode); } return(null); }
public static async Task <IActionResult> GetRestaurants( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "restaurants")] HttpRequest req, [Blob("restaurants", FileAccess.ReadWrite, Connection = "StorageSend")] CloudBlobContainer cloudBlobContainer, ILogger log, ExecutionContext context) { Guid correlationId = Util.ReadCorrelationId(req.Headers); var methodName = MethodBase.GetCurrentMethod().Name; var trace = new Dictionary <string, string>(); EventId eventId = new EventId(correlationId.GetHashCode(), Constants.ButlerCorrelationTraceName); IActionResult actionResult = null; List <RestaurantModel> restaurants = new List <RestaurantModel>(); using (log.BeginScope("Method:{methodName} CorrelationId:{CorrelationId} Label:{Label}", methodName, correlationId.ToString(), context.InvocationId.ToString())) { try { BlobContinuationToken blobContinuationToken = null; var options = new BlobRequestOptions(); var operationContext = new OperationContext(); List <IListBlobItem> cloudBlockBlobs = new List <IListBlobItem>(); do { var blobs = await cloudBlobContainer.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, blobContinuationToken, options, operationContext).ConfigureAwait(false); blobContinuationToken = blobs.ContinuationToken; cloudBlockBlobs.AddRange(blobs.Results); }while (blobContinuationToken != null); foreach (var item in cloudBlockBlobs) { CloudBlockBlob blob = (CloudBlockBlob)item; var blobContent = blob.DownloadTextAsync(); var blobRestaurant = JsonConvert.DeserializeObject <RestaurantModel>(await blobContent); restaurants.Add(blobRestaurant); } log.LogInformation(correlationId, $"'{methodName}' - success", trace); actionResult = new OkObjectResult(restaurants); } catch (Exception e) { trace.Add(string.Format("{0} - {1}", methodName, "rejected"), e.Message); trace.Add(string.Format("{0} - {1} - StackTrace", methodName, "rejected"), e.StackTrace); log.LogInformation(correlationId, $"'{methodName}' - rejected", trace); log.LogError(correlationId, $"'{methodName}' - rejected", trace); ErrorModel errorModel = new ErrorModel() { CorrelationId = correlationId, Details = e.StackTrace, Message = e.Message, }; actionResult = new BadRequestObjectResult(errorModel); } finally { log.LogTrace(eventId, $"'{methodName}' - finished"); log.LogInformation(correlationId, $"'{methodName}' - finished", trace); } } return(actionResult); }
public async Task <IActionResult> SaveFundingConfiguration(string actionName, string controllerName, FundingConfigurationViewModel configurationViewModel, string fundingStreamId, string fundingPeriodId) { Guard.IsNullOrWhiteSpace(actionName, nameof(actionName)); Guard.IsNullOrWhiteSpace(controllerName, nameof(controllerName)); Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId)); Guard.IsNullOrWhiteSpace(fundingPeriodId, nameof(fundingPeriodId)); Guard.ArgumentNotNull(configurationViewModel, nameof(configurationViewModel)); FundingConfiguration fundingConfiguration = _mapper.Map <FundingConfiguration>(configurationViewModel, opt => { opt.Items[nameof(FundingConfiguration.FundingStreamId)] = fundingStreamId; opt.Items[nameof(FundingConfiguration.FundingPeriodId)] = fundingPeriodId; }); BadRequestObjectResult validationResult = (await _fundingConfigurationValidator.ValidateAsync(fundingConfiguration)).PopulateModelState(); if (validationResult != null) { return(validationResult); } //TODO; add validation on existence of template (what is a template exactly) when supplied as the default template id (funding template I'm guessing) try { HttpStatusCode result = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.SaveFundingConfiguration(fundingConfiguration)); if (!result.IsSuccess()) { int statusCode = (int)result; string errorMessage = $"Failed to save configuration file for funding stream id: {fundingStreamId} and period id: {fundingPeriodId} to cosmos db with status {statusCode}"; _logger.Error(errorMessage); return(new InternalServerErrorResult(errorMessage)); } } catch (Exception exception) { string errorMessage = $"Exception occurred writing to configuration file for funding stream id: {fundingStreamId} and period id: {fundingPeriodId} to cosmos db"; _logger.Error(exception, errorMessage); return(new InternalServerErrorResult(errorMessage)); } string fundingPeriodFundingConfigurationCacheKey = $"{CacheKeys.FundingConfig}{fundingStreamId}-{fundingPeriodId}"; await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetAsync(fundingPeriodFundingConfigurationCacheKey, fundingConfiguration)); string fundingStreamFundingConfigurationCacheKey = $"{CacheKeys.FundingConfig}{fundingStreamId}"; await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.RemoveAsync <List <FundingConfiguration> >(fundingStreamFundingConfigurationCacheKey)); _logger.Information($"Successfully saved configuration file for funding stream id: {fundingStreamId} and period id: {fundingPeriodId} to cosmos db"); return(new CreatedAtActionResult(actionName, controllerName, new { fundingStreamId, fundingPeriodId }, string.Empty)); }
/// <inheritdoc /> public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (next == null) { throw new ArgumentNullException(nameof(next)); } var routeData = context.RouteData; var request = context.HttpContext.Request; if (routeData.TryGetWebHookReceiverName(out var receiverName) && IsApplicable(receiverName) && HttpMethods.IsPost(request.Method)) { // 1. Confirm a secure connection. var errorResult = EnsureSecureConnection(ReceiverName, context.HttpContext.Request); if (errorResult != null) { context.Result = errorResult; return; } // 2. Get the expected hash from the signature header. var header = GetRequestHeader(request, GitHubConstants.SignatureHeaderName, out errorResult); if (errorResult != null) { context.Result = errorResult; return; } var values = new TrimmingTokenizer(header, PairSeparators); var enumerator = values.GetEnumerator(); enumerator.MoveNext(); var headerKey = enumerator.Current; if (values.Count != 2 || !StringSegment.Equals( headerKey, GitHubConstants.SignatureHeaderKey, StringComparison.OrdinalIgnoreCase)) { Logger.LogError( 1, "Invalid '{HeaderName}' header value. Expecting a value of '{Key}={Value}'.", GitHubConstants.SignatureHeaderName, GitHubConstants.SignatureHeaderKey, "<value>"); var message = string.Format( CultureInfo.CurrentCulture, Resources.SignatureFilter_BadHeaderValue, GitHubConstants.SignatureHeaderName, GitHubConstants.SignatureHeaderKey, "<value>"); errorResult = new BadRequestObjectResult(message); context.Result = errorResult; return; } enumerator.MoveNext(); var headerValue = enumerator.Current.Value; var expectedHash = GetDecodedHash(headerValue, GitHubConstants.SignatureHeaderName, out errorResult); if (errorResult != null) { context.Result = errorResult; return; } // 3. Get the configured secret key. var secretKey = GetSecretKey( ReceiverName, routeData, GitHubConstants.SecretKeyMinLength, GitHubConstants.SecretKeyMaxLength); if (secretKey == null) { context.Result = new NotFoundResult(); return; } var secret = Encoding.UTF8.GetBytes(secretKey); // 4. Get the actual hash of the request body. var actualHash = await GetRequestBodyHash_SHA1(request, secret); // 5. Verify that the actual hash matches the expected hash. if (!SecretEqual(expectedHash, actualHash)) { // Log about the issue and short-circuit remainder of the pipeline. errorResult = CreateBadSignatureResult(receiverName, GitHubConstants.SignatureHeaderName); context.Result = errorResult; return; } } await next(); }
public void ConfigureServices(IServiceCollection services) { #if SuppressApiControllerBehavior #region snippet_ConfigureApiBehaviorOptions services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .ConfigureApiBehaviorOptions(options => { options.SuppressConsumesConstraintForFormFileParameters = true; options.SuppressInferBindingSourcesForParameters = true; options.SuppressModelStateInvalidFilter = true; options.SuppressMapClientErrors = true; options.ClientErrorMapping[404].Link = "https://httpstatuses.com/404"; }); #endregion #endif #if InvalidModelStateResponseFactory #region snippet_ConfigureBadRequestResponse services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var problemDetails = new ValidationProblemDetails(context.ModelState) { Type = "https://contoso.com/probs/modelvalidation", Title = "One or more model validation errors occurred.", Status = StatusCodes.Status400BadRequest, Detail = "See the errors property for details.", Instance = context.HttpContext.Request.Path }; return(new BadRequestObjectResult(problemDetails) { ContentTypes = { "application/problem+json" } }); }; }); #endregion #endif #if DisableProblemDetailsInvalidModelStateResponseFactory #region snippet_DisableProblemDetailsInvalidModelStateResponseFactory services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); // TODO: add `using using System.Net.Mime;` to resolve MediaTypeNames result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; }); #endregion #endif #if DefaultBehavior services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); #endif }
public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddDbContext <ReviewContext>(opt => opt.UseSqlServer(Configuration.GetSection("database")["connection"])); services.AddDbContext <LogInContext>(opt => opt.UseSqlServer(Configuration.GetSection("database")["connection"])); services.AddControllers(); #if ExceptionFilter #region snippet_AddExceptionFilter services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter())); #endregion #endif #if InvalidModelStateResponseFactory #region snippet_DisableProblemDetailsInvalidModelStateResponseFactory services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); // TODO: add `using using System.Net.Mime;` to resolve MediaTypeNames result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; /* * options.SuppressConsumesConstraintForFormFileParameters = true; * options.SuppressInferBindingSourcesForParameters = true; * options.SuppressModelStateInvalidFilter = true; * options.SuppressMapClientErrors = true; * options.ClientErrorMapping[404].Link = * "https://jyiweb.tcgis.ca/test/404"; * });*/ #endregion #endif // Register the Swagger generator, defining 1 or more Swagger documents services.AddSwaggerGen(c => { //c.SwaggerDoc("v1", new OpenApiInfo { Title = "Review Rating API", Version = "v1" }); c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "Review Rating API", Description = "A simple example ASP.NET Core Web API", TermsOfService = new Uri("https://example.com/terms"), License = new OpenApiLicense { Name = "Use under LICX", Url = new Uri("https://example.com/license"), } }); }); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddDbContext <EcommerceDbContext>(options => { options.UseSqlServer(Config.GetConnectionString("EcommerceDBConnection") , x => x.MigrationsAssembly("Ecommerce.DAL")); //options.UseSqlServer(Config.GetConnectionString("EcommerceDBConnection")); }); services.AddIdentity <ApplicationUser, ApplicationRole>(options => { options.Password.RequiredLength = 5; options.SignIn.RequireConfirmedEmail = true; }).AddEntityFrameworkStores <EcommerceDbContext>() .AddDefaultTokenProviders(); var jwtSettings = new JwtSettings(); Config.Bind(nameof(jwtSettings), jwtSettings); services.AddSingleton(jwtSettings); services.AddScoped <IIdentityService, IdentityService>(); services.AddScoped <IIdentityRepository, IdentityRepository>(); services.AddScoped <ICategoryService, CategoryService>(); services.AddScoped <ICategoryRepository, CategoryRepository>(); services.AddScoped <IUnitService, UnitService>(); services.AddScoped <IUnitsRepository, UnitsRepository>(); services.AddScoped <IProductService, ProductService>(); services.AddScoped <IProductRepository, ProductRepository>(); services.AddScoped <IOrderService, OrderService>(); services.AddScoped <IOrderRepository, OrderRepository>(); services.AddScoped <ICartService, CartService>(); services.AddScoped <ICartRepository, CartRepository>(); services.AddControllers(options => { options.Filters.Add(typeof(EcommerceApiFilter)); }).ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); // TODO: add `using using System.Net.Mime;` to resolve MediaTypeNames result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; }); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key: Encoding.ASCII.GetBytes(jwtSettings.Secret)), ValidateIssuer = false, ValidateAudience = false, RequireExpirationTime = false, ValidateLifetime = true }; services.AddSingleton(tokenValidationParameters); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.SaveToken = true; x.TokenValidationParameters = tokenValidationParameters; }); services.AddCors(); services.AddAutoMapper(typeof(Startup)); }
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Configuration["SECRETS_DIR"])) .SetApplicationName(Configuration["Properties:ApplicationName"]); services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer(Configuration["IdApiConnectionStrings:IdentityDB"], x => x.MigrationsAssembly("IdentityDataCommon"))); services.AddIdentity <ApplicationUser, IdentityRole>() .AddRoleManager <RoleManager <IdentityRole> >() .AddSignInManager <SignInManager <ApplicationUser> >() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.Configure <IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._+"; options.User.RequireUniqueEmail = false; }); services.Configure <IISServerOptions>(options => { options.AutomaticAuthentication = false; }); services.AddCors(options => { options.AddPolicy("default", policy => { policy.WithOrigins(Configuration["AppURLS:IdManagementBaseUrl"], Configuration["AppURLS:IS4BaseUrl"]) .AllowAnyHeader() .AllowAnyMethod(); }); }); services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.SuppressModelStateInvalidFilter = true; options.SuppressInferBindingSourcesForParameters = true; options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); result.ContentTypes.Add(MediaTypeNames.Application.Json); return(result); }; }); services.AddMvcCore(options => { //lock down this Api to only allow access tokens with IdApi scope var policy = ScopePolicy.Create("IdApi"); options.Filters.Add(new AuthorizeFilter(policy)); options.Filters.Add(typeof(ApiValidationFilterAttribute)); }) //https://stackoverflow.com/questions/55666826/where-did-imvcbuilder-addjsonoptions-go-in-net-core-3-0 .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.DictionaryKeyPolicy = null; }) .AddAuthorization(options => { options.AddPolicy("ApiScope", policy => { policy.RequireScope("IdApi"); policy.RequireAuthenticatedUser(); policy.RequireClaim("scope", "IdApi"); }); }); services.AddLogging(); services.AddDistributedMemoryCache(); services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddOAuth2Introspection("introspection", options => { options.Authority = Configuration["AppURLS:IS4BaseUrl"]; options.ClientId = Configuration["AppIds:IdManagementId"]; options.ClientSecret = Configuration["AppSecrets:IdManagementId"]; }) .AddIdentityServerAuthentication("IdentityServerAccessToken", options => { options.Authority = Configuration["AppURLS:IS4BaseUrl"]; options.ApiName = Configuration["ApplicationIds:IdApiId"]; options.ApiSecret = Configuration["ApplicationSecrets:IdApiSecret"]; //Using Reference Tokens - lessons calls to IS4 to validate tokens options.EnableCaching = true; //REQUIRES: services.AddDistributedMemoryCache(); options.CacheDuration = TimeSpan.FromMinutes(2); options.SupportedTokens = SupportedTokens.Both; }); services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "IdApi", Version = "v1" }); }); }
public static async Task <IActionResult> Run( [HttpTrigger( AuthorizationLevel.Function, "post", Route = null)] HttpRequest request, [ServiceBus( "processtext", Connection = "ProcessTextQueueServicebusConnectionString")] IAsyncCollector <dynamic> processTextQueue, [CosmosDB( databaseName: "TextContent", collectionName: "Web", ConnectionStringSetting = "tkawchak-textanalysis_DOCUMENTDB")] IAsyncCollector <dynamic> outputDocument, ILogger log) { ObjectResult httpResponse; log.LogInformation("C# ProcessTextHttp function received request."); // format the data for the response message string bodyContent = string.Empty; string errorMessage = string.Empty; using (var reader = new StreamReader(request.Body)) { bodyContent = await reader.ReadToEndAsync(); } ProcessTextRequest requestContent; if (string.IsNullOrWhiteSpace(bodyContent)) { errorMessage = "Error processing request - Request Body is empty. Cannot process an empty body."; } requestContent = JsonConvert.DeserializeObject <ProcessTextRequest>(bodyContent); if (string.IsNullOrWhiteSpace(requestContent.Title)) { errorMessage = "Error processing request - Title not specified"; } if (string.IsNullOrWhiteSpace(requestContent.Domain)) { errorMessage = "Error processing request - Domain not specified"; } if (!string.IsNullOrWhiteSpace(errorMessage)) { log.LogError(errorMessage); httpResponse = new BadRequestObjectResult(errorMessage); return(httpResponse); } log.LogInformation($"Received request to store data for webpage at {requestContent.Url}"); var outputDoc = Utils.Converters.ConvertProcessTextRequestToProcessedTextDocument(requestContent); log.LogInformation($"Document Title: {outputDoc.Title}"); log.LogInformation($"Document Domain: {outputDoc.Domain}"); await processTextQueue.AddAsync(outputDoc); log.LogInformation($"Sent webpage data to process text queue"); await outputDocument.AddAsync(outputDoc); log.LogInformation($"Stored webpage data to storage"); string message = $"Successfully Processed request to store data for webpage at {requestContent.Domain}."; log.LogInformation(message); httpResponse = new OkObjectResult(message); return(httpResponse); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); bool result = false; string reason = "No reason found for failure"; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); string userId = data?.userId; string productId = data?.productId; string locationName = data?.locationName; string rating = data?.rating; string userNotes = data?.userNotes; if (null != userId) { string uri = "https://serverlessohuser.trafficmanager.net/api/GetUser?userId=" + userId; dynamic content = await MyHttpClientAsync(uri); string userName = content?.userName; string fullName = content?.fullName; if (null != userName && null != fullName) { result = true; } else { result = false; reason = "No user found for ID " + userId; } } else { reason = "No user ID passed in"; } if (null != productId && result) { string uri = "https://serverlessohproduct.trafficmanager.net/api/GetProduct?productId=" + productId; dynamic content = await MyHttpClientAsync(uri); string productName = content?.productName; string productDescription = content?.productDescription; if (null == productName || null == productDescription) { result = false; reason = "No product found for ID " + productId; } } if (null != rating && result) { bool isNumeric = int.TryParse(rating, out int ratingInt); if (isNumeric) { if (0 >= ratingInt && 5 <= ratingInt) { result = false; reason = "Invalid rating: " + rating; } } else { result = false; reason = "Invalid rating: " + rating; } } //Newtonsoft.Json.Linq.JObject obj = Newtonsoft.Json.Linq.JObject.Parse(data); data["id"] = Guid.NewGuid(); data["timestamp"] = DateTime.UtcNow; //data = obj.ToString(); ObjectResult returnValue; if (result) { returnValue = new OkObjectResult(data); } else { returnValue = new BadRequestObjectResult(reason); } return(returnValue); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure <ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { var problemDetails = new ValidationProblemDetails(context.ModelState); var result = new BadRequestObjectResult(problemDetails); result.ContentTypes.Add("application/problem+json"); result.ContentTypes.Add("application/problem+xml"); return(result); }; }); services.Configure <MvcOptions>(c => c.Conventions.Add(new SwaggerApplicationConvention())); services.AddCors(); services.AddControllers(options => options.EnableEndpointRouting = false) .ConfigureApiBehaviorOptions(options => { options.SuppressConsumesConstraintForFormFileParameters = true; options.SuppressInferBindingSourcesForParameters = true; options.SuppressModelStateInvalidFilter = true; options.SuppressMapClientErrors = true; options.ClientErrorMapping[StatusCodes.Status404NotFound].Link = "https://httpstatuses.com/404"; }); services.AddTransient <IConfiguration>(provider => Configuration); services.AddScoped <ApplicationDbContext>(); services.AddScoped <ClientService>(); services.AddScoped <ProductService>(); services.AddScoped <JwtService>(); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(JwtService.Secret)), ValidateIssuer = false, ValidateAudience = false }; }); services.AddApiVersioning(p => { p.DefaultApiVersion = new ApiVersion(1, 0); p.ReportApiVersions = true; p.AssumeDefaultVersionWhenUnspecified = true; }); services.AddVersionedApiExplorer(p => { p.GroupNameFormat = "'v'VVV"; p.SubstituteApiVersionInUrl = true; }); //services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); services.AddSwaggerGen(setup => { setup.SwaggerDoc("v1", new OpenApiInfo { Title = "Magalu Changelle", Version = "v1", Description = "API para o desafio Magalu", Contact = new OpenApiContact { Name = "Raphael Carlos Rego", Url = new Uri("https://raphaelcarlosr.com") } }); setup.ResolveConflictingActions(apiDescriptions => apiDescriptions.FirstOrDefault()); }); //Strict-Transport-Security services.AddHsts(options => { options.IncludeSubDomains = true; options.MaxAge = TimeSpan.FromDays(365); }); services.AddAntiforgery(o => o.SuppressXFrameOptionsHeader = true); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().Build()); }); services.AddDbContext <ShoppingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); services.AddScoped <IUnitOfWork, UnitOfWork>(); services.AddScoped <ICustomerService, CustomerService>(); services.AddScoped <IProductService, ProductServises>(); services.AddScoped <IOrderServices, OrderServicesLogic>(); services.AddScoped <IItemServices, ItemServices>(); services.AddAutoMapper(typeof(Startup)); services.AddScoped <IMailer, Mailer>(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; }); services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; }); services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter())); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Online Shopping", Version = "v1" }); c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); }); services.AddCors(); services.AddMvc(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddControllers(); var appSettingsSection = Configuration.GetSection("AppSettings"); services.Configure <AppSettings>(appSettingsSection); // configure jwt authentication var appSettings = appSettingsSection.Get <AppSettings>(); var key = Encoding.ASCII.GetBytes(appSettings.Secret); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; }); services.AddScoped <IUserService, UserService>(); var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); services.AddDbContext <IDbContext, PruebaContext>(options => options.UseSqlite(connection)); services.AddScoped <IUnitOfWork, UnitOfWork>().AddDbContext <PruebaContext>(); _ = services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var obj = context.ModelState; string jsonString = ""; obj.Values.Where(x => x.Errors.Count > 0).ToList().ForEach(x => { x.Errors.ToList().ForEach(x => { jsonString += x.ErrorMessage.ToString() + System.Environment.NewLine; }); }); var response = new { Status = false, Message = jsonString, }; var result = new BadRequestObjectResult(response); // TODO: add `using System.Net.Mime;` to resolve MediaTypeNames result.ContentTypes.Add(MediaTypeNames.Application.Json); result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; }); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "Woin API", Description = "Web Api service Rev 0.01 Alpha", TermsOfService = new Uri("https://example.com/terms"), Contact = new OpenApiContact { Name = "Dev Zeros", Email = "*****@*****.**", Url = new Uri("https://desarrollo-zeros.github.io/"), }, License = new OpenApiLicense { Name = "Use Private licence", Url = new Uri("http://woin.com.co/"), }, }); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers() .SetCompatibilityVersion(CompatibilityVersion.Version_3_0) .AddJsonOptions(opt => { var serializerOptions = opt.JsonSerializerOptions; serializerOptions.IgnoreNullValues = true; serializerOptions.IgnoreReadOnlyProperties = false; serializerOptions.WriteIndented = true; }) .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var result = new BadRequestObjectResult(context.ModelState); result.ContentTypes.Add(MediaTypeNames.Application.Json); //result.ContentTypes.Add(MediaTypeNames.Application.Xml); return(result); }; }); if (Environment.IsDevelopment()) { services.AddControllers(opts => { opts.Filters.Add(new AllowAnonymousFilter()); }); } services.Configure <GzipCompressionProviderOptions>( options => options.Level = System.IO.Compression.CompressionLevel.Optimal); services.AddResponseCompression(options => { options.Providers.Add <GzipCompressionProvider>(); options.EnableForHttps = true; }); services.AddLogging(loggingBuilder => { loggingBuilder.AddConfiguration(Configuration.GetSection("Logging")); loggingBuilder.AddConsole(); loggingBuilder.AddDebug(); }); services.AddDbContext <DbContext, AplicacaoContext>(opt => opt .UseSqlServer(Configuration.GetConnectionString("Aplicacao"), x => x.EnableRetryOnFailure()) .EnableSensitiveDataLogging(Environment.IsDevelopment()) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)); services.AddStackExchangeRedisCache(options => { options.Configuration = Configuration.GetConnectionString("Redis"); options.InstanceName = "MITArq-"; }); //https://docs.microsoft.com/pt-br/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1 services.AddOptions(); services.AddAutoMapper(typeof(Startup)); // Extension services.AddSwaggerConfigMITArq(); services.AddApiVersioning(o => { o.ReportApiVersions = true; o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(1, 0); o.ApiVersionReader = new HeaderApiVersionReader("x-api-version"); o.ApiVersionReader = new HeaderApiVersionReader("x-api-mitarq"); }); // Extension services.AddServiceCORSMITArq(); // Extension services.AddRegisterServicesMITArq(); Injections.SetSecurity(services, Configuration); services.AddApplicationInsightsTelemetry(); }
public void FarmAlreadyRegistered(string message) { ViewModel = new BadRequestObjectResult(message); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(options => { // this filters are applied globally options.Filters.Add(new HttpResponseExceptionFilter()); options.Filters.Add(new ValidateAntiForgeryTokenAttribute()); }) .AddNewtonsoftJson(options => { options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; }) .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { /* * these lines change the results type to a serializable type (JSON) **/ var result = new BadRequestObjectResult(context.ModelState); result.ContentTypes.Add(MediaTypeNames.Application.Json); return(result); }; }); services.AddDbContext <IdDbContext>(); // *** adding other services *** // services.AddScoped <IUserService, UserService>(); services.AddScoped <IAuthenticationService, AuthenticationService>(); services.AddHttpContextAccessor(); // *** ****** ***** ******** *** // services.AddIdentity <User, Role>(opts => { opts.User.RequireUniqueEmail = true; }) .AddEntityFrameworkStores <IdDbContext>() .AddDefaultTokenProviders(); services.AddAntiforgery(options => { // this is the header name when the token is used to make a request options.HeaderName = "X-XSRF-TOKEN"; }); var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; /* * OpenId Connect - OAuth 2.0 --> * Auth diagrams: https://christianlydemann.com/creating-an-openid-connect-system-with-angular-8-and-identityserver4-oidc-part-1/ * Open Id Connect specification: https://openid.net/specs/openid-connect-core-1_0.html * pkce: https://tools.ietf.org/html/rfc7636 * * For pkce +-------------------+ | Authz Server | +--------+ | +---------------+ | | |--(A)- Authorization Request ---->| | | | | + t(code_verifier), t_m | | Authorization | | | | | | Endpoint | | | |<-(B)---- Authorization Code -----| | | | | | +---------------+ | | Client | | | | | | +---------------+ | | |--(C)-- Access Token Request ---->| | | | | + code_verifier | | Token | | | | | | Endpoint | | | |<-(D)------ Access Token ---------| | | +--------+ | +---------------+ | +-------------------+ | | Figure 2: Abstract Protocol Flow * * To understand better this; The authorization code has an utility of just one time in the token endpoint. * When an authorization request is sent, it is send with a sha256 encrypted random string * known as t(code_verifier) from a code_verifier. Auth server respond with an Authorization code as normal. * Then the client send the code to token endpoint along with the code_verifier without been transformed. * the code_verifier is used to compare and decrypt the t(code_verifier) sent in the first request. * If there is no match then the access token is not sent <-- the request is rejected. * * To know more about the attack read: https://tools.ietf.org/html/rfc7636#section-1 */ services.AddIdentityServer(options => { options.Events.RaiseErrorEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseSuccessEvents = true; // this option will configure all the endpoints in openid-configuration // to use https or the given origin. options.PublicOrigin = "https://todoapp-demo.azurewebsites.net"; options.UserInteraction = new UserInteractionOptions { // because these paths are local they must start with a leadind slash LoginUrl = "/authentication/signin", // This must be the real Server URL! -- Im testing now LogoutUrl = "/authentication/signout", // This must be the real Server URL! -- Im testing now LoginReturnUrlParameter = "returnUrl", }; }) .AddConfigurationStore(options => { options.ConfigureDbContext = builder => { builder.UseSqlServer(ConnStringIdentityServer, optionsBuilder => { optionsBuilder.MigrationsAssembly(migrationAssembly); }); }; }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => { builder.UseSqlServer(ConnStringIdentityServer, optionsBuilder => { optionsBuilder.MigrationsAssembly(migrationAssembly); }); }; options.EnableTokenCleanup = true; }) .AddProfileService <UserProfileService>() .AddDeveloperSigningCredential() .AddAspNetIdentity <User>(); services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/build"; }); }
public TestBadRequestObjectResult(BadRequestObjectResult innerResult) : base(innerResult) { _value = innerResult.Value; }
public override void OnException(ExceptionContext context) { bool isDevelopment = _hostEnviroment.IsDevelopment(); var ex = context.Exception; string stackTrace = (isDevelopment) ? context.Exception.StackTrace : string.Empty; string message = ex.Message; string error = string.Empty; IActionResult actionResult; switch (ex) { case SpyStoreInvalidQuantityException iqe: //returns a 400 error = "Invalid quantity request."; actionResult = new BadRequestObjectResult(new { Error = error, Message = message, stackTrace = stackTrace }); break; case DbUpdateConcurrencyException ce: //Returns a 400 error = "Concurency Issue"; actionResult = new BadRequestObjectResult(new { Error = error, Message = message, StackTrace = stackTrace }); break; case SpyStoreInvalidProductException ipe: error = "Invalid Product Id. "; actionResult = new BadRequestObjectResult(new { Error = error, Message = message, StackTrace = stackTrace }); break; case SpyStoreInvalidCustomerException ice: error = "Invalid Customer Id"; actionResult = new BadRequestObjectResult(new { Error = error, Message = message, StackTrace = stackTrace }); break; default: error = "General Error"; actionResult = new ObjectResult(new { Error = error, Message = message, StackTrace = stackTrace }) { StatusCode = 500 }; break; } // context.ExceptionHandled = true; context.Result = actionResult; }
public override void OnActionExecuting(ActionExecutingContext context) { var userId = context.RouteData.Values["userId"]; var teamId = context.RouteData.Values["teamId"]; var taskId = context.RouteData.Values["taskId"]; var commentId = context.RouteData.Values["commentId"]; var logId = context.RouteData.Values["logId"]; if (userId != null) { var userIdAsGuid = new Guid($"{userId}"); var userIdCheck = _context.Users.Any(u => u.Id == userIdAsGuid); if (!userIdCheck) { context.ModelState.AddModelError("userId", "This user doesn't exist"); var httpResult = new BadRequestObjectResult(context.ModelState) { StatusCode = 404 }; context.Result = httpResult; return; } } if (teamId != null) { var teamIdAsInt = int.Parse(teamId.ToString()); var teamIdCheck = _context.Teams.Any(t => t.Id == teamIdAsInt); if (!teamIdCheck) { context.ModelState.AddModelError("teamId", "This team doesn't exist."); var httpResult = new BadRequestObjectResult(context.ModelState) { StatusCode = 404 }; context.Result = httpResult; return; } } if (taskId != null) { var taskIdAsInt = int.Parse(taskId.ToString()); var taskIdCheck = _context.Teams.Include(t => t.Tasks) .Single(t => t.Id == int.Parse(teamId.ToString())) .Tasks.Any(t => t.Id == taskIdAsInt); if (!taskIdCheck) { context.ModelState.AddModelError("taskId", "This team doesn't have this task or it doesn't exist at all."); var httpResult = new BadRequestObjectResult(context.ModelState) { StatusCode = 404 }; context.Result = httpResult; return; } } if (commentId != null) { var commentIdAsInt = int.Parse(commentId.ToString()); var commentIdCheck = _context.Tasks.Include(t => t.Comments) .Single(t => t.Id == int.Parse(taskId.ToString())) .Comments.Any(c => c.Id == commentIdAsInt); if (!commentIdCheck) { context.ModelState.AddModelError("commentId", "This task doesn't have this comment or it doesn't exist at all."); var httpResult = new BadRequestObjectResult(context.ModelState) { StatusCode = 404 }; context.Result = httpResult; return; } } if (logId != null) { var logIdAsInt = int.Parse(logId.ToString()); var logIdCheck = _context.Tasks.Include(t => t.Log) .Single(t => t.Id == int.Parse(taskId.ToString())) .Log.Any(c => c.Id == logIdAsInt); if (!logIdCheck) { context.ModelState.AddModelError("logId", "This task doesn't have this log or it doesn't exist at all."); var httpResult = new BadRequestObjectResult(context.ModelState) { StatusCode = 404 }; context.Result = httpResult; return; } } base.OnActionExecuting(context); }
public static async Task <IActionResult> CreateRestaurant( [HttpTrigger(AuthorizationLevel.Function, "post", Route = "restaurants")] [RequestBodyType(typeof(RestaurantModel), "Restaurant request")] HttpRequest req, [Blob("restaurants", FileAccess.ReadWrite, Connection = "StorageSend")] CloudBlobContainer cloudBlobContainer, ILogger log, ExecutionContext context) { Guid correlationId = Util.ReadCorrelationId(req.Headers); var methodName = MethodBase.GetCurrentMethod().Name; var trace = new Dictionary <string, string>(); EventId eventId = new EventId(correlationId.GetHashCode(), Constants.ButlerCorrelationTraceName); IActionResult actionResult = null; using (log.BeginScope("Method:{methodName} CorrelationId:{CorrelationId} Label:{Label}", methodName, correlationId.ToString(), context.InvocationId.ToString())) { try { trace.Add(Constants.ButlerCorrelationTraceName, correlationId.ToString()); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); trace.Add("requestBody", requestBody); RestaurantModel restaurantModel = JsonConvert.DeserializeObject <RestaurantModel>(requestBody); bool isValid = Validate(restaurantModel, correlationId, log, out ErrorModel errorModel); if (isValid) { var fileName = CreateFileName(restaurantModel); trace.Add($"fileName", fileName); restaurantModel.Id = fileName; var fullFileName = $"{fileName}.json"; trace.Add($"fullFileName", fullFileName); req.HttpContext.Response.Headers.Add(Constants.ButlerCorrelationTraceHeader, correlationId.ToString()); CloudBlockBlob blob = cloudBlobContainer.GetBlockBlobReference($"{fullFileName}"); if (blob != null) { blob.Properties.ContentType = "application/json"; blob.Metadata.Add(Constants.ButlerCorrelationTraceName, correlationId.ToString().Replace("-", string.Empty)); blob.Metadata.Add(MetaRestaurant, System.Web.HttpUtility.HtmlEncode(restaurantModel.Name)); blob.Metadata.Add(MetaCity, System.Web.HttpUtility.HtmlEncode(restaurantModel.City)); var restaurant = JsonConvert.SerializeObject(restaurantModel); trace.Add("restaurant", restaurant); Task task = blob.UploadTextAsync(requestBody); task.Wait(); actionResult = new OkObjectResult(restaurantModel); log.LogInformation(correlationId, $"'{methodName}' - success", trace); } } else { actionResult = new BadRequestObjectResult(errorModel); log.LogInformation(correlationId, $"'{methodName}' - is not valid", trace); } } catch (Exception e) { trace.Add(string.Format("{0} - {1}", methodName, "rejected"), e.Message); trace.Add(string.Format("{0} - {1} - StackTrace", methodName, "rejected"), e.StackTrace); log.LogInformation(correlationId, $"'{methodName}' - rejected", trace); log.LogError(correlationId, $"'{methodName}' - rejected", trace); ErrorModel errorModel = new ErrorModel() { CorrelationId = correlationId, Details = e.StackTrace, Message = e.Message, }; actionResult = new BadRequestObjectResult(errorModel); } finally { log.LogTrace(eventId, $"'{methodName}' - finished"); log.LogInformation(correlationId, $"'{methodName}' - finished", trace); } } return(actionResult); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddControllers(); // Registrar as dependências de infra-estrutura services.ConfigureDependecies(Configuration); services.AddSingleton <MappingProfile>(); services.AddAutoMapper(o => o.AddProfile(new MappingProfile())); //Middleware Customizado services.AddGlobalExceptionHandlerMiddleware(); //Tratar os erros de validação services.Configure <ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { var problemDetails = new ValidationProblemDetails(context.ModelState); var result = new BadRequestObjectResult(problemDetails); try { BaseResponse respostaApi = new BaseResponse() { Success = false, Message = problemDetails.Title == "One or more validation errors occurred." ? "Ocorreram um ou mais erros de validação." : problemDetails.Title, Errors = problemDetails?.Errors?.Select(x => string.Join("; ", x.Value.ToArray()).ToLower().Contains("campo") ? string.Join("; ", x.Value.ToArray()) : x.Key + ": " + string.Join("; ", x.Value.ToArray())).ToArray() }; result = new BadRequestObjectResult(respostaApi); } catch { result = new BadRequestObjectResult(problemDetails); } result.ContentTypes.Add("application/problem+json"); result.ContentTypes.Add("application/problem+xml"); return(result); }; }); // Gerar a tela de swagger services.AddSwaggerGen(s => { s.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "API - Teste Cliente", Description = "API Swagger - Teste Cliente", Contact = new OpenApiContact { Name = "Ghadeer Ismael", Email = "*****@*****.**" } }); s.EnableAnnotations(); }); }
public override void OnException(ExceptionContext context) { _log(context); var message = context.Exception.Message; IActionResult result = null; switch (context.Exception) { case UnauthorizedAccessException ex: { result = new ObjectResult(new { ErrorMessage = message }) { StatusCode = 403 }; break; } case EntityNotFoundException ex: { result = new NotFoundObjectResult(message); break; } case EntityTagMismatchException ex: { result = new StatusCodeResult(412); break; } case OptimisticConcurrencyException ex: { result = new ObjectResult(new { ErrorMessage = message }) { StatusCode = 409 }; break; } case FluentValidation.ValidationException ex: { var msd = new ModelStateDictionary(); foreach (var error in ex.Errors) { string key = error.PropertyName; msd.AddModelError(key, error.ErrorMessage); } result = new BadRequestObjectResult(msd); break; } case SqlException ex: { if (SqlExceptionHandler.IsPrimaryKeyOrUniqueKeyViolation(ex)) { result = new ObjectResult(new { ErrorMessage = message }) { StatusCode = 409 }; } break; } } if (result != null) { if (result is ObjectResult o) { o.ContentTypes.Clear(); o.ContentTypes.Add("application/json"); } context.Result = result; context.Exception = null; } base.OnException(context); }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddDbContext <DataContext>(opt => opt.UseInMemoryDatabase("DataContextList")); services.AddHttpContextAccessor(); services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; options.SuppressConsumesConstraintForFormFileParameters = true; }); services.Configure <ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = actionContext => { var errors = actionContext.ModelState .Where(e => e.Value.Errors.Count > 0) .Select(e => new { Name = e.Key, Message = e.Value.Errors.First().ErrorMessage }).ToArray(); var invalidResponseFactory = new InvalidResponseFactory(actionContext.HttpContext); var errorreturn = new BadRequestObjectResult(errors); return(invalidResponseFactory.ResponseGenericResult(errorreturn.StatusCode, errorreturn.Value.ToString(), "Invalid Model State")); }; }); services.AddScoped <DbContext, DataContext>(f => f.GetService <DataContext>()); services.AddMvcCore().AddVersionedApiExplorer( options => { options.GroupNameFormat = "'v'VVV"; // note: this option is only necessary when versioning by url segment. the SubstitutionFormat // can also be used to control the format of the API version in route templates options.SubstituteApiVersionInUrl = true; }); services.AddApiVersioning( o => { o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(2, 0); o.ReportApiVersions = true; o.ErrorResponses = new InvalidResponseFactory(); }); #region AddSwaggerGen SwaggerDefaultValues.AddSwaggerGenforService(services); #endregion services.AddTransient(typeof(IGenericRepository <>), typeof(GenericRepository <>)); services.AddTransient(typeof(IGenericRepository <PetEntity>), typeof(GenericRepository <PetEntity>)); services.AddTransient <IPetsManager, PetsManager>(); services.AddTransient <IInvalidResponseFactory, InvalidResponseFactory>(); }
public TestBadRequestObjectResult(BadRequestObjectResult innerResult) : base(innerResult) { }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //services.AddMvc(options => //{ // // options.Filters.Add(typeof(DomainExceptionFilter)); // options.Filters.Add(typeof(ValidateModelAttribute)); //}); services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var loggerFactory = context.HttpContext.RequestServices.GetRequiredService <ILoggerFactory>(); var logger = loggerFactory.CreateLogger("Logger From Invalid Model"); var allErrors = context.ModelState.Values.SelectMany( v => v.Errors.Select(b => new Error { message = b.ErrorMessage })) .ToList <Error>(); logger.LogError(JsonConvert.SerializeObject(allErrors)); var result = new BadRequestObjectResult(allErrors); result.ContentTypes.Add(MediaTypeNames.Application.Json); return(result); }; }); #region Services application //services.Add(new ServiceDescriptor(typeof(IResponse<User>), new Response<User>())); //services.Add(new ServiceDescriptor(typeof(IGenericCommandAsync), new Token())); //services.Add(new ServiceDescriptor(typeof(IGenericCommandAsync<Travel>), new GenericCommandAsync<Travel>(GenericRepositoryAsync<Travel>))); services.AddTransient <IEmailSender, Models.EmailSender>(); //dependency injection of Infrastructure //services.AddScoped<IGenericCommandAsync<Travel>, GenericCommandAsync<Travel>>(); //services.AddScoped<IUserCommandAsync, UserCommandAsync>(); AddPersistence(services, Configuration); // Auto Mapper Configurations var mapperConfig = new MapperConfiguration(mc => { mc.AddProfile(new MappingProfile()); }); IMapper mapper = mapperConfig.CreateMapper(); services.AddSingleton(mapper); #endregion #region AutoMapper services.AddAutoMapper(typeof(Startup)); services.AddControllersWithViews(); #endregion #region Swagger //services.AddSwaggerGen(options => //{ // services.AddSwaggerGen(c => //{ // c.IncludeXmlComments(string.Format(@"{0}\blasa-travel.xml", System.AppDomain.CurrentDomain.BaseDirectory)); // c.SwaggerDoc("v1", new OpenApiInfo // { // Version = "v1", // Title = "blasa-travel", // }); //}); services.AddSwaggerGen(c => { c.IncludeXmlComments(string.Format(@"{0}\blasa-travel.xml", System.AppDomain.CurrentDomain.BaseDirectory)); c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "blasa-travel", }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = @"JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below. \r\n\r\nExample: 'Bearer 12345abcdef'", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, Scheme = "Bearer" }); c.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, }, new List <string>() } }); }); #endregion #region DBcontext //services.AddDbContext<ApplicationContext>(options => // options.UseSqlServer( // Configuration.GetConnectionString("DefaultConnection"), // b => b.MigrationsAssembly(typeof(ApplicationContext).Assembly.FullName))); #endregion #region API Versioning // Add API Versioning to the Project services.AddApiVersioning(config => { // Specify the default API Version as 1.0 config.DefaultApiVersion = new ApiVersion(1, 0); // If the client hasn't specified the API version in the request, use the default API version number config.AssumeDefaultVersionWhenUnspecified = true; // Advertise the API versions supported for the particular endpoint config.ReportApiVersions = true; }); #endregion ////dependency injection of Application layer //services.AddApplication(); // For Identity //services.AddIdentity<User, IdentityRole>(opt => //{ // opt.Password.RequiredLength = 8; // opt.Password.RequireDigit = false; // opt.Password.RequireUppercase = false; // opt.Password.RequireNonAlphanumeric = false; // //opt.User.RequireUniqueEmail = true; // opt.User.RequireUniqueEmail = false; // //opt.SignIn.RequireConfirmedEmail = false; //}) // //services.AddIdentity<ApplicationUser, IdentityRole>() // .AddEntityFrameworkStores<ApplicationDbContext>() // .AddDefaultTokenProviders(); // Adding Authentication services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) // Adding Jwt Bearer .AddJwtBearer(options => { options.SaveToken = true; options.RequireHttpsMetadata = false; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false, ValidateAudience = false, //ValidAudience = Configuration["JWT:ValidAudience"], //ValidIssuer = Configuration["JWT:ValidIssuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"])) }; }); }
/// <summary> /// Verificar se um valor é nulo ou ultrapassa os limites do mínimo/máximo número de caracteres. /// Caso viole alguma dessas regras, será retornado false e um objeto de BadRequest já configurado com /// o erro adequado. Caso nenhum problema seja encontrado, será retornado true e um objeto nulo. /// </summary> /// <param name="value">Valor a ser verificado.</param> /// <param name="minLength">Número mínimo de caracteres.</param> /// <param name="maxLegth">Número máximo de caracteres.</param> /// <param name="errorForNull">Erro que deve ser configurado caso esteja o valor seja nulo.</param> /// <param name="errorForLength">Erro que deve ser configurado caso o valor tenha ultrapassado os limites de caracteres mínimo ou máximo.</param> /// <param name="result">Objeto com o resultado de retorno.</param> /// <returns>Retorna true se o valor for válido, senão, false.</returns> protected bool IsValid(string value, int minLength, int maxLegth, Enum errorForNull, Enum errorForLength, out BadRequestObjectResult result) { if (string.IsNullOrWhiteSpace(value)) { result = BadRequest(errorForNull); } else if (value.Length < minLength || value.Length > maxLegth) { result = BadRequest(errorForLength); } else { result = null; } return(result == null); }
public async Task <ActionResult <Meeting> > PostMeeting(Meeting meeting, [FromQuery] string userId) { if (userId == null) { return(BadRequest("Missing 'userId' query parameter")); } // Check role of user bool isTeacher; try { isTeacher = await _usersService.IsTeacher(userId); } catch { return(StatusCode(500, "Couldn't check the user's role")); } // If user is a teacher, check meeting is theirs if (!isTeacher) { return(StatusCode(403, "Only teachers can create meetings"));; } // If user is a teacher, check meeting is theirs if (isTeacher && !meeting.Organizer.Equals(userId)) { return(StatusCode(403, "The user making the request must match the organizer"));; } // Check all fields are valid BadRequestObjectResult result = ValidateFields(meeting); if (result != null) { return(result); } // Check organizer doesn't have any other meeting // overlapping in time with this one List <Meeting> otherMeetings = _meetingsService.GetByOrganizer(meeting.Organizer); foreach (Meeting other in otherMeetings) { if (TimeOverlap(meeting.StartTime, meeting.EndTime, other.StartTime, other.EndTime)) { return(StatusCode(403, "The same teacher cannot have too meetings overlapping in time")); } } // Calculate and add intervals to meeting int numIntervals = meeting.TotalSpots / meeting.SpotsPerInterval; meeting.Intervals = new Interval[numIntervals]; TimeSpan totalTime = meeting.EndTime - meeting.StartTime; TimeSpan timePerInterval = totalTime / numIntervals; DateTime intervalStartTime = meeting.StartTime; DateTime intervalEndTime = intervalStartTime + timePerInterval; for (int i = 0; i < numIntervals; i++) { meeting.Intervals[i] = new Interval(); meeting.Intervals[i].StartTime = intervalStartTime; meeting.Intervals[i].EndTime = intervalEndTime; meeting.Intervals[i].Spots = meeting.SpotsPerInterval; meeting.Intervals[i].Attendees = new Booking[meeting.Intervals[i].Spots]; intervalStartTime = intervalEndTime; intervalEndTime = intervalStartTime + timePerInterval; } // Save meeting to database _meetingsService.Create(meeting); // Publish serialized event CreateTaskEvent _event = new CreateTaskEvent( "New meeting", meeting.BookingEndTime, meeting.Id); var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; string jsonString = JsonSerializer.Serialize(_event, options); _msgQueueService.ProduceMessage(jsonString); return(CreatedAtAction("GetMeeting", new { id = meeting.Id.ToString() }, meeting)); }