Пример #1
0
        private OrderedDictionary <string, OpenApiPath> ParseOperations(List <RestPath> restPaths, Dictionary <string, OpenApiSchema> schemas, Dictionary <string, OpenApiTag> tags)
        {
            var feature  = HostContext.GetPlugin <OpenApiFeature>();
            var apiPaths = new OrderedDictionary <string, OpenApiPath>();

            foreach (var restPath in restPaths)
            {
                var verbs   = new List <string>();
                var summary = restPath.Summary ?? restPath.RequestType.GetDescription();

                verbs.AddRange(restPath.AllowsAllVerbs
                    ? AnyRouteVerbs
                    : restPath.Verbs);

                var routePath   = restPath.Path.Replace("*", "");
                var requestType = restPath.RequestType;

                if (!apiPaths.TryGetValue(restPath.Path, out var curPath))
                {
                    curPath = new OpenApiPath
                    {
                        Parameters = new List <OpenApiParameter>
                        {
                            new OpenApiParameter {
                                Ref = "#/parameters/Accept"
                            }
                        }
                    };
                    apiPaths.Add(restPath.Path, curPath);
                }

                var op = HostContext.Metadata.OperationsMap[requestType];

                var annotatingTagAttributes = requestType.AllAttributes <TagAttribute>();

                foreach (var verb in verbs)
                {
                    var needAuth = op.RequiresAuthentication;

                    var userTags = new List <string>();
                    if (ApplyToUtils.VerbsApplyTo.TryGetValue(verb, out var applyToVerb))
                    {
                        userTags = annotatingTagAttributes.Where(x => x.ApplyTo.HasFlag(applyToVerb)).Select(x => x.Name).ToList();
                    }

                    var operation = new OpenApiOperation
                    {
                        RequestType = requestType.Name,
                        Summary     = summary,
                        Description = restPath.Notes ?? summary,
                        OperationId = GetOperationName(requestType.Name, routePath, verb),
                        Parameters  = ParseParameters(schemas, requestType, routePath, verb),
                        Responses   = GetMethodResponseCodes(restPath, schemas, requestType),
                        Consumes    = new List <string> {
                            "application/json"
                        },
                        Produces = new List <string> {
                            "application/json"
                        },
                        Tags       = userTags.Count > 0 ? userTags : GetTags(restPath.Path),
                        Deprecated = requestType.HasAttribute <ObsoleteAttribute>(),
                        Security   = needAuth ? new List <Dictionary <string, List <string> > > {
                            OperationSecurity
                        } : null
                    };

                    if (HasFormData(verb, operation.Parameters))
                    {
                        operation.Consumes = new List <string> {
                            "application/x-www-form-urlencoded"
                        }
                    }
                    ;

                    foreach (var tag in operation.Tags)
                    {
                        if (!tags.ContainsKey(tag))
                        {
                            var tagObject = feature.Tags.FirstOrDefault(x => x.Name == tag)
                                            ?? new OpenApiTag {
                                Name = tag
                            };

                            tags.Add(tag, tagObject);
                        }
                    }

                    switch (verb)
                    {
                    case HttpMethods.Get: curPath.Get = operation; break;

                    case HttpMethods.Post: curPath.Post = operation; break;

                    case HttpMethods.Put: curPath.Put = operation; break;

                    case HttpMethods.Delete: curPath.Delete = operation; break;

                    case HttpMethods.Patch: curPath.Patch = operation; break;

                    case HttpMethods.Head: curPath.Head = operation; break;

                    case HttpMethods.Options: curPath.Options = operation; break;
                    }
                }
            }

            return(apiPaths);
        }
Пример #2
0
        /// <summary>
        ///     Create new Registration
        /// </summary>
        public object Post(Register request)
        {
            if (HostContext.GetPlugin <AuthFeature>()?.SaveUserNamesInLowerCase == true)
            {
                if (request.UserName != null)
                {
                    request.UserName = request.UserName.ToLower();
                }
                if (request.Email != null)
                {
                    request.Email = request.Email.ToLower();
                }
            }

            var validateResponse = ValidateFn?.Invoke(this, HttpMethods.Post, request);

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

            RegisterResponse response = null;
            var       session         = this.GetSession();
            bool      registerNewUser;
            IUserAuth user;

            var authRepo    = HostContext.AppHost.GetAuthRepository(base.Request);
            var newUserAuth = ToUserAuth(authRepo, request);

            using (authRepo as IDisposable)
            {
                var existingUser = session.IsAuthenticated ? authRepo.GetUserAuth(session, null) : null;
                registerNewUser = existingUser == null;

                if (!registerNewUser && !AllowUpdates)
                {
                    throw new NotSupportedException(ErrorMessages.RegisterUpdatesDisabled.Localize(Request));
                }

                if (!HostContext.AppHost.GlobalRequestFiltersAsyncArray.Contains(ValidationFilters.RequestFilterAsync)) //Already gets run
                {
                    RegistrationValidator?.ValidateAndThrow(request, registerNewUser ? ApplyTo.Post : ApplyTo.Put);
                }

                user = registerNewUser
                    ? authRepo.CreateUserAuth(newUserAuth, request.Password)
                    : authRepo.UpdateUserAuth(existingUser, newUserAuth, request.Password);

                if (request.AutoLogin.GetValueOrDefault())
                {
                    using (var authService = base.ResolveService <AuthenticateService>())
                    {
                        var authResponse = authService.Post(
                            new Authenticate {
                            provider = CredentialsAuthProvider.Name,
                            UserName = request.UserName ?? request.Email,
                            Password = request.Password,
                            Continue = request.Continue ?? base.Request.GetQueryStringOrForm(Keywords.ReturnUrl)
                        });

                        if (authResponse is IHttpError)
                        {
                            throw (Exception)authResponse;
                        }

                        if (authResponse is AuthenticateResponse typedResponse)
                        {
                            response = new RegisterResponse
                            {
                                SessionId    = typedResponse.SessionId,
                                UserName     = typedResponse.UserName,
                                ReferrerUrl  = typedResponse.ReferrerUrl,
                                UserId       = user.Id.ToString(CultureInfo.InvariantCulture),
                                BearerToken  = typedResponse.BearerToken,
                                RefreshToken = typedResponse.RefreshToken,
                            };
                        }
                    }
                }

                if (registerNewUser)
                {
                    session = this.GetSession();
                    if (!request.AutoLogin.GetValueOrDefault())
                    {
                        session.PopulateSession(user, authRepo);
                    }

                    session.OnRegistered(Request, session, this);
                    AuthEvents?.OnRegistered(this.Request, session, this);
                }
            }

            if (response == null)
            {
                response = new RegisterResponse
                {
                    UserId      = user.Id.ToString(CultureInfo.InvariantCulture),
                    ReferrerUrl = request.Continue,
                    UserName    = session.UserName,
                };
            }

            var isHtml = Request.ResponseContentType.MatchesContentType(MimeTypes.Html);

            if (isHtml)
            {
                if (string.IsNullOrEmpty(request.Continue))
                {
                    return(response);
                }

                return(new HttpResult(response)
                {
                    Location = request.Continue
                });
            }

            return(response);
        }
