コード例 #1
0
        private ActionBase GetMethodBasedAction(string name, Content content, object state)
        {
            var httpContext = (HttpContext)state;
            //var odataRequest = (ODataRequest) httpContext.Items[ODataMiddleware.ODataRequestHttpContextKey];
            OperationCallingContext method;

            try
            {
                method = OperationCenter.GetMethodByRequest(content, name,
                                                            ODataMiddleware.ReadToJsonAsync(httpContext)
                                                            .GetAwaiter().GetResult(),
                                                            httpContext.Request.Query);
            }
            catch (OperationNotFoundException e)
            {
                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }
            catch (AmbiguousMatchException e)
            {
                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }

            method.HttpContext = httpContext;
            return(new ODataOperationMethodExecutor(method));
        }
コード例 #2
0
        public async Task OD_Security_SetPermissions()
        {
            await IsolatedODataTestAsync(async() =>
            {
                InstallCarContentType();
                var testRoot = CreateTestRoot("ODataTestRoot");
                var content  = Content.CreateNew("Car", testRoot, Guid.NewGuid().ToString());
                content.Save();
                var resourcePath = ODataMiddleware.GetEntityUrl(content.Path);

                // ACTION
                var response = await ODataPostAsync(
                    string.Concat("/OData.svc/", resourcePath, "/SetPermissions"),
                    "",
                    "{r:[" +
                    "{identity:\"/Root/IMS/BuiltIn/Portal/Visitor\", OpenMinor:\"allow\", Save:\"deny\"}," +
                    "{identity:\"/Root/IMS/BuiltIn/Portal/Owners\", Custom16:\"A\", Custom17:\"1\"}]}")
                               .ConfigureAwait(false);

                // ASSERT
                AssertNoError(response);
                Assert.AreEqual(0, response.Result.Length);
                Assert.AreEqual(204, response.StatusCode); // 204 No Content
            }).ConfigureAwait(false);
        }
コード例 #3
0
        public async Task OD_Middleware()
        {
            await ODataTestAsync(async() =>
            {
                // ARRANGE

                // Create HttpContext
                var httpContext     = new DefaultHttpContext();
                var request         = httpContext.Request;
                request.Path        = "/OData.svc/Root('IMS')/Name/$value";
                request.QueryString = QueryString.Empty;
                request.Method      = "GET";
                var responseStream  = httpContext.Response.Body = new MemoryStream();

                // ACTION: Simulate the aspnet framework
                // instantiate the OData with the next chain member
                var odata = new ODataMiddleware(new TestMiddleware(null).InvokeAsync);
                // call the first of the chain
                await odata.InvokeAsync(httpContext);

                // ASSERT
                // check response
                string text;
                responseStream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(responseStream))
                    text = reader.ReadToEnd();
                Assert.AreEqual("IMS", text);
                // check additional header
                var header = httpContext.Response.Headers.FirstOrDefault(h => h.Key == "Header1");
                Assert.IsNotNull(header);
                Assert.AreEqual("HeaderValue1", header.Value.ToString());
            }).ConfigureAwait(false);
        }
コード例 #4
0
        public async Task OD_Security_SetPermissions_NotPropagates()
        {
            await IsolatedODataTestAsync(async() =>
            {
                InstallCarContentType();
                var testRoot = CreateTestRoot("ODataTestRoot");
                var content  = Content.CreateNew("Folder", testRoot, Guid.NewGuid().ToString());
                content.Save();
                var folderPath     = ODataMiddleware.GetEntityUrl(content.Path);
                var folderRepoPath = content.Path;
                content            = Content.CreateNew("Car", testRoot, Guid.NewGuid().ToString());
                content.Save();
                var carRepoPath = content.Path;

                // ACTION
                var response = await ODataPostAsync(
                    $"/OData.svc/{folderPath}/SetPermissions",
                    "",
                    "{r:[{identity:\"/Root/IMS/BuiltIn/Portal/Visitor\"," +
                    " OpenMinor:\"allow\", propagates:false}]}")
                               .ConfigureAwait(false);

                // ASSERT
                AssertNoError(response);
                Assert.AreEqual(0, response.Result.Length);
                Assert.AreEqual(204, response.StatusCode);
                var folder = Node.LoadNode(folderRepoPath);
                var car    = Node.LoadNode(carRepoPath);

                Assert.IsTrue(folder.Security.HasPermission(User.Visitor as IUser, PermissionType.OpenMinor));
                Assert.IsFalse(car.Security.HasPermission(User.Visitor as IUser, PermissionType.OpenMinor));
            }).ConfigureAwait(false);
        }
