Ejemplo n.º 1
0
        /// <summary>
        /// Gets store host location
        /// </summary>
        /// <param name="useSsl">Whether to get SSL secured URL</param>
        /// <returns>Store host location</returns>
        public virtual string GetStoreHost(bool useSsl)
        {
            var result = string.Empty;

            //try to get host from the request HOST header
            var hostHeader = _httpContextAccessor.HttpContext.Request.Headers[HeaderNames.Host];

            if (!StringValues.IsNullOrEmpty(hostHeader))
            {
                result = $"{_httpContextAccessor.HttpContext.Request.Scheme}://" + hostHeader.FirstOrDefault();
            }

            //whether database is installed
            if (DataSettingsHelper.DatabaseIsInstalled())
            {
                //get current store (do not inject IWorkContext via constructor because it'll cause circular references)
                var currentStore = EngineContext.Current.Resolve <IStoreContext>().CurrentStore;
                if (currentStore == null)
                {
                    throw new Exception("Current store cannot be loaded");
                }

                if (string.IsNullOrEmpty(result))
                {
                    //HOST header is not available, it is possible only when HttpContext is not available (for example, running in a schedule task)
                    //in this case use URL of a store entity configured in admin area
                    result = currentStore.Url;
                }
                if (!result.StartsWith("https"))
                {
                    if (useSsl)
                    {
                        //if secure URL specified let's use this URL, otherwise a store owner wants it to be detected automatically
                        result = !string.IsNullOrWhiteSpace(currentStore.SecureUrl) ? currentStore.SecureUrl : result.Replace("http://", "https://");
                    }
                    else
                    {
                        if (currentStore.SslEnabled && !string.IsNullOrWhiteSpace(currentStore.SecureUrl))
                        {
                            //SSL is enabled in this store and secure URL is specified, so a store owner don't want it to be detected automatically.
                            //in this case let's use the specified non-secure URL
                            result = currentStore.Url;
                        }
                    }
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(result) && useSsl)
                {
                    //use secure connection
                    result = result.Replace("http://", "https://");
                }
            }

            if (!result.EndsWith("/"))
            {
                result += "/";
            }

            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 处理远端认证结果(阿里钉钉认证服务器认证结果)
        /// </summary>
        /// <returns></returns>
        protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            #region 步骤1,验证会话是否一致
            // 用于存储有关身份验证会话的状态值对象
            AuthenticationProperties properties = null;
            var query = Request.Query;

            // 阿里钉钉授权后会在redirectUri添加参数:redirect_url?auth_code=xxx
            var code  = query["code"];  //用户授权给钉钉开放应用的免登授权码,第一步中获取的code
            var state = query["state"]; //状态码
            properties = Options.StateDataFormat.Unprotect(state);
            if (properties == null)
            {
                return(HandleRequestResult.Fail("The oauth state was missing or invalid."));
            }

            // OAuth2 10.12 CSRF
            if (!ValidateCorrelationId(properties))
            {
                return(HandleRequestResult.Fail("Correlation failed."));
            }

            if (StringValues.IsNullOrEmpty(code))
            {
                return(HandleRequestResult.Fail("Code was not found."));
            }
            #endregion

            #region 步骤2,通过appid,appsecret换取access_token地址。
            var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath));

            var tokens = await ExchangeCodeAsync(codeExchangeContext);

            if (tokens.Error != null)
            {
                return(HandleRequestResult.Fail(tokens.Error));
            }
            //tokens.AccessToken = tokens.Response["provider_access_token"]?.ToString();
            //tokens.ExpiresIn = tokens.Response["expires_in"]?.ToString();
            if (string.IsNullOrEmpty(tokens.AccessToken))
            {
                return(HandleRequestResult.Fail("Failed to retrieve access token."));
            }
            #endregion

            // 初始化一个Identity。有了auth_code和provider_access_token,下一步就是取用户基本信息。ClaimsIssuer:声明发行者
            var identity = new ClaimsIdentity(ClaimsIssuer);
            // 是否保存Token到用户身份验证会话中。
            if (Options.SaveTokens)
            {
                var authTokens = new List <AuthenticationToken>();
                authTokens.Add(new AuthenticationToken {
                    Name = "access_token", Value = tokens.AccessToken
                });
                if (!string.IsNullOrEmpty(tokens.RefreshToken))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "refresh_token", Value = tokens.RefreshToken
                    });
                }
                if (!string.IsNullOrEmpty(tokens.TokenType))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "token_type", Value = tokens.TokenType
                    });
                }
                if (!string.IsNullOrEmpty(tokens.ExpiresIn))
                {
                    int value;
                    if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                    {
                        // https://www.w3.org/TR/xmlschema-2/#dateTime
                        // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
                        var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
                        authTokens.Add(new AuthenticationToken
                        {
                            Name  = "expires_at",
                            Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
                        });
                    }
                }
                properties.StoreTokens(authTokens);
            }

            #region 步骤3,创建认证票据
            var ticket = await CreateTicketAsync(identity, properties, tokens);

            if (ticket != null)
            {
                //返回成功认证
                return(HandleRequestResult.Success(ticket));
            }
            else
            {
                //返回失败认证
                return(HandleRequestResult.Fail("Failed to retrieve user information from remote server."));
            }
            #endregion
        }
Ejemplo n.º 3
0
        protected virtual async Task ProcessRequestAsync()
        {
            var action = "DIRLIST";

            try
            {
                if (!await _permissionService.AuthorizeAsync(StandardPermissionProvider.HtmlEditorManagePictures))
                {
                    throw new Exception("You don't have required permission");
                }

                if (!StringValues.IsNullOrEmpty(HttpContext.Request.Query["a"]))
                {
                    action = HttpContext.Request.Query["a"];
                }

                switch (action.ToUpperInvariant())
                {
                case "DIRLIST":
                    await _roxyFilemanService.GetDirectoriesAsync(HttpContext.Request.Query["type"]);

                    break;

                case "FILESLIST":
                    await _roxyFilemanService.GetFilesAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["type"]);

                    break;

                case "COPYDIR":
                    await _roxyFilemanService.CopyDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]);

                    break;

                case "COPYFILE":
                    await _roxyFilemanService.CopyFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]);

                    break;

                case "CREATEDIR":
                    await _roxyFilemanService.CreateDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]);

                    break;

                case "DELETEDIR":
                    await _roxyFilemanService.DeleteDirectoryAsync(HttpContext.Request.Query["d"]);

                    break;

                case "DELETEFILE":
                    await _roxyFilemanService.DeleteFileAsync(HttpContext.Request.Query["f"]);

                    break;

                case "DOWNLOAD":
                    await _roxyFilemanService.DownloadFileAsync(HttpContext.Request.Query["f"]);

                    break;

                case "DOWNLOADDIR":
                    await _roxyFilemanService.DownloadDirectoryAsync(HttpContext.Request.Query["d"]);

                    break;

                case "MOVEDIR":
                    await _roxyFilemanService.MoveDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]);

                    break;

                case "MOVEFILE":
                    await _roxyFilemanService.MoveFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]);

                    break;

                case "RENAMEDIR":
                    await _roxyFilemanService.RenameDirectoryAsync(HttpContext.Request.Query["d"], HttpContext.Request.Query["n"]);

                    break;

                case "RENAMEFILE":
                    await _roxyFilemanService.RenameFileAsync(HttpContext.Request.Query["f"], HttpContext.Request.Query["n"]);

                    break;

                case "GENERATETHUMB":
                    await _roxyFilemanService.CreateImageThumbnailAsync(HttpContext.Request.Query["f"]);

                    break;

                case "UPLOAD":
                    await _roxyFilemanService.UploadFilesAsync(HttpContext.Request.Form["d"]);

                    break;

                default:
                    await HttpContext.Response.WriteAsync(_roxyFilemanService.GetErrorResponse("This action is not implemented."));

                    break;
                }
            }
            catch (Exception ex)
            {
                if (action == "UPLOAD" && !_roxyFilemanService.IsAjaxRequest())
                {
                    await HttpContext.Response.WriteAsync($"<script>parent.fileUploaded({_roxyFilemanService.GetErrorResponse(await _roxyFilemanService.GetLanguageResourceAsync("E_UploadNoFiles"))});</script>");
                }
                else
                {
                    await HttpContext.Response.WriteAsync(_roxyFilemanService.GetErrorResponse(ex.Message));
                }
            }
        }
