-
-
Notifications
You must be signed in to change notification settings - Fork 86
RG-T133 User Session, Password Reset Changes, More Audits #476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| namespace Resgrid.Config | ||
| { | ||
| public static class SessionSecurityConfig | ||
| { | ||
| // Session tracking is required by the Web BFF and is safe for pre-feature | ||
| // credentials because they are adopted lazily by the validation middleware. | ||
| public static bool TrackingEnabled = true; | ||
| public static bool LegacyAdoptionEnabled = true; | ||
| public static string RequireSessionClaimForCredentialsIssuedAfterUtc = ""; | ||
| // Blank is intentionally disabled at launch. Set to an ISO-8601 UTC timestamp | ||
| // only after previewing stored DepartmentSecurityPolicy session values. | ||
| public static string DepartmentSessionPolicyEnforcementAfterUtc = ""; | ||
| public static int LastActivityWriteIntervalMinutes = 5; | ||
| public static int RevokedSessionRetentionDays = 90; | ||
| public static int PublicResetLinkLifetimeMinutes = 30; | ||
| public static int PublicResetAccountLimitPerHour = 3; | ||
| public static int PublicResetIpLimitPerHour = 10; | ||
| public static int WebBffAccessTokenLifetimeMinutes = 5; | ||
| public static int ClientMetadataMaximumLength = 256; | ||
| public static int UserAgentMaximumLength = 1024; | ||
| // Optional local JSON CIDR database. Leave blank to display location as unavailable. | ||
| public static string IpLocationDatabasePath = ""; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -191,6 +191,8 @@ public enum AuditLogTypes | |
| ModerationReportSubmitted, | ||
| ModerationRequestReopened, | ||
| ModerationRequestCompleted, | ||
| ModerationEvidenceDownloaded | ||
| ModerationEvidenceDownloaded, | ||
| PasswordResetByAdministrator, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security audit coverage gap in Kody rule violation: Emit tamper-evident audit logs with required fields Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Privileged password reset flow in Kody rule violation: Require step-up MFA for privileged operations Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| UserAuthenticationSessionsRevoked | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| namespace Resgrid.Model | ||
| { | ||
| public enum ExternalIdentityLinkMethod | ||
| { | ||
| Subject = 0, | ||
| VerifiedEmail = 1, | ||
| TrustedSamlEmail = 2, | ||
| Scim = 3, | ||
| Administrator = 4 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,8 +7,10 @@ public interface IEmailProvider | |
| { | ||
| void Configure(object sender, string fromAddress); | ||
|
|
||
| Task<bool> SendWelcomeMail(string name, string departmentName, string userName, string password, string email, int departmentId); | ||
| Task<bool> SendPasswordResetMail(string name, string password, string userName, string email, string departmentName); | ||
| Task<bool> SendWelcomeMail(string name, string departmentName, string userName, string email, int departmentId); | ||
| Task<bool> SendPasswordRecoveryMail(string name, string email, string departmentName, | ||
| string resetUrl, string ipAddress, string userAgent, string requestedOn, bool isSsoManaged); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sensitive metadata propagation in Kody rule violation: Do not log PHI; mask and drop sensitive fields string resetUrl, string requestedOn, bool isSsoManaged);Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PII propagation risk in Kody rule violation: Redact PII in logs and metrics by default string resetUrl, string requestedOn, bool isSsoManaged);Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| Task<bool> SendPasswordChangedByAdministratorMail(string name, string userName, string email, string departmentName); | ||
| Task<bool> SendSignupMail(string name, string departmentName, string email); | ||
| Task<bool> SendMessageMail(string email, string subject, string messageSubject, string messageBody, string senderEmail, string senderName, string sentOn, int messageId); | ||
| Task<bool> SendCallMail(string email, string subject, string title, string priority, string natureOfCall, string mapPage, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| using System.Collections.Generic; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace Resgrid.Model.Repositories | ||
| { | ||
| public interface IUserExternalIdentityLinksRepository : IRepository<UserExternalIdentityLink> | ||
| { | ||
| Task<UserExternalIdentityLink> GetActiveBySubjectAsync(string departmentSsoConfigId, string externalSubject); | ||
| Task<UserExternalIdentityLink> GetActiveByUserAndConfigAsync(string userId, string departmentSsoConfigId); | ||
| Task<IReadOnlyList<UserExternalIdentityLink>> GetActiveByUserAsync(string userId); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace Resgrid.Model.Repositories | ||
| { | ||
| public interface IUserSessionsRepository : IRepository<UserSession> | ||
| { | ||
| Task<IReadOnlyList<UserSession>> GetActiveByUserAsync(string userId, DateTime utcNow); | ||
| Task<UserSession> GetByAuthorizationIdAsync(string authorizationId); | ||
| Task<int> TouchAsync(string sessionId, DateTime occurredOn, DateTime writeBefore, string ipAddress, | ||
| string country, string region, string city, string userAgent, CancellationToken cancellationToken); | ||
| Task<int> UpdateDepartmentAsync(string targetUserId, string sessionId, int departmentId, | ||
| CancellationToken cancellationToken); | ||
| Task<int> RevokeAsync(string targetUserId, string sessionId, string actorUserId, int reason, DateTime revokedOn, CancellationToken cancellationToken); | ||
| Task<int> RevokeOthersAsync(string userId, string currentSessionId, int reason, DateTime revokedOn, CancellationToken cancellationToken); | ||
| Task<int> RevokeAllAsync(string targetUserId, string actorUserId, int reason, DateTime revokedOn, CancellationToken cancellationToken); | ||
| Task<int> RevokeDepartmentAsync(string targetUserId, int departmentId, int reason, DateTime revokedOn, CancellationToken cancellationToken); | ||
| Task<int> PurgeInactiveBeforeAsync(DateTime historyBeforeUtc, CancellationToken cancellationToken); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| using System; | ||
|
|
||
| namespace Resgrid.Model.Security | ||
| { | ||
| public class PasswordRecoveryRequest | ||
| { | ||
| public string UserId { get; set; } | ||
| public string Email { get; set; } | ||
| public long AuthenticationGeneration { get; set; } | ||
| public string SecurityStampHash { get; set; } | ||
| public DateTime CreatedOn { get; set; } | ||
| public DateTime ExpiresOn { get; set; } | ||
| } | ||
|
|
||
| public class PasswordRecoveryIssueResult | ||
| { | ||
| public bool Issued { get; set; } | ||
| public bool RateLimited { get; set; } | ||
| public string Token { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace Resgrid.Model.Security | ||
| { | ||
| public static class SessionClaimTypes | ||
| { | ||
| public const string SessionId = "sid"; | ||
| public const string AuthenticationGeneration = "auth_ver"; | ||
| public const string WebEventingOnly = "web_eventing_only"; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using System; | ||
|
|
||
| namespace Resgrid.Model.Security | ||
| { | ||
| public sealed class SessionCreationDeniedException : Exception | ||
| { | ||
| public SessionCreationDeniedException(string failureCode) | ||
| : base("The authentication session could not be created.") | ||
| { | ||
| FailureCode = failureCode; | ||
| } | ||
|
|
||
| public string FailureCode { get; } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mutable static configuration in
Core/Resgrid.Config/OidcConfig.csand the related declarations atWeb/Resgrid.Web/Models/AccountViewModels/ResetPasswordViewModel.cs:20-20,Core/Resgrid.Config/SessionSecurityConfig.cs:7-7,Core/Resgrid.Config/SessionSecurityConfig.cs:8-8,Core/Resgrid.Config/SessionSecurityConfig.cs:9-9,Core/Resgrid.Config/SessionSecurityConfig.cs:12-12,Core/Resgrid.Config/SessionSecurityConfig.cs:13-13,Core/Resgrid.Config/SessionSecurityConfig.cs:14-14,Core/Resgrid.Config/SessionSecurityConfig.cs:15-15,Core/Resgrid.Config/SessionSecurityConfig.cs:16-16,Core/Resgrid.Config/SessionSecurityConfig.cs:17-17,Core/Resgrid.Config/SessionSecurityConfig.cs:18-18,Core/Resgrid.Config/SessionSecurityConfig.cs:19-19,Core/Resgrid.Config/SessionSecurityConfig.cs:20-20,Core/Resgrid.Config/SessionSecurityConfig.cs:22-22, andCore/Resgrid.Services/DepartmentSettingsService.cs:27-27obscures immutability and permits accidental reassignment. MarkTrustedLongLivedClientIdsasreadonlywhere the value is only supplied through configuration or bootstrap.Kody rule violation: Use `readonly` or `const` for Immutable Data
Prompt for LLM
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.