コード例 #5
0
ファイル: ODataTestBase.cs プロジェクト: kuber123/sensenet
        private static async Task <ODataResponse> ODataProcessRequestAsync(string resource, string queryString,
                                                                           string requestBodyJson, string httpMethod, IConfiguration config)
        {
            var httpContext = CreateHttpContext(resource, queryString);
            var request     = httpContext.Request;

            request.Method      = httpMethod;
            request.Path        = resource;
            request.QueryString = new QueryString(queryString);
            if (requestBodyJson != null)
            {
                request.Body = CreateRequestStream(requestBodyJson);
            }

            httpContext.Response.Body = new MemoryStream();

            var odata        = new ODataMiddleware(null, config, null);
            var odataRequest = ODataRequest.Parse(httpContext);
            await odata.ProcessRequestAsync(httpContext, odataRequest).ConfigureAwait(false);

            var responseOutput = httpContext.Response.Body;

            responseOutput.Seek(0, SeekOrigin.Begin);
            string output;

            using (var reader = new StreamReader(responseOutput))
                output = await reader.ReadToEndAsync().ConfigureAwait(false);

            return(new ODataResponse {
                Result = output, StatusCode = httpContext.Response.StatusCode
            });
        }
コード例 #6
0
        public async Task OD_POST_Creation_FIX_InconsistentNameAfterCreation()
        {
            await ODataTestAsync(async() =>
            {
                InstallCarContentType();
                var testRoot = CreateTestRoot("ODataTestRoot");

                var name = "Car";

                // ACTION
                var names = new string[3];
                for (int i = 0; i < 3; i++)
                {
                    var response = await ODataPostAsync(
                        String.Concat("/OData.svc", ODataMiddleware.GetEntityUrl(testRoot.Path)),
                        "?metadata=no&$select=Name",
                        $@"models=[{{""__ContentType"":""Car"",""Name"":""{name}""}}]")
                                   .ConfigureAwait(false);
                    var entity = GetEntity(response);
                    names[i]   = entity.Name;
                }

                // ASSERT
                Assert.AreNotEqual(names[0], names[1]);
                Assert.AreNotEqual(names[0], names[2]);
                Assert.AreNotEqual(names[1], names[2]);
            });
        }
コード例 #7
0
        private ActionBase GetMethodBasedAction(string name, Content content, object state)
        {
            var httpContext = (HttpContext)state;
            OperationCallingContext method;

            try
            {
                //TODO:~ Combine request body and querystring parameters into the 3th parameter.
                method = OperationCenter.GetMethodByRequest(content, name,
                                                            ODataMiddleware.Read(httpContext.Request.Body));
            }
            catch (OperationNotFoundException e)
            {
                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }
            catch (AmbiguousMatchException e)
            {
                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }

            method.HttpContext = httpContext;
            return(new ODataOperationMethodExecutor(method));
        }
コード例 #8
0
        public async Task OD_Middleware_null()
        {
            await ODataTestAsync(async() =>
            {
                // ARRANGE

                // Create HttpContext
                var httpContext     = new DefaultHttpContext();
                var request         = httpContext.Request;
                request.Host        = new HostString("example.com");
                request.Path        = "/OData.svc/Root('IMS')/Name/$value";
                request.QueryString = QueryString.Empty;
                request.Method      = "GET";
                var responseStream  = httpContext.Response.Body = new MemoryStream();

                // ACTION: Simulate the aspnet framework
                var odata = new ODataMiddleware(null, null, null);
                // call the first of the chain
                await odata.InvokeAsync(httpContext, null);

                // ASSERT
                // check response
                string text;
                responseStream.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(responseStream))
                    text = reader.ReadToEnd();
                Assert.AreEqual("IMS", text);
                // there is no additional headers
                var header = httpContext.Response.Headers.FirstOrDefault(h => h.Key == "Header1");
                Assert.IsNull(header.Key);
                Assert.AreEqual(0, header.Value.Count);
            }).ConfigureAwait(false);
        }
