예제 #1
0
        /// <summary>
        /// Create the url for the saved query. The url thaks the user back to the same query.
        /// If the query includes a time variable, set the time filter to the choice the user have done
        /// in the radiobuttonlist.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void CreateSavedQueryUrl(Object sender, EventArgs e)
        {
            txtSaveQueryUrl.Text = "";
            lblError.Visible     = false;
            lblFormatError.Text  = "";
            lblFormatError.Style.Add("visibility", "hidden");
            //Remove css class for red border highlighting error
            ddlOutputFormats.CssClass = ddlOutputFormats.CssClass.Replace("saveas_dropdownlist_error", "");
            string output = ddlOutputFormats.SelectedValue;

            // Output format must be selected
            if (output.Equals("selectFormat"))
            {
                lblFormatError.Text = LocalizationManager.GetLocalizedString("CtrlSaveQuerySelectFormatMissing");
                //Add css class for red border highlighting error
                ddlOutputFormats.CssClass = "saveas_dropdownlist_error";
                lblFormatError.Style.Add("visibility", "visible");
                pnl2_SaveQuerySelection.Style.Add("display", "inline-block");
                return;
            }

            lblUpdateSummaryValue.Text = rblTimePeriod.SelectedItem.Text;
            lblOutputSummaryValue.Text = ddlOutputFormats.SelectedItem.Text;

            string time = rblTimePeriod.SelectedValue;

            try
            {
                var query = GetQueries();


                //start jfi
                foreach (var queryVariable in query.Quieries)
                {
                    var paxiomVariable = PaxiomManager.PaxiomModel.Meta.Variables.FirstOrDefault(v => v.Code.Equals(queryVariable.Code));
                    if (paxiomVariable == null)
                    {
                        if (string.IsNullOrEmpty(queryVariable.VariableType))
                        {
                            queryVariable.VariableType = "N";
                        }
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(queryVariable.VariableType))
                        {
                            queryVariable.VariableType = this.GetVariableTypeCode(paxiomVariable);
                        }
                    }
                }
                //end jfi

                var tvar = PaxiomManager.PaxiomModel.Meta.Variables.FirstOrDefault(v => v.IsTime);
                //No defined time variable in the model, skip time filter
                if (tvar != null)
                {
                    var qq = query.Quieries.FirstOrDefault(q => q.Code == tvar.Code);
                    if (qq == null)
                    {
                        //Will (also?) get here if all timevaules is selected
                        qq                  = new PCAxis.Query.Query();
                        qq.Code             = tvar.Code;
                        qq.VariableType     = "T";
                        qq.Selection        = new PCAxis.Query.QuerySelection();
                        qq.Selection.Filter = "all";
                        qq.Selection.Values = new string[] { "*" };
                        query.Quieries.Add(qq);
                    }

                    if (time == "item")
                    {
                        //Do Nothing
                    }
                    else if (time == "top")
                    {
                        qq.Selection.Filter = "top";
                        qq.Selection.Values = new string[] { tvar.Values.Count.ToString() };
                    }
                    else if (time == "from")
                    {
                        qq.Selection.Filter = "from";
                        var minValue = tvar.Values[0];
                        for (int i = 1; i < tvar.Values.Count; i++)
                        {
                            if (string.Compare(minValue.TimeValue, tvar.Values[i].TimeValue) > 0)
                            {
                                minValue = tvar.Values[i];
                            }
                        }
                        qq.Selection.Values = new string[] { minValue.Code };
                    }
                }

                PCAxis.Query.SavedQuery sq = new PCAxis.Query.SavedQuery();

                sq.Sources.Add(query);

                if (output == "SCREEN")
                {
                    sq.Output = ViewSerializerCreator.GetSerializer().Save();
                }
                else
                {
                    sq.Output = ViewSerializerCreator.GetSerializer(output).Save();
                }
                sq.TimeDependent = PaxiomManager.OperationsTracker.IsTimeDependent;

                sq.Workflow.AddRange(PaxiomManager.OperationsTracker.GetSteps().Where(ws => !ws.Type.ToUpper().StartsWith("PIVOT")).ToArray());

                //Due to convert json -> pxs we will always require manual worksteps as workflow.
                sq.Workflow.AddRange(GetManualWorkStepsForModel());


                string path = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/queries/");
                Dictionary <string, string> parameters = new Dictionary <string, string>();
                parameters.Add(PCAxis.Query.SavedQueryManager.SAVE_PARAMETER_PATH, path); // Save query to this directory

                string name = PCAxis.Query.SavedQueryManager.Current.Save(sq, parameters);

                if (!string.IsNullOrWhiteSpace(name))
                {
                    if (RouteInstance.RouteExtender == null)
                    {
                        txtSaveQueryUrl.Text = GetAppPath() + "sq/" + name;
                    }
                    else
                    {
                        txtSaveQueryUrl.Text = GetAppPath() + RouteInstance.RouteExtender.GetSavedQueryPath(PxUrl.Language, name);
                    }
                }
                else
                {
                    lblError.Visible = true;
                }
                //Hide and show the right panels
                pnl2_SaveQuerySelection.Style.Add("display", "none");
                pnl3_ShowSaveQueryUrl.Style.Add("display", "inline-block");
                Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "openAccordion",
                                                            "jQuery(document).ready(function(){openAccordion('SaveQueryHeader', 'SaveQueryBody')});", true);
            }
            catch (Exception ex)
            {
                lblError.Visible = true;
            }
        }
