Feature/userinfo - #273
Conversation
Bundle ReportBundle size has no change ✅ |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #273 +/- ##
==========================================
+ Coverage 50.07% 56.18% +6.11%
==========================================
Files 998 1193 +195
Lines 58354 80337 +21983
Branches 5853 6165 +312
==========================================
+ Hits 29221 45139 +15918
- Misses 28228 34227 +5999
- Partials 905 971 +66
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
| { | ||
| var result = System.Text.Json.JsonSerializer.Deserialize<DateTime?>($"\"{input}\"", options); | ||
| Assert.NotNull(result); | ||
| var nonNullResult = result.Value; |
| new("scope", "api_access") | ||
| }; | ||
|
|
||
| var formContent = new FormUrlEncodedContent(formParams); |
| foreach (var name in nameList) | ||
| { | ||
| if (!string.IsNullOrEmpty(name.StudentName) && name.ActivityDate.HasValue) | ||
| { | ||
| names.Add($"{name.StudentName} ({name.ActivityDate:MM/dd/yyyy})"); | ||
| } | ||
| } |
| foreach (var middlePart in middleParts) | ||
| { | ||
| if (middlePart.Length > 0) | ||
| { | ||
| var variation = $"{name} {middlePart[0]}"; | ||
| if (!nameVariations.Contains(variation)) | ||
| { | ||
| nameVariations.Add(variation); | ||
| } | ||
| } | ||
| } |
| foreach (var history in historyData) | ||
| { | ||
| var ucpathResult = new UCPathResult | ||
| { | ||
| JobCode = history.Jobcode, | ||
| JobCodeDescription = history.JobcodeDesc, | ||
| DepartmentId = history.Deptid, | ||
| DepartmentDescription = history.DeptDesc, | ||
| ActionDescription = history.ActionDescr, | ||
| PositionEffectiveDate = history.PositionEffdt.HasValue ? DateOnly.FromDateTime(history.PositionEffdt.Value) : null, | ||
| ReportsTo = GetReportsToName(history), | ||
| ReportsToPosition = GetReportsToPosition(history) | ||
| }; | ||
|
|
||
| result.UCPathHistory.Add(ucpathResult); | ||
| } |
| foreach (var groupDn in allGroups) | ||
| { | ||
| var formattedGroup = AdFormat(groupDn, domains); | ||
| if (!string.IsNullOrEmpty(formattedGroup)) | ||
| { | ||
| result.ADMemberOf.Add(formattedGroup); | ||
| } | ||
| } |
| foreach (var perm in permissions) | ||
| { | ||
| var parts = perm.Split('.'); | ||
| var partsToProcess = parts.Skip(1).ToList(); | ||
| if (!partsToProcess.Any()) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| var currentList = roots; | ||
| for (int i = 0; i < partsToProcess.Count; i++) | ||
| { | ||
| var part = partsToProcess[i]; | ||
| var node = currentList.FirstOrDefault(n => n.Name == part); | ||
| if (node == null) | ||
| { | ||
| node = new PermissionNode | ||
| { | ||
| Name = part, | ||
| FullPath = string.Join('.', parts.Take(i + 2)) | ||
| }; | ||
| currentList.Add(node); | ||
| } | ||
| if (i == partsToProcess.Count - 1) | ||
| { | ||
| node.IsPermission = true; | ||
| } | ||
| currentList = node.Children; | ||
| } | ||
| } |
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
|
@JasonRobertFrancis You should rebase this off the latest main branch since this doesn't have the GitHub Actions for code quality checks running |
…modal) and responds to code-quality bot userinfo recommendations
22567dc to
694ecd4
Compare
| foreach (var role in filteredRoles) | ||
| { | ||
| string displayName = role.DisplayName ?? role.Role; | ||
| result.SystemRoles.Add(new SystemRole | ||
| { | ||
| System = system, | ||
| DisplayName = FormatPermissionName(displayName) | ||
| }); | ||
| } |
| catch | ||
| { | ||
| return new List<string>(); | ||
| } |
| catch (Exception ex) | ||
| { | ||
| Console.WriteLine($"Warning: PopulateDirectoryInfoAsync LDAP failed: {ex.Message}"); | ||
| } |
|
@JasonRobertFrancis #261 just merged to main and conflicts with this branch. Small scope: one file, Both branches reworked the same methods, so every region is "main moved it" vs "your feature changed it in place":
The two sides are complementary rather than contradictory: keep main's structure, fold in your Optional: prompt for a coding agent |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Pull request overview
This PR expands the Directory/UserInfo functionality and supporting infrastructure in the VIPER web app by adding new UI styling, new/adjusted endpoints for directory search and session timeout, and a large set of scaffolded EF model types + DbContext registrations for additional data domains (PPS, Keys, IDCards, EquipmentLoan).
Changes:
- Add Directory “userinfo” styling and wire it into the shared layout.
- Add a new
/GetSessionTimeoutJSON endpoint and adjust the SessionTimeout view component behavior in development. - Introduce new Directory controller APIs and a large set of new EF entity classes, plus DbContext registrations for additional schemas/apps; update LDAP/IAM utilities and tests/docs accordingly.
Reviewed changes
Copilot reviewed 218 out of 220 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| web/wwwroot/css/userinfo.css | Adds styling for the Directory “userinfo” page. |
| web/Viper.csproj | Adjusts build warning suppression configuration. |
| web/Views/Shared/Components/SessionTimeout/SessionTimeout.cs | Updates session timeout refresh URL behavior. |
| web/Views/Shared/_VIPERLayout.cshtml | Loads directory/userinfo CSS conditionally; normalizes helper variable naming. |
| web/Properties/launchSettings.json | Changes local launch behavior (launchBrowser). |
| web/Program.cs | Registers additional DbContexts and HTTP client services. |
| web/Models/PPS/VwStipend.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwRankStepEthnicityPayRate.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwPersonAccrual.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwPerson.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwLoa.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwJobCodeAndGroup.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwEmployee.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwAccrualsCdm.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VwAccrual.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/VisaPermitDataDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UpdateLog.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UnionDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathVerificationItem.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathOverride.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathmissingpersonBk.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathMissingPerson20190821.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathMissingPerson.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcpathItemNote.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcdOrganizationDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcdFauDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcdEmployeeFlagsDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/UcdEmployeeFlagsDOverride.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/TitlecodeGroup.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/TimeDailyDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/ServiceCreditUnit.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/ServiceCredit.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsxlatitemV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsVisaPmtDataV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUnionTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcSsDisclosurV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcJobGrpDescV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcJobCodeTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcJobCodesV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcFundAttribV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcExtSystemV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcdDmPsNamesPrefVnamesV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcCtoOscV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcAmSsTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsUcAmSsRcdV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsPrimaryJobsV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsPersonV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsPersonalPhoneV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsPersDataEffdtV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsPerOrgInstV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsJpmProfileV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsJpmCatTypesV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsJpmCatItemsV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsGpRsltAcumV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsGpAbsReasonV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsGpAbsEaV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsGpAbsEaStaV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsEthnicGrpTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsErnProgramTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsEmplClassTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsEmailAddressesV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsEarningsBalV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsDiversEthnicV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsDeptTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsDeptBudgetErnV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsDeptBudgetDtV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsCountryTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsCompRatecdTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsCompensationV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsCitizenStsTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsCitizenshipV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsAddressTypTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsAddressesV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsAddlPayDataV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsActnReasonTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsActionTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PsAcctCdTblV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Prj2EmpidToPpsid.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/PrimaryJobsDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/OrganizationDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/OdsEmployeeFlagsDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JpmFV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JobStatusDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JobOverride.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JobHistoryDetail.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JobHistory.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/JobActionDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/HistServiceCredit.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/HistloaV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/GoAnywhereLog.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/FurloughTarget.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Export.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/EthnicityGender20210201.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/EthnicityGender.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/EmployeeHistory.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/EdbeffrptLog.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Edbeffrpt.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Dvtloa.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/DiversEthnicityDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/DepartmentDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/DepartmentBudgetEarnFV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Ctvhme.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Ctltci.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/Ctlcad.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/CompensationFV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/CompensationDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/CompensationDRateV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AuditOverride.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AccountCodeDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AbsenceResultFV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AbsenceResultDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AbsenceEventFV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AbsenceEventDV.cs | Scaffolded PPS EF entity. |
| web/Models/PPS/AbsenceCalendarDV.cs | Scaffolded PPS EF entity. |
| web/Models/Keys/VwUserinfo.cs | Scaffolded Keys EF entity/view model. |
| web/Models/Keys/KeyManager.cs | Scaffolded Keys EF entity. |
| web/Models/Keys/KeyBuilding.cs | Scaffolded Keys EF entity. |
| web/Models/Keys/KeyAssignment.cs | Scaffolded Keys EF entity. |
| web/Models/Keys/Key.cs | Scaffolded Keys EF entity. |
| web/Models/Keys/Import3.cs | Scaffolded Keys import EF entity. |
| web/Models/Keys/Import2.cs | Scaffolded Keys import EF entity. |
| web/Models/Keys/Import.cs | Scaffolded Keys import EF entity. |
| web/Models/Keys/Disposition.cs | Scaffolded Keys EF entity. |
| web/Models/Keys/Building.cs | Scaffolded Keys EF entity. |
| web/Models/IDCards/VwLatestIdcard.cs | Scaffolded IDCards EF view entity. |
| web/Models/IDCards/VwDelimitedSpecialApprover.cs | Scaffolded IDCards EF view entity. |
| web/Models/IDCards/VwApproverMothraId.cs | Scaffolded IDCards EF view entity. |
| web/Models/IDCards/PrintQueue.cs | Scaffolded IDCards EF entity (with navigation). |
| web/Models/IDCards/PhotoExport.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/LenelBadge.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/IgnoreList.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/IdCardToPrintQueue.cs | Scaffolded join entity. |
| web/Models/IDCards/IdCard.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/ExtVisit.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/EcoTimeBadgeExclusion.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/DvtSvmUnit.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtSpecialty.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtSpecialApprover.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtReason.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtOverseer.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtClient.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtCardStatus.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/DvtApprover.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/Defuncted.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/DbIdCard.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/BulkLoadResult.cs | Scaffolded IDCards EF entity. |
| web/Models/IDCards/Audit.cs | Scaffolded IDCards audit EF entity. |
| web/Models/IDCards/AccessLevel.cs | Scaffolded IDCards lookup entity. |
| web/Models/IDCards/AccessExpiration.cs | Scaffolded IDCards EF entity. |
| web/Models/EquipmentLoan/VwLoan.cs | Scaffolded EquipmentLoan EF view entity. |
| web/Models/EquipmentLoan/Reason.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/O.cs | Scaffolded EquipmentLoan EF entity (OS lookup). |
| web/Models/EquipmentLoan/LoanNote.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/LoanItem.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/Loan.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/EmailTemplate.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/EmailSent.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/Audit.cs | Scaffolded EquipmentLoan audit EF entity. |
| web/Models/EquipmentLoan/AssetType.cs | Scaffolded EquipmentLoan lookup entity. |
| web/Models/EquipmentLoan/AssetNote.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/Asset.cs | Scaffolded EquipmentLoan EF entity. |
| web/Models/EquipmentLoan/AppSetting.cs | Scaffolded EquipmentLoan EF entity. |
| web/Controllers/HomeController.cs | Adds a GetSessionTimeout endpoint. |
| web/Classes/Utilities/LdapService.cs | Adds MothraID lookup and improves sorting; extends LDAP helpers. |
| web/Classes/Utilities/IamApi.cs | Adds custom DateTime parsing for IAM API responses. |
| web/Classes/AreaController.cs | Adds PopulateLeftNav helper and adjusts dev nav link conversion. |
| web/Areas/Directory/Models/UCPathResult.cs | Adds Directory UCPath DTO. |
| web/Areas/Directory/Models/LoanResult.cs | Adds Directory loan DTO. |
| web/Areas/Directory/Models/LdapUserContact.cs | Adjusts LDAP contact model (MothraId nullable). |
| web/Areas/Directory/Models/KeyResult.cs | Adds Directory key DTO. |
| web/Areas/Directory/Models/InstinctResult.cs | Adds Directory instinct DTO. |
| web/Areas/Directory/Models/IndividualSearchResultWithIDs.cs | Adjusts Directory search result mapping. |
| web/Areas/Directory/Models/IndividualSearchResult.cs | Adjusts Directory search result mapping. |
| web/Areas/Directory/Models/IDCardResult.cs | Adds Directory ID card DTO. |
| web/Areas/Directory/Models/DirectoryUser.cs | Adds view model for Directory permissions/features. |
| web/Areas/Directory/Controllers/DirectoryController.cs | Adds query-based search endpoint and left-nav population. |
| Viper.sln.DotSettings | Updates ReSharper inspection severities. |
| test/Usings.cs | Disables xUnit test parallelization globally. |
| test/Areas/Directory/VMACSServiceTest.cs | Updates VMACS URL validation test cases. |
| CLAUDE.md | Updates repo contribution/testing guidance. |
| .gitignore | Updates ignore patterns (currently includes conflict marker and broad ignores). |
| ViewData["sessionRefreshUrl"] = onDev | ||
| ? "/GetSessionTimeout" | ||
| : ("https://" + HttpHelper.HttpContext?.Request.Host.Value + "/") |
| { | ||
| return NotFound(); | ||
| } | ||
| var secondsLeft = (int)(timeout.SessionTimeoutDateTime - DateTime.Now).TotalSeconds; |
| if (id == null) return null; | ||
| string filter = string.Format("(ucdpersonuuid = {0})", id); | ||
| var results = SearchLdap(filter); |
There was a problem hiding this comment.
@JasonRobertFrancis Yes, this was flagged in the previous PR and still an issue
| Email = ldapUserContact.Mail; | ||
| MailId = ldapUserContact.Mail?.Split("@")[0]; | ||
| MailId = ldapUserContact.Mail.Split("@")[0]; | ||
| UserName = ldapUserContact.Uid; | ||
| PostalAddress = (ldapUserContact.PostalAddress ?? "").Replace("$", '\n'.ToString()); | ||
| PostalAddress = ldapUserContact.PostalAddress.Replace("$", '\n'.ToString()); |
| Mobile = ldapUserContact.Mobile; | ||
| UserName = ldapUserContact.Uid; | ||
| PostalAddress = (ldapUserContact.PostalAddress ?? "").Replace("$", '\n'.ToString()); | ||
| PostalAddress = ldapUserContact.PostalAddress.Replace("$", '\n'.ToString()); |
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> | ||
| <PublishDir>bin\Release\net10.0\publish\</PublishDir> | ||
| <NoWarn>$(NoWarn);NU1902;NU1608</NoWarn> |
| .userinfo ul + ul { margin-top: 0.5rem; } | ||
| .userinfo ul li { padding: 0.2rem; margin-left: -0.2rem; } | ||
| .userinfo ul li:nth-child(odd) { background-color: #f1f3f5; } | ||
| .userinfo ul li ul li { padding-left: -0.2rem; margin-left: 2.2rem; } |
bsedwards
left a comment
There was a problem hiding this comment.
Please address the student information in the user info page - we need to remove sensitive information.
Other things I've noticed:
- I was using the directory on secure-test earlier, but now when I search I'm getting an HTML page saying my session has timed out.
- I was missing the AAUD Check, ID Check, and UC Path info links on directory entries.
- Missing AD information from user info page.
- Student information on the user info page only shows 5 flags for me. Please validate the permissions being checked.
| return null; | ||
| } | ||
|
|
||
| Console.WriteLine($"[INSTINCT SERVICE] mothraId: '{mothraId}', iamId: '{iamId}', result.MothraId: '{result.MothraId}'"); |
There was a problem hiding this comment.
I'm not sure we should have console.writeline in production code
| /// <summary> | ||
| /// Get cumulative GPA - equivalent to getCumulativeGPA in SIS.cfc | ||
| /// </summary> | ||
| private async Task<string?> GetStudentCumulativeGPAAsync(string pidm, string termCode, string majorCode) |
There was a problem hiding this comment.
It looks like this is reimplementing every function in SIS.cfc inside UserInfoService.cs. I'm not sure how many of these functions the user info page is actually using (ref previous comment on sensitivity of this info). I suggest implementing these functions in a separate class and having the UserInfoService only reference what is needed and approved for display on the UserInfoPage.
| result.StudentBannerId = await GetStudentBannerIdAsync(result.Pidm); | ||
| result.StudentConfidential = await IsStudentConfidentialAsync(result.Pidm); | ||
| result.StudentConfidentialScope = await GetStudentConfidentialScopeAsync(result.Pidm); | ||
| result.StudentBirthDate = await GetStudentBirthDateAsync(result.Pidm); |
There was a problem hiding this comment.
Are these shown on the User Info page? Many of these fields are sensitive and should only be shown to a small number of users.
| public static async Task<byte[]?> GetUserPhotoAsync(string mailId, bool useAltPhoto = false) | ||
| { | ||
| // stubbed | ||
| return null; |
| var formContent = new FormUrlEncodedContent(formParams); | ||
| Console.WriteLine("[INSTINCT AUTH] Sending token POST request..."); | ||
| var response = await httpClient.PostAsync(tokenUrl, formContent); | ||
| Console.WriteLine($"[INSTINCT AUTH] Response Status Code: {response.StatusCode}"); |
| } | ||
| <li><strong>Dual Degree?:</strong> @(Model.StudentIsDualDegree ? "Yes" : "No")</li> | ||
|
|
||
| @if (Model.CanViewStudentID) |
There was a problem hiding this comment.
I'm not sure being able to view the student ID is sufficient permission to view this detail. I would suggest leaving out things like GPA, residency and citizenship, ethnicity, age, etc. off the UserInfo page entirely.
| <li><strong>Student Employer:</strong> @Model.StudentEmployer</li> | ||
| } | ||
| } | ||
| @if (!string.IsNullOrEmpty(Model.StudentPermanentAddress)) |
There was a problem hiding this comment.
Also leave addresses out of this page
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> | ||
| <PublishDir>bin\Release\net10.0\publish\</PublishDir> | ||
| <NoWarn>$(NoWarn);NU1902;NU1608</NoWarn> |
There was a problem hiding this comment.
Do we want to disable warnings on these issues?
| # Used to reduce unnecessary dotnet builds | ||
| .build-cache/ | ||
|
|
||
| <<<<<<< HEAD |
There was a problem hiding this comment.
Line created during a merge?
|
|
||
| # Agent folders | ||
| .claude | ||
| CLAUDE.md |
There was a problem hiding this comment.
Do we want to exclude the .md files? I think Rex committed some.
| userInfo.CanViewInstinct = ownPage || _userHelper.HasPermission(_rapsContext, currentUser, "SVMSecure.userinfo.instinct"); | ||
| userInfo.CanViewADGroups = _userHelper.HasPermission(_rapsContext, currentUser, "SVMSecure.UserInfo.ADGroups"); | ||
|
|
||
| userInfo.CanViewDirectoryDetail = true; |
There was a problem hiding this comment.
@JasonRobertFrancis The permission overrides are still in place. This has got to be debugging code, right?
| if (id == null) return null; | ||
| string filter = string.Format("(ucdpersonuuid = {0})", id); | ||
| var results = SearchLdap(filter); |
There was a problem hiding this comment.
@JasonRobertFrancis Yes, this was flagged in the previous PR and still an issue
| return NotFound(); | ||
| } | ||
|
|
||
| [Route("/[area]/nav")] |
There was a problem hiding this comment.
@JasonRobertFrancis This will conflict with the /nav route for the Directory. Go to https://secure-test.vetmed.ucdavis.edu/2/Directory/nav and it will give an error that it doesn't on main/PROD.
| <img src="https://viper.vetmed.ucdavis.edu/public/utilities/getbase64image.cfm?mailid=@Model.MailId" width="87" height="111" alt="User Photo" /> | ||
| </span> | ||
| <span class="photo2"> | ||
| <img src="https://viper.vetmed.ucdavis.edu/public/utilities/getbase64image.cfm?mailid=@Model.MailId&altphoto=1" width="87" height="111" alt="Alternative Photo" /> |
There was a problem hiding this comment.
This shouldn't be hardcoded to prod VIPER1, right?
| <div class="direct"> | ||
| <h2>User Information Page</h2> | ||
| <span class="photo"> | ||
| <img src="https://viper.vetmed.ucdavis.edu/public/utilities/getbase64image.cfm?mailid=@Model.MailId" width="87" height="111" alt="User Photo" /> |
There was a problem hiding this comment.
This shouldn't be hardcoded to prod VIPER1, right?
| { | ||
| <li><strong>Banner ID:</strong> @Model.StudentBannerId</li> | ||
| } | ||
| <li><strong>Confidential?:</strong> @(Model.StudentConfidential ? "Yes" : "No")</li> |
There was a problem hiding this comment.
The flag is fetched, but it does not appear to be used to suppress any data. Is that right?
| CLAUDE.md | ||
|
|
||
| # Temp Agent Files | ||
| DESIGN.md* |
There was a problem hiding this comment.
These should not be ignored either
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": false, | ||
| "launchBrowser": true, |
There was a problem hiding this comment.
Not needed. If you use npm run dev the browser will be opened for you
| </article> | ||
|
|
||
| @section Scripts { | ||
| <script src="~/js/userinfo.js"></script> |
There was a problem hiding this comment.
This JS file does not exist
| { | ||
| if (vm?.item != null) | ||
| { | ||
| if (vm.item.Nextel != null) result.Nextel = vm.item.Nextel[0]; |
There was a problem hiding this comment.
An empty value for Nextel/LDPager/Unit can crash the search.
Suggested code:
private static void PopulateVmacsDetails(IndividualSearchResult result, VMACSQuery? vm)
{
var item = vm?.item;
if (item == null)
{
return;
}
if (item.Nextel is { Length: > 0 }) result.Nextel = item.Nextel[0];
if (item.LDPager is { Length: > 0 }) result.LDPager = item.LDPager[0];
if (item.Unit is { Length: > 0 }) result.Department = item.Unit[0];
}
| .ThenByDescending(p => p.Effdt) | ||
| .ToListAsync(); | ||
|
|
||
| foreach (var history in historyData) |
There was a problem hiding this comment.
From a Claude code analysis:
N+1 with synchronous blocking EF calls in an async request
UserInfoService.cs:1333-1348 calls GetReportsToName(history) and GetReportsToPosition(history) per UCPath history row. Each helper (1359-1433) issues up to two FirstOrDefault() calls — synchronous, not FirstOrDefaultAsync — at lines 1367, 1377, 1405, 1416. And the two helpers query the identical rows independently, so it's up to 4 blocking round-trips per row where 1 async batch would do. A person with 30 job actions is 120 sequential blocking DB calls holding a thread-pool thread.
Also:
- PopulateKeysAsync:1498 — one AAUD query per key assignment to resolve IssuedBy
- GetUserPermissionsForSystemAsync — called 5× from 1126-1136, re-running the same two large RAPS joins each time; only the trailing StartsWith(systemPrefix) filter differs
- No .AsNoTracking() anywhere in a 2,229-line entirely read-only service
Seems like a major performance concern.
| [Route("")] | ||
| public ActionResult Index() | ||
| { | ||
| return Redirect("/Directory"); |
There was a problem hiding this comment.
This would go back to VIPER1, is that expected?
| @if (Model.CanViewRoles && Model.SystemRoles.Any()) | ||
| { | ||
| <div class="roles"> | ||
| <h2><a href="/RAPS/" target="_blank">System Roles</a></h2> |
There was a problem hiding this comment.
This would go back to VIPER1, is that expected?
| } | ||
| if (!foundMatch) | ||
| { | ||
| result.ErrorMessage = $"User found in API but no name match. Variations tried: {string.Join(", ", nameVariations)}. API users: {string.Join(", ", graphqlResponse.Data.SearchUsers.Select(u => $"{u.NameFirst} {u.NameLast}"))}"; |
There was a problem hiding this comment.
When this returns no matches, it returns a list of API users. This seems like it would leak user information.
| // Create GraphQL query | ||
| var query = $@" | ||
| query {{ | ||
| searchUsers(name: ""{lastName}"") {{ |
There was a problem hiding this comment.
GraphQL query built by string interpolation
No description provided.