Wednesday, December 26, 2012

Lucene Search - Search All Fields in Sitecore

Recently, I was having troubled trying to figure out why I couldn't get any hits from querying a custom field that I have added programmatically onto Lucene Index. Now beside the customization I have added, I have used Sitecore Advanced Database Crawler that makes life easier working with Lucene and Sitecore.

Anyway, after digging and debugging, I found out that when searching for all Sitecore field through the index, it actually searching on 1 single field in Lucene Index. Essentially this single field in single Lucene Document contain the value of all the fields in a single Sitecore Item. This field in Lucene is called "_content"

For this reason, if I need to search both all of Sitecore fields and the additional fields I have created, I will need to modify the query to search for both "_content" and "additional fields" I have created.

Monday, November 19, 2012

Sitecore Page Editor - RTE field cant be edited

To ensure Page Editor works well in Sitecore, components will need to be coded using Sitecore controls such as 

<sc:text field='text' runat='server'>

So for example if my components html code as such below 

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="StoryResources.ascx.cs"
    Inherits="Sitecore.Web.layouts.StoryResources" %>

    <p>
<sc:text field='text' runat='server'>
    </p>


I would expect that my RTE field called 'Text' will be editable in Page Editor. Surprise surprise, it is not editable. In fact when I look at the Firebug console, there is js error. 

Thinking hard plus trial and error, found out the issue was because of the nested P tag. This is introduce when wrapping my sc:text with a P tag. Now of course being a RTE editor chances of having a P tag in it is high. This resulted into nested P. 

Further to that, I googled nested P tag to found out what happened when you nest a P tag and I found an interesting article. Below is the link 

http://cksource.com/forums/viewtopic.php?f=6&t=11870

In the article, it mentions that nested P tag will transform into unnested P tag. This transformation or invalid html cause the Page Editor to break. So to resolve this, I wrapped the sc:text with a div instead. 

Thursday, October 4, 2012

Sitecore Admin Tools (e.g. cache.aspx) not working

Recently I was tasked to figure out why tools under /sitecore/admin folder are not working. Tools such as cache clearing (cache.aspx).

Now the system is Sitecore Intranet Portal setup running on Sitecore 6.1 with multiple integration points such as Active Directory and Sharepoint. Naturally the configurations are quite many. Anyway when I am trying to access the tool it will throw an arrow as such

Server Error in '/' Application.

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[NullReferenceException: Object reference not set to an instance 
of an object.]
   Sitecore.Nexus.Web.HttpModule. (Object sender, EventArgs e) +340
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication
.IExecutionStep.Execute() +79
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& 
   completedSynchronously) +170



Version Information: Microsoft .NET Framework Version:2.0.50727.5420; ASP.NET Version:2.0.50727.5420 

Figuring out the issue, the error was caused when


<location> tag is added.

Removing it solved the problem

Monday, September 3, 2012

Filtering users by Domain in UserManager


Often we introduce a new domain in usermanager and would like to filter out the users associated to the new domain. This post will outlines how we go about achieving that.


The following outlines the steps needed to filter out users associated to unwanted domain in UserManager.
Firstly, a new class that inherit from UserManager will need to be created. The class will then override OnLoad method to filter the users. The code to achieve that is as follow
01.public class AdvancedUserManager : UserManager
02. {
03. protected override void OnLoad(EventArgs e)
04. {
05. Assert.ArgumentNotNull(e, "e");
06. base.OnLoad(e);
07. Assert.CanRunApplication("Security/User Manager");
08. var managedUsers = global::Sitecore.Context.User.Delegation.GetManagedUsers().Where(IsAllowedDomain);
09. ComponentArtGridHandler<User>.Manage(Users, new GridSource<User>(managedUsers), RebindRequired);
10. Users.LocalizeGrid();
11. }
12.
13. // Properties
14. private bool RebindRequired
15. {
16. get
17. {
18. return ((!Page.IsPostBack && (Request.QueryString["Cart_Users_Callback"] != "yes")) || (Page.Request.Params["requireRebind"] == "true"));
19. }
20. }
21.
22. private static bool IsAllowedDomain(Account user)
23. {
24. if (user.Domain == null) return false;
25. var domainToCheck = user.Domain.Name.ToLower();
26. var excludedDomain = global::Sitecore.Configuration.Settings.GetSetting("ExcludedDomainInUserManager");
27. if (string.IsNullOrEmpty(excludedDomain)) return true;
28. var domainArray = excludedDomain.Split("|".ToCharArray());
29. return domainArray.Select(domain => domain.ToLower().Equals(domainToCheck)).All(isExcludedDomain => !isExcludedDomain);
30. }
31. }
After the class has been created, we need to modify the UserManager.aspx to point to the new namespace. The path to the UserManager will be as follow
\sitecore\shell\Applications\Security\UserManager\UserManager.aspx
Overwrite the default
1.<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserManager.aspx.cs" Inherits="Sitecore.Shell.Applications.Security.UserManager.UserManager" %>
Lastly, we need to create a Sitecore Setting in config file name "ExcludedDomainInUserManager" to determine which Domain to filter.
That's it! You should now have filtered user manager. :)