Ejemplo n.º 4
0
        protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            var query = Request.Query;

            var state      = query["state"];
            var properties = Options.StateDataFormat.Unprotect(state);

            if (properties == null)
            {
                return(HandleRequestResult.Fail("The oauth state was missing or invalid."));
            }

            // OAuth2 10.12 CSRF
            if (!ValidateCorrelationId(properties))
            {
                return(HandleRequestResult.Fail("Correlation failed.", properties));
            }

            var error = query["error"];

            if (!StringValues.IsNullOrEmpty(error))
            {
                // Note: access_denied errors are special protocol errors indicating the user didn't
                // approve the authorization demand requested by the remote authorization server.
                // Since it's a frequent scenario (that is not caused by incorrect configuration),
                // denied errors are handled differently using HandleAccessDeniedErrorAsync().
                // Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
                var errorDescription = query["error_description"];
                var errorUri         = query["error_uri"];
                if (StringValues.Equals(error, "access_denied"))
                {
                    var result = await HandleAccessDeniedErrorAsync(properties);

                    if (!result.None)
                    {
                        return(result);
                    }
                    var deniedEx = new Exception("Access was denied by the resource owner or by the remote server.");
                    deniedEx.Data["error"]             = error.ToString();
                    deniedEx.Data["error_description"] = errorDescription.ToString();
                    deniedEx.Data["error_uri"]         = errorUri.ToString();

                    return(HandleRequestResult.Fail(deniedEx, properties));
                }

                var failureMessage = new StringBuilder();
                failureMessage.Append(error);
                if (!StringValues.IsNullOrEmpty(errorDescription))
                {
                    failureMessage.Append(";Description=").Append(errorDescription);
                }
                if (!StringValues.IsNullOrEmpty(errorUri))
                {
                    failureMessage.Append(";Uri=").Append(errorUri);
                }

                var ex = new Exception(failureMessage.ToString());
                ex.Data["error"]             = error.ToString();
                ex.Data["error_description"] = errorDescription.ToString();
                ex.Data["error_uri"]         = errorUri.ToString();

                return(HandleRequestResult.Fail(ex, properties));
            }

            var code = query["code"];

            if (StringValues.IsNullOrEmpty(code))
            {
                return(HandleRequestResult.Fail("Code was not found.", properties));
            }

            var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath));

            using var tokens = await ExchangeCodeAsync(codeExchangeContext);

            if (tokens.Error != null)
            {
                return(HandleRequestResult.Fail(tokens.Error, properties));
            }

            if (string.IsNullOrEmpty(tokens.AccessToken))
            {
                return(HandleRequestResult.Fail("Failed to retrieve access token.", properties));
            }

            var identity = new ClaimsIdentity(ClaimsIssuer);

            if (Options.SaveTokens)
            {
                var authTokens = new List <AuthenticationToken>();

                authTokens.Add(new AuthenticationToken {
                    Name = "access_token", Value = tokens.AccessToken
                });
                if (!string.IsNullOrEmpty(tokens.RefreshToken))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "refresh_token", Value = tokens.RefreshToken
                    });
                }

                if (!string.IsNullOrEmpty(tokens.TokenType))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "token_type", Value = tokens.TokenType
                    });
                }

                if (!string.IsNullOrEmpty(tokens.ExpiresIn))
                {
                    int value;
                    if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                    {
                        // https://www.w3.org/TR/xmlschema-2/#dateTime
                        // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
                        var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
                        authTokens.Add(new AuthenticationToken
                        {
                            Name  = "expires_at",
                            Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
                        });
                    }
                }

                properties.StoreTokens(authTokens);
            }

            var ticket = await CreateTicketAsync(identity, properties, tokens);

            if (ticket != null)
            {
                return(HandleRequestResult.Success(ticket));
            }
            else
            {
                return(HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties));
            }
        }
        public virtual bool IsResponseCacheable(ResponseCachingContext context)
        {
            var responseCacheControlHeader = context.HttpContext.Response.Headers[HeaderNames.CacheControl];

            // Only cache pages explicitly marked with public
            if (!HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PublicString))
            {
                context.Logger.LogResponseWithoutPublicNotCacheable();
                return(false);
            }

            // Check response no-store
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoStoreString))
            {
                context.Logger.LogResponseWithNoStoreNotCacheable();
                return(false);
            }

            // Check no-cache
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoCacheString))
            {
                context.Logger.LogResponseWithNoCacheNotCacheable();
                return(false);
            }

            var response = context.HttpContext.Response;

            // Do not cache responses with Set-Cookie headers
            if (!StringValues.IsNullOrEmpty(response.Headers[HeaderNames.SetCookie]))
            {
                context.Logger.LogResponseWithSetCookieNotCacheable();
                return(false);
            }

            // Do not cache responses varying by *
            var varyHeader = response.Headers[HeaderNames.Vary];

            if (varyHeader.Count == 1 && string.Equals(varyHeader, "*", StringComparison.OrdinalIgnoreCase))
            {
                context.Logger.LogResponseWithVaryStarNotCacheable();
                return(false);
            }

            // Check private
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PrivateString))
            {
                context.Logger.LogResponseWithPrivateNotCacheable();
                return(false);
            }

            // Check response code
            if (response.StatusCode != StatusCodes.Status200OK)
            {
                context.Logger.LogResponseWithUnsuccessfulStatusCodeNotCacheable(response.StatusCode);
                return(false);
            }

            // Check response freshness
            if (!context.ResponseDate.HasValue)
            {
                if (!context.ResponseSharedMaxAge.HasValue &&
                    !context.ResponseMaxAge.HasValue &&
                    context.ResponseTime.Value >= context.ResponseExpires)
                {
                    context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
                    return(false);
                }
            }
            else
            {
                var age = context.ResponseTime.Value - context.ResponseDate.Value;

                // Validate shared max age
                if (age >= context.ResponseSharedMaxAge)
                {
                    context.Logger.LogExpirationSharedMaxAgeExceeded(age, context.ResponseSharedMaxAge.Value);
                    return(false);
                }
                else if (!context.ResponseSharedMaxAge.HasValue)
                {
                    // Validate max age
                    if (age >= context.ResponseMaxAge)
                    {
                        context.Logger.LogExpirationMaxAgeExceeded(age, context.ResponseMaxAge.Value);
                        return(false);
                    }
                    else if (!context.ResponseMaxAge.HasValue)
                    {
                        // Validate expiration
                        if (context.ResponseTime.Value >= context.ResponseExpires)
                        {
                            context.Logger.LogExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 批量修改,默认对Ids中包含的数据进行修改,子类如果有特殊判断应重载本函数
        /// </summary>
        /// <returns>true代表成功,false代表失败</returns>
        public virtual bool DoBatchEdit()
        {
            //获取批量修改VM的所有属性
            var         pros    = LinkedVM.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
            bool        rv      = true;
            List <Guid> idsData = new List <Guid>(Ids);
            //找到对应的BaseCRUDVM,并初始化
            var vmtype = this.GetType().Assembly.GetExportedTypes().Where(x => x.IsSubclassOf(typeof(BaseCRUDVM <TModel>))).FirstOrDefault();
            IBaseCRUDVM <TModel> vm = null;

            if (vmtype != null)
            {
                vm = vmtype.GetConstructor(System.Type.EmptyTypes).Invoke(null) as IBaseCRUDVM <TModel>;
                vm.CopyContext(this);
            }
            //循环所有数据
            for (int i = 0; i < idsData.Count; i++)
            {
                try
                {
                    //如果找不到对应数据,则输出错误
                    TModel entity = null;
                    entity = DC.Set <TModel>().Find(idsData[i]);
                    if (vm != null)
                    {
                        vm.SetEntity(entity);
                    }
                    if (entity == null)
                    {
                        ErrorMessage.Add(idsData[i], "数据不存在");
                        rv = false;
                        break;
                    }
                    //如果能找到,则循环LinkedVM中的属性,给entity中同名属性赋值
                    foreach (var pro in pros)
                    {
                        var proToSet = entity.GetType().GetProperty(pro.Name);
                        var val      = FC.ContainsKey("LinkedVM." + pro.Name) ? FC["LinkedVM." + pro.Name] : null;
                        if (proToSet != null && val != null)
                        {
                            var hasvalue = false;
                            if (val is StringValues sv && StringValues.IsNullOrEmpty(sv) == false)
                            {
                                hasvalue = true;
                            }
                            if (hasvalue)
                            {
                                proToSet.SetValue(entity, pro.GetValue(LinkedVM));
                            }
                        }
                    }
                    //如果有对应的BaseCRUDVM则使用其进行数据验证
                    if (vm != null)
                    {
                        vm.Validate();
                        var errors = vm.MSD;
                        if (errors != null && errors.Count > 0)
                        {
                            var error = "";
                            foreach (var key in errors.Keys)
                            {
                                if (errors[key].Count > 0)
                                {
                                    error += errors[key].Select(x => x.ErrorMessage).ToSpratedString();
                                }
                            }
                            if (error != "")
                            {
                                ErrorMessage.Add(idsData[i], error);
                                rv = false;
                                break;
                            }
                        }
                    }
                    if (typeof(TModel).IsSubclassOf(typeof(BasePoco)))
                    {
                        BasePoco ent = entity as BasePoco;
                        if (ent.CreateTime == null)
                        {
                            ent.CreateTime = DateTime.Now;
                        }
                        if (string.IsNullOrEmpty(ent.CreateBy))
                        {
                            ent.CreateBy = LoginUserInfo?.ITCode;
                        }
                    }
                    DC.UpdateEntity(entity);
                }
                catch (Exception e)
                {
                    SetExceptionMessage(e, idsData[i]);
                    rv = false;
                }
            }
            //进行数据库的修改操作
            if (rv == true)
            {
                try
                {
                    DC.SaveChanges();
                }
                catch (Exception e)
                {
                    SetExceptionMessage(e, null);
                    rv = false;
                }
            }

            //如果有错误,输出错误信息
            if (rv == false)
            {
                if (ErrorMessage.Count > 0)
                {
                    foreach (var id in idsData)
                    {
                        if (!ErrorMessage.ContainsKey(id))
                        {
                            ErrorMessage.Add(id, "已回滚");
                        }
                    }
                }
                ListVM.DoSearch();
                foreach (var item in ListVM.GetEntityList())
                {
                    item.BatchError = ErrorMessage.Where(x => x.Key == item.ID).Select(x => x.Value).FirstOrDefault();
                }
            }
            return(rv);
        }
            /// <summary>
            /// Validate CAPTCHA
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>True if CAPTCHA is valid; otherwise false</returns>
            protected bool ValidateCaptcha(ActionExecutingContext context)
            {
                var isValid = false;

                //get form values
                var captchaChallengeValue = context.HttpContext.Request.Form[CHALLENGE_FIELD_KEY];
                var captchaResponseValue  = context.HttpContext.Request.Form[RESPONSE_FIELD_KEY];
                var gCaptchaResponseValue = context.HttpContext.Request.Form[G_RESPONSE_FIELD_KEY];

                if ((!StringValues.IsNullOrEmpty(captchaChallengeValue) && !StringValues.IsNullOrEmpty(captchaResponseValue)) || !StringValues.IsNullOrEmpty(gCaptchaResponseValue))
                {
                    //create CAPTCHA validator
                    var captchaValidtor = new GReCaptchaValidator(_captchaSettings.ReCaptchaVersion)
                    {
                        SecretKey = _captchaSettings.ReCaptchaPrivateKey,
                        RemoteIp  = context.HttpContext.Connection.RemoteIpAddress?.ToString(),
                        Response  = !StringValues.IsNullOrEmpty(captchaResponseValue) ? captchaResponseValue : gCaptchaResponseValue,
                        Challenge = captchaChallengeValue
                    };

                    //validate request
                    var recaptchaResponse = captchaValidtor.Validate();
                    isValid = recaptchaResponse.IsValid;
                }

                return(isValid);
            }
Ejemplo n.º 8
0
        public static StringValues GetQueryParam(this string url, string key)
        {
            if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
            {
                var queryParams = QueryHelpers.ParseNullableQuery(uri?.Query);
                if (queryParams != null && queryParams.TryGetValue(key, out var values) && !StringValues.IsNullOrEmpty(values))
                {
                    return(values);
                }
            }

            return(string.Empty);
        }
Ejemplo n.º 9
0
        public static (bool isRangeRequest, RangeItemHeaderValue?range) ParseRange(
            HttpContext context,
            RequestHeaders requestHeaders,
            long length,
            ILogger logger)
        {
            var rawRangeHeader = context.Request.Headers.Range;

            if (StringValues.IsNullOrEmpty(rawRangeHeader))
            {
                logger.LogTrace("Range header's value is empty.");
                return(false, null);
            }

            // Perf: Check for a single entry before parsing it
            if (rawRangeHeader.Count > 1 || rawRangeHeader[0].IndexOf(',') >= 0)
            {
                logger.LogDebug("Multiple ranges are not supported.");

                // The spec allows for multiple ranges but we choose not to support them because the client may request
                // very strange ranges (e.g. each byte separately, overlapping ranges, etc.) that could negatively
                // impact the server. Ignore the header and serve the response normally.
                return(false, null);
            }

            var rangeHeader = requestHeaders.Range;

            if (rangeHeader == null)
            {
                logger.LogDebug("Range header's value is invalid.");
                // Invalid
                return(false, null);
            }

            // Already verified above
            Debug.Assert(rangeHeader.Ranges.Count == 1);

            var ranges = rangeHeader.Ranges;

            if (ranges == null)
            {
                logger.LogDebug("Range header's value is invalid.");
                return(false, null);
            }

            if (ranges.Count == 0)
            {
                return(true, null);
            }

            if (length == 0)
            {
                return(true, null);
            }

            // Normalize the ranges
            var range = NormalizeRange(ranges.Single(), length);

            // Return the single range
            return(true, range);
        }
 private string QueryString(string name)
 {
     if (StringValues.IsNullOrEmpty(HttpContext.Request.Query[name]))
     {
         return(default);
Ejemplo n.º 11
0
        public static StringValues GetRelativeUrlQueryParam(this string url, string key)
        {
            if (!string.IsNullOrWhiteSpace(url))
            {
                var queryIndex = url.IndexOf('?');
                var queryUrl   = queryIndex > -1 ? url.Substring(queryIndex) : string.Empty;

                if (!string.IsNullOrWhiteSpace(queryUrl))
                {
                    var queryParams = QueryHelpers.ParseNullableQuery(queryUrl);
                    if (queryParams != null && queryParams.TryGetValue(key, out var values) && !StringValues.IsNullOrEmpty(values))
                    {
                        return(values);
                    }
                }
            }

            return(string.Empty);
        }
        private Activity?StartActivity(HttpContext httpContext, bool loggingEnabled, bool diagnosticListenerActivityCreationEnabled, out bool hasDiagnosticListener)
        {
            var activity = _activitySource.CreateActivity(ActivityName, ActivityKind.Server);

            if (activity is null && (loggingEnabled || diagnosticListenerActivityCreationEnabled))
            {
                activity = new Activity(ActivityName);
            }
            hasDiagnosticListener = false;

            if (activity is null)
            {
                return(null);
            }

            var headers   = httpContext.Request.Headers;
            var requestId = headers.TraceParent;

            if (requestId.Count == 0)
            {
                requestId = headers.RequestId;
            }

            if (!StringValues.IsNullOrEmpty(requestId))
            {
                activity.SetParentId(requestId);
                var traceState = headers.TraceState;
                if (traceState.Count > 0)
                {
                    activity.TraceStateString = traceState;
                }

                // We expect baggage to be empty by default
                // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
                var baggage = headers.GetCommaSeparatedValues(HeaderNames.Baggage);
                if (baggage.Length == 0)
                {
                    baggage = headers.GetCommaSeparatedValues(HeaderNames.CorrelationContext);
                }

                // AddBaggage adds items at the beginning  of the list, so we need to add them in reverse to keep the same order as the client
                // An order could be important if baggage has two items with the same key (that is allowed by the contract)
                for (var i = baggage.Length - 1; i >= 0; i--)
                {
                    if (NameValueHeaderValue.TryParse(baggage[i], out var baggageItem))
                    {
                        activity.AddBaggage(baggageItem.Name.ToString(), HttpUtility.UrlDecode(baggageItem.Value.ToString()));
                    }
                }
            }

            _diagnosticListener.OnActivityImport(activity, httpContext);

            if (_diagnosticListener.IsEnabled(ActivityStartKey))
            {
                hasDiagnosticListener = true;
                StartActivity(activity, httpContext);
            }
            else
            {
                activity.Start();
            }

            return(activity);
        }
Ejemplo n.º 13
0
        // BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue
        public string CreateStorageVaryByKey(ResponseCachingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var varyByRules = context.CachedVaryByRules;

            if (varyByRules == null)
            {
                throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCachingContext)}");
            }

            if ((StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.QueryKeys)))
            {
                return(varyByRules.VaryByKeyPrefix);
            }

            var request = context.HttpContext.Request;
            var builder = _builderPool.Get();

            try
            {
                // Prepend with the Guid of the CachedVaryByRules
                builder.Append(varyByRules.VaryByKeyPrefix);

                // Vary by headers
                if (varyByRules?.Headers.Count > 0)
                {
                    // Append a group separator for the header segment of the cache key
                    builder.Append(KeyDelimiter)
                    .Append('H');

                    for (var i = 0; i < varyByRules.Headers.Count; i++)
                    {
                        var header       = varyByRules.Headers[i];
                        var headerValues = context.HttpContext.Request.Headers[header];
                        builder.Append(KeyDelimiter)
                        .Append(header)
                        .Append("=");

                        for (var j = 0; j < headerValues.Count; j++)
                        {
                            builder.Append(headerValues[j]);
                        }
                    }
                }

                // Vary by query keys
                if (varyByRules?.QueryKeys.Count > 0)
                {
                    // Append a group separator for the query key segment of the cache key
                    builder.Append(KeyDelimiter)
                    .Append('Q');

                    if (varyByRules.QueryKeys.Count == 1 && string.Equals(varyByRules.QueryKeys[0], "*", StringComparison.Ordinal))
                    {
                        // Vary by all available query keys
                        foreach (var query in context.HttpContext.Request.Query.OrderBy(q => q.Key, StringComparer.OrdinalIgnoreCase))
                        {
                            builder.Append(KeyDelimiter)
                            .AppendUpperInvariant(query.Key)
                            .Append("=");

                            for (var i = 0; i < query.Value.Count; i++)
                            {
                                builder.Append(query.Value[i]);
                            }
                        }
                    }
                    else
                    {
                        for (var i = 0; i < varyByRules.QueryKeys.Count; i++)
                        {
                            var queryKey       = varyByRules.QueryKeys[i];
                            var queryKeyValues = context.HttpContext.Request.Query[queryKey];
                            builder.Append(KeyDelimiter)
                            .Append(queryKey)
                            .Append("=");

                            for (var j = 0; j < queryKeyValues.Count; j++)
                            {
                                builder.Append(queryKeyValues[j]);
                            }
                        }
                    }
                }

                return(builder.ToString());
            }
            finally
            {
                _builderPool.Return(builder);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Get IP address from HTTP context
        /// </summary>
        /// <returns>String of IP address</returns>
        public virtual string GetCurrentIpAddress()
        {
            if (!IsRequestAvailable())
            {
                return(string.Empty);
            }

            var result = string.Empty;

            try
            {
                //first try to get IP address from the forwarded header
                if (_httpContextAccessor.HttpContext.Request.Headers != null)
                {
                    //the X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client
                    //connecting to a web server through an HTTP proxy or load balancer
                    var forwardedHttpHeaderKey = NopHttpDefaults.XForwardedForHeader;
                    if (!string.IsNullOrEmpty(_hostingConfig.ForwardedHttpHeader))
                    {
                        //but in some cases server use other HTTP header
                        //in these cases an administrator can specify a custom Forwarded HTTP header (e.g. CF-Connecting-IP, X-FORWARDED-PROTO, etc)
                        forwardedHttpHeaderKey = _hostingConfig.ForwardedHttpHeader;
                    }

                    var forwardedHeader = _httpContextAccessor.HttpContext.Request.Headers[forwardedHttpHeaderKey];
                    if (!StringValues.IsNullOrEmpty(forwardedHeader))
                    {
                        result = forwardedHeader.FirstOrDefault();
                    }
                }

                //if this header not exists try get connection remote IP address
                if (string.IsNullOrEmpty(result) && _httpContextAccessor.HttpContext.Connection.RemoteIpAddress != null)
                {
                    result = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
                }
            }
            catch
            {
                return(string.Empty);
            }

            //some of the validation
            if (result != null && result.Equals(IPAddress.IPv6Loopback.ToString(), StringComparison.InvariantCultureIgnoreCase))
            {
                result = IPAddress.Loopback.ToString();
            }

            //"TryParse" doesn't support IPv4 with port number
            if (IPAddress.TryParse(result ?? string.Empty, out var ip))
            {
                //IP address is valid
                result = ip.ToString();
            }
            else if (!string.IsNullOrEmpty(result))
            {
                //remove port
                result = result.Split(':').FirstOrDefault();
            }

            return(result);
        }
Ejemplo n.º 15
0
        protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            var query = Request.Query;

            var state      = query["state"];
            var properties = Options.StateDataFormat.Unprotect(state);

            if (properties == null)
            {
                return(HandleRequestResult.Fail("The oauth state was missing or invalid."));
            }

            // OAuth2 10.12 CSRF
            if (!ValidateCorrelationId(properties))
            {
                return(HandleRequestResult.Fail("Correlation failed.", properties));
            }

            var error = query["error"];

            if (!StringValues.IsNullOrEmpty(error))
            {
                var failureMessage = new StringBuilder();
                failureMessage.Append(error);
                var errorDescription = query["error_description"];
                if (!StringValues.IsNullOrEmpty(errorDescription))
                {
                    failureMessage.Append(";Description=").Append(errorDescription);
                }
                var errorUri = query["error_uri"];
                if (!StringValues.IsNullOrEmpty(errorUri))
                {
                    failureMessage.Append(";Uri=").Append(errorUri);
                }

                return(HandleRequestResult.Fail(failureMessage.ToString(), properties));
            }

            var code = query["code"];

            if (StringValues.IsNullOrEmpty(code))
            {
                return(HandleRequestResult.Fail("Code was not found.", properties));
            }

            var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));

            if (tokens.Error != null)
            {
                return(HandleRequestResult.Fail(tokens.Error, properties));
            }

            if (string.IsNullOrEmpty(tokens.AccessToken))
            {
                return(HandleRequestResult.Fail("Failed to retrieve access token.", properties));
            }

            var identity = new ClaimsIdentity(ClaimsIssuer);

            if (Options.SaveTokens)
            {
                var authTokens = new List <AuthenticationToken>();

                authTokens.Add(new AuthenticationToken {
                    Name = "access_token", Value = tokens.AccessToken
                });
                if (!string.IsNullOrEmpty(tokens.RefreshToken))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "refresh_token", Value = tokens.RefreshToken
                    });
                }

                if (!string.IsNullOrEmpty(tokens.TokenType))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "token_type", Value = tokens.TokenType
                    });
                }

                if (!string.IsNullOrEmpty(tokens.ExpiresIn))
                {
                    int value;
                    if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                    {
                        // https://www.w3.org/TR/xmlschema-2/#dateTime
                        // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
                        var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
                        authTokens.Add(new AuthenticationToken
                        {
                            Name  = "expires_at",
                            Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
                        });
                    }
                }

                properties.StoreTokens(authTokens);
            }

            var ticket = await CreateTicketAsync(identity, properties, tokens);

            if (ticket != null)
            {
                return(HandleRequestResult.Success(ticket));
            }
            else
            {
                return(HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties));
            }
        }
