示例#1
0
        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);
        }
示例#3
0
 //[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();
            }
        }
示例#5
0
        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));
        }
示例#6
0
        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)));
        }
示例#7
0
 protected override void OnSetUp()
 {
     Server.WithWebApi("/api", o =>
     {
         o.WithController <TestController>();
         o.OnUnhandledException = (ctx, ex) => throw HttpException.BadRequest();
     });
 }
示例#8
0
            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 });
            }
示例#9
0
        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 });
        }
示例#10
0
        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 });
        }
示例#11
0
        /// <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();
        }
示例#12
0
        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);
        }
示例#13
0
 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}.");
            }
        }
示例#15
0
        /// <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();
        }
示例#16
0
        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));
        }
示例#17
0
        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>()));
        }
示例#19
0
        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,
            });
        }
示例#20
0
        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());
        }
示例#21
0
        /// <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);
        }
示例#22
0
        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>());
        }
示例#23
0
        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");
            }
        }
示例#24
0
        /// <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));
            }
        }
示例#26
0
        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));
        }
示例#27
0
        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
                })
            });
        }