コード例 #9
0
ファイル: ImporterActions.cs プロジェクト: SenseNet/sensenet
        public static object Import(Content content, string path, object data)
        {
            var jData    = data as JObject;
            var imported = new ImportedContent(jData);
            var name     = imported.Name;
            var type     = imported.Type;

            JObject model = imported.Fields;

            model.Remove("Name");

            string        action;
            List <string> brokenReferences;
            var           messages      = new List <string>();
            var           targetContent = Content.Load(path);

            if (targetContent != null)
            {
                ODataMiddleware.UpdateFields(targetContent, model, true, out brokenReferences);
                targetContent.Save();
                action = "updated";
            }
            else
            {
                var parentPath = RepositoryPath.GetParentPath(path);
                targetContent = ODataMiddleware.CreateNewContent(parentPath, type, null, name, null, false, model, true, out brokenReferences);
                action        = "created";
            }

            SetPermissions(targetContent, imported.Permissions, messages, out var retryPermissions);

            return(new { path, name, type, action, brokenReferences, retryPermissions, messages });
        }
コード例 #10
0
        // --------------------------------------------------------------------------------------------------------------- operations

        /// <summary>
        /// Handles GET operations. Parameters come from the URL or the request stream.
        /// </summary>
        internal async Task WriteGetOperationResultAsync(HttpContext httpContext, ODataRequest odataReq, IConfiguration appConfig)
        {
            var content = ODataMiddleware.LoadContentByVersionRequest(odataReq.RepositoryPath, httpContext);

            if (content == null)
            {
                throw new ContentNotFoundException(string.Format(SNSR.GetString("$Action,ErrorContentNotFound"), odataReq.RepositoryPath));
            }

            var action = ODataMiddleware.ActionResolver.GetAction(content, odataReq.Scenario, odataReq.PropertyName, null, null, httpContext, appConfig);

            if (action == null)
            {
                // check if this is a versioning action (e.g. a checkout)
                SavingAction.AssertVersioningAction(content, odataReq.PropertyName, true);

                SnTrace.System.WriteError($"OData: {odataReq.PropertyName} operation not found " +
                                          $"for content {content.Path} and user {User.Current.Username}.");

                throw new InvalidContentActionException(InvalidContentActionReason.UnknownAction, content.Path, null, odataReq.PropertyName);
            }

            if (!action.IsODataOperation)
            {
                throw new ODataException("Not an OData operation.", ODataExceptionCode.IllegalInvoke);
            }
            if (action.CausesStateChange)
            {
                throw new ODataException("OData action cannot be invoked with HTTP GET.", ODataExceptionCode.IllegalInvoke);
            }

            if (action.Forbidden || (action.GetApplication() != null && !action.GetApplication().Security.HasPermission(PermissionType.RunApplication)))
            {
                throw new InvalidContentActionException("Forbidden action: " + odataReq.PropertyName);
            }

            var response = action is ODataOperationMethodExecutor odataAction
                ? (odataAction.IsAsync ? await odataAction.ExecuteAsync(content) : action.Execute(content))
                : action.Execute(content, GetOperationParameters(action, httpContext.Request));

            if (response is Content responseAsContent)
            {
                await WriteSingleContentAsync(responseAsContent, httpContext)
                .ConfigureAwait(false);

                return;
            }

            response = ProcessOperationResponse(response, odataReq, httpContext, out var count);
            await WriteOperationResultAsync(response, httpContext, odataReq, count)
            .ConfigureAwait(false);
        }
