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); } }
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); }
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(); } }
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)); } }
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)); } }
public CheckTokenNodeRequest(long userId, TokenVm token) { UserId = userId; Token = token; RequestType = Enums.NodeRequestType.CheckToken; }
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)); } }
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)); } }
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); } }