Forced Login

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 years ago
My customer wants that the visitor to their nopcommerce based website should see the product  catalog only after they log in.
How to enforce a login before one can view the products?
12 years ago
@if (Request.IsAuthenticated)
{
}

Try wrapping the CategoryNavigation.cshtml file in your view folders.

Or [Authorize] In the controller which is under Catalog/CategoryNavigation I think..
12 years ago
There are posts on how to do this in the category controller to block out only the catalogue. I needed something to lock users out of the whole site unless registered...

I created a partial class "BaseNopController.mycompany.cs" in Nop.Web.Controllers, as follows;


    public partial class BaseNopController
    {
        private class AllowedRoutes
        {
            public string Controller { get; set; }
            public string Action { get; set; }
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            var currentAction = filterContext.RouteData.Values["action"].ToString();
            var currentControler = filterContext.RouteData.Values["controller"].ToString();

            var allowedActions = new List<AllowedRoutes>
            {
                new AllowedRoutes {Controller = "Home", Action = "Invite"},
                new AllowedRoutes {Controller = "Customer", Action = "Login"},
                new AllowedRoutes {Controller = "Topic", Action = "TopicBlock"}
            };

            var query = from a in allowedActions
                        where a.Action == currentAction &&
                        a.Controller == currentControler
                        select a;

            var ignorePage = (query.ToList().Count > 0);

            var workContext = EngineContext.Current.Resolve<IWorkContext>();
            
            if (!workContext.CurrentCustomer.IsRegistered() && !ignorePage)
            {
                filterContext.Result = new RedirectResult(Url.Action("Invite", "Home"));
                return;
            }
        }
    }


Then I just had to create the "Invite" view (mostly just a copy of the login form) and create the "Invite" action in the controller to manage the login. Again, easiest was to create a "HomeController.mycompany.cs" file and make the NOP file a partial class.

I am not allowing registrations, but if you do, you should be able to add to the Allowed routes collection to execute the registration actions you need.
12 years ago
Thank you for sharing. Could you possibly share the controller method I need exactly the same as what you created.

I presume In the NOP index/home controller you changed it from the return the index view to your personal View??

All help highly regarded.

R
12 years ago
Yes, a very stripped down version as the base code makes calls to the catalogue, best sellers and the likes.
Controller is just a copy of the existing log in.


/* Nop.Web.Controllers/HomeController.myco.cs */
using System;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Domain.Customers;
using Nop.Services.Authentication;
using Nop.Services.Customers;
using Nop.Services.Orders;
using Nop.Web.Models.Customer;

namespace Nop.Web.Controllers
{
    public partial class HomeController
    {
        private readonly CustomerSettings _customerSettings;
        private readonly ICustomerRegistrationService _customerRegistrationService;
        private readonly ICustomerService _customerService;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IWorkContext _workContext;
        private readonly IAuthenticationService _authenticationService;

        public HomeController(CustomerSettings customerSettings, ICustomerRegistrationService customerRegistrationService, ICustomerService customerService,
            IShoppingCartService shoppingCartService, IWorkContext workContext, IAuthenticationService authenticationService)
        {
            this._customerSettings = customerSettings;
            this._customerRegistrationService = customerRegistrationService;
            this._customerService = customerService;
            this._shoppingCartService = shoppingCartService;
            this._workContext = workContext;
            this._authenticationService = authenticationService;
        }

        public ActionResult Invite(bool? checkoutAsGuest)
        {
            var model = new LoginModel();
            model.UsernamesEnabled = _customerSettings.UsernamesEnabled;
            model.CheckoutAsGuest = checkoutAsGuest.HasValue ? checkoutAsGuest.Value : false;
            return View(model);
        }

        [HttpPost]
        public ActionResult Invite(LoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                //do our own little login to prevent issue with views on failed attempts.

                if (_customerSettings.UsernamesEnabled && model.Username != null)
                {
                    model.Username = model.Username.Trim();
                }

                if (_customerRegistrationService.ValidateCustomer(_customerSettings.UsernamesEnabled ? model.Username : model.Email, model.Password))
                {
                    var customer = _customerSettings.UsernamesEnabled ? _customerService.GetCustomerByUsername(model.Username) : _customerService.GetCustomerByEmail(model.Email);

                    //migrate shopping cart
                    _shoppingCartService.MigrateShoppingCart(_workContext.CurrentCustomer, customer);

                    //sign in new customer
                    _authenticationService.SignIn(customer, model.RememberMe);


                    if (!String.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
                        return Redirect(returnUrl);

                    return RedirectToAction("Index", "Home");
                }

                ModelState.AddModelError("", "Invalid login details provided.");
            }

            return View(model);
        }
    }
}



@model Nop.Web.Models.Customer.LoginModel
@{
    Layout = null;
}
<!DOCTYPE html>

