-
Notifications
You must be signed in to change notification settings - Fork 756
/
Copy pathUserController.cs
2323 lines (2027 loc) · 110 KB
/
UserController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information
namespace DotNetNuke.Entities.Users
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using DotNetNuke.Abstractions.Portals;
using DotNetNuke.Collections.Internal;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Data;
using DotNetNuke.Entities.Controllers;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Profile;
using DotNetNuke.Entities.Users.Membership;
using DotNetNuke.Framework;
using DotNetNuke.Internal.SourceGenerators;
using DotNetNuke.Security;
using DotNetNuke.Security.Membership;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Security.Roles;
using DotNetNuke.Services.Cache;
using DotNetNuke.Services.FileSystem;
using DotNetNuke.Services.Localization;
using DotNetNuke.Services.Log.EventLog;
using DotNetNuke.Services.Mail;
using DotNetNuke.Services.Messaging.Data;
using MembershipProvider = DotNetNuke.Security.Membership.MembershipProvider;
/// <summary>The UserController class provides Business Layer methods for Users.</summary>
/// <remarks>
/// DotNetNuke user management is base on asp.net membership provider, but the default implementation of these providers
/// do not satisfy the broad set of use cases which we need to support in DotNetNuke. so The dependency of DotNetNuke on the
/// MemberRole (ASP.NET 2 Membership) components will be abstracted into a DotNetNuke Membership Provider, in order to allow
/// developers complete flexibility in implementing alternate Membership approaches.
/// <list type="bullet">
/// <item>This will allow for a number of enhancements to be added</item>
/// <item>Removal of dependence on the HttpContext</item>
/// <item>Support for Hashed Passwords</item>
/// <item>Support for Password Question and Answer</item>
/// <item>Enforce Password Complexity</item>
/// <item>Password Aging (Expiry)</item>
/// <item>Force Password Update</item>
/// <item>Enable/Disable Password Retrieval/Reset</item>
/// <item>CAPTCHA Support</item>
/// <item>Redirect after registration/login/logout</item>
/// </list>
/// </remarks>
/// <seealso cref="DotNetNuke.Security.Membership.MembershipProvider"/>
public partial class UserController : ServiceLocator<IUserController, UserController>, IUserController
{
/// <summary>Gets or sets the display name format with support for replacing some tokens.</summary>
/// <remarks>Valid tokens are: [USERID], [FIRSTNAME], [LASTNAME] and [USERNAME].</remarks>
public string DisplayFormat { get; set; }
/// <summary>Gets or sets the site (portal) id.</summary>
public int PortalId { get; set; }
/// <summary>Gets the number count for all duplicate e-mail adresses in the database.</summary>
/// <returns>An integer representing the amount of duplicate emails.</returns>
public static int GetDuplicateEmailCount()
{
return DataProvider.Instance().GetDuplicateEmailCount(PortalSettings.Current.PortalId);
}
/// <summary>add new userportal record (used for creating sites with existing user).</summary>
/// <param name="portalId">portalid.</param>
/// <param name="userId">userid.</param>
public static void AddUserPortal(int portalId, int userId)
{
Requires.NotNullOrEmpty("portalId", portalId.ToString());
Requires.NotNullOrEmpty("userId", userId.ToString());
MembershipProvider.Instance().AddUserPortal(portalId, userId);
}
/// <summary>ApproveUser removes the Unverified Users role from the user and adds the auto assigned roles.</summary>
/// <param name="user">The user to update.</param>
public static void ApproveUser(UserInfo user)
{
Requires.NotNull("user", user);
var settings = PortalController.Instance.GetCurrentPortalSettings();
var role = RoleController.Instance.GetRole(settings.PortalId, r => r.RoleName == "Unverified Users");
RoleController.DeleteUserRole(user, role, settings, false);
AutoAssignUsersToRoles(user, settings.PortalId);
}
/// <summary>User has agreed to terms and conditions. The time is recorded at the same time in SQL.</summary>
/// <param name="user">The user that agreed.</param>
public static void UserAgreedToTerms(UserInfo user)
{
Requires.NotNull("user", user);
MembershipProvider.Instance().UserAgreedToTerms(user);
}
/// <summary>When called all users in the portal will need to agree to terms and conditions again.</summary>
/// <param name="portalId">The portal for which to reset.</param>
public static void ResetTermsAgreement(int portalId)
{
Requires.NotNull("portalId", portalId);
MembershipProvider.Instance().ResetTermsAgreement(portalId);
}
/// <summary>
/// A user may request that their account be removed. This sets a flag on the user portal
/// so further processing may occur manually by the site admins.
/// </summary>
/// <param name="user">The user that desires to be removed.</param>
/// <param name="remove">A value indicating whether the user has requested removal.</param>
public static void UserRequestsRemoval(UserInfo user, bool remove)
{
Requires.NotNull("user", user);
MembershipProvider.Instance().UserRequestsRemoval(user, remove);
}
/// <summary>Attempts to change the users password.</summary>
/// <param name="user">The user to update.</param>
/// <param name="oldPassword">The old password.</param>
/// <param name="newPassword">The new password.</param>
/// <returns>A Boolean indicating success or failure.</returns>
public static bool ChangePassword(UserInfo user, string oldPassword, string newPassword)
{
bool passwordChanged;
// Although we would hope that the caller has already validated the password,
// Validate the new Password
if (ValidatePassword(newPassword))
{
passwordChanged = MembershipProvider.Instance().ChangePassword(user, oldPassword, newPassword);
if (passwordChanged)
{
// Update User
user.Membership.UpdatePassword = false;
UpdateUser(user.PortalID, user);
}
}
else
{
throw new InvalidPasswordException("Invalid Password");
}
return passwordChanged;
}
/// <summary>Validates the password reset token and if valid changes the password.</summary>
/// <param name="portalid">The site (portal) id on which the user exists.</param>
/// <param name="username">The username of the user to change the password for.</param>
/// <param name="newPassword">The new password.</param>
/// <param name="resetToken">The reset token, typically supplied through a password reset email.</param>
/// <returns>A Boolean indicating whether the password change succeeded.</returns>
public static bool ChangePasswordByToken(int portalid, string username, string newPassword, string resetToken)
{
bool passwordChanged;
Guid resetTokenGuid = new Guid(resetToken);
var user = GetUserByName(portalid, username);
// if user does not exist return false
if (user == null)
{
return false;
}
// check if the token supplied is the same as the users and is still valid
if (user.PasswordResetToken != resetTokenGuid || user.PasswordResetExpiration < DateTime.Now)
{
return false;
}
var m = new MembershipPasswordController();
if (m.IsPasswordInHistory(user.UserID, user.PortalID, newPassword))
{
return false;
}
// Although we would hope that the caller has already validated the password,
// Validate the new Password
if (ValidatePassword(newPassword))
{
passwordChanged = MembershipProvider.Instance().ResetAndChangePassword(user, newPassword);
// update reset token values to ensure token is 1-time use
user.PasswordResetExpiration = DateTime.MinValue;
user.PasswordResetToken = Guid.NewGuid();
if (passwordChanged)
{
// Update User
user.Membership.UpdatePassword = false;
UpdateUser(user.PortalID, user);
}
}
else
{
throw new Exception("Invalid Password");
}
return passwordChanged;
}
/// <summary>Validates the password reset token and changes the password if valid.</summary>
/// <param name="portalid">The site (portal) id where the user exists.</param>
/// <param name="username">The username of the user to change the password for.</param>
/// <param name="newPassword">The new password.</param>
/// <param name="answer">The password reset question/answer answer.</param>
/// <param name="resetToken">The password reset token, typically supplied through a password reset email.</param>
/// <param name="errorMessage">If the attempt fails, this parameter will contain the reason.</param>
/// <returns>A Boolean indicating success or failure.</returns>
public static bool ChangePasswordByToken(
int portalid,
string username,
string newPassword,
string answer,
string resetToken,
out string errorMessage)
{
bool passwordChanged;
errorMessage = Null.NullString;
Guid resetTokenGuid = new Guid(resetToken);
var user = GetUserByName(portalid, username);
// if user does not exist return false
if (user == null)
{
errorMessage = Localization.GetString("PasswordResetFailed_UserUndefined");
return false;
}
// check if the token supplied is the same as the users and is still valid
if (user.PasswordResetToken != resetTokenGuid || user.PasswordResetExpiration < DateTime.Now)
{
errorMessage = Localization.GetString("PasswordResetFailed_ResetLinkExpired");
return false;
}
var m = new MembershipPasswordController();
if (m.IsPasswordInHistory(user.UserID, user.PortalID, newPassword, false))
{
errorMessage = Localization.GetString("PasswordResetFailed_PasswordInHistory");
return false;
}
// Although we would hope that the caller has already validated the password,
// Validate the new Password
if (ValidatePassword(newPassword))
{
try
{
passwordChanged = MembershipProvider.Instance().ResetAndChangePassword(user, newPassword, answer);
if (passwordChanged)
{
// update reset token values to ensure token is 1-time use
user.PasswordResetExpiration = DateTime.MinValue;
user.PasswordResetToken = Guid.NewGuid();
// Update User
user.Membership.UpdatePassword = false;
UpdateUser(user.PortalID, user);
m.IsPasswordInHistory(user.UserID, user.PortalID, newPassword, true); // add the password into history.
}
else
{
errorMessage = Localization.GetString("PasswordResetFailed_WrongAnswer");
}
}
catch (Exception)
{
passwordChanged = false;
errorMessage = Localization.GetString("PasswordResetFailed_WrongAnswer");
}
}
else
{
throw new Exception("Invalid Password");
}
return passwordChanged;
}
/// <summary>Attempts to change the users password reset question and answer.</summary>
/// <param name="user">The user to update.</param>
/// <param name="password">The password.</param>
/// <param name="passwordQuestion">The new password question.</param>
/// <param name="passwordAnswer">The new password answer.</param>
/// <returns>A Boolean indicating success or failure.</returns>
public static bool ChangePasswordQuestionAndAnswer(UserInfo user, string password, string passwordQuestion, string passwordAnswer)
{
EventLogController.Instance.AddLog(user, PortalController.Instance.GetCurrentSettings(), GetCurrentUserInternal().UserID, string.Empty, EventLogController.EventLogType.USER_UPDATED);
return MembershipProvider.Instance().ChangePasswordQuestionAndAnswer(user, password, passwordQuestion, passwordAnswer);
}
/// <summary>
/// update username in the system
/// works around membershipprovider limitation.
/// </summary>
/// <param name="userId">user id.</param>
/// <param name="newUsername">new one.</param>
public static void ChangeUsername(int userId, string newUsername)
{
MembershipProvider.Instance().ChangeUsername(userId, newUsername);
}
/// <summary>Checks if the user has known default username and password.</summary>
/// <param name="username">The user username.</param>
/// <param name="password">The user password.</param>
/// <param name="loginStatus">
/// If a known default username and password is used, will return
/// <see cref="UserLoginStatus.LOGIN_INSECUREADMINPASSWORD"/> or
/// <see cref="UserLoginStatus.LOGIN_INSECUREHOSTPASSWORD"/>.
/// </param>
[DnnDeprecated(9, 8, 1, "No alternative method implemented")]
public static partial void CheckInsecurePassword(string username, string password, ref UserLoginStatus loginStatus)
{
if (username == "admin" && (password == "admin" || password == "dnnadmin"))
{
loginStatus = UserLoginStatus.LOGIN_INSECUREADMINPASSWORD;
}
if (username == "host" && (password == "host" || password == "dnnhost"))
{
loginStatus = UserLoginStatus.LOGIN_INSECUREHOSTPASSWORD;
}
}
/// <summary>Copys a user to a different portal.</summary>
/// <param name="user">The user to copy.</param>
/// <param name="destinationPortal">The destination portal.</param>
/// <param name="mergeUser">A flag that indicates whether to merge the original user.</param>
public static void CopyUserToPortal(UserInfo user, PortalInfo destinationPortal, bool mergeUser)
{
var targetUser = GetUserById(destinationPortal.PortalID, user.UserID);
if (targetUser == null)
{
AddUserPortal(destinationPortal.PortalID, user.UserID);
if (!user.IsSuperUser)
{
AutoAssignUsersToRoles(user, destinationPortal.PortalID);
}
targetUser = GetUserById(destinationPortal.PortalID, user.UserID);
MergeUserProperties(user, targetUser);
MergeUserProfileProperties(user, targetUser);
}
else
{
targetUser.PortalID = destinationPortal.PortalID;
if (mergeUser)
{
MergeUserProperties(user, targetUser);
MergeUserProfileProperties(user, targetUser);
}
}
UpdateUser(targetUser.PortalID, targetUser);
}
/// <summary>Creates a new User in the Data Store.</summary>
/// <param name="user">The userInfo object to persist to the Database.</param>
/// <returns>The <see cref="UserCreateStatus"/> ot the User.</returns>
public static UserCreateStatus CreateUser(ref UserInfo user)
{
return CreateUser(ref user, false);
}
/// <summary>Creates a new User in the Data Store optionally sending an email notification.</summary>
/// <param name="user">The <see cref="UserInfo"/> object to persist to the Database.</param>
/// <param name="sendEmailNotification">A value indicating whether a registration email will be sent to user.</param>
/// <returns>The <see cref="UserCreateStatus"/> of the User.</returns>
public static UserCreateStatus CreateUser(ref UserInfo user, bool sendEmailNotification)
{
int portalId = user.PortalID;
user.PortalID = GetEffectivePortalId(portalId);
// ensure valid GUID exists (covers case where password is randomly generated - has 24 hr validity as per other Admin user steps
var passwordExpiry = DateTime.Now.AddMinutes(1440);
var passwordGuid = Guid.NewGuid();
user.PasswordResetExpiration = passwordExpiry;
user.PasswordResetToken = passwordGuid;
// Create the User
var createStatus = MembershipProvider.Instance().CreateUser(ref user);
if (createStatus == UserCreateStatus.Success)
{
// reapply guid/expiry (cleared when user is created)
user.PasswordResetExpiration = passwordExpiry;
user.PasswordResetToken = passwordGuid;
UpdateUser(user.PortalID, user);
EventLogController.Instance.AddLog(user, PortalController.Instance.GetCurrentSettings(), GetCurrentUserInternal().UserID, string.Empty, EventLogController.EventLogType.USER_CREATED);
CachingProvider.Instance().Remove(string.Format(DataCache.PortalUserCountCacheKey, portalId));
if (!user.IsSuperUser)
{
// autoassign user to portal roles
AutoAssignUsersToRoles(user, portalId);
}
EventManager.Instance.OnUserCreated(new UserEventArgs { User = user, SendNotification = sendEmailNotification });
}
// Reset PortalId
FixMemberPortalId(user, portalId);
return createStatus;
}
/// <summary>Deletes all Unauthorized Users for a Portal.</summary>
/// <param name="portalId">The Id of the Portal.</param>
public static void DeleteUnauthorizedUsers(int portalId)
{
var arrUsers = (portalId == -1) ? GetUsers(true, true, portalId) : GetUnAuthorizedUsers(portalId);
for (int i = 0; i < arrUsers.Count; i++)
{
var user = arrUsers[i] as UserInfo;
if (user != null)
{
if (user.Membership.Approved == false || user.Membership.LastLoginDate == Null.NullDate)
{
DeleteUser(ref user, true, false);
}
}
}
}
/// <summary>Deletes an existing User from the Data Store.</summary>
/// <param name="user">The userInfo object to delete from the Database.</param>
/// <param name="notify">A flag that indicates whether an email notification should be sent.</param>
/// <param name="deleteAdmin">A flag that indicates whether the Portal Administrator should be deleted.</param>
/// <returns>A Boolean value that indicates whether the User was successfully deleted.</returns>
public static bool DeleteUser(ref UserInfo user, bool notify, bool deleteAdmin)
{
int portalId = user.PortalID;
user.PortalID = GetEffectivePortalId(portalId);
// If the HTTP Current Context is unavailable (e.g. when called from within a SchedulerClient) GetCurrentPortalSettings() returns null and the
// PortalSettings are created/loaded for the portal (originally) assigned to the user.
var portalSettings = PortalController.Instance.GetCurrentPortalSettings() ?? new PortalSettings(portalId);
var canDelete = deleteAdmin || (user.UserID != portalSettings.AdministratorId);
if (canDelete)
{
// Delete Permissions
DeleteUserPermissions(user);
canDelete = MembershipProvider.Instance().DeleteUser(user);
}
if (canDelete)
{
// Obtain PortalSettings from Current Context or from the users (original) portal if the HTTP Current Context is unavailable.
EventLogController.Instance.AddLog("Username", user.Username, portalSettings, user.UserID, EventLogController.EventLogType.USER_DELETED);
if (notify && !user.IsSuperUser)
{
// send email notification to portal administrator that the user was removed from the portal
SendDeleteEmailNotifications(user, portalSettings);
}
DataCache.ClearPortalUserCountCache(user.PortalID);
DataCache.ClearUserCache(user.PortalID, user.Username);
// also clear current portal's cache if the user is a host user
if (portalSettings.PortalId != portalId)
{
DataCache.ClearPortalCache(portalSettings.PortalId, false);
DataCache.ClearUserCache(portalSettings.PortalId, user.Username);
}
// queue remove user contributions from search index
var document = new Services.Search.Entities.SearchDocumentToDelete
{
PortalId = portalId,
AuthorUserId = user.UserID,
SearchTypeId = Services.Search.Internals.SearchHelper.Instance.GetSearchTypeByName("user").SearchTypeId,
};
DataProvider.Instance().AddSearchDeletedItems(document);
EventManager.Instance.OnUserDeleted(new UserEventArgs { User = user });
}
FixMemberPortalId(user, portalId);
UpdateUser(portalId, GetUserById(portalId, user.UserID));
return canDelete;
}
/// <summary>Deletes all Users for a Portal.</summary>
/// <param name="portalId">The Id of the Portal.</param>
/// <param name="notify">A flag that indicates whether an email notification should be sent.</param>
/// <param name="deleteAdmin">A flag that indicates whether the Portal Administrator should be deleted.</param>
public static void DeleteUsers(int portalId, bool notify, bool deleteAdmin)
{
var arrUsers = GetUsers(portalId);
for (int i = 0; i < arrUsers.Count; i++)
{
var objUser = arrUsers[i] as UserInfo;
DeleteUser(ref objUser, notify, deleteAdmin);
}
}
/// <summary>Generates a new random password.</summary>
/// <returns>A string representing the randomly generated password which is the minimum password length + 4 characters.</returns>
public static string GeneratePassword()
{
return GeneratePassword(MembershipProviderConfig.MinPasswordLength + 4);
}
/// <summary>Generates a new random password.</summary>
/// <param name="length">The length of password to generate.</param>
/// <returns>A string representing the newly generated random password.</returns>
public static string GeneratePassword(int length)
{
return MembershipProvider.Instance().GeneratePassword(length);
}
/// <summary>
/// Retrieves the User from the Cache, or fetches a fresh copy if
/// not in cache or if Cache settings are not set to HeavyCaching.
/// </summary>
/// <param name="portalId">The Id of the Portal.</param>
/// <param name="username">The username of the user being retrieved.</param>
/// <returns>The user as a <see cref="UserInfo"/> object.</returns>
public static UserInfo GetCachedUser(int portalId, string username)
{
var masterPortalId = GetEffectivePortalId(portalId);
var user = MembershipProvider.Instance().GetUserByUserName(masterPortalId, username);
FixMemberPortalId(user, portalId);
if (user != null)
{
var lookUp = GetUserLookupDictionary(portalId);
using (lookUp.GetWriteLock())
{
lookUp[user.UserID] = user.Username;
}
}
return user;
}
/// <summary>Gets deleted users for a portal.</summary>
/// <param name="portalId">The portal id for which to get the deleted users.</param>
/// <returns>An ArrayList of <see cref="UserInfo"/>.</returns>
public static ArrayList GetDeletedUsers(int portalId)
{
return MembershipProvider.Instance().GetDeletedUsers(GetEffectivePortalId(portalId));
}
/// <summary>Gets a collection of Online Users.</summary>
/// <param name="portalId">The Id of the Portal.</param>
/// <returns>An ArrayList of UserInfo objects.</returns>
[DnnDeprecated(8, 0, 0, "Other solutions exist outside of the DNN Platform", RemovalVersion = 11)]
public static partial ArrayList GetOnlineUsers(int portalId)
{
return MembershipProvider.Instance().GetOnlineUsers(GetEffectivePortalId(portalId));
}
/// <summary>Gets the Current Password Information for the User.</summary>
/// <remarks>
/// This method will only return the password if the memberProvider supports
/// and is using a password encryption method that supports decryption.
/// </remarks>
/// <param name="user">The user whose Password information we are retrieving.</param>
/// <param name="passwordAnswer">The answer to the user's password Question.</param>
/// <returns>A string representing the user password.</returns>
/// <exception cref="ConfigurationErrorsException">is thrown if the current configuration does not allow password retrieval.</exception>
public static string GetPassword(ref UserInfo user, string passwordAnswer)
{
if (MembershipProviderConfig.PasswordRetrievalEnabled)
{
user.Membership.Password = MembershipProvider.Instance().GetPassword(user, passwordAnswer);
}
else
{
// Throw a configuration exception as password retrieval is not enabled
throw new ConfigurationErrorsException("Password Retrieval is not enabled");
}
return user.Membership.Password;
}
/// <summary>Gets the unauthorized users for a portal.</summary>
/// <param name="portalId">The site (portal) id on which to search for Unauthorized users.</param>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating whether to include superusers (hosts).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/>.</returns>
public static ArrayList GetUnAuthorizedUsers(int portalId, bool includeDeleted, bool superUsersOnly)
{
return MembershipProvider.Instance().GetUnAuthorizedUsers(GetEffectivePortalId(portalId), includeDeleted, superUsersOnly);
}
/// <summary>Gets all the users of the portal, that are not authorized.</summary>
/// <param name="portalId">The Id of the site (portal).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUnAuthorizedUsers(int portalId)
{
return GetUnAuthorizedUsers(portalId, false, false);
}
/// <inheritdoc cref="IUserController.GetUserById"/>
public static UserInfo GetUserById(int portalId, int userId)
{
// stop any sql calls for guest users
if (userId == Null.NullInteger)
{
return null;
}
var lookUp = GetUserLookupDictionary(portalId);
UserInfo user;
string userName;
bool userFound;
using (lookUp.GetReadLock())
{
userFound = lookUp.TryGetValue(userId, out userName);
}
if (userFound)
{
user = GetCachedUser(portalId, userName);
}
else
{
user = MembershipProvider.Instance().GetUser(GetEffectivePortalId(portalId), userId);
FixMemberPortalId(user, portalId);
if (user != null)
{
using (lookUp.GetWriteLock())
{
lookUp[userId] = user.Username;
}
}
}
return user;
}
/// <summary>Gets a User from the DataStore.</summary>
/// <param name="username">The username of the user being retrieved from the Data Store.</param>
/// <returns>The User as a <see cref="UserInfo"/> object.</returns>
public static UserInfo GetUserByName(string username)
{
return MembershipProvider.Instance().GetUserByUserName(-1, username);
}
/// <summary>Gets a user from the DataStore.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="username">The username of the user being retrieved from the Data Store.</param>
/// <returns>The User as a <see cref="UserInfo"/> object.</returns>
public static UserInfo GetUserByName(int portalId, string username)
{
return GetCachedUser(portalId, username);
}
/// <summary>Gets a user by its vanity url.</summary>
/// <param name="portalId">The site (portal) id of the user.</param>
/// <param name="vanityUrl">The vanity url to search.</param>
/// <returns>A user as a <see cref="UserInfo"/> object.</returns>
public static UserInfo GetUserByVanityUrl(int portalId, string vanityUrl)
{
portalId = GetEffectivePortalId(portalId);
return MembershipProvider.Instance().GetUserByVanityUrl(portalId, vanityUrl);
}
/// <summary>Gets a single user by its password reset token.</summary>
/// <param name="portalId">The site (portal) id for the user.</param>
/// <param name="resetToken">the password reset token.</param>
/// <returns>A user represented in a <see cref="UserInfo"/> object.</returns>
public static UserInfo GetUserByPasswordResetToken(int portalId, string resetToken)
{
portalId = GetEffectivePortalId(portalId);
return MembershipProvider.Instance().GetUserByPasswordResetToken(portalId, resetToken);
}
/// <summary>Gets the number of users in a site (portal).</summary>
/// <param name="portalId">The id of the portal to search.</param>
/// <returns>The no of users the portal contains.</returns>
public static int GetUserCountByPortal(int portalId)
{
portalId = GetEffectivePortalId(portalId);
var cacheKey = string.Format(DataCache.PortalUserCountCacheKey, portalId);
return CBO.GetCachedObject<int>(new CacheItemArgs(cacheKey, DataCache.PortalUserCountCacheTimeOut, DataCache.PortalUserCountCachePriority, portalId), GetUserCountByPortalCallBack);
}
/// <summary>Gets a localized string representing the user creation status.</summary>
/// <param name="userRegistrationStatus">The user creation status as a <see cref="UserCreateStatus"/>.</param>
/// <returns>A localized string representing the user creation status.</returns>
public static string GetUserCreateStatus(UserCreateStatus userRegistrationStatus)
{
switch (userRegistrationStatus)
{
case UserCreateStatus.DuplicateEmail:
return Localization.GetString("UserEmailExists");
case UserCreateStatus.InvalidAnswer:
return Localization.GetString("InvalidAnswer");
case UserCreateStatus.InvalidEmail:
return Localization.GetString("InvalidEmail");
case UserCreateStatus.InvalidPassword:
string strInvalidPassword = Localization.GetString("InvalidPassword");
strInvalidPassword = strInvalidPassword.Replace("[PasswordLength]", MembershipProviderConfig.MinPasswordLength.ToString());
strInvalidPassword = strInvalidPassword.Replace("[NoneAlphabet]", MembershipProviderConfig.MinNonAlphanumericCharacters.ToString());
return strInvalidPassword;
case UserCreateStatus.PasswordMismatch:
return Localization.GetString("PasswordMismatch");
case UserCreateStatus.InvalidQuestion:
return Localization.GetString("InvalidQuestion");
case UserCreateStatus.InvalidUserName:
return Localization.GetString("InvalidUserName");
case UserCreateStatus.InvalidDisplayName:
return Localization.GetString("InvalidDisplayName");
case UserCreateStatus.DuplicateDisplayName:
return Localization.GetString("DuplicateDisplayName");
case UserCreateStatus.UserRejected:
return Localization.GetString("UserRejected");
case UserCreateStatus.DuplicateUserName:
case UserCreateStatus.UserAlreadyRegistered:
case UserCreateStatus.UsernameAlreadyExists:
return Localization.GetString("UserNameExists");
case UserCreateStatus.BannedPasswordUsed:
return Localization.GetString("BannedPasswordUsed");
case UserCreateStatus.ProviderError:
case UserCreateStatus.DuplicateProviderUserKey:
case UserCreateStatus.InvalidProviderUserKey:
return Localization.GetString("RegError");
case UserCreateStatus.InvalidFirstName:
return Localization.GetString("InvalidFirstName");
case UserCreateStatus.InvalidLastName:
return Localization.GetString("InvalidLastName");
default:
throw new ArgumentException("Unknown UserCreateStatus value encountered", "userRegistrationStatus");
}
}
/// <summary>Gets the membership information for a user.</summary>
/// <param name="user">The user whose membership information to retrieve.</param>
/// <remarks>This method does not return the membership information, it populates it inside the <see cref="UserInfo"/> object.</remarks>
public static void GetUserMembership(UserInfo user)
{
int portalId = user.PortalID;
user.PortalID = GetEffectivePortalId(portalId);
MembershipProvider.Instance().GetUserMembership(ref user);
FixMemberPortalId(user, portalId);
}
/// <summary>Gets a set of default portal settings relative to user management.</summary>
/// <returns>A <see cref="Hashtable"/> or the user related portal settings.</returns>
public static Hashtable GetDefaultUserSettings()
{
var portalId = -1;
var portalSettings = PortalController.Instance.GetCurrentSettings();
if (portalSettings != null)
{
portalId = portalSettings.PortalId;
}
return GetUserSettings(portalId, new Hashtable());
}
/// <summary>Gets the user related portal settings.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <returns>The Settings Hashtable.</returns>
public static Hashtable GetUserSettings(int portalId)
{
var settings = GetDefaultUserSettings();
var masterPortalId = GetEffectivePortalId(portalId);
Dictionary<string, string> settingsDictionary = (portalId == Null.NullInteger)
? HostController.Instance.GetSettingsDictionary()
: PortalController.Instance.GetPortalSettings(masterPortalId);
Dictionary<string, string> currentPortalSettings = null;
if (portalId != Null.NullInteger && masterPortalId != portalId)
{
currentPortalSettings = PortalController.Instance.GetPortalSettings(portalId);
}
if (settingsDictionary != null)
{
foreach (KeyValuePair<string, string> kvp in settingsDictionary)
{
int index = kvp.Key.IndexOf("_");
if (index > 0)
{
// Get the prefix
string prefix = kvp.Key.Substring(0, index + 1);
switch (prefix)
{
case "Column_":
case "Display_":
case "Profile_":
case "Records_":
case "Redirect_":
case "Registration_":
case "Security_":
switch (kvp.Key)
{
case "Display_Mode":
settings[kvp.Key] = (DisplayMode)Convert.ToInt32(kvp.Value);
break;
case "Profile_DefaultVisibility":
settings[kvp.Key] = (UserVisibilityMode)Convert.ToInt32(kvp.Value);
break;
case "Security_UsersControl":
settings[kvp.Key] = (UsersControl)Convert.ToInt32(kvp.Value);
break;
default:
// update value or add any new values
settings[kvp.Key] = kvp.Value;
break;
}
break;
}
}
}
}
if (currentPortalSettings != null)
{
foreach (var kvp in currentPortalSettings.Where(kvp => kvp.Key.StartsWith("Redirect_")))
{
settings[kvp.Key] = kvp.Value;
}
}
return settings;
}
/// <summary>Gets all the users of a given portal.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsers(int portalId)
{
return GetUsers(false, false, portalId);
}
/// <summary>Gets the users of a given portal.</summary>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating whether to ONLY include SuperUsers (Hosts).</param>
/// <param name="portalId">The id of the site (portal).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsers(bool includeDeleted, bool superUsersOnly, int portalId)
{
var totalrecords = -1;
return GetUsers(portalId, -1, -1, ref totalrecords, includeDeleted, superUsersOnly);
}
/// <summary>Gets all the users of a given portal, excluding deleted users and SuperUsers (Hosts), by page.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records.</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsers(int portalId, int pageIndex, int pageSize, ref int totalRecords)
{
return GetUsers(portalId, pageIndex, pageSize, ref totalRecords, false, false);
}
/// <summary>Gets all the users of a given portal, by page.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records.</param>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating whether to ONLY include superUsers (Hosts).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsers(int portalId, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
{
return MembershipProvider.Instance().GetUsers(GetEffectivePortalId(portalId), pageIndex, pageSize, ref totalRecords, includeDeleted, superUsersOnly);
}
/// <summary>Gets all the users of a given portal whose email matches a provided filter, excluding deleted users and SuperUsers (Hosts).</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="emailToMatch">The email address to use to find a match.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByEmail(int portalId, string emailToMatch, int pageIndex, int pageSize, ref int totalRecords)
{
return GetUsersByEmail(portalId, emailToMatch, pageIndex, pageSize, ref totalRecords, false, false);
}
/// <summary>
/// Gets one single user matching the email address provided, this will only return the first match found.
/// This will only be useful in portals without duplicate email addresses.
/// </summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="emailToMatch">The email address to use to find a match.</param>
/// <returns>A single <see cref="UserInfo"/> object or null if no user found.</returns>
public static UserInfo GetUserByEmail(int portalId, string emailToMatch)
{
int uid = DataProvider.Instance().GetSingleUserByEmail(portalId, emailToMatch);
if (uid > -1)
{
return GetUserById(portalId, uid);
}
return null;
}
/// <summary>Gets all the users of the portal whose email matches a provided filter expression.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="emailToMatch">The email address to use to find a match.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating if the search should ONLY include SuperUsers (Hosts).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByEmail(int portalId, string emailToMatch, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
{
return MembershipProvider.Instance().GetUsersByEmail(GetEffectivePortalId(portalId), emailToMatch, pageIndex, pageSize, ref totalRecords, includeDeleted, superUsersOnly);
}
/// <summary>
/// Gets all the users of the portal whose profile matches
/// the profile property pased as a parameter.
/// </summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="propertyName">The name of the property being matched.</param>
/// <param name="propertyValue">The value of the property being matched.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByProfileProperty(int portalId, string propertyName, string propertyValue, int pageIndex, int pageSize, ref int totalRecords)
{
return GetUsersByProfileProperty(portalId, propertyName, propertyValue, pageIndex, pageSize, ref totalRecords, false, false);
}
/// <summary>
/// Gets all the users of the portal whose profile matches
/// the profile property pased as a parameter.
/// </summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="propertyName">The name of the property being matched.</param>
/// <param name="propertyValue">The value of the property being matched.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating whether to ONLY include SuperUsers (Hosts).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByProfileProperty(int portalId, string propertyName, string propertyValue, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
{
return MembershipProvider.Instance().GetUsersByProfileProperty(GetEffectivePortalId(portalId), propertyName, propertyValue, pageIndex, pageSize, ref totalRecords, includeDeleted, superUsersOnly);
}
/// <summary>Gets all the users of the portal whose username matches a provided filter expression, excluding deleted users and SuperUsers (Hosts), by page.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="userNameToMatch">The username to use to find a match.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByUserName(int portalId, string userNameToMatch, int pageIndex, int pageSize, ref int totalRecords)
{
return GetUsersByUserName(portalId, userNameToMatch, pageIndex, pageSize, ref totalRecords, false, false);
}
/// <summary>Gets all the users of the portal whose username matches a provided filter expression, by page.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="userNameToMatch">The username to use to find a match.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>
/// <param name="includeDeleted">A value indicating whether to include deleted users.</param>
/// <param name="superUsersOnly">A value indicating whether to ONLY include SuperUsers (Hosts).</param>
/// <returns>An ArrayList of <see cref="UserInfo"/> objects.</returns>
public static ArrayList GetUsersByUserName(int portalId, string userNameToMatch, int pageIndex, int pageSize, ref int totalRecords, bool includeDeleted, bool superUsersOnly)
{
return MembershipProvider.Instance().GetUsersByUserName(GetEffectivePortalId(portalId), userNameToMatch, pageIndex, pageSize, ref totalRecords, includeDeleted, superUsersOnly);
}
/// <summary>Gets all the users of the portal whose display name matches a provided filter expression, by page.</summary>
/// <param name="portalId">The id of the site (portal).</param>
/// <param name="nameToMatch">The display name to use to find a match.</param>
/// <param name="pageIndex">The page of records to return.</param>
/// <param name="pageSize">The size of each page.</param>
/// <param name="totalRecords">The total number of records that satisfy the criteria.</param>