public async Task CollectingGameService_WhenPlayersOrFursuitsHaveSameCollectionCount_ThenWhoeverAchievedItFirstRanksHigher()
        {
            var players       = new RegSysIdentityRecord[3];
            var tokens        = new TokenRecord[3];
            var fursuitBadges = new FursuitBadgeRecord[3];

            // 3 players, each with suit
            for (int i = 0; i < 3; i++)
            {
                players[i] = await CreateRegSysIdentityAsync();

                tokens[i] = await CreateTokenAsync();

                fursuitBadges[i] = await CreateFursuitBadgeAsync(players[i].Uid);

                await _collectingGameService.RegisterTokenForFursuitBadgeForOwnerAsync(
                    players[i].Uid, fursuitBadges[i].Id, tokens[i].Value);
            }

            // Each catches everyone else.
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (j == i)
                    {
                        continue;
                    }

                    var result = await _collectingGameService.CollectTokenForPlayerAsync(
                        players[i].Uid, tokens[j].Value);

                    Assert.True(result.IsSuccessful);
                }
            }

            var playerScoreboard = await _collectingGameService.GetPlayerScoreboardEntriesAsync(5);

            var fursuitScoreboard = await _collectingGameService.GetFursuitScoreboardEntriesAsync(5);

            // 1 catches first, then 2, then 3
            Assert.Equal(3, playerScoreboard.Value.Length);
            Assert.True(playerScoreboard.Value.All(a => a.CollectionCount == 2));
            Assert.Equal(players[0].Username, playerScoreboard.Value[0].Name);
            Assert.Equal(players[1].Username, playerScoreboard.Value[1].Name);
            Assert.Equal(players[2].Username, playerScoreboard.Value[2].Name);

            // 3 gets the 2 catches first (by 1 + 2), then 1 (by 2 + 3), then 2
            Assert.Equal(3, fursuitScoreboard.Value.Length);
            Assert.True(fursuitScoreboard.Value.All(a => a.CollectionCount == 2));
            Assert.Equal(fursuitBadges[2].Id, fursuitScoreboard.Value[0].BadgeId);
            Assert.Equal(fursuitBadges[0].Id, fursuitScoreboard.Value[1].BadgeId);
            Assert.Equal(fursuitBadges[1].Id, fursuitScoreboard.Value[2].BadgeId);
        }
        private async Task <RegSysIdentityRecord> CreateRegSysIdentityAsync()
        {
            var id     = Guid.NewGuid();
            var record = new RegSysIdentityRecord()
            {
                Id       = id,
                Uid      = $"Test:{id}",
                Username = $"Test Attendee {id}",
                Roles    = new[] { "Attendee" },
            };

            await _regSysIdentityRepository.InsertOneAsync(record);

            return(record);
        }
        public async Task <AuthenticationResponse> AuthorizeViaRegSys(RegSysAuthenticationRequest request)
        {
            AuthenticationResult authenticationResult = null;

            foreach (var provider in _authenticationProviders)
            {
                var providerResult = await provider.ValidateRegSysAuthenticationRequestAsync(request);

                if (providerResult.IsAuthenticated)
                {
                    authenticationResult = providerResult;
                    break;
                }
            }

            if (authenticationResult == null)
            {
                _logger.LogWarning(LogEvents.Audit, "Authentication failed for {Username} {RegNo}", request.Username, request.RegNo);
                return(null);
            }

            var uid = $"RegSys:{_conventionSettings.ConventionNumber}:{authenticationResult.RegNo}";

            var identityRecord = await _regSysIdentityRepository.FindOneAsync(a => a.Uid == uid);

            if (identityRecord == null)
            {
                identityRecord = new RegSysIdentityRecord
                {
                    Id    = Guid.NewGuid(),
                    Uid   = uid,
                    Roles = new List <string>()
                    {
                        "Attendee"
                    }
                };
                await _regSysIdentityRepository.InsertOneAsync(identityRecord);
            }

            if (!String.IsNullOrWhiteSpace(request.AccessToken))
            {
                var accessToken = await _regSysAccessTokenRepository.FindOneAsync(a => a.Token == request.AccessToken);

                if (accessToken != null && !accessToken.ClaimedAtDateTimeUtc.HasValue)
                {
                    identityRecord.Roles = identityRecord.Roles
                                           .Concat(accessToken.GrantRoles)
                                           .Distinct()
                                           .ToArray();

                    accessToken.ClaimedByUid         = identityRecord.Uid;
                    accessToken.ClaimedAtDateTimeUtc = DateTime.UtcNow;

                    await _regSysAccessTokenRepository.ReplaceOneAsync(accessToken);
                }
            }

            identityRecord.Username = authenticationResult.Username;
            await _regSysIdentityRepository.ReplaceOneAsync(identityRecord);


            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.Name, uid),
                new Claim(ClaimTypes.GivenName, authenticationResult.Username),
                new Claim(ClaimTypes.PrimarySid, authenticationResult.RegNo.ToString()),
                new Claim(ClaimTypes.GroupSid, _conventionSettings.ConventionNumber.ToString()),
                new Claim(ClaimTypes.System, "RegSys")
            };

            claims.AddRange(identityRecord.Roles.Select(role => new Claim(ClaimTypes.Role, role)));

            var expiration = DateTime.UtcNow.Add(_authenticationSettings.DefaultTokenLifeTime);
            var token      = _tokenFactory.CreateTokenFromClaims(claims, expiration);

            var response = new AuthenticationResponse
            {
                Uid             = uid,
                Token           = token,
                TokenValidUntil = expiration,
                Username        = $"{authenticationResult.Username} ({authenticationResult.RegNo})"
            };

            _logger.LogInformation(LogEvents.Audit, "Authentication successful for {Username} {RegNo} ({Uid}) via {Source}",
                                   authenticationResult.Username, authenticationResult.RegNo, response.Uid, authenticationResult.Source);

            return(response);
        }