Ejemplo n.º 16
0
        private string FormatHeaders(IHeaderDictionary headersIn)
        {
            var headers = headersIn.AsEnumerable().Select(h => KeyValuePair.Create(h.Key, !StringValues.IsNullOrEmpty(h.Value) ? h.Value.ToList() : Enumerable.Empty <string>()));

            return(FormatEnumerableHeaders(headers));
        }
Ejemplo n.º 17
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseFileServer();

            // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec)
            // This is for testing purposes only (karma hosts the client on its own server), never do this in production
            app.Use((context, next) =>
            {
                var originHeader = context.Request.Headers[HeaderNames.Origin];
                if (!StringValues.IsNullOrEmpty(originHeader))
                {
                    context.Response.Headers[HeaderNames.AccessControlAllowOrigin]      = originHeader;
                    context.Response.Headers[HeaderNames.AccessControlAllowCredentials] = "true";

                    var requestMethod = context.Request.Headers[HeaderNames.AccessControlRequestMethod];
                    if (!StringValues.IsNullOrEmpty(requestMethod))
                    {
                        context.Response.Headers[HeaderNames.AccessControlAllowMethods] = requestMethod;
                    }

                    var requestHeaders = context.Request.Headers[HeaderNames.AccessControlRequestHeaders];
                    if (!StringValues.IsNullOrEmpty(requestHeaders))
                    {
                        context.Response.Headers[HeaderNames.AccessControlAllowHeaders] = requestHeaders;
                    }
                }

                if (string.Equals(context.Request.Method, "OPTIONS", StringComparison.OrdinalIgnoreCase))
                {
                    context.Response.StatusCode = StatusCodes.Status204NoContent;
                    return(Task.CompletedTask);
                }

                return(next.Invoke());
            });

            app.Use((context, next) =>
            {
                if (context.Request.Path.StartsWithSegments("/redirect"))
                {
                    var newUrl = context.Request.Query["baseUrl"] + "/testHub?numRedirects=" + Interlocked.Increment(ref _numRedirects);
                    return(context.Response.WriteAsync($"{{ \"url\": \"{newUrl}\" }}"));
                }

                return(next());
            });

            app.Use(async(context, next) =>
            {
                if (context.Request.Path.Value.Contains("/negotiate"))
                {
                    context.Response.Cookies.Append("testCookie", "testValue");
                    context.Response.Cookies.Append("testCookie2", "testValue2");
                    context.Response.Cookies.Append("expiredCookie", "doesntmatter", new CookieOptions()
                    {
                        Expires = DateTimeOffset.Now.AddHours(-1)
                    });
                }

                await next.Invoke();
            });

            app.UseRouting();

            // Custom CORS to allow any origin + credentials (which isn't allowed by the CORS spec)
            // This is for testing purposes only (karma hosts the client on its own server), never do this in production
            app.UseCors(policy =>
            {
                policy.SetIsOriginAllowed(host => host.StartsWith("http://localhost:") || host.StartsWith("http://127.0.0.1:"))
                .AllowAnyHeader()
                .AllowAnyMethod()
                .AllowCredentials();
            });

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub <TestHub>("/testhub");
                endpoints.MapHub <TestHub>("/testhub-nowebsockets", options => options.Transports = HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling);
                endpoints.MapHub <UncreatableHub>("/uncreatable");
                endpoints.MapHub <HubWithAuthorization>("/authorizedhub");

                endpoints.MapConnectionHandler <EchoConnectionHandler>("/echo");

                endpoints.MapGet("/generateJwtToken", context =>
                {
                    return(context.Response.WriteAsync(GenerateJwtToken()));
                });

                endpoints.MapGet("/deployment", context =>
                {
                    var attributes = Assembly.GetAssembly(typeof(Startup)).GetCustomAttributes <AssemblyMetadataAttribute>();

                    context.Response.ContentType = "application/json";
                    using (var textWriter = new StreamWriter(context.Response.Body))
                        using (var writer = new JsonTextWriter(textWriter))
                        {
                            var json       = new JObject();
                            var commitHash = string.Empty;

                            foreach (var attribute in attributes)
                            {
                                json.Add(attribute.Key, attribute.Value);

                                if (string.Equals(attribute.Key, "CommitHash"))
                                {
                                    commitHash = attribute.Value;
                                }
                            }

                            if (!string.IsNullOrEmpty(commitHash))
                            {
                                json.Add("GitHubUrl", $"https://github.com/aspnet/SignalR/commit/{commitHash}");
                            }

                            json.WriteTo(writer);
                        }

                    return(Task.CompletedTask);
                });
            });
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Whether the request is made with ajax
 /// </summary>
 /// <returns>True or false</returns>
 protected virtual bool IsAjaxRequest()
 {
     return(HttpContext.Request.Form != null &&
            !StringValues.IsNullOrEmpty(HttpContext.Request.Form["method"]) &&
            HttpContext.Request.Form["method"] == "ajax");
 }
