public async Task <UserSession> CreateSessionForExternalUser(ExternalUserDetails externalUserDetails) { var user = await _userBusinessLogic.FindByEmail(externalUserDetails.Email); if (user == null) { user = _userBusinessLogic.CreateUser(externalUserDetails); } else { if (user.Type != externalUserDetails.UserType) { throw new InvalidOperationException("Multiple sign-in providers are not supported for the same user."); } // Check number of active sessions var activeSessionsCount = _userSessionRepository.GetActiveUserSessionsCount(user.Id); if (activeSessionsCount >= ApplicationConstants.Sessions.MaxActiveSessions) { throw new InvalidOperationException($"Max number of active sessions reached for user '{user.Id}'."); } // Update user information user.FirstName = externalUserDetails.FirstName; user.LastName = externalUserDetails.LastName; user.DisplayName = externalUserDetails.DisplayName; user.PictureUrl = externalUserDetails.PictureUrl; } var session = new UserSession { Token = Guid.NewGuid(), // TODO: use cryptographically random tokens State = UserSessionState.Active, CreationDate = DateTime.UtcNow, UserId = user.Id }; _userSessionRepository.Add(session); return(session); }