private IActionResult HandleError(IExceptionHandlerPathFeature feature)
        {
            var       ex = feature.Error;
            AppResult result;

            if (ex is AppValidationException validEx)
            {
                result          = validEx.Result;
                StatusCodeStyle = Resources.BadRequestMessageStyle;
                MessageTitle    = Localizer[Resources.BadRequestMessageTitle];
                Code            = (int)HttpStatusCode.BadRequest;
            }
            else if (ex is AuthorizationException authEx)
            {
                if (authEx.IsUnauthorized)
                {
                    result          = AppResult.Unauthorized(_resultLocalizer);
                    StatusCodeStyle = Resources.UnauthorizedMessageStyle;
                    MessageTitle    = Localizer[Resources.UnauthorizedMessageTitle];
                    Code            = (int)HttpStatusCode.Unauthorized;
                }
                else
                {
                    result          = AppResult.AccessDenied(_resultLocalizer);
                    StatusCodeStyle = Resources.AccessDeniedMessageStyle;
                    MessageTitle    = Localizer[Resources.AccessDeniedMessageTitle];
                    Code            = (int)HttpStatusCode.Forbidden;
                }
            }
            else if (ex is AppException appEx)
            {
                result          = appEx.Result;
                StatusCodeStyle = Resources.ErrorMessageStyle;
                MessageTitle    = Localizer[Resources.ErrorMessageTitle];
                Code            = (int)HttpStatusCode.InternalServerError;
            }
            else
            {
                if (_env.IsDevelopment())
                {
                    result = AppResult.Error(_resultLocalizer, data: ex, mess: ex.Message);
                }
                else
                {
                    result = AppResult.Error(_resultLocalizer, Localizer[Resources.ErrorMessage]);
                }

                StatusCodeStyle = Resources.ErrorMessageStyle;
                MessageTitle    = Localizer[Resources.ErrorMessageTitle];
                Code            = (int)HttpStatusCode.InternalServerError;
            }

            Message     = result.Message;
            RequestId   = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
            OriginalUrl = feature.Path;

            return(Page());
        }
        public async Task <IActionResult> LogIn([FromForm] AuthorizationGrantModel model)
        {
            var validationData = _service.ValidateLogin(User, model);

            if (!validationData.IsValid)
            {
                return(BadRequest(AppResult.FailValidation(data: validationData)));
            }
            AppUser entity = null;

            switch (model.grant_type)
            {
            case "password":
            case null:
            {
                entity = await
                         _service.AuthenticateAsync(model.username, model.password);

                if (entity == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid username or password")));
                }
            }
            break;

            case "refresh_token":
            {
                var validResult = _service.ValidateRefreshToken(model.refresh_token);
                if (validResult == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid refresh token")));
                }
                entity = await _service.GetUserByIdAsync(validResult.Identity.Name);

                if (entity == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid user identity")));
                }
            }
            break;

            default:
                return(BadRequest(AppResult
                                  .Unsupported("Unsupported grant type")));
            }
            var identity =
                await _service.GetIdentityAsync(entity, JwtBearerDefaults.AuthenticationScheme);

            var principal = new ClaimsPrincipal(identity);
            var utcNow    = DateTime.UtcNow;
            var props     = new AuthenticationProperties()
            {
                IssuedUtc  = utcNow,
                ExpiresUtc = utcNow.AddHours(WebApi.Settings.Instance.TokenValidHours)
            };

            props.Parameters["refresh_expires"] = utcNow.AddHours(
                WebApi.Settings.Instance.RefreshTokenValidHours);
            var resp = _service.GenerateTokenResponse(principal, props, model.scope);

            _logger.CustomProperties(entity).Info("Login user");
            return(Ok(resp));
        }