Пример #3
0
        protected override void Render(HtmlTextWriter output)
        {
            var operationsPart = new TableTemplate
            {
                Title       = "Operations",
                Items       = this.OperationNames,
                ForEachItem = RenderRow
            }.ToString();

#if !NETSTANDARD1_6
            var xsdsPart = new ListTemplate
            {
                Title            = "XSDS:",
                ListItemsIntMap  = this.Xsds,
                ListItemTemplate = @"<li><a href=""?xsd={0}"">{1}</a></li>"
            }.ToString();
#else
            var xsdsPart = "";
#endif

            var wsdlTemplate = StringBuilderCache.Allocate();
            var soap11Config = MetadataConfig.GetMetadataConfig("soap11") as SoapMetadataConfig;
            var soap12Config = MetadataConfig.GetMetadataConfig("soap12") as SoapMetadataConfig;
            if (soap11Config != null || soap12Config != null)
            {
                wsdlTemplate.AppendLine("<h3>WSDLS:</h3>");
                wsdlTemplate.AppendLine("<ul>");
                if (soap11Config != null)
                {
                    wsdlTemplate.AppendFormat(
                        @"<li><a href=""{0}"">{0}</a></li>",
                        soap11Config.WsdlMetadataUri);
                }
                if (soap12Config != null)
                {
                    wsdlTemplate.AppendFormat(
                        @"<li><a href=""{0}"">{0}</a></li>",
                        soap12Config.WsdlMetadataUri);
                }
                wsdlTemplate.AppendLine("</ul>");
            }

            var metadata    = HostContext.GetPlugin <MetadataFeature>();
            var pluginLinks = metadata != null && metadata.PluginLinks.Count > 0
                ? new ListTemplate
            {
                Title            = metadata.PluginLinksTitle,
                ListItemsMap     = ToAbsoluteUrls(metadata.PluginLinks),
                ListItemTemplate = @"<li><a href=""{0}"">{1}</a></li>"
            }.ToString()
                : "";

            var debugOnlyInfo = HostContext.DebugMode && metadata != null && metadata.DebugLinks.Count > 0
                ? new ListTemplate
            {
                Title            = metadata.DebugLinksTitle,
                ListItemsMap     = ToAbsoluteUrls(metadata.DebugLinks),
                ListItemTemplate = @"<li><a href=""{0}"">{1}</a></li>"
            }.ToString()
                : "";

            var errorCount    = HostContext.AppHost.StartUpErrors.Count;
            var plural        = errorCount > 1 ? "s" : "";
            var startupErrors = HostContext.DebugMode && errorCount > 0
                ? $"<div class='error-popup'><a href='?debug=requestinfo'>Review {errorCount} Error{plural} on Startup</a></div>"
                : "";

            var renderedTemplate = HtmlTemplates.Format(
                HtmlTemplates.GetIndexOperationsTemplate(),
                this.Title,
                this.XsdServiceTypesIndex,
                operationsPart,
                xsdsPart,
                StringBuilderCache.ReturnAndFree(wsdlTemplate),
                pluginLinks,
                debugOnlyInfo,
                Env.VersionString,
                startupErrors);

            output.Write(renderedTemplate);
        }
Пример #4
0
 public SwiftGenerator(MetadataTypesConfig config)
 {
     Config   = config;
     feature  = HostContext.GetPlugin <NativeTypesFeature>();
     AllTypes = new List <MetadataType>();
 }
