/// <summary>
 /// NOTE: This method will be deleted when RSIS Goal 925 is completed. But continue using it when necessary since there is no good alternative.
 /// </summary>
 public static ActionButtonSetup CreateWithUrl( string text, ResourceInfo resourceInfo, ActionControlIcon icon = null )
 {
     return new ActionButtonSetup( text, new EwfLink( resourceInfo ), icon: icon );
 }
 protected override bool isIdenticalTo( ResourceInfo infoAsBaseType )
 {
     var info = infoAsBaseType as StaticFileInfo;
     return info != null && info.appRelativeFilePath == appRelativeFilePath;
 }
 private string getTransferPath( ResourceInfo resource )
 {
     var url = resource.GetUrl( true, true, false );
     if( resource.ShouldBeSecureGivenCurrentRequest != RequestIsSecure( Request ) )
         throw new ApplicationException( url + " has a connection security setting that is incompatible with the current request." );
     return url;
 }
        private void navigate( ResourceInfo destination, FullResponse secondaryResponse )
        {
            var requestState = AppRequestState.Instance.EwfPageRequestState;

            string destinationUrl;
            try {
                // Determine the final redirect destination. If a destination is already specified and it is the current page or a page with the same entity setup,
                // replace any default optional parameter values it may have with new values from this post back. If a destination isn't specified, make it the current
                // page with new parameter values from this post back. At the end of this block, redirectInfo is always newly created with fresh data that reflects any
                // changes that may have occurred in EH methods. It's important that every case below *actually creates* a new page info object to guard against this
                // scenario:
                // 1. A page modifies data such that a previously created redirect destination page info object that is then used here is no longer valid because it
                //    would throw an exception from init if it were re-created.
                // 2. The page redirects, or transfers, to this destination, leading the user to an error page without developers being notified. This is bad behavior.
                if( requestState.ModificationErrorsExist ||
                    ( requestState.DmIdAndSecondaryOp != null && requestState.DmIdAndSecondaryOp.Item2 == SecondaryPostBackOperation.NoOperation ) )
                    destination = InfoAsBaseType.CloneAndReplaceDefaultsIfPossible( true );
                else if( destination != null )
                    destination = destination.CloneAndReplaceDefaultsIfPossible( false );
                else
                    destination = createInfoFromNewParameterValues();

                // This GetUrl call is important even for the transfer case below for the same reason that we *actually create* a new page info object in every case
                // above. We want to force developers to get an error email if a page modifies data to make itself unauthorized/disabled without specifying a different
                // page as the redirect destination. The resulting transfer would lead the user to an error page.
                destinationUrl = destination.GetUrl();
            }
            catch( Exception e ) {
                throw getPossibleDeveloperMistakeException( "The post-modification destination page became invalid.", innerException: e );
            }

            // Put the secondary response into session state right before navigation so that it doesn't get sent if there is an error before this point.
            if( secondaryResponse != null ) {
                // It's important that we put the response in session state first since it's used by the Info.init method of the pre-built-response page.
                StandardLibrarySessionState.Instance.ResponseToSend = secondaryResponse;
                StandardLibrarySessionState.Instance.SetClientSideNavigation(
                    EwfApp.MetaLogicFactory.CreatePreBuiltResponsePageInfo().GetUrl(),
                    !secondaryResponse.FileName.Any(),
                    null );
            }

            // If the redirect destination is identical to the current page, do a transfer instead of a redirect.
            if( destination.IsIdenticalToCurrent() ) {
                AppRequestState.Instance.ClearUserAndImpersonator();
                resetPage();
            }

            // If the redirect destination is the current page, but with different query parameters, save request state in session state until the next request.
            if( destination.GetType() == InfoAsBaseType.GetType() )
                StandardLibrarySessionState.Instance.EwfPageRequestState = requestState;

            NetTools.Redirect( destinationUrl );
        }
 /// <summary>
 /// Returns true if this resource info object is identical to the specified resource info object.
 /// </summary>
 protected abstract bool isIdenticalTo( ResourceInfo infoAsBaseType );
