public async Task SetProjectGuestContext_IfUserIsAGuestInTheSameAccountAndWhenAdmittedFromLobbyWasPromotedToMember_ClearsProjectGuestContext()
        {
            var guestSessionId = Guid.NewGuid();

            _projectGuestContextServiceMock
            .Setup(x => x.GetProjectGuestContextAsync(It.IsAny <string>()))
            .ReturnsAsync(new ProjectGuestContext()
            {
                GuestSessionId = guestSessionId,
                GuestState     = Guest.ProjectContext.Enums.GuestState.PromotedToProjectMember,
                ProjectId      = _defaultProjectId,
                TenantId       = _projectTenantId
            });

            var guestSession = new GuestSession {
                Id = guestSessionId, ProjectId = _defaultProjectId, UserId = _currentUserId, ProjectAccessCode = _defaultAccessCode, GuestSessionState = GuestState.PromotedToProjectMember
            };

            _guestSessionRepositoryMock
            .Setup(x => x.GetItemAsync(It.Is <Guid>(g => g == guestSessionId), It.IsAny <QueryOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(guestSession);

            _guestSessionRepositoryMock
            .Setup(x => x.GetItemsAsync(It.IsAny <Expression <Func <GuestSession, bool> > >(), It.IsAny <BatchOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new List <GuestSession> {
                guestSession
            });

            await _target.SetProjectGuestContextAsync(_defaultProjectId, null, _currentUserId, _projectTenantId, _defaultPrincipalId);

            _projectGuestContextServiceMock
            .Verify(y => y.SetProjectGuestContextAsync(It.Is <ProjectGuestContext>(x =>
                                                                                   x.ProjectId == Guid.Empty &&
                                                                                   x.GuestSessionId == Guid.Empty), It.IsAny <string>()));
        }
コード例 #2
0
        /// <summary>
        /// Updates statistic
        /// </summary>
        /// <param name="session"> Session which will be used to retrieve the statistic </param>
        public void Update(GuestSession session)
        {
            var res = session.Get("http://www.elitepvpers.com/forum/");
            var doc = new HtmlDocument();

            doc.LoadHtml(res);

            var statsNode = doc.GetElementbyId("collapseobj_forumhome_stats");

            if (statsNode == null)
            {
                return;
            }

            statsNode = statsNode.SelectSingleNode("tr[1]/td[2]/div[1]/div[1]");
            if (statsNode == null)
            {
                return;
            }

            var match = Regex.Matches(statsNode.InnerText, "([0-9,]+)");

            if (match.Count == 3)
            {
                Threads = match[0].Groups[1].Value.Replace(",", "").To <uint>();
                Posts   = match[1].Groups[1].Value.Replace(",", "").To <uint>();
                Members = match[2].Groups[1].Value.Replace(",", "").To <uint>();
            }
        }
コード例 #3
0
        public void SignIn()
        {
            if (!EmailValidator.Validate())
            {
                return;
            }

            Guest guest;

            try {
                guest = Business.Guest(new Email(email.Text));
                EmailValidator.ResetError();
            } catch (InexistentEmailException ex) {
                EmailValidator.SetError(ex.Message);
                return;
            }

            if (!PasswordValidator.Validate())
            {
                return;
            }

            try {
                GuestSession.SignIn(guest, password.Password);
                PasswordValidator.ResetError();
                Frame.Navigate(new GuestPage(Business, GuestSession, Frame));
            } catch (WrongPasswordException ex) {
                PasswordValidator.SetError(ex.Message);
            }
        }
コード例 #4
0
        public async Task TestAuthenticationCreateGuestSessionAsync()
        {
            GuestSession guestSession = await TMDbClient.AuthenticationCreateGuestSessionAsync();

            Assert.NotNull(guestSession);
            Assert.True(guestSession.Success);
            Assert.NotNull(guestSession.GuestSessionId);
        }
コード例 #5
0
        public void TestAuthenticationCreateGuestSession()
        {
            GuestSession guestSession = _config.Client.AuthenticationCreateGuestSession();

            Assert.IsNotNull(guestSession);
            Assert.IsTrue(guestSession.Success);
            Assert.IsNotNull(guestSession.ExpiresAt);
            Assert.IsNotNull(guestSession.GuestSessionId);
        }
コード例 #6
0
        public async Task <GuestSession> AuthenticationCreateGuestSessionAsync(CancellationToken cancellationToken = default)
        {
            RestRequest request = _client.Create("authentication/guest_session/new");
            //{
            //    DateFormat = "yyyy-MM-dd HH:mm:ss UTC"
            //};

            GuestSession response = await request.GetOfT <GuestSession>(cancellationToken).ConfigureAwait(false);

            return(response);
        }
コード例 #7
0
        /// <summary>
        /// Updates the user by requesting the profile
        /// </summary>
        /// <param name="session"> Session used for sending the request </param>
        public void Update(GuestSession session)
        {
            if (ID == 0)
            {
                throw new ArgumentException("User ID must not be 0");
            }
            var res = session.Get(GetUrl());

            var doc = new HtmlDocument();

            doc.LoadHtml(res);
            new UserParser(this, false).Execute(doc);
        }
コード例 #8
0
        /// <summary>
        /// Updates information about the section
        /// </summary>
        /// <param name="session"> Session used for storing personal shoutbox data into the session user field </param>
        public void Update(GuestSession session)
        {
            if (Shortname == String.Empty)
            {
                throw new ArgumentException("Sections cannot be updated if no url-address-name is provided");
            }

            var res = session.Get(String.Format("https://www.elitepvpers.com/forum/{0}/", Shortname));
            var doc = new HtmlDocument();

            doc.LoadHtml(res);

            PageCount = new Regex(@"<td.*?>Page \d+ of (\d+)</td>").Match(doc.DocumentNode.InnerHtml).Groups[1].Value.To <UInt32>();

            new SectionParser.AnnouncementsParser(this).Execute(doc.GetElementbyId("threadslist"));
        }
コード例 #9
0
 private GuestSession CloneGuestSession(GuestSession guestSession)
 {
     return(new GuestSession
     {
         Id = guestSession.Id,
         AccessGrantedBy = guestSession.AccessGrantedBy,
         AccessGrantedDateTime = guestSession.AccessGrantedDateTime,
         AccessRevokedBy = guestSession.AccessRevokedBy,
         AccessRevokedDateTime = guestSession.AccessRevokedDateTime,
         CreatedDateTime = guestSession.CreatedDateTime,
         EmailedHostDateTime = guestSession.EmailedHostDateTime,
         GuestSessionState = guestSession.GuestSessionState,
         ProjectId = guestSession.ProjectId,
         ProjectAccessCode = guestSession.ProjectAccessCode,
         UserId = guestSession.UserId
     });
 }
        public async Task SetProjectGuestContext_IfUserHasDifferentTenantHasBeenAdmittedToProject_UserHasAccessIsTrue()
        {
            var guestSessionId = Guid.NewGuid();

            _projectGuestContextServiceMock
            .Setup(x => x.GetProjectGuestContextAsync(It.IsAny <string>()))
            .ReturnsAsync(new ProjectGuestContext()
            {
                GuestSessionId = guestSessionId,
                GuestState     = Guest.ProjectContext.Enums.GuestState.InProject,
                ProjectId      = _defaultProjectId,
                TenantId       = _projectTenantId
            });

            _projectAccessApiMock
            .Setup(x => x.GetProjectMemberUserIdsAsync(_defaultProjectId, MemberRoleFilter.FullUser, _defaultProjectTenantHeaders))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK, (new List <Guid>()).AsEnumerable()));

            var guestSession = new GuestSession {
                Id = guestSessionId, ProjectId = _defaultProjectId, UserId = _currentUserId, ProjectAccessCode = _defaultAccessCode, GuestSessionState = GuestState.InProject
            };

            _guestSessionRepositoryMock
            .Setup(x => x.GetItemAsync(It.Is <Guid>(g => g == guestSessionId), It.IsAny <QueryOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(guestSession);

            _guestSessionRepositoryMock
            .Setup(x => x.GetItemsAsync(It.IsAny <Expression <Func <GuestSession, bool> > >(), It.IsAny <BatchOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new List <GuestSession> {
                guestSession
            });

            var response = await _target.SetProjectGuestContextAsync(_defaultProjectId, "code", _currentUserId, Guid.NewGuid(), _defaultPrincipalId);

            Assert.True(response.UserHasAccess);
        }
コード例 #11
0
        /// <summary>
        /// Retrieves information about the <c>SectionThread</c>
        /// </summary>
        /// <param name="session"> Session used for sending the request </param>
        /// <remarks>
        /// ID and the section represented by a <c>Section</c> object is required in order to update.
        /// </remarks>
        public void Update(GuestSession session)
        {
            if (ID == 0)
            {
                throw new ArgumentException("ID must not be empty");
            }
            if (String.IsNullOrEmpty(Section.Shortname))
            {
                throw new ArgumentException("The section needs to be addressable");
            }

            var res          = session.Get(GetUrl());
            var htmlDocument = new HtmlDocument();

            htmlDocument.LoadHtml(res);

            var postsRootNode = htmlDocument.GetElementbyId("posts");

            if (postsRootNode == null)
            {
                return;
            }

            Closed = htmlDocument.DocumentNode.Descendants().GetElementsByName("img")
                     .Any(node => node.Attributes.Contains("src")
                                ? node.Attributes["src"].Value.Contains("threadclosed.gif")
                                : false);

            var currentRatingNode = htmlDocument.GetElementbyId("threadrating_current");

            if (currentRatingNode != null)
            {
                currentRatingNode = currentRatingNode.SelectSingleNode("img[1]");
                if (currentRatingNode != null)
                {
                    if (currentRatingNode.Attributes.Contains("alt"))
                    {
                        var ratingMatch = new Regex(@",\s+([0-9](?:,|.)[0-9]{2})\s+\S+").Match(currentRatingNode.Attributes["alt"].Value);
                        if (ratingMatch.Groups.Count > 1)
                        {
                            Rating = ratingMatch.Groups[1].Value.To <double>();
                        }
                    }
                }
            }

            var tagsRootNode = htmlDocument.GetElementbyId("tag_list_cell");

            if (tagsRootNode != null)
            {
                foreach (var tagNode in tagsRootNode.ChildNodes.GetElementsByTagName("a"))
                {
                    Tags.Add(tagNode.InnerText);
                }
            }

            var pageCountRootNode = htmlDocument.GetElementbyId("poststop");

            if (pageCountRootNode != null)
            {
                pageCountRootNode = pageCountRootNode.SelectSingleNode("following-sibling::table[1]/tr[1]/td[2]/div[1]/table[1]/tr[1]/td[1]");
                if (pageCountRootNode != null)
                {
                    var countMatch = new Regex(@"\S+\s{1}[0-9]+\s{1}\S+\s{1}([0-9]+)").Match(pageCountRootNode.InnerText);
                    if (countMatch.Groups.Count > 1)
                    {
                        PageCount = countMatch.Groups[1].Value.To <uint>();
                    }
                }
            }
        }
コード例 #12
0
        public async Task RecalculateProjectLobbyStateAsync_ReturnsExpectedLobbyState(int fullMemberParticipantCount, int guestSessionCount, LobbyState lobbyState)
        {
            var project   = Project.Example();
            var projectId = project.Id;

            var participants = new List <Participant>();

            for (int i = 1; i <= fullMemberParticipantCount; i++)
            {
                var participant = Participant.Example();
                ParticipantExtensions.SetProjectId(participant, project.Id);
                participant.GuestSessionId = null;
                participant.IsGuest        = false;
                participants.Add(participant);
            }

            _sessionServiceMock.Setup(m => m.GetParticipantsByGroupNameAsync(It.IsAny <string>(), It.IsAny <bool>(), false))
            .ReturnsAsync(participants);

            var guestSessions = new List <GuestSession>();

            project.GuestAccessCode = Guid.NewGuid().ToString();
            for (int i = 1; i <= guestSessionCount; i++)
            {
                var guestSession = GuestSession.Example();
                guestSession.ProjectId         = projectId;
                guestSession.ProjectAccessCode = project.GuestAccessCode;
                guestSession.GuestSessionState = GuestState.InProject;
                guestSession.CreatedDateTime   = DateTime.UtcNow;
                guestSession.UserId            = Guid.NewGuid();
                guestSessions.Add(guestSession);

                // Should never have more than one InProject sessions for same user and project,
                // but need to test LINQ query with group by, where, and order by clauses,
                // for correct calculation of current guest quantity.
                var guestSession2 = CloneGuestSession(guestSession);
                guestSession2.CreatedDateTime = DateTime.UtcNow.AddHours(-1.0);
                guestSessions.Add(guestSession2);

                var guestSession3 = CloneGuestSession(guestSession);
                guestSession3.CreatedDateTime = DateTime.UtcNow.AddHours(-2.0);
                guestSessions.Add(guestSession3);
            }

            _guestSessionRepositoryMock
            .Setup(m => m.GetItemsAsync(It.IsAny <Expression <Func <GuestSession, bool> > >(), It.IsAny <BatchOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(guestSessions);

            _projectApi
            .Setup(m => m.GetProjectByIdAsync(It.IsAny <Guid>(), null))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK, project));

            _cacheMock
            .SetupSequence(m => m.ItemGetAsync(It.IsAny <List <string> >(), typeof(ProjectLobbyState)))
            .ReturnsAsync(new List <ProjectLobbyState>()
            {
                default(ProjectLobbyState)
            });

            _cacheMock
            .Setup(m => m.ItemSetAsync(It.IsAny <string>(), It.IsAny <ProjectLobbyState>(), It.IsAny <TimeSpan>(), It.IsAny <CacheCommandOptions>()))
            .Returns(Task.FromResult(ProjectLobbyState.Example()));

            var result = await _target.RecalculateProjectLobbyStateAsync(project.Id);

            Assert.IsAssignableFrom <ProjectLobbyState>(result);
            Assert.Equal(lobbyState, result.LobbyState);
        }
        public ProjectGuestContextControllerTests()
        {
            _defaultProject = new Project()
            {
                Id = _defaultProjectId, TenantId = _projectTenantId, GuestAccessCode = _defaultAccessCode
            };
            _defaultPrincipalId          = Guid.NewGuid();
            _defaultProjectTenantHeaders = new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>(HeaderKeys.Tenant, _defaultProject.TenantId.ToString())
            };
            _defaultUser = new User {
                Id = _currentUserId, Username = "******"
            };
            var defaultProjectLobbyState = new ProjectLobbyState {
                LobbyState = LobbyState.Normal, ProjectId = _defaultProjectId
            };

            _defaultGuestSession = new GuestSession {
                Id = Guid.NewGuid(), ProjectId = _defaultProjectId, UserId = _currentUserId, ProjectAccessCode = _defaultAccessCode, GuestSessionState = GuestState.InLobby, SessionId = _defaultUserSessionId
            };
            _defaultProjectGuestContext = new ProjectGuestContext
            {
                GuestSessionId = _defaultGuestSession.Id,
                GuestState     = Guest.ProjectContext.Enums.GuestState.InLobby,
                ProjectId      = _defaultProjectId,
                TenantId       = _projectTenantId
            };

            var repositoryFactoryMock = new Mock <IRepositoryFactory>();

            repositoryFactoryMock
            .Setup(x => x.CreateRepository <GuestSession>())
            .Returns(_guestSessionRepositoryMock.Object);

            _projectGuestContextServiceMock
            .Setup(x => x.GetProjectGuestContextAsync(It.IsAny <string>()))
            .ReturnsAsync(_defaultProjectGuestContext);

            _projectAccessApiMock
            .Setup(x => x.GrantProjectMembershipAsync(It.IsAny <GrantProjectMembershipRequest>(), _defaultProjectTenantHeaders))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK));

            _guestSessionControllerMock
            .Setup(x => x.UpdateGuestSessionStateAsync(It.IsAny <UpdateGuestSessionStateRequest>(), It.IsAny <Guid>()))
            .ReturnsAsync(new UpdateGuestSessionStateResponse());

            _guestSessionControllerMock
            .Setup(x => x.VerifyGuestAsync(It.IsAny <GuestVerificationRequest>(), It.IsAny <Project>(), It.IsAny <Guid?>()))
            .ReturnsAsync(new GuestVerificationResponse()
            {
                ResultCode = VerifyGuestResponseCode.Success
            });

            _guestSessionControllerMock
            .Setup(x => x.CreateGuestSessionAsync(It.IsAny <GuestSession>(), _defaultPrincipalId, It.IsAny <Guid>()))
            .ReturnsAsync(_defaultGuestSession);

            _userApiMock
            .Setup(x => x.GetUserAsync(_currentUserId))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK, _defaultUser));

            _serviceToServiceProjectApiMock
            .Setup(x => x.GetProjectByIdAsync(_defaultProjectId, null))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK, _defaultProject));

            _projectAccessApiMock
            .Setup(x => x.GetProjectMemberUserIdsAsync(_defaultProjectId, MemberRoleFilter.FullUser, _defaultProjectTenantHeaders))
            .ReturnsAsync(MicroserviceResponse.Create(HttpStatusCode.OK, (new List <Guid>()
            {
                _currentUserId
            }).AsEnumerable()));

            _projectLobbyStateControllerMock
            .Setup(x => x.GetProjectLobbyStateAsync(_defaultProjectId))
            .ReturnsAsync(defaultProjectLobbyState);

            _target = new ProjectGuestContextController(repositoryFactoryMock.Object,
                                                        _guestSessionControllerMock.Object,
                                                        _projectLobbyStateControllerMock.Object,
                                                        _projectGuestContextServiceMock.Object,
                                                        _projectAccessApiMock.Object,
                                                        _serviceToServiceProjectApiMock.Object,
                                                        _userApiMock.Object);
        }
        /// <summary>
        /// Updates the input GuestSession in the repository and synchronizes
        /// that state on the associated ProjectGuestContext cache item. Publishes
        /// the GuestSessionUpdated event if all operations succeed.
        /// </summary>
        /// <param name="guestSessionModel"></param>
        /// <param name="principalId"></param>
        /// <returns>The updated <see cref="GuestSession">GuestSession</see> as Task&lt;GuestSession&gt;</returns>
        /// <remarks>It is the caller's responsiblity to cause the ProjectLobbyState
        /// to be calculated after the update, as appropriate, as well as for the
        /// ProjectStatusUpdated event to be published. That event triggers the MessageHub to
        /// publish the NotifyProjectStatusChanged message to subscribed SignalR connections.
        /// That message most importantly communicates the changed ProjectLobbyState
        /// to subscribed client applications.
        /// </remarks>
        public async Task <GuestSession> UpdateGuestSessionAsync(GuestSession guestSessionModel, Guid principalId)
        {
            var validationResult = _validatorLocator.ValidateMany(new Dictionary <Type, object>
            {
                { typeof(GuestSessionIdValidator), guestSessionModel.Id },
                { typeof(GuestSessionValidator), guestSessionModel }
            });

            if (!validationResult.IsValid)
            {
                _logger.Error("Failed to validate the resource id and/or resource while attempting to update a GuestSession resource.");
                throw new ValidationFailedException(validationResult.Errors);
            }

            switch (guestSessionModel.GuestSessionState)
            {
            case GuestState.Ended:
                guestSessionModel.AccessRevokedDateTime = DateTime.UtcNow;
                guestSessionModel.AccessRevokedBy       = principalId;
                break;

            case GuestState.InProject:
                guestSessionModel.AccessGrantedDateTime = DateTime.UtcNow;
                guestSessionModel.AccessGrantedBy       = principalId;
                break;
            }

            var existingGuestSession = await _guestSessionRepository.GetItemAsync(guestSessionModel.Id);

            if (existingGuestSession == null)
            {
                throw new NotFoundException();
            }

            guestSessionModel.ProjectTenantId = existingGuestSession.ProjectTenantId;

            var result = await _guestSessionRepository.UpdateItemAsync(guestSessionModel.Id, guestSessionModel);

            if (guestSessionModel.GuestSessionState == GuestState.Ended)
            {
                await _projectGuestContextService.RemoveProjectGuestContextAsync(guestSessionModel.SessionId);
            }
            else
            {
                var existingProjectGuestContext = await _projectGuestContextService.GetProjectGuestContextAsync(result.SessionId);

                var guestState = (Guest.ProjectContext.Enums.GuestState)result.GuestSessionState;

                await _projectGuestContextService.SetProjectGuestContextAsync(new ProjectGuestContext
                {
                    GuestSessionId = existingProjectGuestContext.GuestSessionId,
                    ProjectId      = existingProjectGuestContext.ProjectId,
                    GuestState     = guestState,
                    TenantId       = existingProjectGuestContext.TenantId
                }, result.SessionId);
            }

            _eventService.Publish(EventNames.GuestSessionUpdated, result);

            return(result);
        }
        public async Task <GuestSession> CreateGuestSessionAsync(GuestSession model, Guid principalId, Guid tenantId)
        {
            var validationResult = _validatorLocator.Validate <GuestSessionValidator>(model);

            if (!validationResult.IsValid)
            {
                _logger.Error("Validation failed while attempting to create a GuestSession resource.");
                throw new ValidationFailedException(validationResult.Errors);
            }

            Task <MicroserviceResponse <Project> > getProjectTask = null;

            var isTenantUnknown = tenantId == Guid.Empty;

            if (isTenantUnknown)
            {
                getProjectTask = _serviceToServiceProjectApi.GetProjectByIdAsync(model.ProjectId);
            }

            await EndGuestSessionsForUser(model.UserId, principalId);

            if (isTenantUnknown)
            {
                var projectResponse = await getProjectTask;
                if (!projectResponse.IsSuccess())
                {
                    throw new InvalidOperationException($"Error fetching tenantid for project {model.ProjectId}: {projectResponse.ResponseCode} - {projectResponse.ReasonPhrase} ");
                }

                model.ProjectTenantId = projectResponse.Payload.TenantId;
            }
            else
            {
                model.ProjectTenantId = tenantId;
            }

            model.Id = model.Id == Guid.Empty ? Guid.NewGuid() : model.Id;
            model.CreatedDateTime = DateTime.UtcNow;

            if (_requestHeaders.Keys.Contains("SessionIdString"))
            {
                model.SessionId = _requestHeaders["SessionIdString"].FirstOrDefault();
            }
            else if (_requestHeaders.Keys.Contains("SessionId"))
            {
                model.SessionId = _requestHeaders["SessionId"].FirstOrDefault();
            }
            else
            {
                throw new BadRequestException("Request headers do not contain a SessionId");
            }

            var result = await _guestSessionRepository.CreateItemAsync(model);

            // Delete all prior guest sessions with the same UserId and ProjectId as the session just created.
            await _guestSessionRepository.DeleteItemsAsync(x => x.UserId == model.UserId &&
                                                           x.ProjectId == model.ProjectId &&
                                                           x.Id != result.Id);

            await _projectLobbyStateController.RecalculateProjectLobbyStateAsync(model.ProjectId);

            _eventService.Publish(EventNames.GuestSessionCreated, result);

            return(result);
        }