Ejemplo n.º 19
0
 public override int GetHashCode()
 {
     return(!StringValues.IsNullOrEmpty(_headers) ? _headers.GetHashCode() : 0);
 }
Ejemplo n.º 20
0
            /// <summary>
            /// Called before the action executes, after model binding is complete
            /// </summary>
            /// <param name="context">A context for action filters</param>
            public void OnActionExecuting(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                //check request query parameters
                if (!context.HttpContext.Request?.Query?.Any() ?? true)
                {
                    return;
                }

                //only in GET requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                if (!DataSettingsManager.DatabaseIsInstalled)
                {
                    return;
                }

                var currentCustomer = _workContext.CurrentCustomer;

                //ignore search engines
                if (currentCustomer.IsSearchEngineAccount())
                {
                    return;
                }

                //try to get discount coupon code
                var queryKey = NopDiscountDefaults.DiscountCouponQueryParameter;

                if (!context.HttpContext.Request.Query.TryGetValue(queryKey, out var couponCodes) || StringValues.IsNullOrEmpty(couponCodes))
                {
                    return;
                }

                //get validated discounts with passed coupon codes
                var discounts = couponCodes
                                .SelectMany(couponCode => _discountService.GetAllDiscounts(couponCode: couponCode))
                                .Distinct()
                                .ToList();

                var validCouponCodes = new List <string>();

                foreach (var discount in discounts)
                {
                    if (!_discountService.ValidateDiscount(discount, currentCustomer, couponCodes.ToArray()).IsValid)
                    {
                        continue;
                    }

                    //apply discount coupon codes to customer
                    _customerService.ApplyDiscountCouponCode(currentCustomer, discount.CouponCode);
                    validCouponCodes.Add(discount.CouponCode);
                }

                //show notifications for activated coupon codes
                foreach (var validCouponCode in validCouponCodes.Distinct())
                {
                    _notificationService.SuccessNotification(
                        string.Format(_localizationService.GetResource("ShoppingCart.DiscountCouponCode.Activated"),
                                      validCouponCode));
                }

                //show notifications for invalid coupon codes
                foreach (var invalidCouponCode in couponCodes.Except(
                             validCouponCodes.Distinct()))
                {
                    _notificationService.WarningNotification(
                        string.Format(_localizationService.GetResource("ShoppingCart.DiscountCouponCode.Invalid"),
                                      invalidCouponCode));
                }
            }