Пример #5
0
        private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto,
                                                     bool treatInfoAndWarningsAsErrors)
        {
            var requestType = requestDto.GetType();
            await Validators.AssertTypeValidatorsAsync(req, requestDto, requestType);

            var validator = ValidatorCache.GetValidator(req, requestType);

            if (validator == null)
            {
                return;
            }

            using (validator as IDisposable)
            {
                if (validator is IHasTypeValidators hasTypeValidators && hasTypeValidators.TypeValidators.Count > 0)
                {
                    foreach (var scriptValidator in hasTypeValidators.TypeValidators)
                    {
                        await scriptValidator.ThrowIfNotValidAsync(requestDto, req);
                    }
                }

                try
                {
                    if (req.Verb == HttpMethods.Patch)
                    {
                        // Ignore property rules for AutoCrud Patch operations with default values that aren't reset (which are ignored)
                        if (validator is IServiceStackValidator ssValidator && requestDto is ICrud && requestType.IsOrHasGenericInterfaceTypeOf(typeof(IPatchDb <>)))
                        {
                            var typeProperties         = TypeProperties.Get(requestType);
                            var propsWithDefaultValues = new HashSet <string>();
                            var resetFields            = GetResetFields(req.GetParam(Keywords.reset))?.ToSet(StringComparer.OrdinalIgnoreCase)
                                                         ?? TypeConstants <string> .EmptyHashSet;

                            foreach (var entry in typeProperties.PropertyMap)
                            {
                                if (entry.Value.PublicGetter == null || resetFields.Contains(entry.Key))
                                {
                                    continue;
                                }
                                var defaultValue = entry.Value.PropertyInfo.PropertyType.GetDefaultValue();
                                var propValue    = entry.Value.PublicGetter(requestDto);
                                if (propValue == null || propValue.Equals(defaultValue))
                                {
                                    propsWithDefaultValues.Add(entry.Key);
                                }
                            }
                            if (propsWithDefaultValues.Count > 0)
                            {
                                ssValidator.RemovePropertyRules(rule => propsWithDefaultValues.Contains(rule.PropertyName));
                            }
                        }
                    }

                    var validationResult = await validator.ValidateAsync(req, requestDto);

                    if (treatInfoAndWarningsAsErrors && validationResult.IsValid)
                    {
                        return;
                    }

                    if (!treatInfoAndWarningsAsErrors &&
                        (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error)))
                    {
                        return;
                    }

                    var errorResponse =
                        await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                        ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                    var autoBatchIndex = req.GetItem(Keywords.AutoBatchIndex)?.ToString();
                    if (autoBatchIndex != null)
                    {
                        var responseStatus = errorResponse.GetResponseStatus();
                        if (responseStatus != null)
                        {
                            if (responseStatus.Meta == null)
                            {
                                responseStatus.Meta = new Dictionary <string, string>();
                            }
                            responseStatus.Meta[Keywords.AutoBatchIndex] = autoBatchIndex;
                        }
                    }

                    var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                    if (validationFeature?.ErrorResponseFilter != null)
                    {
                        errorResponse = validationFeature.ErrorResponseFilter(req, validationResult, errorResponse);
                    }

                    await res.WriteToResponse(req, errorResponse);
                }
                catch (Exception ex)
                {
                    var validationEx = ex.UnwrapIfSingleException();

                    var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                    await res.WriteToResponse(req, errorResponse);
                }
            }
        }
        private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto,
                                                     bool treatInfoAndWarningsAsErrors)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());

            if (validator == null)
            {
                return;
            }

            using (validator as IDisposable)
            {
                try
                {
                    var validationResult = await validator.ValidateAsync(req, requestDto);

                    if (treatInfoAndWarningsAsErrors && validationResult.IsValid)
                    {
                        return;
                    }

                    if (!treatInfoAndWarningsAsErrors &&
                        (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error)))
                    {
                        return;
                    }

                    var errorResponse =
                        await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                        ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                    var autoBatchIndex = req.GetItem(Keywords.AutoBatchIndex)?.ToString();
                    if (autoBatchIndex != null)
                    {
                        var responseStatus = errorResponse.GetResponseStatus();
                        if (responseStatus != null)
                        {
                            if (responseStatus.Meta == null)
                            {
                                responseStatus.Meta = new Dictionary <string, string>();
                            }
                            responseStatus.Meta[Keywords.AutoBatchIndex] = autoBatchIndex;
                        }
                    }

                    var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                    if (validationFeature?.ErrorResponseFilter != null)
                    {
                        errorResponse = validationFeature.ErrorResponseFilter(req, validationResult, errorResponse);
                    }

                    await res.WriteToResponse(req, errorResponse);
                }
                catch (Exception ex)
                {
                    var validationEx = ex.UnwrapIfSingleException();

                    var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                        ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                    await res.WriteToResponse(req, errorResponse);
                }
            }
        }
Пример #7
0
        public static JsonObject CreateJwtPayload(
            IAuthSession session, string issuer, TimeSpan expireIn,
            IEnumerable <string> audiences   = null,
            IEnumerable <string> roles       = null,
            IEnumerable <string> permissions = null)
        {
            var now        = DateTime.UtcNow;
            var jwtPayload = new JsonObject
            {
                { "iss", issuer },
                { "sub", session.UserAuthId },
                { "iat", now.ToUnixTime().ToString() },
                { "exp", now.Add(expireIn).ToUnixTime().ToString() },
            };

            jwtPayload.SetAudience(audiences?.ToList());

            if (!string.IsNullOrEmpty(session.Email))
            {
                jwtPayload["email"] = session.Email;
            }
            if (!string.IsNullOrEmpty(session.FirstName))
            {
                jwtPayload["given_name"] = session.FirstName;
            }
            if (!string.IsNullOrEmpty(session.LastName))
            {
                jwtPayload["family_name"] = session.LastName;
            }
            if (!string.IsNullOrEmpty(session.DisplayName))
            {
                jwtPayload["name"] = session.DisplayName;
            }

            if (!string.IsNullOrEmpty(session.UserName))
            {
                jwtPayload["preferred_username"] = session.UserName;
            }
            else if (!string.IsNullOrEmpty(session.UserAuthName) && !session.UserAuthName.Contains("@"))
            {
                jwtPayload["preferred_username"] = session.UserAuthName;
            }

            var profileUrl = session.GetProfileUrl();

            if (profileUrl != null && profileUrl != Svg.GetDataUri(Svg.Icons.DefaultProfile))
            {
                if (profileUrl.Length <= MaxProfileUrlSize)
                {
                    jwtPayload["picture"] = profileUrl;
                }
                else
                {
                    LogManager.GetLogger(typeof(JwtAuthProvider)).Warn($"User '{session.UserAuthId}' ProfileUrl exceeds max JWT Cookie size, using default profile");
                    jwtPayload["picture"] = HostContext.GetPlugin <AuthFeature>()?.ProfileImages?.RewriteImageUri(profileUrl);
                }
            }

            var combinedRoles = new List <string>(session.Roles.Safe());
            var combinedPerms = new List <string>(session.Permissions.Safe());

            roles.Each(x => combinedRoles.AddIfNotExists(x));
            permissions.Each(x => combinedPerms.AddIfNotExists(x));

            if (combinedRoles.Count > 0)
            {
                jwtPayload["roles"] = combinedRoles.ToJson();
            }

            if (combinedPerms.Count > 0)
            {
                jwtPayload["perms"] = combinedPerms.ToJson();
            }

            return(jwtPayload);
        }
