Description
In pkg/auth/user/UserService.go, getUserIdsHonoringFilters (shared by BulkDeleteUsers and, via UserService_ent.go's BulkUpdateStatus, by bulk status updates) calls SetDefaultValuesIfNotPresent and setStatusFilterType before building its query, but never calls setCurrentTimeInUserInfo(request) — unlike the listing path GetAllWithFilters, which calls all three (SetDefaultValuesIfNotPresent, setStatusFilterType, setCurrentTimeInUserInfo, in that order) before building its query.
request.CurrentTime (field in pkg/auth/user/bean/UserRequest.go, ListingRequest struct) is read by buildQueryForStatusFilter in pkg/auth/user/repository/helper/UserRepositoryQueryBuilder.go to build SQL time comparisons for Inactive/TemporaryAccess-flavored statuses (timeout_window_expression < now / > now). Without setCurrentTimeInUserInfo being called, CurrentTime stays at Go's zero value (year 0001), so:
- A bulk delete/status-update filtered by
Status: [Inactive] matches almost no one (comparing every user's expiry against year 0001, so almost nothing is "before" it).
- A bulk delete/status-update filtered by
Status: [TemporaryAccess] (or any combo including it) matches far more than intended (any real expiry timestamp is "after" year 0001).
This is an enterprise-only bug: this repository (devtron-labs/devtron-enterprise) duplicates pkg/auth/user/UserService.go/UserService_ent.go rather than depending on this repo's module, and the OSS copy of this code has no CurrentTime/status-filtering concept at all.
Impact
- Bulk-deleting or bulk-updating-status of users filtered by "Inactive" status silently affects far fewer users than the filter implies.
- Bulk-deleting or bulk-updating-status of users filtered by "Temporary Access" status silently affects far more users than the filter implies (any user with a real, non-zero timeout window expression matches).
Fix
Tracked and fixed in devtron-labs/devtron-enterprise: add the missing setCurrentTimeInUserInfo(request) call to getUserIdsHonoringFilters, in the same position/order relative to SetDefaultValuesIfNotPresent/setStatusFilterType as the listing path GetAllWithFilters already applies it, so the delete/status-update path resolves "now" exactly the same way the listing endpoint does.
Related: this same code path was previously the subject of #7020 / devtron-labs/devtron-enterprise#3399 (a separate bug: an unscoped filter matching every user).
Description
In
pkg/auth/user/UserService.go,getUserIdsHonoringFilters(shared byBulkDeleteUsersand, viaUserService_ent.go'sBulkUpdateStatus, by bulk status updates) callsSetDefaultValuesIfNotPresentandsetStatusFilterTypebefore building its query, but never callssetCurrentTimeInUserInfo(request)— unlike the listing pathGetAllWithFilters, which calls all three (SetDefaultValuesIfNotPresent,setStatusFilterType,setCurrentTimeInUserInfo, in that order) before building its query.request.CurrentTime(field inpkg/auth/user/bean/UserRequest.go,ListingRequeststruct) is read bybuildQueryForStatusFilterinpkg/auth/user/repository/helper/UserRepositoryQueryBuilder.goto build SQL time comparisons forInactive/TemporaryAccess-flavored statuses (timeout_window_expression < now/> now). WithoutsetCurrentTimeInUserInfobeing called,CurrentTimestays at Go's zero value (year 0001), so:Status: [Inactive]matches almost no one (comparing every user's expiry against year 0001, so almost nothing is "before" it).Status: [TemporaryAccess](or any combo including it) matches far more than intended (any real expiry timestamp is "after" year 0001).This is an enterprise-only bug: this repository (
devtron-labs/devtron-enterprise) duplicatespkg/auth/user/UserService.go/UserService_ent.gorather than depending on this repo's module, and the OSS copy of this code has noCurrentTime/status-filtering concept at all.Impact
Fix
Tracked and fixed in
devtron-labs/devtron-enterprise: add the missingsetCurrentTimeInUserInfo(request)call togetUserIdsHonoringFilters, in the same position/order relative toSetDefaultValuesIfNotPresent/setStatusFilterTypeas the listing pathGetAllWithFiltersalready applies it, so the delete/status-update path resolves "now" exactly the same way the listing endpoint does.Related: this same code path was previously the subject of #7020 / devtron-labs/devtron-enterprise#3399 (a separate bug: an unscoped filter matching every user).