コード例 #11
0
        internal async Task WriteMetadataAsync(HttpContext httpContext, ODataRequest req)
        {
            var content = ODataMiddleware.LoadContentByVersionRequest(req.RepositoryPath, httpContext);

            //var isRoot = content?.ContentType.IsInstaceOfOrDerivedFrom("Site") ?? true;
            var isRoot   = content == null;
            var metadata = isRoot
                ? MetaGenerator.GetMetadata()
                : MetaGenerator.GetMetadata(content, req.IsCollection);

            var mimeType = this.MimeType;

            if (mimeType != null)
            {
                httpContext.Response.ContentType = mimeType;
            }

            await WriteMetadataAsync(httpContext, metadata);
        }
コード例 #12
0
ファイル: ODataSecurityTests.cs プロジェクト: onpoc/sensenet
        public async Task OD_Security_Break()
        {
            await IsolatedODataTestAsync(async() =>
            {
                InstallCarContentType();
                var testRoot = CreateTestRoot("ODataTestRoot");
                var content  = Content.CreateNew("Car", testRoot, Guid.NewGuid().ToString());
                content.Save();
                var resourcePath = ODataMiddleware.GetEntityUrl(content.Path);

                // ACTION 1: Break
                var response = await ODataPostAsync(
                    $"/OData.svc/{resourcePath}/SetPermissions",
                    "",
                    "{inheritance:\"break\"}")
                               .ConfigureAwait(false);

                // ASSERT 1: Not inherited
                AssertNoError(response);
                var entity = GetEntity(response);
                Assert.AreEqual(content.Id, entity.Id);
                Assert.AreEqual(200, response.StatusCode);
                var node = Node.LoadNode(content.Id);
                Assert.IsFalse(node.Security.IsInherited);

                // ACTION 2: Unbreak
                response = await ODataPostAsync(
                    $"/OData.svc/{resourcePath}/SetPermissions",
                    "",
                    "{inheritance:\"unbreak\"}")
                           .ConfigureAwait(false);

                // ASSERT 2: Inherited
                AssertNoError(response);
                entity = GetEntity(response);
                Assert.AreEqual(content.Id, entity.Id);
                Assert.AreEqual(200, response.StatusCode);
                node = Node.LoadNode(content.Id);
                Assert.IsTrue(node.Security.IsInherited);
            }).ConfigureAwait(false);
        }
コード例 #13
0
        private ActionBase GetMethodBasedAction(string name, Content content, object state)
        {
            var(httpContext, config) = ((HttpContext, IConfiguration))state;

            //var odataRequest = (ODataRequest) httpContext.Items[ODataMiddleware.ODataRequestHttpContextKey];
            OperationCallingContext method;

            try
            {
                method = OperationCenter.GetMethodByRequest(content, name,
                                                            ODataMiddleware.ReadToJsonAsync(httpContext)
                                                            .GetAwaiter().GetResult(),
                                                            httpContext.Request.Query);
            }
            catch (OperationNotFoundException e)
            {
                SnTrace.System.WriteError($"Operation {name} not found. " +
                                          $"Content: {content.Path}, User: {User.Current.Username}");

                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }
            catch (AmbiguousMatchException e)
            {
                SnTrace.System.WriteError($"Operation {name} is ambiguous. " +
                                          $"Content: {content.Path}, User: {User.Current.Username}");

                throw new InvalidContentActionException(e, InvalidContentActionReason.UnknownAction, content.Path,
                                                        e.Message, name);
            }
            catch (Exception ex)
            {
                SnTrace.System.WriteError($"Error during discovery of method {name}. {ex.Message} " +
                                          $"Content: {content.Path}, User: {User.Current.Username}");
                throw;
            }

            method.HttpContext = httpContext;
            method.ApplicationConfiguration = config;
            return(new ODataOperationMethodExecutor(method));
        }
