示例#1
0
        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());
        }
示例#2
0
        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 static async Task IsPuzzleAuthorCheck(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);

            Puzzle puzzle = await AuthorizationHelper.GetPuzzleFromContext(authContext);

            Event thisEvent = await AuthorizationHelper.GetEventFromContext(authContext);

            if (thisEvent != null && await UserEventHelper.IsAuthorOfPuzzle(dbContext, puzzle, puzzleUser))
            {
                authContext.Succeed(requirement);
            }

            if (puzzle != null)
            {
                dbContext.Entry(puzzle).State = EntityState.Detached;
            }
        }
        /// <summary>
        ///   This routine takes a single annotation that the requester has uploaded, and inserts
        ///   it if it doesn't exist and updates it otherwise.
        /// </summary>
        private async Task InsertOrUpdateOneAnnotation(SyncResponse response, int puzzleId, int teamId, int key, string contents)
        {
            // Check to see if the annotation already exists.  If so, update it and we're done.

            Annotation existingAnnotation =
                await context.Annotations.FirstOrDefaultAsync(a => a.PuzzleID == puzzleId && a.TeamID == teamId && a.Key == key);

            if (existingAnnotation != null)
            {
                context.Entry(existingAnnotation).State = EntityState.Detached;
                await UpdateOneAnnotation(response, puzzleId, teamId, key, contents);
            }
            else
            {
                // The annotation doesn't exist yet.  So, try to generate a new annotation, with version 1.

                Annotation annotation = new Annotation {
                    PuzzleID = puzzleId, TeamID = teamId, Key = key,
                    Version  = 1, Contents = contents, Timestamp = DateTime.Now
                };
                try {
                    context.Annotations.Add(annotation);
                    await context.SaveChangesAsync();
                }
                catch (DbUpdateException) {
                    // If the insert fails, there must already be an annotation there with the
                    // same puzzle ID, team ID, and key.  (This means there was a race condition:
                    // between the time we checked for the existence of a matching annotation and
                    // now, there was another insert.)  So, we need to update the existing one.

                    // But first, we need to detach the annotation from the context so the context
                    // doesn't think the annotation is in the database.

                    context.Entry(annotation).State = EntityState.Detached;
                    await UpdateOneAnnotation(response, puzzleId, teamId, key, contents);
                }
            }
        }
        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));
        }
示例#6
0
        /// <summary>
        ///   This routine stores in the database any annotations the requester has uploaded.
        /// </summary>
        private async Task StoreAnnotations(DecodedSyncRequest request, SyncResponse response, int puzzleId, int teamId)
        {
            if (request.AnnotationRequests == null)
            {
                return;
            }

            foreach (var annotationRequest in request.AnnotationRequests)
            {
                // Try to generate this as a new annotation, with version 1.

                Annotation annotation = new Annotation();
                annotation.PuzzleID  = puzzleId;
                annotation.TeamID    = teamId;
                annotation.Key       = annotationRequest.key;
                annotation.Version   = 1;
                annotation.Contents  = annotationRequest.contents;
                annotation.Timestamp = DateTime.Now;

                try {
                    context.Annotations.Add(annotation);
                    await context.SaveChangesAsync();
                }
                catch (DbUpdateException) {
                    // If the insert fails, there must already be an annotation there with the
                    // same puzzle ID, team ID, and key.  So we need to update the existing one.
                    // As we do so, we increment its version number and update its timestamp.
                    //
                    // You may wonder why we're using ExecuteSqlCommandAsync instead of "normal"
                    // Entity Framework database functions.  The answer is that we need to atomically
                    // update the Version field of the record, and Entity Framework has no way of
                    // expressing that directly.
                    //
                    // The reason we want to update the version number atomically is that we rely
                    // on the version number being a unique identifier of an annotation.  We don't
                    // want the following scenario:
                    //
                    // Alice tries to set the annotation for key 17 to A, and simultaneously Bob
                    // tries to set it to B.  Each reads the current version number, finds it to be
                    // 3, and updates the annotation to have version 4.  Both of these updates may
                    // succeed, but one will overwrite the other; let's say Bob's write happens last
                    // and "wins".  So Alice may believe that version 4 is A when actually version 4
                    // is B.  When Alice asks for the current version, she'll be told it's version 4,
                    // and Alice will believe this means it's A.  So Alice will believe that A is
                    // what's stored in the database even though it's not.  Alice and Bob's computers
                    // will display different annotations for the same key, indefinitely.
                    //
                    // Note that we need a version number because the timestamp isn't guaranteed to
                    // be unique.  So in the example above Alice and Bob might wind up updating with
                    // the same timestamp.
                    //
                    // You may also wonder why we use DateTime.Now instead of letting the database
                    // assign the timestamp itself.  The reason is that the database might be running
                    // on a different machine than the puzzle server, and it might be using a different
                    // time zone.

                    // First, detach the annotation from the context so the context doesn't think the annotation is in the database.
                    context.Entry(annotation).State = EntityState.Detached;

                    try {
                        var sqlCommand = "UPDATE Annotations SET Version = Version + 1, Contents = @Contents, Timestamp = @Timestamp WHERE PuzzleID = @PuzzleID AND TeamID = @TeamID AND [Key] = @Key";
                        int result     = await context.Database.ExecuteSqlCommandAsync(sqlCommand,
                                                                                       new SqlParameter("@Contents", annotationRequest.contents),
                                                                                       new SqlParameter("@Timestamp", DateTime.Now),
                                                                                       new SqlParameter("@PuzzleID", puzzleId),
                                                                                       new SqlParameter("@TeamID", teamId),
                                                                                       new SqlParameter("@Key", annotationRequest.key));

                        if (result != 1)
                        {
                            response.AddError("Annotation update failed.");
                        }
                    }
                    catch (DbUpdateException) {
                        response.AddError("Encountered error while trying to update annotation.");
                    }
                    catch (Exception) {
                        response.AddError("Miscellaneous error while trying to update annotation.");
                    }
                }
            }
        }