Exemple #3
0
        public async Task <IActionResult> LogIn(AuthorizationGrantModel model)
        {
            var validationData = _service.ValidateLogin(User, model);

            if (!validationData.IsValid)
            {
                return(BadRequest(AppResult.FailValidation(data: validationData)));
            }
            AppUser entity;

            switch (model.grant_type)
            {
            case "password":
            case null:
            {
                entity = await
                         _service.AuthenticateAsync(model.username, model.password);

                if (entity == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid username or password")));
                }
            }
            break;

            case "refresh_token":
            {
                var validResult = _service.ValidateRefreshToken(model.refresh_token);
                if (validResult == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid refresh token")));
                }
                entity = await _service.GetUserByIdAsync(validResult.Identity.Name);

                if (entity == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid user identity")));
                }
            }
            break;

            case "firebase_token":
            {
                FirebaseToken validResult = await _service.ValidateFirebaseToken(model.firebase_token);

                if (validResult == null)
                {
                    return(Unauthorized(AppResult
                                        .Unauthorized(mess: "Invalid Firebase token")));
                }
                UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(validResult.Uid);

                bool checkEmailDomain = _service.ValidateEmailDomain(userRecord.Email);
                if (!checkEmailDomain)
                {
                    return(Unauthorized(AppResult.InvalidEmailDomain()));
                }
                entity = await _service.GetUserByEmailAsync(userRecord.Email);

                var userExisted = entity != null;
                if (!userExisted || !entity.LoggedIn)
                {
                    using (var transaction = context.Database.BeginTransaction())
                    {
                        Member memberEntity;
                        if (!userExisted)
                        {
                            var emailInfo = userRecord.Email.GetEmailInfo();
                            entity = _service.ConvertToUser(userRecord, emailInfo.Item3);
                            var result = await _service
                                         .CreateUserWithoutPassAsync(entity);

                            if (!result.Succeeded)
                            {
                                foreach (var err in result.Errors)
                                {
                                    ModelState.AddModelError(err.Code, err.Description);
                                }
                                var builder = ResultHelper.MakeInvalidAccountRegistrationResults(ModelState);
                                return(BadRequest(builder));
                            }
                            _logger.CustomProperties(entity).Info("Register new user");
                            memberEntity = _memberService.ConvertToMember(entity, entity.MemberCode);
                            memberEntity = _memberService.CreateMember(memberEntity);
                        }
                        else
                        {
                            entity = _service.UpdateUser(entity, userRecord);
                            var result = await _service.UpdateUserAsync(entity);

                            if (!result.Succeeded)
                            {
                                foreach (var err in result.Errors)
                                {
                                    ModelState.AddModelError(err.Code, err.Description);
                                }
                                var builder = ResultHelper.MakeInvalidAccountRegistrationResults(ModelState);
                                return(BadRequest(builder));
                            }
                            memberEntity = _memberService.Members.Id(entity.Id).FirstOrDefault();
                            memberEntity = _memberService.UpdateMember(memberEntity, entity);
                        }
                        //log event
                        var ev = _sysService.GetEventForNewUser(
                            $"{memberEntity.Email} has logged into system for the first time",
                            memberEntity.UserId);
                        _sysService.CreateAppEvent(ev);
                        //end log event
                        context.SaveChanges();
                        transaction.Commit();
                    }
                }
            }
            break;

            default:
                return(BadRequest(AppResult.Unsupported("Unsupported grant type")));
            }
            var identity =
                await _service.GetIdentityAsync(entity, JwtBearerDefaults.AuthenticationScheme);

            var principal = new ClaimsPrincipal(identity);
            var utcNow    = DateTime.UtcNow;
            var props     = new AuthenticationProperties()
            {
                IssuedUtc  = utcNow,
                ExpiresUtc = utcNow.AddHours(WebApi.Settings.Instance.TokenValidHours)
            };

            props.Parameters["refresh_expires"] = utcNow.AddHours(
                WebApi.Settings.Instance.RefreshTokenValidHours);
            var resp = _service.GenerateTokenResponse(principal, props, model.scope ?? AppOAuthScope.ROLES);

            _logger.CustomProperties(entity).Info("Login user");
            return(Ok(resp));
        }