sábado, 18 de julho de 2015

MVC Controlador Padrão

using System;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Lapuinka.PCP.Data.Model;
using Lapuinka.PCP.Helper.Culture;
using Lapuinka.PCP.Helper.Exceptions;
using Lapuinka.PCP.Helper.Generics;
using Lapuinka.PCP.Helper.Security;
using Lapuinka.PCP.Resources;
using Lapuinka.PCP.Service;
using Lapuinka.PCP.Web.Core;
using Lapuinka.PCP.Web.Models;

namespace Lapuinka.PCP.Web.Controllers
{
    ///
    /// Controlador utilizado pelo sistema
    ///
    [ValidateInput(false)]
    public class ControladorPadrao : Controller
    {
        #region [ Propriedades ]

        protected LogService servicoLog = new LogService();
        protected MensagemRetorno ultimoErroInterno = new MensagemRetorno();

        #endregion [ Propriedades ]

        #region [ Métodos Subscritos ]

        ///
        /// Analise a mudança de idioma
        ///
        ///
        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            // Is it View ?
            var view = filterContext.Result as ViewResultBase;
            if (view == null) // if not exit
                return;

            var cultureName = ObterCulture();//Thread.CurrentThread.CurrentCulture.Name; // e.g. "en-US" // filterContext.HttpContext.Request.UserLanguages[0]; // needs validation return "en-us" as default           

            // Is it default culture? exit
            if (cultureName == CultureHelper.GetDefaultCulture())
                return;


            // Are views implemented separately for this culture?  if not exit
            var viewImplemented = CultureHelper.IsViewSeparate(cultureName);
            if (viewImplemented == false)
            {
                return;
            }

            var viewName = view.ViewName;
            int i;
            if (String.IsNullOrEmpty(viewName))
            {
                viewName = filterContext.RouteData.Values["action"] + "." + cultureName; // Index.en-US
            }
            else if ((i = viewName.IndexOf('.')) > 0)
            {
                // contains . like "Index.cshtml"               
                viewName = viewName.Substring(0, i + 1) + cultureName + viewName.Substring(i);
            }
            else
            {
                viewName += "." + cultureName; // e.g. "Index" ==> "Index.en-Us"
            }
            view.ViewName = viewName.Replace("." + cultureName, "");
            filterContext.Controller.ViewBag._culture = "." + cultureName;

            base.OnActionExecuted(filterContext);
        }