예제 #2
0
        public void ProcessRequest(HttpContext context)
        {
            // Negotiate with the request limiter (if enabled)
            if (_requestLimiter != null)
            {
                if (!_requestLimiter.ClientLimitOK(context.Request))
                {
                    // Deny request
                    // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                    context.Response.AppendHeader("Retry-After", _requestLimiter.LimiterTimeSpan.ToString());
                    throw new HttpException(429, "429 - Too many requests in too short timeframe. Please try again later.");
                }
            }

            // Enable CORS and preflight requests for saved queries
            // Preflight requests should also be allowed in the API (SSDHandler).

            if (Settings.Current.Features.SavedQuery.EnableCORS)
            {
                // Enable CORS (Cross-Origin-Resource-Sharing)
                context.Response.AppendHeader("Access-Control-Allow-Origin", "*");

                // Handle Preflight requests
                if (context.Request.HttpMethod == "OPTIONS")
                {
                    context.Response.AppendHeader("Access-Control-Allow-Methods", "GET");
                    return;
                }
            }

            string queryName;
            var    routeData = context.Items["RouteData"] as RouteData;

            if (routeData.Values["QueryName"] != null)
            {
                queryName = ValidationManager.GetValue(routeData.Values["QueryName"].ToString());
            }
            else
            {
                //No query supplied goto error page.
                //TODO just to shut the compiler up
                queryName = "";
                //TODO redirect
                throw new Exception("No query supplied");
            }

            // ----- Handle changed output format -----
            _format = GetChangedOutputFormat(routeData);

            // ----- Handle changed language -----
            HandleChangedLanguage();

            //Load saved query
            PCAxis.Query.SavedQuery sq = null;
            PXModel model = null;
            bool    safe  = true;

            try
            {
                if (PCAxis.Query.SavedQueryManager.StorageType == PCAxis.Query.SavedQueryStorageType.File)
                {
                    string path = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/queries/");

                    if (!queryName.ToLower().EndsWith(".pxsq"))
                    {
                        queryName = queryName + ".pxsq";
                    }

                    string[] allfiles = Directory.GetFiles(path, queryName, SearchOption.AllDirectories);

                    if (allfiles.Length == 0)
                    {
                        throw new HttpException(404, "HTTP/1.1 404 Not Found ");
                    }

                    queryName = allfiles[0];
                }

                //Check if the database is active.
                //It should not be possible to run a saved query if the database is not active
                sq = PCAxis.Query.SavedQueryManager.Current.Load(queryName);
                IEnumerable <string> db;
                TableSource          src = sq.Sources[0];

                if (src.Type.ToLower() == "cnmm")
                {
                    db = PXWeb.Settings.Current.General.Databases.CnmmDatabases;
                }
                else
                {
                    db = PXWeb.Settings.Current.General.Databases.PxDatabases;
                }
                bool activeDatabase = false;
                foreach (var item in db)
                {
                    if (item.ToLower() == src.DatabaseId.ToLower())
                    {
                        activeDatabase = true;
                        break;
                    }
                }
                if (!activeDatabase)
                {
                    throw new SystemException();
                }


                //Validate that the user has the rights to access the table
                string tableName = QueryHelper.GetTableName(src);
                //if (!AuthorizationUtil.IsAuthorized(src.DatabaseId, null, src.Source))
                if (!AuthorizationUtil.IsAuthorized(src.DatabaseId, null, tableName)) //TODO: Should be dbid, menu and selection. Only works for SCB right now... (2018-11-14)
                {
                    List <LinkManager.LinkItem> linkItems = new List <LinkManager.LinkItem>();
                    linkItems.Add(new LinkManager.LinkItem()
                    {
                        Key = PxUrl.LANGUAGE_KEY, Value = src.Language
                    });
                    linkItems.Add(new LinkManager.LinkItem()
                    {
                        Key = PxUrl.DB_KEY, Value = src.DatabaseId
                    });
                    linkItems.Add(new LinkManager.LinkItem()
                    {
                        Key = "msg", Value = "UnauthorizedTable"
                    });

                    string url = LinkManager.CreateLink("~/Menu.aspx", linkItems.ToArray());
                    HttpContext.Current.Response.Redirect(url, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    return;
                }

                if (string.IsNullOrWhiteSpace(_format))
                {
                    //Output format is not changed - use output format in the saved query
                    _format = sq.Output.Type;
                }

                // "Pre-flight" request from MS Office application
                var userAgent = context.Request.Headers["User-Agent"];
                //if (userAgent.ToLower().Contains("ms-office") && sq.Output.Type == PxUrl.VIEW_TABLE_IDENTIFIER)
                if (userAgent != null && userAgent.ToLower().Contains("ms-office"))
                {
                    context.Response.Write("<html><body>ms office return</body></html>");
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    //context.Response.End();
                    return;
                }

                //We need to store to be able to run workflow due to variables are referenced with name and not ids
                _originaleSavedQuerylanguage = sq.Sources[0].Language;

                // Check from saved query output type is on screen. If so createCopy shall be true, else false
                bool createCopy = CreateCopyOfCachedPaxiom(_format);

                // Create cache key
                string cacheKey = "";
                if (_language != null)
                {
                    cacheKey = string.Format("{0}_{1}", queryName, _language);
                }
                else
                {
                    cacheKey = string.Format("{0}_{1}", queryName, _originaleSavedQuerylanguage);
                }

                // Handle redirects to the selection page in a special way. The model object will only contain metadata and no data
                if (_format.Equals(PxUrl.PAGE_SELECT))
                {
                    cacheKey = string.Format("{0}_{1}", cacheKey, PxUrl.PAGE_SELECT);
                }

                // Try to get model from cache
                model = PXWeb.Management.SavedQueryPaxiomCache.Current.Fetch(cacheKey, createCopy);
                PaxiomManager.QueryModel = PXWeb.Management.SavedQueryPaxiomCache.Current.FetchQueryModel(cacheKey, createCopy);

                if (model == null || PaxiomManager.QueryModel == null)
                {
                    DateTime timeStamp = DateTime.Now;
                    // Model not found in cache - load it manually

                    model = LoadData(sq);

                    //Check if we need to change langauge to be able to run workflow due to variables are referenced with name and not ids
                    if (!string.IsNullOrEmpty(_language) && _language != _originaleSavedQuerylanguage)
                    {
                        model.Meta.SetLanguage(_originaleSavedQuerylanguage);
                    }

                    // No need to run workflow if we are redirecting to the selection page
                    if (!_format.Equals(PxUrl.PAGE_SELECT))
                    {
                        model = QueryHelper.RunWorkflow(sq, model);
                    }

                    //Set back to requested langauge after workflow operations
                    if (!string.IsNullOrEmpty(_language) && _language != _originaleSavedQuerylanguage)
                    {
                        if (model.Meta.HasLanguage(_language))
                        {
                            model.Meta.SetLanguage(_language);
                        }
                    }

                    // Store model in cache
                    PXWeb.Management.SavedQueryPaxiomCache.Current.Store(cacheKey, model, timeStamp);
                    PXWeb.Management.SavedQueryPaxiomCache.Current.StoreQueryModel(cacheKey, PaxiomManager.QueryModel, timeStamp);
                }

                if (!sq.Safe)
                {
                    safe = !CheckForUnsafeOperations(sq.Workflow);
                }
            }
            catch (Exception ex)
            {
                if ((PCAxis.Query.SavedQueryManager.StorageType == PCAxis.Query.SavedQueryStorageType.File && System.IO.File.Exists(queryName)) ||
                    (PCAxis.Query.SavedQueryManager.StorageType == PCAxis.Query.SavedQueryStorageType.Database))
                {
                    PCAxis.Query.SavedQueryManager.Current.MarkAsFailed(queryName);
                }

                throw new HttpException(404, "HTTP/1.1 404 Not Found");
                //throw ex;
            }

            sq.LoadedQueryName = queryName;
            PCAxis.Query.SavedQueryManager.Current.MarkAsRunned(queryName);

            // Tell the selection page that it sholud clear the PxModel
            if (_format.Equals(PxUrl.PAGE_SELECT))
            {
                HttpContext.Current.Session.Add("SelectionClearPxModel", true);
            }

            ViewSerializerCreator.GetSerializer(_format).Render(_format, sq, model, safe);
        }