示例#6
0
 /// <summary>
 /// NOTE: This method will be deleted when RSIS Goal 925 is completed. But continue using it when necessary since there is no good alternative.
 /// </summary>
 public static ActionButtonSetup CreateWithUrl(string text, ResourceInfo resourceInfo, ActionControlIcon icon = null)
 {
     return(new ActionButtonSetup(text, new EwfLink(resourceInfo), icon: icon));
 }
 /// <summary>
 /// MVC and internal use only.
 /// </summary>
 public AccessDeniedException(bool causedByIntermediateUser, ResourceInfo logInPage)
 {
     this.causedByIntermediateUser = causedByIntermediateUser;
     this.logInPage = logInPage;
 }
 /// <summary>
 /// NOTE: This method will be deleted when RSIS Goal 925 is completed. But continue using it when necessary since there is no good alternative.
 /// </summary>
 public static ActionButtonSetup CreateWithUrl( string text, ResourceInfo resourceInfo )
 {
     return new ActionButtonSetup( text, new EwfLink( resourceInfo ) );
 }
        /// <summary>
        /// Returns credit-card-collection hidden fields and a JavaScript function call getter that opens a Stripe Checkout modal window. If the window's submit
        /// button is clicked, the credit card is charged or otherwise used. Do not execute the getter until after the page tree has been built.
        /// </summary>
        /// <param name="testPublishableKey">Your test publishable API key. Will be used in non-live installations. Do not pass null.</param>
        /// <param name="livePublishableKey">Your live publishable API key. Will be used in live installations. Do not pass null.</param>
        /// <param name="name">See https://stripe.com/docs/checkout. Do not pass null.</param>
        /// <param name="description">See https://stripe.com/docs/checkout. Do not pass null.</param>
        /// <param name="amountInDollars">See https://stripe.com/docs/checkout, but note that this parameter is in dollars, not cents</param>
        /// <param name="testSecretKey">Your test secret API key. Will be used in non-live installations. Do not pass null.</param>
        /// <param name="liveSecretKey">Your live secret API key. Will be used in live installations. Do not pass null.</param>
        /// <param name="successHandler">A method that executes if the credit-card submission is successful. The first parameter is the charge ID and the second
        /// parameter is the amount of the charge, in dollars.</param>
        /// <param name="prefilledEmailAddressOverride">By default, the email will be prefilled with AppTools.User.Email if AppTools.User is not null. You can
        /// override this with either a specified email address (if user is paying on behalf of someone else) or the empty string (to force the user to type in the
        /// email address).</param>
        public static Tuple <IReadOnlyCollection <EtherealComponentOrElement>, Func <string> > GetCreditCardCollectionHiddenFieldsAndJsFunctionCall(
            string testPublishableKey, string livePublishableKey, string name, string description, decimal?amountInDollars, string testSecretKey, string liveSecretKey,
            Func <string, decimal, StatusMessageAndDestination> successHandler, string prefilledEmailAddressOverride = null)
        {
            if (!EwfApp.Instance.RequestIsSecure(HttpContext.Current.Request))
            {
                throw new ApplicationException("Credit-card collection can only be done from secure pages.");
            }
            EwfPage.Instance.ClientScript.RegisterClientScriptInclude(typeof(PaymentProcessingStatics), "Stripe Checkout", "https://checkout.stripe.com/checkout.js");

            if (amountInDollars.HasValue && amountInDollars.Value.DollarValueHasFractionalCents())
            {
                throw new ApplicationException("Amount must not include fractional cents.");
            }

            ResourceInfo successDestination = null;
            var          postBack           = PostBack.CreateFull(
                id: PostBack.GetCompositeId("ewfCreditCardCollection", description),
                actionGetter: () => new PostBackAction(successDestination));
            var token = new DataValue <string>();

            var hiddenFieldId = new HiddenFieldId();
            List <EtherealComponentOrElement> hiddenFields = new List <EtherealComponentOrElement>();

            FormState.ExecuteWithDataModificationsAndDefaultAction(
                postBack.ToCollection(),
                () => hiddenFields.Add(new EwfHiddenField("", (postBackValue, validator) => token.Value = postBackValue.Value, id: hiddenFieldId).PageComponent));

            postBack.AddModificationMethod(
                () => {
                // We can add support later for customer creation, subscriptions, etc. as needs arise.
                if (!amountInDollars.HasValue)
                {
                    throw new ApplicationException("Only simple charges are supported at this time.");
                }

                StripeCharge response;
                try {
                    response =
                        new StripeGateway(ConfigurationStatics.IsLiveInstallation ? liveSecretKey : testSecretKey).Post(
                            new ChargeStripeCustomer
                    {
                        Amount      = (int)(amountInDollars.Value * 100),
                        Currency    = "usd",
                        Description = description.Any() ? description : null,
                        Card        = token.Value
                    });
                }
                catch (StripeException e) {
                    if (e.Type == "card_error")
                    {
                        throw new DataModificationException(e.Message);
                    }
                    throw new ApplicationException("A credit-card charge failed.", e);
                }

                try {
                    var messageAndDestination = successHandler(response.Id, amountInDollars.Value);
                    if (messageAndDestination.Message.Any())
                    {
                        EwfPage.AddStatusMessage(StatusMessageType.Info, messageAndDestination.Message);
                    }
                    successDestination = messageAndDestination.Destination;
                }
                catch (Exception e) {
                    throw new ApplicationException("An exception occurred after a credit card was charged.", e);
                }
            });

            FormAction action = new PostBackFormAction(postBack);

            action.AddToPageIfNecessary();
            return(Tuple.Create <IReadOnlyCollection <EtherealComponentOrElement>, Func <string> >(
                       hiddenFields,
                       () => {
                var jsTokenHandler = "function( token, args ) { " + hiddenFieldId.GetJsValueModificationStatements("token.id") + " " + action.GetJsStatements() + " }";
                return "StripeCheckout.open( { key: '" + (ConfigurationStatics.IsLiveInstallation ? livePublishableKey : testPublishableKey) + "', token: " +
                jsTokenHandler + ", name: '" + name + "', description: '" + description + "', " +
                (amountInDollars.HasValue ? "amount: " + amountInDollars.Value * 100 + ", " : "") + "email: '" +
                (prefilledEmailAddressOverride ?? (AppTools.User == null ? "" : AppTools.User.Email)) + "' } )";
            }));
        }
示例#10
0
 /// <summary>
 /// Creates a image style object.
 /// </summary>
 /// <param name="imageInfo">The image. Do not pass null.</param>
 /// <param name="alternativeText">The alternative text for the image; see https://html.spec.whatwg.org/multipage/embedded-content.html#alt. Pass null (which
 /// omits the alt attribute) or the empty string only when the specification allows.</param>
 /// <param name="sizesToAvailableWidth">Whether the image sizes itself to fit all available width.</param>
 /// <param name="rolloverImageInfo"></param>
 public ImageHyperlinkStyle(ResourceInfo imageInfo, string alternativeText, bool sizesToAvailableWidth = false, ResourceInfo rolloverImageInfo = null)
 {
     this.sizesToAvailableWidth = sizesToAvailableWidth;
     this.imageInfo             = imageInfo;
     this.alternativeText       = alternativeText;
     this.rolloverImageInfo     = rolloverImageInfo;
 }