コード例 #14
0
        /// <summary>
        /// Handles POST operations. Parameters come from request stream.
        /// </summary>
        internal async Task WritePostOperationResultAsync(HttpContext httpContext, ODataRequest odataReq, IConfiguration appConfig)
        {
            var content = ODataMiddleware.LoadContentByVersionRequest(odataReq.RepositoryPath, httpContext);

            if (content == null)
            {
                throw new ContentNotFoundException(string.Format(SNSR.GetString("$Action,ErrorContentNotFound"), odataReq.RepositoryPath));
            }

            var action = ODataMiddleware.ActionResolver.GetAction(content, odataReq.Scenario, odataReq.PropertyName, null, null, httpContext, appConfig);

            if (action == null)
            {
                // check if this is a versioning action (e.g. a checkout)
                SavingAction.AssertVersioningAction(content, odataReq.PropertyName, true);

                throw new InvalidContentActionException(InvalidContentActionReason.UnknownAction, content.Path, null, odataReq.PropertyName);
            }

            if (action.Forbidden || (action.GetApplication() != null && !action.GetApplication().Security.HasPermission(PermissionType.RunApplication)))
            {
                throw new InvalidContentActionException("Forbidden action: " + odataReq.PropertyName);
            }

            var response = action is ODataOperationMethodExecutor odataAction
            ? (odataAction.IsAsync ? await odataAction.ExecuteAsync(content) : action.Execute(content))
            : action.Execute(content, await GetOperationParametersAsync(action, httpContext, odataReq));

            if (response is Content responseAsContent)
            {
                await WriteSingleContentAsync(responseAsContent, httpContext)
                .ConfigureAwait(false);

                return;
            }

            response = ProcessOperationResponse(response, odataReq, httpContext, out var count);
            await WriteOperationResultAsync(response, httpContext, odataReq, count)
            .ConfigureAwait(false);
        }
コード例 #15
0
ファイル: ODataTestBase.cs プロジェクト: kuber123/sensenet
        internal static async Task <HttpContext> ODataProcessRequestEmptyResponseAsync(string resource, string queryString,
                                                                                       string requestBodyJson, string httpMethod, IConfiguration config)
        {
            var httpContext = CreateHttpContext(resource, queryString);
            var request     = httpContext.Request;

            request.Method      = httpMethod;
            request.Path        = resource;
            request.QueryString = new QueryString(queryString);
            if (requestBodyJson != null)
            {
                request.Body = CreateRequestStream(requestBodyJson);
            }

            //httpContext.Response.Body = new MemoryStream();

            var odata        = new ODataMiddleware(null, config, null);
            var odataRequest = ODataRequest.Parse(httpContext);
            await odata.ProcessRequestAsync(httpContext, odataRequest).ConfigureAwait(false);

            return(httpContext);
        }
コード例 #16
0
ファイル: ODataTestBase.cs プロジェクト: pianomanx/sensenet
        private async Task ODataTestAsync(IUser user, Action <RepositoryBuilder> initialize, Func <Task> callback)
        {
            Providers.Instance.ResetBlobProviders();

            OnTestInitialize();

            var builder = base.CreateRepositoryBuilderForTestInstance(); //CreateRepositoryBuilder();

            //UNDONE:<?:   do not call discovery and providers setting in the static ctor of ODataMiddleware
            var _ = new ODataMiddleware(null, null, null); // Ensure running the first-touch discover in the static ctor

            OperationCenter.Operations.Clear();
            OperationCenter.Discover();
            Providers.Instance.SetProvider(typeof(IOperationMethodStorage), new OperationMethodStorage());

            initialize?.Invoke(builder);

            Indexing.IsOuterSearchEngineEnabled = true;

            Cache.Reset();
            ResetContentTypeManager();

            using (var repo = Repository.Start(builder))
            {
                User.Current = user ?? User.Administrator;
                if (user == null)
                {
                    User.Current = User.Administrator;
                    using (new SystemAccount())
                        await callback().ConfigureAwait(false);
                }
                else
                {
                    User.Current = user;
                    await callback().ConfigureAwait(false);
                }
            }
        }
