Exemplo n.º 1
0
 public UserTokensNodeResponse(long requestId, TokenVm token, UserVm user)
 {
     Token        = token;
     User         = user;
     ResponseType = Enums.NodeResponseType.UserTokens;
     RequestId    = requestId;
 }
        public async Task HandleAsync()
        {
            NodeResponse response = default;

            try
            {
                TokenVm token = await tokensService.CheckTokenAsync(request.Token, NodeSettings.Configs.Node.Id).ConfigureAwait(false);

                UserVm user = await loadUsersService.GetUserAsync(token.UserId).ConfigureAwait(false);

                response = new UserTokensNodeResponse(request.RequestId, token, user);
            }
            catch (InvalidTokenException)
            {
                response = new ResultNodeResponse(request.RequestId, ErrorCode.InvalidAccessToken);
            }
            catch (TokensTimeoutException)
            {
                response = new ResultNodeResponse(request.RequestId, ErrorCode.AccessTokenTimeout);
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                response = new ResultNodeResponse(request.RequestId, ErrorCode.UnknownError);
            }
            finally
            {
                NodeWebSocketCommunicationManager.SendResponse(response, current);
            }
        }
Exemplo n.º 3
0
        private async Task <TokenVm> GenerateTokenRequest(User user, ClaimsIdentity identity)
        {
            var claims = new List <Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
                new Claim(JwtRegisteredClaimNames.Iat,
                          ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(),
                          ClaimValueTypes.Integer64)
            };

            foreach (var claim in identity.Claims)
            {
                claims.Add(claim);
            }

            // Create the JWT security token and encode it.
            var jwt = new JwtSecurityToken(
                _jwtOptions.Issuer,
                _jwtOptions.Audience,
                claims,
                _jwtOptions.NotBefore,
                _jwtOptions.Expiration,
                _jwtOptions.SigningCredentials);

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
            var token      = new TokenVm
            {
                ExpiresAt = DateTimeOffset.UtcNow.AddSeconds((int)_jwtOptions.ValidFor.TotalSeconds),
                Token     = encodedJwt,
                Email     = user.Email
            };

            return(token);
        }
Exemplo n.º 4
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();
            }
        }
Exemplo n.º 5
0
        public async Task <Response> CreateResponseAsync()
        {
            try
            {
                TokenVm token = await tokensService.RefreshTokenPairAsync(request.UserId, request.RefreshToken).ConfigureAwait(false);

                clientConnection.FileAccessToken = RandomExtensions.NextString(64);
                return(new TokensResponse(
                           request.RequestId,
                           token.UserId,
                           token.AccessToken,
                           token.RefreshToken,
                           clientConnection.FileAccessToken));
            }
            catch (InvalidTokenException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, "Invalid tokens.", ErrorCode.InvalidAccessToken));
            }
        }
