public async Task <ReasonResult <QueueModel> > TryJoinQueue(ClaimsUser user)
        {
            var currentGame = await _dbContext.Games
                              .FirstOrDefaultAsync(x =>
                                                   x.GameState == GameState.InProgress &&
                                                   (x.PlayerOne == user.Id || x.PlayerTwo == user.Id));

            QueueModel output;

            if (currentGame == null)
            {
                output = new QueueModel()
                {
                    InQueueSince = await AddPlayerToQueue(user.Id),
                };
            }
            else
            {
                _logger.LogInformation("Player tried to join game while already in a game, {@details}", new
                {
                    GameId = currentGame.Id,
                    UserId = user.Id
                });

                output = new QueueModel()
                {
                    GameId = currentGame.Id,
                };
            }

            return(ReasonResult <QueueModel> .Success(output));
        }
        protected ActionResult <T> BuildResponse <T>(ReasonResult <T> reasonResult)
            where T : class
        {
            switch (reasonResult.Status)
            {
            case ActionStatus.Success:
            {
                if (reasonResult.Data != null)
                {
                    return(Ok(reasonResult.Data));
                }
                else
                {
                    return(NoContent());
                }
            }

            case ActionStatus.BadRequest: return(BadRequest(reasonResult.Reasons));

            case ActionStatus.NotFound: return(NotFound(reasonResult.Reasons));

            case ActionStatus.Forbidden: return(StatusCode(403, reasonResult.Reasons));

            default:
                throw new Exception($"Unknown {nameof(ActionStatus)}: {reasonResult.Status}");
            }
        }
Example #3
0
        public async Task <ReasonResult <UserModel> > RegisterAsync(RegisterInputModel inputModel)
        {
            var newUser = new ApplicationUser()
            {
                UserName    = inputModel.Email,
                Email       = inputModel.Email,
                Alias       = inputModel.Alias,
                CreatedDate = DateTime.UtcNow,
            };

            var identityResult = await _userManager.CreateAsync(newUser, inputModel.Password);

            _logger.LogInformation("User Register, {@details}", new
            {
                Id       = newUser.Id,
                UserName = newUser.UserName,
            });

            if (identityResult.Succeeded)
            {
                var output = new UserModel(newUser);
                return(ReasonResult <UserModel> .Success(output));
            }
            else
            {
                return(ReasonResult <UserModel> .BadRequest(identityResult.Errors.Select(x => new Reason(x.Code, x.Description))));
            }
        }
Example #4
0
        public async Task <ReasonResult <GameModel> > GetGameByIdAsync(int id, ClaimsUser user)
        {
            var game = await _dbContext.Games.FirstOrDefaultAsync(x => x.Id == id);

            if (game == null)
            {
                return(ReasonResult <GameModel> .NotFound());
            }

            if (game.PlayerOne != user.Id && game.PlayerTwo != user.Id)
            {
                return(ReasonResult <GameModel> .NotFound());
            }

            return(ReasonResult <GameModel> .Success(new GameModel(game)));
        }
        protected ActionResult BuildResponse(ReasonResult reasonResult)
        {
            switch (reasonResult.Status)
            {
            case ActionStatus.Success: return(NoContent());

            case ActionStatus.BadRequest: return(BadRequest(reasonResult.Reasons));

            case ActionStatus.NotFound: return(NotFound(reasonResult.Reasons));

            case ActionStatus.Forbidden: return(StatusCode(403, reasonResult.Reasons));

            default:
                throw new Exception($"Unknown {nameof(ActionStatus)}: {reasonResult.Status}");
            }
        }
Example #6
0
        public async Task <ReasonResult <AuthResponse> > LoginWithPasswordAsync(LoginPasswordModel inputModel)
        {
            var user = await _userManager.FindByEmailAsync(inputModel.Email);

            if (user != null)
            {
                var signInResult = await _signInManager.CheckPasswordSignInAsync(user, inputModel.Password, lockoutOnFailure : true);

                if (signInResult.Succeeded)
                {
                    await _userManager.RemoveAuthenticationTokenAsync(user, AuthSettings.RefreshTokenProvider, AuthSettings.RefreshTokenName);

                    string newRefreshToken = await _userManager.GenerateUserTokenAsync(user, AuthSettings.RefreshTokenProvider, AuthSettings.RefreshTokenName);

                    await _userManager.SetAuthenticationTokenAsync(user, AuthSettings.RefreshTokenProvider, AuthSettings.RefreshTokenName, newRefreshToken);

                    string accessToken = _jwtGenerator.GenerateToken(user, out var expires);
                    var    output      = new AuthResponse(accessToken, newRefreshToken, expires);

                    return(ReasonResult <AuthResponse> .Success(output));
                }
                else
                {
                    var reasons = new List <Reason>();

                    if (signInResult.IsLockedOut)
                    {
                        reasons.Add(new Reason("LockedOut", "User is locked out"));
                    }

                    if (signInResult.IsNotAllowed)
                    {
                        reasons.Add(new Reason("IsNotAllowed", "User is not allowed to sign in"));
                    }

                    if (!signInResult.IsLockedOut && !signInResult.IsNotAllowed && !signInResult.RequiresTwoFactor)
                    {
                        reasons.Add(new Reason("InvalidPassword", "Password does not match"));
                    }

                    return(ReasonResult <AuthResponse> .BadRequest(reasons));
                }
            }

            return(ReasonResult <AuthResponse> .BadRequest(new Reason[] { new Reason("UserNotFound", "Cannot find User") }));
        }
