예제 #1
0
        internal ScoreSheet Sign(string signature)
        {
            var newScoreSheet = new ScoreSheet(this);

            newScoreSheet.Signature = signature;
            return(newScoreSheet);
        }
예제 #2
0
        internal ScoreSheet Finish()
        {
            var newScoreSheet = new ScoreSheet(this);

            newScoreSheet.FinishedTimestamp = DateTimeOffset.Now;
            return(newScoreSheet);
        }
예제 #3
0
        public ScoreSheet CompletePuzzle(ScoreSheet scoreSheet)
        {
            if (!IsAuthentic(scoreSheet))
            {
                throw new InvalidOperationException("Score sheet is not authentic");
            }

            if (!scoreSheet.CompletedPuzzles.Contains(scoreSheet.CurrentPuzzle))
            {
                scoreSheet = scoreSheet.Complete(scoreSheet.CurrentPuzzle);
            }

            var remainingPuzzles = Puzzle.Ids.Except(scoreSheet.CompletedPuzzles).ToArray();

            if (remainingPuzzles.Any())
            {
                scoreSheet = scoreSheet.ChangeToPuzzle(PickOneAtRandom(remainingPuzzles));
            }
            else
            {
                scoreSheet = scoreSheet.Finish();
            }

            return(Sign(scoreSheet));
        }
예제 #4
0
        public ScoreSheet RegisterNewContestant(string name)
        {
            var firstQuestion = PickOneAtRandom(Puzzle.Ids);
            var scoreSheet    = new ScoreSheet(name, firstQuestion);

            return(Sign(scoreSheet));
        }
예제 #5
0
        public static string ComputeSignature(this ScoreSheet scoresheet, string key)
        {
            var document = JsonSerializer.Serialize(new ScoreSheet(scoresheet));

            using var hmac = new HMACSHA384(Encoding.UTF8.GetBytes(key));
            return(Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(document))));
        }
예제 #6
0
 public ScoreSheet(ScoreSheet otherScoreSheet)
 {
     Name = otherScoreSheet.Name;
     StartingTimestamp = otherScoreSheet.StartingTimestamp;
     FinishedTimestamp = otherScoreSheet.FinishedTimestamp;
     CompletedPuzzles  = otherScoreSheet.CompletedPuzzles;
     CurrentPuzzle     = otherScoreSheet.CurrentPuzzle;
 }
예제 #7
0
        internal ScoreSheet ChangeToPuzzle(Guid puzzleId)
        {
            if (CompletedPuzzles.Contains(puzzleId))
            {
                throw new InvalidOperationException("Can't change to an already completed puzzle");
            }

            var newScoreSheet = new ScoreSheet(this);

            newScoreSheet.CurrentPuzzle = puzzleId;
            return(newScoreSheet);
        }
예제 #8
0
        internal ScoreSheet Complete(Guid puzzleId)
        {
            if (CurrentPuzzle != puzzleId)
            {
                throw new InvalidOperationException("Can only complete the current puzzle");
            }

            var newScoreSheet = new ScoreSheet(this);

            newScoreSheet.CompletedPuzzles = newScoreSheet.CompletedPuzzles.Concat(new[] { puzzleId }).Distinct().ToArray();
            return(newScoreSheet);
        }
예제 #9
0
        private ScoreSheet Sign(ScoreSheet scoreSheet)
        {
            var signature = scoreSheet.ComputeSignature(_signingKey);

            return(scoreSheet.Sign(signature));
        }
예제 #10
0
        public bool IsAuthentic(ScoreSheet scoreSheet)
        {
            var expectedSignature = scoreSheet.ComputeSignature(_signingKey);

            return(scoreSheet.Signature == expectedSignature);
        }