Sitecore Admin Page using MVC - sitecore

I'd like to create a page where I can login using sitecore users, something similar to what the admin pages do. But I want it to be MVC not Webforms/ASPX, is that possible? if yes, How?
Thanks in advance.

Sitecore Admin pages are like any other pages. The only thing the do before displaying content to the user, is a security check:
protected void CheckSecurity(bool isDeveloperAllowed)
{
if (Context.User.IsAdministrator)
{
return;
}
if (isDeveloperAllowed && this.IsDeveloper)
{
return;
}
SiteContext site = Context.Site;
if (site != null)
{
base.Response.Redirect(string.Format("{0}?returnUrl={1}", site.LoginPage, HttpUtility.UrlEncode(base.Request.Url.PathAndQuery)));
}
}
So if you want to create MVC page allowed only to logged in users, make sure that you include a call to that method.

Related

Sitecore: How to show or hide certain pages based on a condition?

I am using Sitecore 7.2. I wanted to show or hide certain pages based on a condition on the user.
For example, Show/Give Read access to page A only to those users whose profile field name country = 'USA' just like we do for individual component in Sitecore item.
Is there a way to do this in Sitecore?
This sounds like the Rules Engine might be a good option for you. You could add a Rules field to your page template to drive the logic.
The rule conditions to check the profile fields already exist within Sitecore, you'd just need to create your own custom logic to deny access to the page
To evaluate the rules on your page you can put some code into a pipeline processor to check the rules apply for each page. Here's an example of evaluating the rules.
public bool EvaluateRule(string fieldName, Item item)
{
var ruleContext = new RuleContext();
foreach (Rule<RuleContext> rule in RuleFactory.GetRules<RuleContext>(new[] { item }, fieldName).Rules)
{
if (rule.Condition != null)
{
var stack = new RuleStack();
rule.Condition.Evaluate(ruleContext, stack);
if (ruleContext.IsAborted)
{
continue;
}
if ((stack.Count != 0) && ((bool)stack.Pop()))
{
return true;
}
}
}
return false;
}
You could combine this with this code to deny access to the page
public class RulesProcessor : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull((object)args, "args");
if (!UserCanAccess())
{
Sitecore.Context.Item=null;
args.PermissionDenied = true;
}
}
private bool UserCanAccess()
{
EvaluateRulesLogic();
}
}
Why not using the role based permission that Sitecore supports?
So for example of each different Countries, you have the respective roles inside Sitecore and use that to define the permission to the items.
Next step would be to update the roles assigned to the user if the profile field country is updated.

Enrolling Anonymous Users in Engagement Plans

I know that it is possible to enroll users in an engagement plan from with Sitecore by adding them to a specific state in the plan when they visit a campaign URL, adding them when they submit a Web Forms for Marketers Form, and manually adding them in the Supervisor interface.
Additionally, I know that you can use the API to add a user as described here:
http://briancaos.wordpress.com/2013/06/03/programming-for-sitecore-dms-engagement-plans/
However, that method requires a username.
I would like to enroll anonymous users in an engagement plan when they visit any page represented by a particular template in Sitecore (ie, page from the Product template). Is this possible using the API?
To expand on my above comment, and to supplement your own answer, here's a processor that you could add to the after the ItemResolver in the httpRequestBegin pipeline that would achieve the desired result. It is a very basic version that you could embellish as you see fit
class CampaignRedirect
{
public void Process(HttpRequestArgs args)
{
var request = HttpContext.Current.Request;
// must not already have the querystring in the URL
if(request.QueryString["sc_camp"] != null &&
request.QueryString["sc_camp"] != "XXXXXXXX")
return;
// must have a context item
if(Sitecore.Context.Item == null)
return;
var item = Sitecore.Context.Item;
// must be the right template
if(item.TemplateID.ToString() != "{XXXXXXXXX-XXXX-XXXXXX}")
return;
var basicUrl = LinkManager.GetItemUrl(item);
var response = HttpContext.Current.Response;
response.Redirect(basicUrl + "?sc_camp=XXXXXXX");
}
}
If you're not familiar with adding processors, take a look here.
Per Sitecore support, this is not currently possible. However, I was able to achieve what I wanted by adding a jQuery AJAX call to the campaign URL to the sublayout used by the page type in question. Naturally this only works for clients with JS enabled, but for my purposes, that is not an issue.
<script type="text/javascript">$(function() { $.get('/?sc_camp=[campaignid]'); });</script>
Edited 2014-05-19
I found a way to do this via the Sitecore API. This is rough and needs to check for null values, exceptions, etc., but it does work:
string cookieVal = Request.Cookies["SC_ANALYTICS_GLOBAL_COOKIE"].Value;
List<Guid> guids = new List<Guid>() {
new Guid(cookieVal)
};
Guid automationStateId = new Guid("{24963AE9-1C8C-4E18-8EEE-01BC249D1F1B}");
Guid automationId = Sitecore.Context.Database.GetItem(new Sitecore.Data.ID(automationStateId)).ParentID.ToGuid();
Sitecore.Analytics.Automation.Data.AutomationManager.Provider.CreateAutomationStatesFromBulk(guids, automationId, automationStateId);

