public SmtActionResult TenantLogin(string user, string pass)
        {
            if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(pass))
            {
                return(CreateObjectResult("user/pass cannot empty", System.Net.HttpStatusCode.BadRequest));
            }

            var tenantEntity = _context.SmtTenant.FirstOrDefault(p => p.Email == user);

            if (tenantEntity == null)
            {
                return(CreateObjectResult(null, System.Net.HttpStatusCode.NotFound));
            }

            if (tenantEntity.IsLocked == true)
            {
                return(CreateObjectResult("User is locked", System.Net.HttpStatusCode.BadRequest));
            }

            var result = Crypto.PasswordHash.VerifyHashedPassword(tenantEntity.PasswordHash, pass);

            if (result == false)
            {
                return(CreateObjectResult("wrong password", System.Net.HttpStatusCode.BadRequest));
            }

            var token = new TokenManager.LoginToken()
            {
                TenantName = tenantEntity.TenantName, TenantID = tenantEntity.ID
            };

            token.Claims.Add("*", new List <string>());
            return(CreateObjectResult(TokenManager.LoginToken.CreateTokenString(token)));
        }
        private bool CheckActionPermission(string controllerName, string actionName, TokenManager.LoginToken token)
        {
            if (token.Claims.ContainsKey("*") == true)
            {
                return(true);
            }

            if (ControllerAction.Smt.ControllerName == controllerName)
            {
                if (SmtControllerActionPermissions.Contains(actionName) == true)
                {
                    return(true);
                }
            }

            List <string> actions;

            if (token.Claims.TryGetValue(controllerName, out actions) == true)
            {
                if (actions.Contains(actionName) == true || actions.Contains("*") == true)
                {
                    return(true);
                }
            }

            return(false);
        }
        private TokenManager.LoginToken CheckLogin(
            string tokenText, HttpContext context,
            string controllerName, string actionName, out SmtActionResult result)
        {
            result = null;
            TokenManager.LoginToken token = null;

            token = TokenManager.LoginToken.VerifyTokenString(tokenText);
            if (token == null)
            {
                result = new SmtActionResult
                {
                    StatusCode  = System.Net.HttpStatusCode.Unauthorized,
                    ResultValue = "VerifyTokenString"
                };
            }
            else if (CheckTokenValid(token, context) == false)
            {
                result = new SmtActionResult
                {
                    StatusCode  = System.Net.HttpStatusCode.Unauthorized,
                    ResultValue = "CheckTokenValid"
                };
            }
            else if (CheckActionPermission(controllerName, actionName, token) == false)
            {
                result = new SmtActionResult
                {
                    StatusCode  = System.Net.HttpStatusCode.Unauthorized,
                    ResultValue = "CheckActionPermission"
                };
            }

            return(token);
        }
 public virtual void Init(TokenManager.LoginToken token, IApplicationBuilder app, HttpContext context, string requestType)
 {
     TokenModel        = token;
     App               = app;
     Context           = context;
     RequestObjectType = requestType;
     Logger            = context.RequestServices.GetRequiredService <ILoggerFactory>().CreateLogger(GetControllerName());
 }
        private SmtActionResult RequestExecutor(
            string controller, string action, Dictionary <string, object> parameter,
            HttpContext context, string requestType)
        {
            SmtActionResult result  = null;
            var             request = context.Request;

            try
            {
                if (ControllerAction.Smt.ControllerName == controller &&
                    SmtControllerAnonymousActions.Contains(action) == true)
                {
                    result = ControllerInvoker(controller, action, parameter, requestType, context, null);
                }
                else if (SmtSettings.Instance.AllowAnonymousActions.Contains(string.Format("{0}.{1}", controller, action)))
                {
                    result = ControllerInvoker(controller, action, parameter, requestType, context, null);
                }
                else
                {
                    var tokenText = request.Headers["token"][0];
                    TokenManager.LoginToken token = CheckLogin(tokenText, context, controller, action, out SmtActionResult checkLoginResult);
                    if (checkLoginResult != null)// check login failed.
                    {
                        result = checkLoginResult;
                    }
                    else
                    {
                        result = ControllerInvoker(controller, action, parameter, requestType, context, token);
                    }
                }
            }
            catch (System.Security.Cryptography.CryptographicException ex)
            {
                _logger.LogError(ex.ToString());
                result = new SmtActionResult
                {
                    StatusCode  = System.Net.HttpStatusCode.Unauthorized,
                    ResultValue = ex.Message
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                result = new SmtActionResult
                {
                    StatusCode  = System.Net.HttpStatusCode.BadRequest,
                    ResultType  = SmtActionResult.ActionResultType.Object,
                    ResultValue = ex.Message
                };
            }
            return(result);
        }
        private bool CheckTokenValid(TokenManager.LoginToken token, HttpContext context)
        {
            var dbContext = (ContextType)context.RequestServices.GetService(typeof(ContextType));

            if (token.IsTenant)
            {
                if (dbContext.SmtTenant.Any(p => p.ID == token.TenantID && p.TokenValidTime <= token.CreateTime) == false)
                {
                    return(false);
                }
            }
            else
            {
                if (dbContext.SmtUser.Any(p => p.ID == token.UserID && p.TokenValidTime <= token.CreateTime) == false)
                {
                    return(false);
                }
            }

            return(true);
        }
 public override void Init(TokenManager.LoginToken token, IApplicationBuilder app, HttpContext context, string requestType)
 {
     base.Init(token, app, context, requestType);
     _context = (ContextType)Context.RequestServices.GetService(typeof(ContextType));
 }
        public SmtActionResult UserLogin(string tenant, string user, string pass)
        {
            if (string.IsNullOrEmpty(tenant) || string.IsNullOrEmpty(user) || string.IsNullOrEmpty(pass))
            {
                return(CreateObjectResult("user/tenantName/pass cannot empty", System.Net.HttpStatusCode.BadRequest));
            }

            var tenantEntity = _context.SmtTenant.FirstOrDefault(p => p.TenantName == tenant);

            if (tenantEntity == null)
            {
                return(CreateObjectResult("Tenant not found", System.Net.HttpStatusCode.NotFound));
            }

            if (tenantEntity.IsLocked == true)
            {
                return(CreateObjectResult("User is locked", System.Net.HttpStatusCode.BadRequest));
            }

            var userEntity = _context.SmtUser.FirstOrDefault(p => p.Email == user && p.TenantID == tenantEntity.ID);

            if (userEntity == null)
            {
                return(CreateObjectResult("user not found", System.Net.HttpStatusCode.NotFound));
            }

            if (userEntity.IsLocked == true)
            {
                return(CreateObjectResult("User is locked", System.Net.HttpStatusCode.BadRequest));
            }

            var result = Crypto.PasswordHash.VerifyHashedPassword(userEntity.PasswordHash, pass);

            if (result == false)
            {
                return(CreateObjectResult("wrong pass", System.Net.HttpStatusCode.BadRequest));
            }

            var token = new TokenManager.LoginToken()
            {
                UserName = userEntity.UserName, TenantName = tenantEntity.TenantName, TenantID = userEntity.TenantID, UserID = userEntity.ID
            };

            foreach (var uc in _context.SmtUserClaim.Where(p => p.UserID == userEntity.ID))
            {
                var temp = uc.Claim.Split('.');
                if (temp.Length != 2)
                {
                    continue;
                }
                var           controllerName = temp[0];
                var           actionName     = temp[1];
                List <string> actions;
                if (token.Claims.TryGetValue(controllerName, out actions) == false)
                {
                    actions = new List <string>();
                    token.Claims.Add(controllerName, actions);
                }
                actions.Add(actionName);
            }

            return(CreateObjectResult(TokenManager.LoginToken.CreateTokenString(token)));
        }
        public async System.Threading.Tasks.Task <SmtActionResult> TenantLoginWithIdTokenAsync(Dictionary <string, object> parameter)
        {
            var idToken  = parameter["idtoken"].ToString();
            var provider = parameter["provider"].ToString();

            if (string.IsNullOrEmpty(idToken) || string.IsNullOrEmpty(provider))
            {
                return(CreateObjectResult("idToken/provider cannot empty", System.Net.HttpStatusCode.BadRequest));
            }

            string user = "";

            switch (provider)
            {
            case "google":
            {
                var validPayload = await GoogleJsonWebSignature.ValidateAsync(idToken);

                if (SmtSettings.Instance.GoogleClientIDs.Contains(validPayload.Audience.ToString()) == false)
                {
                    return(CreateObjectResult("invalid token", System.Net.HttpStatusCode.BadRequest));
                }
                user = validPayload.Email;
            }
            break;

            case "facebook":
            {
                using (var algorithm = new HMACSHA256(Encoding.ASCII.GetBytes(SmtSettings.Instance.FacebookAppSecret)))
                {
                    var hash    = algorithm.ComputeHash(Encoding.ASCII.GetBytes(idToken));
                    var builder = new StringBuilder();
                    for (int i = 0; i < hash.Length; i++)
                    {
                        builder.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture));
                    }
                    var appsecret_proof = builder.ToString();
                    using (HttpClient client = new HttpClient())
                    {
                        var response = await client.GetAsync(SmtSettings.Instance.FacebookUserInfoEndPoint + "?fields=email&access_token=" + idToken + "&appsecret_proof=" + appsecret_proof);

                        if (response.IsSuccessStatusCode == true)
                        {
                            user = Newtonsoft.Json.JsonConvert.DeserializeObject <Dictionary <string, string> >(await response.Content.ReadAsStringAsync())["email"];
                        }
                    }
                }
            }
            break;
            }

            var tenantEntity = _context.SmtTenant.FirstOrDefault(p => p.Email == user);

            if (tenantEntity == null)
            {
                tenantEntity = new TenantEntityType()
                {
                    Email          = user,
                    PasswordHash   = string.Empty,
                    CreateDate     = DateTime.UtcNow,
                    TenantName     = user,
                    TokenValidTime = DateTime.UtcNow.Ticks
                };
                _context.SmtTenant.Add(tenantEntity);

                _context.SaveChanges();
            }

            if (tenantEntity.IsLocked == true)
            {
                return(CreateObjectResult("User is locked", System.Net.HttpStatusCode.BadRequest));
            }

            var token = new TokenManager.LoginToken()
            {
                TenantName = tenantEntity.TenantName, TenantID = tenantEntity.ID
            };

            token.Claims.Add("*", new List <string>());
            return(CreateObjectResult(TokenManager.LoginToken.CreateTokenString(token)));
        }
        private SmtActionResult ControllerInvoker(
            string controllerName, string actionName, Dictionary <string, object> parameter, string requestType, HttpContext context, TokenManager.LoginToken token)
        {
            var controllerType = Type.GetType(
                string.Format(_controllerNamespacePattern, controllerName), true, true);

            var controller = Activator.CreateInstance(controllerType) as SmtAbstractController;

            controller.Init(token, _app, context, requestType);
            return(controller.ActionInvoker(actionName, parameter));
        }