private void ValidateHttpOptions(IHttpContext context) { var requestHeadersHeader = context.Request.Headers[HttpHeaderNames.AccessControlRequestHeaders]; if (!string.IsNullOrWhiteSpace(requestHeadersHeader)) { // TODO: Remove unwanted headers from request context.Response.Headers.Set(HttpHeaderNames.AccessControlAllowHeaders, requestHeadersHeader); } var requestMethodHeader = context.Request.Headers[HttpHeaderNames.AccessControlRequestMethod]; if (string.IsNullOrWhiteSpace(requestMethodHeader)) { return; } var currentMethods = requestMethodHeader.ToLowerInvariant() .SplitByComma(StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()); if (_methods != All && !currentMethods.Any(_validMethods.Contains)) { throw HttpException.BadRequest(); } context.Response.Headers.Set(HttpHeaderNames.AccessControlAllowMethods, requestMethodHeader); }
public async Task create([QueryField] string username, [QueryField] string password) { if (username == null || password == null) { throw HttpException.BadRequest(); } if (!validated) { throw HttpException.Forbidden(); } // If a user already exists, it is not possible to create a new user if (await getUser(username) != null) { throw HttpException.NotAcceptable(); } var model = new AccountModel { username = username.ToLower(), // :to_lower_thinking: - Taylor permissions = new List <string> { "Admin" } }; model.setPassword(password); await accountCollection.InsertOneAsync(model); }
//[AssertionMethod] internal static void ThrowIfAccessingRootButNotAllowed(bool usePortalRoot, bool userIsRestricted) { if (usePortalRoot && userIsRestricted) { throw HttpException.BadRequest("you may only create draft-data, so file operations outside of ADAM is not allowed"); } }
public async Task delete([QueryField] string username) { if (username == null) { throw HttpException.BadRequest(); } if (!validated) { throw HttpException.Forbidden(); } var user = await getUser(username); if (user == null) { throw HttpException.NotFound(); } var result = await accountCollection.DeleteOneAsync( Builders <AccountModel> .Filter.Eq(x => x.id, user.id)); if (result.DeletedCount != 1) { throw HttpException.InternalServerError(); } }
public string login([QueryField] string username, [QueryField] string password) { if (username == null || password == null) { throw HttpException.BadRequest(); } var user = server.client.database .GetCollection <AccountModel>(AccountModel.collectionName) .Find(x => x.username == username.ToLower()); if (!user.Any()) { throw HttpException.Unauthorized(); } if (!user.First().checkPassword(password)) { throw HttpException.Unauthorized(); } return(JWT.Encode(new AuthorizationPayload { fullName = username, validUntil = DateTime.Now.AddHours(1), // Expire in 1 hour permissions = user.First().permissions }, Encoding.UTF8.GetBytes(server.config.jwtSecret), JwsAlgorithm.HS256)); }
public static HttpResponseException ToException(this ValidationResult result) { var validationErrors = result.Errors.Select(e => new KeyValuePair <string, string>(e.PropertyName, e.ErrorMessage) ); return(HttpException.BadRequest(JsonConvert.SerializeObject(validationErrors))); }
protected override void OnSetUp() { Server.WithWebApi("/api", o => { o.WithController <TestController>(); o.OnUnhandledException = (ctx, ex) => throw HttpException.BadRequest(); }); }
public object GetVersionCategory(string client, [QueryField] string etc) { if (client != "Unosquare") { throw HttpException.BadRequest("Only Unosquare", new { Error = "Se murio esto" }); } return(new { Version = "1.0", Client = client, Etc = etc }); }
public object GetVersion4(string client, string product, [QueryField] string etc) { //There are two kinds of exceptions. The system ones and the embedIO's exceptions. if (client != "Unosquare") { throw HttpException.BadRequest("only Unosquare", new { Error = true }); } return(new { Version = "1.0", Client = client, Product = product, Etc = etc }); }
public object getVersion(string client, string product) { if (client != "Unosqure") { throw HttpException.BadRequest("Only Unosquare"); } //throw new InvalidOperationException("Only Unosquare"); return(new { Version = 1.0, Client = client, Product = product }); }
/// <inheritdoc /> protected override Task OnRequestAsync(IHttpContext context) { if (context.RequestedPath == "/") { return(context.SendDataAsync((object)Data)); } var parts = context.RequestedPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); var table = Data[parts[0]]; if (table == null) { throw HttpException.NotFound(); } var verb = context.Request.HttpVerb; switch (parts.Length) { case 1 when verb == HttpVerbs.Get: return(context.SendDataAsync((object)table)); case 1 when verb == HttpVerbs.Post: return(AddRow(context, table)); case 2: { foreach (var row in table) { if (row["id"].ToString() != parts[1]) { continue; } switch (verb) { case HttpVerbs.Get: return(context.SendDataAsync((object)row)); case HttpVerbs.Put: return(UpdateRow(context, row)); case HttpVerbs.Delete: RemoveRow(table, row); return(Task.CompletedTask); } } break; } } throw HttpException.BadRequest(); }
internal bool MustThrowIfAccessingRootButNotAllowed(bool usePortalRoot, out HttpExceptionAbstraction preparedException) { if (usePortalRoot && UserIsRestricted) { preparedException = HttpException.BadRequest("you may only create draft-data, so file operations outside of ADAM is not allowed"); return(true); } preparedException = null; return(false); }
public async Task <bool> OpenAsync([JsonData] CreateNewSerialRequest createNewSerialRequest) { if (createNewSerialRequest is null) { throw HttpException.BadRequest("Request is empty"); } if (createNewSerialRequest.BaudRate < 1) { throw HttpException.BadRequest("Use a standard baud rate."); } return(await _serialHandler.OpenAsync(createNewSerialRequest)); }
public async Task <object?> GetRequestDataAsync(WebApiController controller, Type type, string parameterName) { string body; using (var reader = controller.HttpContext.OpenRequestText()) { body = await reader.ReadToEndAsync().ConfigureAwait(false); } try { return(System.Text.Json.JsonSerializer.Deserialize(body, type, Utils.JsonOptions())); } catch (FormatException) { throw HttpException.BadRequest($"Expected request body to be deserializable to {type.FullName}."); } }
/// <inheritdoc /> protected override async Task OnRequestAsync(IHttpContext context) { var verb = context.Request.HttpVerb; var parts = context.RequestedPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); var setType = _dbTypes .FirstOrDefault(x => x.Name.Equals(parts[0], StringComparison.OrdinalIgnoreCase)); if (setType == null) { throw HttpException.NotFound(); } var table = _dbInstance.Set(setType); switch (parts.Length) { case 1 when verb == HttpVerbs.Get: var current = await _dbInstance.SelectAsync <object>(table, "1=1"); await context.SendDataAsync(current.Select(row => SetValues(Activator.CreateInstance(setType), row)).ToList()); return; case 1 when verb == HttpVerbs.Post: await AddRow(context, setType); return; case 2 when verb == HttpVerbs.Get: var data = _dbInstance.Select <object>(table, RowSelector, new { RowId = parts[1] }); var objTable = SetValues(Activator.CreateInstance(setType), data.First()); await context.SendDataAsync(objTable); return; case 2 when verb == HttpVerbs.Put: await UpdateRow(setType, table, parts[1], context); return; case 2 when verb == HttpVerbs.Delete: await RemoveRow(table, parts[1], setType); return; } throw HttpException.BadRequest(); }
public async Task <FileResponse> SaveAsync() { var parser = await MultipartFormDataParser.ParseAsync(Request.InputStream); if (parser?.Files is null) { throw HttpException.NotFound("No file uploaded"); } if (parser?.Files.Count != 1) { throw HttpException.BadRequest("Only 1 file can be uploaded"); } return(await _filesHandler.SaveAsync(parser.Files[0].Data, parser.Files[0].FileName)); }
async Task <object?> IRequestDataAttribute <WebApiController> .GetRequestDataAsync( WebApiController controller, Type type, string parameterName) { var data = await controller.HttpContext.GetRequestFormDataAsync() .ConfigureAwait(false); var fieldName = FieldName ?? parameterName; if (!data.ContainsKey(fieldName) && BadRequestIfMissing) { throw HttpException.BadRequest($"Missing form field {fieldName}."); } object result = null; if (type.IsArray) { var fieldValues = data.GetValues(fieldName) ?? Array.Empty <string>(); if (!FromString.TryConvertTo(type, fieldValues, out result)) { throw HttpException.BadRequest($"Cannot convert field {fieldName} to an array of {type.GetElementType().Name}."); } return(result); } else { var fieldValue = data.GetValues(fieldName)?.LastOrDefault(); if (fieldValue == null) { if (type.IsValueType) { var parameter = controller.CurrentMethod.GetParameters().FirstOrDefault(p => p.Name == parameterName); result = parameter.HasDefaultValue ? parameter.DefaultValue : Activator.CreateInstance(type); } return(Task.FromResult(result)); } if (!FromString.TryConvertTo(type, fieldValue, out result)) { throw HttpException.BadRequest($"Cannot convert field {fieldName} to {type.Name}."); } return(result); } }
Task <string[]> IRequestDataAttribute <WebApiController, string[]> .GetRequestDataAsync( WebApiController controller, string parameterName) { var data = controller.HttpContext.GetRequestQueryData(); var fieldName = FieldName ?? parameterName; if (!data.ContainsKey(fieldName) && BadRequestIfMissing) { throw HttpException.BadRequest($"Missing query field {fieldName}."); } return(Task.FromResult(data.GetValues(fieldName) ?? Array.Empty <string>())); }
public object GetVersion3(string client, string product, [QueryField] string saludo) { if (client != "Unosquare") { throw HttpException.BadRequest("Only Unosquare", new { Data = "Hazlo bien" }); } return(new { version = 1.0, client, product, saludo, }); }
public string consultar(string deviceName) { DeviceFactory deviceFactory = new DeviceFactory(); Device device; try { device = deviceFactory.create(deviceName); } catch (NotImplementedException) { throw HttpException.BadRequest("Dispositivo não implementado"); } return(device.consultar()); }
/// <summary> /// Determine if errors exist, and return that state /// </summary> /// <returns></returns> protected bool BuildExceptionIfHasIssues(out HttpExceptionAbstraction preparedException, string logMessage = null) { var wrapLog = Log.Call(); preparedException = HasErrors ? HttpException.BadRequest(Errors): null; if (logMessage != null) { Log.Add($"{nameof(logMessage)}:{logMessage}"); } if (HasErrors) { Log.Add($"Errors:{Errors}"); } wrapLog(HasErrors ? "found errors" : "all ok"); return(!HasErrors); }
async Task <string[]> INonNullRequestDataAttribute <WebApiController, string[]> .GetRequestDataAsync( WebApiController controller, string parameterName) { var data = await controller.HttpContext.GetRequestFormDataAsync() .ConfigureAwait(false); var fieldName = FieldName ?? parameterName; if (!data.ContainsKey(fieldName) && BadRequestIfMissing) { throw HttpException.BadRequest($"Missing form field {fieldName}."); } return(data.GetValues(fieldName) ?? Array.Empty <string>()); }
protected void VerifySecurityAndStructure(Eav.Apps.Assets.Folder <TFolderId, TFileId> parentFolder, IAssetWithParentSysId <TFolderId> target, string errPrefix) { // In case the primary file system is used (usePortalRoot) then also check higher permissions if (AdamContext.UseSiteRoot && !AdamContext.Security.CanEditFolder(target)) { throw HttpException.PermissionDenied(errPrefix + " - permission denied"); } if (!AdamContext.Security.SuperUserOrAccessingItemFolder(target.Path, out var exp)) { throw exp; } if (!EqualityComparer <TFolderId> .Default.Equals(target.ParentSysId, parentFolder.SysId)) { throw HttpException.BadRequest(errPrefix + " - not found in folder"); } }
/// <inheritdoc /> protected override async Task OnRequestAsync(IHttpContext context) { if (context.Route.SubPath == null) { throw HttpException.NotFound(); } // Split the sub path string[] pathParts = context.Route.SubPath.Substring(1).Split('/'); // Expect a plugin ID and an endpoint if (pathParts == null || pathParts.Length != 2) { throw HttpException.BadRequest("Path must contain a plugin ID and endpoint and nothing else."); } // Find a matching plugin if (!_pluginEndPoints.TryGetValue(pathParts[0], out Dictionary <string, PluginEndPoint>?endPoints)) { throw HttpException.NotFound($"Found no plugin with ID {pathParts[0]}."); } // Find a matching endpoint if (!endPoints.TryGetValue(pathParts[1], out PluginEndPoint? endPoint)) { throw HttpException.NotFound($"Found no endpoint called {pathParts[1]} for plugin with ID {pathParts[0]}."); } // If Accept-Charset contains a wildcard, remove the header so we default to UTF8 // This is a workaround for an EmbedIO ehh issue string?acceptCharset = context.Request.Headers["Accept-Charset"]; if (acceptCharset != null && acceptCharset.Contains("*")) { context.Request.Headers.Remove("Accept-Charset"); } // It is up to the registration how the request is eventually handled, it might even set a response here await endPoint.InternalProcessRequest(context); // No need to return ourselves, assume the request is fully handled by the end point context.SetHandled(); }
Task <object?> IRequestDataAttribute <WebApiController> .GetRequestDataAsync( WebApiController controller, Type type, string parameterName) { var data = controller.HttpContext.GetRequestQueryData(); var fieldName = FieldName ?? parameterName; if (!data.ContainsKey(fieldName) && BadRequestIfMissing) { throw HttpException.BadRequest($"Missing query field {fieldName}."); } if (type.IsArray) { var fieldValues = data.GetValues(fieldName) ?? Array.Empty <string>(); if (!FromString.TryConvertTo(type, fieldValues, out var result)) { throw HttpException.BadRequest($"Cannot convert field {fieldName} to an array of {type.GetElementType().Name}."); } return(Task.FromResult(result)); } else { var fieldValue = data.GetValues(fieldName)?.LastOrDefault(); if (fieldValue == null) { return(Task.FromResult(type.IsValueType ? Activator.CreateInstance(type) : null)); } if (!FromString.TryConvertTo(type, fieldValue, out var result)) { throw HttpException.BadRequest($"Cannot convert field {fieldName} to {type.Name}."); } return(Task.FromResult(result)); } }
internal bool FileTypeIsOkForThisField(out HttpExceptionAbstraction preparedException) { var wrapLog = Log.Call <bool>(); var fieldDef = AdamState.Attribute; bool result; // check if this field exists and is actually a file-field or a string (wysiwyg) field if (fieldDef == null || !(fieldDef.Type != Eav.Constants.DataTypeHyperlink || fieldDef.Type != Eav.Constants.DataTypeString)) { preparedException = HttpException.BadRequest("Requested field '" + AdamState.ItemField + "' type doesn't allow upload"); Log.Add($"field type:{fieldDef?.Type} - does not allow upload"); result = false; } else { Log.Add($"field type:{fieldDef.Type}"); preparedException = null; result = true; } return(wrapLog(result.ToString(), result)); }
public async Task <object> editData(int index) { if (server.config.userRoleMatches.Count <= index) { throw HttpException.BadRequest($"Match {index} does not exist."); } var workbook = new XSSFWorkbook(HttpContext.Request.InputStream); // Spreadsheet parsing can go wrong quickly, I'm trying to make good error messages to catch that. if (workbook.NumberOfSheets != 1) { return(new { error = $"Expected one sheet but got {workbook.NumberOfSheets}." }); } var sheet = workbook.GetSheetAt(0); // This is a complicated, crappy system. // I'm trying to use to be compatible with as many spreadsheets as possible. CellReference?firstName = null; CellReference?lastName = null; CellReference?email = null; CellReference?fullName = null; var columnsAccounted = new List <int>(); // Here for convenience. It may have been a mistake to use nullable CellReference. For review. bool foundAllCells() { return((firstName.HasValue && lastName.HasValue || fullName.HasValue) && email.HasValue); } bool hasRowConflict() { var list = new[] { firstName?.rowNumber, lastName?.rowNumber, fullName?.rowNumber, email?.rowNumber, }.Where(x => x.HasValue).ToArray(); return(list.Any(x => x != list.First())); } // Justifying my use of exceptions: case is exceptional. See MatchController.pickCell(). try { foreach (IRow row in sheet) { foreach (var cell in row) { // We only want cells that have text and are in a column we haven't seen before. if (cell.CellType != CellType.String || columnsAccounted.Contains(cell.ColumnIndex)) { continue; } var text = cell.StringCellValue.ToLower(); if (text.Length == 0) { continue; } // Rough approximation of what a header might have. if (text.Contains("name")) { if (text.Contains("first")) { pickCell(ref firstName, row, cell, "first name"); } else if (text.Contains("last")) { pickCell(ref lastName, row, cell, "last name"); } else { pickCell(ref fullName, row, cell, "full name"); } } else if (text.Contains("email") || text.Contains("address")) { pickCell(ref email, row, cell, "address"); } columnsAccounted.Add(cell.ColumnIndex); } // I want to make sure the starting row is consistent for all entries. if (hasRowConflict()) { var errorMessage = string.Join(", ", new List <string> { firstName.HasValue ? $"first name: {firstName.Value.rowNumber}" : null, lastName.HasValue ? $"last name: {lastName.Value.rowNumber}" : null, fullName.HasValue ? $"full name: {fullName.Value.rowNumber}" : null, email.HasValue ? $"email: {email.Value.rowNumber}" : null, }.Where(x => x != null)); return(new { error = $"Headers were split across multiple rows ({errorMessage})." }); } // Quit early if we have found all columns. if (foundAllCells()) { break; } } } catch (Exception e) { // Catch anything thrown from MatchController.catchCell(). return(new { error = e.Message }); } if (!foundAllCells()) { // :eyes: var errorMessage = string.Join(", ", new List <string> { firstName.HasValue?null: "missing first name", lastName.HasValue ? null : "missing last name", fullName.HasValue ? null : "missing full name", email.HasValue ? null : "missing email name", }.Where(x => x != null)); return(new { error = $"Could not find required headers ({errorMessage})." }); } if (!email.HasValue) { return(new { error = "Internal error, was not able to collect data." }); } // Email always has a value. See foundAllCells(). var firstNameData = new List <string>(); var lastNameData = new List <string>(); var fullNameData = new List <string>(); var emailData = new List <string>(); var startingRow = email.Value.rowNumber; // Iterate through them all. Efficiency takes a hit, excel allows a lot of empty rows. for (var a = startingRow; a < sheet.LastRowNum; a++) { var row = sheet.GetRow(a); // Use convenience function to reduce duplication. fetchCell(row, firstName, firstNameData); fetchCell(row, lastName, lastNameData); fetchCell(row, fullName, fullNameData); fetchCell(row, email, emailData); } // Going to assume all lists have the same size. I need to combine them manually now. // Email is still guaranteed to have a value I suppose. var details = new List <UserDetails>(); for (var a = 0; a < emailData.Count; a++) { var result = new UserDetails(); if (emailData[a].Length == 0) { continue; } if (fullName.HasValue) { var name = fullNameData[a]; var splitIndex = name.LastIndexOf(' '); result.firstName = name.Substring(0, splitIndex); result.lastName = name.Substring(splitIndex); } else { result.firstName = firstNameData[a]; result.lastName = lastNameData[a]; } result.email = emailData[a]; details.Add(result); } // Replace the previous details object. var match = server.config.userRoleMatches[index]; match.userDetailInformation = details; // Evaluate match takes a long time with rate limits, run later and hope it works. // Better than praying that the super short axios timeout is enough time. await evaluateMatch(match).ConfigureAwait(false); return(new { details = match.userDetailInformation.Select(x => new { x.email, x.firstName, x.lastName }) }); }