Ejemplo n.º 21
0
        public void DeleteCookie(HttpContext context, string key, CookieOptions options)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var keys = new List <string>();

            keys.Add(key + "=");

            var requestCookie = context.Request.Cookies[key];
            var chunks        = ParseChunksCount(requestCookie);

            if (chunks > 0)
            {
                for (int i = 1; i <= chunks + 1; i++)
                {
                    var subkey = key + ChunkKeySuffix + i.ToString(CultureInfo.InvariantCulture);
                    keys.Add(subkey + "=");
                }
            }

            var domainHasValue = !string.IsNullOrEmpty(options.Domain);
            var pathHasValue   = !string.IsNullOrEmpty(options.Path);

            Func <string, bool> rejectPredicate;
            Func <string, bool> predicate = value => keys.Any(k => value.StartsWith(k, StringComparison.OrdinalIgnoreCase));

            if (domainHasValue)
            {
                rejectPredicate = value => predicate(value) && value.IndexOf("domain=" + options.Domain, StringComparison.OrdinalIgnoreCase) != -1;
            }
            else if (pathHasValue)
            {
                rejectPredicate = value => predicate(value) && value.IndexOf("path=" + options.Path, StringComparison.OrdinalIgnoreCase) != -1;
            }
            else
            {
                rejectPredicate = value => predicate(value);
            }

            var responseHeaders = context.Response.Headers;
            var existingValues  = responseHeaders[HeaderNames.SetCookie];

            if (!StringValues.IsNullOrEmpty(existingValues))
            {
                responseHeaders[HeaderNames.SetCookie] = existingValues.Where(value => !rejectPredicate(value)).ToArray();
            }

            AppendResponseCookie(
                context,
                key,
                string.Empty,
                new CookieOptions()
            {
                Path        = options.Path,
                Domain      = options.Domain,
                SameSite    = options.SameSite,
                Secure      = options.Secure,
                IsEssential = options.IsEssential,
                Expires     = DateTimeOffset.UnixEpoch,
                HttpOnly    = options.HttpOnly,
            });

            for (int i = 1; i <= chunks; i++)
            {
                AppendResponseCookie(
                    context,
                    key + "C" + i.ToString(CultureInfo.InvariantCulture),
                    string.Empty,
                    new CookieOptions()
                {
                    Path        = options.Path,
                    Domain      = options.Domain,
                    SameSite    = options.SameSite,
                    Secure      = options.Secure,
                    IsEssential = options.IsEssential,
                    Expires     = DateTimeOffset.UnixEpoch,
                    HttpOnly    = options.HttpOnly,
                });
            }
        }
