Merge pull request #2250 from esdrubal/master
[mono.git] / mcs / class / referencesource / System.Web / Profile / ProfileManager.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="ProfileManager.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 /*
7  * ProfileManager
8  *
9  * Copyright (c) 2002 Microsoft Corporation
10  */
11
12 namespace System.Web.Profile
13 {
14     using  System.Security.Principal;
15     using  System.Security.Permissions;
16     using  System.Collections;
17     using  System.Collections.Specialized;
18     using  System.Web.Configuration;
19     using  System.Web.Util;
20     using  System.Web.Security;
21     using  System.Web.Compilation;
22     using  System.Configuration;
23     using  System.Configuration.Provider;
24     using  System.Reflection;
25     using  System.CodeDom;
26     using System.Web.Hosting;
27
28     public static class ProfileManager
29     {
30         private static ProfilePropertySettingsCollection s_dynamicProperties = new ProfilePropertySettingsCollection();
31         internal static ProfilePropertySettingsCollection DynamicProfileProperties {
32             get {
33                 return s_dynamicProperties;
34             }
35         }
36
37         public static void AddDynamicProfileProperty(ProfilePropertySettings property) {
38             BuildManager.ThrowIfPreAppStartNotRunning();
39             s_dynamicProperties.Add(property);
40         }
41
42         //////////////////////////////////////////////////////////////////////
43         //////////////////////////////////////////////////////////////////////
44         //////////////////////////////////////////////////////////////////////
45         public static bool DeleteProfile(string username)
46         {
47             SecUtility.CheckParameter( ref username, true, true, true, 0, "username" );
48             return (Provider.DeleteProfiles(new string [] {username}) != 0);
49         }
50
51         //////////////////////////////////////////////////////////////////////
52         //////////////////////////////////////////////////////////////////////
53         //////////////////////////////////////////////////////////////////////
54         public static int DeleteProfiles(ProfileInfoCollection profiles)
55         {
56             if( profiles == null )
57             {
58                 throw new ArgumentNullException( "profiles" );
59             }
60
61             if ( profiles.Count < 1 )
62             {
63                 throw new ArgumentException(
64                     SR.GetString(SR.Parameter_collection_empty,
65                         "profiles" ),
66                     "profiles" );
67             }
68
69             foreach (ProfileInfo pi in profiles) {
70                 string username = pi.UserName;
71                 SecUtility.CheckParameter(ref username, true, true, true, 0, "UserName");
72             }
73             return Provider.DeleteProfiles(profiles);
74         }
75
76         //////////////////////////////////////////////////////////////////////
77         //////////////////////////////////////////////////////////////////////
78         //////////////////////////////////////////////////////////////////////
79         public static int DeleteProfiles(string[] usernames)
80         {
81             SecUtility.CheckArrayParameter( ref usernames,
82                                             true,
83                                             true,
84                                             true,
85                                             0,
86                                             "usernames");
87
88
89             return Provider.DeleteProfiles(usernames);
90         }
91
92         //////////////////////////////////////////////////////////////////////
93         //////////////////////////////////////////////////////////////////////
94         //////////////////////////////////////////////////////////////////////
95         public static int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
96         {
97             return Provider.DeleteInactiveProfiles(authenticationOption, userInactiveSinceDate);
98         }
99
100         //////////////////////////////////////////////////////////////////////
101         //////////////////////////////////////////////////////////////////////
102         //////////////////////////////////////////////////////////////////////
103         public static int GetNumberOfProfiles(ProfileAuthenticationOption authenticationOption)
104         {
105             return Provider.GetNumberOfInactiveProfiles(authenticationOption, DateTime.Now.AddDays(1)); // 
106         }
107
108         //////////////////////////////////////////////////////////////////////
109         //////////////////////////////////////////////////////////////////////
110         //////////////////////////////////////////////////////////////////////
111         public static int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
112         {
113             return Provider.GetNumberOfInactiveProfiles(authenticationOption, userInactiveSinceDate);
114         }
115
116
117         //////////////////////////////////////////////////////////////////////
118         //////////////////////////////////////////////////////////////////////
119         //////////////////////////////////////////////////////////////////////
120         public static ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption)
121         {
122             int totalRecords;
123             return Provider.GetAllProfiles(authenticationOption, 0, Int32.MaxValue, out totalRecords);
124         }
125
126
127         //////////////////////////////////////////////////////////////////////
128         //////////////////////////////////////////////////////////////////////
129         //////////////////////////////////////////////////////////////////////
130         public static ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption,
131                                                            int pageIndex,
132                                                            int pageSize,
133                                                            out int totalRecords)
134         {
135             return Provider.GetAllProfiles(authenticationOption, pageIndex, pageSize, out totalRecords);
136         }
137
138
139         //////////////////////////////////////////////////////////////////////
140         //////////////////////////////////////////////////////////////////////
141         //////////////////////////////////////////////////////////////////////
142         public static ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption,
143                                                                    DateTime userInactiveSinceDate)
144         {
145             int totalRecords;
146             return Provider.GetAllInactiveProfiles(authenticationOption, userInactiveSinceDate, 0, Int32.MaxValue, out totalRecords);
147         }
148
149
150         //////////////////////////////////////////////////////////////////////
151         //////////////////////////////////////////////////////////////////////
152         //////////////////////////////////////////////////////////////////////
153         public static ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption,
154                                                                    DateTime userInactiveSinceDate,
155                                                                    int pageIndex,
156                                                                    int pageSize,
157                                                                    out int totalRecords)
158         {
159             return Provider.GetAllInactiveProfiles(authenticationOption, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
160         }
161
162         //////////////////////////////////////////////////////////////////////
163         //////////////////////////////////////////////////////////////////////
164         //////////////////////////////////////////////////////////////////////
165         public static ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption,
166                                                                    string usernameToMatch)
167         {
168             SecUtility.CheckParameter( ref usernameToMatch,
169                                        true,
170                                        true,
171                                        false,
172                                        0,
173                                        "usernameToMatch" );
174
175             int totalRecords;
176             return Provider.FindProfilesByUserName(authenticationOption, usernameToMatch, 0, Int32.MaxValue, out totalRecords);
177         }
178
179         //////////////////////////////////////////////////////////////////////
180         //////////////////////////////////////////////////////////////////////
181         //////////////////////////////////////////////////////////////////////
182         public static ProfileInfoCollection FindProfilesByUserName (ProfileAuthenticationOption authenticationOption,
183                                                                     string usernameToMatch,
184                                                                     int pageIndex,
185                                                                     int pageSize,
186                                                                     out int totalRecords)
187         {
188             if ( pageIndex < 0 )
189             {
190                 throw new ArgumentException(SR.GetString(SR.PageIndex_bad), "pageIndex");
191             }
192
193             if ( pageSize < 1 )
194             {
195                 throw new ArgumentException(SR.GetString(SR.PageSize_bad), "pageSize");
196             }
197
198             SecUtility.CheckParameter( ref usernameToMatch,
199                                        true,
200                                        true,
201                                        false,
202                                        0,
203                                        "usernameToMatch" );
204
205             return Provider.FindProfilesByUserName(authenticationOption, usernameToMatch, pageIndex, pageSize, out totalRecords);
206         }
207
208
209         //////////////////////////////////////////////////////////////////////
210         //////////////////////////////////////////////////////////////////////
211         //////////////////////////////////////////////////////////////////////
212         public static ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption,
213                                                                            string usernameToMatch,
214                                                                            DateTime userInactiveSinceDate)
215         {
216             SecUtility.CheckParameter( ref usernameToMatch,
217                                        true,
218                                        true,
219                                        false,
220                                        0,
221                                        "usernameToMatch" );
222
223             int totalRecords;
224             return Provider.FindInactiveProfilesByUserName(authenticationOption, usernameToMatch, userInactiveSinceDate, 0, Int32.MaxValue, out totalRecords);
225         }
226
227         //////////////////////////////////////////////////////////////////////
228         //////////////////////////////////////////////////////////////////////
229         //////////////////////////////////////////////////////////////////////
230         public static ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption,
231                                                                            string usernameToMatch,
232                                                                            DateTime userInactiveSinceDate,
233                                                                            int pageIndex,
234                                                                            int pageSize,
235                                                                            out int totalRecords)
236         {
237             if ( pageIndex < 0 )
238             {
239                 throw new ArgumentException(SR.GetString(SR.PageIndex_bad), "pageIndex");
240             }
241
242             if ( pageSize < 1 )
243             {
244                 throw new ArgumentException(SR.GetString(SR.PageSize_bad), "pageSize");
245             }
246
247             SecUtility.CheckParameter( ref usernameToMatch,
248                                        true,
249                                        true,
250                                        false,
251                                        0,
252                                        "usernameToMatch" );
253
254             return Provider.FindInactiveProfilesByUserName(authenticationOption, usernameToMatch, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
255         }
256
257
258
259         //////////////////////////////////////////////////////////////////////
260         //////////////////////////////////////////////////////////////////////
261         //////////////////////////////////////////////////////////////////////
262         // Properties
263
264         //////////////////////////////////////////////////////////////////////
265         //////////////////////////////////////////////////////////////////////
266         public static bool Enabled {
267             get {
268                 // 
269                 if (!s_Initialized && !s_InitializedEnabled) {
270                     InitializeEnabled(false);
271                 }
272
273                 return s_Enabled;
274             }
275         }
276
277         //////////////////////////////////////////////////////////////////////
278         //////////////////////////////////////////////////////////////////////
279         public static string ApplicationName {
280             get {
281                 return Provider.ApplicationName;
282             }
283             set {
284                 Provider.ApplicationName = value;
285             }
286         }
287
288         //////////////////////////////////////////////////////////////////////
289         //////////////////////////////////////////////////////////////////////
290         public static bool AutomaticSaveEnabled {
291             get {
292                 HttpRuntime.CheckAspNetHostingPermission(AspNetHostingPermissionLevel.Low, SR.Feature_not_supported_at_this_level);
293                 // WOS #1544130: Don't initialize providers when getting this property, because it is called in ProfileModule.Init
294                 InitializeEnabled(false);
295                 return s_AutomaticSaveEnabled;
296             }
297         }
298         //////////////////////////////////////////////////////////////////////
299         //////////////////////////////////////////////////////////////////////
300         public static ProfileProvider Provider {
301             get {
302                 HttpRuntime.CheckAspNetHostingPermission(AspNetHostingPermissionLevel.Low, SR.Feature_not_supported_at_this_level);
303                 Initialize(true);
304                 if (s_Provider == null) {
305                     throw new InvalidOperationException(SR.GetString(SR.Profile_default_provider_not_found));
306                 }
307                 return s_Provider;
308             }
309         }
310
311         //////////////////////////////////////////////////////////////////////
312         //////////////////////////////////////////////////////////////////////
313         public static ProfileProviderCollection Providers {
314             get {
315                 HttpRuntime.CheckAspNetHostingPermission(AspNetHostingPermissionLevel.Low, SR.Feature_not_supported_at_this_level);
316                 Initialize(true);
317                 return s_Providers;
318             }
319         }
320
321         //////////////////////////////////////////////////////////////////////
322         //////////////////////////////////////////////////////////////////////
323         //////////////////////////////////////////////////////////////////////
324         // Private stuff
325
326         private static void InitializeEnabled(bool initProviders) {
327             if (!s_Initialized || !s_InitializedProviders || !s_InitializeDefaultProvider) {
328                 lock (s_Lock) {
329                     if (!s_Initialized || !s_InitializedProviders || !s_InitializeDefaultProvider) {
330                         try {
331                             ProfileSection config = MTConfigUtil.GetProfileAppConfig();
332                             if (!s_InitializedEnabled) {
333                                 s_Enabled = config.Enabled && HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Low);
334                                 s_AutomaticSaveEnabled = s_Enabled && config.AutomaticSaveEnabled;
335                                 s_InitializedEnabled = true;
336                             }
337                             if (initProviders && s_Enabled && (!s_InitializedProviders || !s_InitializeDefaultProvider)) {
338                                 InitProviders(config);
339                             }
340                         }
341                         catch (Exception e) {
342                             s_InitException = e;
343                         }
344
345                         s_Initialized = true;
346                     }
347                 }
348             }
349         }
350
351         private static void Initialize(bool throwIfNotEnabled)
352         {
353             InitializeEnabled(true);
354             if (s_InitException != null)
355                 throw s_InitException;
356             if (throwIfNotEnabled && !s_Enabled)
357                 throw new ProviderException(SR.GetString(SR.Profile_not_enabled));
358         }
359
360         //////////////////////////////////////////////////////////////////////
361         //////////////////////////////////////////////////////////////////////
362         //////////////////////////////////////////////////////////////////////
363         static private void InitProviders(ProfileSection config)
364         {
365             if (!s_InitializedProviders) {
366                 s_Providers = new ProfileProviderCollection();
367                 if (config.Providers != null) {
368                     ProvidersHelper.InstantiateProviders(config.Providers, s_Providers, typeof(ProfileProvider));
369                 }
370                 s_InitializedProviders = true;
371             }
372
373             bool canInitializeDefaultProvider = (!HostingEnvironment.IsHosted || BuildManager.PreStartInitStage == PreStartInitStage.AfterPreStartInit);
374             if (!s_InitializeDefaultProvider && canInitializeDefaultProvider) {
375                 s_Providers.SetReadOnly();
376
377                 if (config.DefaultProvider == null)
378                     throw new ProviderException(SR.GetString(SR.Profile_default_provider_not_specified));
379
380                 s_Provider = (ProfileProvider)s_Providers[config.DefaultProvider];
381                 if (s_Provider == null)
382                     throw new ConfigurationErrorsException(SR.GetString(SR.Profile_default_provider_not_found), config.ElementInformation.Properties["providers"].Source, config.ElementInformation.Properties["providers"].LineNumber);
383
384                 s_InitializeDefaultProvider = true;
385             }
386         }
387
388         //////////////////////////////////////////////////////////////////////
389         //////////////////////////////////////////////////////////////////////
390         //////////////////////////////////////////////////////////////////////
391         private static ProfileProvider             s_Provider;
392         private static ProfileProviderCollection   s_Providers;
393         private static bool                        s_Enabled;
394         private static bool                        s_Initialized;
395         private static bool                        s_InitializedProviders;
396         private static bool                        s_InitializeDefaultProvider;
397         private static object                      s_Lock = new object();
398         private static Exception                   s_InitException;
399         private static bool                        s_InitializedEnabled;
400         private static bool                        s_AutomaticSaveEnabled;
401     }
402 }