/// <summary>
        /// Gets all the settings data required for the client.
        /// </summary>
        /// <param name="id">Id of the homepage or -1 if global settings.</param>
        public GigyaSettingsApiResponseModel Get(int id)
        {
            var settingsHelper = new Umbraco.Module.Helpers.GigyaSettingsHelper();
            var data           = settingsHelper.Get(id);
            var model          = GetModel(id, data);

            var memberType = this.ApplicationContext.Services.MemberTypeService.Get(Constants.MemberTypeAlias);

            var wrappedModel = new GigyaSettingsApiResponseModel
            {
                Settings = model,
                Data     = new GigyaConfigModel
                {
                    Languages = GigyaLanguageHelper.Languages.Select(i => new GigyaLanguageModel {
                        Code = i.Key, Name = i.Value
                    }).ToList(),
                    MemberProperties = memberType.PropertyTypes.Select(i => new GigyaMemberPropertyViewModel
                    {
                        Alias = i.Alias,
                        Name  = i.Name
                    }).ToList()
                }
            };

            wrappedModel.Data.LanguageOptions = wrappedModel.Data.Languages.ToList();
            wrappedModel.Data.LanguageOptions.Insert(0, new GigyaLanguageModel
            {
                Code = Core.Constants.Languages.Other,
                Name = Core.Constants.Languages.Other
            });
            wrappedModel.Data.LanguageOptions.Insert(0, new GigyaLanguageModel
            {
                Code = Core.Constants.Languages.Auto,
                Name = Core.Constants.Languages.AutoName
            });

            return(wrappedModel);
        }
        public GigyaSettingsResponseModel Save(GigyaSettingsModel model)
        {
            var response = new GigyaSettingsResponseModel();

            if (!ModelState.IsValid)
            {
                var errorList = ModelState.Values.SelectMany(m => m.Errors)
                                .Select(e => e.ErrorMessage)
                                .ToList();

                response.Error = string.Join(" ", errorList);
                _logger.Error(response.Error);
                return(response);
            }

            var settingsHelper = new Umbraco.Module.Helpers.GigyaSettingsHelper();

            if (model.Inherited && model.Id > 0)
            {
                settingsHelper.Delete(model.Id);
                response.Success = true;

                // return global settings to refresh client
                var globalData  = settingsHelper.Get(model.Id);
                var globalModel = GetModel(model.Id, globalData);
                response.Settings = globalModel;
                return(response);
            }

            var user     = UmbracoContext.Application.Services.UserService.GetByUsername(User.Identity.Name);
            var settings = settingsHelper.GetRaw(model.Id);

            // update all fields
            settings.ApiKey           = model.ApiKey;
            settings.DebugMode        = model.DebugMode;
            settings.ApplicationKey   = model.ApplicationKey;
            settings.DataCenter       = !string.IsNullOrEmpty(model.DataCenter) && model.DataCenter != Core.Constants.DataCenter.Other ? model.DataCenter : model.DataCenterOther;
            settings.EnableRaas       = model.EnableRaas;
            settings.GlobalParameters = model.GlobalParameters;
            settings.Language         = !string.IsNullOrEmpty(model.Language.Code) && model.Language.Code != Core.Constants.Languages.Other ? model.Language.Code : model.LanguageOther;
            settings.LanguageFallback = model.LanguageFallback.Code;
            settings.MappingFields    = JsonConvert.SerializeObject(model.MappingFields);
            settings.RedirectUrl      = model.RedirectUrl;
            settings.LogoutUrl        = model.LogoutUrl;
            settings.SessionTimeout   = model.SessionTimeout;
            settings.SessionProvider  = (int)model.SessionProvider;

            if (model.MappingFields == null || !model.MappingFields.Any())
            {
                response.Error = Constants.Errors.UIDFieldRequired;
                _logger.Error(response.Error);
                return(response);
            }

            // validate that there is a mapping field for UID
            var usernameMappingExists = model.MappingFields.Any(i => i.GigyaFieldName == Constants.GigyaFields.UserId);

            if (!usernameMappingExists)
            {
                response.Error = Constants.Errors.UIDFieldRequired;
                _logger.Error(response.Error);
                return(response);
            }

            if (model.MappingFields.Any(i => string.IsNullOrEmpty(i.GigyaFieldName)))
            {
                response.Error = Constants.Errors.GigyaFieldNameRequired;
                _logger.Error(response.Error);
                return(response);
            }

            if (model.MappingFields.Any(i => string.IsNullOrEmpty(i.CmsFieldName)))
            {
                response.Error = Constants.Errors.CmsFieldNameRequired;
                _logger.Error(response.Error);
                return(response);
            }

            // application secret that we will use to validate the settings - store this in a separate var as it's unencrypted
            string plainTextApplicationSecret = string.Empty;

            // check if user can view application secret
            if (!string.IsNullOrEmpty(model.ApplicationSecret))
            {
                plainTextApplicationSecret = model.ApplicationSecret;
                var canViewApplicationSecret = (user.UserType.Name == Constants.UserTypes.Admin) || User.IsInRole(Constants.Roles.GigyaAdmin);
                if (canViewApplicationSecret)
                {
                    if (!Encryptor.IsConfigured)
                    {
                        response.Error = "Encryption key not specified. Refer to installation guide.";
                        _logger.Error(response.Error);
                        return(response);
                    }
                    settings.ApplicationSecret = Encryptor.Encrypt(model.ApplicationSecret);
                }
            }

            if (string.IsNullOrEmpty(plainTextApplicationSecret) && Encryptor.IsConfigured && !string.IsNullOrEmpty(settings.ApplicationSecret))
            {
                plainTextApplicationSecret = TryDecryptApplicationSecret(settings.ApplicationSecret, false);
                if (string.IsNullOrEmpty(plainTextApplicationSecret))
                {
                    response.Error = "Application Secret could not be decrypted. Please re-enter it.";
                    _logger.Error(response.Error);
                    return(response);
                }
            }

            var mappedSettings = Map(settings);

            mappedSettings.ApplicationSecret = plainTextApplicationSecret;

            try
            {
                // validate input
                settingsHelper.Validate(mappedSettings);
            }
            catch (Exception e)
            {
                _logger.Error(response.Error);
                response.Error = e.Message;
                return(response);
            }

            // verify settings are correct
            var apiHelper    = new GigyaApiHelper(settingsHelper, _logger);
            var testResponse = apiHelper.VerifySettings(mappedSettings, plainTextApplicationSecret);

            if (testResponse.GetErrorCode() != 0)
            {
                var gigyaErrorDetail = testResponse.GetString("errorDetails", string.Empty);
                var message          = testResponse.GetErrorMessage();
                if (!string.IsNullOrEmpty(gigyaErrorDetail))
                {
                    message = string.Concat(message, ". ", gigyaErrorDetail);
                }

                response.Error = message;
                return(response);
            }

            settingsHelper.Save(settings);

            response.Success = true;
            return(response);
        }