Login only prestashop catalog

Im building a prestashop catalog, but it needs to be visible to logged in customers only. Is this possible. It would be nice if the built in prestashop login is used for this.. any help is appreciated.
I have a suggestion. You can use the Customer Groups feature in PrestaShop 1.5 and only allow logged in customers to see the prices. For every Customer that is grouped in Visitor, they would see your website in Catalog Mode.
Prestashop 1.5 solution:
Simply upload the original file:
classes\controller\FrontController.php
into:
override/classes/controller/FrontController.php
Next, rename the class. Final code should look like this:
class FrontController extends FrontControllerCore
{
public function init()
{
parent::init();
if (!$this->context->customer->isLogged() && $this->php_self != 'authentication' && $this->php_self != 'password')
{
Tools::redirect('index.php?controller=authentication?back=my-account');
}
}
}
The last step is to manually delete the following file so prestashop is aware of the overriden class (It will be re-generated automatically):
cache/class_index.php
And voilà, functionality achieved without overwriting core files.
It'll be easy.
Use this code:
if(!self::$cookie->isLogged(true) AND in_array($this->step, array(1, 2, 3)))
Tools::redirect('authentication.php');
In the preprocess of your indexController
Here’s my solution, it works like a charm and is a very easy fix!
In classes\Configuration.php (around line 114) it looks like this
static public function get($key, $id_lang = NULL)
{
if ($id_lang AND isset(self::$_CONF_LANG[(int)$id_lang][$key]))
return self::$_CONF_LANG[(int)$id_lang][$key];
elseif (is_array(self::$_CONF) AND key_exists($key, self::$_CONF))
return self::$_CONF[$key];
return false;
}
change it to this:
static public function get($key, $id_lang = NULL)
{
//Grab access to the $cookie which is already loaded in the FrontController as global $cookie;
global $cookie;
if ($id_lang AND isset(self::$_CONF_LANG[(int)$id_lang][$key]))
return self::$_CONF_LANG[(int)$id_lang][$key];
elseif (is_array(self::$_CONF) AND key_exists($key, self::$_CONF))
//If the system is trying to find out if Catalog Mode is ON, then return the configuration setting,
//but override it with the user logon status
if($key == 'PS_CATALOG_MODE')
{
return !$cookie->logged || self::$_CONF[$key];
}
else
{
return self::$_CONF[$key];
}
return false;
}
Essentially, I wanted to force the system to display the “Catalog Mode” when the user is not logged in, and to turn this off when he is logged in.
I can guarantee this works for v1.4.3.0 and the code for the current version 1.4.8.2 (at the time of this post) has not changed, so it should work there.

Facebook's pages.isfan requires user id

Basically I would like to know if my visitor is already a fan of my Facebook Page or not.
I tried looking a while and pages.isFan is the best solution so far.
http://developers.facebook.com/docs/reference/rest/pages.isFan/
But pages.isFan need user id (uid), which I can only get if they installed or grant access to my Facebook apps.
My question is, is there a way just to get the uid of my visiting user without ask them to grant access to my Facebook apps?
This code should do the trick:
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["page"]["liked"])) {
/* Not Fan */
}
else {
/* Fan */
}
More methods can be found here: http://www.masteringapi.com/tutorials/facebook-api-check-if-a-user-is-fan-of-a-facebook-page/20/

MVC - open page in View mode

Hi
I am trying to see if anybody has a briliant idea on how to implement View mode concept in MVC. So if the user opens a page, the page should open in view mode (all controls disabled), if they dont have edit priviledges else should open as normal. Please note that the View page has partial pages as well
I think you have total control on your page under MVC framework. If you are using standard MVC method to generate input controls, you could do following ways.
#Html.TextBox("MyTextBoxID", Model==null?"":Model.MyFieldValue, new {disabled = "disabled})
If you are not using standard MVC method to generate input controls. You can create your own method to generate input controls. For example in MyExt.cs
public static class MyExt
{
public static MvcHtmlString MyTextBox(this HtmlHelper html, string id, object value)
{
// check user privilege
if (CurrentUser.CanEditThisPage /*Implement your own logic here */)
return html.TextBox(id, value);
else
return html.TextBox(id, value, new {disabled = "disabled"});
}
}
And in your page
#using MyNamespace
...
#Html.MyTextBox("MyTextBoxID", Mode==null?"":Model.MyFieldValue)
Another Way
Pass an indicator from server side to client side and using javascript or JQuery to disable all controls.
#Html.Hidden("CanEdit", CurrentUser.CanEditThisPage)
In javascript
void pageLoad() {
if ($("#CanEdit").val() == "true"))
$("input").attr("disabled", "disabled");
}
Something like that (not sure about correctness of syntax :P)