public static bool HasRequiredPermissions(Application app, NodeHead contextHead) { if (app == null) { return(true); } var perms = GetRequiredPermissions(app); return(perms.All(permType => SecurityHandler.HasPermission(contextHead, permType) && (!app.DeepPermissionCheck || SecurityHandler.HasSubTreePermission(contextHead, permType)))); }
public override void AssertPermissions() { var isOwner = TargetNode.CreatorId == User.Current.Id; if (!SecurityHandler.HasPermission(TargetNode, PermissionType.See)) { base.ThrowNotFound(); } if (!SecurityHandler.HasPermission(TargetNode, PermissionType.Open)) { base.ThrowForbidden(); } }
public static string[] GetProtectedPaths(Content content) { var permitted = ContentProtector.GetProtectedPaths() .Where(x => { var head = NodeHead.Get(x); return(head != null && SecurityHandler.HasPermission( User.Current, head.Id, PermissionType.See)); }) .ToArray(); return(permitted); }
protected override Node GetContextNode() { if (!string.IsNullOrEmpty(this.KPIDataSource)) { var sourcePath = RepositoryPath.Combine(kpiSourcePath, this.KPIDataSource); var sourceHead = NodeHead.Get(sourcePath); return(!SecurityHandler.HasPermission(sourceHead, PermissionType.See) ? null : Node.LoadNode(sourceHead)); } return(null); }
public static SnIdentity Create(int nodeId) { Node node = null; using (new SystemAccount()) node = Node.LoadNode(nodeId); if (node == null || !SecurityHandler.HasPermission(node, PermissionType.See)) { node = Node.LoadNode(Identifiers.SomebodyUserId); } string name = node.Name; SnIdentityKind kind = SnIdentityKind.User; var nodeAsUser = node as IUser; if (nodeAsUser != null) { name = nodeAsUser.FullName; kind = SnIdentityKind.User; } else { var nodeAsGroup = node as IGroup; if (nodeAsGroup != null) { kind = SnIdentityKind.Group; } else { var nodeAsOrgUnit = node as IOrganizationalUnit; if (nodeAsOrgUnit != null) { kind = SnIdentityKind.OrganizationalUnit; } else { throw new ApplicationException(String.Concat("Cannot create SnIdentity from NodeType ", Providers.Instance.StorageSchema.NodeTypes.GetItemById(node.NodeTypeId).Name, ". Path: ", node.Path)); } } } return(new SnIdentity { NodeId = node.Id, Path = node.Path, Name = name, Kind = kind }); }
private Control CreateViewControl(string path) { if (!string.IsNullOrEmpty(path)) { // only display the view if the user has permissions for it var viewHead = NodeHead.Get(path); if (viewHead != null && SecurityHandler.HasPermission(viewHead, PermissionType.RunApplication)) { return(Page.LoadControl(path)); } } return(new Control()); }
private void SetActualParent(Node actualNode, int index) { _actualNodeLevel = index; switch (StartBindTarget) { case Portlets.StartBindTarget.CurrentSite: if (actualNode.NodeType.IsInstaceOfOrDerivedFrom("Site")) { return; } break; case Portlets.StartBindTarget.CurrentList: if (PortalContext.Current.ContentList != null && actualNode.Path == PortalContext.Current.ContentList.Path) { return; } break; case Portlets.StartBindTarget.CurrentWorkspace: if (PortalContext.Current.ContextWorkspace != null && actualNode.Path == PortalContext.Current.ContextWorkspace.Path) { return; } break; default: break; } var parentHead = NodeHead.Get(actualNode.ParentId); var parent = parentHead == null ? null : SecurityHandler.HasPermission(parentHead, PermissionType.See, PermissionType.Open) ? actualNode.Parent : null; if (parent != null) { index++; _pathNodeList.Add(parent); SetActualParent(parent, index); } else { return; } }
private bool IsPermitted(int?contentId) { if (contentId == null) { return(true); } try { return(SecurityHandler.HasPermission(User.Current, contentId.Value, PermissionType.Open)); } catch (EntityNotFoundException) { return(false); } }
public override bool CheckPermission() { if (!base.CheckPermission()) { return(false); } if (HttpHandlerNode != null) { if (!SecurityHandler.HasPermission(HttpHandlerNode, PermissionType.RunApplication)) { return(false); } } return(true); }
internal static File LoadViewWithPermissions(string viewPath) { var viewHead = NodeHead.Get(viewPath); if (viewHead != null && SecurityHandler.HasPermission(viewHead, PermissionType.RunApplication)) { // elevation: we have to serve the view, if the user has run // application for it, even if no Open permission is given using (new SystemAccount()) { return(Node.LoadNode(viewHead) as File); } } return(null); }
public override bool CheckPermission() { if (!base.CheckPermission()) { return(false); } //content that serve themselves as IHttpHandlers - e.g. images - do not require a Run application permission if (HttpHandlerNode != null && (TargetNode != null && TargetNode.Id != HttpHandlerNode.Id)) { if (!SecurityHandler.HasPermission(HttpHandlerNode, PermissionType.RunApplication)) { return(false); } } return(true); }
public void InitialData_FW_Permissions_Apply() { var initialData = new InitialData { Permissions = new List <string> { "+6|Normal|-6:_______________________________________________________________+", "-1000|Normal|+6:_______________________________________________________________+", } }; InitialSecurityDataTest(() => { var mask = PermissionType.GetPermissionMask(PermissionType.BuiltInPermissionTypes); SecurityHandler.CreateAclEditor() .RemoveExplicitEntries(2) .RemoveExplicitEntries(6) .RemoveExplicitEntries(1000) .Set(2, 7, false, mask, 0UL) .Apply(); // PRECHECKS // Administrators group has 1 entry on the Root. Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count); // Visitor has no any permission. Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See)); Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 1000, PermissionType.See)); // There is no break. Assert.IsTrue(SecurityHandler.IsEntityInherited(6)); Assert.IsTrue(SecurityHandler.IsEntityInherited(1000)); // ACTION SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData); // ASSERT // Administrators group has an entry on the Root. Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count); // Visitor has See permission on both contents. Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See)); Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 1000, PermissionType.See)); // The second content is not inherited. Assert.IsTrue(SecurityHandler.IsEntityInherited(6)); Assert.IsFalse(SecurityHandler.IsEntityInherited(1000)); }); }
protected override bool UserAuthorized(IPrincipal user) { var princ = user as PortalPrincipal; if (princ?.Identity == null) { return(false); } if (!princ.Identity.IsAuthenticated) { return(false); } var permissionHead = NodeHead.Get(PermissionPlaceholderPath + HubType.Name); return(permissionHead != null && SecurityHandler.HasPermission(permissionHead, PermissionType.RunApplication)); }
public static void TakeOwnership(Content content, string userOrGroup) { if (content == null) { throw new ArgumentNullException("content"); } Content target = null; if (!String.IsNullOrEmpty(userOrGroup)) { target = Content.LoadByIdOrPath(userOrGroup); if (target == null) { throw new ArgumentException("The parameter cannot be recognized as a path or an Id: " + userOrGroup); } } if (SecurityHandler.HasPermission(content.Id, PermissionType.TakeOwnership)) { if (target == null) { // if the input string was null or empty content["Owner"] = User.Current; } else { if (target.ContentHandler is Group) { content["Owner"] = target.ContentHandler as Group; } else if (target.ContentHandler is User) { content["Owner"] = target.ContentHandler as User; } else { throw new ArgumentException("The parameter cannot be recognized as a User or a Group: " + userOrGroup); } } content.Save(); } }
/// <summary> /// Gets the model. /// </summary> /// <returns></returns> protected override object GetModel() { var managerHead = NodeHead.Get(FirstManager); if (managerHead == null) { throw new NotSupportedException(ResourceManager.Current.GetString("OrganizationChart", "NoSuchManagerError")); } var resultXml = new XmlDocument(); if (!SecurityHandler.HasPermission(managerHead, PermissionType.Open)) { return(resultXml); } var manager = Content.Load(FirstManager); if (manager == null) { throw new NotSupportedException(ResourceManager.Current.GetString("OrganizationChart", "NoSuchManagerError")); } var managerStream = manager.GetXml(true); resultXml.Load(managerStream); _usedNodeId = new List <int> { manager.Id }; try { GetEmployees(manager, resultXml.SelectSingleNode("/Content"), 1); } catch (Exception ex) { Logger.WriteException(ex); throw new NotSupportedException(ex.Message); } return(resultXml); }
public static SnIdentity Create(int nodeId) { Node node; using (new SystemAccount()) node = Node.LoadNode(nodeId); if (node == null || !SecurityHandler.HasPermission(node, PermissionType.See)) { node = User.Somebody; } string name = node.Name; SnIdentityKind kind; switch (node) { case IUser nodeAsUser: name = nodeAsUser.FullName; kind = SnIdentityKind.User; break; case IGroup _: kind = SnIdentityKind.Group; break; case IOrganizationalUnit _: kind = SnIdentityKind.OrganizationalUnit; break; default: throw new ApplicationException(string.Concat("Cannot create SnIdentity from NodeType ", Providers.Instance.StorageSchema.NodeTypes.GetItemById(node.NodeTypeId).Name, ". Path: ", node.Path)); } return(new SnIdentity { NodeId = node.Id, Path = node.Path, Name = name, Kind = kind }); }
public int GetPermittedCount() { var userId = SenseNet.ContentRepository.Storage.Security.AccessProvider.Current.GetCurrentUser().Id; if (userId < 0) { return(IdCount); } int count = 0; foreach (var head in new NodeHeadResolver(RawData)) { if (SecurityHandler.HasPermission(head, PermissionType.See)) { count++; } } return(count); }
private static object[] GetNodeInternal(string parentPath, bool simpleContent = false) { Node node = null; if (parentPath == Repository.RootPath || parentPath == RepositoryStructure.ImsFolderPath) { // Elevation: Root and IMS should be accessible through this service // (the user already passed the feature permission check). using (new SystemAccount()) { node = Node.LoadNode(parentPath); } } else { var head = NodeHead.Get(parentPath); if (head != null && SecurityHandler.HasPermission(head, PermissionType.Open)) { node = Node.LoadNode(head); } } if (node == null) { throw new ArgumentNullException("parentPath"); } if (simpleContent) { return(new List <cs.SimpleServiceContent> { new cs.SimpleServiceContent(node) }.ToArray()); } else { return(new List <cs.Content> { new cs.Content(node, true, false, false, false, 0, 0) }.ToArray()); } }
private void SetControls() { var contextNode = PortalContext.Current.ContextNode; foreach (var templateName in templateNames) { var templateNode = contextNode.GetReference <Node>(string.Concat(templateName, "Page")); if (templateNode == null) { continue; } var templateContent = ContentRepository.Content.Create(templateNode); var placeHolder = this.FindControlRecursive(string.Concat("ph", templateName)); var pageContentView = contextNode.GetReference <Node>("PageContentView").Path; var contentView = ContentView.Create(templateContent, this.Page, ViewMode.Browse, pageContentView); if (placeHolder == null || contentView == null) { continue; } placeHolder.Controls.Clear(); placeHolder.Controls.Add(contentView); var btnEdit = this.FindControlRecursive(string.Concat("btnEdit", templateName)) as Button; if (btnEdit == null) { continue; } if (SecurityHandler.HasPermission(contextNode, new[] { PermissionType.AddNew, PermissionType.Save }) && SecurityHandler.HasPermission(templateNode, PermissionType.Save)) { btnEdit.Visible = true; } } }
public static List <string> GetGetContentPickerRootPathList(string path) { var pathList = new List <string>(); var contentHead = NodeHead.Get(path); var parentPath = string.Empty; // add the highest reachable parent while (contentHead != null) { var parent = NodeHead.Get(contentHead.ParentId); if (parent == null || !SecurityHandler.HasPermission(parent, PermissionType.See)) { parentPath = contentHead.Path; break; } contentHead = parent; } if (!string.IsNullOrEmpty(parentPath) && !pathList.Contains(parentPath)) { pathList.Add(parentPath); } // add site path //var site = PortalContext.GetSiteByNodePath(path); //if (site != null && !pathList.Contains(site.Path)) // pathList.Add(site.Path); // add root if (!pathList.Contains(Repository.RootPath)) { pathList.Add(Repository.RootPath); } return(pathList); }
protected override bool UserAuthorized(System.Security.Principal.IPrincipal user) { var princ = user as PortalPrincipal; if (princ == null || princ.Identity == null) { throw new ArgumentNullException("user"); } if (!princ.Identity.IsAuthenticated) { return(false); } var permissionHead = NodeHead.Get(PermissionPlaceholderPath + HubType.Name); if (permissionHead != null && SecurityHandler.HasPermission(permissionHead, PermissionType.RunApplication)) { return(true); } return(false); }
void VotingItemNewContentViewUserAction(object sender, UserActionEventArgs e) { // If the button's action is not Save if (e.ActionName != "Save") { return; } if (!SecurityHandler.HasPermission(e.ContentView.ContentHandler, PermissionType.AddNew)) { e.ContentView.ContentException = new Exception("You do not have the appropriate permissions to answer this question."); return; } e.ContentView.UpdateContent(); if (e.ContentView.Content.IsValid) { e.ContentView.Content.Save(); Controls.Clear(); ChildControlsCreated = false; _myState = "ThankYouView"; } }
private static bool HasPermission(Subscription subscription, Event @event) { if (@event == null || string.IsNullOrEmpty(@event.ContentPath) || subscription == null || subscription.User == null) { return(false); } var head = NodeHead.Get(@event.ContentPath); if (head == null) { return(false); } if (@event.NotificationType == NotificationType.MinorVersionModified) { return(SecurityHandler.HasPermission(subscription.User, head.Id, PermissionType.OpenMinor)); } else { return(SecurityHandler.HasPermission(subscription.User, head.Id, PermissionType.Open)); } }
public void InitialData_Permissions_Apply() { var initialData = new InitialData { Permissions = new List <string> { "+6|Normal|-6:_______________________________________________________________+", "-1113|Normal|+6:_______________________________________________________________+", } }; InitialSecurityDataTest(() => { // PRECHECKS // Administrators group has 1 entry on the Root. Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count); // Visitor has no any permission. Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See)); Assert.IsFalse(SecurityHandler.HasPermission(User.Visitor, 1113, PermissionType.See)); // There is no break. Assert.IsTrue(SecurityHandler.IsEntityInherited(6)); Assert.IsTrue(SecurityHandler.IsEntityInherited(1113)); // ACTION SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData); // ASSERT // Administrators group has an entry on the Root. Assert.AreEqual(1, SecurityHandler.GetExplicitEntries(2, new[] { 7 }).Count); // Visitor has See permission on both contents. Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 6, PermissionType.See)); Assert.IsTrue(SecurityHandler.HasPermission(User.Visitor, 1113, PermissionType.See)); // The second content is not inherited. Assert.IsTrue(SecurityHandler.IsEntityInherited(6)); Assert.IsFalse(SecurityHandler.IsEntityInherited(1113)); }); }
public PreviewComment(PreviewCommentData data) { Data = data; // Workaround: we only have a domain\username information here that cannot be used // to load a node head. We have to try to load the whole user node in elevated mode // and check for permissions after. var caller = AccessProvider.Current.GetOriginalUser(); var user = SystemAccount.Execute(() => string.IsNullOrEmpty(data.CreatedBy) ? null : User.Load(data.CreatedBy)); if (user == null || !SecurityHandler.HasPermission(caller, user.Id, PermissionType.Open)) { user = User.Somebody; } CreatedBy = new PreviewCommentUser { Id = user.Id, Path = user.Path, Username = user.Username, DisplayName = user.DisplayName, AvatarUrl = user.AvatarUrl }; }
public async Task OD_Security_HasPermission_Administrator() { await IsolatedODataTestAsync(async() => { SecurityHandler.CreateAclEditor() .Allow(Repository.Root.Id, Group.Administrators.Id, false, PermissionType.Open) .Allow(Repository.Root.Id, Group.Administrators.Id, false, PermissionType.Save) .Apply(); var hasPermission = SecurityHandler.HasPermission( User.Administrator, Group.Administrators, PermissionType.Open, PermissionType.Save); Assert.IsTrue(hasPermission); // ACTION var response = await ODataPostAsync( "/OData.svc/Root/IMS/BuiltIn/Portal('Administrators')/HasPermission", "", $"{{user:\"{User.Administrator.Path}\", permissions:[\"Open\",\"Save\"] }}") .ConfigureAwait(false); // ASSERT Assert.AreEqual("true", response.Result); }).ConfigureAwait(false); }
private bool IsReachedEndpoint(Node current) { if (current.ParentId == 0) { return(true); } if (!SecurityHandler.HasPermission(current.ParentId, PermissionType.See)) { return(true); } var endPoint = GetStartBindingRoot(); if (endPoint != null) { if ((!ShowFirstElement && current.Parent.Id == endPoint.Id) || (ShowFirstElement && endPoint.Id == current.Id)) { return(true); } } return(false); }
public void ProcessRequest(HttpContext context, string httpMethod, Stream inputStream) { ODataRequest odataReq = null; ODataFormatter formatter = null; var portalContext = (PortalContext)context.Items[PortalContext.CONTEXT_ITEM_KEY]; try { Content content; Exception requestError = null; try { odataReq = ODataRequest.Parse(portalContext.RequestedUri.GetComponents(UriComponents.Path, UriFormat.Unescaped), portalContext); this.ODataRequest = odataReq; } catch (Exception e) { requestError = e; } formatter = ODataFormatter.Create(portalContext, odataReq); if (formatter == null) { formatter = ODataFormatter.Create("json", portalContext); throw new ODataException(ODataExceptionCode.InvalidFormatParameter); } if (requestError != null) { var innerOdataError = requestError as ODataException; var message = "An error occured during request parsing. " + requestError.Message + " See inner exception for details."; var code = innerOdataError == null ? ODataExceptionCode.RequestError : innerOdataError.ODataExceptionCode; throw new ODataException(message, code, requestError); } odataReq.Format = formatter.FormatName; formatter.Initialize(odataReq); // Cross-Origin Resource Sharing (CORS) // Do this after the formatter was initialized to be able to provide a proper error message. HttpHeaderTools.AssertOriginHeader(); var exists = Node.Exists(odataReq.RepositoryPath); if (httpMethod != "POST" && !exists) { ContentNotFound(context, odataReq.RepositoryPath); return; } JObject model = null; switch (httpMethod) { case "GET": if (odataReq.IsServiceDocumentRequest) { formatter.WriteServiceDocument(portalContext, odataReq); } else if (odataReq.IsMetadataRequest) { formatter.WriteMetadata(context, odataReq); } else { if (!Node.Exists(odataReq.RepositoryPath)) { ContentNotFound(context, odataReq.RepositoryPath); } if (odataReq.HasContentQuery) { formatter.WriteQueryResult(portalContext, odataReq); } else if (odataReq.IsCollection) { formatter.WriteChildrenCollection(odataReq.RepositoryPath, portalContext, odataReq); } else if (odataReq.IsMemberRequest) { formatter.WriteContentProperty(odataReq.RepositoryPath, odataReq.PropertyName, odataReq.IsRawValueRequest, portalContext, odataReq); } else { formatter.WriteSingleContent(odataReq.RepositoryPath, portalContext); } } break; case "PUT": // update if (odataReq.IsMemberRequest) { throw new ODataException("Cannot access a member with HTTP PUT.", ODataExceptionCode.IllegalInvoke); } else { model = Read(inputStream); content = Content.Load(odataReq.RepositoryPath); ResetContent(content); UpdateContent(content, model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "MERGE": case "PATCH": // update if (odataReq.IsMemberRequest) { throw new ODataException(String.Concat("Cannot access a member with HTTP ", httpMethod, "."), ODataExceptionCode.IllegalInvoke); } else { model = Read(inputStream); content = Content.Load(odataReq.RepositoryPath); UpdateContent(content, model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "POST": // invoke an action, create content if (odataReq.IsMemberRequest) { formatter.WriteOperationResult(inputStream, portalContext, odataReq); } else { model = Read(inputStream); content = CreateContent(model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "DELETE": if (odataReq.IsMemberRequest) { throw new ODataException(String.Concat("Cannot access a member with HTTP ", httpMethod, "."), ODataExceptionCode.IllegalInvoke); } else { //model = Read(inputStream); Content.Delete(odataReq.RepositoryPath); } break; } } catch (ContentNotFoundException e) { var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e); formatter.WriteErrorResponse(context, oe); } catch (ODataException e) { if (e.HttpStatusCode == 500) { Logger.WriteException(e); } formatter.WriteErrorResponse(context, e); } catch (SecurityException e) { // In case of a visitor we should not expose the information that this content actually exists. We return // a simple 404 instead to provide exactly the same response as the regular 404, where the content // really does not exist. But do this only if the visitor really does not have permission for the // requested content (because security exception could be thrown by an action or something else too). if (odataReq != null && User.Current.Id == User.Visitor.Id) { var head = NodeHead.Get(odataReq.RepositoryPath); if (head != null && !SecurityHandler.HasPermission(head, PermissionType.Open)) { ContentNotFound(context, odataReq.RepositoryPath); return; } } var oe = new ODataException(ODataExceptionCode.NotSpecified, e); Logger.WriteException(oe); formatter.WriteErrorResponse(context, oe); } catch (InvalidContentActionException ex) { var oe = new ODataException(ODataExceptionCode.NotSpecified, ex); if (ex.Reason != InvalidContentActionReason.NotSpecified) { oe.ErrorCode = Enum.GetName(typeof(InvalidContentActionReason), ex.Reason); } // it is unnecessary to log this exception as this is not a real error //Logger.WriteException(oe); formatter.WriteErrorResponse(context, oe); } catch (Exception ex) { var oe = new ODataException(ODataExceptionCode.NotSpecified, ex); Logger.WriteException(oe); formatter.WriteErrorResponse(context, oe); } finally { context.Response.End(); } }
internal void AuthorizeRequest(HttpContext context) { PortalContext currentPortalContext = PortalContext.Current; if (currentPortalContext == null) { return; } var currentUser = context?.User.Identity as User; // deny access for visitors in case of webdav or office protocol requests, if they have no See access to the content if (currentUser != null && currentUser.Id == Identifiers.VisitorUserId && (currentPortalContext.IsOfficeProtocolRequest || currentPortalContext.IsWebdavRequest)) { if (!currentPortalContext.IsRequestedResourceExistInRepository || currentPortalContext.ContextNodeHead == null || !SecurityHandler.HasPermission(currentPortalContext.ContextNodeHead, PermissionType.See)) { AuthenticationHelper.ForceBasicAuthentication(HttpContext.Current); } } if (context == null) { return; } if (currentPortalContext.IsRequestedResourceExistInRepository) { var authMode = currentPortalContext.AuthenticationMode; if (string.IsNullOrEmpty(authMode)) { authMode = WebApplication.DefaultAuthenticationMode; } bool appPerm; if (authMode == "Forms") { appPerm = currentPortalContext.CurrentAction.CheckPermission(); } else if (authMode == "Windows") { currentPortalContext.CurrentAction.AssertPermissions(); appPerm = true; } else { throw new NotSupportedException("None authentication is not supported"); } var path = currentPortalContext.RepositoryPath; var nodeHead = NodeHead.Get(path); var permissionValue = SecurityHandler.GetPermission(nodeHead, PermissionType.Open); if (permissionValue == PermissionValue.Allowed && DocumentPreviewProvider.Current.IsPreviewOrThumbnailImage(nodeHead)) { // In case of preview images we need to make sure that they belong to a content version that // is accessible by the user (e.g. must not serve images for minor versions if the user has // access only to major versions of the content). if (!DocumentPreviewProvider.Current.IsPreviewAccessible(nodeHead)) { permissionValue = PermissionValue.Denied; } } else if (permissionValue != PermissionValue.Allowed && appPerm && DocumentPreviewProvider.Current.HasPreviewPermission(nodeHead)) { // In case Open permission is missing: check for Preview permissions. If the current Document // Preview Provider allows access to a preview, we should allow the user to access the content. permissionValue = PermissionValue.Allowed; } if (permissionValue != PermissionValue.Allowed) { if (nodeHead.Id == Identifiers.PortalRootId) { if (currentPortalContext.IsOdataRequest) { if (currentPortalContext.ODataRequest.IsMemberRequest) { permissionValue = PermissionValue.Allowed; } } } } if (permissionValue != PermissionValue.Allowed || !appPerm) { if (currentPortalContext.IsOdataRequest) { AuthenticationHelper.ThrowForbidden(); } switch (authMode) { case "Forms": if (User.Current.IsAuthenticated) { // user is authenticated, but has no permissions: return 403 context.Response.StatusCode = 403; context.Response.Flush(); context.Response.Close(); } else { // let webdav and office protocol handle authentication - in these cases redirecting to a login page makes no sense if (PortalContext.Current.IsWebdavRequest || PortalContext.Current.IsOfficeProtocolRequest) { return; } // user is not authenticated and visitor has no permissions: redirect to login page // Get the login page Url (eg. http://localhost:1315/home/login) string loginPageUrl = currentPortalContext.GetLoginPageUrl(); // Append trailing slash if (loginPageUrl != null && !loginPageUrl.EndsWith("/")) { loginPageUrl = loginPageUrl + "/"; } // Cut down the querystring (eg. drop ?Param1=value1@Param2=value2) string currentRequestUrlWithoutQueryString = currentPortalContext.RequestedUri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.Unescaped); // Append trailing slash if (!currentRequestUrlWithoutQueryString.EndsWith("/")) { currentRequestUrlWithoutQueryString = currentRequestUrlWithoutQueryString + "/"; } // Redirect to the login page, if neccessary. if (currentRequestUrlWithoutQueryString != loginPageUrl) { context.Response.Redirect(loginPageUrl + "?OriginalUrl=" + System.Web.HttpUtility.UrlEncode(currentPortalContext.RequestedUri.ToString()), true); } } break; default: AuthenticationHelper.DenyAccess(context); break; } } } }
/// <summary> /// Processes the OData web request. Designed for test purposes. /// </summary> /// <param name="context">An <see cref="HttpContext" /> object that provides references to the intrinsic server objects (for example, <see langword="Request" />, <see langword="Response" />, <see langword="Session" />, and <see langword="Server" />) used to service HTTP requests. </param> /// <param name="httpMethod">HTTP protocol method.</param> /// <param name="inputStream">Request stream containing the posted JSON object.</param> public void ProcessRequest(HttpContext context, string httpMethod, Stream inputStream) { ODataRequest odataReq = null; ODataFormatter formatter = null; var portalContext = (PortalContext)context.Items[PortalContext.CONTEXT_ITEM_KEY]; try { Content content; odataReq = portalContext.ODataRequest; if (odataReq == null) { formatter = ODataFormatter.Create("json", portalContext); throw new ODataException("The Request is not an OData request.", ODataExceptionCode.RequestError); } this.ODataRequest = portalContext.ODataRequest; Exception requestError = this.ODataRequest.RequestError; formatter = ODataFormatter.Create(portalContext, odataReq); if (formatter == null) { formatter = ODataFormatter.Create("json", portalContext); throw new ODataException(ODataExceptionCode.InvalidFormatParameter); } if (requestError != null) { var innerOdataError = requestError as ODataException; var message = "An error occured during request parsing. " + requestError.Message + " See inner exception for details."; var code = innerOdataError?.ODataExceptionCode ?? ODataExceptionCode.RequestError; throw new ODataException(message, code, requestError); } odataReq.Format = formatter.FormatName; formatter.Initialize(odataReq); var exists = Node.Exists(odataReq.RepositoryPath); if (!exists && !odataReq.IsServiceDocumentRequest && !odataReq.IsMetadataRequest && !AllowedMethodNamesWithoutContent.Contains(httpMethod)) { ContentNotFound(context, odataReq.RepositoryPath); return; } JObject model; switch (httpMethod) { case "GET": if (odataReq.IsServiceDocumentRequest) { formatter.WriteServiceDocument(portalContext, odataReq); } else if (odataReq.IsMetadataRequest) { formatter.WriteMetadata(context, odataReq); } else { if (!Node.Exists(odataReq.RepositoryPath)) { ContentNotFound(context, odataReq.RepositoryPath); } else if (odataReq.IsCollection) { formatter.WriteChildrenCollection(odataReq.RepositoryPath, portalContext, odataReq); } else if (odataReq.IsMemberRequest) { formatter.WriteContentProperty(odataReq.RepositoryPath, odataReq.PropertyName, odataReq.IsRawValueRequest, portalContext, odataReq); } else { formatter.WriteSingleContent(odataReq.RepositoryPath, portalContext); } } break; case "PUT": // update if (odataReq.IsMemberRequest) { throw new ODataException("Cannot access a member with HTTP PUT.", ODataExceptionCode.IllegalInvoke); } else { model = Read(inputStream); content = LoadContentOrVirtualChild(odataReq); if (content == null) { ContentNotFound(context, odataReq.RepositoryPath); return; } ResetContent(content); UpdateContent(content, model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "MERGE": case "PATCH": // update if (odataReq.IsMemberRequest) { throw new ODataException( String.Concat("Cannot access a member with HTTP ", httpMethod, "."), ODataExceptionCode.IllegalInvoke); } else { model = Read(inputStream); content = LoadContentOrVirtualChild(odataReq); if (content == null) { ContentNotFound(context, odataReq.RepositoryPath); return; } UpdateContent(content, model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "POST": // invoke an action, create content if (odataReq.IsMemberRequest) { formatter.WriteOperationResult(inputStream, portalContext, odataReq); } else { // parent must exist if (!Node.Exists(odataReq.RepositoryPath)) { ContentNotFound(context, odataReq.RepositoryPath); return; } model = Read(inputStream); content = CreateContent(model, odataReq); formatter.WriteSingleContent(content, portalContext); } break; case "DELETE": if (odataReq.IsMemberRequest) { throw new ODataException( String.Concat("Cannot access a member with HTTP ", httpMethod, "."), ODataExceptionCode.IllegalInvoke); } else { content = LoadContentOrVirtualChild(odataReq); content?.Delete(); } break; } } catch (ContentNotFoundException e) { var oe = new ODataException(ODataExceptionCode.ResourceNotFound, e); formatter?.WriteErrorResponse(context, oe); } catch (ODataException e) { if (e.HttpStatusCode == 500) { SnLog.WriteException(e); } formatter?.WriteErrorResponse(context, e); } catch (SenseNetSecurityException e) { // In case of a visitor we should not expose the information that this content actually exists. We return // a simple 404 instead to provide exactly the same response as the regular 404, where the content // really does not exist. But do this only if the visitor really does not have permission for the // requested content (because security exception could be thrown by an action or something else too). if (odataReq != null && User.Current.Id == Identifiers.VisitorUserId) { var head = NodeHead.Get(odataReq.RepositoryPath); if (head != null && !SecurityHandler.HasPermission(head, PermissionType.Open)) { ContentNotFound(context, odataReq.RepositoryPath); return; } } var oe = new ODataException(ODataExceptionCode.NotSpecified, e); SnLog.WriteException(oe); formatter?.WriteErrorResponse(context, oe); } catch (InvalidContentActionException ex) { var oe = new ODataException(ODataExceptionCode.NotSpecified, ex); if (ex.Reason != InvalidContentActionReason.NotSpecified) { oe.ErrorCode = Enum.GetName(typeof(InvalidContentActionReason), ex.Reason); } // it is unnecessary to log this exception as this is not a real error formatter?.WriteErrorResponse(context, oe); } catch (ContentRepository.Storage.Data.NodeAlreadyExistsException nae) { var oe = new ODataException(ODataExceptionCode.ContentAlreadyExists, nae); formatter?.WriteErrorResponse(context, oe); } catch (System.Threading.ThreadAbortException tae) { if (!context.Response.IsRequestBeingRedirected) { var oe = new ODataException(ODataExceptionCode.RequestError, tae); formatter?.WriteErrorResponse(context, oe); } // specific redirect response so do nothing } catch (Exception ex) { var oe = new ODataException(ODataExceptionCode.NotSpecified, ex); SnLog.WriteException(oe); formatter?.WriteErrorResponse(context, oe); } finally { context.Response.End(); } }