示例#1
0
        private void _Grade(ChallengeSpec spec, SectionSubmission submission)
        {
            var section = spec.Challenge.Sections.ElementAtOrDefault(submission.SectionIndex);

            double lastScore = spec.Score;

            int i = 0;

            foreach (var question in section.Questions)
            {
                question.Grade(submission.Questions.ElementAtOrDefault(i++)?.Answer ?? "");
            }

            section.Score = section.Questions
                            .Where(q => q.IsCorrect)
                            .Select(q => q.Weight - q.Penalty)
                            .Sum()
            ;

            spec.Score = spec.Challenge.Sections
                         .SelectMany(s => s.Questions)
                         .Where(q => q.IsCorrect)
                         .Select(q => q.Weight - q.Penalty)
                         .Sum()
            ;

            if (spec.Score > lastScore)
            {
                spec.LastScoreTime = submission.Timestamp;
            }
        }
示例#2
0
        private ChallengeView MapChallenge(ChallengeSpec spec, int sectionIndex = 0)
        {
            var section = spec.Challenge.Sections.ElementAtOrDefault(sectionIndex);

            var challenge = new ChallengeView
            {
                Text          = string.Join("\n\n", spec.Text, spec.Challenge.Text),
                LastScoreTime = spec.LastScoreTime,
                MaxPoints     = spec.MaxPoints,
                MaxAttempts   = spec.MaxAttempts,
                Attempts      = spec.Submissions.Count,
                Score         = Math.Round(spec.Score * spec.MaxPoints, 0, MidpointRounding.AwayFromZero),
                SectionIndex  = sectionIndex,
                SectionCount  = spec.Challenge.Sections.Count,
                SectionScore  = Math.Round(section.Score * spec.MaxPoints, 0, MidpointRounding.AwayFromZero),
                SectionText   = section.Text,
                Questions     = Mapper.Map <QuestionView[]>(section.Questions.Where(q => !q.Hidden))
            };

            foreach (var q in challenge.Questions)
            {
                q.Weight  = (float)Math.Round(q.Weight * spec.MaxPoints, 0, MidpointRounding.AwayFromZero);
                q.Penalty = (float)Math.Round(q.Penalty * spec.MaxPoints, 0, MidpointRounding.AwayFromZero);
            }

            return(challenge);
        }
示例#3
0
        public async Task UpdateChallenge(int id, ChallengeSpec spec)
        {
            var entity = await _workspaceStore.Load(id);

            if (entity == null || !entity.CanEdit(User))
            {
                throw new InvalidOperationException();
            }

            // spec.Randoms.Clear();

            // hydrate question weights
            var   unweighted = spec.Questions.Where(q => q.Weight == 0).ToArray();
            float max        = spec.Questions.Sum(q => q.Weight);

            if (unweighted.Any())
            {
                float val = (1 - max) / unweighted.Length;
                foreach (var q in unweighted.Take(unweighted.Length - 1))
                {
                    q.Weight = val;
                    max     += val;
                }
                unweighted.Last().Weight = 1 - max;
            }

            entity.Challenge = JsonSerializer.Serialize(spec, jsonOptions);

            await _workspaceStore.Update(entity);
        }
示例#4
0
        public async Task UpdateChallenge(string id, ChallengeSpec spec)
        {
            var entity = await _store.Retrieve(id);

            entity.Challenge = JsonSerializer.Serialize <ChallengeSpec>(spec, jsonOptions);

            await _store.Update(entity);
        }
示例#5
0
        public ActionResult <ChallengeSpec> SaveChallengeSpec([FromRoute] string name, [FromBody] ChallengeSpec challengeSpec)
        {
            ChallengeSpec spec = _challengeService.SaveChallengeSpec(name, challengeSpec);

            if (spec == null)
            {
                throw new InvalidOperationException($"ChallengeSpec {name} was not saved. Please try again.");
            }

            return(Ok(spec));
        }
示例#6
0
        public Task <List <ChallengeSpec> > ChallengeSpecs()
        {
            //TODO: it would be better if we could retrieve the items that were added by save method.
            //There is not a way to enumerate keys on IMemoryCache
            List <ChallengeSpec> challengeSpecs = new List <ChallengeSpec>();
            ChallengeSpec        challengeSpec  = GetChallengeSpec();

            challengeSpecs.Add(challengeSpec);

            return(Task.FromResult(challengeSpecs));
        }