        ///
        /// Descobre se mudou o idioma
        ///
        protected override void ExecuteCore()
        {
            var cultureName = ObterCulture();
            cultureName = CultureHelper.GetValidCulture(cultureName);
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName);
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName);
            try
            {
                #region [Tratamento de Script Evil, e tamanho máximo]
                if (ExisteScriptMaliciso(Server.UrlDecode(Request.QueryString.ToString()))
                    || ExisteScriptMaliciso(Server.UrlDecode(Request.Form.ToString()))
                    || Request.ContentLength > MvcApplication.TamanhoMaximoFoto
                    )
                {
                    //Script Evil
                    var isreadonly = typeof(NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
                    isreadonly.SetValue(this.Request.QueryString, false, null);

                    //a) Para Request.QueryString
                    var filteredQueryString = new NameValueCollection(Request.QueryString);
                    Request.QueryString.Clear();
                    foreach (string key in filteredQueryString)
                    {
                        Request.QueryString.Add(key, Server.HtmlEncode(filteredQueryString[key]));
                    }

                    //b) Para Request.Form
                    if (Request.ContentLength > MvcApplication.TamanhoMaximoFoto)//detecta tamanho grande do Request
                    {
                        isreadonly.SetValue(this.Request.Form, false, null);
                        var msg = String.Format(Resource.Msg_Geral_ArquivoGrande, Convert.ToString(MvcApplication.TamanhoMaximoFoto));
                        LogService.Log("BaseController.ExecuteCore()", msg, LogService.LogTipo.Erro);
                        ultimoErroInterno.Sucesso = false;
                        ultimoErroInterno.Descricao = msg;
                        ultimoErroInterno.Codigo = "-1";
                    }
                    else
                    {
                        try
                        {
                            isreadonly.SetValue(this.Request.Form, false, null);
                            var filteredForms = new NameValueCollection(Request.Form);
                            Request.Form.Clear();
                            foreach (string key in filteredForms)
                            {
                                Request.Form.Add(key, RemoveScriptMalicioso(filteredForms[key]));
                            }
                        }
                        catch (Exception ex)
                        {
                            LogService.Log("BaseController.ExecuteCore() :: Exception : ", ex);
                            ultimoErroInterno.Sucesso = false;
                            ultimoErroInterno.Descricao = ex.Message;
                            ultimoErroInterno.Codigo = "-1";
                        }
                    }
                }
                #endregion [Tratamento de Script Evil, e tamanho máximo]

                base.ExecuteCore();
            }
            catch (HttpRequestValidationException ex)
            {
                LogService.Log("BaseController.ExecuteCore() :: HttpRequestValidationException : ", ex);
                ultimoErroInterno.Sucesso = false;
                ultimoErroInterno.Descricao = ex.Message;
                ultimoErroInterno.Codigo = "-1";
            }
            catch (Exception ex)
            {
                LogService.Log("BaseController.ExecuteCore() :: Exception : ", ex);
                ultimoErroInterno.Sucesso = false;
                ultimoErroInterno.Descricao = ex.Message;
                ultimoErroInterno.Codigo = "-1";
            }
        }

        ///
        /// Called when an unhandled exception occurs in the action.
        ///
        /// Information about the current request and action.
        protected override void OnException(ExceptionContext filterContext)
        {
            // Executa rotina para Gravar e armazenar a Exception Gerada
            if (filterContext.Exception != null)
            {
                if (ExisteAjaxRequest(filterContext))
                {
                    TratarErroAjax(filterContext);
                }

                if (filterContext.ExceptionHandled)
                {
                    if (filterContext.Exception.GetType().Equals(typeof(CustomException)))
                    {
                        var customException = (CustomException)filterContext.Exception;
                        if (customException.ExceptionType == ExceptionType.NaoAutenticado)
                        {
                            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
                            {
                                action = "Login",
                                controller = "Account"
                            }));
                        }
                    }
                    return;
                }

                var ex = filterContext.Exception;
                while (ex.InnerException != null) ex = ex.InnerException;

                if (ExisteAjaxRequest(filterContext))
                {
                    filterContext.Result = Json(new MensagemRetorno
                                                    {
                                                        Sucesso = false,
                                                        Descricao = Resource.Msg_Geral_Erro
                                                    });
                }
                else if (filterContext.Exception.GetType().Equals(typeof(CustomException)))
                {
                    var customException = (CustomException)filterContext.Exception;
                    if (customException.ExceptionType == ExceptionType.NaoAutenticado)
                    {
                        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
                        {
                            action = "Login",
                            controller = "Account"
                        }));
                    }
                    if (customException.ExceptionType == ExceptionType.Interno)
                    {
                        // TODO: QUANDO cair aqui deverá ser tratado para Retornar o Erro para Tela
                        // ou apenas deixar Grava na BASE (como já está)!
                    }
                }
                else if (filterContext.Exception.GetType().Equals(typeof(NullReferenceException)))
                {
                    var descricao = String.Format("{0}", ex);
                    if (ex.StackTrace != null)
                    {
                        var stackTrace = ex.StackTrace.Split(new[] { "at" }, StringSplitOptions.RemoveEmptyEntries)[1];
                        if (!String.IsNullOrWhiteSpace(stackTrace))
                        {
                            descricao = String.Format("{0} - [StackTrace:{1}]", ex, stackTrace);
                        }
                    }
                    LogService.Log("OnException: ", descricao, LogService.LogTipo.Erro);
                }
                else
                {
                    var viewName = "Error";
                    var msg = ex.Message;
                    if (ex.Message.Contains("Maximum request length exceeded"))
                    {
                        viewName = "ErrorFrame";
                        msg = String.Format(Resource.Msg_Geral_ArquivoGrande, MvcApplication.TamanhoMaximoFoto);
                    }

                    LogService.Log("OnException: ", ex);

                    filterContext.Result = new ViewResult { ViewName = viewName };
                    var result = filterContext.Result as ViewResult;
                    result.ViewData["MensagemErro"] = msg;
                }
            }

            filterContext.ExceptionHandled = true;
        }

        /////
        ///// Método padrão do MVC para liberar recursos
        /////
        ///// flag de status
        //protected override void Dispose(Boolean disposing)
        //{
        //    //db.Dispose();
        //    base.Dispose(disposing);
        //}

        #endregion [ Métodos Subscritos ]

        #region [ Métodos ]

        ///
        /// Tratamento para tratar posts maliciosos
        ///
        ///
        ///
        public String RemoveScriptMalicioso(String possivelScriptMalicioso)
        {
            return Regex.IsMatch(possivelScriptMalicioso, "<(.|\n)*?>") ? Server.HtmlEncode(possivelScriptMalicioso) : possivelScriptMalicioso;
        }

        ///
        /// Verifica algum XSS
        ///
        /// valor
        ///
        public Boolean ExisteScriptMaliciso(String valor)
        {
            return (Regex.IsMatch(valor, "<(.|\n)*?>"));
        }

        ///
        /// Converte objeto para json.
        ///
        /// The objeto.
        ///
        protected String ConverterParaJson(object objeto)
        {
            return Helper.Serializer.Serializer.Serialize(objeto, objeto.GetType(), Helper.Serializer.SerializerType.JSON);
        }

        ///
        /// Define a culture.
        ///
        /// The identificador pais.
        public void DefinirCulture(String identificadorPais)
        {
            var culture = new RegiaoService(SecurityHelper.ObtemFirstConnectionString()).ObterCulturaPorRegiao(Convert.ToInt32(identificadorPais));

            Int32 idPaisSelecionado;
            if (Int32.TryParse(identificadorPais, out idPaisSelecionado))
            {
                // Armazena o Identificador do Pais na Sessão
                SecurityHelper.ArmazenarIdentificadorPais(idPaisSelecionado);

                // Armazena a ConnectionString conforme o identificador do Pais
                SecurityHelper.ArmazenarConnectionString();
            }
            else
            {
                LogService.Log("DefinirCulture()", String.Format(Resource.Msg_Cultura_Problema, identificadorPais), LogService.LogTipo.Erro);
            }

            // culture = CultureHelper.GetValidCulture(culture);
            var cookieCulture = System.Web.HttpContext.Current.Request.Cookies[ConstantHelper._cookieCulture];
            if (cookieCulture != null)
            {
                cookieCulture.Value = culture;
            }
            else
            {
                cookieCulture = new HttpCookie(ConstantHelper._cookieCulture) { HttpOnly = false, Value = culture, Expires = DateTime.Now.AddYears(1) };
                // Not accessible by JS.  - Não é acesivel via Javascript M.L.
            }
            System.Web.HttpContext.Current.Response.Cookies.Add(cookieCulture);
        }

        ///
        /// Método que Obtem o identificador do pais.
        ///
        ///
        public String ObterIdentificadorPais()
        {
            return SecurityHelper.ObterIdentificadorPais().ToString();
        }

        ///
        /// Método que define a URL para o método Url.Content("~/Home/Index");
        ///
        /// The URL contante.
        ///
        public String DefinirUrlPorConstante(String urlContante)
        {
            return !String.IsNullOrWhiteSpace(urlContante) ? Url.Content(String.Format("~{0}", urlContante)) : urlContante;
        }

        ///
        /// Existe ou não ConnectionString
        ///
        ///
        public Boolean ExisteConnectionString()
        {
            if (ControllerContext.HttpContext == null)// || System.Web.HttpContext.Current.Session == null)
            {
                return false;
            }
            return ControllerContext.HttpContext.Session[ConstantHelper._sesConnectionString] != null;
            //return  System.Web.HttpContext.Current.Session[ConstantHelper._sesConnectionString] != null;
        }

        ///
        /// Verifica se a Sessão contem Informações do usuário logado...
        ///
        public Boolean UsuarioAindaEstaLogado()
        {
            var estaAutenticado = false;
            if (LapuinkaUserService.ObterUsuarioLogado() != null && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                estaAutenticado = true;
            }
            else if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                LapuinkaUserService.RecuperarUsuarioMembership(System.Web.HttpContext.Current.User.Identity.Name);
                estaAutenticado = true;
            }
            return estaAutenticado;
        }

        ///
        /// Método que Autentica o Usuário, Cria um SetAuthCookie e armazena na sessão o LapuinkaUserService
        ///
        /// LogOnModel
        /// LapuinkaMembershipService "[já configurado]".
        ///
        public LapuinkaUserService AutenticarUsuario(LogOnModel model, LapuinkaMembershipService customMemberShip)
        {
            // Comentada a linha abaixo para testes da nova forma de autenticação -> M.L. -> 02/07/2012
            FormsAuthentication.SetAuthCookie(model.Usuario, model.MeLembre);

            // Obtem o objeto do Usuário Autenticado
            var LapuinkaUser = customMemberShip.ObterUsuario(model.Usuario, true);

            // Armazena as Regras do Usuário no objeto recém obtido
            LapuinkaUser.Regras = LapuinkaUser.RegrasPorUsuario(LapuinkaUser.UserName);

            //DefineAutenticacao(model.Usuario, LapuinkaUser.Regras.ToString());

            // Armazena na Sessão o objeto do Usuário Autenticado
            LapuinkaUserService.ArmazenaUsuarioLogado(LapuinkaUser);

            return LapuinkaUser;
        }

        ///
        /// Define o método de autenticacao e armazena em cookie as informações
        ///
        /// Name of the user.
        /// The user data.
        public void DefineAutenticacao(String userName, String userData)
        {
            var ticket = new FormsAuthenticationTicket(1, // Version
                userName,   // Login do Usuário
                DateTime.Now, // Data atual
                DateTime.Now.AddMinutes(30), // Data de expiração do Cookie
                false, // Persistente Cookie
                userData, // Dados do Usuário
                FormsAuthentication.FormsCookiePath);

            // Por rações de Segurança é feito um hash para o Cookie
            var hashCookies = FormsAuthentication.Encrypt(ticket);

            //if (!FormsAuthentication.CookiesSupported)
            //{
            //    //If the authentication ticket is specified not to use cookie, set it in the URL
            //    FormsAuthentication.SetAuthCookie(hashCookies, false);
            //}
            //else
            //{
            //    //If the authentication ticket is specified to use a cookie,
            //    //wrap it within a cookie.
            //    //The default cookie name is .ASPXAUTH if not specified
            //    //in the element in web.config
            //    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashCookies)
            //                         {
            //                             Expires = ticket.Expiration
            //                         };
            //    //Set the cookie's expiration time to the tickets expiration time
            //    //Set the cookie in the Response
            //    System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
            //}


            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashCookies); //{ Expires = ticket.Expiration };
            // add the cookie to user browser
            System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
            //ControllerContext.HttpContext.Response.AppendCookie(cookie);
        }

        ///
        /// Obtem o usuario logado no sistema.
        ///
        ///
        public LapuinkaUserService ObterUsuarioLogado()
        {
            var usuarioLogado = LapuinkaUserService.ObterUsuarioLogado();
            if (usuarioLogado != null)
            {
                return usuarioLogado;
            }
            return null;
        }

        ///
        /// Obtem o nome do usuario logado. (Caso o usuário não exista retornará Empty)
        ///
        ///
        public String ObterNomeUsuarioLogado()
        {
            return UsuarioAindaEstaLogado() ? ObterUsuarioLogado().UserName : String.Empty;
        }

        #region [ Estáticos ]

        ///
        /// Obter a culture do Cookie or Default(Web.Config)
        ///
        ///
        public static String ObterCulture()
        {
            if (System.Web.HttpContext.Current != null)
            {
                var httpCookie = System.Web.HttpContext.Current.Request.Cookies[ConstantHelper._cookieCulture];
                if (httpCookie != null && (!String.IsNullOrEmpty(httpCookie.Value)))
                {
                    return httpCookie.Value;
                }
            }
            //return System.Web.HttpContext.Current.Request.Cookies[ConstantHelper._cookieCulture] != null &&
            //    System.Web.HttpContext.Current.Request.Cookies[ConstantHelper._cookieCulture].Value != string.Empty ?
            //    System.Web.HttpContext.Current.Request.Cookies[ConstantHelper._cookieCulture].Value :
            return CultureHelper.GetDefaultCulture();
        }

        ///
        /// Retorna o Usuário Logado do Sistema de Forma Estatica
        ///
        ///
        public static LapuinkaUserService UsuarioLogado()
        {
            var usuarioLogado = LapuinkaUserService.ObterUsuarioLogado();
            if (usuarioLogado != null)
            {
                return usuarioLogado;
            }
            return null;
        }

        ///
        /// Atualiza a Imagem no servidor
        ///
        /// Caminho completo
        /// codigo do produto, para fazer o resize
        ///
        protected String AtualizaImagem(String caminhoCompletoServidorArquivoTemporario, String cdProduto)
        {
            string arquivoProduto = string.Format("{0}{1}", Path.GetFileName(ProdutoService.CodigoProdutoParaHtml(cdProduto)), Path.GetExtension(caminhoCompletoServidorArquivoTemporario));
            GeneralHelpers.ResizeImage(caminhoCompletoServidorArquivoTemporario, Path.Combine(Server.MapPath(MvcApplication.UrlImgProdutoDetalhe), arquivoProduto), MvcApplication.ImagemLarguraPadraoProduto, MvcApplication.ImagemLarguraPadraoProduto, true);
            GeneralHelpers.ResizeImage(caminhoCompletoServidorArquivoTemporario, Path.Combine(Server.MapPath(MvcApplication.UrlImgProdutoMini), arquivoProduto), MvcApplication.ImagemLarguraPadraoProdutoMini, MvcApplication.ImagemLarguraPadraoProdutoMini, true);
            System.IO.File.Delete(caminhoCompletoServidorArquivoTemporario);
            return arquivoProduto;
        }

        ///
        /// Verifica se a Sessão do Usuário ainda está ativa e também verificar se o Usuário está Autenticado no Contexto.
        /// Se estiver somente autenticado no Contexto, irá jogar em sessão novamente o usuário
        ///
        ///
        public static Boolean EstaAutenticado()
        {
            var estaAutenticado = false;
            if (LapuinkaUserService.ObterUsuarioLogado() != null && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                estaAutenticado = true;
            }
            else if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                LapuinkaUserService.RecuperarUsuarioMembership(System.Web.HttpContext.Current.User.Identity.Name);
                estaAutenticado = true;
            }
            return estaAutenticado;
        }

        ///
        /// Verifica se o Usuario possui regra informada.
        ///
        /// The regra.
        ///
        public static Boolean UsuarioPossuiRegra(String regra)
        {
            var usuarioLogado = LapuinkaUserService.ObterUsuarioLogado();
            if (usuarioLogado != null)
            {
                if (usuarioLogado.Regras != null)
                {
                    return usuarioLogado.UsuarioPossuiRegra(regra);
                }
            }
            return false;
        }

        ///
        /// Controle o Status do Ckeckbox -> "checked" ou String.Empty
        ///
        /// The valor.
        ///
        public static String CheckBoxStatus(String valor)
        {
            if (valor != null && valor.ToUpper() == "S")
            {
                return "checked";
            }
            return String.Empty;
        }

        ///
        /// Verificar se a Requisição foi ajax ou não
        ///
        /// The filter context.
        ///
        private static Boolean ExisteAjaxRequest(ControllerContext filterContext)
        {
            return ((filterContext.HttpContext.Request).Headers != null) &&
                   ((filterContext.HttpContext.Request).Headers["X-Requested-With"] == "XMLHttpRequest");
        }

        ///
        /// Trata o erro quando a requisição é ajax.
        ///
        /// The filter context.
        private void TratarErroAjax(ExceptionContext filterContext)
        {
            if (filterContext.Exception != null)
            {
                if (((filterContext.HttpContext.Request).Headers != null) &&
                    ((filterContext.HttpContext.Request).Headers["X-Requested-With"] == "XMLHttpRequest"))
                {
                    var msg = new MensagemRetorno { Sucesso = false };
                    // Executa rotina para Verificar a Queda de Sessão
                    if (filterContext.Exception.GetType().Equals(typeof(CustomException)))
                    {
                        switch (((CustomException)filterContext.Exception).ExceptionType)
                        {
                            case ExceptionType.Interno:
                                {
                                    msg.Descricao = Resource.Msg_Geral_Erro;
                                }
                                break;
                            case ExceptionType.NaoAutorizado:
                                {
                                    msg.Descricao = Resource.Msg_Geral_AcessoNegado;
                                }
                                break;
                            case ExceptionType.NaoAutenticado:
                                {
                                    msg.Descricao = Resource.Msg_Geral_ErroSessao;
                                    msg.PaginaParaNavegar = Url.Content(Constantes._urlAccountLogin);
                                }
                                break;
                        }
                    }
                    else if (filterContext.GetType() == typeof(ExceptionContext))
                    {
                        if (filterContext.Result != null && ((ViewResultBase)(filterContext.Result)).Model != null)
                        {
                            var model = ((ViewResultBase)(filterContext.Result)).Model;
                            var handlerErrorInfo = ((HandleErrorInfo)model);
                            var url = String.Format("~/{0}/{1}/", handlerErrorInfo.ControllerName, handlerErrorInfo.ActionName);
                            msg.PaginaParaNavegar = Url.Content(url);
                        }
                        msg.Descricao = Resource.Msg_Geral_PesquisaSemRetorno;
                    }
                    else
                    {
                        msg.Descricao = Resource.Msg_Geral_Erro;
                    }
                    filterContext.ExceptionHandled = true;
                    filterContext.Result = Json(msg);
                }
            }
        }

        #endregion [ Estáticos ]

        #endregion [ Métodos ]
    }

}
Postar um comentário