Пример #8
0
 public TypeScriptGenerator(MetadataTypesConfig config)
 {
     Config  = config;
     feature = HostContext.GetPlugin <NativeTypesFeature>();
 }
Пример #9
0
        public List <PostmanRequest> GetRequests(Postman request, string parentId, IEnumerable <Operation> operations)
        {
            var ret     = new List <PostmanRequest>();
            var feature = HostContext.GetPlugin <PostmanFeature>();

            var headers = feature.Headers ?? ("Accept: " + MimeTypes.Json);

            if (Response is IHttpResponse httpRes)
            {
                if (request.ssopt != null ||
                    request.sspid != null ||
                    request.ssid != null)
                {
                    if (feature.EnableSessionExport != true)
                    {
                        throw new ArgumentException("PostmanFeature.EnableSessionExport is not enabled");
                    }
                }

                if (request.ssopt != null)
                {
                    Request.AddSessionOptions(request.ssopt);
                }
                if (request.sspid != null)
                {
                    httpRes.Cookies.AddPermanentCookie(SessionFeature.PermanentSessionId, request.sspid);
                }
                if (request.ssid != null)
                {
                    httpRes.Cookies.AddSessionCookie(SessionFeature.SessionId, request.ssid,
                                                     (HostContext.Config.UseSecureCookies && Request.IsSecureConnection));
                }
            }

            foreach (var op in operations)
            {
                Uri url = null;

                if (!HostContext.Metadata.IsVisible(base.Request, op))
                {
                    continue;
                }

                var allVerbs = new HashSet <string>(op.Actions.Concat(
                                                        op.Routes.SelectMany(x => x.Verbs))
                                                    .SelectMany(x => x == ActionContext.AnyAction
                        ? feature.DefaultVerbsForAny
                        : new List <string> {
                    x
                }));

                var propertyTypes = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                op.RequestType.GetSerializableFields()
                .Each(x => propertyTypes[x.Name] = x.FieldType.AsFriendlyName(feature));
                op.RequestType.GetSerializableProperties()
                .Each(x => propertyTypes[x.Name] = x.PropertyType.AsFriendlyName(feature));

                foreach (var route in op.Routes)
                {
                    var routeVerbs = route.Verbs.Contains(ActionContext.AnyAction)
                        ? feature.DefaultVerbsForAny.ToArray()
                        : route.Verbs;

                    var restRoute = route.ToRestRoute();

                    foreach (var verb in routeVerbs)
                    {
                        allVerbs.Remove(verb); //exclude handled verbs

                        var routeData = restRoute.QueryStringVariables
                                        .Map(x => new PostmanData
                        {
                            key   = x,
                            value = "",
                            type  = "text",
                        })
                                        .ApplyPropertyTypes(propertyTypes);

                        url = new Uri(Request.GetBaseUrl().CombineWith(restRoute.Path.ToPostmanPathVariables()));
                        ret.Add(new PostmanRequest
                        {
                            request = new PostmanRequestDetails {
                                url = new PostmanRequestUrl {
                                    raw      = url.OriginalString,
                                    host     = url.Host,
                                    port     = url.Port.ToString(),
                                    protocol = url.Scheme,
                                    path     = url.LocalPath.SplitPaths(),
                                    query    = !HttpUtils.HasRequestBody(verb)
                                        ? routeData.Select(x => x.key)
                                               .ApplyPropertyTypes(propertyTypes)
                                               .Map(x => new PostmanRequestKeyValue {
                                        key = x.Key, value = x.Value
                                    })
                                        : null,
                                    variable = restRoute.Variables.Any()
                                        ? restRoute.Variables.Map(x => new PostmanRequestKeyValue {
                                        key = x
                                    })
                                        : null
                                },
                                method = verb,
                                body   = new PostmanRequestBody {
                                    formdata = HttpUtils.HasRequestBody(verb)
                                    ? routeData
                                    : null,
                                },
                                header = headers,
                            },
                            name = GetName(feature, request, op.RequestType, restRoute.Path),
                        });
                    }
                }

                var emptyRequest = op.RequestType.CreateInstance();
                var virtualPath  = emptyRequest.ToReplyUrlOnly();

                var requestParams = propertyTypes
                                    .Map(x => new PostmanData
                {
                    key   = x.Key,
                    value = x.Value,
                    type  = "text",
                });

                url = new Uri(Request.GetBaseUrl().CombineWith(virtualPath));

                ret.AddRange(allVerbs.Select(verb =>
                                             new PostmanRequest
                {
                    request = new PostmanRequestDetails {
                        url = new PostmanRequestUrl {
                            raw      = url.OriginalString,
                            host     = url.Host,
                            port     = url.Port.ToString(),
                            protocol = url.Scheme,
                            path     = url.LocalPath.SplitPaths(),
                            query    = !HttpUtils.HasRequestBody(verb)
                                    ? requestParams.Select(x => x.key)
                                       .Where(x => !x.StartsWith(":"))
                                       .ApplyPropertyTypes(propertyTypes)
                                       .Map(x => new PostmanRequestKeyValue {
                                key = x.Key, value = x.Value
                            })
                                    : null,
                            variable = url.Segments.Any(x => x.StartsWith(":"))
                                    ? url.Segments.Where(x => x.StartsWith(":"))
                                       .Map(x => new PostmanRequestKeyValue {
                                key = x.Replace(":", ""), value = ""
                            })
                                    : null
                        },
                        method = verb,
                        body   = new PostmanRequestBody {
                            formdata = HttpUtils.HasRequestBody(verb)
                                ? requestParams
                                : null,
                        },
                        header = headers,
                    },
                    name = GetName(feature, request, op.RequestType, virtualPath),
                }));
            }

            return(ret);
        }