コード例 #17
0
        private async Task <object[]> GetOperationParametersAsync(ActionBase action,
                                                                  HttpContext httpContext, ODataRequest odataRequest)
        {
            if (action.ActionParameters.Length == 0)
            {
                return(ActionParameter.EmptyValues);
            }

            var inputStream = httpContext?.Request?.Body;
            var values      = new object[action.ActionParameters.Length];

            var parameters = action.ActionParameters;

            if (parameters.Length == 1 && parameters[0].Name == null)
            {
                var parameter = parameters[0];
                if (parameter.Type == null)
                {
                    using (var reader = new StreamReader(inputStream))
                        values[0] = reader.ReadToEnd();
                    if (parameter.Required && values[0] == null)
                    {
                        // ReSharper disable once NotResolvedInText
                        throw new ArgumentNullException("[unnamed]", "Request parameter is required.");
                    }
                }
                else
                {
                    values[0] = ODataMiddleware.Read(inputStream, parameter.Type);
                    if (parameter.Required && values[0] == null)
                    {
                        // ReSharper disable once NotResolvedInText
                        throw new ArgumentNullException("[unnamed]", "Request parameter is required. Type: " + parameter.Type.FullName);
                    }
                }
            }
            else
            {
                var model = await ODataMiddleware.ReadToJsonAsync(httpContext);

                var i = 0;
                foreach (var parameter in parameters)
                {
                    var name = parameter.Name;
                    var type = parameter.Type;
                    if (type == typeof(HttpContext))
                    {
                        values[i] = httpContext;
                    }
                    else if (type == typeof(ODataRequest))
                    {
                        values[i] = odataRequest;
                    }
                    else
                    {
                        var val = model?[name];
                        if (val == null)
                        {
                            if (parameter.Required)
                            {
                                throw new ArgumentNullException(parameter.Name);
                            }
                            values[i] = Type.Missing;
                        }
                        else
                        {
                            var valStr = val.ToString();

                            if (type == typeof(string))
                            {
                                values[i] = valStr;
                            }
                            else if (type == typeof(Boolean))
                            {
                                // we handle "True", "true" and "1" as boolean true values
                                values[i] = JsonConvert.DeserializeObject(valStr.ToLower(), type);
                            }
                            else if (type.IsEnum)
                            {
                                values[i] = Enum.Parse(type, valStr, true);
                            }
                            else
                            {
                                values[i] = JsonConvert.DeserializeObject(valStr, type);
                            }
                        }
                    }
                    i++;
                }
            }
            return(values);
        }
コード例 #18
0
        internal async Task WriteContentPropertyAsync(string path, string propertyName, bool rawValue, HttpContext httpContext, ODataRequest req, IConfiguration appConfig)
        {
            var content = ODataMiddleware.LoadContentByVersionRequest(path, httpContext);

            if (content == null)
            {
                ODataMiddleware.ContentNotFound(httpContext);
                return;
            }

            if (propertyName == ODataMiddleware.ActionsPropertyName)
            {
                var actionItems = ODataTools.GetActionItems(content, req, httpContext).ToArray();
                await WriteActionsAsync(actionItems, httpContext, req);

                return;
            }
            if (propertyName == ODataMiddleware.ChildrenPropertyName)
            {
                await WriteChildrenCollectionAsync(path, httpContext, req)
                .ConfigureAwait(false);
            }

            if (content.Fields.TryGetValue(propertyName, out var field))
            {
                if (field is ReferenceField refField)
                {
                    var refFieldSetting = refField.FieldSetting as ReferenceFieldSetting;
                    var isMultiRef      = true;
                    if (refFieldSetting != null)
                    {
                        isMultiRef = refFieldSetting.AllowMultiple == true;
                    }
                    if (isMultiRef)
                    {
                        await WriteMultiRefContentsAsync(refField.GetData(), httpContext, req)
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        await WriteSingleRefContentAsync(refField.GetData(), httpContext)
                        .ConfigureAwait(false);
                    }
                }
                else if (field is AllowedChildTypesField actField)
                {
                    await WriteMultiRefContentsAsync(actField.GetData(), httpContext, req)
                    .ConfigureAwait(false);
                }
                else if (!rawValue)
                {
                    await WriteSingleContentAsync(httpContext, new ODataEntity { { propertyName, field.GetData() } })
                    .ConfigureAwait(false);
                }
                else
                {
                    await WriteRawAsync(field.GetData(), httpContext)
                    .ConfigureAwait(false);
                }
            }
            else
            {
                await WriteGetOperationResultAsync(httpContext, req, appConfig)
                .ConfigureAwait(false);
            }
        }