示例#7
0
        public async Task <ChallengeSpec> SaveChallengeSpec(string name, ChallengeSpec challengeSpec)
        {
            var result = await Http.PostAsync($"/api/challenge/savechallengespec/{name}", Json(challengeSpec));

            if (!result.IsSuccessStatusCode)
            {
                throw new HttpRequestException(result.ReasonPhrase);
            }

            return(JsonConvert.DeserializeObject <ChallengeSpec>(await result.Content.ReadAsStringAsync()));
        }
示例#8
0
        public Task <ChallengeSpec> SaveChallengeSpec(string name, ChallengeSpec challengeSpec)
        {
            if (!string.IsNullOrEmpty(name) && challengeSpec != null)
            {
                challengeSpec.Slug = name;
                Cache.Set(name, challengeSpec);

                return(Task.FromResult(challengeSpec));
            }
            else
            {
                throw new ArgumentException("The ChallengeSpec save operation failed.");
            }
        }
示例#9
0
        public async Task <IActionResult> UpdateChallengeSpec([FromRoute] string id, [FromBody] ChallengeSpec model)
        {
            await Validate(new Entity { Id = id });

            await Validate(model);

            AuthorizeAny(
                () => Actor.IsAdmin,
                () => _svc.CanEdit(id, Actor.Id).Result
                );

            await _svc.UpdateChallenge(id, model);

            // TODO: broadcast updated

            return(Ok());
        }
示例#10
0
        private ChallengeSpec GetChallengeSpec()
        {
            ChallengeSpec challengeSpec = new ChallengeSpec();

            challengeSpec.Title       = "The Test Game";
            challengeSpec.Tags        = "Sift, Forensics";
            challengeSpec.Document    = "AI500 - T1.pdf";
            challengeSpec.Description = " | Use Sift workstation to analyze evidence drives **Analysis using the virtual gamespace required **";
            challengeSpec.Workspace   = new WorkspaceSpec
            {
                Id = 104,
                CustomizeTemplates = true,
                Vms = new VmSpec[] { new VmSpec
                                     {
                                         Name     = "Windows10",
                                         Replicas = 3
                                     } }
            };
            challengeSpec.Flags = new FlagSpec[] {
                new FlagSpec
                {
                    Tokens = new TokenSpec[] { new TokenSpec {
                                                   Value = "ncrypt10n_ch4ll3ng1ng"
                                               } }
                },
                new FlagSpec
                {
                    Tokens = new TokenSpec[] { new TokenSpec {
                                                   Value = "ncrypt10n_h3lps"
                                               } },
                    GenerateCommand = "sed -i \"s/evidence1.vmdk/evidence2.vmdk/\" /dst/_templates.json",
                    GenerateImage   = "bash"
                },
                new FlagSpec
                {
                    Tokens = new TokenSpec[] { new TokenSpec {
                                                   Value = "b1tl0ck3r"
                                               } },
                    GenerateCommand = "sed -i \"s/evidence1.vmdk/evidence3.vmdk/\" /dst/_templates.json",
                    GenerateImage   = "bash"
                }
            };

            return(challengeSpec);
        }
示例#11
0
        /// <summary>
        /// Save a ChallengeSpec to a file
        /// </summary>
        /// <param name="name"></param>
        /// <param name="challengeSpec"></param>
        /// <returns></returns>
        public bool SaveChallengeSpec(string name, ChallengeSpec challengeSpec)
        {
            string folderPath = Path.Combine(Data.RootPath, Options.ChallengePath, name);

            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }

            // TODO: how do we save all of the files that go into the ChallengeSpec?

            string filePath          = Path.Combine(Data.RootPath, Options.ChallengePath, name + ".yaml");
            string challengeSpecYaml = serializer.Serialize(challengeSpec);

            File.WriteAllText(filePath, challengeSpecYaml);

            return(true);
        }
示例#12
0
        public ChallengeSpec SaveChallengeSpec(string name, ChallengeSpec challengeSpec)
        {
            //bool isValid = ValidateChallengeSpec(name, challengeSpec);

            //if(!isValid)
            //{
            //    throw new ArgumentException("The ChallengeSpec was not saved. An Invalid ChallengeSpec was submitted.");
            //}

            var  spec    = Data.GetChallengeSpec(name);
            bool created = false;

            if (spec != null)
            {
                // this file already exists
                // archive existing spec and create a new one with this name
                if (ArchiveChallengeSpec(name))
                {
                    if (CreateNewChallengeSpec(name, challengeSpec))
                    {
                        created = true;
                    }
                }
            }
            else
            {
                if (CreateNewChallengeSpec(name, challengeSpec))
                {
                    created = true;
                }
            }

            if (created)
            {
                // TODO: force reload so we can get it from memory and return to caller. look into reloading just one item rather than all files.
                _dataContext.Reload();
                return(Data.GetChallengeSpec(name));
            }

            return(null);
        }