Wednesday, April 11, 2012

ECM - Scheduled email is not working

Recently, I was presented an issue where email cannot be scheduled from ECM. Though test email or immediate dispatch of emails work just fine. The following set of actions will replicate the issue on the particular setup we have

  1. User creates a newsletter (any template) under target audience draft folder.
  2. User schedules dispatch the newsletter.
  3. System moves newsletter to scheduled folder.
  4. System creates a new task item.
  5. System triggers task when schedule arrives (sometimes with few minutes delay*).
  6. System moves newsletter to dispatch folder.
  7. System set the newsletter status to pause.
With the help from support team in Sitecore, the issue was resolved. Apparently the strange behavior is caused by setting EventQueue to true.

However the setup is actually a Scaled Setup where EventQueue is essential in clearing cache and also to rebuild indexes on the delivery server. For now, further test will be conducted and i will update once more information is available.

Page Editor - Unable to edit fields

Recently I encountered a puzzling situation where when I logged in to Sitecore Page Editor, I can do all the things page editor allow me to do except editing fields. It turns out that there is a checkbox that prevent editing of fields. This checkbox can be founder view ribbon and its called "Editing".

Thursday, February 2, 2012

Cancellable publishing wizard

A interesting page about cancellable publishing wizard. http://sitecoregadgets.blogspot.com.au/2011/09/advanced-publish-dialog.html

Sitecore and Cores (CPU)

I was recently intrigue to know if Sitecore utilities more than 2 core in the CPU. The answer is yes.

One of thing in Sitecore that deals with CPU Cores is Sitecore jobs. Sitecore jobs (e.g. publishing) are an abstraction of the worker thread pool. This is why jobs in Sitecore will run on any available core. This means Sitecore can run more than 2 core, hence the answer to my question.

Another note about Sitecore jobs, they cannot be canceled programmatically or at least without a substantial risk.

Tuesday, January 31, 2012

Sitecore Query and Fields

Came across a site which details nicely about sitecore query and fields that support and do not support them. http://sitecorener.com/en/Developers/ContentDisplay/SitecoreQueries/UsingSitecoreQuery.aspx

Wednesday, January 18, 2012

Securing content and media without authentication

I will explain the situation/setup first, the potential security breach and then the solution to resolve this.

The following is the setup that is required

Sitecore
*** Content
****** Internet (Site root for public site)
********* Page One
****** Intranet (Site root for intranet site)
********* Secured Page One
*** Media Library
****** Internet (Media folder for public site)
********* Media One
****** Intranet (Media folder for intranet site)
********* Secured Media One

Let's say we have the following domains for their respective sites
1. Internet site domain - http://internetWebsite.com which is public
2. Intranet site domain - http://intranetPortal.com. The client do not want to use Authentication because everyone in their network will need to have access to intranet without logging in. Hence the only IP restriction was put in place as security measure.

If you are familiar with the way url is constructed to access the page within Sitecore you will know the following scenario.

1. http://internetWebsite.com/Page One.aspx - this is used to access Internet content when site definition for internet has been setup.
2. http://internetWebsite.com/sitecore/content/internet/page one.aspx - this is also a valid url where full path is appended after the domain.
3. http://internetWebsite.com/~/media/internet/media one.ashx

From the above scenario if you have Sitecore knowledge coupled with familiarity with the Site content structure. You can access restricted content which is secured by other means than Sitecore security. In this case by IP restriction. There are two potential security breach here

First - accessing secured page,
So without tweaking Sitecore, the following URL can be used to access intranet contents

http://internetWebsite.com/sitecore/content/intranet/secured page one.aspx

There are two steps to fix the first issue:
1. Add a custom pipelines at the end of <httpRequestBegin>
2. Second is to create a class for the custom pipelines. The following is the code I have

public class DisableAbsolutePath : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
var rawUrl = args.Context.Request.RawUrl;
var isAuthenticated = Context.User.IsAuthenticated;
if (rawUrl.Contains("/sitecore/content/") && !isAuthenticated)
args.Context.Response.StatusCode = 404;
}
}

Logic is pretty simple, first I check if the url contains "/sitecore/content" and check if the user is authenticated. If both condition is not met, I throw 404 status code. The reason why I also check authentication is because I want to preserve as much as possible the default Sitecore behavior.

Second - accessing media library
The following URL can be used to access restricted media
http://internetWebsite.com/~/media/intranet/secured media one.ashx

There is a few way to solve this issue,
1. Create custom pipelines. *Note: The location of custom pipelines is not the same as page.
2. Through Sitecore security and custom domain.

We took the second approach as it is more configurable within the CMS and we can extend this in the future if the client decide to implement authentication.

1. Create a new domain called "Intranet". The setup is done via a domain.config found in app_config/include/security/domain.config.
2. Create a role called "Intranet\Frontend User" and a user called "Intranet\Intranet User"
3. Applied restriction on /sitecore/media library/intranet with the following setup
4. At the layout.aspx.cs file, I automatically login the "Intranet User" like so.

if (!Sitecore.Context.User.IsAuthenticated)

AuthenticationManager.Login("@intranet\\Intranet User");

Of course this problem will not occur if there is Authentication put in place