CurrentUser from Context

Apr 23, 2013 at 1:35 AM
I am modifying the AdminMenu.cs file in the Orchard Blogs module, as it does not work for a scenario where you have multiple blog authors. Namely, if you have access to all blogs, you get menu items. If you only have access to your own blog, then singleblog is never used, so the permissions don't show any action items.

I verified this by first force the singleblog to always be the blog at index 0, then my folks with a role of Author could see a menu item for managing their own blog (albeit only with the one at index 0).

Then I decided if I could get the user from context and I could get the owner of the blog then I might be able to set singleblog to the blog that matches those criteria.

I hacked and figured a way to drill down to the Owner of the blog and I have some idea that I want to use the WorkContextAccessor to get at the CurrentUser.

Is this the right approach or am I missing something more obvious? Also, what would be the best way to get at the WorkContextAccessor from this location in the codebase.

Here is what I have so far (my stuff commented out). I do plan on cleaning up my approach to getting the owner out of the blogs with linq... this was an experimental foray.

Thanks in advance.

private void BuildMenu(NavigationItemBuilder menu) {
var blogs = _blogService.Get();

//IWorkContextAccessor workContextAccessor // not completely thought out yet....
/* get the blog owner from a particular blog entry */
//var firstBlog = blogs.ElementAt(0).ContentItem.Parts.ElementAt(3);
//var firstCommon = (Orchard.Core.Common.Models.CommonPart) firstBlog;
//var owner = firstCommon.Owner;
/**************************************************/

var blogCount = blogs.Count();
var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null;

if (blogCount > 0 && singleBlog == null) {
menu.Add(T("Manage Blogs"), "3",
item => item.Action("List", "BlogAdmin", new { area = "Orchard.Blogs" }).Permission(Permissions.MetaListBlogs));
}
else if (singleBlog != null)
menu.Add(T("Manage Blog"), "1.0",
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogId = singleBlog.Id }).Permission(Permissions.MetaListOwnBlogs));

if (singleBlog != null)
menu.Add(T("New Post"), "1.1",
item =>
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogId = singleBlog.Id }).Permission(Permissions.MetaListOwnBlogs));

menu.Add(T("New Blog"), "1.2",
item =>
item.Action("Create", "BlogAdmin", new { area = "Orchard.Blogs" }).Permission(Permissions.ManageBlogs));

}

--
Mark :)
Apr 23, 2013 at 10:59 AM
private readonly IOrchardServices orchardServices;
...
orchardServices.WorkContext.CurrentUser
and getting Owner is as simple as:
ContentItem.CommonPart.Owner
I don't think you really want to be modifying code in the core. You can create your own AdminMenu that does the functionality you need maybe?
Apr 23, 2013 at 2:29 PM
You're right that I don't WANT to be changing core. I think, in this instance, core is broken. I believe the behavior I am trying to provide should be present and the logic hints that it was intended to be present.

I was kind of putting feelers out to see if maybe it wasn't broken and I was missing something else. I don't believe so and I have read some discussion that the issue was known, but that it had been fixed... I don't see that it has been fixed.

I encourage criticism of my approach to fix this. Assuming I come up with solution that is more code than hack, I would gladly put in a pull request to have my code included in core. I have submitted one minor pull request (about 3 months ago) with tests to fix the slugification logic (core was causing a 400 Bad Request error to be thrown whenever a % was used in a title). That pull request does not ever appear to have been incorporated...


Apr 23, 2013 at 2:31 PM
Oh, I forgot one thing. It wasn't as straightforward as ContentItem.CommonPart.Owner. I had to do the weird things I did to get access to owner (at least that was what context sensitive help was telling me).


Apr 23, 2013 at 2:34 PM
And, just one final thing... in your example, I can see a problem with orchardServices (because I thought of this idea many times). Your orchardServices is never set to anything. So, that is just as productive as my trying to use IWorkContextAccessor. It is all fine a good to create an object instance, but where do I actually get the object so the instance does not reference null (without being a total hack, obviously).


Coordinator
Apr 24, 2013 at 3:11 AM
I don't understand what you think is a bug in core, but I also don't understand why you don't inject IWorkContextAccessor from the constructor of your class.
Developer
Apr 24, 2013 at 12:14 PM
Hey mlybrand - Are you saying that when you can only see one blog, it should take you straight to that blog, instead to a list of blogs?
Apr 24, 2013 at 9:40 PM
The situation we have is that we have 14 blogs. Each blog has a different author. If you set the blog author as role Author (or custom Blog Author in our case, but the same for our purposes), they do not have ManageAllBlogs permission, but only ManageOwnBlogs permission. Regardless, since there are 14 blogs, singleBlog is always null, so the code covered by ManageOwnBlogs never comes into play. That, Mr LeRoy, is why I believe this is a bug. A further bug would be when a particular author has more that one "own" blog, but I don't really care about that situation (unless it is agreed that it is a bug and people are okay with me fixing it... then I would also try to cover that case).

As far as injecting IWorkContextAccessor into the constructor of my class. What class? How does just injecting the interface help me have access to the context. I guess my skills are not such that I am able to grok how this is supposed to work. Could you point to places in the Orchard code base where this is being done to see how it might help in this situation.

I hope all of this makes sense.

Mark :)


Developer
Apr 24, 2013 at 11:25 PM
Oh I see... So you on want that method to act against blogs that use has access to? instead of doing a count against all of them... Makes sense.

Do you have a fix?
Apr 24, 2013 at 11:26 PM
I have a hack in mind. I don't know that it rises to the level of "fix" :)


Developer
Apr 24, 2013 at 11:55 PM
Whats the hack? Can you put the code here?
Apr 25, 2013 at 12:03 AM
I haven't pulled the trigger yet, since the client has not agreed to the added work (they may be willing to accept things as they are, however inelegant the user experience is). When our client gives the go-ahead, I will post my hack here. I expect it will be met with the derision it deserves. It will be inelegant in code, perhaps, but the UX should be pretty nice.

Mark :)