public void SetUp()
        {
            var services = new ServiceCollection();

            services.AddServiceInjection();
            ServiceInjection.Register(new List <Assembly>()
            {
                Assembly.GetAssembly(typeof(WebApi.Startup))
            });
            services.AddScoped <UsersController>();
            // mocks
            _validModel = new AuthorizationGrantModel
            {
                username = "******",
                password = "******",
            };
            _invalidModel = new AuthorizationGrantModel
            {
                username = "******",
                password = DateTime.Now.ToString(),
            };
            _anonymous = new ClaimsPrincipal();

            var identityServiceMock = new Mock <IIdentityService>();

            identityServiceMock.Setup(o => o.ValidateLogin(It.IsAny <ClaimsPrincipal>(),
                                                           It.IsAny <AuthorizationGrantModel>()))
            .Returns(new ValidationData());
            identityServiceMock.Setup(o => o.AuthenticateAsync(
                                          It.Is <string>(u => u == _validModel.username),
                                          It.Is <string>(p => p == _validModel.password)))
            .Returns(Task.FromResult(new AppUser()));
            identityServiceMock.Setup(o => o.GetIdentityAsync(It.IsAny <AppUser>(), It.IsAny <string>()))
            .Returns(Task.FromResult(new ClaimsIdentity()));
            identityServiceMock.Setup(o => o.GenerateTokenResponse(It.IsAny <ClaimsPrincipal>(),
                                                                   It.IsAny <AuthenticationProperties>(), It.IsAny <string>()))
            .Returns(new TokenResponseModel());

            var dbContextMock = Mock.Of <DbContext>();

            services.AddScoped(p => identityServiceMock.Object);
            services.AddScoped(p => dbContextMock);

            _provider = services.BuildServiceProvider();
        }
        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));
        }
Ejemplo n.º 3
0
 public ValidationData ValidateLogin(
     ClaimsPrincipal principal, AuthorizationGrantModel model)
 {
     return(new ValidationData());
 }
Ejemplo n.º 4
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));
        }
Ejemplo n.º 5
0
 public ValidationResult ValidateLogin(
     ClaimsPrincipal principal, AuthorizationGrantModel model)
 {
     return(ValidationResult.Pass());
 }