Ejemplo n.º 22
0
        protected virtual string ParseVendorAttributes(IFormCollection form)
        {
            if (form == null)
            {
                throw new ArgumentNullException(nameof(form));
            }

            var attributesXml    = string.Empty;
            var vendorAttributes = _vendorAttributeService.GetAllVendorAttributes();

            foreach (var attribute in vendorAttributes)
            {
                var          controlId = $"vendor_attribute_{attribute.Id}";
                StringValues ctrlAttributes;
                switch (attribute.AttributeControlType)
                {
                case AttributeControlType.DropdownList:
                case AttributeControlType.RadioList:
                    ctrlAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(ctrlAttributes))
                    {
                        var selectedAttributeId = int.Parse(ctrlAttributes);
                        if (selectedAttributeId > 0)
                        {
                            attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml,
                                                                                      attribute, selectedAttributeId.ToString());
                        }
                    }

                    break;

                case AttributeControlType.Checkboxes:
                    var cblAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(cblAttributes))
                    {
                        foreach (var item in cblAttributes.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var selectedAttributeId = int.Parse(item);
                            if (selectedAttributeId > 0)
                            {
                                attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml,
                                                                                          attribute, selectedAttributeId.ToString());
                            }
                        }
                    }

                    break;

                case AttributeControlType.ReadonlyCheckboxes:
                    //load read-only (already server-side selected) values
                    var attributeValues = _vendorAttributeService.GetVendorAttributeValues(attribute.Id);
                    foreach (var selectedAttributeId in attributeValues
                             .Where(v => v.IsPreSelected)
                             .Select(v => v.Id)
                             .ToList())
                    {
                        attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml,
                                                                                  attribute, selectedAttributeId.ToString());
                    }

                    break;

                case AttributeControlType.TextBox:
                case AttributeControlType.MultilineTextbox:
                    ctrlAttributes = form[controlId];
                    if (!StringValues.IsNullOrEmpty(ctrlAttributes))
                    {
                        var enteredText = ctrlAttributes.ToString().Trim();
                        attributesXml = _vendorAttributeParser.AddVendorAttribute(attributesXml,
                                                                                  attribute, enteredText);
                    }

                    break;

                case AttributeControlType.Datepicker:
                case AttributeControlType.ColorSquares:
                case AttributeControlType.ImageSquares:
                case AttributeControlType.FileUpload:
                //not supported vendor attributes
                default:
                    break;
                }
            }

            return(attributesXml);
        }