Пример #10
0
        public override void ProcessRequest(IRequest req, IResponse res, string operationName)
        {
            var format = HostContext.GetPlugin <RazorFormat>();

            try
            {
                if (viewEngineResult == null)
                {
                    if (PathInfo == null)
                    {
                        throw new ArgumentNullException(nameof(PathInfo));
                    }

                    viewEngineResult = format.GetPageFromPathInfo(PathInfo);

                    if (viewEngineResult == null)
                    {
                        throw new ArgumentException("Could not find Razor Page at " + PathInfo);
                    }
                }

                res.ContentType = MimeTypes.Html;
                var model = Model;
                if (model == null)
                {
                    req.Items.TryGetValue("Model", out model);
                }

                ViewDataDictionary viewData = null;
                if (model == null)
                {
                    var razorView  = viewEngineResult.View as RazorView;
                    var genericDef = razorView.RazorPage.GetType().FirstGenericType();
                    var modelType  = genericDef?.GetGenericArguments()[0];
                    if (modelType != null && modelType != typeof(object))
                    {
                        model    = DeserializeHttpRequest(modelType, req, req.ContentType);
                        viewData = RazorFormat.CreateViewData(model);
                    }
                }

                if (viewData == null)
                {
                    viewData = new ViewDataDictionary <object>(
                        metadataProvider: new EmptyModelMetadataProvider(),
                        modelState: new ModelStateDictionary());

                    foreach (string header in req.Headers)
                    {
                        viewData[header] = req.Headers[header];
                    }
                    foreach (string key in req.QueryString)
                    {
                        viewData[key] = req.QueryString[key];
                    }
                    foreach (string key in req.FormData)
                    {
                        viewData[key] = req.QueryString[key];
                    }
                }

                format.RenderView(req, viewData, viewEngineResult.View);
            }
            catch (Exception ex)
            {
                //Can't set HTTP Headers which are already written at this point
                req.Response.WriteErrorBody(ex);
            }
        }
Пример #11
0
        public object Post(CreateUser request)
        {
            if (HostContext.GetPlugin <AuthFeature>()?.SaveUserNamesInLowerCase == true)
            {
                if (request.UserName != null)
                {
                    request.UserName = request.UserName.ToLower();
                }
                if (request.Email != null)
                {
                    request.Email = request.Email.ToLower();
                }
            }

            CreateUserDataReponse response = null;

            var newUserAuth = ToUserAuth(AuthRepo, request);
            var user        = AuthRepo.CreateUserAuth(newUserAuth, request.Password);

            if (!request.Role.IsNullOrEmpty())
            {
                using (var assignRoleService = ResolveService <AssignRolesService>())
                {
                    var assignRoleResponse = assignRoleService.Post(new AssignRoles()
                    {
                        UserName = user.UserName,
                        Roles    = new List <string>()
                        {
                            request.Role
                        }
                    });
                    switch (assignRoleResponse)
                    {
                    case IHttpError _:
                        throw (Exception)assignRoleResponse;

                    default:
                        break;
                    }
                }
            }

            if (request.AutoLogin.GetValueOrDefault())
            {
                using (var authService = ResolveService <AuthenticateService>())
                {
                    var authResponse = authService.Post(
                        new Authenticate {
                        provider = CredentialsAuthProvider.Name,
                        UserName = request.UserName ?? request.Email,
                        Password = request.Password,
                        Continue = request.Continue
                    });

                    switch (authResponse)
                    {
                    case IHttpError _:
                        throw (Exception)authResponse;

                    case AuthenticateResponse typedResponse:
                        response = new CreateUserDataReponse
                        {
                            SessionId    = typedResponse.SessionId,
                            UserName     = typedResponse.UserName,
                            ReferrerUrl  = typedResponse.ReferrerUrl,
                            UserId       = user.Id.ToString(CultureInfo.InvariantCulture),
                            BearerToken  = typedResponse.BearerToken,
                            RefreshToken = typedResponse.RefreshToken,
                        };
                        break;
                    }
                }
            }

            var session = GetSession();

            if (!request.AutoLogin.GetValueOrDefault())
            {
                session.PopulateSession(user, new List <IAuthTokens>());
            }

            session.OnRegistered(Request, session, this);

            AuthEvents?.OnRegistered(Request, session, this);
            if (response == null)
            {
                response = new CreateUserDataReponse
                {
                    UserId      = user.Id.ToString(CultureInfo.InvariantCulture),
                    ReferrerUrl = request.Continue,
                    UserName    = session.UserName,
                };
            }

            var isHtml = Request.ResponseContentType.MatchesContentType(MimeTypes.Html);

            if (!isHtml)
            {
                return new CreateUserReponse()
                       {
                           Status = (int)CommonStatus.Success,
                           Data   = response
                       }
            }
            ;
            if (string.IsNullOrEmpty(request.Continue))
            {
                return(response);
            }

            return(new HttpResult(response)
            {
                Location = request.Continue
            });
        }