示例#13
0
        private void ResolveTransforms(ChallengeSpec spec, RegistrationContext ctx)
        {
            foreach (var kvp in spec.Transforms.ToArray())
            {
                kvp.Value = ResolveRandom(kvp.Value, ctx);

                // insert `key_index: value` for any multi-token values (i.e. list-resolver)
                var tokens = kvp.Value.Split(" ", StringSplitOptions.RemoveEmptyEntries);
                if (tokens.Length > 1)
                {
                    int i = 0;
                    foreach (string token in tokens)
                    {
                        spec.Transforms.Add(new StringKeyValue
                        {
                            Key   = $"{kvp.Key}_{++i}",
                            Value = token
                        });
                    }
                }
            }
        }
示例#14
0
 private bool CreateNewChallengeSpec(string name, ChallengeSpec challengeSpec)
 {
     return(Data.SaveChallengeSpec(name, challengeSpec));
 }
示例#15
0
        public async Task <IActionResult> Challenge([FromRoute] int id, [FromBody] ChallengeSpec model)
        {
            await _workspaceService.UpdateChallenge(id, model);

            return(Ok());
        }
示例#16
0
 private async Task _validate(ChallengeSpec model)
 {
     await Task.CompletedTask;
 }
示例#17
0
        private async Task <Data.Gamespace> Create(
            Data.Workspace workspace,
            string client,
            string isolationId
            )
        {
            var gamespace = new Data.Gamespace
            {
                GlobalId  = isolationId,
                Name      = workspace.Name,
                Workspace = workspace,
                ShareCode = Guid.NewGuid().ToString("n"),
                Audience  = client
            };

            gamespace.Players.Add(
                new Data.Player
            {
                PersonId   = User.Id,
                Permission = Data.Permission.Manager
                             // LastSeen = DateTime.UtcNow
            }
                );

            // glean randomize targets
            var regex = new Regex("##[^#]*##");

            var map = new Dictionary <string, string>();

            foreach (var t in gamespace.Workspace.Templates)
            {
                foreach (Match match in regex.Matches(t.Guestinfo ?? ""))
                {
                    map.TryAdd(match.Value, "");
                }

                foreach (Match match in regex.Matches(t.Detail ?? t.Parent?.Detail ?? ""))
                {
                    map.TryAdd(match.Value, "");
                }
            }

            // clone challenge
            var spec = new ChallengeSpec();

            if (!string.IsNullOrEmpty(workspace.Challenge))
            {
                spec = JsonSerializer.Deserialize <ChallengeSpec>(workspace.Challenge ?? "{}", jsonOptions);

                foreach (var question in spec.Questions)
                {
                    foreach (Match match in regex.Matches(question.Answer))
                    {
                        string key = match.Value;
                        string val = "";

                        if (key.Contains(":list##"))
                        {
                            string[] list = question.Answer
                                            .Split(' ', StringSplitOptions.RemoveEmptyEntries)
                                            .Skip(1)
                                            .ToArray();

                            if (list.Length > 0)
                            {
                                val = list[_random.Next(list.Length)];

                                question.Answer = key;

                                if (map.ContainsKey(key))
                                {
                                    map[key] = val;
                                }
                            }
                        }

                        map.TryAdd(key, val);
                    }
                }
            }

            // resolve macros
            foreach (string key in map.Keys.ToArray())
            {
                if (string.IsNullOrEmpty(map[key]))
                {
                    map[key] = ResolveRandom(key);
                }
            }

            // apply macros to spec answers
            foreach (var q in spec.Questions)
            {
                foreach (string key in map.Keys)
                {
                    q.Answer = q.Answer.Replace(key, map[key]);
                }
            }

            spec.Randoms = map;

            gamespace.Challenge = JsonSerializer.Serialize(spec, jsonOptions);

            await _gamespaceStore.Add(gamespace);

            return(gamespace);
        }