public static User GetUserFromClaims(ClaimsPrincipal userPrincipal, IUserRepository userRepository, IApiRequestLogger requestLogger)
        {
            string externalId;
            string emailAddress;
            bool   emailVerified;

            try
            {
                externalId    = userPrincipal.FindFirst(ClaimTypes.NameIdentifier).Value;
                emailAddress  = userPrincipal.FindFirst(TivClaimTypes.EmailIdentifier).Value;
                emailVerified = userPrincipal.FindFirst(TivClaimTypes.EmailVerifiedIdentifier).Value.IsTrue();
            }
            catch
            {
                throw new WebRequestException(401, GENERAL_AUTH_ERROR);
            }

            if (externalId.IsNullOrEmpty() || emailAddress.IsNullOrEmpty())
            {
                throw new WebRequestException(401, GENERAL_AUTH_ERROR);
            }

            if (!emailVerified)
            {
                throw new WebRequestException(401, "User has not verified their primary email address.");
            }

            User user = null;

            // If we can't ensure the maximum user name from the external source as our search and as our key then we can only rely on email address. This is unllikely but possible.
            if (externalId.Length > 50)
            {
                requestLogger.LogWarn($"External User Name '{externalId}' will be truncated because of length, cannot use for ID based search and must rely on Email '{emailAddress}'.");
                externalId = externalId.VerifySize(50);
            }
            else
            {
                user = userRepository.FindByUserName(externalId);
            }

            if (user == null)
            {
                requestLogger.LogInfo($"User not found by User Name '{externalId}' searching by Email '{emailAddress}'.");
                user = userRepository.FindByEmail(emailAddress);
            }

            if (user == null)
            {
                user = NewUserFromExternalClaims(externalId, emailAddress);
                userRepository.Insert(user, externalId);
                requestLogger.LogInfo($"User not found by eternal information User Name '{externalId}' and Email '{emailAddress}', created a new user with ID '{user.Id}'.");
            }
            else if (!user.UserName.CompareNoCase(externalId) || !user.Email.CompareNoCase(emailAddress))
            {
                var changeNote =
                    $"Changing User Name and/or Email to to new value(s) given by external authority. '{user.UserName}' => '{externalId}', '{user.Email}' => '{emailAddress}'";
                requestLogger.LogWarn(changeNote);
                changeNote = $"{changeNote} on {DateTime.Now}";
                if (!user.Notes.IsNullOrEmpty())
                {
                    user.Notes += Environment.NewLine + changeNote;
                }
                else
                {
                    user.Notes = changeNote;
                }
                user.UserName = externalId;
                user.Email    = emailAddress;
                if (user.UserAccomplishments.Count == 0)
                {
                    requestLogger.LogInfo($"Adding default accomplishments to User Name '{externalId}' and Email '{emailAddress}'");
                    AddUserCreatedAccomplishment(user);
                }
                userRepository.Update(user, externalId);
            }
            else if (user.UserAccomplishments.Count == 0)
            {
                requestLogger.LogInfo($"Adding default accomplishments to User Name '{user.UserName}' and Email '{user.Email}'");
                AddUserCreatedAccomplishment(user);
                userRepository.Update(user, user.UserName);
            }

            return(user);
        }