<html>
<head>
    <title>Myco Invitation Login</title>
    <link href="/Themes/myco/Content/invite.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <header class="header">
        <div class="top-menu">
                <div class="message-error">@Html.ValidationSummary(true, T("Account.Login.Unsuccessful").Text)</div>
        </div>
        <div class="header-logo">
            <img src="/Themes/myco/Content/images/full-logo.jpg" alt="motto!" />
        </div>
        <div class="login">
        @using (Html.BeginForm())
        {
            <table class="login-table-container">
                <tbody>
                    @if (Model.UsernamesEnabled)
                    {
                        <tr class="row">
                            <td class="item-name">
                                @Html.LabelFor(m => m.Username):
                            </td>
                            <td class="item-value">
                                @Html.TextBoxFor(m => m.Username)
                                @Html.ValidationMessageFor(m => m.Username)
                            </td>
                        </tr>
                    }
                    else
                    {
                        <tr class="row">
                            <td class="item-name">
                                @Html.LabelFor(m => m.Email):
                            </td>
                            <td class="item-value">
                                @Html.TextBoxFor(m => m.Email)
                                @Html.ValidationMessageFor(m => m.Email)
                            </td>
                        </tr>
                    }
                    <tr class="row">
                        <td class="item-name">
                            @Html.LabelFor(m => m.Password):
                        </td>
                        <td class="item-value">
                            @Html.PasswordFor(m => m.Password)
                            @Html.ValidationMessageFor(m => m.Password)
                        </td>
                    </tr>
                    <tr class="row">
                        <td class="item-value" colspan="2">
                            @Html.CheckBoxFor(m => m.RememberMe)
                            @Html.LabelFor(m => m.RememberMe)
                        </td>
                    </tr>
                    <tr class="row">
                        <td colspan="2">
                            <div class="buttons">
                                <button class="loginbutton" type="submit">@T("Account.Login.LoginButton")</button>
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        }
        </div>
        <div class="clear" />
    </header>
    
    <div class="content">
        <div class="about">
            <h1>Welcome</h1>
            <p>
                <strong>Blurb...</strong>
            </p>
            <p>
                The site is currently by invitation only...
            </p>
            <p>
                <strong>... </strong>
            </p>
    </div>
    <footer class="footer clear">

    </footer>
</body>
</html>


I'll probably make the 'about' div a topic for admins to edit.
12 years ago
Thank you for the reply and sharing. I'm a novice I have few questions if you have the time to help?

With the HomeController.myco.cs  I have used the following as I want possible customers the option to register but It throwing an error which I have highlighted in bold

public partial class HomeController : BaseNopController
    {
        private readonly CustomerSettings _customerSettings;
        private readonly ICustomerRegistrationService _customerRegistrationService;
        private readonly ICustomerService _customerService;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IWorkContext _workContext;
        private readonly IAuthenticationService _authenticationService;

        public HomeController(CustomerSettings customerSettings, ICustomerRegistrationService customerRegistrationService, ICustomerService customerService,
            IShoppingCartService shoppingCartService, IWorkContext workContext, IAuthenticationService authenticationService)


It throws this.

Error  1  The type or namespace name 'ICustomerRegistrationService' could not be found (are you missing a using directive or an assembly reference?)  Z:\NopCommerce\Presentation\Nop.Web\Controllers\HomeController.con.cs  15  26  Nop.Web

Also I'm wondering if I could and the routes with the login and register blocks in the master wrapper left side shared two column layout so before the user is authenticated they still access to certain routes but can't get access to the catalogue.

All help would be highly regarded

Richard.
12 years ago
The ICustomerRegistrationService is in the Nop.Services.Customers namespace and if your registration worked before, it should have found it if your new partial HomeController.myco.cs class is inside the existing Nop.Web project too.

If you do not wish to create a new View as I did, you will have to look at which routes to allow (as you say, look at the layout template and see what actions it calls). Lazy way of doing it is by putting a break point in the authorization override of the new BaseController and just seeing what actions the code execution runs through.
12 years ago
Hi

Yes I know it may sound lazy but I just need to have a quick turn over on this part of the project..

I have resolved the issue of the ICustomerRegistrationService.. The namespace was right when I dierectly wrote it worked, but I had to generate Error  2  

'Nop.Web.Controllers.HomeController' does not contain a definition for '_customerService'

I had to generate a method stub for customerService. Is this the right procedure I don't know??
eg
private Services.Customers.ICustomerService _customerService;


There is one other area I was hoping you provide further info/help .

Error  1  Missing partial modifier on declaration of type 'Nop.Web.Controllers.BaseNopController'; another partial declaration of this type exists  C:\Users\Richard\Desktop\Nop2.5\Presentation\Nop.Web\Controllers\BaseNopController.cs  16  27  Nop.Web

I have created both controllers HomeControllerCompany.cs and BaseNopControllerCompany.cs as partial classes and turned the NOP HomeController into a
public partial class
but I'm hit with error above.. The Nop BaseController as an
public abstract class


Just hoping you could advise me on what I'm missing.

Thanks again

R
12 years ago
For the customerService you need the private variable declared as you did in your class (and you have to initialize it on the constructor for dependency injection, which i assume you have done).

with regards to the partial class, my BaseNopController class is declared as follows:
public abstract partial class BaseNopController : Controller
12 years ago
Hi thank you again for the reply and sorry for my late.

I have had to upgraded from 2.3 to 2.5 as the ICustomerRegistrationService wasn't availble in 2.3. (As allot more :)

I followed the exacte procedure's you said its asking me to generate a method stub in Nop.Core.Domain.customer,
was this the same when you wrote these's files, if so would you able to share the method as I'm a novice
and don't know how to do so I generated it in VS10 but on debugging It returned an error.

Thank you for the help and kind regards :)

Richard
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.