Example #7
0
        public async Task <ReasonResult <AuthResponse> > LoginWithRefreshTokenAsync(LoginRefreshTokenModel inputModel)
        {
            var query = (
                from userToken in _dbContext.UserTokens
                join applicationUser in _dbContext.ApplicationUsers on userToken.UserId equals applicationUser.Id
                where
                userToken.LoginProvider == AuthSettings.RefreshTokenProvider &&
                userToken.Name == AuthSettings.RefreshTokenName &&
                userToken.Value == inputModel.RefreshToken
                select new
            {
                ApplicationUser = applicationUser,
                Token = userToken
            }
                );

            var data = await query.FirstOrDefaultAsync();

            if (data == null)
            {
                return(ReasonResult <AuthResponse> .BadRequest(new Reason[] { new Reason("RefreshTokenNotFound", "Cannot find Refresh Token") }));
            }

            var    user         = data.ApplicationUser;
            string refreshToken = data.Token.Value;

            bool verify = await _userManager.VerifyUserTokenAsync(user, AuthSettings.RefreshTokenProvider, AuthSettings.RefreshTokenName, refreshToken);

            if (!verify)
            {
                return(ReasonResult <AuthResponse> .BadRequest(new Reason[] { new Reason("RefreshTokenInvalid", "Refresh Token is invalid") }));
            }

            string accessToken = _jwtGenerator.GenerateToken(user, out var expires);
            var    output      = new AuthResponse(accessToken, refreshToken, expires);

            return(ReasonResult <AuthResponse> .Success(output));
        }
Example #8
0
        public async Task <ReasonResult <GameModel> > TakeTurnAsync(int id, int turnX, int turnY, ClaimsUser user)
        {
            var game = await _dbContext.Games
                       .FirstOrDefaultAsync(x => x.Id == id);

            if (game == null)
            {
                return(ReasonResult <GameModel> .NotFound());
            }

            BoardPlayer player;

            if (game.PlayerOne == user.Id)
            {
                player = BoardPlayer.PlayerOne;
            }
            else if (game.PlayerTwo == user.Id)
            {
                player = BoardPlayer.PlayerTwo;
            }
            else
            {
                return(ReasonResult <GameModel> .NotFound());
            }

            if (game.GameState != GameState.InProgress)
            {
                _logger.LogInformation("Player tried to take turn on game with incorrect state, {@details}", new
                {
                    GameId    = game.Id,
                    GameState = game.GameState,
                    UserId    = user.Id,
                });

                return(ReasonResult <GameModel> .BadRequest(new[] { GameInWrongState }));
            }

            var oldDecompressedBoardState = new DecompressedBoardState(game.BoardHistory);
            var takeTurnResult            = oldDecompressedBoardState.TryTakeTurn(turnX, turnY, player, out var newDecompressedBoardState);

            switch (takeTurnResult)
            {
            case TakeTurnResult.Success:
            {
                _logger.LogInformation("Player took turn, {@details}", new
                    {
                        GameId          = game.Id,
                        UserId          = user.Id,
                        GameState       = game.GameState,
                        X               = turnX,
                        Y               = turnY,
                        OldBoardHistory = oldDecompressedBoardState.BoardHistory,
                        NewBoardHistory = newDecompressedBoardState.BoardHistory,
                        Snapshot        = newDecompressedBoardState.ToString(),
                    });

                UpdateGameUsingDecompressedBoardState(game, newDecompressedBoardState);

                await _dbContext.SaveChangesAsync();

                return(ReasonResult <GameModel> .Success(new GameModel(game)));
            }

            case TakeTurnResult.NotInProgress:
                return(ReasonResult <GameModel> .BadRequest(new[] { GameInWrongState }));

            case TakeTurnResult.TileAlreadySet:
                return(ReasonResult <GameModel> .BadRequest(new[] { TileAlreadySet }));

            case TakeTurnResult.WrongPlayer:
                return(ReasonResult <GameModel> .BadRequest(new[] { ActingOnWrongTurn }));

            default:
                throw new Exception($"Unknown failure state reached during {nameof(DecompressedBoardState)}.{nameof(DecompressedBoardState.TryTakeTurn)}");
            }
        }