示例#4
0
        public async Task <AuthenticationResponse> AuthorizeViaRegSys(RegSysAuthenticationRequest request)
        {
            AuthenticationResult authenticationResult = null;

            foreach (var provider in _authenticationProviders)
            {
                var providerResult = await provider.ValidateRegSysAuthenticationRequestAsync(request);

                if (providerResult.IsAuthenticated)
                {
                    authenticationResult = providerResult;
                    break;
                }
            }

            if (authenticationResult == null)
            {
                _logger.LogWarning("Authentication failed for {Username} {RegNo}", request.Username, request.RegNo);
                return(null);
            }

            var uid = $"RegSys:{_conventionSettings.ConventionNumber}:{authenticationResult.RegNo}";

            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.Name, uid),
                new Claim(ClaimTypes.GivenName, authenticationResult.Username),
                new Claim(ClaimTypes.PrimarySid, authenticationResult.RegNo.ToString()),
                new Claim(ClaimTypes.GroupSid, _conventionSettings.ConventionNumber.ToString()),
                new Claim(ClaimTypes.Role, "Attendee"),
                new Claim(ClaimTypes.System, "RegSys")
            };

            var expiration = DateTime.UtcNow.Add(_authenticationSettings.DefaultTokenLifeTime);
            var token      = _tokenFactory.CreateTokenFromClaims(claims, expiration);

            var response = new AuthenticationResponse
            {
                Uid             = uid,
                Token           = token,
                TokenValidUntil = expiration,
                Username        = $"{authenticationResult.Username} ({authenticationResult.RegNo})"
            };

            var identityRecord = await _regSysIdentityRepository.FindOneAsync(a => a.Uid == uid);

            if (identityRecord == null)
            {
                identityRecord = new RegSysIdentityRecord
                {
                    Id  = Guid.NewGuid(),
                    Uid = uid
                };
                await _regSysIdentityRepository.InsertOneAsync(identityRecord);
            }

            identityRecord.Username = authenticationResult.Username;
            await _regSysIdentityRepository.ReplaceOneAsync(identityRecord);

            _logger.LogInformation("Authentication successful for {Username} {RegNo} via {Source}",
                                   authenticationResult.Username, authenticationResult.RegNo, authenticationResult.Source);

            return(response);
        }