Ejemplo n.º 23
0
        /// <inheritdoc />
        public virtual async Task OnResourceExecutionAsync(
            ResourceExecutingContext context,
            ResourceExecutionDelegate next)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            var routeData = context.RouteData;

            if (!routeData.TryGetWebHookReceiverName(out var receiverName))
            {
                await next();

                return;
            }

            var eventFromBodyMetadata = _eventFromBodyMetadata
                                        .FirstOrDefault(metadata => metadata.IsApplicable(receiverName));

            if (eventFromBodyMetadata == null)
            {
                await next();

                return;
            }

            // Determine the applicable WebhookBodyType i.e. how to read the request body.
            // WebHookReceiverExistsConstraint confirms the IWebHookBodyTypeMetadataService implementation exists.
            var bodyTypeMetadata = _bodyTypeMetadata.First(metadata => metadata.IsApplicable(receiverName));

            // No need to double-check the request's Content-Type. WebHookVerifyBodyTypeFilter would have
            // short-circuited the request if unsupported.
            StringValues eventNames;

            switch (bodyTypeMetadata.BodyType)
            {
            case WebHookBodyType.Form:
                var form = await _requestReader.ReadAsFormDataAsync(context);

                if (form == null)
                {
                    // ReadAsFormDataAsync returns null only when other filters will log and return errors
                    // about the same conditions. Let those filters run.
                    await next();

                    return;
                }

                eventNames = form[eventFromBodyMetadata.BodyPropertyPath];
                break;

            case WebHookBodyType.Json:
                var json = await _requestReader.ReadBodyAsync <JContainer>(context);

                if (json == null)
                {
                    var modelState = context.ModelState;
                    if (modelState.IsValid)
                    {
                        // ReadAsJContainerAsync returns null when model state is valid only when other filters
                        // will log and return errors about the same conditions. Let those filters run.
                        await next();
                    }
                    else
                    {
                        context.Result = new BadRequestObjectResult(modelState);
                    }

                    return;
                }

                eventNames = ObjectPathUtilities.GetStringValues(json, eventFromBodyMetadata.BodyPropertyPath);
                break;

            case WebHookBodyType.Xml:
                var xml = await _requestReader.ReadBodyAsync <XElement>(context);

                if (xml == null)
                {
                    var modelState = context.ModelState;
                    if (modelState.IsValid)
                    {
                        // ReadAsXmlAsync returns null when model state is valid only when other filters will log
                        // and return errors about the same conditions. Let those filters run.
                        await next();
                    }
                    else
                    {
                        context.Result = new BadRequestObjectResult(modelState);
                    }

                    return;
                }

                eventNames = ObjectPathUtilities.GetStringValues(xml, eventFromBodyMetadata.BodyPropertyPath);
                break;

            default:
                var message = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.General_InvalidEnumValue,
                    typeof(WebHookBodyType),
                    bodyTypeMetadata.BodyType);
                throw new InvalidOperationException(message);
            }

            if (StringValues.IsNullOrEmpty(eventNames) && !eventFromBodyMetadata.AllowMissing)
            {
                _logger.LogWarning(
                    0,
                    "A '{ReceiverName}' WebHook request must contain a match for '{BodyPropertyPath}' in the HTTP " +
                    "request entity body indicating the type or types of event.",
                    receiverName,
                    eventFromBodyMetadata.BodyPropertyPath);

                var message = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.EventMapper_NoBodyProperty,
                    receiverName,
                    eventFromBodyMetadata.BodyPropertyPath);
                context.Result = new BadRequestObjectResult(message);

                return;
            }

            routeData.SetWebHookEventNames(eventNames);

            await next();
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Validate payment form
        /// </summary>
        /// <param name="form">The parsed form values</param>
        /// <returns>List of validating errors</returns>
        public IList <string> ValidatePaymentForm(IFormCollection form)
        {
            if (form == null)
            {
                throw new ArgumentNullException(nameof(form));
            }

            if (_qualpaySettings.UseEmbeddedFields)
            {
                //try to get errors from Qualpay card tokenization
                if (form.TryGetValue(nameof(PaymentInfoModel.Errors), out var errorsString) && !StringValues.IsNullOrEmpty(errorsString))
                {
                    return(errorsString.ToString().Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList());
                }
            }
            else
            {
                //validate payment info (custom validation)
                var validationResult = new PaymentInfoValidator(_localizationService).Validate(new PaymentInfoModel
                {
                    CardholderName  = form[nameof(PaymentInfoModel.CardholderName)],
                    CardNumber      = form[nameof(PaymentInfoModel.CardNumber)],
                    ExpireMonth     = form[nameof(PaymentInfoModel.ExpireMonth)],
                    ExpireYear      = form[nameof(PaymentInfoModel.ExpireYear)],
                    CardCode        = form[nameof(PaymentInfoModel.CardCode)],
                    BillingCardId   = form[nameof(PaymentInfoModel.BillingCardId)],
                    SaveCardDetails = form.TryGetValue(nameof(PaymentInfoModel.SaveCardDetails), out var saveCardDetails) &&
                                      bool.TryParse(saveCardDetails.FirstOrDefault(), out var saveCard) &&
                                      saveCard
                });
Ejemplo n.º 25
0
        public async Task <object> GetStaticResult(IRequest requestContext, StaticResultOptions options)
        {
            options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            var contentType = options.ContentType;

            if (!StringValues.IsNullOrEmpty(requestContext.Headers[HeaderNames.IfModifiedSince]))
            {
                // See if the result is already cached in the browser
                var result = GetCachedResult(requestContext, options.ResponseHeaders, options);

                if (result != null)
                {
                    return(result);
                }
            }

            // TODO: We don't really need the option value
            var isHeadRequest   = options.IsHeadRequest || string.Equals(requestContext.Verb, "HEAD", StringComparison.OrdinalIgnoreCase);
            var factoryFn       = options.ContentFactory;
            var responseHeaders = options.ResponseHeaders;

            AddCachingHeaders(responseHeaders, options.CacheDuration, false, options.DateLastModified);
            AddAgeHeader(responseHeaders, options.DateLastModified);

            var rangeHeader = requestContext.Headers[HeaderNames.Range];

            if (!isHeadRequest && !string.IsNullOrEmpty(options.Path))
            {
                var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem, _streamHelper)
                {
                    OnComplete = options.OnComplete,
                    OnError    = options.OnError,
                    FileShare  = options.FileShare
                };

                AddResponseHeaders(hasHeaders, options.ResponseHeaders);
                return(hasHeaders);
            }

            var stream = await factoryFn().ConfigureAwait(false);

            var totalContentLength = options.ContentLength;

            if (!totalContentLength.HasValue)
            {
                try
                {
                    totalContentLength = stream.Length;
                }
                catch (NotSupportedException)
                {
                }
            }

            if (!string.IsNullOrWhiteSpace(rangeHeader) && totalContentLength.HasValue)
            {
                var hasHeaders = new RangeRequestWriter(rangeHeader, totalContentLength.Value, stream, contentType, isHeadRequest, _logger)
                {
                    OnComplete = options.OnComplete
                };

                AddResponseHeaders(hasHeaders, options.ResponseHeaders);
                return(hasHeaders);
            }
            else
            {
                if (isHeadRequest)
                {
                    using (stream)
                    {
                        return(GetHttpResult(requestContext, Array.Empty <byte>(), contentType, true, responseHeaders));
                    }
                }

                var hasHeaders = new StreamWriter(stream, contentType)
                {
                    OnComplete = options.OnComplete,
                    OnError    = options.OnError
                };

                AddResponseHeaders(hasHeaders, options.ResponseHeaders);
                return(hasHeaders);
            }
        }
Ejemplo n.º 26
0
        protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            var query = Request.Query;
            var protectedRequestToken = Request.Cookies[Options.StateCookie.Name];

            var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken);

            if (requestToken == null)
            {
                return(HandleRequestResult.Fail("Invalid state cookie."));
            }

            var properties = requestToken.Properties;

            // REVIEW: see which of these are really errors

            var returnedToken = query["oauth_token"];

            if (StringValues.IsNullOrEmpty(returnedToken))
            {
                return(HandleRequestResult.Fail("Missing oauth_token", properties));
            }

            if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal))
            {
                return(HandleRequestResult.Fail("Unmatched token", properties));
            }

            var oauthVerifier = query["oauth_verifier"];

            if (StringValues.IsNullOrEmpty(oauthVerifier))
            {
                return(HandleRequestResult.Fail("Missing or blank oauth_verifier", properties));
            }

            var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow);

            Response.Cookies.Delete(Options.StateCookie.Name, cookieOptions);

            var accessToken = await ObtainAccessTokenAsync(requestToken, oauthVerifier);

            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer),
                new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer),
                new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer),
                new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer)
            },
                                              ClaimsIssuer);

            JObject user = null;

            if (Options.RetrieveUserDetails)
            {
                user = await RetrieveUserDetailsAsync(accessToken, identity);
            }

            if (Options.SaveTokens)
            {
                properties.StoreTokens(new [] {
                    new AuthenticationToken {
                        Name = "access_token", Value = accessToken.Token
                    },
                    new AuthenticationToken {
                        Name = "access_token_secret", Value = accessToken.TokenSecret
                    }
                });
            }

            return(HandleRequestResult.Success(await CreateTicketAsync(identity, properties, accessToken, user)));
        }
        /// <summary>
        /// Get custom address attributes from the passed form
        /// </summary>
        /// <param name="form">Form values</param>
        /// <returns>Attributes in XML format</returns>
        public virtual string ParseCustomAddressAttributes(IFormCollection form)
        {
            if (form == null)
            {
                throw new ArgumentNullException(nameof(form));
            }

            var attributesXml = string.Empty;

            foreach (var attribute in _addressAttributeService.GetAllAddressAttributes())
            {
                var controlId       = string.Format(SmiCommonDefaults.AddressAttributeControlName, attribute.Id);
                var attributeValues = form[controlId];
                switch (attribute.AttributeControlType)
                {
                case AttributeControlType.DropdownList:
                case AttributeControlType.RadioList:
                    if (!StringValues.IsNullOrEmpty(attributeValues) && int.TryParse(attributeValues, out var value) && value > 0)
                    {
                        attributesXml = AddAddressAttribute(attributesXml, attribute, value.ToString());
                    }
                    break;

                case AttributeControlType.Checkboxes:
                    foreach (var attributeValue in attributeValues.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (int.TryParse(attributeValue, out value) && value > 0)
                        {
                            attributesXml = AddAddressAttribute(attributesXml, attribute, value.ToString());
                        }
                    }

                    break;

                case AttributeControlType.ReadonlyCheckboxes:
                    //load read-only (already server-side selected) values
                    var addressAttributeValues = _addressAttributeService.GetAddressAttributeValues(attribute.Id);
                    foreach (var addressAttributeValue in addressAttributeValues)
                    {
                        if (addressAttributeValue.IsPreSelected)
                        {
                            attributesXml = AddAddressAttribute(attributesXml, attribute, addressAttributeValue.Id.ToString());
                        }
                    }

                    break;

                case AttributeControlType.TextBox:
                case AttributeControlType.MultilineTextbox:
                    if (!StringValues.IsNullOrEmpty(attributeValues))
                    {
                        attributesXml = AddAddressAttribute(attributesXml, attribute, attributeValues.ToString().Trim());
                    }
                    break;

                case AttributeControlType.Datepicker:
                case AttributeControlType.ColorSquares:
                case AttributeControlType.ImageSquares:
                case AttributeControlType.FileUpload:
                default:
                    break;
                }
            }

            return(attributesXml);
        }
Ejemplo n.º 28
0
        protected override async Task <HandleRequestResult> HandleRemoteAuthenticateAsync()
        {
            var query = Request.Query;
            var protectedRequestToken = Request.Cookies[Options.StateCookie.Name];

            var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken);

            if (requestToken == null)
            {
                return(HandleRequestResult.Fail("Invalid state cookie."));
            }

            var properties = requestToken.Properties;

            var denied = query["denied"];

            if (!StringValues.IsNullOrEmpty(denied))
            {
                // Note: denied errors are special protocol errors indicating the user didn't
                // approve the authorization demand requested by the remote authorization server.
                // Since it's a frequent scenario (that is not caused by incorrect configuration),
                // denied errors are handled differently using HandleAccessDeniedErrorAsync().
                var result = await HandleAccessDeniedErrorAsync(properties);

                return(!result.None ? result
                    : HandleRequestResult.Fail("Access was denied by the resource owner or by the remote server.", properties));
            }

            var returnedToken = query["oauth_token"];

            if (StringValues.IsNullOrEmpty(returnedToken))
            {
                return(HandleRequestResult.Fail("Missing oauth_token", properties));
            }

            if (!string.Equals(returnedToken, requestToken.Token, StringComparison.Ordinal))
            {
                return(HandleRequestResult.Fail("Unmatched token", properties));
            }

            var oauthVerifier = query["oauth_verifier"];

            if (StringValues.IsNullOrEmpty(oauthVerifier))
            {
                return(HandleRequestResult.Fail("Missing or blank oauth_verifier", properties));
            }

            var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow);

            Response.Cookies.Delete(Options.StateCookie.Name, cookieOptions);

            var accessToken = await ObtainAccessTokenAsync(requestToken, oauthVerifier);

            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer),
                new Claim(ClaimTypes.Name, accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer),
                new Claim("urn:twitter:userid", accessToken.UserId, ClaimValueTypes.String, ClaimsIssuer),
                new Claim("urn:twitter:screenname", accessToken.ScreenName, ClaimValueTypes.String, ClaimsIssuer)
            },
                                              ClaimsIssuer);

            JsonDocument user;

            if (Options.RetrieveUserDetails)
            {
                user = await RetrieveUserDetailsAsync(accessToken, identity);
            }
            else
            {
                user = JsonDocument.Parse("{}");
            }

            using (user)
            {
                if (Options.SaveTokens)
                {
                    properties.StoreTokens(new[] {
                        new AuthenticationToken {
                            Name = "access_token", Value = accessToken.Token
                        },
                        new AuthenticationToken {
                            Name = "access_token_secret", Value = accessToken.TokenSecret
                        }
                    });
                }

                var ticket = await CreateTicketAsync(identity, properties, accessToken, user.RootElement);

                return(HandleRequestResult.Success(ticket));
            }
        }
