public async Task <IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return(Page()); } var user = await _userManager.GetUserAsync(User); if (user == null) { return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.")); } var thisPuzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(_context, User, _userManager); // enforce access rights, do not let these change! Input.ID = thisPuzzleUser.ID; Input.IsGlobalAdmin = thisPuzzleUser.IsGlobalAdmin; Input.IdentityUserId = thisPuzzleUser.IdentityUserId; _context.Entry(thisPuzzleUser).State = EntityState.Detached; _context.Attach(Input).State = EntityState.Modified; await _context.SaveChangesAsync(true); await _signInManager.RefreshSignInAsync(user); StatusMessage = "Your profile has been updated"; return(RedirectToPage()); }
public async Task <IActionResult> OnGetAddAdminAsync(int userId) { // Check that the user isn't already an admin if (await(from admin in _context.EventAdmins where admin.Admin.ID == userId && admin.Event == Event select admin).AnyAsync()) { return(NotFound("User is already an admin in this event.")); } EventAdmins Admin = new EventAdmins(); PuzzleUser user = await _context.PuzzleUsers.FirstOrDefaultAsync(m => m.ID == userId); if (user == null) { return(NotFound("Could not find user with ID '" + userId + "'. Check to make sure the user hasn't been removed.")); } Admin.Admin = user; Admin.Event = Event; _context.EventAdmins.Add(Admin); await _context.SaveChangesAsync(); return(RedirectToPage("/Events/Players")); }
public async Task <IActionResult> OnGetAddAuthorAsync(int userId) { // Check that the user isn't already an author if (await(from author in _context.EventAuthors where author.Author.ID == userId && author.Event == Event select author).AnyAsync()) { return(NotFound("User is already an author in this event.")); } EventAuthors Author = new EventAuthors(); PuzzleUser user = await _context.PuzzleUsers.FirstOrDefaultAsync(m => m.ID == userId); if (user == null) { return(NotFound("Could not find user with ID '" + userId + "'. Check to make sure the user hasn't been removed.")); } Author.Author = user; Author.Event = Event; _context.EventAuthors.Add(Author); user.MayBeAdminOrAuthor = true; await _context.SaveChangesAsync(); return(RedirectToPage("/Events/Players")); }
public async Task <IActionResult> Index(string eventId, int puzzleId) { Event currentEvent = await EventHelper.GetEventFromEventId(context, eventId); PuzzleUser user = await PuzzleUser.GetPuzzleUserForCurrentUser(context, User, userManager); Team team = await UserEventHelper.GetTeamForPlayer(context, currentEvent, user); Puzzle thisPuzzle = await context.Puzzles.FirstOrDefaultAsync(m => m.ID == puzzleId); // Find the material file with the latest-alphabetically ShortName that contains the substring "customPage". var materialFile = await(from f in context.ContentFiles where f.Puzzle == thisPuzzle && f.FileType == ContentFileType.PuzzleMaterial && f.ShortName.Contains("customPage") orderby f.ShortName descending select f).FirstOrDefaultAsync(); if (materialFile == null) { return(Content("ERROR: There's no custom page uploaded for this puzzle")); } var materialUrl = materialFile.Url; // Download that material file. string fileContents; using (var wc = new System.Net.WebClient()) { fileContents = await wc.DownloadStringTaskAsync(materialUrl); } // Return the file contents to the user. return(Content(fileContents, "text/html")); }
public async Task IsPuzzleAuthorCheck(AuthorizationHandlerContext authContext, IAuthorizationRequirement requirement) { EventRole role = GetEventRoleFromRoute(); if (role != EventRole.author) { return; } PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Puzzle puzzle = await GetPuzzleFromRoute(); Event thisEvent = await GetEventFromRoute(); if (thisEvent != null && await UserEventHelper.IsAuthorOfPuzzle(dbContext, puzzle, puzzleUser)) { authContext.Succeed(requirement); } if (puzzle != null) { dbContext.Entry(puzzle).State = EntityState.Detached; } }
public async Task <IActionResult> OnPostAsync(string returnUrl = null) { if (string.IsNullOrEmpty(PuzzleUser.Email)) { ModelState.AddModelError("PuzzleUser.Email", "An email is required."); } else if (!MailHelper.IsValidEmail(PuzzleUser.Email)) { ModelState.AddModelError("PuzzleUser.Email", "This email address is not valid."); } if (!ModelState.IsValid) { return(Page()); } var thisPuzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(_context, User, _userManager); if (thisPuzzleUser != null) { _context.Entry(thisPuzzleUser).State = EntityState.Detached; } _context.Attach(PuzzleUser).State = EntityState.Modified; await _context.SaveChangesAsync(); return(Redirect(returnUrl)); }
public async Task <IActionResult> Post(string eventId, int puzzleId, List <int> query_puzzle_ids, int?min_solve_count, string annotations, string last_sync_time) { // Find what team this user is on, relative to the event. Event currentEvent = await EventHelper.GetEventFromEventId(context, eventId); if (currentEvent == null) { return(Unauthorized()); } PuzzleUser user = await PuzzleUser.GetPuzzleUserForCurrentUser(context, User, userManager); if (user == null) { return(Unauthorized()); } Team team = await UserEventHelper.GetTeamForPlayer(context, currentEvent, user); if (team == null) { return(Unauthorized()); } var helper = new SyncHelper(context); var response = await helper.GetSyncResponse(currentEvent.ID, team.ID, puzzleId, query_puzzle_ids, min_solve_count, annotations, last_sync_time, false); return(Json(response)); }
public async Task IsPlayerOnTeamCheck(AuthorizationHandlerContext authContext, IAuthorizationRequirement requirement) { EventRole role = GetEventRoleFromRoute(); if (role != EventRole.play) { return; } PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Team team = await GetTeamFromRoute(); Event thisEvent = await GetEventFromRoute(); if (thisEvent != null) { Team userTeam = await UserEventHelper.GetTeamForPlayer(dbContext, thisEvent, puzzleUser); if (userTeam != null && userTeam.ID == team.ID) { authContext.Succeed(requirement); } } }
/// <summary> /// Runs before page actions /// </summary> public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) { LoggedInUser = await PuzzleUser.GetPuzzleUserForCurrentUser(_context, User, userManager); // Required to have the rest of page execution occur await next.Invoke(); }
public async Task <IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return(Page()); } _context.Events.Add(Event); var loggedInUser = await PuzzleUser.GetPuzzleUserForCurrentUser(_context, User, _userManager); if (loggedInUser != null) { _context.EventAdmins.Add(new EventAdmins() { Event = Event, Admin = loggedInUser }); _context.EventAuthors.Add(new EventAuthors() { Event = Event, Author = loggedInUser }); } await _context.SaveChangesAsync(); return(RedirectToPage("./Index")); }
/// <summary> /// Set the solve state of some puzzle state records. In the course of setting the state, instantiate any state records that are missing on the server. /// </summary> /// <param name="context">The puzzle DB context</param> /// <param name="eventObj">The event we are querying from</param> /// <param name="puzzle"> /// The puzzle; if null, get all puzzles in the event. /// </param> /// <param name="team"> /// The team; if null, get all the teams in the event. /// </param> /// <param name="value">The solve time (null if unsolving)</param> /// <param name="author"></param> /// <returns> /// A task that can be awaited for the solve/unsolve operation /// </returns> public static async Task SetSolveStateAsync( PuzzleServerContext context, Event eventObj, Puzzle puzzle, Team team, DateTime?value, PuzzleUser author = null) { IQueryable <PuzzleStatePerTeam> statesQ = PuzzleStateHelper .GetFullReadWriteQuery(context, eventObj, puzzle, team, author); List <PuzzleStatePerTeam> states = await statesQ.ToListAsync(); for (int i = 0; i < states.Count; i++) { // Only allow solved time to be modified if it is being marked as unsolved (set to null) or if it is being solved for the first time if (value == null || states[i].SolvedTime == null) { // Unlock puzzles when solving them if (value != null && states[i].UnlockedTime == null) { states[i].UnlockedTime = value; } states[i].SolvedTime = value; } } // Award hint coins if (value != null && puzzle != null && puzzle.HintCoinsForSolve != 0) { if (team != null) { team.HintCoinCount += puzzle.HintCoinsForSolve; } else { var allTeams = from Team curTeam in context.Teams where curTeam.Event == eventObj select curTeam; foreach (Team curTeam in allTeams) { curTeam.HintCoinCount += puzzle.HintCoinsForSolve; } } } await context.SaveChangesAsync(); // if this puzzle got solved, look for others to unlock if (puzzle != null && value != null) { await UnlockAnyPuzzlesThatThisSolveUnlockedAsync(context, eventObj, puzzle, team, value.Value); } }
public async Task <SubmissionResponse> PostSubmitAnswerAsync([FromBody] AnswerSubmission submission, [FromRoute] string eventId, [FromRoute] int puzzleId) { Event currentEvent = await EventHelper.GetEventFromEventId(context, eventId); PuzzleUser user = await PuzzleUser.GetPuzzleUserForCurrentUser(context, User, userManager); return(await SubmissionEvaluator.EvaluateSubmission(context, user, currentEvent, puzzleId, submission.SubmissionText, submission.AllowFreeformSharing)); }
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext authContext, IsGlobalAdminRequirement requirement) { PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); if (puzzleUser.IsGlobalAdmin) { authContext.Succeed(requirement); } }
/// <summary> /// Adds a user to a team after performing a number of checks to make sure that the change is valid /// </summary> /// <param name="context">The context to update</param> /// <param name="Event">The event that the team is for</param> /// <param name="EventRole">The event role of the user that is making this change</param> /// <param name="teamId">The id of the team the player should be added to</param> /// <param name="userId">The user that should be added to the team</param> /// <returns> /// A tuple where the first element is a boolean that indicates whether the player was successfully /// added to the team and the second element is a message to display that explains the error in the /// case where the user was not successfully added to the team /// </returns> public static async Task <Tuple <bool, string> > AddMemberAsync(PuzzleServerContext context, Event Event, EventRole EventRole, int teamId, int userId) { Team team = await context.Teams.FirstOrDefaultAsync(m => m.ID == teamId); if (team == null) { return(new Tuple <bool, string>(false, $"Could not find team with ID '{teamId}'. Check to make sure the team hasn't been removed.")); } var currentTeamMembers = await context.TeamMembers.Where(members => members.Team.ID == team.ID).ToListAsync(); if (currentTeamMembers.Count >= Event.MaxTeamSize && EventRole != EventRole.admin) { return(new Tuple <bool, string>(false, $"The team '{team.Name}' is full.")); } PuzzleUser user = await context.PuzzleUsers.FirstOrDefaultAsync(m => m.ID == userId); if (user == null) { return(new Tuple <bool, string>(false, $"Could not find user with ID '{userId}'. Check to make sure the user hasn't been removed.")); } if (user.EmployeeAlias == null && currentTeamMembers.Where((m) => m.Member.EmployeeAlias == null).Count() >= Event.MaxExternalsPerTeam) { return(new Tuple <bool, string>(false, $"The team '{team.Name}' is already at its maximum count of non-employee players, and '{user.Email}' has no registered alias.")); } if (await(from teamMember in context.TeamMembers where teamMember.Member == user && teamMember.Team.Event == Event select teamMember).AnyAsync()) { return(new Tuple <bool, string>(false, $"'{user.Email}' is already on a team in this event.")); } TeamMembers Member = new TeamMembers(); Member.Team = team; Member.Member = user; // Remove any applications the user might have started for this event var allApplications = from app in context.TeamApplications where app.Player == user && app.Team.Event == Event select app; context.TeamApplications.RemoveRange(allApplications); context.TeamMembers.Add(Member); await context.SaveChangesAsync(); return(new Tuple <bool, string>(true, "")); }
public static async Task IsEventAdminCheck(AuthorizationHandlerContext authContext, PuzzleServerContext dbContext, UserManager <IdentityUser> userManager, IAuthorizationRequirement requirement) { PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Event thisEvent = await AuthorizationHelper.GetEventFromContext(authContext); EventRole role = AuthorizationHelper.GetEventRoleFromContext(authContext); if (thisEvent != null && role == EventRole.admin && await puzzleUser.IsAdminForEvent(dbContext, thisEvent)) { authContext.Succeed(requirement); } }
public async Task <IActionResult> OnGetAsync(string eventId, int puzzleId) { Event currentEvent = await EventHelper.GetEventFromEventId(_context, eventId); if (currentEvent == null) { return(Unauthorized()); } EventId = currentEvent.ID; PuzzleUser user = LoggedInUser; if (user == null) { return(Unauthorized()); } Team team = await UserEventHelper.GetTeamForPlayer(_context, currentEvent, user); if (team == null) { return(Unauthorized()); } Puzzle kitchenSyncPuzzle = await _context.Puzzles.FirstOrDefaultAsync(m => m.Name == "Kitchen Sync" && m.Event.ID == EventId); KitchenSyncId = kitchenSyncPuzzle.ID; Puzzle heatSyncPuzzle = await _context.Puzzles.FirstOrDefaultAsync(m => m.Name == "Heat Sync" && m.Event.ID == EventId); HeatSyncId = heatSyncPuzzle.ID; Puzzle lipSyncPuzzle = await _context.Puzzles.FirstOrDefaultAsync(m => m.Name == "Lip Sync" && m.Event.ID == EventId); LipSyncId = lipSyncPuzzle.ID; Puzzle syncTestMetapuzzle = await _context.Puzzles.FirstOrDefaultAsync(m => m.Name == "Sync Test" && m.Event.ID == EventId); MetapuzzleId = syncTestMetapuzzle.ID; var helper = new SyncHelper(_context); List <int> query_puzzle_ids = new List <int> { KitchenSyncId, HeatSyncId, LipSyncId }; var response = await helper.GetSyncResponse(currentEvent.ID, team.ID, puzzleId, query_puzzle_ids, 0, null, null); var responseSerialized = JsonConvert.SerializeObject(response); InitialSyncString = HttpUtility.JavaScriptStringEncode(responseSerialized); return(Page()); }
/// <summary> /// Set the solve state of some puzzle state records. In the course of setting the state, instantiate any state records that are missing on the server. /// </summary> /// <param name="context">The puzzle DB context</param> /// <param name="eventObj">The event we are querying from</param> /// <param name="puzzle"> /// The puzzle; if null, get all puzzles in the event. /// </param> /// <param name="team"> /// The team; if null, get all the teams in the event. /// </param> /// <param name="value">The solve time (null if unsolving)</param> /// <param name="author"></param> /// <returns> /// A task that can be awaited for the solve/unsolve operation /// </returns> public static async Task SetSolveStateAsync( PuzzleServerContext context, Event eventObj, Puzzle puzzle, Team team, DateTime?value, PuzzleUser author = null) { IQueryable <PuzzleStatePerTeam> statesQ = await PuzzleStateHelper .GetFullReadWriteQueryAsync(context, eventObj, puzzle, team, author); List <PuzzleStatePerTeam> states = await statesQ.ToListAsync(); for (int i = 0; i < states.Count; i++) { states[i].SolvedTime = value; } // Award hint coins if (value != null && puzzle != null && puzzle.HintCoinsForSolve != 0) { if (team != null) { team.HintCoinCount += puzzle.HintCoinsForSolve; } else { var allTeams = from Team curTeam in context.Teams where curTeam.Event == eventObj select curTeam; foreach (Team curTeam in allTeams) { curTeam.HintCoinCount += puzzle.HintCoinsForSolve; } } } await context.SaveChangesAsync(); // if this puzzle got solved, look for others to unlock if (value != null) { await UnlockAnyPuzzlesThatThisSolveUnlockedAsync(context, eventObj, puzzle, team, value.Value); } }
public async Task IsEventAdminCheck(AuthorizationHandlerContext authContext, IAuthorizationRequirement requirement) { EventRole role = GetEventRoleFromRoute(); if (role != EventRole.admin) { return; } PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Event thisEvent = await GetEventFromRoute(); if (thisEvent != null && puzzleUser != null && await puzzleUser.IsAdminForEvent(dbContext, thisEvent)) { authContext.Succeed(requirement); } }
public async Task <IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (remoteError != null) { ErrorMessage = $"Error from external provider: {remoteError}"; return(RedirectToPage("./Login", new { ReturnUrl = returnUrl })); } var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null) { ErrorMessage = "Error loading external login information."; return(RedirectToPage("./Login", new { ReturnUrl = returnUrl })); } // Sign in the user with this external login provider if the user already has a login. var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent : false, bypassTwoFactor : true); if (result.Succeeded) { _logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider); return(LocalRedirect(returnUrl)); } if (result.IsLockedOut) { return(RedirectToPage("./Lockout")); } else { // If the user does not have an account, then ask the user to create an account. ReturnUrl = returnUrl; LoginProvider = info.LoginProvider; if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email)) { Input = new PuzzleUser { Email = info.Principal.FindFirstValue(ClaimTypes.Email), IdentityUserId = "fake" }; } return(Page()); } }
public async Task <IActionResult> OnGetAsync(string eventId, int puzzleId) { Event currentEvent = await EventHelper.GetEventFromEventId(_context, eventId); if (currentEvent == null) { return(Unauthorized()); } EventId = currentEvent.ID; PuzzleUser user = LoggedInUser; if (user == null) { return(Unauthorized()); } Team team = await UserEventHelper.GetTeamForPlayer(_context, currentEvent, user); if (team == null) { return(Unauthorized()); } Puzzle thisPuzzle = await _context.Puzzles.FirstOrDefaultAsync(m => m.ID == puzzleId && m.Event.ID == EventId); if (thisPuzzle == null || !thisPuzzle.Name.Equals("The Play That Goes Wrong")) { return(Unauthorized()); } MetapuzzleId = puzzleId; var helper = new SyncHelper(_context); List <int> query_puzzle_ids = Enumerable.Range(MetapuzzleId - 10, 11).ToList(); var response = await helper.GetSyncResponse(currentEvent.ID, team.ID, puzzleId, query_puzzle_ids, 0, null, null); var responseSerialized = JsonConvert.SerializeObject(response); InitialSyncString = HttpUtility.JavaScriptStringEncode(responseSerialized); return(Page()); }
public async Task <IActionResult> OnPostAsync(string returnUrl = null) { if (!ModelState.IsValid) { return(Page()); } var thisPuzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(_context, User, _userManager); if (thisPuzzleUser != null) { _context.Entry(thisPuzzleUser).State = EntityState.Detached; } _context.Attach(PuzzleUser).State = EntityState.Modified; await _context.SaveChangesAsync(); return(Redirect(returnUrl)); }
public static async Task IsPuzzleAuthorCheck(AuthorizationHandlerContext authContext, PuzzleServerContext dbContext, UserManager <IdentityUser> userManager, IAuthorizationRequirement requirement) { PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Puzzle puzzle = await AuthorizationHelper.GetPuzzleFromContext(authContext); Event thisEvent = await AuthorizationHelper.GetEventFromContext(authContext); EventRole role = AuthorizationHelper.GetEventRoleFromContext(authContext); if (thisEvent != null && role == EventRole.author && await UserEventHelper.IsAuthorOfPuzzle(dbContext, puzzle, puzzleUser)) { authContext.Succeed(requirement); } if (puzzle != null) { dbContext.Entry(puzzle).State = EntityState.Detached; } }
public static async Task IsPlayerOnTeamCheck(AuthorizationHandlerContext authContext, PuzzleServerContext dbContext, UserManager <IdentityUser> userManager, IAuthorizationRequirement requirement) { PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Team team = await AuthorizationHelper.GetTeamFromContext(authContext); Event thisEvent = await AuthorizationHelper.GetEventFromContext(authContext); EventRole role = AuthorizationHelper.GetEventRoleFromContext(authContext); if (thisEvent != null && role == EventRole.play) { Team userTeam = await UserEventHelper.GetTeamForPlayer(dbContext, thisEvent, puzzleUser); if (userTeam != null && userTeam.ID == team.ID) { authContext.Succeed(requirement); } } }
/// <summary> /// Set the lockout expiry time of some puzzle state records. In the /// course of setting the state, instantiate any state records that are /// missing on the server. /// </summary> /// <param name="context">The puzzle DB context</param> /// <param name="eventObj">The event we are querying from</param> /// <param name="puzzle"> /// The puzzle; if null, get all puzzles in the event. /// </param> /// <param name="team"> /// The team; if null, get all the teams in the event. /// </param> /// <param name="value">The Lockout expiry time<param> /// <param name="author"></param> /// <returns> /// A task that can be awaited for the lockout operation /// </returns> public static async Task SetLockoutExpiryTimeAsync( PuzzleServerContext context, Event eventObj, Puzzle puzzle, Team team, DateTime?value, PuzzleUser author = null) { IQueryable <PuzzleStatePerTeam> statesQ = await PuzzleStateHelper .GetFullReadWriteQueryAsync(context, eventObj, puzzle, team, author); List <PuzzleStatePerTeam> states = await statesQ.ToListAsync(); for (int i = 0; i < states.Count; i++) { states[i].LockoutExpiryTime = value; } await context.SaveChangesAsync(); }
public static async Task IsEventAuthorCheck(AuthorizationHandlerContext authContext, PuzzleServerContext dbContext, UserManager <IdentityUser> userManager, IAuthorizationRequirement requirement) { EventRole role = AuthorizationHelper.GetEventRoleFromContext(authContext); if (role != EventRole.author) { return; } PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); if (authContext.Resource is AuthorizationFilterContext filterContext) { Event thisEvent = await AuthorizationHelper.GetEventFromContext(authContext); if (thisEvent != null && await puzzleUser.IsAuthorForEvent(dbContext, thisEvent)) { authContext.Succeed(requirement); } } }
public async Task <IActionResult> OnGetAsync() { var user = await _userManager.GetUserAsync(User); if (user == null) { return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.")); } PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUser(user.Id, _context); var userName = await _userManager.GetUserNameAsync(user); Username = userName; Input = puzzleUser; IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user); return(Page()); }
public async Task PlayerCanSeePuzzleCheck(AuthorizationHandlerContext authContext, IAuthorizationRequirement requirement) { PuzzleUser puzzleUser = await PuzzleUser.GetPuzzleUserForCurrentUser(dbContext, authContext.User, userManager); Puzzle puzzle = await GetPuzzleFromRoute(); Event thisEvent = await GetEventFromRoute(); if (thisEvent != null && puzzle != null) { Team team = await UserEventHelper.GetTeamForPlayer(dbContext, thisEvent, puzzleUser); if (team != null) { IQueryable <PuzzleStatePerTeam> statesQ = PuzzleStateHelper.GetFullReadOnlyQuery(dbContext, thisEvent, puzzle, team); if (statesQ.FirstOrDefault().UnlockedTime != null || thisEvent.AreAnswersAvailableNow) { authContext.Succeed(requirement); } } } }
/// <summary> /// Set the email only mode of some puzzle state records. In the course /// of setting the state, instantiate any state records that are /// missing on the server. /// </summary> /// <param name="context">The puzzle DB context</param> /// <param name="eventObj">The event we are querying from</param> /// <param name="puzzle"> /// The puzzle; if null, get all puzzles in the event. /// </param> /// <param name="team"> /// The team; if null, get all the teams in the event. /// </param> /// <param name="value">The new email only state for the puzzle</param> /// <param name="author"></param> /// <returns> /// A task that can be awaited for the lockout operation /// </returns> public static async Task SetEmailOnlyModeAsync( PuzzleServerContext context, Event eventObj, Puzzle puzzle, Team team, bool value, PuzzleUser author = null) { IQueryable <PuzzleStatePerTeam> statesQ = await PuzzleStateHelper .GetFullReadWriteQueryAsync(context, eventObj, puzzle, team, author); List <PuzzleStatePerTeam> states = await statesQ.ToListAsync(); for (int i = 0; i < states.Count; i++) { states[i].IsEmailOnlyMode = value; if (value == true) { states[i].WrongSubmissionCountBuffer += 50; } } await context.SaveChangesAsync(); }
public async Task <IActionResult> Index(string eventId, int puzzleId) { Event currentEvent = await EventHelper.GetEventFromEventId(context, eventId); if (currentEvent == null) { return(Content("ERROR: That event doesn't exist")); } PuzzleUser user = await PuzzleUser.GetPuzzleUserForCurrentUser(context, User, userManager); if (user == null) { return(Content("ERROR: You aren't logged in")); } Team team = await UserEventHelper.GetTeamForPlayer(context, currentEvent, user); if (team == null) { return(Content("ERROR: You're not on a team")); } Puzzle thisPuzzle = await context.Puzzles.FirstOrDefaultAsync(m => m.ID == puzzleId); if (thisPuzzle == null) { return(Content("ERROR: That's not a valid puzzle ID")); } if (!currentEvent.AreAnswersAvailableNow) { var puzzleState = await(from state in context.PuzzleStatePerTeam where state.Puzzle == thisPuzzle && state.Team == team select state).FirstOrDefaultAsync(); if (puzzleState == null || puzzleState.UnlockedTime == null) { return(Content("ERROR: You haven't unlocked this puzzle yet")); } } // Find the material file with the latest-alphabetically ShortName that contains the substring "client". var materialFile = await(from f in context.ContentFiles where f.Puzzle == thisPuzzle && f.FileType == ContentFileType.PuzzleMaterial && f.ShortName.Contains("client") orderby f.ShortName descending select f).FirstOrDefaultAsync(); if (materialFile == null) { return(Content("ERROR: There's no sync client registered for this puzzle")); } var materialUrl = materialFile.Url; // Start doing a sync asynchronously while we download the file contents. var helper = new SyncHelper(context); Task <Dictionary <string, object> > responseTask = helper.GetSyncResponse(currentEvent.ID, team.ID, puzzleId, null, 0, null, null, true); // Download that material file. string fileContents; using (var wc = new System.Net.WebClient()) { fileContents = await wc.DownloadStringTaskAsync(materialUrl); } // Wait for the asynchronous sync we started earlier to complete, then serialize // its results and use them to replace the substring "@SYNC" where it appears // in the downloaded file contents. Dictionary <string, object> response = await responseTask; var responseSerialized = JsonConvert.SerializeObject(response); var initialSyncString = HttpUtility.JavaScriptStringEncode(responseSerialized); fileContents = fileContents.Replace("@SYNC", initialSyncString); // Return the file contents to the user. return(Content(fileContents, "text/html")); }
/// <summary> /// Adds a user to a team after performing a number of checks to make sure that the change is valid /// </summary> /// <param name="context">The context to update</param> /// <param name="Event">The event that the team is for</param> /// <param name="EventRole">The event role of the user that is making this change</param> /// <param name="teamId">The id of the team the player should be added to</param> /// <param name="userId">The user that should be added to the team</param> /// <returns> /// A tuple where the first element is a boolean that indicates whether the player was successfully /// added to the team and the second element is a message to display that explains the error in the /// case where the user was not successfully added to the team /// </returns> public static async Task <Tuple <bool, string> > AddMemberAsync(PuzzleServerContext context, Event Event, EventRole EventRole, int teamId, int userId) { Team team = await context.Teams.FirstOrDefaultAsync(m => m.ID == teamId); if (team == null) { return(new Tuple <bool, string>(false, $"Could not find team with ID '{teamId}'. Check to make sure the team hasn't been removed.")); } var currentTeamMembers = await context.TeamMembers.Where(members => members.Team.ID == team.ID).ToListAsync(); if (currentTeamMembers.Count >= Event.MaxTeamSize && EventRole != EventRole.admin) { return(new Tuple <bool, string>(false, $"The team '{team.Name}' is full.")); } PuzzleUser user = await context.PuzzleUsers.FirstOrDefaultAsync(m => m.ID == userId); if (user == null) { return(new Tuple <bool, string>(false, $"Could not find user with ID '{userId}'. Check to make sure the user hasn't been removed.")); } if (user.EmployeeAlias == null && currentTeamMembers.Where((m) => m.Member.EmployeeAlias == null).Count() >= Event.MaxExternalsPerTeam) { return(new Tuple <bool, string>(false, $"The team '{team.Name}' is already at its maximum count of non-employee players, and '{user.Email}' has no registered alias.")); } if (await(from teamMember in context.TeamMembers where teamMember.Member == user && teamMember.Team.Event == Event select teamMember).AnyAsync()) { return(new Tuple <bool, string>(false, $"'{user.Email}' is already on a team in this event.")); } TeamMembers Member = new TeamMembers(); Member.Team = team; Member.Member = user; // Remove any applications the user might have started for this event var allApplications = from app in context.TeamApplications where app.Player == user && app.Team.Event == Event select app; context.TeamApplications.RemoveRange(allApplications); context.TeamMembers.Add(Member); await context.SaveChangesAsync(); MailHelper.Singleton.SendPlaintextWithoutBcc(new string[] { team.PrimaryContactEmail, user.Email }, $"{Event.Name}: {user.Name} has now joined {team.Name}!", $"Have a great time!"); var teamCount = await context.TeamMembers.Where(members => members.Team.ID == team.ID).CountAsync(); if (teamCount >= Event.MaxTeamSize) { var extraApplications = await(from app in context.TeamApplications where app.Team == team select app).ToListAsync(); context.TeamApplications.RemoveRange(extraApplications); var extraApplicationMails = from app in extraApplications select app.Player.Email; MailHelper.Singleton.SendPlaintextBcc(extraApplicationMails.ToList(), $"{Event.Name}: You can no longer join {team.Name} because it is now full", $"Sorry! You can apply to another team if you wish."); } return(new Tuple <bool, string>(true, "")); }