Skip to content

Commit 2ae64d1

Browse files
authored
Fix org profile to show correct MFA status for site admins (#9106)
1 parent 7f60406 commit 2ae64d1

3 files changed

Lines changed: 126 additions & 3 deletions

File tree

src/NuGetGallery/ViewModels/UserProfileModel.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public UserProfileModel(User user, User currentUser, List<ListPackageItemViewMod
1616
Username = user.Username;
1717
EmailAddress = user.EmailAddress;
1818
UnconfirmedEmailAddress = user.UnconfirmedEmailAddress;
19-
HasEnabledMultiFactorAuthentication = user.EnableMultiFactorAuthentication;
2019
IsLocked = user.IsLocked;
2120
AllPackages = allPackages;
2221
TotalPackages = allPackages.Count;
@@ -43,7 +42,25 @@ public UserProfileModel(User user, User currentUser, List<ListPackageItemViewMod
4342
public string Username { get; private set; }
4443
public string EmailAddress { get; private set; }
4544
public string UnconfirmedEmailAddress { get; set; }
46-
public bool HasEnabledMultiFactorAuthentication { get; set; }
45+
public bool HasEnabledMultiFactorAuthentication
46+
{
47+
get
48+
{
49+
if (UserIsOrganization)
50+
{
51+
var organization = (Organization)User;
52+
return organization
53+
.Members
54+
.Select(x => x.Member)
55+
.All(x => x.EnableMultiFactorAuthentication);
56+
}
57+
else
58+
{
59+
return User.EnableMultiFactorAuthentication;
60+
}
61+
}
62+
}
63+
4764
public bool IsLocked { get; set; }
4865
public ICollection<ListPackageItemViewModel> AllPackages { get; private set; }
4966
public ICollection<ListPackageItemViewModel> PagedPackages { get; private set; }

src/NuGetGallery/Views/Users/Profiles.cshtml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@
3939
<dt>Unconfirmed Email Address:</dt>
4040
<dd>@Model.UnconfirmedEmailAddress</dd>
4141
}
42-
<dt>Multi-factor Authentication:</dt>
42+
43+
@if (Model.UserIsOrganization)
44+
{
45+
<dt>Org Multi-factor Authentication:</dt>
46+
}
47+
else
48+
{
49+
<dt>Multi-factor Authentication:</dt>
50+
}
4351
<dd>@(Model.HasEnabledMultiFactorAuthentication ? "Enabled" : "Disabled")</dd>
4452
<dt>Locked:</dt>
4553
<dd>@(Model.IsLocked ? "Yes" : "No")</dd>

tests/NuGetGallery.Facts/ViewModels/UserProfileModelFacts.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,104 @@ public void TotalDownloadCount_DoesNotThrowIntegerOverflow()
3434
Assert.Equal(expected, profile.TotalPackageDownloadCount);
3535
}
3636

37+
[Theory]
38+
[InlineData(true)]
39+
[InlineData(false)]
40+
public void HasEnabledMultiFactorAuthentication_ForUsers(bool userMfaStatus)
41+
{
42+
var controller = GetController<UsersController>();
43+
var user = new User("theUser")
44+
{
45+
EnableMultiFactorAuthentication = userMfaStatus,
46+
};
47+
var currentUser = new User("theCurrentUser");
48+
var packages = new List<ListPackageItemViewModel>
49+
{
50+
CreatePackageItemViewModel("1.0.0"),
51+
CreatePackageItemViewModel("2.0.0")
52+
};
53+
54+
// Act
55+
var profile = new UserProfileModel(user, currentUser, packages, 0, 10, controller.Url);
56+
57+
// Assert
58+
Assert.Equal(userMfaStatus, profile.HasEnabledMultiFactorAuthentication);
59+
}
60+
61+
[Theory]
62+
[InlineData(true, false, true, false)]
63+
[InlineData(true, true, false, false)]
64+
[InlineData(false, false, true, false)]
65+
[InlineData(true, true, true, true)]
66+
public void HasEnabledMultiFactorAuthentication_ForOrganizations(bool user1MfaStatus, bool user2MfaStatus, bool collabUserMfaStatus, bool expectedOrgMfaStatus)
67+
{
68+
var controller = GetController<UsersController>();
69+
var userList = new List<User>() {
70+
new User("theUser")
71+
{
72+
EnableMultiFactorAuthentication = user1MfaStatus
73+
},
74+
new User("theOtherUser")
75+
{
76+
EnableMultiFactorAuthentication = user2MfaStatus
77+
}
78+
};
79+
80+
var collabUser = new User("TheCollabUser")
81+
{
82+
EnableMultiFactorAuthentication = collabUserMfaStatus
83+
};
84+
85+
var org = CreateTestOrganization(userList, collabUser);
86+
var currentUser = new User("theCurrentUser");
87+
var packages = new List<ListPackageItemViewModel>
88+
{
89+
CreatePackageItemViewModel("1.0.0"),
90+
CreatePackageItemViewModel("2.0.0")
91+
};
92+
93+
// Act
94+
var profile = new UserProfileModel(org, currentUser, packages, 0, 10, controller.Url);
95+
96+
// Assert
97+
Assert.Equal(expectedOrgMfaStatus, profile.HasEnabledMultiFactorAuthentication);
98+
}
99+
100+
private Organization CreateTestOrganization(List<User> usersList, User collabUser)
101+
{
102+
var organization = new Organization()
103+
{
104+
Key = 1,
105+
Username = "a"
106+
};
107+
108+
foreach (var user in usersList)
109+
{
110+
organization.Members.Add(new Membership()
111+
{
112+
MemberKey = user.Key,
113+
Member = user,
114+
OrganizationKey = organization.Key,
115+
Organization = organization,
116+
IsAdmin = true
117+
});
118+
}
119+
120+
if (collabUser != null)
121+
{
122+
organization.Members.Add(new Membership()
123+
{
124+
MemberKey = collabUser.Key,
125+
Member = collabUser,
126+
OrganizationKey = organization.Key,
127+
Organization = organization,
128+
IsAdmin = false
129+
});
130+
}
131+
132+
return organization;
133+
}
134+
37135
private ListPackageItemViewModel CreatePackageItemViewModel(string version)
38136
{
39137
return new ListPackageItemViewModelFactory(Mock.Of<IIconUrlProvider>()).Create(new Package

0 commit comments

Comments
 (0)