public async Task <IActionResult> CreateContact([FromBody] ViewModels.Contact item)
        {
            // get the current user.
            UserSettings userSettings = UserSettings.CreateFromHttpContext(_httpContextAccessor);

            // first check to see that a contact exists.
            var contactSiteminderGuid = userSettings.SiteMinderGuid;

            if (contactSiteminderGuid == null || contactSiteminderGuid.Length == 0)
            {
                _logger.LogDebug(LoggingEvents.Error, "No Contact Siteminder Guid exernal id");
                throw new Exception("Error. No ContactSiteminderGuid exernal id");
            }

            // get the contact record.
            MicrosoftDynamicsCRMcontact userContact = null;

            // see if the contact exists.
            try
            {
                userContact = _dynamicsClient.GetActiveContactByExternalId(contactSiteminderGuid);
                if (userContact != null)
                {
                    throw new Exception("Contact already Exists");
                }
            }
            catch (HttpOperationException httpOperationException)
            {
                _logger.LogError(httpOperationException, "Error getting contact by Siteminder Guid.");
                throw new HttpOperationException("Error getting contact by Siteminder Guid");
            }

            // create a new contact.
            var contact = new MicrosoftDynamicsCRMcontact();

            contact.CopyValues(item);


            if (userSettings.IsNewUserRegistration)
            {
                // get additional information from the service card headers.
                contact.CopyHeaderValues(_httpContextAccessor);
            }

            contact.AdoxioExternalid = DynamicsExtensions.GetServiceCardID(contactSiteminderGuid);
            try
            {
                contact = await _dynamicsClient.Contacts.CreateAsync(contact);
            }
            catch (HttpOperationException httpOperationException)
            {
                _logger.LogError(httpOperationException, "Error creating contact. ");
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Unknown error creating contact.");
            }

            // if we have not yet authenticated, then this is the new record for the user.
            if (userSettings.IsNewUserRegistration)
            {
                userSettings.ContactId = contact.Contactid;

                // we can now authenticate.
                if (userSettings.AuthenticatedUser == null)
                {
                    var user = new User();
                    user.Active    = true;
                    user.ContactId = Guid.Parse(userSettings.ContactId);
                    user.UserType  = userSettings.UserType;
                    user.SmUserId  = userSettings.UserId;
                    userSettings.AuthenticatedUser = user;
                }

                userSettings.IsNewUserRegistration = false;

                var userSettingsString = JsonConvert.SerializeObject(userSettings);
                _logger.LogDebug("userSettingsString --> " + userSettingsString);

                // add the user to the session.
                _httpContextAccessor.HttpContext.Session.SetString("UserSettings", userSettingsString);
                _logger.LogDebug("user added to session. ");
            }
            else
            {
                _logger.LogDebug(LoggingEvents.Error, "Invalid user registration.");
                throw new Exception("Invalid user registration.");
            }

            return(new JsonResult(contact.ToViewModel()));
        }
        /// <summary>
        /// Process Authentication Request
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            // get siteminder headers
            _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");


            string userId                 = null;
            string devCompanyId           = null;
            string siteMinderGuid         = "";
            string siteMinderBusinessGuid = "";
            string siteMinderUserType     = "";

            try
            {
                ClaimsPrincipal principal;
                HttpContext     context      = Request.HttpContext;
                UserSettings    userSettings = new UserSettings();

                IConfiguration _configuration = (IConfiguration)context.RequestServices.GetService(typeof(IConfiguration));
                _dynamicsClient = (IDynamicsClient)context.RequestServices.GetService(typeof(IDynamicsClient));

                IWebHostEnvironment hostingEnv = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment));

                // Fail if login disabled
                if (!string.IsNullOrEmpty(_configuration["FEATURE_DISABLE_LOGIN"]))
                {
                    return(AuthenticateResult.Fail(_options.LoginDisabledError));
                }

                // Fail if coming from JS
                if (context.Request.GetDisplayUrl().ToLower().Contains(".js"))
                {
                    return(AuthenticateResult.NoResult());
                }

                // **************************************************
                // Check if the user session is already created
                // **************************************************
                try
                {
                    _logger.Debug("Checking user session");
                    userSettings = UserSettings.ReadUserSettings(context);

                    // fix for cases where AuthenticatedUser contact is empty.
                    if (userSettings?.AuthenticatedUser?.ContactId != null &&
                        userSettings?.AuthenticatedUser?.ContactId == Guid.Empty && !string.IsNullOrEmpty(userSettings?.SiteMinderGuid))
                    {
                        var contact = _dynamicsClient.GetActiveContactByExternalId(userSettings.SiteMinderGuid);
                        if (contact != null)
                        {
                            userSettings.AuthenticatedUser.ContactId = Guid.Parse(contact.Contactid);
                        }
                    }

                    _logger.Debug("UserSettings found: " + userSettings.GetJson());
                }
                catch
                {
                    //do nothing
                    _logger.Debug("No UserSettings found");
                }

                // is user authenticated - if so we're done
                if ((userSettings.UserAuthenticated && string.IsNullOrEmpty(userId)) ||
                    (userSettings.UserAuthenticated && !string.IsNullOrEmpty(userId) &&
                     !string.IsNullOrEmpty(userSettings.UserId) && userSettings.UserId == userId))
                {
                    _logger.Debug("User already authenticated with active session: " + userSettings.UserId);
                    principal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);
                    return(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme)));
                }

                // **************************************************
                // Check if we have a Dev Environment Cookie
                // **************************************************
                if (!hostingEnv.IsProduction() &&
                    (!string.IsNullOrEmpty(context.Request.Cookies[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Cookies[_options.DevBCSCAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevBCSCAuthenticationTokenKey]))
                    )
                {
                    try
                    {
                        return(await LoginDevUser(context, _dynamicsClient));
                    }
                    catch (Exception ex)
                    {
                        _logger.Information(ex.Message);
                        _logger.Information("Couldn't successfully login as dev user - continuing as regular user");
                    }
                }

                // determine if it is the new bridge entity based flow or the legacy.
                if (!string.IsNullOrEmpty(_configuration["FEATURE_BRIDGE_LOGIN"]))
                {
                    return(await HandleBridgeAuthentication(userSettings, context));
                }
                else
                {
                    return(await HandleLegacyAuthentication(userSettings, context));
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception.Message);
                throw;
            }
        }
        /// <summary>
        /// Process Authentication Request
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            // get siteminder headers
            _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");


            string userId                 = null;
            string devCompanyId           = null;
            string siteMinderGuid         = "";
            string siteMinderBusinessGuid = "";
            string siteMinderUserType     = "";

            try
            {
                ClaimsPrincipal principal;
                HttpContext     context      = Request.HttpContext;
                UserSettings    userSettings = new UserSettings();

                IConfiguration _configuration = (IConfiguration)context.RequestServices.GetService(typeof(IConfiguration));
                _dynamicsClient = (IDynamicsClient)context.RequestServices.GetService(typeof(IDynamicsClient));
                FileManagerClient   _fileManagerClient = (FileManagerClient)context.RequestServices.GetService(typeof(FileManagerClient));
                IWebHostEnvironment hostingEnv         = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment));

                // Fail if login disabled
                if (!string.IsNullOrEmpty(_configuration["FEATURE_DISABLE_LOGIN"]))
                {
                    return(AuthenticateResult.Fail(_options.LoginDisabledError));
                }

                // Fail if coming from JS
                if (context.Request.GetDisplayUrl().ToLower().Contains(".js"))
                {
                    return(AuthenticateResult.NoResult());
                }

                // **************************************************
                // Check if the user session is already created
                // **************************************************
                try
                {
                    _logger.Debug("Checking user session");
                    userSettings = UserSettings.ReadUserSettings(context);
                    _logger.Debug("UserSettings found: " + userSettings.GetJson());
                }
                catch
                {
                    //do nothing
                    _logger.Debug("No UserSettings found");
                }

                // is user authenticated - if so we're done
                if ((userSettings.UserAuthenticated && string.IsNullOrEmpty(userId)) ||
                    (userSettings.UserAuthenticated && !string.IsNullOrEmpty(userId) &&
                     !string.IsNullOrEmpty(userSettings.UserId) && userSettings.UserId == userId))
                {
                    _logger.Debug("User already authenticated with active session: " + userSettings.UserId);
                    principal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);
                    return(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme)));
                }

                // **************************************************
                // Check if we have a Dev Environment Cookie
                // **************************************************
                if (!hostingEnv.IsProduction() &&
                    (!string.IsNullOrEmpty(context.Request.Cookies[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Cookies[_options.DevBCSCAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevBCSCAuthenticationTokenKey]))
                    )
                {
                    try
                    {
                        return(await LoginDevUser(context, _dynamicsClient));
                    }
                    catch (Exception ex)
                    {
                        _logger.Information(ex.Message);
                        _logger.Information("Couldn't successfully login as dev user - continuing as regular user");
                    }
                }

                // **************************************************
                // Authenticate based on SiteMinder Headers
                // **************************************************
                _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");
                _logger.Debug("Getting user data from headers");

                if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderUserDisplayNameKey]))
                {
                    userSettings.UserDisplayName = context.Request.Headers[_options.SiteMinderUserDisplayNameKey];
                }

                if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderBusinessLegalNameKey]))
                {
                    userSettings.BusinessLegalName = context.Request.Headers[_options.SiteMinderBusinessLegalNameKey];
                }

                userId = context.Request.Headers[_options.SiteMinderUserNameKey];
                if (string.IsNullOrEmpty(userId))
                {
                    userId = context.Request.Headers[_options.SiteMinderUniversalIdKey];
                }

                siteMinderGuid         = context.Request.Headers[_options.SiteMinderUserGuidKey];
                siteMinderBusinessGuid = context.Request.Headers[_options.SiteMinderBusinessGuidKey];
                siteMinderUserType     = context.Request.Headers[_options.SiteMinderUserTypeKey];


                // **************************************************
                // Validate credentials
                // **************************************************
                if (string.IsNullOrEmpty(userId))
                {
                    _logger.Debug(_options.MissingSiteMinderUserIdError);
                    return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
                }

                if (string.IsNullOrEmpty(siteMinderGuid))
                {
                    _logger.Debug(_options.MissingSiteMinderGuidError);
                    return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
                }
                if (string.IsNullOrEmpty(siteMinderUserType))
                {
                    _logger.Debug(_options.MissingSiteMinderUserTypeError);
                    return(AuthenticateResult.Fail(_options.MissingSiteMinderUserTypeError));
                }

                _logger.Debug("Loading user external id = " + siteMinderGuid);
                // 3/18/2020 - Note that LoadUser will now work if there is a match on the guid, as well as a match on name in a case where there is no guid.
                userSettings.AuthenticatedUser = await _dynamicsClient.LoadUser(siteMinderGuid, context.Request.Headers, _ms_logger);

                _logger.Information("After getting authenticated user = "******" (" + userId + ")");
                    return(AuthenticateResult.Fail(_options.InactivegDbUserIdError));
                }

                // set the usertype to siteminder
                if (userSettings.AuthenticatedUser != null &&
                    !string.IsNullOrEmpty(siteMinderUserType))
                {
                    userSettings.AuthenticatedUser.UserType = siteMinderUserType;
                }

                userSettings.UserType = siteMinderUserType;

                // Get the various claims for the current user.
                ClaimsPrincipal userPrincipal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);

                // **************************************************
                // Create authenticated user
                // **************************************************
                _logger.Debug("Authentication successful: " + userId);
                _logger.Debug("Setting identity and creating session for: " + userId);

                // create session info for the current user
                userSettings.UserId                = userId;
                userSettings.UserAuthenticated     = true;
                userSettings.IsNewUserRegistration = userSettings.AuthenticatedUser == null;

                // set other session info
                userSettings.SiteMinderGuid         = siteMinderGuid;
                userSettings.SiteMinderBusinessGuid = siteMinderBusinessGuid;
                _logger.Debug("Before getting contact and account ids = " + userSettings.GetJson());

                if (userSettings.AuthenticatedUser != null)
                {
                    userSettings.ContactId = userSettings.AuthenticatedUser.ContactId.ToString();
                    // ensure that the given account has a documents folder.

                    if (siteMinderBusinessGuid != null) // BCeID user
                    {
                        var contact = _dynamicsClient.GetActiveContactByExternalId(userSettings.ContactId);
                        if (contact == null)
                        {
                            // try by other means.
                            var contactVM = new Contact();
                            contactVM.CopyHeaderValues(context.Request.Headers);
                            contact = _dynamicsClient.GetContactByContactVmBlankSmGuid(contactVM);
                        }
                        if (contact != null && contact.Contactid != null)
                        {
                            await CreateSharePointContactDocumentLocation(_fileManagerClient, contact);
                        }

                        // Note that this will search for active accounts
                        var account = await _dynamicsClient.GetActiveAccountBySiteminderBusinessGuid(siteMinderBusinessGuid);

                        if (account == null)
                        {
                            // try by other means.
                            account = _dynamicsClient.GetActiveAccountByLegalName(userSettings.BusinessLegalName);
                        }
                        if (account != null && account.Accountid != null)
                        {
                            userSettings.AccountId = account.Accountid;
                            userSettings.AuthenticatedUser.AccountId = Guid.Parse(account.Accountid);

                            // ensure that the given account has a documents folder.
                            await CreateSharePointAccountDocumentLocation(_fileManagerClient, account);
                        }
                        else  // force the new user process if contact exists but account does not.
                        {
                            userSettings.AuthenticatedUser     = null;
                            userSettings.IsNewUserRegistration = true;
                        }
                    }
                }

                // add the worker settings if it is a new user.
                if (userSettings.IsNewUserRegistration)
                {
                    userSettings.NewWorker = new Worker();
                    userSettings.NewWorker.CopyHeaderValues(context.Request.Headers);

                    userSettings.NewContact = new Contact();
                    userSettings.NewContact.CopyHeaderValues(context.Request.Headers);
                }
                else if (siteMinderUserType == "VerifiedIndividual")
                {
                    await HandleVerifiedIndividualLogin(userSettings, context);

                    if (HttpUtility.ParseQueryString(context.Request.QueryString.ToString()).Get("path") != "cannabis-associate-screening")
                    {
                        await HandleWorkerLogin(userSettings, context);
                    }
                }

                // **************************************************
                // Update user settings
                // **************************************************
                UserSettings.SaveUserSettings(userSettings, context);

                return(AuthenticateResult.Success(new AuthenticationTicket(userPrincipal, null, Options.Scheme)));
            }
            catch (Exception exception)
            {
                _logger.Error(exception.Message);
                throw;
            }
        }
        private async Task <AuthenticateResult> HandleLegacyAuthentication(UserSettings userSettings, HttpContext context)
        {
            // **************************************************
            // Authenticate based on SiteMinder Headers
            // **************************************************
            _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");
            _logger.Debug("Getting user data from headers");

            FileManagerClient _fileManagerClient = (FileManagerClient)context.RequestServices.GetService(typeof(FileManagerClient));

            if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderUserDisplayNameKey]))
            {
                userSettings.UserDisplayName = context.Request.Headers[_options.SiteMinderUserDisplayNameKey];
            }

            if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderBusinessLegalNameKey]))
            {
                userSettings.BusinessLegalName = context.Request.Headers[_options.SiteMinderBusinessLegalNameKey];
            }

            var userId = context.Request.Headers[_options.SiteMinderUserNameKey];

            if (string.IsNullOrEmpty(userId))
            {
                userId = context.Request.Headers[_options.SiteMinderUniversalIdKey];
            }

            string siteMinderGuid         = context.Request.Headers[_options.SiteMinderUserGuidKey];
            string siteMinderBusinessGuid = context.Request.Headers[_options.SiteMinderBusinessGuidKey];
            string siteMinderUserType     = context.Request.Headers[_options.SiteMinderUserTypeKey];


            // **************************************************
            // Validate credentials
            // **************************************************
            if (string.IsNullOrEmpty(userId))
            {
                _logger.Debug(_options.MissingSiteMinderUserIdError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
            }

            if (string.IsNullOrEmpty(siteMinderGuid))
            {
                _logger.Debug(_options.MissingSiteMinderGuidError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
            }
            if (string.IsNullOrEmpty(siteMinderUserType))
            {
                _logger.Debug(_options.MissingSiteMinderUserTypeError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderUserTypeError));
            }

            _logger.Debug("Loading user external id = " + siteMinderGuid);
            // 3/18/2020 - Note that LoadUserLegacy will now work if there is a match on the guid, as well as a match on name in a case where there is no guid.
            userSettings.AuthenticatedUser = await _dynamicsClient.LoadUserLegacy(siteMinderGuid, context.Request.Headers, _ms_logger);

            _logger.Information("After getting authenticated user = "******" (" + userId + ")");
                return(AuthenticateResult.Fail(_options.InactivegDbUserIdError));
            }

            // set the usertype to siteminder
            if (userSettings.AuthenticatedUser != null &&
                !string.IsNullOrEmpty(siteMinderUserType))
            {
                userSettings.AuthenticatedUser.UserType = siteMinderUserType;
            }

            userSettings.UserType = siteMinderUserType;

            // Get the various claims for the current user.
            ClaimsPrincipal userPrincipal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);

            // **************************************************
            // Create authenticated user
            // **************************************************
            _logger.Debug("Authentication successful: " + userId);
            _logger.Debug("Setting identity and creating session for: " + userId);

            // create session info for the current user
            userSettings.UserId                = userId;
            userSettings.UserAuthenticated     = true;
            userSettings.IsNewUserRegistration = userSettings.AuthenticatedUser == null;

            // set other session info
            userSettings.SiteMinderGuid         = siteMinderGuid;
            userSettings.SiteMinderBusinessGuid = siteMinderBusinessGuid;
            _logger.Debug("Before getting contact and account ids = " + userSettings.GetJson());

            if (userSettings.AuthenticatedUser != null)
            {
                userSettings.ContactId = userSettings.AuthenticatedUser.ContactId.ToString();
                // ensure that the given account has a documents folder.

                if (siteMinderBusinessGuid != null) // BCeID user
                {
                    var contact = _dynamicsClient.GetActiveContactByExternalId(userSettings.ContactId);
                    if (contact == null)
                    {
                        // try by other means.
                        var contactVM = new ViewModels.Contact();
                        contactVM.CopyHeaderValues(context.Request.Headers);
                        contact = _dynamicsClient.GetContactByContactVmBlankSmGuid(contactVM);
                    }
                    if (contact != null && contact.Contactid != null)
                    {
                        await CreateSharePointContactDocumentLocation(_fileManagerClient, contact);
                    }

                    // Note that this will search for active accounts
                    var account = await _dynamicsClient.GetActiveAccountBySiteminderBusinessGuid(siteMinderBusinessGuid);

                    if (account == null)
                    {
                        // try by other means.
                        account = _dynamicsClient.GetActiveAccountByLegalName(userSettings.BusinessLegalName);
                    }
                    if (account != null && account.Accountid != null)
                    {
                        userSettings.AccountId = account.Accountid;
                        userSettings.AuthenticatedUser.AccountId = Guid.Parse(account.Accountid);

                        // ensure that the given account has a documents folder.
                        await CreateSharePointAccountDocumentLocation(_fileManagerClient, account);
                    }
                    else  // force the new user process if contact exists but account does not.
                    {
                        userSettings.AuthenticatedUser     = null;
                        userSettings.IsNewUserRegistration = true;
                    }

                    // handle cases where Contact was deleted.
                    if (contact == null)
                    {
                        userSettings.IsNewUserRegistration = true;
                    }
                }
            }

            // add the worker settings if it is a new user.
            if (userSettings.IsNewUserRegistration)
            {
                userSettings.NewWorker = new Worker();
                userSettings.NewWorker.CopyHeaderValues(context.Request.Headers);

                userSettings.NewContact = new ViewModels.Contact();
                userSettings.NewContact.CopyHeaderValues(context.Request.Headers);
            }
            else if (siteMinderUserType == "VerifiedIndividual")
            {
                await HandleVerifiedIndividualLogin(userSettings, context);

                if (HttpUtility.ParseQueryString(context.Request.QueryString.ToString()).Get("path") != "cannabis-associate-screening")
                {
                    await HandleWorkerLogin(userSettings, context);
                }
            }

            // **************************************************
            // Update user settings
            // **************************************************
            UserSettings.SaveUserSettings(userSettings, context);

            return(AuthenticateResult.Success(new AuthenticationTicket(userPrincipal, null, Options.Scheme)));
        }