Ejemplo n.º 29
0
    // BaseKey<delimiter>H<delimiter>HeaderName=HeaderValue<delimiter>Q<delimiter>QueryName=QueryValue1<subdelimiter>QueryValue2
    public string CreateStorageVaryByKey(ResponseCachingContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var varyByRules = context.CachedVaryByRules;

        if (varyByRules == null)
        {
            throw new InvalidOperationException($"{nameof(CachedVaryByRules)} must not be null on the {nameof(ResponseCachingContext)}");
        }

        if (StringValues.IsNullOrEmpty(varyByRules.Headers) && StringValues.IsNullOrEmpty(varyByRules.QueryKeys))
        {
            return(varyByRules.VaryByKeyPrefix);
        }

        var request = context.HttpContext.Request;
        var builder = _builderPool.Get();

        try
        {
            // Prepend with the Guid of the CachedVaryByRules
            builder.Append(varyByRules.VaryByKeyPrefix);

            // Vary by headers
            var headersCount = varyByRules?.Headers.Count ?? 0;
            if (headersCount > 0)
            {
                // Append a group separator for the header segment of the cache key
                builder.Append(KeyDelimiter)
                .Append('H');

                var requestHeaders = context.HttpContext.Request.Headers;
                for (var i = 0; i < headersCount; i++)
                {
                    var header       = varyByRules !.Headers[i] ?? string.Empty;
                    var headerValues = requestHeaders[header];
                    builder.Append(KeyDelimiter)
                    .Append(header)
                    .Append('=');

                    var headerValuesArray = headerValues.ToArray();
                    Array.Sort(headerValuesArray, StringComparer.Ordinal);

                    for (var j = 0; j < headerValuesArray.Length; j++)
                    {
                        builder.Append(headerValuesArray[j]);
                    }
                }
            }

            // Vary by query keys
            if (varyByRules?.QueryKeys.Count > 0)
            {
                // Append a group separator for the query key segment of the cache key
                builder.Append(KeyDelimiter)
                .Append('Q');

                if (varyByRules.QueryKeys.Count == 1 && string.Equals(varyByRules.QueryKeys[0], "*", StringComparison.Ordinal))
                {
                    // Vary by all available query keys
                    var queryArray = context.HttpContext.Request.Query.ToArray();
                    // Query keys are aggregated case-insensitively whereas the query values are compared ordinally.
                    Array.Sort(queryArray, QueryKeyComparer.OrdinalIgnoreCase);

                    for (var i = 0; i < queryArray.Length; i++)
                    {
                        builder.Append(KeyDelimiter)
                        .AppendUpperInvariant(queryArray[i].Key)
                        .Append('=');

                        var queryValueArray = queryArray[i].Value.ToArray();
                        Array.Sort(queryValueArray, StringComparer.Ordinal);

                        for (var j = 0; j < queryValueArray.Length; j++)
                        {
                            if (j > 0)
                            {
                                builder.Append(KeySubDelimiter);
                            }

                            builder.Append(queryValueArray[j]);
                        }
                    }
                }
                else
                {
                    for (var i = 0; i < varyByRules.QueryKeys.Count; i++)
                    {
                        var queryKey       = varyByRules.QueryKeys[i] ?? string.Empty;
                        var queryKeyValues = context.HttpContext.Request.Query[queryKey];
                        builder.Append(KeyDelimiter)
                        .Append(queryKey)
                        .Append('=');

                        var queryValueArray = queryKeyValues.ToArray();
                        Array.Sort(queryValueArray, StringComparer.Ordinal);

                        for (var j = 0; j < queryValueArray.Length; j++)
                        {
                            if (j > 0)
                            {
                                builder.Append(KeySubDelimiter);
                            }

                            builder.Append(queryValueArray[j]);
                        }
                    }
                }
            }

            return(builder.ToString());
        }
        finally
        {
            _builderPool.Return(builder);
        }
    }
Ejemplo n.º 30
0
    public async Task ProxyAsync_EmptyRequestHeader_Proxied()
    {
        var refererReceived = new TaskCompletionSource <StringValues>(TaskCreationOptions.RunContinuationsAsynchronously);
        var customReceived  = new TaskCompletionSource <StringValues>(TaskCreationOptions.RunContinuationsAsynchronously);

        IForwarderErrorFeature proxyError = null;
        Exception unhandledError          = null;

        var test = new TestEnvironment(
            context =>
        {
            if (context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header))
            {
                refererReceived.SetResult(header);
            }
            else
            {
                refererReceived.SetException(new Exception($"Missing '{HeaderNames.Referer}' header in request"));
            }

            if (context.Request.Headers.TryGetValue("custom", out header))
            {
                customReceived.SetResult(header);
            }
            else
            {
                customReceived.SetException(new Exception($"Missing 'custom' header in request"));
            }


            return(Task.CompletedTask);
        },
            proxyBuilder => { },
            proxyApp =>
        {
            proxyApp.Use(async(context, next) =>
            {
                try
                {
                    Assert.True(context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header));
                    var value = Assert.Single(header);
                    Assert.True(StringValues.IsNullOrEmpty(value));

                    Assert.True(context.Request.Headers.TryGetValue("custom", out header));
                    value = Assert.Single(header);
                    Assert.True(StringValues.IsNullOrEmpty(value));

                    await next();
                    proxyError = context.Features.Get <IForwarderErrorFeature>();
                }
                catch (Exception ex)
                {
                    unhandledError = ex;
                    throw;
                }
            });
        },
            proxyProtocol: HttpProtocols.Http1);

        await test.Invoke(async proxyUri =>
        {
            var proxyHostUri = new Uri(proxyUri);

            using var tcpClient    = new TcpClient(proxyHostUri.Host, proxyHostUri.Port);
            await using var stream = tcpClient.GetStream();
            await stream.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes($"Host: {proxyHostUri.Host}:{proxyHostUri.Port}\r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes($"Content-Length: 0\r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes($"Connection: close\r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes($"Referer: \r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes($"custom: \r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
            await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
            var buffer          = new byte[4096];
            var responseBuilder = new StringBuilder();
            while (true)
            {
                var count = await stream.ReadAsync(buffer);
                if (count == 0)
                {
                    break;
                }
                responseBuilder.Append(Encoding.ASCII.GetString(buffer, 0, count));
            }
            var response = responseBuilder.ToString();

            Assert.Null(proxyError);
            Assert.Null(unhandledError);

            Assert.StartsWith("HTTP/1.1 200 OK", response);

            Assert.True(refererReceived.Task.IsCompleted);
            var refererHeader = await refererReceived.Task;
            var referer       = Assert.Single(refererHeader);
            Assert.True(StringValues.IsNullOrEmpty(referer));

            Assert.True(customReceived.Task.IsCompleted);
            var customHeader = await customReceived.Task;
            var custom       = Assert.Single(customHeader);
            Assert.True(StringValues.IsNullOrEmpty(custom));
        });
    }