Пример #12
0
        public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
        {
            if (Page == null && pagePath != null)
            {
                var pages = httpReq.TryResolve <ISharpPages>();
                Page = pages.GetPage(pagePath)
                       ?? throw new FileNotFoundException($"Template Page not found '{pagePath}'");

                if (!string.IsNullOrEmpty(layoutPath))
                {
                    LayoutPage = pages.GetPage(layoutPath)
                                 ?? throw new FileNotFoundException($"Template Page not found '{layoutPath}'");
                }
            }

            var feature = HostContext.GetPlugin <SharpPagesFeature>();

            var args = httpReq.GetTemplateRequestParams(importRequestParams: feature.ImportRequestParams);

            if (Args != null)
            {
                foreach (var entry in Args)
                {
                    args[entry.Key] = entry.Value;
                }
            }

            var pageResult = new PageResult(Page)
            {
                Args       = args,
                LayoutPage = LayoutPage,
                Model      = Model,
            };

            try
            {
                httpRes.ContentType = Page.Format.ContentType;
                if (OutputStream != null)
                {
                    await pageResult.WriteToAsync(OutputStream);
                }
                else
                {
                    // Buffering improves perf when running behind a reverse proxy (recommended for .NET Core)
                    using (var ms = MemoryStreamFactory.GetStream())
                    {
                        await pageResult.WriteToAsync(ms);

                        var response = pageResult.ReturnValue?.Result;
                        if (response != null)
                        {
                            if (response is Task <object> responseTask)
                            {
                                response = await responseTask;
                            }
                            if (response is IRawString raw)
                            {
                                response = raw.ToRawString();
                            }

                            if (response != null)
                            {
                                var httpResult = TemplateApiPagesService.ToHttpResult(pageResult, response);
                                await httpRes.WriteToResponse(httpReq, httpResult);

                                return;
                            }
                        }

                        ms.Position = 0;
                        await ms.WriteToAsync(httpRes.OutputStream);
                    }
                }
            }
            catch (Exception ex)
            {
                await Page.Format.OnViewException(pageResult, httpReq, ex);
            }
        }
Пример #13
0
        public object Post(Authenticate request)
        {
            AssertAuthProviders();

            if (ValidateFn != null)
            {
                var validationResponse = ValidateFn(this, Request.Verb, request);
                if (validationResponse != null)
                {
                    return(validationResponse);
                }
            }

            if (request.RememberMe.HasValue)
            {
                var opt = request.RememberMe.GetValueOrDefault(false)
                    ? SessionOptions.Permanent
                    : SessionOptions.Temporary;

                base.Request.AddSessionOptions(opt);
            }

            var provider = request.provider ?? AuthProviders[0].Provider;

            if (provider == CredentialsAliasProvider)
            {
                provider = CredentialsProvider;
            }

            var authProvider = GetAuthProvider(provider);

            if (authProvider == null)
            {
                throw HttpError.NotFound(ErrorMessages.UnknownAuthProviderFmt.Fmt(provider.SafeInput()));
            }

            if (LogoutAction.EqualsIgnoreCase(request.provider))
            {
                return(authProvider.Logout(this, request));
            }

            if (authProvider is IAuthWithRequest && !base.Request.IsInProcessRequest())
            {
                //IAuthWithRequest normally doesn't call Authenticate directly, but they can to return Auth Info
                //But as AuthenticateService doesn't have [Authenticate] we need to call it manually
                new AuthenticateAttribute().ExecuteAsync(base.Request, base.Response, request).Wait();
                if (base.Response.IsClosed)
                {
                    return(null);
                }
            }

            var session = this.GetSession();

            var isHtml = base.Request.ResponseContentType.MatchesContentType(MimeTypes.Html);

            try
            {
                var response = Authenticate(request, provider, session, authProvider);

                // The above Authenticate call may end an existing session and create a new one so we need
                // to refresh the current session reference.
                session = this.GetSession();

                if (request.provider == null && !session.IsAuthenticated)
                {
                    throw HttpError.Unauthorized(ErrorMessages.NotAuthenticated.Localize(Request));
                }

                var referrerUrl = request.Continue
                                  ?? session.ReferrerUrl
                                  ?? request.Continue
                                  ?? base.Request.GetQueryStringOrForm(Keywords.ReturnUrl)
                                  ?? this.Request.GetHeader(HttpHeaders.Referer)
                                  ?? authProvider.CallbackUrl;

                var manageRoles = AuthRepository as IManageRoles;

                var alreadyAuthenticated = response == null;
                response = response ?? new AuthenticateResponse {
                    UserId      = session.UserAuthId,
                    UserName    = session.UserAuthName,
                    DisplayName = session.DisplayName
                                  ?? session.UserName
                                  ?? $"{session.FirstName} {session.LastName}".Trim(),
                    SessionId   = session.Id,
                    ReferrerUrl = referrerUrl,
                };

                if (response is AuthenticateResponse authResponse)
                {
                    authResponse.ProfileUrl = authResponse.ProfileUrl ?? session.GetProfileUrl();

                    var authFeature = HostContext.GetPlugin <AuthFeature>();
                    if (authFeature?.IncludeRolesInAuthenticateResponse == true)
                    {
                        authResponse.Roles = authResponse.Roles ?? (manageRoles != null
                             ? manageRoles.GetRoles(session.UserAuthId)?.ToList()
                             : session.Roles);
                        authResponse.Permissions = authResponse.Permissions ?? (manageRoles != null
                            ? manageRoles.GetPermissions(session.UserAuthId)?.ToList()
                            : session.Permissions);
                    }

                    var authCtx = new AuthFilterContext {
                        AuthService          = this,
                        AuthProvider         = authProvider,
                        AuthRequest          = request,
                        AuthResponse         = authResponse,
                        ReferrerUrl          = referrerUrl,
                        Session              = session,
                        AlreadyAuthenticated = alreadyAuthenticated,
                        DidAuthenticate      = Request.Items.ContainsKey(Keywords.DidAuthenticate),
                    };

                    foreach (var responseFilter in AuthResponseFilters)
                    {
                        responseFilter.Execute(authCtx);
                    }

                    if (AuthResponseDecorator != null)
                    {
                        var authDecoratorResponse = AuthResponseDecorator(authCtx);
                        if (authDecoratorResponse != response)
                        {
                            return(authDecoratorResponse);
                        }
                    }
                }

                if (isHtml && request.provider != null)
                {
                    if (alreadyAuthenticated)
                    {
                        return(this.Redirect(referrerUrl.SetParam("s", "0")));
                    }

                    if (!(response is IHttpResult) && !string.IsNullOrEmpty(referrerUrl))
                    {
                        return(new HttpResult(response)
                        {
                            Location = referrerUrl
                        });
                    }
                }

                return(response);
            }
            catch (Exception ex)
            {
                if (isHtml && Request.GetErrorView() != null)
                {
                    return(ex);
                }

                if (ex is HttpError)
                {
                    var errorReferrerUrl = this.Request.GetHeader(HttpHeaders.Referer);
                    if (isHtml && errorReferrerUrl != null)
                    {
                        errorReferrerUrl = errorReferrerUrl.SetParam("f", ex.Message.Localize(Request));
                        return(HttpResult.Redirect(errorReferrerUrl));
                    }
                }

                throw;
            }
        }
        protected override void Render(HtmlTextWriter output)
        {
            var operationsPart = new TableTemplate
            {
                Title       = "Operations",
                Items       = this.OperationNames,
                ForEachItem = RenderRow
            }.ToString();

            var xsdsPart = new ListTemplate
            {
                Title            = "XSDS:",
                ListItemsIntMap  = this.Xsds,
                ListItemTemplate = @"<li><a href=""?xsd={0}"">{1}</a></li>"
            }.ToString();

            var wsdlTemplate = new StringBuilder();
            var soap11Config = MetadataConfig.GetMetadataConfig("soap11") as SoapMetadataConfig;
            var soap12Config = MetadataConfig.GetMetadataConfig("soap12") as SoapMetadataConfig;

            if (soap11Config != null || soap12Config != null)
            {
                wsdlTemplate.AppendLine("<h3>WSDLS:</h3>");
                wsdlTemplate.AppendLine("<ul>");
                if (soap11Config != null)
                {
                    wsdlTemplate.AppendFormat(
                        @"<li><a href=""{0}"">{0}</a></li>",
                        soap11Config.WsdlMetadataUri);
                }
                if (soap12Config != null)
                {
                    wsdlTemplate.AppendFormat(
                        @"<li><a href=""{0}"">{0}</a></li>",
                        soap12Config.WsdlMetadataUri);
                }
                wsdlTemplate.AppendLine("</ul>");
            }

            var metadata    = HostContext.GetPlugin <MetadataFeature>();
            var pluginLinks = metadata != null && metadata.PluginLinks.Count > 0
                ? new ListTemplate
            {
                Title            = metadata.PluginLinksTitle,
                ListItemsMap     = metadata.PluginLinks,
                ListItemTemplate = @"<li><a href=""{0}"">{1}</a></li>"
            }.ToString()
                : "";

            var debugOnlyInfo = HostContext.DebugMode && metadata != null && metadata.DebugLinks.Count > 0
                ? new ListTemplate
            {
                Title            = metadata.DebugLinksTitle,
                ListItemsMap     = metadata.DebugLinks,
                ListItemTemplate = @"<li><a href=""{0}"">{1}</a></li>"
            }.ToString()
                : "";

            var renderedTemplate = HtmlTemplates.Format(
                HtmlTemplates.GetIndexOperationsTemplate(),
                this.Title,
                this.XsdServiceTypesIndex,
                operationsPart,
                xsdsPart,
                wsdlTemplate,
                pluginLinks,
                debugOnlyInfo);

            output.Write(renderedTemplate);
        }