Ejemplo n.º 6
0
        public async Task <IActionResult> LogIn([FromForm] AuthorizationGrantModel model)
        {
            var validationResult = _service.ValidateLogin(User, model);

            if (!validationResult.Valid)
            {
                return(BadRequest(validationResult.Result));
            }
            AppUser entity = null;

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

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

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

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

            default:
                return(BadRequest(new AppResultBuilder()
                                  .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");
            if (principal.IsInRole(RoleName.Device))
            {
                if (model.fcm_token == null)
                {
                    return(BadRequest(new AppResultBuilder()
                                      .FailValidation(mess: "FCM Token is required for device login")));
                }
                using (var trans = context.Database.BeginTransaction())
                {
                    var device      = _deviceService.Devices.Id(entity.Id).FirstOrDefault();
                    var oldFcmToken = device.CurrentFcmToken;
                    _deviceService.ChangeDeviceToken(device, model.fcm_token, resp.access_token);
                    context.SaveChanges();
                    _service.LoginDevice(device, oldFcmToken, model.fcm_token);
                    trans.Commit();
                }
            }
            return(Ok(resp));
        }
Ejemplo n.º 7
0
        public JsonResult Index(AuthorizationGrantModel model)
        {
            try
            {
                if (model.grant_type == "authorization_code")
                {
                    //Validate the code is used only once

                    var client = clientRepo.GetClient(model.client_id);

                    if (client == null)
                    {
                        return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet));
                    }

                    if (!client.ClientSecret.Equals(model.client_secret))
                    {
                        return(Json(new { error = "invalid_client" }, JsonRequestBehavior.AllowGet));
                    }

                    var code = codeRepo.GetAuthorizationCode(model.code);

                    if (code == null)
                    {
                        return(Json(new { error = "invalid_grant" }, JsonRequestBehavior.AllowGet));
                    }

                    if (!code.ClientID.Equals(client.ClientID))
                    {
                        return(Json(new { error = "unauthorized_client" }, JsonRequestBehavior.AllowGet));
                    }

                    //Validate Uri match the client url registered

                    if (!string.IsNullOrEmpty(code.Redirect_Uri) && !code.Redirect_Uri.Equals(model.redirect_uri))
                    {
                        return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet));
                    }

                    //Valid
                    var key      = Convert.FromBase64String(client.ClientSecret);
                    var provider = new System.Security.Cryptography.HMACSHA256(key);

                    var UserID = code.UserID;

                    var rawTokenInfo = string.Concat(code.Code, client.ClientSecret, UserID, DateTime.UtcNow.ToString("hhmmss"));
                    var rawTokenByte = Encoding.UTF8.GetBytes(rawTokenInfo);
                    var token        = provider.ComputeHash(rawTokenByte);

                    var rawRefreeshInfo = string.Concat(code.Code, client.ClientSecret, DateTime.UtcNow.ToString("hhmmss"));
                    var rawRefreshByte  = Encoding.UTF8.GetBytes(rawRefreeshInfo);
                    var refresh         = provider.ComputeHash(rawRefreshByte);

                    var accessToken = new AccessToken()
                    {
                        ClientID     = model.client_id,
                        UserID       = UserID,
                        Token        = Convert.ToBase64String(token),
                        Type         = "bearer",
                        Expiration   = DateTime.Now.AddDays(1),
                        RefreshToken = Convert.ToBase64String(refresh),
                        Scope        = string.Empty
                    };

                    if (tokenRepo.Save(accessToken))
                    {
                        return(Json(new AccessTokenModel(accessToken), JsonRequestBehavior.AllowGet));
                    }
                }

                if (model.grant_type == "refresh_token" && !string.IsNullOrEmpty(model.refresh_token))
                {
                    //Validate the code is used only once

                    var client = clientRepo.GetClient(model.client_id);

                    if (client == null)
                    {
                        return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet));
                    }

                    if (!client.ClientSecret.Equals(model.client_secret))
                    {
                        return(Json(new { error = "invalid_client" }, JsonRequestBehavior.AllowGet));
                    }

                    var oldToken = tokenRepo.GetRefreshToken(model.refresh_token);

                    if (oldToken == null)
                    {
                        return(Json(new { error = "invalid_grant" }, JsonRequestBehavior.AllowGet));
                    }

                    if (!oldToken.ClientID.Equals(client.ClientID))
                    {
                        return(Json(new { error = "unauthorized_client" }, JsonRequestBehavior.AllowGet));
                    }

                    //Valid
                    var key      = Convert.FromBase64String(client.ClientSecret);
                    var provider = new System.Security.Cryptography.HMACSHA256(key);

                    var UserID = oldToken.UserID;

                    var rawTokenInfo = string.Concat(oldToken.Token, client.ClientSecret, DateTime.UtcNow.ToString("hhmmss"));
                    var rawTokenByte = Encoding.UTF8.GetBytes(rawTokenInfo);
                    var token        = provider.ComputeHash(rawTokenByte);

                    var accessToken = new AccessToken()
                    {
                        ClientID     = model.client_id,
                        UserID       = UserID,
                        Token        = Convert.ToBase64String(token),
                        Type         = "bearer",
                        Expiration   = DateTime.Now.AddDays(1),
                        RefreshToken = string.Empty,
                        Scope        = string.Empty
                    };

                    if (tokenRepo.Save(accessToken))
                    {
                        return(Json(new AccessTokenModel(accessToken), JsonRequestBehavior.AllowGet));
                    }
                }
            }
            catch
            {
                return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet));
            }

            return(Json(new { error = "invalid_request" }, JsonRequestBehavior.AllowGet));
        }