예제 #1
0
        public async Task <ValuePair <TokenVm, string> > UserIdPasswordCreateTokenPairAsync(long userId, string password,
                                                                                            string deviceTokenId)
        {
            byte[] passwordHash = CreateUsersService.GetSha512Hash(password);
            using (MessengerDbContext context = contextFactory.Create())
            {
                User targetUser =
                    await context.Users.FirstOrDefaultAsync(user => user.Id == userId && user.Sha512Password.SequenceEqual(passwordHash) && !user.Deleted)
                    .ConfigureAwait(false);

                if (targetUser != null)
                {
                    string accessToken  = RandomExtensions.NextString(64);
                    string refreshToken = RandomExtensions.NextString(64);
                    Token  tokenPair    = new Token()
                    {
                        UserId       = userId,
                        AccessToken  = accessToken,
                        RefreshToken = refreshToken,
                        AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime(),
                        RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime(),
                        DeviceTokenId = deviceTokenId
                    };
                    string newPassword = RandomExtensions.NextString(CreateUsersService.PASSWORD_LENGTH);
                    targetUser.Sha512Password = CreateUsersService.GetSha512Hash(newPassword);
                    context.Users.Update(targetUser);
                    await context.Tokens.AddAsync(tokenPair).ConfigureAwait(false);

                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(new ValuePair <TokenVm, string>(TokenConverter.GetTokenVm(tokenPair), newPassword));
                }
            }
            throw new UserNotFoundException();
        }
예제 #2
0
        public async Task <TokenVm> RefreshTokenPairAsync(long userId, string refreshToken)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                Token target = await context.Tokens
                               .FirstOrDefaultAsync(token => token.RefreshToken == refreshToken && token.UserId == userId && !token.User.Deleted)
                               .ConfigureAwait(false);

                if (target != null)
                {
                    target.AccessToken  = RandomExtensions.NextString(64);
                    target.RefreshToken = RandomExtensions.NextString(64);
                    target.AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime();
                    target.RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime();
                    context.Tokens.Update(target);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(TokenConverter.GetTokenVm(target));
                }
                else
                {
                    throw new InvalidTokenException();
                }
            }
        }
예제 #3
0
        public async Task <TokenVm> CheckTokenAsync(TokenVm targetToken, long nodeId)
        {
            long userId = targetToken.UserId;

            using (MessengerDbContext context = contextFactory.Create())
            {
                Token tokenPair = await context.Tokens
                                  .Include(token => token.User)
                                  .FirstOrDefaultAsync(
                    token => token.UserId == userId && token.AccessToken == targetToken.AccessToken && !token.User.Deleted)
                                  .ConfigureAwait(false);

                if (tokenPair == null)
                {
                    User userInfo = await context.Users.FindAsync(userId).ConfigureAwait(false);

                    if (userInfo != null && userInfo.NodeId != nodeId)
                    {
                        throw new UserFromAnotherNodeException(userInfo.NodeId);
                    }
                    throw new InvalidTokenException();
                }

                if (DateTime.UtcNow <= tokenPair.AccessTokenExpirationTime.ToDateTime())
                {
                    tokenPair.DeviceTokenId = targetToken.DeviceTokenId;
                    context.Update(tokenPair);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(TokenConverter.GetTokenVm(tokenPair));
                }
                if (DateTime.UtcNow >= tokenPair.AccessTokenExpirationTime.ToDateTime() &&
                    DateTime.UtcNow <= tokenPair.RefreshTokenExpirationTime.GetValueOrDefault().ToDateTime())
                {
                    string accessToken  = RandomExtensions.NextString(64);
                    string refreshToken = RandomExtensions.NextString(64);
                    Token  newToken     = new Token
                    {
                        AccessToken                = accessToken,
                        RefreshToken               = refreshToken,
                        UserId                     = userId,
                        DeviceTokenId              = targetToken.DeviceTokenId,
                        AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime(),
                        RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime()
                    };
                    await context.Tokens.AddAsync(newToken).ConfigureAwait(false);

                    context.Remove(tokenPair);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    context.Database.CloseConnection();
                    return(TokenConverter.GetTokenVm(newToken));
                }
                throw new TokensTimeoutException();
            }
        }
예제 #4
0
        public async Task <TokenVm> UpdateTokenDataAsync(string osName, string deviceName, string appName, string ipAddress, TokenVm tokenVm)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var token = await context.Tokens.FirstOrDefaultAsync(opt =>
                                                                     opt.AccessToken == tokenVm.AccessToken &&
                                                                     opt.UserId == tokenVm.UserId).ConfigureAwait(false);

                token.AppName    = appName;
                token.DeviceName = deviceName;
                token.OSName     = osName;
                token.IPAddress  = ipAddress;
                context.Tokens.Update(token);
                await context.SaveChangesAsync().ConfigureAwait(false);

                return(TokenConverter.GetTokenVm(token));
            }
        }