Пример #15
0
        public async Task <object> Any(ApiPages request)
        {
            if (string.IsNullOrEmpty(request.PageName))
            {
                throw new ArgumentNullException(nameof(request.PageName));
            }

            var parts = string.IsNullOrEmpty(request.PathInfo)
                ? TypeConstants.EmptyStringArray
                : request.PathInfo.SplitOnLast('.');

            var hasPathContentType = parts.Length > 1 && Host.ContentTypes.KnownFormats.Contains(parts[1]);
            var pathInfo           = hasPathContentType
                ? parts[0]
                : request.PathInfo;

            var pathArgs = string.IsNullOrEmpty(pathInfo)
                ? TypeConstants.EmptyStringArray
                : pathInfo.Split('/');

            parts = request.PageName.SplitOnLast('.');
            var hasPageContentType = pathArgs.Length == 0 && parts.Length > 1 && Host.ContentTypes.KnownFormats.Contains(parts[1]);
            var pageName           = hasPageContentType
                ? parts[0]
                : request.PageName;

            // Change .csv download file name
            base.Request.OperationName = pageName + (pathArgs.Length > 0 ? "_" + string.Join("_", pathArgs) : "");

            var feature = HostContext.GetPlugin <TemplatePagesFeature>();

            if (feature.ApiDefaultContentType != null &&
                !hasPathContentType &&
                !hasPageContentType &&
                base.Request.QueryString[TemplateConstants.Format] == null && base.Request.ResponseContentType == MimeTypes.Html)
            {
                base.Request.ResponseContentType = feature.ApiDefaultContentType;
            }

            var pagePath = feature.ApiPath.CombineWith(pageName).TrimStart('/');
            var page     = base.Request.GetPage(pagePath);

            if (page == null)
            {
                throw HttpError.NotFound($"No API Page was found at '{pagePath}'");
            }

            var requestArgs = base.Request.GetTemplateRequestParams();

            requestArgs[TemplateConstants.PathInfo] = request.PathInfo;
            requestArgs[TemplateConstants.PathArgs] = pathArgs;

            var pageResult = new PageResult(page)
            {
                NoLayout          = true,
                RethrowExceptions = true,
                Args = requestArgs
            };

            var discardedOutput = await pageResult.RenderToStringAsync();

            if (!pageResult.Args.TryGetValue(TemplateConstants.Return, out var response))
            {
                throw HttpError.NotFound($"The API Page did not specify a response. Use the 'return' filter to set a return value for the page.");
            }

            if (response is Task <object> responseTask)
            {
                response = await responseTask;
            }
            if (response is IRawString raw)
            {
                response = raw.ToRawString();
            }

            var httpResult = ToHttpResult(pageResult, response);

            return(httpResult);
        }
Пример #16
0
 private string GetBaseUrl(string baseUrl) => baseUrl ?? HostContext.GetPlugin <NativeTypesFeature>().MetadataTypesConfig.BaseUrl ?? Request.GetBaseUrl();