Exemplo n.º 6
0
        public async Task <Response> CreateResponseAsync()
        {
            if (!NodeSettings.Configs.Node.UserRegistrationAllowed)
            {
                return(new ResultResponse(request.RequestId, "User registration is not allowed.", ErrorCode.PermissionDenied));
            }
            UserVm user = request.User;

            try
            {
                VerificationCodeInfo verificationCode = null;
                if (!request.User.Phones.IsNullOrEmpty() && request.User.Emails.IsNullOrEmpty())
                {
                    if (NodeSettings.Configs.Node.RegistrationMethod == RegistrationMethod.EmailRequired)
                    {
                        var errorObject = new
                        {
                            Email = "Email required"
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                    if (await loadUsersService.IsPhoneExistsAsync(request.User.Phones.FirstOrDefault().FullNumber).ConfigureAwait(false))
                    {
                        var errorObject = new
                        {
                            Phone = "Phone already exists"
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                    verificationCode = await verificationCodesService.GetUserVerificationCodeAsync(request.User.Phones.FirstOrDefault().FullNumber).ConfigureAwait(false);
                }
                else if (request.User.Phones.IsNullOrEmpty() && !request.User.Emails.IsNullOrEmpty())
                {
                    if (NodeSettings.Configs.Node.RegistrationMethod == RegistrationMethod.PhoneRequired)
                    {
                        var errorObject = new
                        {
                            Email = "Phone required"
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                    if (await loadUsersService.IsEmailExistsAsync(request.User.Emails.FirstOrDefault()).ConfigureAwait(false))
                    {
                        var errorObject = new
                        {
                            Email = "Email already exists."
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                    verificationCode = await verificationCodesService.GetUserVerificationCodeAsync(request.User.Emails.FirstOrDefault()).ConfigureAwait(false);
                }
                else
                {
                    if (NodeSettings.Configs.Node.RegistrationMethod != RegistrationMethod.NothingRequired)
                    {
                        var errorObject = new
                        {
                            Email = "Email only or phone only",
                            Phone = "Email only or phone only"
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                }
                if (verificationCode != null &&
                    verificationCode.VCode != request.VCode &&
                    (!request.User.Emails.IsNullOrEmpty() || !request.User.Phones.IsNullOrEmpty()))
                {
                    var errorObject = new
                    {
                        VCode = "Wrong verification code"
                    };
                    return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongVerificationCode));
                }
                ValuePair <UserVm, string> userPasswordPair = await createUsersService.CreateNewUserAsync(user, NodeSettings.Configs.Node.Id, NodeSettings.Configs.ConfirmUsers).ConfigureAwait(false);

                TokenVm tempTokens = await tokensService.CreateTokenPairByUserIdAsync(userPasswordPair.FirstValue.Id.GetValueOrDefault(), false, 30 * 60).ConfigureAwait(false);

                clientConn.FileAccessToken = RandomExtensions.NextString(64);
                BlockSegmentVm segment = await BlockSegmentsService.Instance.CreateNewUserSegmentAsync(
                    userPasswordPair.FirstValue,
                    NodeSettings.Configs.Node.Id,
                    NodeData.Instance.NodeKeys.SignPrivateKey,
                    NodeData.Instance.NodeKeys.SymmetricKey,
                    NodeData.Instance.NodeKeys.Password,
                    NodeData.Instance.NodeKeys.KeyId).ConfigureAwait(false);

                BlockGenerationHelper.Instance.AddSegment(segment);
                ShortUser shortUser = new ShortUser
                {
                    UserId      = userPasswordPair.FirstValue.Id.GetValueOrDefault(),
                    PrivateData = segment.PrivateData
                };
                nodeNoticeService.SendNewUsersNodeNoticeAsync(shortUser, segment);
                return(new TokensResponse(
                           request.RequestId,
                           userPasswordPair.FirstValue,
                           tempTokens.AccessToken,
                           tempTokens.RefreshToken,
                           clientConn.FileAccessToken,
                           userPasswordPair.SecondValue));
            }
            catch (CreateNewUserException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, ex.Message, ErrorCode.UnknownError));
            }
        }
Exemplo n.º 7
0
 public CheckTokenNodeRequest(long userId, TokenVm token)
 {
     UserId      = userId;
     Token       = token;
     RequestType = Enums.NodeRequestType.CheckToken;
 }
Exemplo n.º 8
0
        public async Task <Response> CreateResponseAsync()
        {
            try
            {
                clientConnection.FileAccessToken = RandomExtensions.NextString(64);
                TokensResponse response = default;
                if (request.DeviceTokenId != null && !string.IsNullOrWhiteSpace(request.DeviceTokenId))
                {
                    await tokensService.SetDeviceTokenIdNullAsync(request.DeviceTokenId).ConfigureAwait(false);
                }

                UserVm user = null;
                switch (request.LoginType)
                {
                case LoginType.VerificationCode:
                {
                    TokenVm token = null;
                    if (request.UidType == UidType.Phone)
                    {
                        token = await tokensService.PhoneVCodeCreateTokenPairAsync(request.Uid, request.VCode.GetValueOrDefault(), request.DeviceTokenId).ConfigureAwait(false);
                    }
                    else if (request.UidType == UidType.Email)
                    {
                        token = await tokensService.EmailVCodeCreateTokenPairAsync(request.Uid, request.VCode.GetValueOrDefault(), request.DeviceTokenId).ConfigureAwait(false);
                    }
                    else if (request.UidType == UidType.UserId)
                    {
                        token = await tokensService.UserIdVCodeCreateTokenPairAsync(Convert.ToInt64(request.Uid), request.VCode.GetValueOrDefault(), request.DeviceTokenId).ConfigureAwait(false);
                    }
                    clientConnection.UserId = token.UserId;
                    token = await tokensService.UpdateTokenDataAsync(request.OSName, request.DeviceName, request.AppName, clientConnection.ClientIP.ToString(), token).ConfigureAwait(false);

                    clientConnection.CurrentToken = token;
                    user = await loadUsersService.GetUserInformationAsync(token.UserId).ConfigureAwait(false);

                    response = new TokensResponse(request.RequestId, token, clientConnection.FileAccessToken, null, user);
                    noticeService.SendNewSessionNoticeAsync(clientConnection);
                }
                break;

                case LoginType.AccessTokenAndUserId:
                {
                    TokenVm token = new TokenVm
                    {
                        UserId        = request.Token.UserId,
                        AccessToken   = request.Token.AccessToken,
                        RefreshToken  = request.Token.RefreshToken,
                        DeviceTokenId = request.DeviceTokenId
                    };
                    token = await tokensService.CheckTokenAsync(token, NodeSettings.Configs.Node.Id).ConfigureAwait(false);

                    clientConnection.UserId = token.UserId;
                    token = await tokensService.UpdateTokenDataAsync(request.OSName, request.DeviceName, request.AppName, clientConnection.ClientIP.ToString(), token).ConfigureAwait(false);

                    clientConnection.CurrentToken = token;
                    user = await loadUsersService.GetUserInformationAsync(token.UserId).ConfigureAwait(false);

                    response = new TokensResponse(request.RequestId, token, clientConnection.FileAccessToken, null, user);
                }
                break;

                case LoginType.Password:
                {
                    ValuePair <TokenVm, string> tokenPasswordPair;
                    if (request.UidType == UidType.Phone)
                    {
                        tokenPasswordPair = await tokensService.PhonePasswordCreateTokenPairAsync(request.Uid, request.Password, request.DeviceTokenId).ConfigureAwait(false);
                    }
                    else if (request.UidType == UidType.Email)
                    {
                        tokenPasswordPair = await tokensService.EmailPasswordCreateTokenPairAsync(request.Uid, request.Password, request.DeviceTokenId).ConfigureAwait(false);
                    }
                    else if (request.UidType == UidType.UserId)
                    {
                        tokenPasswordPair = await tokensService.UserIdPasswordCreateTokenPairAsync(Convert.ToInt64(request.Uid), request.Password, request.DeviceTokenId).ConfigureAwait(false);
                    }
                    else
                    {
                        var errorObject = new
                        {
                            UidType = "Unknown UidType."
                        };
                        return(new ResultResponse(request.RequestId, ObjectSerializer.ObjectToJson(errorObject), ErrorCode.WrongArgumentError));
                    }
                    clientConnection.UserId      = tokenPasswordPair.FirstValue.UserId;
                    tokenPasswordPair.FirstValue =
                        await tokensService.UpdateTokenDataAsync(request.OSName, request.DeviceName, request.AppName, clientConnection.ClientIP.ToString(), tokenPasswordPair.FirstValue)
                        .ConfigureAwait(false);

                    clientConnection.CurrentToken = tokenPasswordPair.FirstValue;
                    user = await loadUsersService.GetUserInformationAsync(clientConnection.UserId.Value).ConfigureAwait(false);

                    response = new TokensResponse(
                        request.RequestId,
                        tokenPasswordPair.FirstValue,
                        clientConnection.FileAccessToken,
                        tokenPasswordPair.SecondValue,
                        user);
                    noticeService.SendNewSessionNoticeAsync(clientConnection);
                }
                break;
                }
                clientConnection.Confirmed = user.Confirmed;
                clientConnection.Banned    = user.Banned;
                connectionsService.AddOrUpdateUserConnection(clientConnection.UserId.Value, clientConnection);
                SendPendingMessagesAsync();
                return(response);
            }
            catch (InvalidTokenException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, "Invalid token.", ErrorCode.InvalidAccessToken));
            }
            catch (WrongVerificationCodeException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, "Invalid verification code.", ErrorCode.WrongVerificationCode));
            }
            catch (UserNotFoundException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, "User not found.", ErrorCode.UserNotFound));
            }
            catch (CreateTokenPairException ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, "Login failed.", ErrorCode.AuthorizationProblem));
            }
            catch (TokensTimeoutException ex)
            {
                Logger.WriteLog(ex, request);
                await noticeService.SendNeedLoginNoticeAsync(clientConnection).ConfigureAwait(false);

                return(new ResultResponse(request.RequestId, "Refresh token expired.", ErrorCode.RefreshTokenTimeout));
            }
            catch (UserFromAnotherNodeException ex)
            {
                await MetricsHelper.Instance.SetCrossNodeApiInvolvedAsync(request.RequestId).ConfigureAwait(false);

                var userToken = await nodeRequestSender.CheckTokenAsync(
                    request.Token.UserId,
                    request.Token,
                    ex.NodeId.GetValueOrDefault()).ConfigureAwait(false);

                if (userToken != null)
                {
                    clientConnection.UserId             = userToken.FirstValue.UserId;
                    clientConnection.ProxyNodeWebSocket = connectionsService.GetNodeConnection(ex.NodeId.GetValueOrDefault()).NodeWebSocket;
                    connectionsService.AddOrUpdateUserConnection(clientConnection.UserId.Value, clientConnection);
                    return(new TokensResponse(request.RequestId, userToken.FirstValue, clientConnection.FileAccessToken, null, userToken.SecondValue));
                }
                return(new ResultResponse(request.RequestId, "Login failed.", ErrorCode.AuthorizationProblem));
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex, request);
                return(new ResultResponse(request.RequestId, null, ErrorCode.UnknownError));
            }
        }
Exemplo n.º 9
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));
            }
        }
Exemplo n.º 10
0
        public async Task <ValuePair <TokenVm, UserVm> > CheckTokenAsync(long userId, TokenVm token, long nodeId)
        {
            var nodeConnection = connectionsService.GetNodeConnection(nodeId);

            if (nodeConnection != null)
            {
                CheckTokenNodeRequest request = new CheckTokenNodeRequest(userId, token);
                SendRequest(nodeConnection, request);
                NodeResponse nodeResponse = await GetResponseAsync(request).ConfigureAwait(false);

                switch (nodeResponse.ResponseType)
                {
                case NodeResponseType.UserTokens:
                {
                    UserTokensNodeResponse tokensResponse = (UserTokensNodeResponse)nodeResponse;
                    return(new ValuePair <TokenVm, UserVm>(tokensResponse.Token, tokensResponse.User));
                }

                default:
                    return(null);
                }
            }
            else
            {
                return(null);
            }
        }