Exemplo n.º 1
0
        private IResponse Query <T>(IRequestContext ctx, Route route, IQuery <T> query, NameValueCollection p)
        {
            IQuery <T> wrappedQuery = WrapInJoinQueryIfFound(query, this.Database, p);

            // Ensure the table exists and set it on the query
            string tableName = GetAndValidateTableName(route);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table not found to query."));
            }

            query.TableName = tableName;

            // Correct the query with default correctors
            using (ctx.Monitor(MonitorEventLevel.Verbose, "Correct", type: "Table", identity: tableName, detail: query.Where.ToString()))
            {
                query.Correct(this.CurrentCorrectors(ctx));
            }

            // Execute and return results for the query
            using (ctx.Monitor(MonitorEventLevel.Information, query.GetType().Name, type: "Table", identity: tableName, detail: query.Where.ToString()))
            {
                T result = this.Database.Query(wrappedQuery, (si) => this.IsInIdentity(ctx.Request.User, si));
                return(ArribaResponse.Ok(result));
            }
        }
Exemplo n.º 2
0
        protected IResponse ValidateCreateAccess(IRequestContext ctx, Route route)
        {
            bool hasPermission = false;

            var security = this.Database.DatabasePermissions();

            if (!security.HasTableAccessSecurity)
            {
                // If there's no security, table create is only allowed if the service is running as the same user
                hasPermission = ctx.Request.User.Identity.Name.Equals(WindowsIdentity.GetCurrent().Name);
            }
            else
            {
                // Otherwise, check for writer or better permissions at the DB level
                hasPermission = HasPermission(security, ctx.Request.User, PermissionScope.Writer);
            }

            if (!hasPermission)
            {
                return(ArribaResponse.Forbidden(String.Format("Create Table access denied for {0}.", ctx.Request.User.Identity.Name)));
            }
            else
            {
                return(ContinueToNextHandlerResponse);
            }
        }
Exemplo n.º 3
0
        private async Task <IResponse> Suggest(IRequestContext ctx, Route route)
        {
            NameValueCollection p = await ParametersFromQueryStringAndBody(ctx);

            string     query         = p["q"];
            string     selectedTable = p["t"];
            IPrincipal user          = ctx.Request.User;

            IntelliSenseResult result = null;

            using (ctx.Monitor(MonitorEventLevel.Verbose, "Suggest", type: "Suggest", detail: query))
            {
                // Get all available tables
                List <Table> tables = new List <Table>();
                foreach (string tableName in this.Database.TableNames)
                {
                    if (this.HasTableAccess(tableName, user, PermissionScope.Reader))
                    {
                        if (String.IsNullOrEmpty(selectedTable) || selectedTable.Equals(tableName, StringComparison.OrdinalIgnoreCase))
                        {
                            tables.Add(this.Database[tableName]);
                        }
                    }
                }

                // Get IntelliSense results and return
                QueryIntelliSense qi = new QueryIntelliSense();
                result = qi.GetIntelliSenseItems(query, tables);
            }

            return(ArribaResponse.Ok(result));
        }
        private IResponse AllCount(IRequestContext ctx, Route route)
        {
            string queryString = ctx.Request.ResourceParameters["q"] ?? "";
            AllCountResult result = new AllCountResult(queryString);

            // Build a Count query
            IQuery<AggregationResult> query = new AggregationQuery("count", null, queryString);

            // Wrap in Joins, if found
            query = WrapInJoinQueryIfFound(query, this.Database, ctx);

            // Run server correctors
            using (ctx.Monitor(MonitorEventLevel.Verbose, "Correct", type: "AllCount", detail: query.Where.ToString()))
            {
                query.Correct(this.CurrentCorrectors(ctx));
            }

            // Accumulate Results for each table
            IPrincipal user = ctx.Request.User;
            using (ctx.Monitor(MonitorEventLevel.Information, "AllCount", type: "AllCount", detail: query.Where.ToString()))
            {
                IExpression defaultWhere = query.Where;

                foreach (string tableName in this.Database.TableNames)
                {
                    if (this.HasTableAccess(tableName, user, PermissionScope.Reader))
                    {
                        query.TableName = tableName;
                        query.Where = defaultWhere;

                        AggregationResult tableCount = this.Database.Query(query, (si) => this.IsInIdentity(ctx.Request.User, si));

                        if (!tableCount.Details.Succeeded || tableCount.Values == null)
                        {
                            result.ResultsPerTable.Add(new CountResult(tableName, 0, true, false));
                        }
                        else
                        {
                            result.ResultsPerTable.Add(new CountResult(tableName, (ulong)tableCount.Values[0, 0], true, tableCount.Details.Succeeded));
                        }
                    }
                    else
                    {
                        result.ResultsPerTable.Add(new CountResult(tableName, 0, false, false));
                    }
                }
            }

            // Sort results so that succeeding tables are first and are subsorted by count [descending]
            result.ResultsPerTable.Sort((left, right) =>
            {
                int order = right.Succeeded.CompareTo(left.Succeeded);
                if (order != 0) return order;

                return right.Count.CompareTo(left.Count);
            });

            return ArribaResponse.Ok(result);
        }
