@@ -121,13 +121,13 @@ public async Task RemovePackageOwnerAsync(PackageRegistration packageRegistratio
121
121
using ( var strategy = new SuspendDbExecutionStrategy ( ) )
122
122
using ( var transaction = _entitiesContext . GetDatabase ( ) . BeginTransaction ( ) )
123
123
{
124
- await RemovePackageOwnerImplAsync ( packageRegistration , requestingOwner , ownerToBeRemoved ) ;
124
+ await RemovePackageOwnerImplAsync ( packageRegistration , ownerToBeRemoved ) ;
125
125
transaction . Commit ( ) ;
126
126
}
127
127
}
128
128
else
129
129
{
130
- await RemovePackageOwnerImplAsync ( packageRegistration , requestingOwner , ownerToBeRemoved ) ;
130
+ await RemovePackageOwnerImplAsync ( packageRegistration , ownerToBeRemoved ) ;
131
131
}
132
132
133
133
await _auditingService . SaveAuditRecordAsync (
@@ -139,38 +139,29 @@ await _auditingService.SaveAuditRecordAsync(
139
139
}
140
140
}
141
141
142
- private async Task RemovePackageOwnerImplAsync ( PackageRegistration packageRegistration , User requestingOwner , User ownerToBeRemoved )
142
+ private async Task RemovePackageOwnerImplAsync ( PackageRegistration packageRegistration , User ownerToBeRemoved )
143
143
{
144
- // 1. Remove this package registration from the namespaces owned by this user if he is the only package owner in the set of matching namespaces
145
- // 2. Remove the IsVerified flag from package registration if all the matching namespaces are owned by this user alone (no other package owner owns a matching namespace for this PR)
146
- var allMatchingNamespacesForRegistration = packageRegistration . ReservedNamespaces ;
147
- if ( allMatchingNamespacesForRegistration . Any ( ) )
144
+ // Remove the user from owners list of package registration
145
+ await _packageService . RemovePackageOwnerAsync ( packageRegistration , ownerToBeRemoved , commitChanges : false ) ;
146
+
147
+ // Remove this package registration from the namespaces owned by this user that are owned by no other package owners
148
+ foreach ( var reservedNamespace in packageRegistration . ReservedNamespaces . ToArray ( ) )
148
149
{
149
- var allPackageOwners = packageRegistration . Owners ;
150
- var matchingNamespacesOwnedByUser = allMatchingNamespacesForRegistration
151
- . Where ( rn => rn . Owners . Any ( o => o == ownerToBeRemoved ) ) ;
152
- var namespacesToModify = matchingNamespacesOwnedByUser
153
- . Where ( rn => rn . Owners . Intersect ( allPackageOwners ) . Count ( ) == 1 )
154
- . ToList ( ) ;
155
-
156
- if ( namespacesToModify . Any ( ) )
150
+ if ( ! packageRegistration . Owners
151
+ . Any ( o => ActionsRequiringPermissions . AddPackageToReservedNamespace
152
+ . CheckPermissionsOnBehalfOfAnyAccount ( o , reservedNamespace ) == PermissionsCheckResult . Allowed ) )
157
153
{
158
- // The package will lose its 'IsVerified' flag if the user is the only package owner who owns all the namespaces that match this registration
159
- var shouldModifyIsVerified = allMatchingNamespacesForRegistration . Count ( ) == namespacesToModify . Count ( ) ;
160
- if ( shouldModifyIsVerified && packageRegistration . IsVerified )
161
- {
162
- await _packageService . UpdatePackageVerifiedStatusAsync ( new List < PackageRegistration > { packageRegistration } , isVerified : false ) ;
163
- }
164
-
165
- namespacesToModify
166
- . ForEach ( rn => _reservedNamespaceService . RemovePackageRegistrationFromNamespace ( rn . Value , packageRegistration ) ) ;
167
-
168
- await _entitiesContext . SaveChangesAsync ( ) ;
154
+ _reservedNamespaceService . RemovePackageRegistrationFromNamespace ( reservedNamespace , packageRegistration ) ;
169
155
}
170
156
}
171
157
172
- // Remove the user from owners list of package registration
173
- await _packageService . RemovePackageOwnerAsync ( packageRegistration , ownerToBeRemoved ) ;
158
+ // Remove the IsVerified flag from package registration if all the matching namespaces are owned by this user alone (no other package owner owns a matching namespace for this PR)
159
+ if ( packageRegistration . IsVerified && ! packageRegistration . ReservedNamespaces . Any ( ) )
160
+ {
161
+ await _packageService . UpdatePackageVerifiedStatusAsync ( new List < PackageRegistration > { packageRegistration } , isVerified : false , commitChanges : false ) ;
162
+ }
163
+
164
+ await _entitiesContext . SaveChangesAsync ( ) ;
174
165
}
175
166
176
167
public async Task DeletePackageOwnershipRequestAsync ( PackageRegistration packageRegistration , User newOwner )
@@ -191,31 +182,21 @@ public async Task DeletePackageOwnershipRequestAsync(PackageRegistration package
191
182
await _packageOwnerRequestService . DeletePackageOwnershipRequest ( request ) ;
192
183
}
193
184
}
194
-
195
- // The requesting owner can remove other owner only if
196
- // 1. Is an admin.
197
- // 2. Owns a namespace.
198
- // 3. Or the other user also does not own a namespace.
185
+
199
186
private static bool OwnerHasPermissionsToRemove ( User requestingOwner , User ownerToBeRemoved , PackageRegistration packageRegistration )
200
187
{
201
- if ( requestingOwner . IsAdministrator )
188
+ var reservedNamespaces = packageRegistration . ReservedNamespaces . ToList ( ) ;
189
+ if ( ActionsRequiringPermissions . AddPackageToReservedNamespace
190
+ . CheckPermissionsOnBehalfOfAnyAccount ( ownerToBeRemoved , reservedNamespaces ) == PermissionsCheckResult . Allowed )
202
191
{
203
- return true ;
192
+ // If the owner to be removed owns a reserved namespace that applies to this package,
193
+ // the requesting user must own a reserved namespace that applies to this package or be a site admin.
194
+ return ActionsRequiringPermissions . RemovePackageFromReservedNamespace
195
+ . CheckPermissionsOnBehalfOfAnyAccount ( requestingOwner , reservedNamespaces ) == PermissionsCheckResult . Allowed ;
204
196
}
205
197
206
- var requestingOwnerOwnsNamespace = IsUserAnOwnerOfPackageNamespace ( packageRegistration , requestingOwner ) ;
207
- if ( requestingOwnerOwnsNamespace )
208
- {
209
- return true ;
210
- }
211
-
212
- var ownerToBeRemovedOwnsNamespace = IsUserAnOwnerOfPackageNamespace ( packageRegistration , ownerToBeRemoved ) ;
213
- return ! ownerToBeRemovedOwnsNamespace ;
214
- }
215
-
216
- private static bool IsUserAnOwnerOfPackageNamespace ( PackageRegistration packageRegistration , User user )
217
- {
218
- return packageRegistration . ReservedNamespaces . Any ( rn => rn . Owners . Any ( owner => owner == user ) ) ;
198
+ // If the owner to be removed does not own any reserved namespaces that apply to this package, they can be removed by anyone.
199
+ return true ;
219
200
}
220
201
}
221
202
}
0 commit comments