955 lines
46 KiB
C#
955 lines
46 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="ClientSettingsProvider.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.Web.ClientServices.Providers
|
||
|
{
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Specialized;
|
||
|
using System.ComponentModel;
|
||
|
using System.Configuration;
|
||
|
using System.Configuration.Provider;
|
||
|
using System.Diagnostics;
|
||
|
using System.Globalization;
|
||
|
using System.IO;
|
||
|
using System.Security;
|
||
|
using System.Security.Principal;
|
||
|
using System.Security.Permissions;
|
||
|
using System.Net;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Activation;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.ServiceModel.Dispatcher;
|
||
|
using System.Web.ClientServices;
|
||
|
using System.Web.Resources;
|
||
|
using System.Web.Security;
|
||
|
using System.Threading;
|
||
|
using System.Data;
|
||
|
using System.Data.Common;
|
||
|
using System.Reflection;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Web.ApplicationServices;
|
||
|
using System.Web.Script.Serialization;
|
||
|
using System.Diagnostics.CodeAnalysis;
|
||
|
|
||
|
[SecurityCritical]
|
||
|
[PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
|
||
|
public class ClientSettingsProvider : SettingsProvider, IApplicationSettingsProvider
|
||
|
{
|
||
|
private string _ConnectionString = null;
|
||
|
private string _ConnectionStringProvider = "";
|
||
|
private bool _NeedToDoReset = false;
|
||
|
private bool _HonorCookieExpiry = false;
|
||
|
private bool _firstTime = true;
|
||
|
private string _UserName = "";
|
||
|
|
||
|
private SettingsPropertyValueCollection _PropertyValues = new SettingsPropertyValueCollection();
|
||
|
private SettingsPropertyCollection _Properties = null;
|
||
|
private static Hashtable _KnownTypesHashtable = null;
|
||
|
private static Type [] _KnownTypesArray = null;
|
||
|
|
||
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
public override string ApplicationName {
|
||
|
[SecuritySafeCritical]
|
||
|
get { return ""; }
|
||
|
[SecuritySafeCritical]
|
||
|
set { } }
|
||
|
private static string _ServiceUri = "";
|
||
|
private static object _lock = new object();
|
||
|
private static bool _UsingFileSystemStore = false;
|
||
|
private static bool _UsingIsolatedStore = true;
|
||
|
private static bool _UsingWFCService = false;
|
||
|
private static ApplicationSettingsBase _SettingsBaseClass = null;
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId="0#", Justification="Reviewed and approved by feature crew"),
|
||
|
SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")]
|
||
|
public static SettingsPropertyCollection GetPropertyMetadata(string serviceUri)
|
||
|
{
|
||
|
CookieContainer cookies = null;
|
||
|
IIdentity id = Thread.CurrentPrincipal.Identity;
|
||
|
SettingsPropertyCollection retColl = new SettingsPropertyCollection();
|
||
|
|
||
|
|
||
|
if (id is ClientFormsIdentity)
|
||
|
cookies = ((ClientFormsIdentity)id).AuthenticationCookies;
|
||
|
|
||
|
if (serviceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase)) {
|
||
|
throw new NotImplementedException();
|
||
|
|
||
|
// CustomBinding binding = ProxyHelper.GetBinding();
|
||
|
// ChannelFactory<ProfileService> channelFactory = new ChannelFactory<ProfileService>(binding, new EndpointAddress(serviceUri));
|
||
|
// ProfilePropertyMetadata[] props = null;
|
||
|
// ProfileService clientService = channelFactory.CreateChannel();
|
||
|
|
||
|
// using (new OperationContextScope((IContextChannel)clientService)) {
|
||
|
// ProxyHelper.AddCookiesToWCF(cookies, serviceUri, id.Name, null, null);
|
||
|
// props = clientService.GetPropertiesMetadata();
|
||
|
// ProxyHelper.GetCookiesFromWCF(cookies, serviceUri, id.Name, null, null);
|
||
|
// }
|
||
|
// if (props == null)
|
||
|
// return retColl;
|
||
|
|
||
|
// for(int iter=0; iter<props.Length; iter++) {
|
||
|
// AddToColl(props[iter], retColl, id.IsAuthenticated);
|
||
|
// }
|
||
|
|
||
|
} else {
|
||
|
object o = ProxyHelper.CreateWebRequestAndGetResponse(serviceUri + "/GetPropertiesMetadata",
|
||
|
ref cookies,
|
||
|
id.Name,
|
||
|
null,
|
||
|
null,
|
||
|
null,
|
||
|
null,
|
||
|
typeof(Collection<ProfilePropertyMetadata>));
|
||
|
|
||
|
Collection<ProfilePropertyMetadata> props2 = (Collection<ProfilePropertyMetadata>) o;
|
||
|
if (props2 != null) {
|
||
|
foreach(ProfilePropertyMetadata p in props2)
|
||
|
AddToColl(p, retColl, id.IsAuthenticated);
|
||
|
}
|
||
|
}
|
||
|
return retColl;
|
||
|
}
|
||
|
private static void AddToColl(ProfilePropertyMetadata p, SettingsPropertyCollection retColl, bool isAuthenticated) {
|
||
|
string propName = p.PropertyName;
|
||
|
Type propType = Type.GetType(p.TypeName, false, true);
|
||
|
bool allowAnon = p.AllowAnonymousAccess;
|
||
|
bool readOnly = p.IsReadOnly;
|
||
|
|
||
|
if (!allowAnon && !isAuthenticated)
|
||
|
return;
|
||
|
|
||
|
SettingsSerializeAs serializeAs = (SettingsSerializeAs)p.SerializeAs;
|
||
|
SettingsAttributeDictionary dict = new SettingsAttributeDictionary();
|
||
|
dict.Add("AllowAnonymous", allowAnon);
|
||
|
retColl.Add(new SettingsProperty(propName, propType, null, readOnly,p.DefaultValue, serializeAs, dict, true, true));
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
[SecuritySafeCritical]
|
||
|
public override void Initialize(string name, NameValueCollection config) {
|
||
|
|
||
|
_UsingIsolatedStore = false;
|
||
|
|
||
|
// Initialize using appSettings section
|
||
|
string temp = System.Configuration.ConfigurationManager.AppSettings["ClientSettingsProvider.ServiceUri"];
|
||
|
if (!string.IsNullOrEmpty(temp))
|
||
|
ServiceUri = temp;
|
||
|
|
||
|
temp = System.Configuration.ConfigurationManager.AppSettings["ClientSettingsProvider.ConnectionStringName"];
|
||
|
if (!string.IsNullOrEmpty(temp)) {
|
||
|
if (ConfigurationManager.ConnectionStrings[temp] != null) {
|
||
|
_ConnectionStringProvider = ConfigurationManager.ConnectionStrings[temp].ProviderName;
|
||
|
_ConnectionString = ConfigurationManager.ConnectionStrings[temp].ConnectionString;
|
||
|
} else {
|
||
|
_ConnectionString = temp;
|
||
|
}
|
||
|
} else {
|
||
|
_ConnectionString = SqlHelper.GetDefaultConnectionString();
|
||
|
}
|
||
|
|
||
|
|
||
|
temp = System.Configuration.ConfigurationManager.AppSettings["ClientSettingsProvider.HonorCookieExpiry"];
|
||
|
if (!string.IsNullOrEmpty(temp))
|
||
|
_HonorCookieExpiry = (string.Compare(temp, "true", StringComparison.OrdinalIgnoreCase) == 0);
|
||
|
if (name == null)
|
||
|
name = this.GetType().ToString();
|
||
|
|
||
|
base.Initialize(name, config);
|
||
|
|
||
|
if (config != null) {
|
||
|
temp = config["serviceUri"];
|
||
|
if (!string.IsNullOrEmpty(temp))
|
||
|
ServiceUri = temp;
|
||
|
|
||
|
temp = config["connectionStringName"];
|
||
|
if (!string.IsNullOrEmpty(temp)) {
|
||
|
if (ConfigurationManager.ConnectionStrings[temp] != null) {
|
||
|
_ConnectionStringProvider = ConfigurationManager.ConnectionStrings[temp].ProviderName;
|
||
|
_ConnectionString = ConfigurationManager.ConnectionStrings[temp].ConnectionString;
|
||
|
} else {
|
||
|
_ConnectionString = temp;
|
||
|
}
|
||
|
}
|
||
|
config.Remove("name");
|
||
|
config.Remove("description");
|
||
|
config.Remove("connectionStringName");
|
||
|
config.Remove("serviceUri");
|
||
|
foreach (string attribUnrecognized in config.Keys)
|
||
|
if (!String.IsNullOrEmpty(attribUnrecognized))
|
||
|
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, AtlasWeb.AttributeNotRecognized, attribUnrecognized));
|
||
|
}
|
||
|
|
||
|
switch(SqlHelper.IsSpecialConnectionString(_ConnectionString))
|
||
|
{
|
||
|
case 1:
|
||
|
_UsingFileSystemStore = true;
|
||
|
break;
|
||
|
case 2:
|
||
|
_UsingIsolatedStore = true;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
[SecuritySafeCritical]
|
||
|
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection propertyCollection) {
|
||
|
if (propertyCollection == null || propertyCollection.Count < 1)
|
||
|
return new SettingsPropertyValueCollection();
|
||
|
lock(_lock) {
|
||
|
if (_SettingsBaseClass == null && context != null) {
|
||
|
Type oType = context["SettingsClassType"] as Type;
|
||
|
if (oType != null) {
|
||
|
_SettingsBaseClass = oType.InvokeMember("Default", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static,
|
||
|
null, null, null, CultureInfo.InvariantCulture) as ApplicationSettingsBase;
|
||
|
}
|
||
|
}
|
||
|
_PropertyValues = new SettingsPropertyValueCollection();
|
||
|
_Properties = propertyCollection;
|
||
|
|
||
|
StoreKnownTypes(propertyCollection);
|
||
|
GetPropertyValuesCore();
|
||
|
return _PropertyValues;
|
||
|
}
|
||
|
}
|
||
|
private void GetPropertyValuesCore()
|
||
|
{
|
||
|
_UserName = Thread.CurrentPrincipal.Identity.Name;
|
||
|
if (_firstTime) {
|
||
|
_firstTime = false;
|
||
|
_NeedToDoReset = GetNeedToReset();
|
||
|
RegisterForValidateUserEvent();
|
||
|
}
|
||
|
|
||
|
if (_NeedToDoReset) {
|
||
|
_NeedToDoReset = false;
|
||
|
SetNeedToReset(false);
|
||
|
_PropertyValues = new SettingsPropertyValueCollection();
|
||
|
SetRemainingValuesToDefault();
|
||
|
SetPropertyValuesCore(_PropertyValues, false);
|
||
|
}
|
||
|
|
||
|
bool isCacheMoreFresh = GetIsCacheMoreFresh();
|
||
|
|
||
|
GetPropertyValuesFromSQL(); // Always start with the local copy
|
||
|
|
||
|
if (!ConnectivityStatus.IsOffline) {
|
||
|
if (isCacheMoreFresh) {
|
||
|
SetPropertyValuesWeb(_PropertyValues, isCacheMoreFresh); // local copy is fresher, so update the web-copy
|
||
|
} else {
|
||
|
GetPropertyValuesFromWeb();
|
||
|
SetPropertyValuesSQL(_PropertyValues, false);
|
||
|
}
|
||
|
}
|
||
|
if (_PropertyValues.Count < _Properties.Count)
|
||
|
SetRemainingValuesToDefault();
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
[SecuritySafeCritical]
|
||
|
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propertyValueCollection) {
|
||
|
if (propertyValueCollection == null || propertyValueCollection.Count < 1)
|
||
|
return;
|
||
|
lock(_lock) {
|
||
|
StoreKnownTypes(propertyValueCollection);
|
||
|
SetPropertyValuesCore(propertyValueCollection, true);
|
||
|
}
|
||
|
}
|
||
|
private void SetPropertyValuesCore(SettingsPropertyValueCollection values, bool raiseEvent) {
|
||
|
lock(_lock) {
|
||
|
bool isCacheMoreFresh = GetIsCacheMoreFresh();
|
||
|
// First store in SQL
|
||
|
SetPropertyValuesSQL(values, true);
|
||
|
|
||
|
Collection<string> errorList = null;
|
||
|
// Store in web if it is offline
|
||
|
if (!ConnectivityStatus.IsOffline)
|
||
|
errorList = SetPropertyValuesWeb(values, isCacheMoreFresh);
|
||
|
|
||
|
if (raiseEvent && SettingsSaved != null) {
|
||
|
if (errorList == null)
|
||
|
errorList = new Collection<string>();
|
||
|
SettingsSaved(this, new SettingsSavedEventArgs(errorList));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
[SecuritySafeCritical]
|
||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
public void Reset(SettingsContext context) {
|
||
|
lock(_lock) {
|
||
|
if (_Properties == null) {
|
||
|
SetNeedToReset(true);
|
||
|
} else {
|
||
|
_PropertyValues = new SettingsPropertyValueCollection();
|
||
|
SetRemainingValuesToDefault();
|
||
|
SetPropertyValues(context, _PropertyValues);
|
||
|
_NeedToDoReset = false;
|
||
|
SetNeedToReset(false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
[SecuritySafeCritical]
|
||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
public void Upgrade(SettingsContext context, SettingsPropertyCollection properties) {
|
||
|
return;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
[SecuritySafeCritical]
|
||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||
|
public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property) {
|
||
|
if (_Properties == null)
|
||
|
_Properties = new SettingsPropertyCollection();
|
||
|
if (_Properties[property.Name] == null)
|
||
|
_Properties.Add(property);
|
||
|
GetPropertyValuesCore();
|
||
|
return _PropertyValues[property.Name];
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
private string GetServiceUri()
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(_ServiceUri))
|
||
|
throw new ArgumentException(AtlasWeb.ServiceUriNotFound);
|
||
|
return _ServiceUri;
|
||
|
}
|
||
|
|
||
|
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Reviewed and approved by feature crew")]
|
||
|
public static string ServiceUri
|
||
|
{
|
||
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Reviewed and approved by feature crew")]
|
||
|
get
|
||
|
{
|
||
|
return _ServiceUri;
|
||
|
}
|
||
|
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Reviewed and approved by feature crew")]
|
||
|
set {
|
||
|
_ServiceUri = value;
|
||
|
if (string.IsNullOrEmpty(_ServiceUri)) {
|
||
|
_UsingWFCService = false;
|
||
|
} else {
|
||
|
_UsingWFCService = _ServiceUri.EndsWith(".svc", StringComparison.OrdinalIgnoreCase);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public event EventHandler<SettingsSavedEventArgs> SettingsSaved;
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
internal static Type[] GetKnownTypes(ICustomAttributeProvider knownTypeAttributeTarget)
|
||
|
{
|
||
|
if (_KnownTypesArray == null)
|
||
|
InitKnownTypes();
|
||
|
return _KnownTypesArray;
|
||
|
}
|
||
|
static private void InitKnownTypes()
|
||
|
{
|
||
|
_KnownTypesHashtable = new Hashtable();
|
||
|
_KnownTypesArray = new Type[]{ typeof(bool),
|
||
|
typeof(string),
|
||
|
typeof(ArrayList),
|
||
|
typeof(ProfilePropertyMetadata),
|
||
|
typeof(IDictionary<string, object>),
|
||
|
typeof(Collection<string>)
|
||
|
};
|
||
|
|
||
|
for(int iter=0; iter<_KnownTypesArray.Length; iter++)
|
||
|
_KnownTypesHashtable.Add(_KnownTypesArray[iter], string.Empty);
|
||
|
}
|
||
|
|
||
|
static private void StoreKnownTypes(SettingsPropertyValueCollection propertyValueCollection)
|
||
|
{
|
||
|
if (_KnownTypesHashtable == null)
|
||
|
InitKnownTypes();
|
||
|
|
||
|
ArrayList al = null;
|
||
|
foreach(SettingsPropertyValue p in propertyValueCollection) {
|
||
|
if (!_KnownTypesHashtable.Contains(p.Property.PropertyType)) {
|
||
|
_KnownTypesHashtable.Add(p.Property.PropertyType, string.Empty);
|
||
|
if (al == null)
|
||
|
al = new ArrayList();
|
||
|
al.Add(p.Property.PropertyType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (al != null) {
|
||
|
Type [] temp = new Type[_KnownTypesArray.Length + al.Count];
|
||
|
_KnownTypesArray.CopyTo(temp, 0);
|
||
|
al.CopyTo(temp, _KnownTypesArray.Length);
|
||
|
_KnownTypesArray = temp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static private void StoreKnownTypes(SettingsPropertyCollection propertyCollection)
|
||
|
{
|
||
|
if (_KnownTypesHashtable == null)
|
||
|
InitKnownTypes();
|
||
|
|
||
|
ArrayList al = null;
|
||
|
foreach(SettingsProperty p in propertyCollection) {
|
||
|
if (!_KnownTypesHashtable.Contains(p.PropertyType)) {
|
||
|
_KnownTypesHashtable.Add(p.PropertyType, string.Empty);
|
||
|
if (al == null)
|
||
|
al = new ArrayList();
|
||
|
al.Add(p.PropertyType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (al != null) {
|
||
|
Type [] temp = new Type[_KnownTypesArray.Length + al.Count];
|
||
|
_KnownTypesArray.CopyTo(temp, 0);
|
||
|
al.CopyTo(temp, _KnownTypesArray.Length);
|
||
|
_KnownTypesArray = temp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
private void GetPropertyValuesFromWeb()
|
||
|
{
|
||
|
GetPropertyValuesFromWebCore(_HonorCookieExpiry);
|
||
|
|
||
|
// Any failures?
|
||
|
bool anyFailures = (_PropertyValues.Count < _Properties.Count);
|
||
|
|
||
|
if (!_HonorCookieExpiry && anyFailures) {
|
||
|
// if there were failures, try re-validating the ClientFormsIdentity
|
||
|
// and try again
|
||
|
|
||
|
ClientFormsIdentity id = Thread.CurrentPrincipal.Identity as ClientFormsIdentity;
|
||
|
|
||
|
if (id != null) {
|
||
|
id.RevalidateUser();
|
||
|
GetPropertyValuesFromWebCore(true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
[SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")]
|
||
|
private void GetPropertyValuesFromWebCore(bool bubbleExceptionFromSvc) {
|
||
|
string [] propertyNames = new string[_Properties.Count];
|
||
|
int iter = 0;
|
||
|
CookieContainer cookies = null;
|
||
|
IIdentity id = Thread.CurrentPrincipal.Identity;
|
||
|
|
||
|
foreach (SettingsProperty setting in _Properties) {
|
||
|
propertyNames[iter++] = setting.Name;
|
||
|
}
|
||
|
|
||
|
if (id is ClientFormsIdentity)
|
||
|
cookies = ((ClientFormsIdentity)id).AuthenticationCookies;
|
||
|
|
||
|
if (_UsingWFCService) {
|
||
|
throw new NotImplementedException();
|
||
|
|
||
|
// CustomBinding binding = ProxyHelper.GetBinding();
|
||
|
// ChannelFactory<ProfileService> channelFactory = new ChannelFactory<ProfileService>(binding, new EndpointAddress(GetServiceUri()));
|
||
|
// ProfileService clientService = channelFactory.CreateChannel();
|
||
|
// Dictionary<string, object> propertyValues = null;
|
||
|
|
||
|
|
||
|
// using (new OperationContextScope((IContextChannel)clientService)) {
|
||
|
// ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), id.Name, GetConnectionString(), _ConnectionStringProvider);
|
||
|
// propertyValues = clientService.GetPropertiesForCurrentUser(propertyNames, id.IsAuthenticated && (id is ClientFormsIdentity));
|
||
|
// ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), id.Name, GetConnectionString(), _ConnectionStringProvider);
|
||
|
// }
|
||
|
|
||
|
// for(iter = 0; iter<propertyNames.Length; iter++) {
|
||
|
// string name = propertyNames[iter];
|
||
|
// if (!propertyValues.ContainsKey(name))
|
||
|
// continue;
|
||
|
// SettingsProperty setting = _Properties[name];
|
||
|
// if (setting == null)
|
||
|
// continue; // Bad -- why wasn't it found?
|
||
|
// bool mustAdd = false;
|
||
|
// SettingsPropertyValue value = _PropertyValues[setting.Name];
|
||
|
// if (value == null) {
|
||
|
// value = new SettingsPropertyValue(setting);
|
||
|
// mustAdd = true;
|
||
|
// }
|
||
|
|
||
|
// //if ((value.SerializedValue is string) && ((string)value.SerializedValue == "(null)")) {
|
||
|
// value.PropertyValue = propertyValues[name];
|
||
|
// value.Deserialized = true;
|
||
|
// // } else if (setting.SerializeAs == SettingsSerializeAs.Binary)
|
||
|
// // value.SerializedValue = Convert.FromBase64String(propertyValues[iter]);
|
||
|
// // else
|
||
|
// // value.SerializedValue = propertyValues[iter];
|
||
|
// // value.Deserialized = false;
|
||
|
// value.IsDirty = false;
|
||
|
// if (mustAdd)
|
||
|
// _PropertyValues.Add(value);
|
||
|
// }
|
||
|
} else {
|
||
|
|
||
|
string [] paramNames = new string [] {"properties", "authenticatedUserOnly" };
|
||
|
object [] paramValues = new object [] {propertyNames, id.IsAuthenticated && (id is ClientFormsIdentity) };
|
||
|
object obj = null;
|
||
|
try {
|
||
|
obj = ProxyHelper.CreateWebRequestAndGetResponse(
|
||
|
GetServiceUri() + "/GetPropertiesForCurrentUser",
|
||
|
ref cookies,
|
||
|
id.Name,
|
||
|
_ConnectionString,
|
||
|
_ConnectionStringProvider,
|
||
|
paramNames,
|
||
|
paramValues,
|
||
|
typeof(Dictionary<string, object>));
|
||
|
|
||
|
} catch {
|
||
|
if (bubbleExceptionFromSvc)
|
||
|
throw;
|
||
|
}
|
||
|
|
||
|
if (obj != null) {
|
||
|
Dictionary<string, object> ret = (Dictionary<string, object>) obj;
|
||
|
|
||
|
foreach(KeyValuePair<string,object> de in ret) {
|
||
|
SettingsProperty setting = _Properties[(string) de.Key];
|
||
|
if (setting == null)
|
||
|
continue; // Bad -- why wasn't it found?
|
||
|
bool mustAdd = false;
|
||
|
SettingsPropertyValue value = _PropertyValues[setting.Name];
|
||
|
if (value == null) {
|
||
|
value = new SettingsPropertyValue(setting);
|
||
|
mustAdd = true;
|
||
|
}
|
||
|
|
||
|
if (de.Value != null && !setting.PropertyType.IsAssignableFrom(de.Value.GetType()))
|
||
|
{
|
||
|
object convertedValue = null;
|
||
|
if (!ObjectConverter.TryConvertObjectToType(de.Value,
|
||
|
setting.PropertyType,
|
||
|
new JavaScriptSerializer(),
|
||
|
out convertedValue))
|
||
|
{
|
||
|
// Failure to convert!
|
||
|
continue;
|
||
|
}
|
||
|
value.PropertyValue = convertedValue;
|
||
|
} else {
|
||
|
value.PropertyValue = de.Value;
|
||
|
|
||
|
}
|
||
|
|
||
|
value.Deserialized = true;
|
||
|
value.IsDirty = false;
|
||
|
if (mustAdd)
|
||
|
_PropertyValues.Add(value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
private Collection<string> SetPropertyValuesWeb(SettingsPropertyValueCollection values, bool cacheIsMoreFresh)
|
||
|
{
|
||
|
bool anyFailures = false;
|
||
|
Collection<string> errorList = null;
|
||
|
ClientFormsIdentity id = Thread.CurrentPrincipal.Identity as ClientFormsIdentity;
|
||
|
try {
|
||
|
errorList = SetPropertyValuesWebCore(values, cacheIsMoreFresh);
|
||
|
anyFailures = (errorList != null && errorList.Count > 0);
|
||
|
}
|
||
|
catch (WebException) {
|
||
|
if (id == null || _HonorCookieExpiry) {
|
||
|
throw;
|
||
|
}
|
||
|
anyFailures = true;
|
||
|
}
|
||
|
|
||
|
if (!_HonorCookieExpiry && anyFailures) {
|
||
|
// if there were failures, try re-validating the ClientFormsIdentity
|
||
|
// and try again
|
||
|
if (id != null) {
|
||
|
id.RevalidateUser();
|
||
|
errorList = SetPropertyValuesWebCore(values, cacheIsMoreFresh);
|
||
|
}
|
||
|
}
|
||
|
return errorList;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
[SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification="Reviewed and approved by feature crew")]
|
||
|
private Collection<string> SetPropertyValuesWebCore(SettingsPropertyValueCollection values, bool cacheIsMoreFresh)
|
||
|
{
|
||
|
Dictionary<string, object> propertyValues = new Dictionary<string, object>();
|
||
|
Collection<string> errorList = null;
|
||
|
foreach(SettingsPropertyValue value in values) {
|
||
|
if (cacheIsMoreFresh || value.IsDirty) {
|
||
|
propertyValues.Add(value.Property.Name, value.PropertyValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CookieContainer cookies = null;
|
||
|
IIdentity id = Thread.CurrentPrincipal.Identity;
|
||
|
|
||
|
if (id is ClientFormsIdentity)
|
||
|
cookies = ((ClientFormsIdentity)id).AuthenticationCookies;
|
||
|
|
||
|
|
||
|
if (_UsingWFCService) {
|
||
|
throw new NotImplementedException();
|
||
|
|
||
|
// CustomBinding binding = ProxyHelper.GetBinding();
|
||
|
// ChannelFactory<ProfileService> channelFactory = new ChannelFactory<ProfileService>(binding, new EndpointAddress(GetServiceUri()));
|
||
|
// ProfileService clientService = channelFactory.CreateChannel();
|
||
|
// using (new OperationContextScope((IContextChannel)clientService)) {
|
||
|
// ProxyHelper.AddCookiesToWCF(cookies, GetServiceUri(), id.Name, GetConnectionString(), _ConnectionStringProvider);
|
||
|
// errorList = clientService.SetPropertiesForCurrentUser(propertyValues, id.IsAuthenticated && (id is ClientFormsIdentity));
|
||
|
// ProxyHelper.GetCookiesFromWCF(cookies, GetServiceUri(), id.Name, GetConnectionString(), _ConnectionStringProvider);
|
||
|
// }
|
||
|
} else {
|
||
|
// Collection<string> SetPropertiesForCurrentUser(IDictionary<string, object> values, bool authenticatedUserOnly)
|
||
|
string [] paramNames = new string [] {"values", "authenticatedUserOnly" };
|
||
|
object [] paramValues = new object [] {propertyValues, id.IsAuthenticated && (id is ClientFormsIdentity) };
|
||
|
|
||
|
object o = ProxyHelper.CreateWebRequestAndGetResponse(GetServiceUri() + "/SetPropertiesForCurrentUser",
|
||
|
ref cookies,
|
||
|
id.Name,
|
||
|
_ConnectionString,
|
||
|
_ConnectionStringProvider,
|
||
|
paramNames,
|
||
|
paramValues,
|
||
|
typeof(Collection<string>));
|
||
|
errorList = (Collection<string>) o;
|
||
|
}
|
||
|
SetIsCacheMoreFresh(false);
|
||
|
return errorList;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
private void GetPropertyValuesFromSQL()
|
||
|
{
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore)
|
||
|
{
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(Thread.CurrentPrincipal.Identity.Name, _UsingIsolatedStore);
|
||
|
if (cd.SettingsNames == null || cd.SettingsValues == null)
|
||
|
return;
|
||
|
int len = cd.SettingsNames.Length;
|
||
|
if (cd.SettingsNames.Length != cd.SettingsStoredAs.Length || cd.SettingsValues.Length != cd.SettingsStoredAs.Length)
|
||
|
{
|
||
|
return; // Bad!
|
||
|
}
|
||
|
for(int iter=0; iter<len; iter++) {
|
||
|
AddProperty(cd.SettingsNames[iter], cd.SettingsStoredAs[iter], cd.SettingsValues[iter]);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
using (DbConnection conn = SqlHelper.GetConnection(Thread.CurrentPrincipal.Identity.Name,
|
||
|
GetConnectionString(), _ConnectionStringProvider))
|
||
|
{
|
||
|
DbTransaction trans = null;
|
||
|
try {
|
||
|
trans = conn.BeginTransaction();
|
||
|
DbCommand cmd = conn.CreateCommand();
|
||
|
cmd.CommandText = "SELECT PropertyName, PropertyStoredAs, PropertyValue FROM Settings";
|
||
|
cmd.Transaction = trans;
|
||
|
using(DbDataReader reader = cmd.ExecuteReader()) {
|
||
|
while(reader.Read()) {
|
||
|
string name = reader.GetString(0);
|
||
|
string storedAs = reader.GetString(1);
|
||
|
string propVal = (reader.IsDBNull(2) ? null : reader.GetString(2));
|
||
|
|
||
|
AddProperty(name, storedAs, propVal);
|
||
|
}
|
||
|
}
|
||
|
} catch {
|
||
|
if (trans != null) {
|
||
|
trans.Rollback();
|
||
|
trans = null;
|
||
|
}
|
||
|
throw;
|
||
|
} finally {
|
||
|
if (trans != null)
|
||
|
trans.Commit();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void AddProperty(string name, string storedAs, string propVal)
|
||
|
{
|
||
|
if (storedAs != "S" && storedAs != "B" && storedAs != "N")
|
||
|
return;
|
||
|
|
||
|
SettingsProperty prop = _Properties[name];
|
||
|
if (prop == null)
|
||
|
return;
|
||
|
SettingsPropertyValue value = _PropertyValues[name];
|
||
|
bool mustAdd = false;
|
||
|
if (value == null) {
|
||
|
value = new SettingsPropertyValue(prop);
|
||
|
mustAdd = true;
|
||
|
}
|
||
|
|
||
|
switch(storedAs) {
|
||
|
case "S":
|
||
|
value.SerializedValue = propVal;
|
||
|
break;
|
||
|
case "B":
|
||
|
value.SerializedValue = Convert.FromBase64String(propVal);
|
||
|
break;
|
||
|
case "N":
|
||
|
value.SerializedValue = null;
|
||
|
break;
|
||
|
}
|
||
|
value.Deserialized = false;
|
||
|
value.IsDirty = false;
|
||
|
if (mustAdd)
|
||
|
_PropertyValues.Add(value);
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
private void SetPropertyValuesSQL(SettingsPropertyValueCollection values, bool updateSaveTime)
|
||
|
{
|
||
|
string username = Thread.CurrentPrincipal.Identity.Name;
|
||
|
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore)
|
||
|
{
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(username, _UsingIsolatedStore);
|
||
|
cd.SettingsNames = new string[values.Count];
|
||
|
cd.SettingsStoredAs = new string[values.Count];
|
||
|
cd.SettingsValues = new string[values.Count];
|
||
|
|
||
|
int iter=0;
|
||
|
|
||
|
foreach(SettingsPropertyValue value in values) {
|
||
|
|
||
|
cd.SettingsNames[iter] = value.Property.Name;
|
||
|
|
||
|
object val = value.SerializedValue;
|
||
|
if (val == null) {
|
||
|
cd.SettingsStoredAs[iter] = "N";
|
||
|
} else if (val is string) {
|
||
|
cd.SettingsStoredAs[iter] = "S";
|
||
|
cd.SettingsValues[iter] = (string) val;
|
||
|
} else {
|
||
|
cd.SettingsStoredAs[iter] = "B";
|
||
|
cd.SettingsValues[iter] = Convert.ToBase64String((byte[])val);
|
||
|
}
|
||
|
|
||
|
iter++;
|
||
|
}
|
||
|
if (updateSaveTime)
|
||
|
cd.SettingsCacheIsMoreFresh = true;
|
||
|
cd.Save();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
using (DbConnection conn = SqlHelper.GetConnection(username, GetConnectionString(), _ConnectionStringProvider)) {
|
||
|
DbTransaction trans = null;
|
||
|
try {
|
||
|
trans = conn.BeginTransaction();
|
||
|
foreach(SettingsPropertyValue value in values) {
|
||
|
DbCommand cmd = conn.CreateCommand();
|
||
|
cmd.Transaction = trans;
|
||
|
cmd.CommandText = "DELETE FROM Settings WHERE PropertyName = @PropName";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", value.Property.Name);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
|
||
|
cmd = conn.CreateCommand();
|
||
|
cmd.Transaction = trans;
|
||
|
object val = value.SerializedValue;
|
||
|
if (val == null) {
|
||
|
cmd.CommandText = "INSERT INTO Settings (PropertyName, PropertyStoredAs, PropertyValue) VALUES (@PropName, 'N', '')";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", value.Property.Name);
|
||
|
} else if (val is string) {
|
||
|
cmd.CommandText = "INSERT INTO Settings (PropertyName, PropertyStoredAs, PropertyValue) VALUES (@PropName, 'S', @PropVal)";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", value.Property.Name);
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropVal", (string) val);
|
||
|
} else {
|
||
|
cmd.CommandText = "INSERT INTO Settings (PropertyName, PropertyStoredAs, PropertyValue) VALUES (@PropName, 'B', @PropVal)";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", value.Property.Name);
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropVal", Convert.ToBase64String((byte[])val));
|
||
|
}
|
||
|
cmd.ExecuteNonQuery();
|
||
|
}
|
||
|
} catch {
|
||
|
if (trans != null) {
|
||
|
trans.Rollback();
|
||
|
trans = null;
|
||
|
}
|
||
|
throw;
|
||
|
} finally {
|
||
|
if (trans != null)
|
||
|
trans.Commit();
|
||
|
}
|
||
|
}
|
||
|
if (updateSaveTime)
|
||
|
SetIsCacheMoreFresh(true);
|
||
|
}
|
||
|
|
||
|
private bool GetNeedToReset()
|
||
|
{
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore) {
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(Thread.CurrentPrincipal.Identity.Name, _UsingIsolatedStore);
|
||
|
return cd.SettingsNeedReset;
|
||
|
} else {
|
||
|
string temp = GetTagValue("NeeedToDoReset");
|
||
|
return (temp != null && temp == "1");
|
||
|
}
|
||
|
}
|
||
|
private void SetNeedToReset(bool fSet)
|
||
|
{
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore) {
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(Thread.CurrentPrincipal.Identity.Name, _UsingIsolatedStore);
|
||
|
cd.SettingsNeedReset = fSet;
|
||
|
cd.Save();
|
||
|
} else {
|
||
|
SetTagValue("NeeedToDoReset", fSet ? "1" : "0");
|
||
|
}
|
||
|
}
|
||
|
private bool GetIsCacheMoreFresh()
|
||
|
{
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore) {
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(Thread.CurrentPrincipal.Identity.Name, _UsingIsolatedStore);
|
||
|
return cd.SettingsCacheIsMoreFresh;
|
||
|
} else {
|
||
|
string temp = GetTagValue("IsCacheMoreFresh");
|
||
|
return (temp != null && temp == "1");
|
||
|
}
|
||
|
}
|
||
|
private void SetIsCacheMoreFresh(bool fSet)
|
||
|
{
|
||
|
if (_UsingFileSystemStore || _UsingIsolatedStore) {
|
||
|
ClientData cd = ClientDataManager.GetUserClientData(Thread.CurrentPrincipal.Identity.Name, _UsingIsolatedStore);
|
||
|
cd.SettingsCacheIsMoreFresh = fSet;
|
||
|
cd.Save();
|
||
|
} else {
|
||
|
SetTagValue("IsCacheMoreFresh", fSet ? "1" : "0");
|
||
|
}
|
||
|
}
|
||
|
private string GetTagValue(string tagName)
|
||
|
{
|
||
|
string username = Thread.CurrentPrincipal.Identity.Name;
|
||
|
using (DbConnection conn = SqlHelper.GetConnection(username, GetConnectionString(), _ConnectionStringProvider))
|
||
|
{
|
||
|
DbCommand cmd = conn.CreateCommand();
|
||
|
cmd.CommandText = @"SELECT PropertyValue FROM Settings WHERE PropertyName = @PropName AND PropertyStoredAs='I'";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", tagName);
|
||
|
return cmd.ExecuteScalar() as string;
|
||
|
}
|
||
|
}
|
||
|
private void SetTagValue(string tagName, string tagValue)
|
||
|
{
|
||
|
string username = Thread.CurrentPrincipal.Identity.Name;
|
||
|
using (DbConnection conn = SqlHelper.GetConnection(username, GetConnectionString(), _ConnectionStringProvider)) {
|
||
|
DbCommand cmd = conn.CreateCommand();
|
||
|
cmd.CommandText = @"DELETE FROM Settings WHERE PropertyName = @PropName AND PropertyStoredAs='I'";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", tagName);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
if (tagValue != null) {
|
||
|
cmd = conn.CreateCommand();
|
||
|
cmd.CommandText = @"INSERT INTO Settings (PropertyName, PropertyStoredAs, PropertyValue) VALUES (@PropName, 'I', @PropValue)";
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropName", tagName);
|
||
|
SqlHelper.AddParameter(conn, cmd, "@PropValue", tagValue);
|
||
|
cmd.ExecuteNonQuery();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RegisterForValidateUserEvent()
|
||
|
{
|
||
|
foreach(MembershipProvider provider in Membership.Providers) {
|
||
|
EventInfo ei = provider.GetType().GetEvent("UserValidated");
|
||
|
if (ei == null)
|
||
|
continue;
|
||
|
|
||
|
MethodInfo addMethod = ei.GetAddMethod();
|
||
|
if (addMethod == null)
|
||
|
continue;
|
||
|
|
||
|
ParameterInfo[] addMethodParams = addMethod.GetParameters();
|
||
|
Delegate handlerDelegate = Delegate.CreateDelegate(addMethodParams[0].ParameterType, this, "OnUserValidated");
|
||
|
addMethod.Invoke(provider, new Object[1]{handlerDelegate});
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification="Called via Reflection")]
|
||
|
private void OnUserValidated(object src, UserValidatedEventArgs e)
|
||
|
{
|
||
|
_NeedToDoReset = GetNeedToReset();
|
||
|
if (_Properties != null && _Properties.Count > 0 && string.Compare(e.UserName, _UserName, StringComparison.OrdinalIgnoreCase) != 0) {
|
||
|
try {
|
||
|
if (_SettingsBaseClass != null)
|
||
|
_SettingsBaseClass.Reload();
|
||
|
// _PropertyValues = new SettingsPropertyValueCollection();
|
||
|
// GetPropertyValuesCore(); // refresh the collection
|
||
|
} catch {
|
||
|
// it's possible that the (new) user doesn't have the same props
|
||
|
// if (_PropertyValues.Count < _Properties.Count)
|
||
|
// SetRemainingValuesToDefault();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void SetRemainingValuesToDefault()
|
||
|
{
|
||
|
foreach (SettingsProperty prop in _Properties) {
|
||
|
SettingsPropertyValue value = _PropertyValues[prop.Name];
|
||
|
if (value == null) {
|
||
|
value = new SettingsPropertyValue(prop);
|
||
|
value.SerializedValue = prop.DefaultValue;
|
||
|
value.Deserialized = false;
|
||
|
object o = value.PropertyValue;
|
||
|
value.PropertyValue = o;
|
||
|
_PropertyValues.Add(value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
private string GetConnectionString()
|
||
|
{
|
||
|
if (_ConnectionString == null)
|
||
|
_ConnectionString = SqlHelper.GetDefaultConnectionString();
|
||
|
return _ConnectionString;
|
||
|
}
|
||
|
}
|
||
|
}
|