Пример #17
0
 public List <RedisHostMasterInfo> Any(GetActiveHosts req)
 {
     return(Redis.GetAll <RedisHostMasterInfo>(Redis.GetKeysByPattern("{0}:host:*".Fmt(HostContext.GetPlugin <RedisServiceDiscoveryFeature>().RedisPrefix))).Values.ToList());
 }
Пример #18
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(req, res))
            {
                return(TypeConstants.EmptyTask);
            }

            var feature = HostContext.GetPlugin <ServerEventsFeature>();

            var session = req.GetSession();

            if (feature.LimitToAuthenticatedUsers && !session.IsAuthenticated)
            {
                session.ReturnFailedAuthentication(req);
                return(TypeConstants.EmptyTask);
            }

            res.ContentType = MimeTypes.ServerSentEvents;
            res.AddHeader(HttpHeaders.CacheControl, "no-cache");
            res.ApplyGlobalResponseHeaders();
            res.UseBufferedStream = false;
            res.KeepAlive         = true;

            if (feature.OnInit != null)
            {
                feature.OnInit(req);
            }

            res.Flush();

            var serverEvents = req.TryResolve <IServerEvents>();
            var userAuthId   = session != null ? session.UserAuthId : null;
            var anonUserId   = serverEvents.GetNextSequence("anonUser");
            var userId       = userAuthId ?? ("-" + anonUserId);
            var displayName  = session.GetSafeDisplayName()
                               ?? "user" + anonUserId;

            var now            = DateTime.UtcNow;
            var subscriptionId = SessionExtensions.CreateRandomSessionId();

            //Handle both ?channel=A,B,C or ?channels=A,B,C
            var channels = new List <string>();
            var channel  = req.QueryString["channel"];

            if (!string.IsNullOrEmpty(channel))
            {
                channels.AddRange(channel.Split(','));
            }
            channel = req.QueryString["channels"];
            if (!string.IsNullOrEmpty(channel))
            {
                channels.AddRange(channel.Split(','));
            }

            if (channels.Count == 0)
            {
                channels = EventSubscription.UnknownChannel.ToList();
            }

            var subscription = new EventSubscription(res)
            {
                CreatedAt       = now,
                LastPulseAt     = now,
                Channels        = channels.ToArray(),
                SubscriptionId  = subscriptionId,
                UserId          = userId,
                UserName        = session != null ? session.UserName : null,
                DisplayName     = displayName,
                SessionId       = req.GetSessionId(),
                IsAuthenticated = session != null && session.IsAuthenticated,
                UserAddress     = req.UserHostAddress,
                OnPublish       = feature.OnPublish,
                //OnError = feature.OnError,
                Meta =
                {
                    { "userId",                           userId                                                                 },
                    { "displayName",                      displayName                                                            },
                    { "channels",                         string.Join(",", channels)                                             },
                    { AuthMetadataProvider.ProfileUrlKey, session.GetProfileUrl() ?? AuthMetadataProvider.DefaultNoProfileImgUrl },
                }
            };

            if (feature.OnCreated != null)
            {
                feature.OnCreated(subscription, req);
            }

            if (req.Response.IsClosed)
            {
                return(TypeConstants.EmptyTask); //Allow short-circuiting in OnCreated callback
            }
            var heartbeatUrl = feature.HeartbeatPath != null
                ? req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath)).AddQueryParam("id", subscriptionId)
                : null;

            var unRegisterUrl = feature.UnRegisterPath != null
                ? req.ResolveAbsoluteUrl("~/".CombineWith(feature.UnRegisterPath)).AddQueryParam("id", subscriptionId)
                : null;

            heartbeatUrl  = AddSessionParamsIfAny(heartbeatUrl, req);
            unRegisterUrl = AddSessionParamsIfAny(unRegisterUrl, req);

            subscription.ConnectArgs = new Dictionary <string, string>(subscription.Meta)
            {
                { "id", subscriptionId },
                { "unRegisterUrl", unRegisterUrl },
                { "heartbeatUrl", heartbeatUrl },
                { "updateSubscriberUrl", req.ResolveAbsoluteUrl("~/event-subscribers/" + subscriptionId) },
                { "heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) },
                { "idleTimeoutMs", ((long)feature.IdleTimeout.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
            };

            if (feature.OnConnect != null)
            {
                feature.OnConnect(subscription, subscription.ConnectArgs);
            }

            serverEvents.Register(subscription, subscription.ConnectArgs);

            var tcs = new TaskCompletionSource <bool>();

            subscription.OnDispose = _ =>
            {
                try
                {
                    res.EndHttpHandlerRequest(skipHeaders: true);
                }
                catch { }
                tcs.SetResult(true);
            };

            return(tcs.Task);
        }
Пример #19
0
        public static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto)
        {
            var validator = ValidatorCache.GetValidator(req, requestDto.GetType());
            var ruleSet   = req.Verb;

            if (validator == null)
            {
                return;
            }

            try
            {
                ValidationResult validationResult;

                if (validator.HasAsyncValidators(ruleSet))
                {
                    validationResult = await validator.ValidateAsync(
                        new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))
                    {
                        Request = req
                    });
                }
                else
                {
                    validationResult = validator.Validate(
                        new ValidationContext(requestDto, null, new MultiRuleSetValidatorSelector(ruleSet))
                    {
                        Request = req
                    });
                }

                if (validationResult.IsValid)
                {
                    return;
                }

                var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException())
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult());

                var validationFeature = HostContext.GetPlugin <ValidationFeature>();
                if (validationFeature?.ErrorResponseFilter != null)
                {
                    errorResponse = validationFeature.ErrorResponseFilter(validationResult, errorResponse);
                }

                await res.WriteToResponse(req, errorResponse);
            }
            catch (Exception ex)
            {
                var validationEx = ex.UnwrapIfSingleException();

                var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx)
                                    ?? DtoUtils.CreateErrorResponse(requestDto, validationEx);

                await res.WriteToResponse(req, errorResponse);
            }
            finally
            {
                using (validator as IDisposable) { }
            }
        }