Exemplo n.º 5
0
        protected Task <IResponse> ValidateBodyAsync(IRequestContext ctx, Route route)
        {
            if (!ctx.Request.HasBody)
            {
                return(Task.FromResult <IResponse>(ArribaResponse.BadRequest("Request must have content body")));
            }

            return(Task.FromResult <IResponse>(null));
        }
        private async Task<IResponse> Select(IRequestContext ctx, Route route)
        {
            string tableName = GetAndValidateTableName(route);
            if (!this.Database.TableExists(tableName))
            {
                return ArribaResponse.NotFound("Table not found to select from.");
            }

            string outputFormat = ctx.Request.ResourceParameters["fmt"];

            SelectQuery query = await SelectQueryFromRequest(this.Database, ctx);
            query.TableName = tableName;

            Table table = this.Database[tableName];
            SelectResult result = null;

            // If no columns were requested or this is RSS, get only the ID column
            if(query.Columns == null || query.Columns.Count == 0 || String.Equals(outputFormat, "rss", StringComparison.OrdinalIgnoreCase))
            {
                query.Columns = new string[] { table.IDColumn.Name };
            }

            // Read Joins, if passed
            IQuery<SelectResult> wrappedQuery = WrapInJoinQueryIfFound(query, this.Database, ctx);

            ICorrector correctors = this.CurrentCorrectors(ctx);
            using (ctx.Monitor(MonitorEventLevel.Verbose, "Correct", type: "Table", identity: tableName, detail: query.Where.ToString()))
            {
                // Run server correctors
                wrappedQuery.Correct(correctors);
            }

            using (ctx.Monitor(MonitorEventLevel.Information, "Select", type: "Table", identity: tableName, detail: query.Where.ToString()))
            {
                // Run the query
                result = this.Database.Query(wrappedQuery, (si) => this.IsInIdentity(ctx.Request.User, si));
            }

            // Format the result in the return format
            switch((outputFormat ?? "").ToLowerInvariant())
            {
                case "":
                case "json":
                    return ArribaResponse.Ok(result);
                case "csv":
                    return ToCsvResponse(result, $"{tableName}-{DateTime.Now:yyyyMMdd}.csv");
                case "rss":
                    return ToRssResponse(result, "", query.TableName + ": " + query.Where, ctx.Request.ResourceParameters["iURL"]);
                default:
                    throw new ArgumentException($"OutputFormat [fmt] passed, '{outputFormat}', was invalid.");
            }
        }
Exemplo n.º 7
0
        protected IResponse ValidateTableAccess(IRequestContext ctx, Route routeData, PermissionScope scope, bool overrideLocalHostSameUser = false)
        {
            string tableName = GetAndValidateTableName(routeData);

            if (!this.Database.TableExists(tableName))
            {
                return(ArribaResponse.NotFound("Table requested does not exist."));
            }

            var currentUser = ctx.Request.User;

            // If we are asked if override auth, check if the request was made from a loopback address (local) and the
            // current process identity matches the request identity
            if (overrideLocalHostSameUser && IsRequestOriginLoopback(ctx.Request) && IsProcessUserSame(currentUser.Identity))
            {
                // Log for auditing that we skipped out on checking table auth.
                this.EventSource.Raise(MonitorEventLevel.Warning,
                                       MonitorEventOpCode.Mark,
                                       entityType: "Table",
                                       entityIdentity: tableName,
                                       name: "Authentication Override",
                                       user: ctx.Request.User.Identity.Name,
                                       detail: "Skipping table authentication for local loopback user on request");

                return(ContinueToNextHandlerResponse);
            }

            if (!HasTableAccess(tableName, currentUser, scope))
            {
                return(ArribaResponse.Forbidden(String.Format("Access to {0} denied for {1}.", tableName, currentUser.Identity.Name)));
            }
            else
            {
                return(ContinueToNextHandlerResponse);
            }
        }