예제 #5
0
        public async Task <TokenVm> UserIdVCodeCreateTokenPairAsync(long userId, short vCode,
                                                                    string deviceTokenId)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                User targetUser = await context.Users
                                  .Include(opt => opt.Phones)
                                  .FirstOrDefaultAsync(user => user.Id == userId && !user.Deleted)
                                  .ConfigureAwait(false);

                if (targetUser != null)
                {
                    if (!await verificationCodesService.IsVerificationCodeValidAsync(
                            targetUser.Phones.FirstOrDefault().PhoneNumber, userId, vCode).ConfigureAwait(false))
                    {
                        throw new WrongVerificationCodeException();
                    }
                    string accessToken  = RandomExtensions.NextString(64);
                    string refreshToken = RandomExtensions.NextString(64);
                    Token  tokenPair    = new Token()
                    {
                        UserId       = userId,
                        AccessToken  = accessToken,
                        RefreshToken = refreshToken,
                        AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime(),
                        RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime(),
                        DeviceTokenId = deviceTokenId
                    };
                    context.Users.Update(targetUser);
                    await context.Tokens.AddAsync(tokenPair).ConfigureAwait(false);

                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(TokenConverter.GetTokenVm(tokenPair));
                }
                throw new UserNotFoundException();
            }
        }
예제 #6
0
        public async Task <TokenVm> CreateTokenByQRCodeAsync(QRCodeContent qRCodeContent,
                                                             string deviceTokenId = null,
                                                             string osName        = null,
                                                             string deviceName    = null,
                                                             string appName       = null)
        {
            byte[] sequenceHash = GetSequenceHashSha512(qRCodeContent.Sequence);
            using (MessengerDbContext context = contextFactory.Create())
            {
                var qrCode = await context.QRCodes
                             .FirstOrDefaultAsync(qr => qr.UserId == qRCodeContent.UserId && qr.SequenceHash.SequenceEqual(sequenceHash))
                             .ConfigureAwait(false);

                if (qrCode == null)
                {
                    throw new ObjectDoesNotExistsException("QR-code with the data was not found.");
                }

                Token token = new Token
                {
                    AccessToken  = RandomExtensions.NextString(64),
                    RefreshToken = RandomExtensions.NextString(64),
                    AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(TokensService.ACCESS_LIFETIME_HOUR).ToUnixTime(),
                    RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(TokensService.REFRESH_LIFETIME_HOUR).ToUnixTime(),
                    AppName       = appName,
                    DeviceName    = deviceName,
                    OSName        = osName,
                    DeviceTokenId = deviceTokenId,
                    UserId        = qRCodeContent.UserId
                };
                await context.Tokens.AddAsync(token).ConfigureAwait(false);

                context.QRCodes.Remove(qrCode);
                await context.SaveChangesAsync().ConfigureAwait(false);

                return(TokenConverter.GetTokenVm(token));
            }
        }
예제 #7
0
        public async Task <TokenVm> CreateTokenPairByUserIdAsync(long userId, bool generateRefresh = true,
                                                                 int?tokenLifetimeSeconds          = ACCESS_LIFETIME_HOUR * 60 * 60)
        {
            string accessToken = RandomExtensions.NextString(64);
            var    tokenPair   = new Token()
            {
                UserId       = userId,
                AccessToken  = accessToken,
                RefreshToken = generateRefresh ? RandomExtensions.NextString(64) : null,
                AccessTokenExpirationTime = DateTime.UtcNow.AddSeconds(tokenLifetimeSeconds.GetValueOrDefault())
                                            .ToUnixTime(),
                RefreshTokenExpirationTime =
                    DateTime.UtcNow.AddSeconds(REFRESH_LIFETIME_HOUR * 60 * 60).ToUnixTime(),
            };

            using (MessengerDbContext context = contextFactory.Create())
            {
                await context.Tokens.AddAsync(tokenPair).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);
            }
            return(TokenConverter.GetTokenVm(tokenPair));
        }
예제 #8
0
        public async Task <TokenVm> EmailVCodeCreateTokenPairAsync(string email, short vCode,
                                                                   string deviceTokenId)
        {
            string accessToken  = RandomExtensions.NextString(64);
            string refreshToken = RandomExtensions.NextString(64);

            using (MessengerDbContext context = contextFactory.Create())
            {
                var targetUser =
                    await context.Users.FirstOrDefaultAsync(user => user.Emails.Any(p => p.EmailAddress == email) && !user.Deleted)
                    .ConfigureAwait(false);

                if (targetUser == null)
                {
                    throw new UserNotFoundException();
                }
                if (!await verificationCodesService.IsVerificationCodeValidAsync(email, targetUser.Id, vCode).ConfigureAwait(false))
                {
                    throw new WrongVerificationCodeException();
                }
                var tokenPair = new Token
                {
                    UserId       = targetUser.Id,
                    AccessToken  = accessToken,
                    RefreshToken = refreshToken,
                    AccessTokenExpirationTime  = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime(),
                    RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime(),
                    DeviceTokenId = deviceTokenId
                };
                await context.Tokens.AddAsync(tokenPair).ConfigureAwait(false);

                await context.SaveChangesAsync().ConfigureAwait(false);

                return(TokenConverter.GetTokenVm(tokenPair));
            }
        }